<commit_before>var IssueApp = angular.module('issueApp', ['firebase', 'ga', 'ngAnimate'])

.constant('Firebase', Firebase)
.constant('markdown', markdown)

.controller('AppCtrl', function($scope, $rootScope, LoginService, GitHubService, $http) {

  $scope.issue = {
    title: '',
    type: '',
    platform: '',
    iosVersion: '7',
    androidVersion: '4.4',
    webview: null,
    description: ''
  };

  $scope.typeOptions = [
    { id: 'bug', label: 'bug' },
    { id: 'perf', label: 'performance' },
    { id: 'docs', label: 'documentation' },
    { id: 'feat', label: 'feature request' }
  ];
  $scope.platformOptions = [
    { id: 'ios', label: 'ios' },
    { id: 'android',  label: 'android' },
    { id: 'mobile', label: 'all mobile devices' },
    { id: 'desktop', label: 'desktop' }
  ];
  $scope.iosVersions = [
    '7',
    '6'
  ];
  $scope.androidVersions = [
    '4.4',
    '4.3',
    '4.2',
    '4.0',
    '4.1',
    '4.x',
    '2.x'
  ];
  $scope.componentOptions = [
    'action sheet',
    'animations',
    'cards',
    'checkbox',
    'content',
    'footers',
    'gesture',
    'grid',
    'headers',
    'inputs',
    'lists',
    'loading',
    'menus',
    'navigation',
    'modal',
    'popup',
    'platform',
    'radio',
    'range',
    'scroll',
    'slide box',
    'tabs',
    'toggle',
    'tap/click',
    'view'
  ];

  var user;
  $rootScope.$on('userStateChange', function(e, newUser) {
    user = newUser;
  });
  $scope.authenticated = function() {
    return !!user;
  };
  $scope.currentUser = function() {
    return user;
  };
  $scope.signIn = function() {
    return LoginService.login(null, function() {
    });
  };
  $scope.signOut = function() {
    return LoginService.logout();
  };

  var issueTitleTemplate = '<%= type %>: <%= title %>';
  var issueTemplatePromise = $http.get('/submit-issue/issue-template.html')
    .then(function(response) {
      return response.data;
    });
  $scope.submitIssue = function() {
    $scope.issue.loading = true;
    return issueTemplatePromise.then(function(template) {
      return GitHubService.submitIssue({
        title: _.template(issueTitleTemplate, $scope.issue),
        body: _.template(template, $scope.issue)
      }, user.accessToken, 'driftyco', 'ionic');
    }).then(function(response) {
      alert('Issue Submitted Succesfully! Going there now.');
      window.location.href = response.data.html_url;
    }, function(err) {
      $scope.issue.loading = false;
      alert('Issue Submission Error! Try again.');
    });
  };

})

.directive('stepMaster', function() {
  return {
    controller: function StepCtrl() {
      this.stepsDone = 0;
      this.numSteps = 0;
    }
  };
})
.directive('step', function() {
  return {
    transclude: true,
    restrict: 'A',
    require: '^stepMaster',
    template:
      '
' +
        '
' +
          '[ {{stepText()}} ] ' +
          '{{heading}}' +
          ' ' +
        '
' +
        '

' +
      '
',
    scope: true,
    link: function(scope, elm, attr, stepsCtrl, transclude) {
      if (!attr.noTotal) {
        stepsCtrl.numSteps++;
      }

      scope.noTotal = attr.noTotal;
      scope.heading = attr.heading;
      scope.step = +attr.step;

      var doneWatch = scope.$parent.$watch(function() {
        return scope.$eval(attr.isDone) && scope.showStep();
      }, function(done) {
        if (done) {
          scope.done = true;
          stepsCtrl.stepsDone++;
          doneWatch();
        }
      });

      scope.stepText = function() {
        return (1+scope.step) + ' / ' + stepsCtrl.numSteps;
      };

      scope.showStep = function() {
        return stepsCtrl.stepsDone >= scope.step;
      };
    }
  };
})
.directive('textarea', function() {
  return {
    restrict: 'E',
    link: function(scope, elm, attr) {
      jQuery(elm[0]).autosize();
    }
  };
})

;
<commit_msg>add "all platforms" to submit-issue<commit_after>var IssueApp = angular.module('issueApp', ['firebase', 'ga', 'ngAnimate'])

.constant('Firebase', Firebase)
.constant('markdown', markdown)

.controller('AppCtrl', function($scope, $rootScope, LoginService, GitHubService, $http) {

  $scope.issue = {
    title: '',
    type: '',
    platform: '',
    iosVersion: '7',
    androidVersion: '4.4',
    webview: null,
    description: ''
  };

  $scope.typeOptions = [
    { id: 'bug', label: 'bug' },
    { id: 'perf', label: 'performance' },
    { id: 'docs', label: 'documentation' },
    { id: 'feat', label: 'feature request' }
  ];
  $scope.platformOptions = [
    { id: 'ios', label: 'ios' },
    { id: 'android',  label: 'android' },
    { id: 'mobile', label: 'all mobile devices' },
    { id: 'desktop', label: 'desktop' },
    { id: 'all', label: 'all platforms' }
  ];
  $scope.iosVersions = [
    '7',
    '6'
  ];
  $scope.androidVersions = [
    '4.4',
    '4.3',
    '4.2',
    '4.0',
    '4.1',
    '4.x',
    '2.x'
  ];
  $scope.componentOptions = [
    'action sheet',
    'animations',
    'cards',
    'checkbox',
    'content',
    'footers',
    'gesture',
    'grid',
    'headers',
    'inputs',
    'lists',
    'loading',
    'menus',
    'navigation',
    'modal',
    'popup',
    'platform',
    'radio',
    'range',
    'scroll',
    'slide box',
    'tabs',
    'toggle',
    'tap/click',
    'view'
  ];

  var user;
  $rootScope.$on('userStateChange', function(e, newUser) {
    user = newUser;
  });
  $scope.authenticated = function() {
    return !!user;
  };
  $scope.currentUser = function() {
    return user;
  };
  $scope.signIn = function() {
    return LoginService.login(null, function() {
    });
  };
  $scope.signOut = function() {
    return LoginService.logout();
  };

  var issueTitleTemplate = '<%= type %>: <%= title %>';
  var issueTemplatePromise = $http.get('/submit-issue/issue-template.html')
    .then(function(response) {
      return response.data;
    });
  $scope.submitIssue = function() {
    $scope.issue.loading = true;
    return issueTemplatePromise.then(function(template) {
      return GitHubService.submitIssue({
        title: _.template(issueTitleTemplate, $scope.issue),
        body: _.template(template, $scope.issue)
      }, user.accessToken, 'driftyco', 'ionic');
    }).then(function(response) {
      alert('Issue Submitted Succesfully! Going there now.');
      window.location.href = response.data.html_url;
    }, function(err) {
      $scope.issue.loading = false;
      alert('Issue Submission Error! Try again.');
    });
  };

})

.directive('stepMaster', function() {
  return {
    controller: function StepCtrl() {
      this.stepsDone = 0;
      this.numSteps = 0;
    }
  };
})
.directive('step', function() {
  return {
    transclude: true,
    restrict: 'A',
    require: '^stepMaster',
    template:
      '
' +
        '
' +
          '[ {{stepText()}} ] ' +
          '{{heading}}' +
          ' ' +
        '
' +
        '

' +
      '
',
    scope: true,
    link: function(scope, elm, attr, stepsCtrl, transclude) {
      if (!attr.noTotal) {
        stepsCtrl.numSteps++;
      }

      scope.noTotal = attr.noTotal;
      scope.heading = attr.heading;
      scope.step = +attr.step;

      var doneWatch = scope.$parent.$watch(function() {
        return scope.$eval(attr.isDone) && scope.showStep();
      }, function(done) {
        if (done) {
          scope.done = true;
          stepsCtrl.stepsDone++;
          doneWatch();
        }
      });

      scope.stepText = function() {
        return (1+scope.step) + ' / ' + stepsCtrl.numSteps;
      };

      scope.showStep = function() {
        return stepsCtrl.stepsDone >= scope.step;
      };
    }
  };
})
.directive('textarea', function() {
  return {
    restrict: 'E',
    link: function(scope, elm, attr) {
      jQuery(elm[0]).autosize();
    }
  };
})

;
<|endoftext|>


<commit_before>Meteor.users.allow({
  insert: () => false,
  update: () => false,
  remove: () => false
});

Meteor.users.deny({
  insert: () => true,
  update: () => true,
  remove: () => true
});
<commit_msg>switched user id to string type.<commit_after>Meteor.users.allow({
  insert: () => false,
  update: () => false,
  remove: () => false
});

Meteor.users.deny({
  insert: () => true,
  update: () => true,
  remove: () => true
});<|endoftext|>


<commit_before>const gcloud = require('google-cloud');
const webpush = require('web-push');
const model = require('../model');
const project_id = 'web-push-rocks';
const pubsub = gcloud.pubsub({
  projectId: project_id
});

/*
  Push Notification Send Service
  This service will get notified when we need to send a notification
*/

const sendTopic = `projects/${project_id}/topics/send`;

// Create the topic
pubsub.createTopic(sendTopic)
      .then(data => data[0])
      .catch(data => {
        console.log('Error creating topic')
        return pubsub.topic(sendTopic);
      })
      .then(topic => {
        console.log('subscribing to topic')
        return topic.subscribe('sub-send-subscription');
      })
      .then(data => {
        console.log('waiting for messages', data)
        const subscription = data[0];
        subscription.on('message', message => {
          // We only expect one message a day so this for now will be super super lightweight
          const id = message.data.id;
          const payload = message.data.message;

          console.log(`Recieved Message ${message.data}`);
          console.log(`Recieved Message.Id ${id}`);

          model.Subscription.getByEndpoint(id)
          .then(sub => {
            console.log(`Got Subscription ${sub.endpoint}`);
            const applicationServerKey = sub.applicationServerKey;
            const endpoint = sub.endpoint;
            const p256dh = sub.p256dh;
            const auth = sub.authKey;
            const privateKey = sub.privateKey;
            const stringPayload = JSON.stringify(payload);
            console.log(`Payload: ${stringPayload}`);
            const pushSubscription = {
              endpoint: endpoint,
              keys: {
                p256dh: p256dh,
                auth: auth
              }
            };

            webpush.setVapidDetails('https://webpush.rocks', applicationServerKey, privateKey);

            webpush.sendNotification(
              pushSubscription,
              stringPayload
            )
            .catch(err => {
              if(err.statusCode && err.statusCode == 410) {
                console.log('Subscription not registered');
                // Delete the subscription and ack
                return sub.delete();
              }
            })
            .then(res => {
              message.ack();
            });
          }, err=> {
            console.error(`Error ${err}`);
            message.ack();
          })
          .catch(err => {
            console.error(`Error getting subscription: ${err}`);
            message.ack();
          });
        });
      });<commit_msg>adding reuse back in.<commit_after>const gcloud = require('google-cloud');
const webpush = require('web-push');
const model = require('../model');
const project_id = 'web-push-rocks';
const pubsub = gcloud.pubsub({
  projectId: project_id
});

/*
  Push Notification Send Service
  This service will get notified when we need to send a notification
*/

const sendTopic = `projects/${project_id}/topics/send`;

// Create the topic
pubsub.createTopic(sendTopic)
      .then(data => data[0])
      .catch(data => {
        console.log('Error creating topic')
        return pubsub.topic(sendTopic);
      })
      .then(topic => {
        console.log('subscribing to topic')
        return topic.subscribe('sub-send-subscription',{reuseExisting:true});
      })
      .then(data => {
        console.log('waiting for messages', data)
        const subscription = data[0];
        subscription.on('message', message => {
          // We only expect one message a day so this for now will be super super lightweight
          const id = message.data.id;
          const payload = message.data.message;

          console.log(`Recieved Message ${message.data}`);
          console.log(`Recieved Message.Id ${id}`);

          model.Subscription.getByEndpoint(id)
          .then(sub => {
            console.log(`Got Subscription ${sub.endpoint}`);
            const applicationServerKey = sub.applicationServerKey;
            const endpoint = sub.endpoint;
            const p256dh = sub.p256dh;
            const auth = sub.authKey;
            const privateKey = sub.privateKey;
            const stringPayload = JSON.stringify(payload);
            console.log(`Payload: ${stringPayload}`);
            const pushSubscription = {
              endpoint: endpoint,
              keys: {
                p256dh: p256dh,
                auth: auth
              }
            };

            webpush.setVapidDetails('https://webpush.rocks', applicationServerKey, privateKey);

            webpush.sendNotification(
              pushSubscription,
              stringPayload
            )
            .catch(err => {
              if(err.statusCode && err.statusCode == 410) {
                console.log('Subscription not registered');
                // Delete the subscription and ack
                return sub.delete();
              }
            })
            .then(res => {
              message.ack();
            });
          }, err=> {
            console.error(`Error ${err}`);
            message.ack();
          })
          .catch(err => {
            console.error(`Error getting subscription: ${err}`);
            message.ack();
          });
        });
      });<|endoftext|>


<commit_before>var request = require("request");
var qs = require("querystring");

function OmeglePlugin(bot) {
	var self = this;
	self.name = "omegle";
	self.help = "Omegle plugin";
	self.depend = ["cmd"];

	self.regex = /^(\s*([a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*)\s*[,:]|>)\s*(.*)$/i;

	self.skips = [];

	self.load = function(data) {
		if (data) {
			self.skips = data.skips;
		}
	};

	self.save = function() {
		return {"skips": self.skips};
	};

	self.chats = {};

	self.disable = function() {
		for (var to in self.chats) {
			self.chats[to].hardDisconnect();
		}
		self.chats = {};
	};

	self.start = function(to, topics, lang) {
		if (self.chats[to] === undefined) {
			self.chats[to] = {
				"auto": false,
				"lang": lang || "en",
				"topics": topics || []
			};
		}
		else {
			if (topics !== undefined)
				self.chats[to].topics = topics;
			if (lang !== undefined)
				self.chats[to].lang = lang;
		}

		var server = "http://front1.omegle.com/";
		self.chats[to].server = server;

		var query = {
			"rcs": 1,
			//"firstevents": 1,
			"spid": "",
			"lang": self.chats[to].lang,
			"topics": JSON.stringify(self.chats[to].topics)
		};
		request.post({url: server + "start?" + qs.stringify(query) }, function(err, res, body) {
			if (!err && res.statusCode == 200) {
				var data = JSON.parse(body);
				self.chats[to].id = data;
				var interval = setInterval(function() {
					request.post({url: server + "events", form: {"id": data}}, function(err, res, body) {
						if (!err && res.statusCode == 200) {
							var eventdata = JSON.parse(body);
							if (eventdata != null) {
								for (var i = 0; i < eventdata.length; i++) {
									switch (eventdata[i][0]) {
									case "waiting":
										bot.notice(to, "waiting for stranger [lang: " + self.chats[to].lang + "; interests: " + self.chats[to].topics.join(",") + "]");
										break;
									case "connected":
										bot.notice(to, "stranger connected");
										break;
									case "typing":
										bot.notice(to, "typing...");
										break;
									case "stoppedTyping":
										bot.notice(to, "stopped typing");
										break;
									case "gotMessage":
										var msg = eventdata[i][1];
										bot.say(to, "\x02" + msg);
										if (self.skips.some(function(skip) {
											return msg.match(new RegExp(skip));
										})) {
											bot.notice(to, "bot detected, disconnecting");
											self.chats[to].softDisconnect();
										}
										break;
									case "strangerDisconnected":
										bot.notice(to, "stranger disconnected");
										self.chats[to].softDisconnect();
										break;
									case "statusInfo":
										//bot.notice(to, "Omegle users online: " + eventdata[i][1].count);
										break;
									case "commonLikes":
										bot.notice(to, "common likes: " + eventdata[i][1].join(","));
										break;
									}
								}
							}
						}
					});
				}, 1000);
				var hardDisconnect = function() {
					request.post({url: server + "disconnect", form: {"id": data}});
					clearInterval(interval);
				};
				var softDisconnect = function() {
					hardDisconnect();
					if (self.chats[to].auto) {
						self.start(to);
					}
					else {
						delete self.chats[to];
					}
				};

				self.chats[to].interval = interval;
				self.chats[to].hardDisconnect = hardDisconnect;
				self.chats[to].softDisconnect = softDisconnect;
			}
			else {
				bot.notice(to, "omegle failure");
				delete self.chats[to];
			}
		});
	};

	self.events = {
		"cmd#omegle": function(nick, to, args) {
			if (!(to in self.chats)) {
				bot.notice(to, "omegle started");
				self.start(to, args[1] === undefined ? undefined : args[1].split(","), args[2]);
			}
			else
				bot.notice(to, "omegle already started");
		},

		"cmd#unomegle": function(nick, to, args) {
			if (to in self.chats) {
				self.chats[to].hardDisconnect();
				delete self.chats[to];
				bot.notice(to, "omegle stopped");
			}
			else
				bot.notice(to, "omegle not started");
		},

		"cmd#reomegle": function(nick, to, args, message) {
			if (to in self.chats) {
				self.chats[to].hardDisconnect();
			}
			self.start(to, args[1] === undefined ? undefined : args[1].split(","), args[2]);
		},

		"cmd#autoomegle": function(nick, to, args) {
			if (to in self.chats) {
				if (self.chats[to].auto) {
					self.chats[to].auto = false;
					bot.notice(to, "autoreomegle disabled");
				}
				else {
					self.chats[to].auto = true;
					bot.notice(to, "autoreomegle enabled");
				}
			}
			else
				bot.notice(to, "omegle not started");
		},

		"cmd#lang": function(nick, to, args) {
			if (to in self.chats) {
				self.chats[to].lang = args[1];
			}
		},

		"cmd#interests": function(nick, to, args) {
			if (to in self.chats) {
				self.chats[to].topics = args[1].split(",");
			}
		},

		"nocmd": function(nick, to, text) {
			if (to in self.chats)
			{
				var match = text.match(self.regex);
				if (nick == to || (match && (match[1] == ">" || match[2] == bot.nick))) {
					request.post({url: self.chats[to].server + "send", form: {"id": self.chats[to].id, "msg": (nick != to ? match[3] : text)}});
				}
			}
		}
	}
}

module.exports = OmeglePlugin;
<commit_msg>Log omegle usage<commit_after>var request = require("request");
var qs = require("querystring");

function OmeglePlugin(bot) {
	var self = this;
	self.name = "omegle";
	self.help = "Omegle plugin";
	self.depend = ["cmd"];

	self.regex = /^(\s*([a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*)\s*[,:]|>)\s*(.*)$/i;

	self.skips = [];

	self.load = function(data) {
		if (data) {
			self.skips = data.skips;
		}
	};

	self.save = function() {
		return {"skips": self.skips};
	};

	self.chats = {};

	self.disable = function() {
		for (var to in self.chats) {
			self.chats[to].hardDisconnect();
		}
		self.chats = {};
	};

	self.start = function(to, topics, lang) {
		if (self.chats[to] === undefined) {
			self.chats[to] = {
				"auto": false,
				"lang": lang || "en",
				"topics": topics || []
			};
		}
		else {
			if (topics !== undefined)
				self.chats[to].topics = topics;
			if (lang !== undefined)
				self.chats[to].lang = lang;
		}

		var server = "http://front1.omegle.com/";
		self.chats[to].server = server;

		var query = {
			"rcs": 1,
			//"firstevents": 1,
			"spid": "",
			"lang": self.chats[to].lang,
			"topics": JSON.stringify(self.chats[to].topics)
		};
		request.post({url: server + "start?" + qs.stringify(query) }, function(err, res, body) {
			if (!err && res.statusCode == 200) {
				var data = JSON.parse(body);
				self.chats[to].id = data;
				var interval = setInterval(function() {
					request.post({url: server + "events", form: {"id": data}}, function(err, res, body) {
						if (!err && res.statusCode == 200) {
							var eventdata = JSON.parse(body);
							if (eventdata != null) {
								for (var i = 0; i < eventdata.length; i++) {
									switch (eventdata[i][0]) {
									case "waiting":
										bot.notice(to, "waiting for stranger [lang: " + self.chats[to].lang + "; interests: " + self.chats[to].topics.join(",") + "]");
										break;
									case "connected":
										bot.out.log("omegle", "stranger connected in " + to);
										bot.notice(to, "stranger connected");
										break;
									case "typing":
										bot.notice(to, "typing...");
										break;
									case "stoppedTyping":
										bot.notice(to, "stopped typing");
										break;
									case "gotMessage":
										var msg = eventdata[i][1];
										bot.out.log("omegle", "stranger in " + to + ": " + msg);
										bot.say(to, "\x02" + msg);
										if (self.skips.some(function(skip) {
											return msg.match(new RegExp(skip));
										})) {
											bot.out.log("omegle", "stranger is bot, skipping");
											bot.notice(to, "bot detected, skipping");
											self.chats[to].softDisconnect();
										}
										break;
									case "strangerDisconnected":
										bot.out.log("omegle", "stranger disconnected");
										bot.notice(to, "stranger disconnected");
										self.chats[to].softDisconnect();
										break;
									case "statusInfo":
										//bot.notice(to, "Omegle users online: " + eventdata[i][1].count);
										break;
									case "commonLikes":
										bot.notice(to, "common likes: " + eventdata[i][1].join(","));
										break;
									}
								}
							}
						}
					});
				}, 1000);
				var hardDisconnect = function() {
					request.post({url: server + "disconnect", form: {"id": data}});
					clearInterval(interval);
				};
				var softDisconnect = function() {
					hardDisconnect();
					if (self.chats[to].auto) {
						self.start(to);
					}
					else {
						delete self.chats[to];
					}
				};

				self.chats[to].interval = interval;
				self.chats[to].hardDisconnect = hardDisconnect;
				self.chats[to].softDisconnect = softDisconnect;
			}
			else {
				bot.notice(to, "omegle failure");
				delete self.chats[to];
			}
		});
	};

	self.events = {
		"cmd#omegle": function(nick, to, args) {
			if (!(to in self.chats)) {
				bot.notice(to, "omegle started");
				self.start(to, args[1] === undefined ? undefined : args[1].split(","), args[2]);
			}
			else
				bot.notice(to, "omegle already started");
		},

		"cmd#unomegle": function(nick, to, args) {
			if (to in self.chats) {
				self.chats[to].hardDisconnect();
				delete self.chats[to];
				bot.out.log("omegle", nick + " in " + to + " disconnected");
				bot.notice(to, "omegle stopped");
			}
			else
				bot.notice(to, "omegle not started");
		},

		"cmd#reomegle": function(nick, to, args, message) {
			if (to in self.chats) {
				self.chats[to].hardDisconnect();
			}
			self.start(to, args[1] === undefined ? undefined : args[1].split(","), args[2]);
		},

		"cmd#autoomegle": function(nick, to, args) {
			if (to in self.chats) {
				if (self.chats[to].auto) {
					self.chats[to].auto = false;
					bot.notice(to, "autoreomegle disabled");
				}
				else {
					self.chats[to].auto = true;
					bot.notice(to, "autoreomegle enabled");
				}
			}
			else
				bot.notice(to, "omegle not started");
		},

		"cmd#lang": function(nick, to, args) {
			if (to in self.chats) {
				self.chats[to].lang = args[1];
			}
		},

		"cmd#interests": function(nick, to, args) {
			if (to in self.chats) {
				self.chats[to].topics = args[1].split(",");
			}
		},

		"nocmd": function(nick, to, text) {
			if (to in self.chats)
			{
				var match = text.match(self.regex);
				if (nick == to || (match && (match[1] == ">" || match[2] == bot.nick))) {
					var msg = nick != to ? match[3] : text;
					bot.out.log("omegle", nick + " in " + to + ": " + msg);
					request.post({url: self.chats[to].server + "send", form: {"id": self.chats[to].id, "msg": msg}});
				}
			}
		}
	}
}

module.exports = OmeglePlugin;
<|endoftext|>


<commit_before>/**
 * jStat - JavaScript Statistical Library
 * Copyright (c) 2011
 * This document is licensed as free software under the terms of the
 * MIT License: http://www.opensource.org/licenses/mit-license.php */
(function( Math, _this, undefined ) {

	// global function
	var jstat = function() {
			return new jstat.fn.init( slice.call( arguments ));
		},

		// for quick reference
		slice = Array.prototype.slice,
		toString = Object.prototype.toString,

		// ascending/descending functions for sort
		ascNum = function( a, b ) { return a - b; },
		descNum = function( a, b ) { return b - a; },

		// test if array
		isArray = function( arg ) {
			return toString.call( arg ) === "[object Array]";
		},

		// test if function
		isFunction = function( arg ) {
			return toString.call( arg ) === "[object Function]";
		},

		// simple method to run functions in setTimeout
		callLater = function( func, context, values ) {
			setTimeout( function() {
				func.apply( context, values );
			}, 10 );
		};

	jstat.fn = jstat.prototype = {
		constructor : jstat,
		init : function( args ) {

			// if first argument is an array, must be vector or matrix
			if ( isArray( args[0] )) {
				for ( var i = 0; i < args.length; i++ ) {
					this.push( args[i] );
				};

			// if first argument is number, assume creation of sequence
			} else if ( !isNaN( args[0] )) {
				this.push( jstat.seq.apply( this, args ));
			};
			return this;
		},

		// default length
		length : 0,

		// return clean array
		toArray : function() {
			return slice.call( this, 0 );
		},

		// only to be used internally
		push : Array.prototype.push,
		sort : [].sort,
		splice : [].splice
	};
	jstat.fn.init.prototype = jstat.fn;

	// TODO: there's got to be an easy way to combine these two
	// create method for easy extension
	jstat.extend = function( obj ) {
		for ( var i in obj ) {
			jstat[i] = obj[i];
		};
		return this;
	};
	jstat.fn.extend = function( obj ) {
		for ( var i in obj ) {
			jstat.fn[i] = obj[i];
		};
		return this;
	};

	// extend jstat.fn with applicable static methods
	(function( funcs ) {
		funcs = funcs.split( ' ' );
		for ( var i = 0; i < funcs.length; i++ ) (function( passfunc ) {
			jstat.fn[ funcs[i] ] = function( func ) {
				for ( var i = 0; i < this.length; i++ ) {
					callLater( func, jstat( this[i] ), [ jstat[ passfunc ]( this[i] )]);
				};
				return this;
			};
		})( funcs[i] );
	})( 'sum min max mean median mode range variance stdev meandev meddev quartiles' );

	// extend jstat.fn
	jstat.fn.extend({
		seq : function( start, count, func ) {
			this.push( jstat.seq( start, count, func ));
			return this;
		}
	});

	// generate sequence
	jstat.seq = function( start, count, func ) {
		var arr = [], i = 0;
		if ( count > 0 ) {
			for ( ; i < count; i++ ) arr.push( func ? func.call( this, start++ ) : start++ );
		} else {
			for ( ; i > count; i-- ) arr.push( start-- );
		};
		return arr;
	};

	// sum of an array
	jstat.sum = function( arr ) {
		var sum = 0,
			i = arr.length;
		while ( --i >= 0 ) {
			sum += arr[i];
		};
		return sum;
	};

	// minimum value of an array
	jstat.min = function( arr ) {
		return Math.min.apply( null, arr );
	};

	// maximum value of an array
	jstat.max = function( arr ) {
		return Math.max.apply( null, arr );
	};

	// mean value of an array
	jstat.mean = function( arr ) {
		return jstat.sum( arr ) / arr.length;
	};

	// median of an array
	jstat.median = function( arr ) {
		var arrlen = arr.length,
			_arr = arr.slice().sort( ascNum );

		// check if array is even or odd, then return the appropriate
		return !( arrlen & 1 ) ? ( _arr[ ( arrlen / 2 ) - 1 ] + _arr[ ( arrlen / 2 ) ] ) / 2 : _arr[ Math.floor( arrlen / 2 ) ];
	};

	// mode of an array
	jstat.mode = function( arr ) {
		var arrLen = arr.length,
			_arr = arr.slice().sort( ascNum ),
			count = 1,
			maxCount = 0,
			numMaxCount = 0,
			i = 0,
			maxNum;
		for ( ; i < arrLen; i++ ) {
			if ( _arr[ i ] === _arr[ i + 1 ] ) {
				count++;
			} else {
				if ( count > maxCount ) {
					maxNum = _arr[i];
					maxCount = count;
					count = 1;
					numMaxCount = 0;
				} else {

					// are there multiple max counts
					if ( count === maxCount ) {
						numMaxCount++;

					// count is less than max count, so reset values
					} else {
						count = 1;
					};
				};
			};
		};

		return ( numMaxCount === 0 ) ? maxNum : false;
	};

	// range of an array
	jstat.range = function( arr ) {
		var _arr = arr.slice().sort( ascNum );
		return _arr[ _arr.length - 1 ] - _arr[0];
	};

	// variance of an array
	jstat.variance = function( arr ) {
		var mean = jstat.mean( arr ),
			stSum = 0,
			i = arr.length - 1;
		for( ; i >= 0; i-- ) {
			stSum += Math.pow( ( arr[i] - mean ), 2 );
		};
		return stSum / ( arr.length - 1 );
	};

	// standard deviation of an array
	jstat.stdev = function( arr ) {
		return Math.sqrt( jstat.variance( arr ) );
	};

	// mean deviation (mean absolute deviation) of an array
	jstat.meandev = function( arr ) {
		var devSum = 0,
			mean = jstat.mean( arr ),
			i = arr.length - 1;
		for ( ; i >= 0; i-- ) {
			devSum += Math.abs( arr[ i ] - mean );
		};
		return devSum / arr.length;
	};

	// median deviation (median absolute deviation) of an array
	jstat.meddev = function( arr ) {
		var devSum = 0,
			median = jstat.median( arr ),
			i = arr.length - 1;
		for ( ; i >= 0; i-- ) {
			devSum += Math.abs( arr[ i ] - median );
		};
		return devSum / arr.length;
	};

	// factorial of n
	jstat.factorial = function( n ) {
		var fval = 1;
		if ( n < 0 ) return NaN;
		if ( n != Math.floor( n ) ) return jstat.gamma( n + 1 );
		for( ; n > 0; n-- ) {
			fval *= n;
		};
		return fval;
	};

	// combinations of n, m
	jstat.combination = function( n, m ) {
		return ( jstat.factorial( n ) / jstat.factorial( m ) ) / jstat.factorial( n - m );
	};

	// permutations of n, m
	jstat.permutation = function( n, m ) {
		return jstat.factorial( n ) / jstat.factorial( n - m );
	};

	// gamma of x
	jstat.gamma = function( x ) {
		var v = 1,
			w;
		if ( x == Math.floor( x ) ) return jstat.factorial( x - 1 );
		while ( x < 8 ) {
			v *= x;
			x++;
		};
		w = 1 / (x * x);
		return Math.exp((((((((-3617 / 122400 * w + 7 / 1092) * w - 691 / 360360) * w + 5 / 5940) * w - 1 / 1680)  * w + 1 / 1260) * w - 1 / 360) * w + 1 / 12) / x + 0.5 * Math.log(2 * Math.PI) - Math.log(v) - x + (x - 0.5) * Math.log(x));
	};

	// quartiles of an array
	jstat.quartiles = function( arr ) {
		var arrlen = arr.length,
			_arr = arr.slice().sort( ascNum );
		return [ _arr[ Math.round( ( arrlen ) / 4 ) - 1 ], _arr[ Math.round( ( arrlen ) / 2 ) - 1 ], _arr[ Math.round( ( arrlen ) * 3 / 4 ) - 1 ] ];
	};

	// covariance of two arrays
	jstat.covariance = function( arr1, arr2 ) {
		var u = jstat.mean( arr1 ),
			v = jstat.mean( arr2 ),
			sq_dev = [],
			arr1Len = arr1.length,
			i = 0;
		for ( ; i < arr1Len; i++ ) {
			sq_dev[ i ] = ( arr1[ i ] - u ) * ( arr2[ i ] - v );
		};
		return jstat.sum( sq_dev ) / arr1Len;
	};

	// correlation coefficient of two arrays
	jstat.corrcoeff = function( arr1, arr2 ) {
		return jstat.covariance( arr1, arr2 ) / jstat.stdev( arr1 ) / jstat.stdev( arr2 );
	};

	// probability of uniform distibution
	jstat.uniformcdf = function( a, b, x ) {
		if ( x < a ) {
			return 0;
		} else if ( x < b ) {
			return ( x - a ) / ( b - a );
		};
		return 1;
	};

	// probability of binomial distribution
	jstat.binomial = function( n, p, k ) {
		return jstat.combination( n, k ) * Math.pow( p, k ) * Math.pow( 1 - p, n - k );
	};

	// probability of binomial cdf distribution
	jstat.binomialcdf = function( n, p, x ) {
		var binomarr = [],
			k = 0,
			i = 0,
			sum = 0;
		if ( x < 0 ) {
			return 0;
		};
		for ( ; k < n; k++ ) {
			binomarr[k] = jstat.binomial(n, p, k);
		};
		if ( x < n ) {
			for ( ; i <= x; i++ ) {
				sum += binomarr[ i ];
			};
			return sum;
		};
		return 1;
	};

	// weibull distribution of x
	jstat.weibull = function( x, a, b ) {
		return x < 0 ? 0 : ( a / b ) * Math.pow(( x / b ),( a - 1 )) * Math.exp(-( Math.pow(( x / b ), a )));
	};

	// cumulative probability of x for weibull distibution
	jstat.weibullcdf = function( x, a, b ) {
		return x < 0 ? 0 : 1 - Math.exp( Math.pow(-( x / b ), a ));
	};

	// probability of exact success
	jstat.negbin = function( r, p, x ) {
		return x !== Math.floor( x )
			? false
		: x < 0
			? 0
		: jstat.combination( x + r - 1, r - 1 ) * Math.pow( p, r ) * Math.pow( 1 - p, x );
	};

	// probability of cdf success
	jstat.negbincdf = function( n, p, x ) {
		var sum = 0,
			k = 0;
		if ( x < 0 ) return 0;
		for ( ; k <= x; k++ ) {
			sum += jstat.negbin( n, p, k );
		};
		return sum;
	};

	// probability of selection
	jstat.hypgeom = function( N, m, n, x ) {
		return x !== Math.floor( x )
			? false
		: ( x < 0)
			? 0
		: jstat.combination( m, x ) * jstat.combination(( N - m ), n - x ) / jstat.combination( N, n );
	};

	// probability of cdf selection
	jstat.hypgeomcdf = function( N, m, n, x ) {
		var sum = 0,
			k = 0;
		if ( x < 0 ) return 0;
		for ( ; k <= x; k++ ) {
			sum += jstat.hypgeom( N, m, n, k );
		};
		return sum;
	};

	// probability an exponentially distributed variable with parameter
	jstat.exponentialcdf = function( l, x ) {
		return 1 - Math.exp( -l * x );
	};

	// probability a possion variable with parameter
	jstat.poisson = function( l, x ) {
		return Math.pow( l, x ) * Math.exp( -l ) / jstat.factorial( x );
	};

	// calculate cumulative poisson distribution cumulative probability with parameter
	jstat.poissoncdf = function( l, x ) {
		var sum = 0,
			k = 0;
		if ( x < 0 ) return 0;
		for ( ; k <= x; k++ ) {
			sum += jstat.poisson( l, k );
		};
		return sum;
	};

	// calcualte sum of f(x) from a to b
	jstat.sumFunc = function( a, b, func ) {
		var sum = 0;
		while ( a <= b ) {
			sum += func( a++ );
		};
		return sum;
	}

	// exposing jstat
	_this.jstat = jstat;

// passing this for Node.js modules compatibility
})( Math, this );
<commit_msg>no need for the extra indent<commit_after>/**
 * jStat - JavaScript Statistical Library
 * Copyright (c) 2011
 * This document is licensed as free software under the terms of the
 * MIT License: http://www.opensource.org/licenses/mit-license.php */
(function( Math, _this, undefined ) {

// global function
var jstat = function() {
		return new jstat.fn.init( slice.call( arguments ));
	},

	// for quick reference
	slice = Array.prototype.slice,
	toString = Object.prototype.toString,

	// ascending/descending functions for sort
	ascNum = function( a, b ) { return a - b; },
	descNum = function( a, b ) { return b - a; },

	// test if array
	isArray = function( arg ) {
		return toString.call( arg ) === "[object Array]";
	},

	// test if function
	isFunction = function( arg ) {
		return toString.call( arg ) === "[object Function]";
	},

	// simple method to run functions in setTimeout
	callLater = function( func, context, values ) {
		setTimeout( function() {
			func.apply( context, values );
		}, 10 );
	};

jstat.fn = jstat.prototype = {
	constructor : jstat,
	init : function( args ) {

		// if first argument is an array, must be vector or matrix
		if ( isArray( args[0] )) {
			for ( var i = 0; i < args.length; i++ ) {
				this.push( args[i] );
			};

		// if first argument is number, assume creation of sequence
		} else if ( !isNaN( args[0] )) {
			this.push( jstat.seq.apply( this, args ));
		};
		return this;
	},

	// default length
	length : 0,

	// return clean array
	toArray : function() {
		return slice.call( this, 0 );
	},

	// only to be used internally
	push : Array.prototype.push,
	sort : [].sort,
	splice : [].splice
};
jstat.fn.init.prototype = jstat.fn;

// TODO: there's got to be an easy way to combine these two
// create method for easy extension
jstat.extend = function( obj ) {
	for ( var i in obj ) {
		jstat[i] = obj[i];
	};
	return this;
};
jstat.fn.extend = function( obj ) {
	for ( var i in obj ) {
		jstat.fn[i] = obj[i];
	};
	return this;
};

// extend jstat.fn with applicable static methods
(function( funcs ) {
	funcs = funcs.split( ' ' );
	for ( var i = 0; i < funcs.length; i++ ) (function( passfunc ) {
		jstat.fn[ funcs[i] ] = function( func ) {
			for ( var i = 0; i < this.length; i++ ) {
				callLater( func, jstat( this[i] ), [ jstat[ passfunc ]( this[i] )]);
			};
			return this;
		};
	})( funcs[i] );
})( 'sum min max mean median mode range variance stdev meandev meddev quartiles' );

// extend jstat.fn
jstat.fn.extend({
	seq : function( start, count, func ) {
		this.push( jstat.seq( start, count, func ));
		return this;
	}
});

// static methods are beyone this line //

// generate sequence
jstat.seq = function( start, count, func ) {
	var arr = [], i = 0;
	if ( count > 0 ) {
		for ( ; i < count; i++ ) arr.push( func ? func.call( this, start++ ) : start++ );
	} else {
		for ( ; i > count; i-- ) arr.push( start-- );
	};
	return arr;
};

// sum of an array
jstat.sum = function( arr ) {
	var sum = 0,
		i = arr.length;
	while ( --i >= 0 ) {
		sum += arr[i];
	};
	return sum;
};

// minimum value of an array
jstat.min = function( arr ) {
	return Math.min.apply( null, arr );
};

// maximum value of an array
jstat.max = function( arr ) {
	return Math.max.apply( null, arr );
};

// mean value of an array
jstat.mean = function( arr ) {
	return jstat.sum( arr ) / arr.length;
};

// median of an array
jstat.median = function( arr ) {
	var arrlen = arr.length,
		_arr = arr.slice().sort( ascNum );

	// check if array is even or odd, then return the appropriate
	return !( arrlen & 1 ) ? ( _arr[ ( arrlen / 2 ) - 1 ] + _arr[ ( arrlen / 2 ) ] ) / 2 : _arr[ Math.floor( arrlen / 2 ) ];
};

// mode of an array
jstat.mode = function( arr ) {
	var arrLen = arr.length,
		_arr = arr.slice().sort( ascNum ),
		count = 1,
		maxCount = 0,
		numMaxCount = 0,
		i = 0,
		maxNum;
	for ( ; i < arrLen; i++ ) {
		if ( _arr[ i ] === _arr[ i + 1 ] ) {
			count++;
		} else {
			if ( count > maxCount ) {
				maxNum = _arr[i];
				maxCount = count;
				count = 1;
				numMaxCount = 0;
			} else {

				// are there multiple max counts
				if ( count === maxCount ) {
					numMaxCount++;

				// count is less than max count, so reset values
				} else {
					count = 1;
				};
			};
		};
	};

	return ( numMaxCount === 0 ) ? maxNum : false;
};

// range of an array
jstat.range = function( arr ) {
	var _arr = arr.slice().sort( ascNum );
	return _arr[ _arr.length - 1 ] - _arr[0];
};

// variance of an array
jstat.variance = function( arr ) {
	var mean = jstat.mean( arr ),
		stSum = 0,
		i = arr.length - 1;
	for( ; i >= 0; i-- ) {
		stSum += Math.pow( ( arr[i] - mean ), 2 );
	};
	return stSum / ( arr.length - 1 );
};

// standard deviation of an array
jstat.stdev = function( arr ) {
	return Math.sqrt( jstat.variance( arr ) );
};

// mean deviation (mean absolute deviation) of an array
jstat.meandev = function( arr ) {
	var devSum = 0,
		mean = jstat.mean( arr ),
		i = arr.length - 1;
	for ( ; i >= 0; i-- ) {
		devSum += Math.abs( arr[ i ] - mean );
	};
	return devSum / arr.length;
};

// median deviation (median absolute deviation) of an array
jstat.meddev = function( arr ) {
	var devSum = 0,
		median = jstat.median( arr ),
		i = arr.length - 1;
	for ( ; i >= 0; i-- ) {
		devSum += Math.abs( arr[ i ] - median );
	};
	return devSum / arr.length;
};

// factorial of n
jstat.factorial = function( n ) {
	var fval = 1;
	if ( n < 0 ) return NaN;
	if ( n != Math.floor( n ) ) return jstat.gamma( n + 1 );
	for( ; n > 0; n-- ) {
		fval *= n;
	};
	return fval;
};

// combinations of n, m
jstat.combination = function( n, m ) {
	return ( jstat.factorial( n ) / jstat.factorial( m ) ) / jstat.factorial( n - m );
};

// permutations of n, m
jstat.permutation = function( n, m ) {
	return jstat.factorial( n ) / jstat.factorial( n - m );
};

// gamma of x
jstat.gamma = function( x ) {
	var v = 1,
		w;
	if ( x == Math.floor( x ) ) return jstat.factorial( x - 1 );
	while ( x < 8 ) {
		v *= x;
		x++;
	};
	w = 1 / (x * x);
	return Math.exp((((((((-3617 / 122400 * w + 7 / 1092) * w - 691 / 360360) * w + 5 / 5940) * w - 1 / 1680)  * w + 1 / 1260) * w - 1 / 360) * w + 1 / 12) / x + 0.5 * Math.log(2 * Math.PI) - Math.log(v) - x + (x - 0.5) * Math.log(x));
};

// quartiles of an array
jstat.quartiles = function( arr ) {
	var arrlen = arr.length,
		_arr = arr.slice().sort( ascNum );
	return [ _arr[ Math.round( ( arrlen ) / 4 ) - 1 ], _arr[ Math.round( ( arrlen ) / 2 ) - 1 ], _arr[ Math.round( ( arrlen ) * 3 / 4 ) - 1 ] ];
};

// covariance of two arrays
jstat.covariance = function( arr1, arr2 ) {
	var u = jstat.mean( arr1 ),
		v = jstat.mean( arr2 ),
		sq_dev = [],
		arr1Len = arr1.length,
		i = 0;
	for ( ; i < arr1Len; i++ ) {
		sq_dev[ i ] = ( arr1[ i ] - u ) * ( arr2[ i ] - v );
	};
	return jstat.sum( sq_dev ) / arr1Len;
};

// correlation coefficient of two arrays
jstat.corrcoeff = function( arr1, arr2 ) {
	return jstat.covariance( arr1, arr2 ) / jstat.stdev( arr1 ) / jstat.stdev( arr2 );
};

// probability of uniform distibution
jstat.uniformcdf = function( a, b, x ) {
	if ( x < a ) {
		return 0;
	} else if ( x < b ) {
		return ( x - a ) / ( b - a );
	};
	return 1;
};

// probability of binomial distribution
jstat.binomial = function( n, p, k ) {
	return jstat.combination( n, k ) * Math.pow( p, k ) * Math.pow( 1 - p, n - k );
};

// probability of binomial cdf distribution
jstat.binomialcdf = function( n, p, x ) {
	var binomarr = [],
		k = 0,
		i = 0,
		sum = 0;
	if ( x < 0 ) {
		return 0;
	};
	for ( ; k < n; k++ ) {
		binomarr[k] = jstat.binomial(n, p, k);
	};
	if ( x < n ) {
		for ( ; i <= x; i++ ) {
			sum += binomarr[ i ];
		};
		return sum;
	};
	return 1;
};

// weibull distribution of x
jstat.weibull = function( x, a, b ) {
	return x < 0 ? 0 : ( a / b ) * Math.pow(( x / b ),( a - 1 )) * Math.exp(-( Math.pow(( x / b ), a )));
};

// cumulative probability of x for weibull distibution
jstat.weibullcdf = function( x, a, b ) {
	return x < 0 ? 0 : 1 - Math.exp( Math.pow(-( x / b ), a ));
};

// probability of exact success
jstat.negbin = function( r, p, x ) {
	return x !== Math.floor( x )
		? false
	: x < 0
		? 0
	: jstat.combination( x + r - 1, r - 1 ) * Math.pow( p, r ) * Math.pow( 1 - p, x );
};

// probability of cdf success
jstat.negbincdf = function( n, p, x ) {
	var sum = 0,
		k = 0;
	if ( x < 0 ) return 0;
	for ( ; k <= x; k++ ) {
		sum += jstat.negbin( n, p, k );
	};
	return sum;
};

// probability of selection
jstat.hypgeom = function( N, m, n, x ) {
	return x !== Math.floor( x )
		? false
	: ( x < 0)
		? 0
	: jstat.combination( m, x ) * jstat.combination(( N - m ), n - x ) / jstat.combination( N, n );
};

// probability of cdf selection
jstat.hypgeomcdf = function( N, m, n, x ) {
	var sum = 0,
		k = 0;
	if ( x < 0 ) return 0;
	for ( ; k <= x; k++ ) {
		sum += jstat.hypgeom( N, m, n, k );
	};
	return sum;
};

// probability an exponentially distributed variable with parameter
jstat.exponentialcdf = function( l, x ) {
	return 1 - Math.exp( -l * x );
};

// probability a possion variable with parameter
jstat.poisson = function( l, x ) {
	return Math.pow( l, x ) * Math.exp( -l ) / jstat.factorial( x );
};

// calculate cumulative poisson distribution cumulative probability with parameter
jstat.poissoncdf = function( l, x ) {
	var sum = 0,
		k = 0;
	if ( x < 0 ) return 0;
	for ( ; k <= x; k++ ) {
		sum += jstat.poisson( l, k );
	};
	return sum;
};

// calcualte sum of f(x) from a to b
jstat.sumFunc = function( a, b, func ) {
	var sum = 0;
	while ( a <= b ) {
		sum += func( a++ );
	};
	return sum;
}

// exposing jstat
_this.jstat = jstat;

// passing this for Node.js modules compatibility
})( Math, this );
<|endoftext|>


<commit_before>var app = require('cantina')
  , http = require('http');

// Default conf.
app.conf.add({
  web: {
    server: {
      port: 3000
    }
  }
});

// Create server.
if (!app.server) {
  app.server = http.createServer();

  // When the app starts, start listening.
  app.hook('start').last(1000, function (next) {
    var conf = app.conf.get('web:server');
    if (!app.server.address() && conf.port) {
      app.server.listen(conf.port, function () {
        var address = app.server.address();
        app.log('Listening on ' + address.address + ':' + address.port);
        app.emit('listening');
        next();
      });
    }
    else {
      next();
    }
  });

  // When the app is being destroyed, close the server.
  app.hook('destroy').last(1000, function (next) {
    app.server.close(next);
  });
}
<commit_msg>Allow port 0.<commit_after>var app = require('cantina')
  , http = require('http');

// Default conf.
app.conf.add({
  web: {
    server: {
      port: 3000
    }
  }
});

// Create server.
if (!app.server) {
  app.server = http.createServer();

  // When the app starts, start listening.
  app.hook('start').last(1000, function (next) {
    var conf = app.conf.get('web:server');
    if (!app.server.address() && (typeof conf.port !== 'undefined')) {
      app.server.listen(conf.port, function () {
        var address = app.server.address();
        app.log('Listening on ' + address.address + ':' + address.port);
        app.emit('listening');
        next();
      });
    }
    else {
      next();
    }
  });

  // When the app is being destroyed, close the server.
  app.hook('destroy').last(1000, function (next) {
    app.server.close(next);
  });
}
<|endoftext|>


<commit_before>var document   = window.document
  , _tire      = window.tire
  , _$         = window.$
  , idExp      = /^#/
  , simpleExp  = /^#?([\w-]+)$/
  , classExp   = /^\./
  , tagExp     = /<([\w:]+)/
  , slice      = [].slice;

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function (array, from, to) {
  var rest = array.slice((to || from) + 1 || array.length);
  array.length = from < 0 ? array.length + from : from;
  return array.push.apply(array, rest);
};

// If forEach isn't available we provied a backup
if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(fn, scope) {
    for(var i = 0, len = this.length; i < len; ++i) {
      fn.call(scope || this, this[i], i, this);
    }
  };
}

// If slice is not available we provide a backup
try {
  slice.call(document.documentElement.childNodes, 0)[0].nodeType;
} catch(e) {
  slice = function (i) {
    var elem, results = [];
    for (; (elem = this[i]); i++ ) {
      results.push( elem );
    }
    return results;
  };
}

var tire = function (selector, context) {
  return new tire.fn.find(selector, context);
};

tire.fn = tire.prototype = {

  /**
   * Default length is zero
   */

  length: 0,

  /**
   * Extend `tire.fn`
   *
   * @param {Object} o
   */

  extend: function (o) {
    for (var k in o) {
      this[k] = o[k];
    }
  },

  /**
   * Find elements by selector
   *
   * @param {String|Object|Function} selector
   * @param {Object} context
   *
   * @return {Object}
   */

  find: function (selector, context) {
    var elms = [];

    if (!selector) {
      return this;
    }

    if (tire.isFun(selector)) {
      tire.ready(selector);
    }

    if (selector.nodeType) {
      this.selector = '';
      this.context = selector;
      return this.set([selector]);
    }

    if (selector.length === 1 && selector[0].nodeType) {
      this.selector = selector.selector;
      this.context = selector[0];
      return this.set(selector);
    }

    this.context = context = (context || document);

    if (tire.isStr(selector)) {
      this.selector = selector;
      if (simpleExp.test(selector)) {
        elms = slice.call(idExp.test(selector) ? [document.getElementById(selector.substr(1))] : document.getElementsByTagName(selector), 0);
        if (elms[0] === null) {
          elms = [];
        }
      } else if (classExp.test(selector) && document.getElementsByClassName !== undefined) {
        elms = slice.call(document.getElementsByClassName(selector.substr(1)), 0);
        if (elms[0] === null) {
          elms = [];
        }
      } else if (tagExp.test(selector)) {
        var tmp = document.createElement('div');
        tmp.innerHTML = selector;
        this.each.call(slice.call(tmp.childNodes, 0), function () {
          elms.push(this);
        });
      } else {
        if (window.Sizzle !== undefined) {
          elms = Sizzle(selector, context);
        } else {
          elms = document.querySelectorAll(selector);
        }
      }
    } else  if (selector.nodeName || selector === window) {
      elms = [selector];
    }

    return this.set(elms);
  },

  pluck: function (prop) {
    var result = [];
    this.each(function () {
      if (this[prop]) result.push(this[prop]);
    });
    return result;
  },

  /**
   * Reduce the set of matched elements to a subset specified by a range of indices.
   *
   * @return {Object}
   */

  slice: function () {
    return this.set(slice.apply(this, arguments));
  },

  /**
   * Run callback for each element in the collection
   *
   * @param {Object} target
   * @param {Function} callback
   * @return {Object}
   */

  each: function(target, callback) {
    if (tire.isFun(target)) {
      callback = target;
      target = this;
    }

    for (var i = 0, len = target.length; i < len; ++i) {
        if (callback.call(target[i], target[i], i, target) === false)
        break;
    }

    return target;
  },

  /**
   * Set elements to tire object before returning `this`
   *
   * @param {Array} elements
   * @return {Object}
   */

  set: function (elements) {
    var i = 0;
    for (; i < elements.length; i++) {
      this[i] = elements[i];
    }
    this.length = i;
    return this;
  }
};

/**
 * Extend `tire` with arguments, if the arguments length is one the extend target is `tire`
 */

tire.extend = function () {
  var options
    , i = 1
    , target = arguments[0] || {};

  if (typeof target !== 'object' && typeof target !== 'function') {
    target = {};
  }

  if (arguments.length === 1) {
    target = this;
    i = 0;
  }

  for (; i < arguments.length; i++) {
    if ((options = arguments[i]) !== null) {
      for (var key in options) {
        if (target[key] === options[key]) {
          continue;
        } else {
          target[key] = options[key];
        }
      }
    }
  }

  return target;
};

tire.fn.find.prototype = tire.fn;

tire.extend({

  /**
   * Trim string
   *
   * @param {String} str
   * @return {String}
   */

  trim: function (str) {
    return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
  },

  /**
   * Check if the element matches the selector
   *
   * @param {Object} element
   * @param {String} selector
   * @return {Boolean}
   */

  matches: function (element, selector) {
    if (!element || element.nodeType !== 1) return;

    // Trying to use matchesSelector if it is available
    var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector || element.matchesSelector;
    if (matchesSelector) {
      return matchesSelector.call(element, selector);
    }

    // Trying to use Sizzle's matchesSelector if it is available
    if (window.Sizzle !== undefined) {
      return window.Sizzle.matchesSelector(element, selector);
    }

    // querySelectorAll fallback
    if (document.querySelectorAll !== undefined) {
      var nodes = element.parentNode.querySelectorAll(selector);

      for (var i = 0; i < nodes.length; i++) {
        if (nodes[i] === element) return true;
      }

      return false;
    }
  },

  /**
   * Check if the object is a function
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isFun: function (obj) {
    return typeof obj === 'function';
  },

  /**
   * Check if the object is a array
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isArr: function (obj) {
    return obj instanceof Array;
  },

  /**
   * Check if the object is a string
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isStr: function (obj) {
    return typeof obj === 'string';
  },

  /**
   * Check if the object is a boolean
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isBool: function (obj) {
    return (obj === true) || (obj === false);
  },

  /**
   * Check if the object is a number
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isNum: function (obj) {
    return typeof obj === 'number';
  },

  /**
   * Check if the object is a object
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isObj: function (obj) {
    return obj instanceof Object;
  },

  /**
   * Parse JSON string to object.
   *
   * @param {String} str
   * @return {Object|null)
   */

  parseJSON: function (str) {
    if (!this.isStr || !str) {
      return null;
    }

    str = this.trim(str);

    if (window.JSON && window.JSON.parse) {
      return window.JSON.parse(str);
    }
  },

  /**
   * Calling .noConflict will restore the window.$` to its previous value.
   *
   * @param {Boolean} name Restore `tire` to it's previous value.
   * @return {Object}
   */

  noConflict: function (name) {
    if (name) {
      window.tire = _tire;
    }

    window.$ = _$;
    return tire;
  }
});<commit_msg>adding comment to pluck function<commit_after>var document   = window.document
  , _tire      = window.tire
  , _$         = window.$
  , idExp      = /^#/
  , simpleExp  = /^#?([\w-]+)$/
  , classExp   = /^\./
  , tagExp     = /<([\w:]+)/
  , slice      = [].slice;

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function (array, from, to) {
  var rest = array.slice((to || from) + 1 || array.length);
  array.length = from < 0 ? array.length + from : from;
  return array.push.apply(array, rest);
};

// If forEach isn't available we provied a backup
if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(fn, scope) {
    for(var i = 0, len = this.length; i < len; ++i) {
      fn.call(scope || this, this[i], i, this);
    }
  };
}

// If slice is not available we provide a backup
try {
  slice.call(document.documentElement.childNodes, 0)[0].nodeType;
} catch(e) {
  slice = function (i) {
    var elem, results = [];
    for (; (elem = this[i]); i++ ) {
      results.push( elem );
    }
    return results;
  };
}

var tire = function (selector, context) {
  return new tire.fn.find(selector, context);
};

tire.fn = tire.prototype = {

  /**
   * Default length is zero
   */

  length: 0,

  /**
   * Extend `tire.fn`
   *
   * @param {Object} o
   */

  extend: function (o) {
    for (var k in o) {
      this[k] = o[k];
    }
  },

  /**
   * Find elements by selector
   *
   * @param {String|Object|Function} selector
   * @param {Object} context
   *
   * @return {Object}
   */

  find: function (selector, context) {
    var elms = [];

    if (!selector) {
      return this;
    }

    if (tire.isFun(selector)) {
      tire.ready(selector);
    }

    if (selector.nodeType) {
      this.selector = '';
      this.context = selector;
      return this.set([selector]);
    }

    if (selector.length === 1 && selector[0].nodeType) {
      this.selector = selector.selector;
      this.context = selector[0];
      return this.set(selector);
    }

    this.context = context = (context || document);

    if (tire.isStr(selector)) {
      this.selector = selector;
      if (simpleExp.test(selector)) {
        elms = slice.call(idExp.test(selector) ? [document.getElementById(selector.substr(1))] : document.getElementsByTagName(selector), 0);
        if (elms[0] === null) {
          elms = [];
        }
      } else if (classExp.test(selector) && document.getElementsByClassName !== undefined) {
        elms = slice.call(document.getElementsByClassName(selector.substr(1)), 0);
        if (elms[0] === null) {
          elms = [];
        }
      } else if (tagExp.test(selector)) {
        var tmp = document.createElement('div');
        tmp.innerHTML = selector;
        this.each.call(slice.call(tmp.childNodes, 0), function () {
          elms.push(this);
        });
      } else {
        if (window.Sizzle !== undefined) {
          elms = Sizzle(selector, context);
        } else {
          elms = document.querySelectorAll(selector);
        }
      }
    } else  if (selector.nodeName || selector === window) {
      elms = [selector];
    }

    return this.set(elms);
  },

  /**
   * Fetch property from elements
   *
   * @param {String} prop
   * @return {Array}
   */

  pluck: function (prop) {
    var result = [];
    this.each(function () {
      if (this[prop]) result.push(this[prop]);
    });
    return result;
  },

  /**
   * Reduce the set of matched elements to a subset specified by a range of indices.
   *
   * @return {Object}
   */

  slice: function () {
    return this.set(slice.apply(this, arguments));
  },

  /**
   * Run callback for each element in the collection
   *
   * @param {Object} target
   * @param {Function} callback
   * @return {Object}
   */

  each: function(target, callback) {
    if (tire.isFun(target)) {
      callback = target;
      target = this;
    }

    for (var i = 0, len = target.length; i < len; ++i) {
        if (callback.call(target[i], target[i], i, target) === false)
        break;
    }

    return target;
  },

  /**
   * Set elements to tire object before returning `this`
   *
   * @param {Array} elements
   * @return {Object}
   */

  set: function (elements) {
    var i = 0;
    for (; i < elements.length; i++) {
      this[i] = elements[i];
    }
    this.length = i;
    return this;
  }
};

/**
 * Extend `tire` with arguments, if the arguments length is one the extend target is `tire`
 */

tire.extend = function () {
  var options
    , i = 1
    , target = arguments[0] || {};

  if (typeof target !== 'object' && typeof target !== 'function') {
    target = {};
  }

  if (arguments.length === 1) {
    target = this;
    i = 0;
  }

  for (; i < arguments.length; i++) {
    if ((options = arguments[i]) !== null) {
      for (var key in options) {
        if (target[key] === options[key]) {
          continue;
        } else {
          target[key] = options[key];
        }
      }
    }
  }

  return target;
};

tire.fn.find.prototype = tire.fn;

tire.extend({

  /**
   * Trim string
   *
   * @param {String} str
   * @return {String}
   */

  trim: function (str) {
    return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
  },

  /**
   * Check if the element matches the selector
   *
   * @param {Object} element
   * @param {String} selector
   * @return {Boolean}
   */

  matches: function (element, selector) {
    if (!element || element.nodeType !== 1) return;

    // Trying to use matchesSelector if it is available
    var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector || element.matchesSelector;
    if (matchesSelector) {
      return matchesSelector.call(element, selector);
    }

    // Trying to use Sizzle's matchesSelector if it is available
    if (window.Sizzle !== undefined) {
      return window.Sizzle.matchesSelector(element, selector);
    }

    // querySelectorAll fallback
    if (document.querySelectorAll !== undefined) {
      var nodes = element.parentNode.querySelectorAll(selector);

      for (var i = 0; i < nodes.length; i++) {
        if (nodes[i] === element) return true;
      }

      return false;
    }
  },

  /**
   * Check if the object is a function
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isFun: function (obj) {
    return typeof obj === 'function';
  },

  /**
   * Check if the object is a array
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isArr: function (obj) {
    return obj instanceof Array;
  },

  /**
   * Check if the object is a string
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isStr: function (obj) {
    return typeof obj === 'string';
  },

  /**
   * Check if the object is a boolean
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isBool: function (obj) {
    return (obj === true) || (obj === false);
  },

  /**
   * Check if the object is a number
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isNum: function (obj) {
    return typeof obj === 'number';
  },

  /**
   * Check if the object is a object
   *
   * @param {Object} obj
   * @return {Boolean}
   */

  isObj: function (obj) {
    return obj instanceof Object;
  },

  /**
   * Parse JSON string to object.
   *
   * @param {String} str
   * @return {Object|null)
   */

  parseJSON: function (str) {
    if (!this.isStr || !str) {
      return null;
    }

    str = this.trim(str);

    if (window.JSON && window.JSON.parse) {
      return window.JSON.parse(str);
    }
  },

  /**
   * Calling .noConflict will restore the window.$` to its previous value.
   *
   * @param {Boolean} name Restore `tire` to it's previous value.
   * @return {Object}
   */

  noConflict: function (name) {
    if (name) {
      window.tire = _tire;
    }

    window.$ = _$;
    return tire;
  }
});<|endoftext|>


<commit_before>import settings from './settings';
import viewer from './viewer';

let prevTime;
let frames = 0;
let fps = 60;
let lastFps = 60;
let steadyCount = 0;
let hidden = false;
let cullDistance = settings.cullDistance;
let fogNear = settings.fogNear;

document.addEventListener('visibilitychange', () => {
  hidden = document.hidden;
});

export default (interval = 3000) => {
  if (hidden) {
    prevTime = null;
    frames = 0;
    return fps;
  }
  frames++;
  const time = (performance || Date).now();
  if (prevTime == null) prevTime = time;
  if (time > prevTime + interval) {
    fps = (frames * 1000) / (time - prevTime);
    fps = Math.min(55, Math.round(fps * 0.2) * 5);
    frames = 0;
    prevTime = time;

    if (fps === lastFps) {
      steadyCount++;
    } else {
      steadyCount = 0;
    }
    lastFps = fps;
    const lastCullDistance = cullDistance;
    if (fps < 55) {
      cullDistance = Math.max(
        settings.minCullDistance,
        cullDistance - settings.roomDepth
      );
    } else {
      cullDistance = Math.min(
        settings.maxCullDistance,
        cullDistance + settings.roomDepth * 2
      );
    }
    fogNear = settings.cullDistance - settings.roomDepth;
    if (lastCullDistance !== cullDistance) {
      console.log('Changed cull distance to', cullDistance);
    }
  }
  settings.cullDistance = settings.cullDistance * 0.95 + cullDistance * 0.05;
  settings.fogNear = settings.fogNear * 0.95 + fogNear * 0.05;
  viewer.fog.near = settings.fogNear;
  return fps;
};
<commit_msg>less aggressive culling, less pop in/out fighting<commit_after>import settings from './settings';
import viewer from './viewer';

let prevTime;
let frames = 0;
let fps = 60;
let lastFps = 60;
let steadyCount = 0;
let hidden = false;
let cullDistance = settings.cullDistance;
let fogNear = settings.fogNear;

document.addEventListener('visibilitychange', () => {
  hidden = document.hidden;
});

export default (interval = 3000) => {
  if (hidden) {
    prevTime = null;
    frames = 0;
    return fps;
  }
  frames++;
  const time = (performance || Date).now();
  if (prevTime == null) prevTime = time;
  if (time > prevTime + interval) {
    fps = (frames * 1000) / (time - prevTime);
    fps = Math.min(55, Math.round(fps * 0.2) * 5);
    frames = 0;
    prevTime = time;

    if (fps === lastFps) {
      steadyCount++;
    } else {
      steadyCount = 0;
    }
    lastFps = fps;
    const lastCullDistance = cullDistance;
    if (fps < 52) {
      cullDistance = Math.max(
        settings.minCullDistance,
        cullDistance - settings.roomDepth
      );
    } else {
      cullDistance = Math.min(
        settings.maxCullDistance,
        cullDistance + settings.roomDepth
      );
    }
    fogNear = settings.cullDistance - settings.roomDepth;
    if (lastCullDistance !== cullDistance) {
      console.log('Changed cull distance to', cullDistance);
    }
  }
  settings.cullDistance = settings.cullDistance * 0.95 + cullDistance * 0.05;
  settings.fogNear = settings.fogNear * 0.95 + fogNear * 0.05;
  viewer.fog.near = settings.fogNear;
  return fps;
};
<|endoftext|>


<commit_before>import settings from './settings';
import viewer from './viewer';

let prevTime;
let frames = 0;
let fps = 60;
let hidden = false;
let cullDistance = settings.cullDistance;
const logging = false;

document.addEventListener('visibilitychange', () => {
  hidden = document.hidden;
});

export default {
  tick: (interval = 3000) => {
    if (hidden) {
      prevTime = null;
      frames = 0;
      return fps;
    }
    frames++;
    const time = (performance || Date).now();
    if (prevTime == null) prevTime = time;
    if (time > prevTime + interval) {
      fps = (frames * 1000) / (time - prevTime);
      // Change FPS to multiples of 50 in order to ignore slight fluctuations:
      fps = Math.min(55, Math.round(fps * 0.2) * 5);
      frames = 0;
      prevTime = time;
      const lastCullDistance = settings.cullDistance;
      settings.cullDistance = fps <= 50
        ? Math.max(
          settings.minCullDistance,
          settings.cullDistance - settings.roomDepth
        )
        : Math.min(
          settings.maxCullDistance,
          settings.cullDistance + settings.roomDepth
        );
      if (logging && lastCullDistance !== settings.cullDistance) {
        console.log(`${lastCullDistance > settings.cullDistance ? 'Lowering' : 'Upping'} cull distance to`, settings.cullDistance);
      }
    }
    cullDistance = cullDistance * 0.95 + settings.cullDistance * 0.05;
    if (viewer.isOrthographic) {
      viewer.fog.near = settings.maxCullDistance;
      viewer.fog.far = settings.maxCullDistance;
    } else if (!viewer.isInsideTransition) {
      viewer.fog.near = cullDistance - settings.roomDepth;
      viewer.fog.far = cullDistance;
    }
  },

  setDistance: (distance) => {
    settings.cullDistance = cullDistance = distance;
  },

  reset: () => {
    prevTime = null;
    frames = 0;
  },
};
<commit_msg>more stable room culling -less on/off when in the 50 fps range<commit_after>import settings from './settings';
import viewer from './viewer';

let prevTime;
let frames = 0;
let fps = 60;
let hidden = false;
let cullDistance = settings.cullDistance;
const logging = false;

document.addEventListener('visibilitychange', () => {
  hidden = document.hidden;
});

export default {
  tick: (interval = 3000) => {
    if (hidden) {
      prevTime = null;
      frames = 0;
      return fps;
    }
    frames++;
    const time = (performance || Date).now();
    if (prevTime == null) prevTime = time;
    if (time > prevTime + interval) {
      fps = (frames * 1000) / (time - prevTime);
      // Change FPS to multiples of 2.5 in order to ignore slight fluctuations:
      fps = Math.min(55, Math.round(fps * 0.4) * 2.5);
      frames = 0;
      prevTime = time;
      const lastCullDistance = settings.cullDistance;

      // if the fps is between 50 and 55, don't do anything
      if (fps < 50) {
        settings.cullDistance = Math.max(
          settings.minCullDistance,
          settings.cullDistance - settings.roomDepth
        )
      } else if (fps >= 55) {
        settings.cullDistance = Math.min(
          settings.maxCullDistance,
          settings.cullDistance + settings.roomDepth
        )
      }
      if (logging && lastCullDistance !== settings.cullDistance) {
        console.log(`${lastCullDistance > settings.cullDistance ? 'Lowering' : 'Upping'} cull distance to`, settings.cullDistance);
      }
    }
    cullDistance = cullDistance * 0.95 + settings.cullDistance * 0.05;
    if (viewer.isOrthographic) {
      viewer.fog.near = settings.maxCullDistance;
      viewer.fog.far = settings.maxCullDistance;
    } else if (!viewer.isInsideTransition) {
      viewer.fog.near = cullDistance - settings.roomDepth;
      viewer.fog.far = cullDistance;
    }
  },

  setDistance: (distance) => {
    settings.cullDistance = cullDistance = distance;
  },

  reset: () => {
    prevTime = null;
    frames = 0;
  },
};
<|endoftext|>


<commit_before>/**
 * Created by keyvan on 8/16/16.
 */

import {v1 as neo4j} from 'neo4j-driver';
import fs from 'file-system';
import chalk from 'chalk';
import parser from 'parse-neo4j';
import {parseNeo4jInts} from './preprocess';
import {pipe, getArgs} from './util';

class Neo4jConnection {
    constructor({boltUrl, user, password} = {}) {
        this.queries = {};

        this.driver = neo4j.driver(boltUrl, neo4j.auth.basic(user, password));
        const session = this.driver.session();
        this.initialized = session.run('RETURN "Neo4j instance successfully connected."')
            .then((result) => {
                console.log(chalk.green(parser.parse(result)));
                session.close();
            })
            .catch(error => {
                console.error(
                    chalk.red('Error connecting to the Neo4j instance, check connection options'));
                console.log(error);
                throw error;
            });
    }

    addCypherQueryFile(cypherQueryFilePath) {
        this.queries[cypherQueryFilePath] = fs.readFileSync(cypherQueryFilePath, 'utf8');
    }

    executeCypher(cypherQueryFilePath, queryParams) {
        return new Promise((resolve, reject) => {
            if (!this.queries[cypherQueryFilePath])
                this.addCypherQueryFile(cypherQueryFilePath);

            const query = this.queries[cypherQueryFilePath];
            const session = this.driver.session();

            session.run(query, queryParams)
                .then(result => {
                    resolve(result);
                    session.close();
                })
                .catch(error => {
                    reject(new Error(error.fields ? JSON.stringify(error.fields[0])
                        : String(error)));
                });
        })
            .then(parser.parse);
    }
}

class Hook {
    constructor(functionOrArrayOfFunctions, procedureName, hookName) {
        this.timeout = 4000;
        this.name = hookName;
        this.procedureName = procedureName;
        if (!Array.isArray(functionOrArrayOfFunctions))
            if (typeof functionOrArrayOfFunctions === 'function')
                functionOrArrayOfFunctions = [functionOrArrayOfFunctions];
            else
                throw new Error('hook should be function or array of functions');
        this.phases = [];
        this.context = {};
        for (const func of functionOrArrayOfFunctions)
            if (typeof func === 'function')
                this.phases.push(this.asyncify(func));
            else
                throw new Error(`element ${func} in array passed as ${this.procedureName} ` +
                'lifecycle is not a function');

        this.execute = (...args) => {
            let next = Promise.resolve(args);
            for (const phase of this.phases)
                next = next.then(response => {
                    let args;
                    if (Array.isArray(response))
                        args = response;
                    else
                        args = [response];
                    return phase(...args);
                });
            return next;
        };
    }

    asyncify(func) {
        return (...args) => Promise.race([
            Promise.resolve(func.apply(this.context, args)),
            new Promise((resolve, reject) => setTimeout(() => reject('TimeOutError'), this.timeout))
        ])
            .catch((error) => {
                if (error === 'TimeOutError')
                    throw new Error(`${this.name} lifecycle of ${this.procedureName} timed out, ` +
                            'no response after 4 seconds');
                throw error;
            });
    }
}

const createProcedure = (neo4jConnection, {cypherQueryFile, check = (params, user) => true,
    preProcess = params => params, postProcess = result => result, postServe = result => result,
    name = 'createProcedure'} = {}) => {
    const checkHook = new Hook(check, name, 'check');
    const preProcessHook = new Hook(preProcess, name, 'preProcess');
    const postProcessHook = new Hook(postProcess, name, 'postProcess');
    const postServeHook = new Hook(postServe, name, 'postServe');

    return (params, user) => {
        const response = checkHook.execute(params, user)
            .then(checkPassed => {
                if (!checkPassed)
                    throw new Error('Check lifecycle hook did not pass');
                return params;
            })
            .then(pipe(parseNeo4jInts('id', 'skip', 'limit'),
                params => [params, user], preProcessHook.execute))
            .then(params => Promise.all([
                neo4jConnection.executeCypher(cypherQueryFile, params),
                Promise.resolve(params)
            ]))
            .then(([result, params]) => Promise.all([
                postProcessHook.execute(result, params),
                Promise.resolve(params)
            ]));

        response.then(([result, params]) => postServeHook.execute(result, params));
        return response.then(([result, params]) => result);
    };
};

class API {
    constructor(neo4jConnection, {method, route, allowedRoles = [], procedure,
        cypherQueryFile, check, preProcess, postProcess, postServe} = {}) {
        if (typeof procedure === 'function')
            this.response = procedure;
        else
            this.response = createProcedure(neo4jConnection,
                {cypherQueryFile, check, preProcess, postProcess, postServe, name: route});

        this.method = method;
        this.route = route;
        this.allowedRoles = allowedRoles;
        this.requiresJwtAuthentication = allowedRoles &&
            Array.isArray(allowedRoles) && allowedRoles.length > 0;
    }
}

export {Neo4jConnection, createProcedure, API};
<commit_msg>moved parseNeo4jInts('id', 'skip', 'limit') after preProcess<commit_after>/**
 * Created by keyvan on 8/16/16.
 */

import {v1 as neo4j} from 'neo4j-driver';
import fs from 'file-system';
import chalk from 'chalk';
import parser from 'parse-neo4j';
import {parseNeo4jInts} from './preprocess';
import {pipe, getArgs} from './util';

class Neo4jConnection {
    constructor({boltUrl, user, password} = {}) {
        this.queries = {};

        this.driver = neo4j.driver(boltUrl, neo4j.auth.basic(user, password));
        const session = this.driver.session();
        this.initialized = session.run('RETURN "Neo4j instance successfully connected."')
            .then((result) => {
                console.log(chalk.green(parser.parse(result)));
                session.close();
            })
            .catch(error => {
                console.error(
                    chalk.red('Error connecting to the Neo4j instance, check connection options'));
                console.log(error);
                throw error;
            });
    }

    addCypherQueryFile(cypherQueryFilePath) {
        this.queries[cypherQueryFilePath] = fs.readFileSync(cypherQueryFilePath, 'utf8');
    }

    executeCypher(cypherQueryFilePath, queryParams) {
        return new Promise((resolve, reject) => {
            if (!this.queries[cypherQueryFilePath])
                this.addCypherQueryFile(cypherQueryFilePath);

            const query = this.queries[cypherQueryFilePath];
            const session = this.driver.session();

            session.run(query, queryParams)
                .then(result => {
                    resolve(result);
                    session.close();
                })
                .catch(error => {
                    reject(new Error(error.fields ? JSON.stringify(error.fields[0])
                        : String(error)));
                });
        })
            .then(parser.parse);
    }
}

class Hook {
    constructor(functionOrArrayOfFunctions, procedureName, hookName) {
        this.timeout = 4000;
        this.name = hookName;
        this.procedureName = procedureName;
        if (!Array.isArray(functionOrArrayOfFunctions))
            if (typeof functionOrArrayOfFunctions === 'function')
                functionOrArrayOfFunctions = [functionOrArrayOfFunctions];
            else
                throw new Error('hook should be function or array of functions');
        this.phases = [];
        this.context = {};
        for (const func of functionOrArrayOfFunctions)
            if (typeof func === 'function')
                this.phases.push(this.asyncify(func));
            else
                throw new Error(`element ${func} in array passed as ${this.procedureName} ` +
                'lifecycle is not a function');

        this.execute = (...args) => {
            let next = Promise.resolve(args);
            for (const phase of this.phases)
                next = next.then(response => {
                    let args;
                    if (Array.isArray(response))
                        args = response;
                    else
                        args = [response];
                    return phase(...args);
                });
            return next;
        };
    }

    asyncify(func) {
        return (...args) => Promise.race([
            Promise.resolve(func.apply(this.context, args)),
            new Promise((resolve, reject) => setTimeout(() => reject('TimeOutError'), this.timeout))
        ])
            .catch((error) => {
                if (error === 'TimeOutError')
                    throw new Error(`${this.name} lifecycle of ${this.procedureName} timed out, ` +
                            'no response after 4 seconds');
                throw error;
            });
    }
}

const createProcedure = (neo4jConnection, {cypherQueryFile, check = (params, user) => true,
    preProcess = params => params, postProcess = result => result, postServe = result => result,
    name = 'createProcedure'} = {}) => {
    const checkHook = new Hook(check, name, 'check');
    const preProcessHook = new Hook(preProcess, name, 'preProcess');
    const postProcessHook = new Hook(postProcess, name, 'postProcess');
    const postServeHook = new Hook(postServe, name, 'postServe');

    return (params, user) => {
        const response = checkHook.execute(params, user)
            .then(checkPassed => {
                if (!checkPassed)
                    throw new Error('Check lifecycle hook did not pass');
                return params;
            })
            .then(pipe(params => [params, user], preProcessHook.execute))
            .then(parseNeo4jInts('id', 'skip', 'limit'))
            .then(params => Promise.all([
                neo4jConnection.executeCypher(cypherQueryFile, params),
                Promise.resolve(params)
            ]))
            .then(([result, params]) => Promise.all([
                postProcessHook.execute(result, params),
                Promise.resolve(params)
            ]));

        response.then(([result, params]) => postServeHook.execute(result, params));
        return response.then(([result, params]) => result);
    };
};

class API {
    constructor(neo4jConnection, {method, route, allowedRoles = [], procedure,
        cypherQueryFile, check, preProcess, postProcess, postServe} = {}) {
        if (typeof procedure === 'function')
            this.response = procedure;
        else
            this.response = createProcedure(neo4jConnection,
                {cypherQueryFile, check, preProcess, postProcess, postServe, name: route});

        this.method = method;
        this.route = route;
        this.allowedRoles = allowedRoles;
        this.requiresJwtAuthentication = allowedRoles &&
            Array.isArray(allowedRoles) && allowedRoles.length > 0;
    }
}

export {Neo4jConnection, createProcedure, API};
<|endoftext|>


<commit_before>/**
 * Created by keyvan on 8/16/16.
 */

import {v1 as neo4j} from 'neo4j-driver';
import fs from 'file-system';
import chalk from 'chalk';
import parser from 'parse-neo4j';
import {parseNeo4jInts} from './preprocess';
import {Procedure} from './procedure';

class Neo4jConnection {
    constructor({boltUrl, user, password} = {}) {
        this.queries = {};

        this.driver = neo4j.driver(boltUrl, neo4j.auth.basic(user, password));
        const session = this.driver.session();
        this.initialized = session.run('RETURN "Neo4j instance successfully connected."')
            .then((result) => {
                console.log(chalk.green(parser.parse(result)));
                session.close();
            })
            .catch(error => {
                console.error(
                    chalk.red('Error connecting to the Neo4j instance, check connection options'));
                console.log(error);
                throw error;
            });
    }

    addCypherQueryFile(cypherQueryFilePath) {
        this.queries[cypherQueryFilePath] = fs.readFileSync(cypherQueryFilePath, 'utf8');
    }

    executeCypher(cypherQueryFilePath, queryParams, pathIsQuery = false) {
        return new Promise((resolve, reject) => {
            if (!pathIsQuery && !this.queries[cypherQueryFilePath])
                this.addCypherQueryFile(cypherQueryFilePath);

            let query = cypherQueryFilePath;
            if (!pathIsQuery)
                query = this.queries[cypherQueryFilePath];
            const session = this.driver.session();

            session.run(query, queryParams)
                .then(result => {
                    resolve(result);
                    session.close();
                })
                .catch(error => {
                    error = error.fields ? JSON.stringify(error.fields[0]) : String(error);
                    reject(`error while executing Cypher: ${error}`);
                });
        })
            .then(parser.parse);
    }
}

class Hook {
    constructor(functions, neo4jConnection,
                procedureName, hookName, timeout = 4000) {
        this.timeout = timeout;
        this.name = hookName;
        this.procedureName = procedureName;
        if (!Array.isArray(functions))
        // TODO instanceof not working due to webpack!
        // if (typeof functions === 'function' || functions instanceof Procedure)
            if (typeof functions === 'function' || functions.isProcedure)
                functions = [functions];
            else
                throw new Error('hook should be function or array of functions');
        this.phases = [];
        this.context = {};
        for (let func of functions) {
            // TODO instanceof not working due to webpack!
            // if (func instanceof Procedure)
            if (func.isProcedure)
                func = createProcedure(neo4jConnection, func);
            else if (typeof func !== 'function')
                throw new Error(`element ${func} passed as ${this.procedureName} lifecycle ` +
                    "is neither a 'function' nor a 'procedure'");
            this.phases.push(this.asyncify(func));
        }

        this.execute = (...args) => {
            let next = Promise.resolve(this.phases[0](...args));
            const rest = args.slice(1);
            for (let i =  1; i < this.phases.length; i++)
                next = Promise.all([this.phases[i], next, rest])
                    .then(([phase, response, rest]) => phase(response, ...rest));
            return next;
        };
    }

    asyncify(func) {
        return (...args) => Promise.race([
            Promise.resolve(func.apply(this.context, args))
                .then(response => {
                    if (Array.isArray(response))
                        return Promise.all(response);
                    if (typeof response !== 'undefined')
                        return response;
                    if (typeof args[0] === 'object' && !Array.isArray(args[0]))
                        return args[0];
                    throw new Error('have you forgotten to return in the previous function ' +
                        "in the pipe? Hook's first argument not in correct format");
                }),
            new Promise((resolve, reject) => setTimeout(() => reject('TimeOutError'), this.timeout))
        ])
            .catch((error) => {
                if (error === 'TimeOutError')
                    throw new Error(`${this.name} lifecycle of '${this.procedureName}' timed out, `
                        + `no response after ${this.timeout / 1000} seconds`);
                if (typeof error === 'string')
                    error += `, in ${this.name} lifecycle of '${this.procedureName}'`;
                else
                    error.message += `, in ${this.name} lifecycle of '${this.procedureName}'`;
                throw error;
            });
    }
}

const createProcedure = (neo4jConnection, procedure) => {
    const options = new Procedure(procedure);
    const checkHook = new Hook(options.check, neo4jConnection, options.name, 'check');
    const preProcessHook = new Hook(options.preProcess, neo4jConnection,
        options.name, 'preProcess', procedure.timeout);
    const executionHook = new Hook((params, cypherQueryFile) => {
        let result, paramsResult, paramsCypher;
        if (typeof params.result !== 'undefined') {
            if (Array.isArray(params.result))
                result = Promise.all(params.result);
            else
                result = Promise.resolve(params.result);
            paramsResult = true;
        }
        else if (params.cypher || cypherQueryFile) {
            result = neo4jConnection.executeCypher(params.cypher || cypherQueryFile,
                params, params.cypher);
            paramsCypher = true;
        }
        else
            result = Promise.reject(
                new Error("none of 'params.result', 'params.cypher' and " +
                    "'cypherQueryFile' were present"));
        return {result, paramsResult, paramsCypher};
    }, neo4jConnection, options.name, 'execution', procedure.timeout);

    const postProcessHook = new Hook(options.postProcess, neo4jConnection,
        options.name, 'postProcess', procedure.timeout);
    const postServeHook = new Hook(options.postServe, neo4jConnection,
        options.name, 'postServe', procedure.timeout * 3);

    return (params, ctx) => {
        const response = checkHook.execute(params, ctx)
            .then(checkPassed => {
                if (!checkPassed)
                    throw new Error(`Check lifecycle hook of ${options.name} did not pass`);
                return [params, ctx];
            })
            .then(([params, ctx]) => Promise.all([
                preProcessHook.execute(params, ctx),
                ctx
            ]))
            .then(([params, ctx]) => Promise.all([
                parseNeo4jInts('id', 'skip', 'limit')(params),
                ctx
            ]))
            .then(([params, ctx]) => Promise.all([
                executionHook.execute(params, options.cypherQueryFile),
                params,
                ctx
            ]))
            .then(([{result, paramsResult, paramsCypher}, params, ctx]) => {
                if (paramsResult)
                    delete params.result;
                if (paramsCypher)
                    delete params.cypher;
                return Promise.all([result, params, ctx]);
            })
            .then(([result, params, ctx]) => Promise.all([
                postProcessHook.execute(result, params, ctx),
                params,
                ctx
            ]));

        response
            .catch(error => {
                console.error(chalk.red(`Error in postProcess of '${options.name}'`));
                console.dir(error);
                return [];
            })
            .then(([result, params, ctx]) => {
                if (result || params || ctx)
                    return postServeHook.execute(result, params, ctx);
            })
            .catch(error => {
                console.error(chalk.red(`Error in postServe of '${options.name}'`));
                console.dir(error);
            });
        return response.then(([result, params, ctx]) => result);
    };
};

class API {
    constructor(neo4jConnection, {method, route, allowedRoles = [], procedure,
        cypherQueryFile, check, timeout, preProcess, postProcess, postServe} = {}) {
        if (typeof procedure === 'function')
            this.invoke = procedure;
        else
            this.invoke = createProcedure(neo4jConnection,
                {cypherQueryFile, timeout, check, preProcess, postProcess, postServe, name: route});

        this.method = method;
        this.route = route;
        this.allowedRoles = allowedRoles;
        this.requiresJwtAuthentication = allowedRoles &&
            Array.isArray(allowedRoles) && allowedRoles.length > 0;
    }
}

export {Neo4jConnection, Procedure, createProcedure, API};
<commit_msg>timeout for API definition<commit_after>/**
 * Created by keyvan on 8/16/16.
 */

import {v1 as neo4j} from 'neo4j-driver';
import fs from 'file-system';
import chalk from 'chalk';
import parser from 'parse-neo4j';
import {parseNeo4jInts} from './preprocess';
import {Procedure} from './procedure';

class Neo4jConnection {
    constructor({boltUrl, user, password} = {}) {
        this.queries = {};

        this.driver = neo4j.driver(boltUrl, neo4j.auth.basic(user, password));
        const session = this.driver.session();
        this.initialized = session.run('RETURN "Neo4j instance successfully connected."')
            .then((result) => {
                console.log(chalk.green(parser.parse(result)));
                session.close();
            })
            .catch(error => {
                console.error(
                    chalk.red('Error connecting to the Neo4j instance, check connection options'));
                console.log(error);
                throw error;
            });
    }

    addCypherQueryFile(cypherQueryFilePath) {
        this.queries[cypherQueryFilePath] = fs.readFileSync(cypherQueryFilePath, 'utf8');
    }

    executeCypher(cypherQueryFilePath, queryParams, pathIsQuery = false) {
        return new Promise((resolve, reject) => {
            if (!pathIsQuery && !this.queries[cypherQueryFilePath])
                this.addCypherQueryFile(cypherQueryFilePath);

            let query = cypherQueryFilePath;
            if (!pathIsQuery)
                query = this.queries[cypherQueryFilePath];
            const session = this.driver.session();

            session.run(query, queryParams)
                .then(result => {
                    resolve(result);
                    session.close();
                })
                .catch(error => {
                    error = error.fields ? JSON.stringify(error.fields[0]) : String(error);
                    reject(`error while executing Cypher: ${error}`);
                });
        })
            .then(parser.parse);
    }
}

class Hook {
    constructor(functions, neo4jConnection,
                procedureName, hookName, timeout = 4000) {
        this.timeout = timeout;
        this.name = hookName;
        this.procedureName = procedureName;
        if (!Array.isArray(functions))
        // TODO instanceof not working due to webpack!
        // if (typeof functions === 'function' || functions instanceof Procedure)
            if (typeof functions === 'function' || functions.isProcedure)
                functions = [functions];
            else
                throw new Error('hook should be function or array of functions');
        this.phases = [];
        this.context = {};
        for (let func of functions) {
            // TODO instanceof not working due to webpack!
            // if (func instanceof Procedure)
            if (func.isProcedure)
                func = createProcedure(neo4jConnection, func);
            else if (typeof func !== 'function')
                throw new Error(`element ${func} passed as ${this.procedureName} lifecycle ` +
                    "is neither a 'function' nor a 'procedure'");
            this.phases.push(this.asyncify(func));
        }

        this.execute = (...args) => {
            let next = Promise.resolve(this.phases[0](...args));
            const rest = args.slice(1);
            for (let i =  1; i < this.phases.length; i++)
                next = Promise.all([this.phases[i], next, rest])
                    .then(([phase, response, rest]) => phase(response, ...rest));
            return next;
        };
    }

    asyncify(func) {
        return (...args) => Promise.race([
            Promise.resolve(func.apply(this.context, args))
                .then(response => {
                    if (Array.isArray(response))
                        return Promise.all(response);
                    if (typeof response !== 'undefined')
                        return response;
                    if (typeof args[0] === 'object' && !Array.isArray(args[0]))
                        return args[0];
                    throw new Error('have you forgotten to return in the previous function ' +
                        "in the pipe? Hook's first argument not in correct format");
                }),
            new Promise((resolve, reject) => setTimeout(() => reject('TimeOutError'), this.timeout))
        ])
            .catch((error) => {
                if (error === 'TimeOutError')
                    throw new Error(`${this.name} lifecycle of '${this.procedureName}' timed out, `
                        + `no response after ${this.timeout / 1000} seconds`);
                if (typeof error === 'string')
                    error += `, in ${this.name} lifecycle of '${this.procedureName}'`;
                else
                    error.message += `, in ${this.name} lifecycle of '${this.procedureName}'`;
                throw error;
            });
    }
}

const createProcedure = (neo4jConnection, procedure) => {
    const options = new Procedutchre(procedure);
    const checkHook = new Hook(options.check, neo4jConnection, options.name, 'check');
    const preProcessHook = new Hook(options.preProcess, neo4jConnection,
        options.name, 'preProcess', procedure.timeout);
    const executionHook = new Hook((params, cypherQueryFile) => {
        let result, paramsResult, paramsCypher;
        if (typeof params.result !== 'undefined') {
            if (Array.isArray(params.result))
                result = Promise.all(params.result);
            else
                result = Promise.resolve(params.result);
            paramsResult = true;
        }
        else if (params.cypher || cypherQueryFile) {
            result = neo4jConnection.executeCypher(params.cypher || cypherQueryFile,
                params, params.cypher);
            paramsCypher = true;
        }
        else
            result = Promise.reject(
                new Error("none of 'params.result', 'params.cypher' and " +
                    "'cypherQueryFile' were present"));
        return {result, paramsResult, paramsCypher};
    }, neo4jConnection, options.name, 'execution', procedure.timeout);

    const postProcessHook = new Hook(options.postProcess, neo4jConnection,
        options.name, 'postProcess', procedure.timeout);
    const postServeHook = new Hook(options.postServe, neo4jConnection,
        options.name, 'postServe', procedure.timeout * 3);

    return (params, ctx) => {
        const response = checkHook.execute(params, ctx)
            .then(checkPassed => {
                if (!checkPassed)
                    throw new Error(`Check lifecycle hook of ${options.name} did not pass`);
                return [params, ctx];
            })
            .then(([params, ctx]) => Promise.all([
                preProcessHook.execute(params, ctx),
                ctx
            ]))
            .then(([params, ctx]) => Promise.all([
                parseNeo4jInts('id', 'skip', 'limit')(params),
                ctx
            ]))
            .then(([params, ctx]) => Promise.all([
                executionHook.execute(params, options.cypherQueryFile),
                params,
                ctx
            ]))
            .then(([{result, paramsResult, paramsCypher}, params, ctx]) => {
                if (paramsResult)
                    delete params.result;
                if (paramsCypher)
                    delete params.cypher;
                return Promise.all([result, params, ctx]);
            })
            .then(([result, params, ctx]) => Promise.all([
                postProcessHook.execute(result, params, ctx),
                params,
                ctx
            ]));

        response
            .catch(error => {
                console.error(chalk.red(`Error in postProcess of '${options.name}'`));
                console.dir(error);
                return [];
            })
            .then(([result, params, ctx]) => {
                if (result || params || ctx)
                    return postServeHook.execute(result, params, ctx);
            })
            .catch(error => {
                console.error(chalk.red(`Error in postServe of '${options.name}'`));
                console.dir(error);
            });
        return response.then(([result, params, ctx]) => result);
    };
};

class API {
    constructor(neo4jConnection, {method, route, allowedRoles = [], procedure,
        cypherQueryFile, check, timeout, preProcess, postProcess, postServe} = {}) {
        if (typeof procedure === 'function')
            this.invoke = procedure;
        else
            this.invoke = createProcedure(neo4jConnection,
                {cypherQueryFile, timeout, check, preProcess, postProcess, postServe, name: route});

        this.method = method;
        this.route = route;
        this.allowedRoles = allowedRoles;
        this.requiresJwtAuthentication = allowedRoles &&
            Array.isArray(allowedRoles) && allowedRoles.length > 0;
    }
}

export {Neo4jConnection, Procedure, createProcedure, API};
<|endoftext|>