<commit_before>var app = angular.module('okpy', ['ngResource', 'ui.router', 'angular-loading-bar', 'ui.bootstrap', 'angularMoment']);

// http://ngmodules.org/modules/MacGyver

app.directive('snippet', ['$timeout', '$interpolate', function ($timeout, $interpolate) {
        "use strict";
        return {
            restrict: 'E',
            template: '

',
            replace: true,
            transclude: true,
            link: function (scope, elm) {
                var tmp = $interpolate(elm.find('code').text())(scope);
                elm.find('code').html(hljs.highlightAuto(tmp).value);
            }
        };
    }]);

app.directive('diff', ['$timeout', '$interpolate', function ($timeout, $interpolate) {
        "use strict";
        return {
            restrict: 'E',
            template: '

',
            replace: true,
            transclude: true,
            link: function (scope, elm) {
              elm.html("");

              var contents = JSON.parse($interpolate(elm.text())(scope));
              var leftNum = 0;
              var rightNum = 0;
              for (var i = 0; i <= contents.length; i++) {
                var val = contents[i];
                var start = val[0];
                var content = val[0] + val.slice(2);
                var elem = $("
")
                var lineNumLeft = $("")
                var lineNumRight = $("")
                var code = $("")
                var showLeft = false;
                var showRight = false;
                if (start == " ") {
                  code.addClass('diff-line-code-empty')
                  showRight = true;
                  showLeft = true;
                } else if (start == "+") {
                  code.addClass('diff-line-code-pos')
                  lineNumRight.addClass('diff-line-num-pos')
                  lineNumLeft.addClass('diff-line-num-pos')
                  showRight = true;
                } else if (start == "-") {
                  code.addClass('diff-line-code-neg')
                  lineNumLeft.addClass('diff-line-num-neg')
                  lineNumRight.addClass('diff-line-num-neg')
                  showLeft = true;
                }
                if (showRight == true) {
                  rightNum++;
                  lineNumRight.text(rightNum);
                }
                if (showLeft == true) {
                  leftNum++;
                  lineNumLeft.text(leftNum);
                }
                code.text(content);
                elem.append(lineNumLeft);
                elem.append(lineNumRight);
                elem.append(code);
                elm.append(elem);
              };
            }
        };
    }]);

app.config(['$stateProvider', '$urlRouterProvider',
  function($stateProvider, $urlRouterProvider, $locationProvider) {
    $urlRouterProvider.otherwise("/submission/");

    var submissions = {
      name: 'submission',
      abstract: true,
      url: '/submission',
      templateUrl: 'static/partials/submission.base.html',
    }

    var submissionList = {
      name: 'submission.list',
      url: '/',
      templateUrl: 'static/partials/submission.list.html',
      controller: "SubmissionListCtrl"
    }

    var submissionDetail = {
      name: 'submission.detail',
      url: '/:submissionId',
      templateUrl: 'static/partials/submission.detail.html',
      controller: "SubmissionDetailCtrl"
    }

    var submissionDiff = {
      name: 'submission.diff',
      url: '/:submissionId/diff',
      templateUrl: 'static/partials/submission.diff.html',
      controller: "SubmissionDiffCtrl"
    }

    var assignments = {
      name: 'assignment',
      abstract: true,
      url: '/assignment',
      templateUrl: 'static/partials/assignment.base.html',
    }

    var assignmentList = {
      name: 'assignment.list',
      url: '/',
      templateUrl: 'static/partials/assignment.list.html',
      controller: "AssignmentListCtrl"
    }

    var assignmentDetail = {
      name: 'assignment.detail',
      url: '/:assignmentId',
      templateUrl: 'static/partials/assignment.detail.html',
      controller: "AssignmentDetailCtrl"
    }

    var courses = {
      name: 'course',
      abstract: true,
      url: '/course',
      templateUrl: 'static/partials/course.base.html',
    }

    var courseList = {
      name: 'course.list',
      url: '/',
      templateUrl: 'static/partials/course.list.html',
      controller: "CourseListCtrl"
    }

    var courseDetail = {
      name: 'course.detail',
      url: '/:courseId',
      templateUrl: 'static/partials/course.detail.html',
      controller: "CourseDetailCtrl"
    }

    var courseNew = {
      name: 'course.new',
      url: '/new',
      templateUrl: 'static/partials/course.new.html',
      controller: "CourseNewCtrl"
    }

    $stateProvider.
      state(submissions).
      state(submissionList).
      state(submissionDetail).
      state(submissionDiff).
      state(assignments).
      state(assignmentList).
      state(assignmentDetail).
      state(courses).
      state(courseList).
      state(courseNew)
      ;
  }]);

app.factory('Submission', ['$resource',
    function($resource) {
      return $resource('api/v1/submission/:id', {format: "json"}, {
        query: {
          isArray: false
        },
        get: {
          isArray: false,
          transformResponse: function(data) {
            return JSON.parse(data).data;
          }
        },
        diff: {
          url: 'api/v1/submission/:id/diff',
          isArray: false,
          transformResponse: function(data) {
            return JSON.parse(data).data;
          }
        }
      });
    }
  ]);

app.controller("SubmissionListCtrl", ['$scope', 'Submission',
  function($scope, Submission) {
  $scope.itemsPerPage = 20;
  $scope.currentPage = 1;

  $scope.refresh = function(page) {
    Submission.query({
      fields: {
        'created': true,
        'id': true,
        'submitter': {
          'id': true
        },
        'assignment': {
          'name': true,
          'id': true,
        },
      },
      page: page,
      num_page: $scope.itemsPerPage
    }, function(response) {
      $scope.data = response.data;
      $scope.message = response.message;
      $scope.totalItems = response.data.statistics.total;
      if (response.data.page !== $scope.currentPage) {
        $scope.currentPage = response.data.page;
        $scope.pageChange();
      }
    });
  }
  $scope.pageChanged = function() {
    console.log("changed")
    $scope.refresh($scope.currentPage);
  }
  $scope.refresh(1);
  }]);

app.controller("SubmissionDetailCtrl", ['$scope', '$stateParams',  'Submission',
  function($scope, $stateParams, Submission) {
    $scope.submission = Submission.get({id: $stateParams.submissionId});
  }]);

app.controller("SubmissionDiffCtrl", ['$scope', '$stateParams',  'Submission',
  function($scope, $stateParams, Submission) {
    $scope.diff = Submission.diff({id: $stateParams.submissionId});
  }]);

app.factory('Assignment', ['$resource',
    function($resource) {
      return $resource('api/v1/assignment/:id', {format: "json"}, {
        query: {
          isArray: true,
          transformResponse: function(data) {
            return JSON.parse(data).data.results;
          }
        },
        get: {
          isArray: false,
          transformResponse: function(data) {
            return JSON.parse(data).data;
          }
        }
      });
    }
  ]);

app.controller("AssignmentListCtrl", ['$scope', 'Assignment',
  function($scope, Assignment) {
    $scope.assignments = Assignment.query();
  }]);

app.controller("AssignmentDetailCtrl", ["$scope", "$stateParams", "Assignment",
    function ($scope, $stateParams, Assignment) {
      $scope.assignment = Assignment.get({id: $stateParams.assignmentId});
    }
  ]);

app.factory('Course', ['$resource',
    function($resource) {
      return $resource('api/v1/course/:id', {
        format: "json",
      }, {
        query: {
          isArray: true,
          transformResponse: function(data) {
            return JSON.parse(data).data.results;
          }
        },
        get: {
          isArray: false,
          transformResponse: function(data) {
            return JSON.parse(data).data;
          }
        },
      });
    }
  ]);

app.controller("CourseListCtrl", ['$scope', 'Course',
  function($scope, Course) {
    $scope.courses = Course.query();
  }]);

app.controller("CourseDetailCtrl", ["$scope", "$stateParams", "Course",
    function ($scope, $stateParams, Course) {
      $scope.course = Course.get({id: $stateParams.courseId});
    }
  ]);

// NOT WORKING RIGHT NOW
app.controller("CourseNewCtrl", ["$scope", "Course",
    function ($scope, Course) {
      $scope.course = {};
      $scope.test = {'test':3};

      $scope.save = function() {
        var course = new Course($scope.course);
        course.$save();
      };
    }
  ]);
<commit_msg>fixed bug<commit_after>var app = angular.module('okpy', ['ngResource', 'ui.router', 'angular-loading-bar', 'ui.bootstrap', 'angularMoment']);

// http://ngmodules.org/modules/MacGyver

app.directive('snippet', ['$timeout', '$interpolate', function ($timeout, $interpolate) {
        "use strict";
        return {
            restrict: 'E',
            template: '

',
            replace: true,
            transclude: true,
            link: function (scope, elm) {
                var tmp = $interpolate(elm.find('code').text())(scope);
                elm.find('code').html(hljs.highlightAuto(tmp).value);
            }
        };
    }]);

app.directive('diff', ['$timeout', '$interpolate', function ($timeout, $interpolate) {
        "use strict";
        return {
            restrict: 'E',
            template: '

',
            replace: true,
            transclude: true,
            link: function (scope, elm) {

              var contents = JSON.parse($interpolate(elm.text())(scope));
              elm.html("");

              var leftNum = 0;
              var rightNum = 0;
              for (var i = 0; i <= contents.length; i++) {
                var val = contents[i];
                var start = val[0];
                var content = val[0] + val.slice(2);
                var elem = $("
")
                var lineNumLeft = $("")
                var lineNumRight = $("")
                var code = $("")
                var showLeft = false;
                var showRight = false;
                if (start == " ") {
                  code.addClass('diff-line-code-empty')
                  showRight = true;
                  showLeft = true;
                } else if (start == "+") {
                  code.addClass('diff-line-code-pos')
                  lineNumRight.addClass('diff-line-num-pos')
                  lineNumLeft.addClass('diff-line-num-pos')
                  showRight = true;
                } else if (start == "-") {
                  code.addClass('diff-line-code-neg')
                  lineNumLeft.addClass('diff-line-num-neg')
                  lineNumRight.addClass('diff-line-num-neg')
                  showLeft = true;
                }
                if (showRight == true) {
                  rightNum++;
                  lineNumRight.text(rightNum);
                }
                if (showLeft == true) {
                  leftNum++;
                  lineNumLeft.text(leftNum);
                }
                code.text(content);
                elem.append(lineNumLeft);
                elem.append(lineNumRight);
                elem.append(code);
                elm.append(elem);
              };
            }
        };
    }]);

app.config(['$stateProvider', '$urlRouterProvider',
  function($stateProvider, $urlRouterProvider, $locationProvider) {
    $urlRouterProvider.otherwise("/submission/");

    var submissions = {
      name: 'submission',
      abstract: true,
      url: '/submission',
      templateUrl: 'static/partials/submission.base.html',
    }

    var submissionList = {
      name: 'submission.list',
      url: '/',
      templateUrl: 'static/partials/submission.list.html',
      controller: "SubmissionListCtrl"
    }

    var submissionDetail = {
      name: 'submission.detail',
      url: '/:submissionId',
      templateUrl: 'static/partials/submission.detail.html',
      controller: "SubmissionDetailCtrl"
    }

    var submissionDiff = {
      name: 'submission.diff',
      url: '/:submissionId/diff',
      templateUrl: 'static/partials/submission.diff.html',
      controller: "SubmissionDiffCtrl"
    }

    var assignments = {
      name: 'assignment',
      abstract: true,
      url: '/assignment',
      templateUrl: 'static/partials/assignment.base.html',
    }

    var assignmentList = {
      name: 'assignment.list',
      url: '/',
      templateUrl: 'static/partials/assignment.list.html',
      controller: "AssignmentListCtrl"
    }

    var assignmentDetail = {
      name: 'assignment.detail',
      url: '/:assignmentId',
      templateUrl: 'static/partials/assignment.detail.html',
      controller: "AssignmentDetailCtrl"
    }

    var courses = {
      name: 'course',
      abstract: true,
      url: '/course',
      templateUrl: 'static/partials/course.base.html',
    }

    var courseList = {
      name: 'course.list',
      url: '/',
      templateUrl: 'static/partials/course.list.html',
      controller: "CourseListCtrl"
    }

    var courseDetail = {
      name: 'course.detail',
      url: '/:courseId',
      templateUrl: 'static/partials/course.detail.html',
      controller: "CourseDetailCtrl"
    }

    var courseNew = {
      name: 'course.new',
      url: '/new',
      templateUrl: 'static/partials/course.new.html',
      controller: "CourseNewCtrl"
    }

    $stateProvider.
      state(submissions).
      state(submissionList).
      state(submissionDetail).
      state(submissionDiff).
      state(assignments).
      state(assignmentList).
      state(assignmentDetail).
      state(courses).
      state(courseList).
      state(courseNew)
      ;
  }]);

app.factory('Submission', ['$resource',
    function($resource) {
      return $resource('api/v1/submission/:id', {format: "json"}, {
        query: {
          isArray: false
        },
        get: {
          isArray: false,
          transformResponse: function(data) {
            return JSON.parse(data).data;
          }
        },
        diff: {
          url: 'api/v1/submission/:id/diff',
          isArray: false,
          transformResponse: function(data) {
            return JSON.parse(data).data;
          }
        }
      });
    }
  ]);

app.controller("SubmissionListCtrl", ['$scope', 'Submission',
  function($scope, Submission) {
  $scope.itemsPerPage = 20;
  $scope.currentPage = 1;

  $scope.refresh = function(page) {
    Submission.query({
      fields: {
        'created': true,
        'id': true,
        'submitter': {
          'id': true
        },
        'assignment': {
          'name': true,
          'id': true,
        },
      },
      page: page,
      num_page: $scope.itemsPerPage
    }, function(response) {
      $scope.data = response.data;
      $scope.message = response.message;
      $scope.totalItems = response.data.statistics.total;
      if (response.data.page !== $scope.currentPage) {
        $scope.currentPage = response.data.page;
        $scope.pageChange();
      }
    });
  }
  $scope.pageChanged = function() {
    console.log("changed")
    $scope.refresh($scope.currentPage);
  }
  $scope.refresh(1);
  }]);

app.controller("SubmissionDetailCtrl", ['$scope', '$stateParams',  'Submission',
  function($scope, $stateParams, Submission) {
    $scope.submission = Submission.get({id: $stateParams.submissionId});
  }]);

app.controller("SubmissionDiffCtrl", ['$scope', '$stateParams',  'Submission',
  function($scope, $stateParams, Submission) {
    $scope.diff = Submission.diff({id: $stateParams.submissionId});
  }]);

app.factory('Assignment', ['$resource',
    function($resource) {
      return $resource('api/v1/assignment/:id', {format: "json"}, {
        query: {
          isArray: true,
          transformResponse: function(data) {
            return JSON.parse(data).data.results;
          }
        },
        get: {
          isArray: false,
          transformResponse: function(data) {
            return JSON.parse(data).data;
          }
        }
      });
    }
  ]);

app.controller("AssignmentListCtrl", ['$scope', 'Assignment',
  function($scope, Assignment) {
    $scope.assignments = Assignment.query();
  }]);

app.controller("AssignmentDetailCtrl", ["$scope", "$stateParams", "Assignment",
    function ($scope, $stateParams, Assignment) {
      $scope.assignment = Assignment.get({id: $stateParams.assignmentId});
    }
  ]);

app.factory('Course', ['$resource',
    function($resource) {
      return $resource('api/v1/course/:id', {
        format: "json",
      }, {
        query: {
          isArray: true,
          transformResponse: function(data) {
            return JSON.parse(data).data.results;
          }
        },
        get: {
          isArray: false,
          transformResponse: function(data) {
            return JSON.parse(data).data;
          }
        },
      });
    }
  ]);

app.controller("CourseListCtrl", ['$scope', 'Course',
  function($scope, Course) {
    $scope.courses = Course.query();
  }]);

app.controller("CourseDetailCtrl", ["$scope", "$stateParams", "Course",
    function ($scope, $stateParams, Course) {
      $scope.course = Course.get({id: $stateParams.courseId});
    }
  ]);

// NOT WORKING RIGHT NOW
app.controller("CourseNewCtrl", ["$scope", "Course",
    function ($scope, Course) {
      $scope.course = {};
      $scope.test = {'test':3};

      $scope.save = function() {
        var course = new Course($scope.course);
        course.$save();
      };
    }
  ]);
<|endoftext|>


<commit_before>const redis = require('./redis');
const config = require('../config/index.js');

const getRequest = async (requestId) => {
  // Set TTL for request
  redis.expire(`requests:${requestId}`, config('requests_ttl'));
  return await redis.hgetallAsync(`requests:${requestId}`);
};

const createRequest = async (requestDetails) => {
  // get new unique id for request
  const requestId = await redis.incrAsync('next_request_id');

  // create a new request entry in Redis
  const {user_id, pickup, dropoff, requested_pickup_time, size, weight} = requestDetails;
  const [pickup_lat, pickup_long] = pickup.split(',');
  const [dropoff_lat, dropoff_long] = dropoff.split(',');
  redis.hmsetAsync(`requests:${requestId}`,
    'user_id', user_id,
    'pickup_lat', pickup_lat,
    'pickup_long', pickup_long,
    'dropoff_lat', dropoff_lat,
    'dropoff_long', dropoff_long,
    'requested_pickup_time', requested_pickup_time,
    'size', size,
    'weight', weight,
  );

  // Set TTL for request
  redis.expire(`requests:${requestId}`, 43200);
  return requestId;
};

const deleteRequest = async (requestId) => {
  return await redis.del(`requests:${requestId}`);
};

module.exports = {
  createRequest,
  getRequest,
  deleteRequest
};
<commit_msg>Remove another constant and shorten require path<commit_after>const redis = require('./redis');
const config = require('../config');

const getRequest = async (requestId) => {
  // Set TTL for request
  redis.expire(`requests:${requestId}`, config('requests_ttl'));
  return await redis.hgetallAsync(`requests:${requestId}`);
};

const createRequest = async (requestDetails) => {
  // get new unique id for request
  const requestId = await redis.incrAsync('next_request_id');

  // create a new request entry in Redis
  const {user_id, pickup, dropoff, requested_pickup_time, size, weight} = requestDetails;
  const [pickup_lat, pickup_long] = pickup.split(',');
  const [dropoff_lat, dropoff_long] = dropoff.split(',');
  redis.hmsetAsync(`requests:${requestId}`,
    'user_id', user_id,
    'pickup_lat', pickup_lat,
    'pickup_long', pickup_long,
    'dropoff_lat', dropoff_lat,
    'dropoff_long', dropoff_long,
    'requested_pickup_time', requested_pickup_time,
    'size', size,
    'weight', weight,
  );

  // Set TTL for request
  redis.expire(`requests:${requestId}`, config('requests_ttl'));
  return requestId;
};

const deleteRequest = async (requestId) => {
  return await redis.del(`requests:${requestId}`);
};

module.exports = {
  createRequest,
  getRequest,
  deleteRequest
};
<|endoftext|>


<commit_before>/*
 * Top-level namespace for the GapVis application
 */
define(function() {

//     // removed in production by uglify
//     if (DEBUG) {
// //        API_ROOT = '/api';
// //        REPORT_URL = '/api/flags/';
// //        API_DATA_TYPE = 'json';
//     	API_ROOT = 'tests/api';
//     	REPORT_URL = 'tests/api/flags/';
//     	API_DATA_TYPE = 'json';
//     }

    // map styles
    var novisibility = [{ visibility: "off" }],
        mapStyle = [
            {
                elementType: "labels",
                stylers: novisibility
            },{
                featureType: "administrative",
                elementType: "geometry",
                stylers: novisibility
            },{
                featureType: "road",
                elementType: "geometry",
                stylers: novisibility
            },{
                featureType: "transit",
                elementType: "geometry",
                stylers: novisibility
            },{
                featureType: "poi",
                elementType: "geometry",
                stylers: novisibility
            },{
                featureType: "water",
                stylers: [
                    { hue: "#0033ff" },
                    { saturation: 82 },
                    { lightness: 95 }
                ]
            },{
                featureType: "landscape",
                stylers: [
                    { hue: "#80ff00" },
                    { saturation: 15 },
                    { lightness: -20 }
                ]
            }
        ],
        // colors for frequency scale
        scaleColors = ["090066", "6b0051", "ce003c", "cc0020", "ee0000"],
        colorThemes = scaleColors.map(function(color) {
            return TimeMapTheme.createCircleTheme({ color: color });
        });

		// colors for types
		placeTypes = { "SETTLEMENT": "0000ee", "NATURAL_FEATURE" : "ee0000", "REGION" : "00ee00" };
		themeByType = function(place){
			var color = "555555",
			 	ptypes = this.placeTypes,
				ptypecolor = ptypes[place.get('type')];
			if( typeof ptypecolor != 'undefined' ){
				color = ptypecolor;
			}
			return TimeMapTheme.createCircleTheme({ color: color });
		};
    var gv = window.gv = spf;

    gv.settings = _.extend(spf.config, {
        // core settings (set from config)
        API_ROOT: API_ROOT,
        REPORT_URL: REPORT_URL,
        API_DATA_TYPE: API_DATA_TYPE,
        disableChangeLink: (typeof disableChangeLink!=='undefined')?!!disableChangeLink:false,
        VIEW_ON: (typeof VIEW_ON!=='undefined')?VIEW_ON:null,
		REPORT_BAD_TOKEN_URL: (typeof REPORT_BAD_TOKEN_URL !== 'undefined')?REPORT_BAD_TOKEN_URL:false,
		PLACE_THEME: PLACE_THEME,
		viewOnLink : (typeof VIEW_ON_LINK === 'function') ? VIEW_ON_LINK : false,
         // google maps style settings
        mapStyle: mapStyle,
        scaleColors: scaleColors,
        colorThemes: colorThemes,
		placeTypes: placeTypes,
		themeByType: themeByType
    });

    return gv;
});<commit_msg>About #22 PLACE_THEME configuration may be unset, in this case fall back to 'frequency' as default<commit_after>/*
 * Top-level namespace for the GapVis application
 */
define(function() {

//     // removed in production by uglify
//     if (DEBUG) {
// //        API_ROOT = '/api';
// //        REPORT_URL = '/api/flags/';
// //        API_DATA_TYPE = 'json';
//     	API_ROOT = 'tests/api';
//     	REPORT_URL = 'tests/api/flags/';
//     	API_DATA_TYPE = 'json';
//     }

    // map styles
    var novisibility = [{ visibility: "off" }],
        mapStyle = [
            {
                elementType: "labels",
                stylers: novisibility
            },{
                featureType: "administrative",
                elementType: "geometry",
                stylers: novisibility
            },{
                featureType: "road",
                elementType: "geometry",
                stylers: novisibility
            },{
                featureType: "transit",
                elementType: "geometry",
                stylers: novisibility
            },{
                featureType: "poi",
                elementType: "geometry",
                stylers: novisibility
            },{
                featureType: "water",
                stylers: [
                    { hue: "#0033ff" },
                    { saturation: 82 },
                    { lightness: 95 }
                ]
            },{
                featureType: "landscape",
                stylers: [
                    { hue: "#80ff00" },
                    { saturation: 15 },
                    { lightness: -20 }
                ]
            }
        ],
        // colors for frequency scale
        scaleColors = ["090066", "6b0051", "ce003c", "cc0020", "ee0000"],
        colorThemes = scaleColors.map(function(color) {
            return TimeMapTheme.createCircleTheme({ color: color });
        });

		// colors for types
		placeTypes = { "SETTLEMENT": "0000ee", "NATURAL_FEATURE" : "ee0000", "REGION" : "00ee00" };
		themeByType = function(place){
			var color = "555555",
			 	ptypes = this.placeTypes,
				ptypecolor = ptypes[place.get('type')];
			if( typeof ptypecolor != 'undefined' ){
				color = ptypecolor;
			}
			return TimeMapTheme.createCircleTheme({ color: color });
		};
    var gv = window.gv = spf;

    gv.settings = _.extend(spf.config, {
        // core settings (set from config)
        API_ROOT: API_ROOT,
        REPORT_URL: REPORT_URL,
        API_DATA_TYPE: API_DATA_TYPE,
        disableChangeLink: (typeof disableChangeLink!=='undefined')?!!disableChangeLink:false,
        VIEW_ON: (typeof VIEW_ON!=='undefined')?VIEW_ON:null,
		REPORT_BAD_TOKEN_URL: (typeof REPORT_BAD_TOKEN_URL !== 'undefined')?REPORT_BAD_TOKEN_URL:false,
		PLACE_THEME: (typeof PLACE_THEME == 'undefined') ? 'frequency' : PLACE_THEME,
		viewOnLink : (typeof VIEW_ON_LINK === 'function') ? VIEW_ON_LINK : false,
         // google maps style settings
        mapStyle: mapStyle,
        scaleColors: scaleColors,
        colorThemes: colorThemes,
		placeTypes: placeTypes,
		themeByType: themeByType
    });

    return gv;
});<|endoftext|>


<commit_before>//     any.mt.js @VERSION@
//     (c) 2011 Philip Lehmann, Lukas Westermann, at-point ag
//     any.js is freely distributable under the MIT license.
//     Portions of any.js are inspired or borrowed from Underscore.js,
//     Prototype and jQuery.
//     For all details and documentation:
//     TODO: gh-pages

// touchevent documentation from apple
// http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchEventClassReference/TouchEvent/TouchEvent.html#//apple_ref/javascript/cl/TouchEvent

// Touch documentation from apple
// http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchClassReference/Touch/Touch.html#//apple_ref/javascript/cl/Touch

(function($a) {
	var root = this;

	var $mt = {};

	root.$mt = root._anyMtNoConflict = $mt;

	$mt.VERSION = '0.0.1';

	$mt.bindHandler = {};
	$mt.registerBindHandler = function(handler, browser) {
		this.bindHandler[browser] = handler;
	};

	$mt.unregsiterBindHandler = function(browser) {
		delete this.bindHandler[browser];
	}

	$mt.bind = function(node, event, callback, useCapture, data) {
		var browser = $a.browserDetection();
		if( ! $a.isArr(node) && ! $a.isCol(node)) {
			node = [node];
		}
		for(var i=0; i < node.length; i++) {
			if(this.bindHandler[browser]) {
				this.bindHandler[browser].bind(node[i], event, callback, useCapture, data);
			} else {
				EmulateTouch.bind(node[i], event, callback, useCapture, data);
			}
		}
	};

	$mt.unbind = function(node, event, callback, useCapture, data) {
		var browser = $a.browserDetection();
		if( ! $a.isArr(node) && ! $a.isCol(node)) {
			node = [node];
		}
		for(var i=0; i < node.length; i++) {
			if(this.bindHandler[browser]) {
				this.bindHandler[browser].unbind(node[i], event, callback, useCapture, data);
			} else {
				EmulateTouch.unbind(node[i], event, callback, useCapture, data);
			}
		}
	};

	/**
	 * swipe a node
	 * obj {
	 * 	 node - HTMLElement
	 *   type - horizontal | vertical - default horizontal
	 *   minSpeed - default 1
	 *   startAfter - default 20
	 *   onSwipeStart
	 *   onSwipeMove,
	 *   onSwipeEnd
	 * }
	 */
	$mt.swipe = function(attrs) {
		if( ! attrs.node instanceof HTMLElement) throw 'no node defined';
		if(attrs.startAfter == undefined) attrs.startAfter = 20;
		if(attrs.minSpeed == undefined) attrs.minSpeed = 1;
		if(attrs.type == undefined) attrs.type = 'horizontal';

		if(attrs.node._swipe == undefined) attrs.node._swipe = {};
		if(attrs.node._swipe[attrs.type] == undefined) attrs.node._swipe[attrs.type] = {};
		attrs.node._swipe[attrs.type].attrs = attrs;

		var type = {type: attrs.type};
		$mt.bind(attrs.node, 'touchstart', $mt.swipeStart, false, type);
		$mt.bind(attrs.node, 'touchmove', $mt.swipeMove, false, type);
		$mt.bind(attrs.node, 'touchend', $mt.swipeEnd, false, type);
	};

	$mt.unswipe = function(node, type) {
		var type = {type: attrs.type};
		$mt.unbind(node, 'touchstart', $mt.swipeStart, false, type);
		$mt.unbind(node, 'touchmove', $mt.swipeMove, false, type);
		$mt.unbind(node, 'touchend', $mt.swipeEnd, false, type);
	}

	$mt.swipeStart = function(event, data) {
		console.debug(data);
		var el = event.currentTarget;
		if(el._swipe == undefined) el._swipe = {};
		if(el._swipe[data.type] == undefined) el._swipe[data.type] = {};
		var swipe = el._swipe[data.type];
		swipe.tsStart = Date.now();
		if($a.isFunc(swipe.attrs.onSwipeStart)) {
			swipe.attrs.onSwipeStart(event);
		}
	};

	$mt.swipeMove = function(event, data) {
		console.debug(data);
		var el = event.currentTarget;
		if(el._swipe == undefined) el._swipe = {};
		if(el._swipe[data.type] == undefined) el._swipe[data.type] = {};
		var swipe = el._swipe[data.type];
		if($a.isFunc(swipe.attrs.onSwipeMove)) {
			swipe.attrs.onSwipeMove(event);
		}
	};

	$mt.swipeEnd = function(event, data) {
		console.debug(data);
		var el = event.currentTarget;
		if(el._swipe == undefined) el._swipe = {};
		if(el._swipe[data.type] == undefined) el._swipe[data.type] = {};
		var swipe = el._swipe[data.type];
		if($a.isFunc(swipe.attrs.onSwipeEnd)) {
			swipe.attrs.onSwipeEnd(event);
		}
	};

	$mt.draw = {};
	$mt.draw.items = [];
	$mt.draw.called = false;
	$mt.draw.set = function(element) {
		if($mt.draw.items.indexOf(element) === -1) {
			$mt.draw.items.push(element);
		}
		$mt.draw.called = true;
		$a.requestAnimationFrame($mt.draw.run);
	};

	$mt.draw.run = function(ts) {
		$mt.draw.items.forEach(function(element, i) {
			var style = $a.transform(element);
			element.style.mozTransform = style;
			element.style.webkitTransform = style;
			element.style.oTransform = style;
			element.style.transform = style;
		});
		$mt.draw.called = false;
	};

	$mt.elementCounter = 0;

	// handlers: touchStartCallbackStart, touchStartCallbackEnd, touchMoveCallbackStart, touchMoveCallbackEnd, touchEndCallbackStart, touchEndCallbackEnd
	// $mt.moveGesture(element, {gestureMoveCallbackEnd: function(event) {alert(event.rotation;)}});
	$mt.registerMove = function(element, handlers) {
		if(element._move_handlers != undefined) return;
		element._move_handlers = handlers;
		$mt.bind(element, 'touchstart', $mt.touchStart);
		$mt.bind(element, 'touchmove', $mt.touchMove);
		$mt.bind(element, 'touchend', $mt.touchEnd);
	};

	$mt.unregisterMove = function(element) {
		$mt.unbind(element, 'touchstart', $mt.touchStart);
		$mt.unbind(element, 'touchmove', $mt.touchMove);
		$mt.unbind(element, 'touchend', $mt.touchEnd);
		delete element._move_handlers;
	};

	$mt.touchStart = function(event) {
		var el = event.currentTarget;
		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchStartCallbackStart)) {
			el._move_handlers.touchStartCallbackStart(event);
		}

		event.preventDefault();
		el.style.zIndex = $mt.elementCounter += 1;
		el.touchX = event.pageX;
	  el.touchY = event.pageY;
		el.touchSID = event.streamId;

		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchStartCallbackEnd)) {
			el._move_handlers.touchStartCallbackEnd(event);
		}
	};

	$mt.touchMove = function(event) {
		var el = event.currentTarget;
		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchMoveCallbackStart)) {
			el._move_handlers.touchMoveCallbackStart(event);
		}

		if(el.gesture || el.touchSID != event.streamId || (isNaN(el.touchX) || isNaN(el.touchY)) || el.touchX == undefined || el.touchY == undefined) {
			return;
		}

		var translate = $a.transform(el, 'translate');
		var translateX = translate.x + (event.pageX - el.touchX);
		var translateY = translate.y + (event.pageY - el.touchY);
		$a.requestAnimationFrame(function() {
			$a.transform(el, 'translate', translateX, translateY);
		});

		el.touchX = event.pageX;
		el.touchY = event.pageY;

		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchMoveCallbackEnd)) {
			el._move_handlers.touchMoveCallbackEnd(event);
		}
	};

	$mt.touchEnd = function(event) {
		var el = event.currentTarget;
		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchEndCallbackStart)) {
			el._move_handlers.touchEndCallbackStart(event);
		}

		if(event.streamId != el.touchSID) return;
		delete el.touchX;
		delete el.touchY;
		delete el.touchSID;

		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchEndCallbackEnd)) {
			el._move_handlers.touchEndCallbackEnd(event);
		}
	};

	// handlers: gestureStartCallbackStart, gestureStartCallbackEnd, gestureMoveCallbackStart, gestureMoveCallbackEnd, gestureEndCallbackStart, gestureEndCallbackEnd
	// $mt.registerGesture(element, {gestureMoveCallbackEnd: function(event) {alert(event.rotation;)}});
	$mt.registerGesture = function(element, handlers) {
		if(element._move_handlers != undefined) return;
		element._move_handlers = handlers;
		$mt.bind(element, 'gesturestart', $mt.gestureStart);
		$mt.bind(element, 'gesturechange', $mt.gestureChange);
		$mt.bind(element, 'gestureend', $mt.gesturteEnd);
	};

	$mt.unregisterGesture = function(element, rotate, scale, handlers) {
		if(handlers == undefined) handlers = {};
		handlers.rotate = rotate || false;
		handlers.scale = scale || false;
	};

	$mt.gestureStart = function(event, data) {
		var el = event.currentTarget;
		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureStartCallbackStart)) {
			el._gesture_handlers.gestureStartCallbackStart(event);
		}

		el.scale = $a.transform(el, 'scale').x || 1;
		el.rotation = $a.transform(el, 'rotate').x || 0;
		el.gesture = true;

		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureStartCallbackEnd)) {
			data.gestureStartCallbackEnd(event);
		}
	};

	$mt.gestureChange = function(event) {
		var el = event.currentTarget;
		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureStartCallbackStart)) {
			el._gesture_handlers.gestureStartCallbackStart(event);
		}

		if(el.running === true) return;
		el.running = true;

		var change = false;
		var rot = 0;
		if(data.rotate && el.rotation !== undefined) {
			rot = (el.rotation + event.rotation) % 360;
			change = true;
			$a.transform(el, 'rotate', rot, undefined, undefined, true);
		}
		var scaleRes = 0;
		if(data.scale && el.scale !== undefined) {
			scaleRes = el.scale * event.scale;
			change = true;
			$a.transform(el, 'scale', scaleRes, undefined, undefined, true);
		}

		if(change) {
			$mt.draw.set(el);
		}

		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureStartCallbackEnd)) {
			el._gesture_handlers.gestureStartCallbackEnd(event, rot, scaleRes);
		}
		el.running = false;
	};

	$mt.gestureEnd = function(event, data) {
		var el = event.currentTarget;
		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureEndCallbackStart)) {
			el._gesture_handlers.gestureEndCallbackStart(event);
		}

		el.scale = undefined;
		el.rotation = undefined;
		delete el.gesture;

		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureEndCallbackEnd)) {
			el._gesture_handlers.gestureEndCallbackEnd(event);
		}
	};

	$mt.escapeElement = function(element) {
		element.onclick = function(event){return false;};
		element.onmousedown = function(event){document.getElementById('focusmaker').focus();return false;};
		element.onmousemove = function(event){return false;};
		element.onmouseup = function(event){return false;};
		element.onmouseover = function(event){return false;};
		element.onmouseout = function(event){return false;};
		element.onmouseenter = function(event){return false;};
		element.onmouseleave = function(event){return false;};
	};

	var EmulateTouch = {
		_mapping: {touch: 'click', touchstart: 'mousedown', touchmove: 'mousemove', touchend: 'mouseup'},
		bind: function(node, event, callback, useCapture, data) {
			if(this._mapping[event] !== undefined) {
				return $a.bind(node, this._mapping[event], callback, useCapture, data);
			} else {
				return $a.bind(node, event, callback, useCapture, data);
			}
		},

		unbind: function(node, event, callback, useCapture, data) {
			if(this._mapping[event] !== undefined) {
				return $a.unbind(node, this._mapping[event], callback, useCapture, data);
			} else {
				return $a.unbind(node, event, callback, useCapture, data);
			}
		}
	};

})(this._anyNoConflict);<commit_msg>improve swipe function<commit_after>//     any.mt.js @VERSION@
//     (c) 2011 Philip Lehmann, Lukas Westermann, at-point ag
//     any.js is freely distributable under the MIT license.
//     Portions of any.js are inspired or borrowed from Underscore.js,
//     Prototype and jQuery.
//     For all details and documentation:
//     TODO: gh-pages

// touchevent documentation from apple
// http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchEventClassReference/TouchEvent/TouchEvent.html#//apple_ref/javascript/cl/TouchEvent

// Touch documentation from apple
// http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchClassReference/Touch/Touch.html#//apple_ref/javascript/cl/Touch

(function($a) {
	var root = this;

	var $mt = {};

	root.$mt = root._anyMtNoConflict = $mt;

	$mt.VERSION = '0.0.1';

	$mt.bindHandler = {};
	$mt.registerBindHandler = function(handler, browser) {
		this.bindHandler[browser] = handler;
	};

	$mt.unregsiterBindHandler = function(browser) {
		delete this.bindHandler[browser];
	}

	$mt.bind = function(node, event, callback, useCapture, data) {
		var browser = $a.browserDetection();
		if( ! $a.isArr(node) && ! $a.isCol(node)) {
			node = [node];
		}
		for(var i=0; i < node.length; i++) {
			if(this.bindHandler[browser]) {
				this.bindHandler[browser].bind(node[i], event, callback, useCapture, data);
			} else {
				EmulateTouch.bind(node[i], event, callback, useCapture, data);
			}
		}
	};

	$mt.unbind = function(node, event, callback, useCapture, data) {
		var browser = $a.browserDetection();
		if( ! $a.isArr(node) && ! $a.isCol(node)) {
			node = [node];
		}
		for(var i=0; i < node.length; i++) {
			if(this.bindHandler[browser]) {
				this.bindHandler[browser].unbind(node[i], event, callback, useCapture, data);
			} else {
				EmulateTouch.unbind(node[i], event, callback, useCapture, data);
			}
		}
	};

	/**
	 * swipe a node
	 * obj {
	 * 	 node - HTMLElement
	 *   type - horizontal | vertical - default horizontal
	 *   minSpeed - default 1
	 *   startAfter - default 20
	 *   onSwipeStart
	 *   onSwipeMove,
	 *   onSwipeEnd
	 * }
	 */
	$mt.swipe = function(attrs) {
		if( ! attrs.node instanceof HTMLElement) throw 'no node defined';
		if(attrs.startAfter == undefined) attrs.startAfter = 20;
		if(attrs.minSpeed == undefined) attrs.minSpeed = 1;
		if(attrs.type == undefined) attrs.type = 'horizontal';

		if(attrs.node._swipe == undefined) attrs.node._swipe = {};
		if(attrs.node._swipe[attrs.type] == undefined) attrs.node._swipe[attrs.type] = {};
		attrs.node._swipe[attrs.type].attrs = attrs;

		var type = {type: attrs.type};

		$mt.bind(attrs.node, 'touchstart', $mt.swipeStart, false, type);
		$mt.bind(attrs.node, 'touchmove', $mt.swipeMove, false, type);
		$mt.bind(attrs.node, 'touchend', $mt.swipeEnd, false, type);
	};

	$mt.unswipe = function(node, type) {
		$mt.unbind(node, 'touchstart', $mt.swipeStart, false, {type: type, func: 'start'});
		$mt.unbind(node, 'touchmove', $mt.swipeMove, false, {type: type, func: 'move'});
		$mt.unbind(node, 'touchend', $mt.swipeEnd, false, {type: type, func: 'end'});
	}

	$mt.swipeStart = function(event, data) {
		var el = event.currentTarget;
		if(el._swipe == undefined) el._swipe = {};
		if(el._swipe[data.type] == undefined) el._swipe[data.type] = {};
		var swipe = el._swipe[data.type];

		swipe.tsStart = Date.now();
		if($a.isFunc(swipe.attrs.onSwipeStart)) {
			swipe.attrs.onSwipeStart(event);
		}
	};

	$mt.swipeMove = function(event, data) {
		var el = event.currentTarget;
		if(el._swipe == undefined) el._swipe = {};
		if(el._swipe[data.type] == undefined) el._swipe[data.type] = {};
		var swipe = el._swipe[data.type];
		if($a.isFunc(swipe.attrs.onSwipeMove)) {
			swipe.attrs.onSwipeMove(event);
		}
	};

	$mt.swipeEnd = function(event, data) {
		var el = event.currentTarget;
		if(el._swipe == undefined) el._swipe = {};
		if(el._swipe[data.type] == undefined) el._swipe[data.type] = {};
		var swipe = el._swipe[data.type];

		if($a.isFunc(swipe.attrs.onSwipeEnd)) {
			swipe.attrs.onSwipeEnd(event);
		}
	};

	$mt.draw = {};
	$mt.draw.items = [];
	$mt.draw.called = false;
	$mt.draw.set = function(element) {
		if($mt.draw.items.indexOf(element) === -1) {
			$mt.draw.items.push(element);
		}
		$mt.draw.called = true;
		$a.requestAnimationFrame($mt.draw.run);
	};

	$mt.draw.run = function(ts) {
		$mt.draw.items.forEach(function(element, i) {
			var style = $a.transform(element);
			element.style.mozTransform = style;
			element.style.webkitTransform = style;
			element.style.oTransform = style;
			element.style.transform = style;
		});
		$mt.draw.called = false;
	};

	$mt.elementCounter = 0;

	// handlers: touchStartCallbackStart, touchStartCallbackEnd, touchMoveCallbackStart, touchMoveCallbackEnd, touchEndCallbackStart, touchEndCallbackEnd
	// $mt.moveGesture(element, {gestureMoveCallbackEnd: function(event) {alert(event.rotation;)}});
	$mt.registerMove = function(element, handlers) {
		if(element._move_handlers != undefined) return;
		element._move_handlers = handlers;
		$mt.bind(element, 'touchstart', $mt.touchStart);
		$mt.bind(element, 'touchmove', $mt.touchMove);
		$mt.bind(element, 'touchend', $mt.touchEnd);
	};

	$mt.unregisterMove = function(element) {
		$mt.unbind(element, 'touchstart', $mt.touchStart);
		$mt.unbind(element, 'touchmove', $mt.touchMove);
		$mt.unbind(element, 'touchend', $mt.touchEnd);
		delete element._move_handlers;
	};

	$mt.touchStart = function(event) {
		var el = event.currentTarget;
		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchStartCallbackStart)) {
			el._move_handlers.touchStartCallbackStart(event);
		}

		event.preventDefault();
		el.style.zIndex = $mt.elementCounter += 1;
		el.touchX = event.pageX;
	  el.touchY = event.pageY;
		el.touchSID = event.streamId;

		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchStartCallbackEnd)) {
			el._move_handlers.touchStartCallbackEnd(event);
		}
	};

	$mt.touchMove = function(event) {
		var el = event.currentTarget;
		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchMoveCallbackStart)) {
			el._move_handlers.touchMoveCallbackStart(event);
		}

		if(el.gesture || el.touchSID != event.streamId || (isNaN(el.touchX) || isNaN(el.touchY)) || el.touchX == undefined || el.touchY == undefined) {
			return;
		}

		var translate = $a.transform(el, 'translate');
		var translateX = translate.x + (event.pageX - el.touchX);
		var translateY = translate.y + (event.pageY - el.touchY);
		$a.requestAnimationFrame(function() {
			$a.transform(el, 'translate', translateX, translateY);
		});

		el.touchX = event.pageX;
		el.touchY = event.pageY;

		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchMoveCallbackEnd)) {
			el._move_handlers.touchMoveCallbackEnd(event);
		}
	};

	$mt.touchEnd = function(event) {
		var el = event.currentTarget;
		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchEndCallbackStart)) {
			el._move_handlers.touchEndCallbackStart(event);
		}

		if(event.streamId != el.touchSID) return;
		delete el.touchX;
		delete el.touchY;
		delete el.touchSID;

		if($a.isObj(el._move_handlers) && $a.isFunc(el._move_handlers.touchEndCallbackEnd)) {
			el._move_handlers.touchEndCallbackEnd(event);
		}
	};

	// handlers: gestureStartCallbackStart, gestureStartCallbackEnd, gestureMoveCallbackStart, gestureMoveCallbackEnd, gestureEndCallbackStart, gestureEndCallbackEnd
	// $mt.registerGesture(element, {gestureMoveCallbackEnd: function(event) {alert(event.rotation;)}});
	$mt.registerGesture = function(element, handlers) {
		if(element._move_handlers != undefined) return;
		element._move_handlers = handlers;
		$mt.bind(element, 'gesturestart', $mt.gestureStart);
		$mt.bind(element, 'gesturechange', $mt.gestureChange);
		$mt.bind(element, 'gestureend', $mt.gesturteEnd);
	};

	$mt.unregisterGesture = function(element, rotate, scale, handlers) {
		if(handlers == undefined) handlers = {};
		handlers.rotate = rotate || false;
		handlers.scale = scale || false;
	};

	$mt.gestureStart = function(event, data) {
		var el = event.currentTarget;
		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureStartCallbackStart)) {
			el._gesture_handlers.gestureStartCallbackStart(event);
		}

		el.scale = $a.transform(el, 'scale').x || 1;
		el.rotation = $a.transform(el, 'rotate').x || 0;
		el.gesture = true;

		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureStartCallbackEnd)) {
			data.gestureStartCallbackEnd(event);
		}
	};

	$mt.gestureChange = function(event) {
		var el = event.currentTarget;
		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureStartCallbackStart)) {
			el._gesture_handlers.gestureStartCallbackStart(event);
		}

		if(el.running === true) return;
		el.running = true;

		var change = false;
		var rot = 0;
		if(data.rotate && el.rotation !== undefined) {
			rot = (el.rotation + event.rotation) % 360;
			change = true;
			$a.transform(el, 'rotate', rot, undefined, undefined, true);
		}
		var scaleRes = 0;
		if(data.scale && el.scale !== undefined) {
			scaleRes = el.scale * event.scale;
			change = true;
			$a.transform(el, 'scale', scaleRes, undefined, undefined, true);
		}

		if(change) {
			$mt.draw.set(el);
		}

		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureStartCallbackEnd)) {
			el._gesture_handlers.gestureStartCallbackEnd(event, rot, scaleRes);
		}
		el.running = false;
	};

	$mt.gestureEnd = function(event, data) {
		var el = event.currentTarget;
		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureEndCallbackStart)) {
			el._gesture_handlers.gestureEndCallbackStart(event);
		}

		el.scale = undefined;
		el.rotation = undefined;
		delete el.gesture;

		if($a.isObj(el._gesture_handlers) && $a.isFunc(el._gesture_handlers.gestureEndCallbackEnd)) {
			el._gesture_handlers.gestureEndCallbackEnd(event);
		}
	};

	$mt.escapeElement = function(element) {
		element.onclick = function(event){return false;};
		element.onmousedown = function(event){document.getElementById('focusmaker').focus();return false;};
		element.onmousemove = function(event){return false;};
		element.onmouseup = function(event){return false;};
		element.onmouseover = function(event){return false;};
		element.onmouseout = function(event){return false;};
		element.onmouseenter = function(event){return false;};
		element.onmouseleave = function(event){return false;};
	};

	var EmulateTouch = {
		_mapping: {touch: 'click', touchstart: 'mousedown', touchmove: 'mousemove', touchend: 'mouseup'},
		bind: function(node, event, callback, useCapture, data) {
			if(this._mapping[event] !== undefined) {
				return $a.bind(node, this._mapping[event], callback, useCapture, data);
			} else {
				return $a.bind(node, event, callback, useCapture, data);
			}
		},

		unbind: function(node, event, callback, useCapture, data) {
			if(this._mapping[event] !== undefined) {
				return $a.unbind(node, this._mapping[event], callback, useCapture, data);
			} else {
				return $a.unbind(node, event, callback, useCapture, data);
			}
		}
	};

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


<commit_before>/*
  ApiVis - Simple JavaScript objects API visualization

  Copyright (c) 2017 Radoslav Peev <rpeev@ymail.com> (MIT License)
*/

(function (exports) {

exports.typeStr = function (obj) {
  let t = Object.prototype.toString.call(obj).
    match(/^\[object ([^\]]*)\]$/)[1];

  if (t == 'Object' &&
    obj.constructor &&
    obj.constructor.name != 'Object'
  ) {
    t = (obj.constructor.name) ?
      obj.constructor.name :
      'AnonymousConstructor';
  }

  if (obj instanceof Function) {
    t = `${t}(${obj.length})`;
  }

  if (obj instanceof Error &&
    obj.message
  ) {
    t = `${t}("${obj.message}")`;
  }

  return t;
};

exports.privateMembers = function (obj) {
  let pms = {};

  for (let k in obj) {
    if (k.startsWith('_')) {
      pms[k] = obj[k];
    }
  }

  return pms;
};

exports.props = function (obj) {
  return Object.getOwnPropertyNames(obj).sort();
};

exports.propsStr = function (obj, inst = obj, indent = '  ', level = 0) {
  return exports.props(obj).
    map(k => {
      let v = null;

      try {
        let o = (['constructor', 'prototype'].includes(k)) ?
          obj :
          inst;

        v = o[k];
      } catch (err) {
        v = err;
      }

      return `${indent.repeat(level)}${k}: ${exports.typeStr(v)}`;
    }).
    join('\n');
};

exports.protos = function (obj) {
  let chain = [];

  for (let proto = Object.getPrototypeOf(obj);
    proto;
    proto = Object.getPrototypeOf(proto)
  ) {
    chain.push(proto);
  }

  return chain;
};

exports.protosStr = function (obj, indent = '  ') {
  return exports.protos(obj).
    reverse().
    map((o, i) => `${indent.repeat(i)}${(i != 0) ? '\u25b2' : ''}${exports.typeStr(o)}`).
    join('\n');
};

exports.apiStr = function (inst, filters = [], indent = '  ') {
  let chain = exports.protos(inst);

  chain.unshift(inst);

  if (filters.length > 0) {
    if (typeof filters == 'string') {
      filters = [filters];
    }

    chain = chain.filter(o => filters.some(f => exports.typeStr(o).includes(f)));
  }

  return chain.
    reverse().
    map((o, i) => `${indent.repeat(i)}${(i != 0) ? '\u25b2' : ''}${exports.typeStr(o)}\n${exports.propsStr(o, inst, indent, i + 1)}`).
    join('\n');
};

})((typeof window != 'undefined') ? window.apivis = {} : exports);
<commit_msg>Improve typeStr prototype format heuristic<commit_after>/*
  ApiVis - Simple JavaScript objects API visualization

  Copyright (c) 2017 Radoslav Peev <rpeev@ymail.com> (MIT License)
*/

(function (exports) {

exports.typeStr = function (obj) {
  let t = Object.prototype.toString.call(obj).
    match(/^\[object ([^\]]*)\]$/)[1];

  if (t == 'Object' &&
    obj.constructor &&
    obj.constructor.name != 'Object'
  ) {
    t = (obj.constructor.name) ?
      obj.constructor.name :
      'AnonymousConstructor';
  }

  if (obj instanceof Function) {
    t = `${t}(${obj.length})`;
  }

  if (obj &&
    obj.hasOwnProperty &&
    obj.hasOwnProperty('constructor') &&
    !t.endsWith('Prototype')
  ) {
    t = `${t}.prototype`;
  }

  if (obj instanceof Error &&
    obj.message
  ) {
    t = `${t}("${obj.message}")`;
  }

  return t;
};

exports.privateMembers = function (obj) {
  let pms = {};

  for (let k in obj) {
    if (k.startsWith('_')) {
      pms[k] = obj[k];
    }
  }

  return pms;
};

exports.props = function (obj) {
  return Object.getOwnPropertyNames(obj).sort();
};

exports.propsStr = function (obj, inst = obj, indent = '  ', level = 0) {
  return exports.props(obj).
    map(k => {
      let v = null;

      try {
        let o = (['constructor', 'prototype'].includes(k)) ?
          obj :
          inst;

        v = o[k];
      } catch (err) {
        v = err;
      }

      return `${indent.repeat(level)}${k}: ${exports.typeStr(v)}`;
    }).
    join('\n');
};

exports.protos = function (obj) {
  let chain = [];

  for (let proto = Object.getPrototypeOf(obj);
    proto;
    proto = Object.getPrototypeOf(proto)
  ) {
    chain.push(proto);
  }

  return chain;
};

exports.protosStr = function (obj, indent = '  ') {
  return exports.protos(obj).
    reverse().
    map((o, i) => `${indent.repeat(i)}${(i != 0) ? '\u25b2' : ''}${exports.typeStr(o)}`).
    join('\n');
};

exports.apiStr = function (inst, filters = [], indent = '  ') {
  let chain = exports.protos(inst);

  chain.unshift(inst);

  if (filters.length > 0) {
    if (typeof filters == 'string') {
      filters = [filters];
    }

    chain = chain.filter(o => filters.some(f => exports.typeStr(o).includes(f)));
  }

  return chain.
    reverse().
    map((o, i) => `${indent.repeat(i)}${(i != 0) ? '\u25b2' : ''}${exports.typeStr(o)}\n${exports.propsStr(o, inst, indent, i + 1)}`).
    join('\n');
};

})((typeof window != 'undefined') ? window.apivis = {} : exports);
<|endoftext|>


<commit_before><commit_msg>Added: trigger success event handler on link/form after evaluating response. Fixed: Chrome likes to send the request as XML, which fails when there's no body (e.g. links that post).<commit_after><|endoftext|>


<commit_before>Script.include("../BenchmarkLib.js");

var TRACING_RULES = "" +
    "trace.*=true\n" +
    "*.detail=true\n" +
    "";

Resources.overrideUrlPrefix(TEST_ROOT, Script.resolvePath(".."));
var testScript = new TestScript();
testScript.addTest({
    name: "measureTimingHifiqa-master",
    loader: TestScript.locationLoader("hifi://www", true),
    tracingRules: TRACING_RULES,
    traceActions: TestScript.measureTimingSteps([
        { time: 5, step: 0.1, keepActive: true, pos: { x:   29.2, y: -8.3, z: -26.2 }, ori:{ yaw:  127.1 } }, // landing point
        { time: 5, step: 0.1, keepActive: true, pos: { x:   20.4, y: -9.3, z:   1.4 }, ori:{ yaw:   90.9 } }, // looking at quad
        { time: 5, step: 0.1, keepActive: true, pos: { x:  -29.8, y: -9.0, z:  15.0 }, ori:{ yaw: -125.2 } }, // engine pod
        { time: 5, step: 0.1, keepActive: true, pos: { x:  -22.1, y: -4.9, z: -47.3 }, ori:{ yaw:  173.6 } }, // near a chatterbox
        { time: 5, step: 0.1, keepActive: true, pos: { x: -196.8, y: -7.8, z:  82.1 }, ori:{ yaw:   40.7 } }, // capitol
    ]),
    duration: 30
});

testScript.runTests();<commit_msg>Changing name to match filename<commit_after>Script.include("../BenchmarkLib.js");

var TRACING_RULES = "" +
    "trace.*=true\n" +
    "*.detail=true\n" +
    "";

Resources.overrideUrlPrefix(TEST_ROOT, Script.resolvePath(".."));
var testScript = new TestScript();
testScript.addTest({
    name: "measureTimingWWW",
    loader: TestScript.locationLoader("hifi://www", true),
    tracingRules: TRACING_RULES,
    traceActions: TestScript.measureTimingSteps([
        { time: 5, step: 0.1, keepActive: true, pos: { x:   29.2, y: -8.3, z: -26.2 }, ori:{ yaw:  127.1 } }, // landing point
        { time: 5, step: 0.1, keepActive: true, pos: { x:   20.4, y: -9.3, z:   1.4 }, ori:{ yaw:   90.9 } }, // looking at quad
        { time: 5, step: 0.1, keepActive: true, pos: { x:  -29.8, y: -9.0, z:  15.0 }, ori:{ yaw: -125.2 } }, // engine pod
        { time: 5, step: 0.1, keepActive: true, pos: { x:  -22.1, y: -4.9, z: -47.3 }, ori:{ yaw:  173.6 } }, // near a chatterbox
        { time: 5, step: 0.1, keepActive: true, pos: { x: -196.8, y: -7.8, z:  82.1 }, ori:{ yaw:   40.7 } }, // capitol
    ]),
    duration: 30
});

testScript.runTests();
<|endoftext|>


<commit_before>// @flow
import * as Constants from '../constants/signup'
import HiddenString from '../util/hidden-string'
import _ from 'lodash'
import type {CheckInviteCode, CheckUsernameEmail, CheckPassphrase, SubmitDeviceName,
  Signup, ShowPaperKey, ShowSuccess, ResetSignup, RestartSignup, RequestInvite,
  StartRequestInvite, SignupWaiting} from '../constants/signup'
import type {RouteAppend} from '../constants/router'
import type {TypedAsyncAction, AsyncAction} from '../constants/types/flux'
import {Map} from 'immutable'
import {loginTab} from '../constants/tabs'
import {routeAppend, navigateUp} from '../actions/router'
import {signupSignupRpc, signupCheckInvitationCodeRpc, signupCheckUsernameAvailableRpc,
  signupInviteRequestRpc, deviceCheckDeviceNameFormatRpc} from '../constants/types/flow-types'
import {isValidEmail, isValidName, isValidUsername} from '../util/simple-validators'

function nextPhase (): TypedAsyncAction<RouteAppend> {
  return (dispatch, getState) => {
    // TODO careful here since this will not be sync on a remote component!
    const phase: string = getState().signup.phase
    dispatch(routeAppend(phase))
  }
}

export function startRequestInvite (): TypedAsyncAction<StartRequestInvite | RouteAppend> {
  return dispatch => new Promise((resolve, reject) => {
    dispatch({type: Constants.startRequestInvite, payload: {}})
    dispatch(nextPhase())
  })
}

export function checkInviteCode (inviteCode: string): TypedAsyncAction<CheckInviteCode | RouteAppend | SignupWaiting> {
  return dispatch => new Promise((resolve, reject) => {
    dispatch({type: Constants.checkInviteCode, payload: {inviteCode}})

    signupCheckInvitationCodeRpc({
      param: {invitationCode: inviteCode},
      waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
      callback: err => {
        if (err) {
          console.warn('error in inviteCode:', err)
          dispatch(({type: Constants.checkInviteCode, error: true, payload: {errorText: "Sorry, that's not a valid invite code."}}: CheckInviteCode))
          reject(err)
        } else {
          dispatch({type: Constants.checkInviteCode, payload: {inviteCode}})
          dispatch(nextPhase())
          resolve()
        }
      },
    })
  })
}

export function requestInvite (email: string, name: string): TypedAsyncAction<RequestInvite | RouteAppend | SignupWaiting> {
  return dispatch => new Promise((resolve, reject) => {
    // Returns an error string if not valid
    const emailError = isValidEmail(email)
    const nameError = isValidName(name)
    if (emailError || nameError || !email || !name) {
      dispatch(({
        type: Constants.requestInvite,
        error: true,
        payload: {emailError, nameError, email, name},
      }: RequestInvite))
      resolve()
      return
    }

    signupInviteRequestRpc({
      param: {
        email: email,
        fullname: name,
        notes: 'Requested through GUI app',
      },
      waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
      callback: err => {
        if (err) {
          dispatch({
            type: Constants.requestInvite,
            payload: {error: true, emailError: err.message, nameError: null, email, name},
          })
          reject(err)
        } else {
          if (email && name) {
            dispatch({
              type: Constants.requestInvite,
              payload: {error: null, email, name},
            })
            dispatch(nextPhase())
            resolve()
          } else {
            reject(err)
          }
        }
      },
    })
  })
}

export function checkUsernameEmail (username: ?string, email: ?string): TypedAsyncAction<CheckUsernameEmail | RouteAppend | SignupWaiting> {
  return dispatch => new Promise((resolve, reject) => {
    const emailError = isValidEmail(email)
    const usernameError = isValidUsername(username)

    if (emailError || usernameError || !username || !email) {
      dispatch(({
        type: Constants.checkUsernameEmail,
        error: true,
        payload: {emailError, usernameError, email, username},
      }: CheckUsernameEmail))
      resolve()
      return
    }

    signupCheckUsernameAvailableRpc({
      param: {username},
      waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
      callback: err => {
        if (err) {
          console.warn("username isn't available:", err)
          dispatch(({
            type: Constants.checkUsernameEmail,
            error: true,
            payload: {emailError, usernameError: `Username error: ${err.message}`, email, username},
          }: CheckUsernameEmail))
          resolve()
        } else {
          // We need this check to make flow happy. This should never be null
          if (username && email) {
            dispatch({
              type: Constants.checkUsernameEmail,
              payload: {username, email},
            })
            dispatch(nextPhase())
            resolve()
          } else {
            reject()
          }
        }
      },
    })
  })
}

export function checkPassphrase (passphrase1: string, passphrase2: string): TypedAsyncAction<CheckPassphrase | RouteAppend> {
  return dispatch => new Promise((resolve, reject) => {
    let passphraseError = null
    if (!passphrase1 || !passphrase2) {
      passphraseError = new HiddenString('Fields cannot be blank')
    } else if (passphrase1 !== passphrase2) {
      passphraseError = new HiddenString('Passphrases must match')
    } else if (passphrase1.length < 12) {
      passphraseError = new HiddenString('Passphrase must be at least 12 Characters')
    }

    if (passphraseError) {
      dispatch(({
        type: Constants.checkPassphrase,
        error: true,
        payload: {passphraseError},
      }: CheckPassphrase))
    } else {
      dispatch({
        type: Constants.checkPassphrase,
        payload: {passphrase: new HiddenString(passphrase1)},
      })
      dispatch(nextPhase())
    }

    resolve()
  })
}

export function submitDeviceName (deviceName: string, skipMail?: boolean, onDisplayPaperKey?: () => void): TypedAsyncAction<SubmitDeviceName | RouteAppend | Signup | ShowPaperKey | SignupWaiting> {
  return dispatch => new Promise((resolve, reject) => {
    // TODO do some checking on the device name - ideally this is done on the service side
    let deviceNameError = null
    if (_.trim(deviceName).length === 0) {
      deviceNameError = 'Device name must not be empty.'
    }

    if (deviceNameError) {
      dispatch(({
        type: Constants.submitDeviceName,
        error: true,
        payload: {deviceNameError: deviceNameError || '', deviceName},
      }: SubmitDeviceName))
    } else {
      deviceCheckDeviceNameFormatRpc({
        param: {name: deviceName},
        waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
        callback: err => {
          if (err) {
            console.warn('device name is invalid: ', err)
            dispatch(({
              type: Constants.submitDeviceName,
              error: true,
              payload: {deviceNameError: `Device name is invalid: ${err.message}.`, deviceName},
            }: SubmitDeviceName))
            reject(err)
          } else {
            if (deviceName) {
              dispatch(({
                type: Constants.submitDeviceName,
                payload: {deviceName},
              }: SubmitDeviceName))

              const signupPromise = dispatch(signup(skipMail || false, onDisplayPaperKey))
              if (signupPromise) {
                signupPromise.then(resolve, reject)
              } else {
                throw new Error('did not get promise from signup')
              }
            }
          }
        },
      })
    }
  })
}

let paperKeyResponse = null
export function sawPaperKey (): AsyncAction {
  return () => {
    if (paperKeyResponse) {
      paperKeyResponse.result()
      paperKeyResponse = null
    }
  }
}

function signup (skipMail: boolean, onDisplayPaperKey?: () => void): TypedAsyncAction<Signup | ShowPaperKey | RouteAppend | SignupWaiting> {
  return (dispatch, getState) => new Promise((resolve, reject) => {
    const {email, username, inviteCode, passphrase, deviceName} = getState().signup
    paperKeyResponse = null

    if (email && username && inviteCode && passphrase && deviceName) {
      signupSignupRpc({
        waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
        param: {
          deviceName,
          email,
          genPGPBatch: false,
          inviteCode,
          passphrase: passphrase.stringValue(),
          skipMail,
          storeSecret: false,
          username,
        },
        incomingCallMap: {
          'keybase.1.loginUi.displayPrimaryPaperKey': ({sessionID, phrase}, response) => {
            paperKeyResponse = response
            dispatch(({
              type: Constants.showPaperKey,
              payload: {paperkey: new HiddenString(phrase)},
            }: ShowPaperKey))
            onDisplayPaperKey && onDisplayPaperKey()
            dispatch(nextPhase())
          },
          'keybase.1.gpgUi.wantToAddGPGKey': (params, response) => {
            // Do not add a gpg key for now
            response.result(false)
          },
        },
        callback: (err, {passphraseOk, postOk, writeOk}) => {
          if (err) {
            console.warn('error in signup:', err)
            dispatch(({
              type: Constants.signup,
              error: true,
              payload: {signupError: new HiddenString(err.desc)},
            }: Signup))
            dispatch(nextPhase())
            reject()
          } else {
            console.log('Successful signup', passphraseOk, postOk, writeOk)
            dispatch(waiting(true))
            resolve()
          }
        },
      })
    } else {
      console.warn('Entered signup action with a null required field')
      reject()
    }
  })
}

function waiting (isWaiting: boolean): SignupWaiting {
  return {
    type: Constants.signupWaiting,
    payload: isWaiting,
  }
}

export function resetSignup (): ResetSignup {
  return {
    type: Constants.resetSignup,
    payload: undefined,
  }
}

export function restartSignup (): TypedAsyncAction<RestartSignup | RouteAppend> {
  return dispatch => new Promise((resolve, reject) => {
    dispatch({type: Constants.restartSignup, payload: {}})
    dispatch(navigateUp(loginTab, Map({path: 'signup'})))
    dispatch(navigateUp())
    resolve()
  })
}

export function showSuccess (): ShowSuccess {
  return {type: Constants.showSuccess, payload: {}}
}
<commit_msg>Fix undefined error text in actions/signup (#4525)<commit_after>// @flow
import * as Constants from '../constants/signup'
import HiddenString from '../util/hidden-string'
import _ from 'lodash'
import type {CheckInviteCode, CheckUsernameEmail, CheckPassphrase, SubmitDeviceName,
  Signup, ShowPaperKey, ShowSuccess, ResetSignup, RestartSignup, RequestInvite,
  StartRequestInvite, SignupWaiting} from '../constants/signup'
import type {RouteAppend} from '../constants/router'
import type {TypedAsyncAction, AsyncAction} from '../constants/types/flux'
import {Map} from 'immutable'
import {loginTab} from '../constants/tabs'
import {routeAppend, navigateUp} from '../actions/router'
import {signupSignupRpc, signupCheckInvitationCodeRpc, signupCheckUsernameAvailableRpc,
  signupInviteRequestRpc, deviceCheckDeviceNameFormatRpc} from '../constants/types/flow-types'
import {isValidEmail, isValidName, isValidUsername} from '../util/simple-validators'

function nextPhase (): TypedAsyncAction<RouteAppend> {
  return (dispatch, getState) => {
    // TODO careful here since this will not be sync on a remote component!
    const phase: string = getState().signup.phase
    dispatch(routeAppend(phase))
  }
}

export function startRequestInvite (): TypedAsyncAction<StartRequestInvite | RouteAppend> {
  return dispatch => new Promise((resolve, reject) => {
    dispatch({type: Constants.startRequestInvite, payload: {}})
    dispatch(nextPhase())
  })
}

export function checkInviteCode (inviteCode: string): TypedAsyncAction<CheckInviteCode | RouteAppend | SignupWaiting> {
  return dispatch => new Promise((resolve, reject) => {
    dispatch({type: Constants.checkInviteCode, payload: {inviteCode}})

    signupCheckInvitationCodeRpc({
      param: {invitationCode: inviteCode},
      waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
      callback: err => {
        if (err) {
          console.warn('error in inviteCode:', err)
          dispatch(({type: Constants.checkInviteCode, error: true, payload: {errorText: "Sorry, that's not a valid invite code."}}: CheckInviteCode))
          reject(err)
        } else {
          dispatch({type: Constants.checkInviteCode, payload: {inviteCode}})
          dispatch(nextPhase())
          resolve()
        }
      },
    })
  })
}

export function requestInvite (email: string, name: string): TypedAsyncAction<RequestInvite | RouteAppend | SignupWaiting> {
  return dispatch => new Promise((resolve, reject) => {
    // Returns an error string if not valid
    const emailError = isValidEmail(email)
    const nameError = isValidName(name)
    if (emailError || nameError || !email || !name) {
      dispatch(({
        type: Constants.requestInvite,
        error: true,
        payload: {emailError, nameError, email, name},
      }: RequestInvite))
      resolve()
      return
    }

    signupInviteRequestRpc({
      param: {
        email: email,
        fullname: name,
        notes: 'Requested through GUI app',
      },
      waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
      callback: err => {
        if (err) {
          dispatch(({
            type: Constants.requestInvite,
            error: true,
            payload: {emailError: err.desc, nameError: null, email, name},
          }: RequestInvite))
          reject(err)
        } else {
          if (email && name) {
            dispatch({
              type: Constants.requestInvite,
              payload: {error: null, email, name},
            })
            dispatch(nextPhase())
            resolve()
          } else {
            reject(err)
          }
        }
      },
    })
  })
}

export function checkUsernameEmail (username: ?string, email: ?string): TypedAsyncAction<CheckUsernameEmail | RouteAppend | SignupWaiting> {
  return dispatch => new Promise((resolve, reject) => {
    const emailError = isValidEmail(email)
    const usernameError = isValidUsername(username)

    if (emailError || usernameError || !username || !email) {
      dispatch(({
        type: Constants.checkUsernameEmail,
        error: true,
        payload: {emailError, usernameError, email, username},
      }: CheckUsernameEmail))
      resolve()
      return
    }

    signupCheckUsernameAvailableRpc({
      param: {username},
      waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
      callback: err => {
        if (err) {
          console.warn("username isn't available:", err)
          dispatch(({
            type: Constants.checkUsernameEmail,
            error: true,
            payload: {emailError, usernameError: `Username error: ${err.desc}`, email, username},
          }: CheckUsernameEmail))
          resolve()
        } else {
          // We need this check to make flow happy. This should never be null
          if (username && email) {
            dispatch({
              type: Constants.checkUsernameEmail,
              payload: {username, email},
            })
            dispatch(nextPhase())
            resolve()
          } else {
            reject()
          }
        }
      },
    })
  })
}

export function checkPassphrase (passphrase1: string, passphrase2: string): TypedAsyncAction<CheckPassphrase | RouteAppend> {
  return dispatch => new Promise((resolve, reject) => {
    let passphraseError = null
    if (!passphrase1 || !passphrase2) {
      passphraseError = new HiddenString('Fields cannot be blank')
    } else if (passphrase1 !== passphrase2) {
      passphraseError = new HiddenString('Passphrases must match')
    } else if (passphrase1.length < 12) {
      passphraseError = new HiddenString('Passphrase must be at least 12 Characters')
    }

    if (passphraseError) {
      dispatch(({
        type: Constants.checkPassphrase,
        error: true,
        payload: {passphraseError},
      }: CheckPassphrase))
    } else {
      dispatch({
        type: Constants.checkPassphrase,
        payload: {passphrase: new HiddenString(passphrase1)},
      })
      dispatch(nextPhase())
    }

    resolve()
  })
}

export function submitDeviceName (deviceName: string, skipMail?: boolean, onDisplayPaperKey?: () => void): TypedAsyncAction<SubmitDeviceName | RouteAppend | Signup | ShowPaperKey | SignupWaiting> {
  return dispatch => new Promise((resolve, reject) => {
    // TODO do some checking on the device name - ideally this is done on the service side
    let deviceNameError = null
    if (_.trim(deviceName).length === 0) {
      deviceNameError = 'Device name must not be empty.'
    }

    if (deviceNameError) {
      dispatch(({
        type: Constants.submitDeviceName,
        error: true,
        payload: {deviceNameError: deviceNameError || '', deviceName},
      }: SubmitDeviceName))
    } else {
      deviceCheckDeviceNameFormatRpc({
        param: {name: deviceName},
        waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
        callback: err => {
          if (err) {
            console.warn('device name is invalid: ', err)
            dispatch(({
              type: Constants.submitDeviceName,
              error: true,
              payload: {deviceNameError: `Device name is invalid: ${err.desc}.`, deviceName},
            }: SubmitDeviceName))
            reject(err)
          } else {
            if (deviceName) {
              dispatch(({
                type: Constants.submitDeviceName,
                payload: {deviceName},
              }: SubmitDeviceName))

              const signupPromise = dispatch(signup(skipMail || false, onDisplayPaperKey))
              if (signupPromise) {
                signupPromise.then(resolve, reject)
              } else {
                throw new Error('did not get promise from signup')
              }
            }
          }
        },
      })
    }
  })
}

let paperKeyResponse = null
export function sawPaperKey (): AsyncAction {
  return () => {
    if (paperKeyResponse) {
      paperKeyResponse.result()
      paperKeyResponse = null
    }
  }
}

function signup (skipMail: boolean, onDisplayPaperKey?: () => void): TypedAsyncAction<Signup | ShowPaperKey | RouteAppend | SignupWaiting> {
  return (dispatch, getState) => new Promise((resolve, reject) => {
    const {email, username, inviteCode, passphrase, deviceName} = getState().signup
    paperKeyResponse = null

    if (email && username && inviteCode && passphrase && deviceName) {
      signupSignupRpc({
        waitingHandler: isWaiting => { dispatch(waiting(isWaiting)) },
        param: {
          deviceName,
          email,
          genPGPBatch: false,
          inviteCode,
          passphrase: passphrase.stringValue(),
          skipMail,
          storeSecret: false,
          username,
        },
        incomingCallMap: {
          'keybase.1.loginUi.displayPrimaryPaperKey': ({sessionID, phrase}, response) => {
            paperKeyResponse = response
            dispatch(({
              type: Constants.showPaperKey,
              payload: {paperkey: new HiddenString(phrase)},
            }: ShowPaperKey))
            onDisplayPaperKey && onDisplayPaperKey()
            dispatch(nextPhase())
          },
          'keybase.1.gpgUi.wantToAddGPGKey': (params, response) => {
            // Do not add a gpg key for now
            response.result(false)
          },
        },
        callback: (err, {passphraseOk, postOk, writeOk}) => {
          if (err) {
            console.warn('error in signup:', err)
            dispatch(({
              type: Constants.signup,
              error: true,
              payload: {signupError: new HiddenString(err.desc)},
            }: Signup))
            dispatch(nextPhase())
            reject()
          } else {
            console.log('Successful signup', passphraseOk, postOk, writeOk)
            dispatch(waiting(true))
            resolve()
          }
        },
      })
    } else {
      console.warn('Entered signup action with a null required field')
      reject()
    }
  })
}

function waiting (isWaiting: boolean): SignupWaiting {
  return {
    type: Constants.signupWaiting,
    payload: isWaiting,
  }
}

export function resetSignup (): ResetSignup {
  return {
    type: Constants.resetSignup,
    payload: undefined,
  }
}

export function restartSignup (): TypedAsyncAction<RestartSignup | RouteAppend> {
  return dispatch => new Promise((resolve, reject) => {
    dispatch({type: Constants.restartSignup, payload: {}})
    dispatch(navigateUp(loginTab, Map({path: 'signup'})))
    dispatch(navigateUp())
    resolve()
  })
}

export function showSuccess (): ShowSuccess {
  return {type: Constants.showSuccess, payload: {}}
}
<|endoftext|>


<commit_before><commit_msg>fix typo<commit_after><|endoftext|>


<commit_before><commit_msg>fixed a thing that on node 6.x doesn't work<commit_after><|endoftext|>


<commit_before><commit_msg>Added View Update Insert and Delecte Code<commit_after><|endoftext|>


<commit_before>/**
 *
 * NUT adapter
 *
 * Adapter loading NUT data from an UPS
 *
 */

"use strict";

var utils = require(__dirname + '/lib/utils'); // Get common adapter utils
var Nut   = require('node-nut');

var adapter = utils.adapter({
  name: 'nut',
  ready: function () {
    //oNut = new Nut(3493, 'localhost');
    var oNut = new Nut(adapter.config.host_port, adapter.config.host_ip);

    oNut.on('error', function(err) {
      adapter.log.error('Error happend: ' + err);
    });

    oNut.on('close', function() {
      adapter.log.debug('NUT Connection closed. Done.');
      setTimeout(function () {
        adapter.stop();
      }, 2000);
    });

    oNut.on('ready', function() {
      adapter.log.debug('NUT Connection ready');
      var self = this;
      this.GetUPSVars(adapter.config.ups_name,function(varlist) {
        adapter.log.debug('Got values, start setting them');
        storeNutData(varlist);
        self.close();
      });
    });

    oNut.start();
  }
});

adapter.on('stateChange', function (id, state) {
    adapter.log.debug('stateChange ' + id + ' ' + JSON.stringify(state));

    // you can use the ack flag to detect if state is command(false) or status(true)
    if (!state.ack) {
        adapter.log.info('ack is not set!');
    }
});

function storeNutData(varlist) {
  var last='';
  var current='';
  var index=0;
  var stateName='';

  for (var key in varlist) {
    index=key.indexOf('.');
    if (index > 0) {
      current=key.substring(0,index);
    }
    else {
      current='';
      last='';
      index=-1;
    }
    if (((last=='') || (last!=current)) && (current!='')) {
      adapter.log.debug('Create Channel '+current);
      adapter.setObjectNotExists(current, {
          type: 'channel',
          common: {name: current},
          native: {}
      });
    }
    stateName=current+'.'+key.substring(index+1).replace(/\./g,'-');
    adapter.log.debug('Create State '+stateName);
    if (stateName=='battery.charge') {
      adapter.setObjectNotExists(stateName, {
          type: 'state',
          common: {name: stateName, type: 'number', role: 'value.battery', read: true, write: false},
          native: {id: stateName}
      });
    }
    else {
      adapter.setObjectNotExists(stateName, {
          type: 'state',
          common: {name: stateName, type: 'string', read: true, write: false},
          native: {id: stateName}
      });
    }
    adapter.log.debug('Set State '+stateName+' = '+varlist[key]);
    adapter.setState(stateName, {ack: true, val: varlist[key]});
    last=current;
  }

  // Command Datapoint to be used with "NOIFY EVENTS" and upsmon
  /*
ONLINE

    The UPS is back on line.
ONBATT

    The UPS is on battery.
LOWBATT

    The UPS battery is low (as determined by the driver).
FSD

    The UPS has been commanded into the "forced shutdown" mode.
COMMOK

    Communication with the UPS has been established.
COMMBAD

    Communication with the UPS was just lost.
SHUTDOWN

    The local system is being shut down.
REPLBATT

    The UPS needs to have its battery replaced.
NOCOMM

    The UPS can’t be contacted for monitoring.
*/
  adapter.setObjectNotExists(stateName, {
      type: 'state',
      common: {
        name: 'upsmon_event',
        type: 'string',
        read: true,
        write: true,
        def:""
      },
      native: {id: stateName}
  });
  adapter.subscribeStates('upsmon_event');

  adapter.log.debug('Create Channel status');
  adapter.setObjectNotExists(current, {
      type: 'channel',
      common: {name: 'status'},
      native: {}
  });
  var severityVal = 'unknown';
  adapter.setObjectNotExists(stateName, {
      type: 'state',
      common: {
        name: 'status.severity',
        role: 'indicator',
        type: 'number',
        read: true,
        write: false,
        def:4,
        states: '0:idle;1:operating;2:operating_critical;3:action_needed;4:unknown'
      },
      native: {id: stateName}
  });
  if (varlist['ups.status']) {
    var statusMap = {
              'OL':{name:'online',severity:'idle'},
              'OB':{name:'onbattery',severity:'operating'},
              'LB':{name:'lowbattery',severity:'operating_critical'},
              'HB':{name:'highbattery',severity:'operating_critical'},
              'RB':{name:'replacebattery',severity:'action_needed'},
              'CHRG':{name:'charging',severity:'operating'},
              'DISCHRG':{name:'discharging',severity:'operating'},
              'BYPASS':{name:'bypass',severity:'action_needed'},
              'CAL':{name:'calibration',severity:'operating'},
              'OFF':{name:'offline',severity:'action_needed'},
              'OVER':{name:'overload',severity:'action_needed'},
              'TRIM':{name:'trimming',severity:'operating'},
              'BOOST':{name:'boosting',severity:'operating'},
              'FSD':{name:'shutdown',severity:'operating_critical'}
            };
    var severity = {
              'idle':false,
              'operating':false,
              'operating_critical':false,
              'action_needed':false
            };
    var checker=' '+varlist['ups.status']+' ';
    for (var idx in statusMap) {
      if (statusMap.hasOwnProperty(idx)) {
        var found=(checker.indexOf(idx)>-1);
        stateName='status.'+statusMap[idx]['name'];
        adapter.log.debug('Create State '+stateName);
        adapter.setObjectNotExists(stateName, {
            type: 'state',
            common: {name: stateName, type: 'boolean', read: true, write: false},
            native: {id: stateName}
        });
        adapter.log.debug('Set State '+stateName+' = '+found);
        adapter.setState(stateName, {ack: true, val: found});
        if (found) {
          severity[statusMap[idx]['severity']]=true;
          adapter.log.debug('Severity Flag '+statusMap[idx]['severity']+'=true');
        }
      }
    }
    if (severity['operating_critical']) severityVal='operating_critical';
      else if (severity['action_needed']) severityVal='action_needed';
      else if (severity['operating']) severityVal='operating';
      else if (severity['idle']) severityVal='idle';
  }
  adapter.log.debug('Set State status.severity = '+severityVal);
  adapter.setState('status.severity', {ack: true, val: severityVal});

  adapter.log.info('All Nut values set');
}
<commit_msg>severity content change to numbers<commit_after>/**
 *
 * NUT adapter
 *
 * Adapter loading NUT data from an UPS
 *
 */

"use strict";

var utils = require(__dirname + '/lib/utils'); // Get common adapter utils
var Nut   = require('node-nut');

var adapter = utils.adapter({
  name: 'nut',
  ready: function () {
    //oNut = new Nut(3493, 'localhost');
    var oNut = new Nut(adapter.config.host_port, adapter.config.host_ip);

    oNut.on('error', function(err) {
      adapter.log.error('Error happend: ' + err);
    });

    oNut.on('close', function() {
      adapter.log.debug('NUT Connection closed. Done.');
      setTimeout(function () {
        adapter.stop();
      }, 2000);
    });

    oNut.on('ready', function() {
      adapter.log.debug('NUT Connection ready');
      var self = this;
      this.GetUPSVars(adapter.config.ups_name,function(varlist) {
        adapter.log.debug('Got values, start setting them');
        storeNutData(varlist);
        self.close();
      });
    });

    oNut.start();
  }
});

adapter.on('stateChange', function (id, state) {
    adapter.log.debug('stateChange ' + id + ' ' + JSON.stringify(state));

    // you can use the ack flag to detect if state is command(false) or status(true)
    if (!state.ack) {
        adapter.log.info('ack is not set!');
    }
});

function storeNutData(varlist) {
  var last='';
  var current='';
  var index=0;
  var stateName='';

  for (var key in varlist) {
    index=key.indexOf('.');
    if (index > 0) {
      current=key.substring(0,index);
    }
    else {
      current='';
      last='';
      index=-1;
    }
    if (((last=='') || (last!=current)) && (current!='')) {
      adapter.log.debug('Create Channel '+current);
      adapter.setObjectNotExists(current, {
          type: 'channel',
          common: {name: current},
          native: {}
      });
    }
    stateName=current+'.'+key.substring(index+1).replace(/\./g,'-');
    adapter.log.debug('Create State '+stateName);
    if (stateName=='battery.charge') {
      adapter.setObjectNotExists(stateName, {
          type: 'state',
          common: {name: stateName, type: 'number', role: 'value.battery', read: true, write: false},
          native: {id: stateName}
      });
    }
    else {
      adapter.setObjectNotExists(stateName, {
          type: 'state',
          common: {name: stateName, type: 'string', read: true, write: false},
          native: {id: stateName}
      });
    }
    adapter.log.debug('Set State '+stateName+' = '+varlist[key]);
    adapter.setState(stateName, {ack: true, val: varlist[key]});
    last=current;
  }

  // Command Datapoint to be used with "NOIFY EVENTS" and upsmon
  /*
ONLINE

    The UPS is back on line.
ONBATT

    The UPS is on battery.
LOWBATT

    The UPS battery is low (as determined by the driver).
FSD

    The UPS has been commanded into the "forced shutdown" mode.
COMMOK

    Communication with the UPS has been established.
COMMBAD

    Communication with the UPS was just lost.
SHUTDOWN

    The local system is being shut down.
REPLBATT

    The UPS needs to have its battery replaced.
NOCOMM

    The UPS can’t be contacted for monitoring.
*/
  adapter.setObjectNotExists(stateName, {
      type: 'state',
      common: {
        name: 'upsmon_event',
        type: 'string',
        read: true,
        write: true,
        def:""
      },
      native: {id: stateName}
  });
  adapter.subscribeStates('upsmon_event');

  adapter.log.debug('Create Channel status');
  adapter.setObjectNotExists(current, {
      type: 'channel',
      common: {name: 'status'},
      native: {}
  });
  var severityVal = 'unknown';
  adapter.setObjectNotExists(stateName, {
      type: 'state',
      common: {
        name: 'status.severity',
        role: 'indicator',
        type: 'number',
        read: true,
        write: false,
        def:4,
        states: '0:idle;1:operating;2:operating_critical;3:action_needed;4:unknown'
      },
      native: {id: stateName}
  });
  if (varlist['ups.status']) {
    var statusMap = {
              'OL':{name:'online',severity:0}, // idle
              'OB':{name:'onbattery',severity:1}, // operating
              'LB':{name:'lowbattery',severity:2}, // operating_critical
              'HB':{name:'highbattery',severity:2}, // operating_critical
              'RB':{name:'replacebattery',severity:3}, // action_needed
              'CHRG':{name:'charging',severity:0}, // idle
              'DISCHRG':{name:'discharging',severity:1}, // operating
              'BYPASS':{name:'bypass',severity:3}, // action_needed
              'CAL':{name:'calibration',severity:1}, // operating
              'OFF':{name:'offline',severity:3}, // action_needed
              'OVER':{name:'overload',severity:3}, // action_needed
              'TRIM':{name:'trimming',severity:1}, // operating
              'BOOST':{name:'boosting',severity:1}, // operating
              'FSD':{name:'shutdown',severity:2} // operating_critical
            };
    var severity = {
              0:false,
              1:false,
              2:false,
              3:false
            };
    var checker=' '+varlist['ups.status']+' ';
    for (var idx in statusMap) {
      if (statusMap.hasOwnProperty(idx)) {
        var found=(checker.indexOf(idx)>-1);
        stateName='status.'+statusMap[idx]['name'];
        adapter.log.debug('Create State '+stateName);
        adapter.setObjectNotExists(stateName, {
            type: 'state',
            common: {name: stateName, type: 'boolean', read: true, write: false},
            native: {id: stateName}
        });
        adapter.log.debug('Set State '+stateName+' = '+found);
        adapter.setState(stateName, {ack: true, val: found});
        if (found) {
          severity[statusMap[idx]['severity']]=true;
          adapter.log.debug('Severity Flag '+statusMap[idx]['severity']+'=true');
        }
      }
    }
    if (severity['operating_critical']) severityVal='operating_critical';
      else if (severity['action_needed']) severityVal='action_needed';
      else if (severity['operating']) severityVal='operating';
      else if (severity['idle']) severityVal='idle';
  }
  adapter.log.debug('Set State status.severity = '+severityVal);
  adapter.setState('status.severity', {ack: true, val: severityVal});

  adapter.log.info('All Nut values set');
}
<|endoftext|>


<commit_before>/**
 * Seedable random number generator functions.
 * @version 1.0
 * @license Public Domain
 *
 * @example
 * var rng = new RNG('Example');
 * rng.random(40, 50);  //  42
 * rng.uniform();       //  0.7972798995050903
 * rng.normal();        // -0.6698504543216376
 * rng.exponential();   //  1.0547367609131555
 * rng.poisson(4);      //  2
 */

/**
 * Get the underlying bytes of this string.
 * @returns {Array} An array of bytes
 */
String.prototype.getBytes = function() {
    var output = [];
    for (var i = 0; i < this.length; i++) {
        var c = this.charCodeAt(i);
        var bytes = [];
        do {
            bytes.push(c & 0xFF);
            c = c >> 8;
        } while (c > 0);
        output = output.concat(bytes.reverse());
    }
    return output;
};

/**
 * @param {String} seed A string to seed the generator.
 * @constructor
 */
function RC4(seed) {
    this.s = new Array(256);
    this.i = 0;
    this.j = 0;
    for (var i = 0; i < 256; i++) {
        this.s[i] = i;
    }
    if (seed) {
        this.mix(seed);
    }
}

RC4.prototype._swap = function(i, j) {
    var tmp = this.s[i];
    this.s[i] = this.s[j];
    this.s[j] = tmp;
};

/**
 * Mix additional entropy into this generator.
 * @param {String} seed
 */
RC4.prototype.mix = function(seed) {
    var input = seed.getBytes();
    var j = 0;
    for (var i = 0; i < this.s.length; i++) {
        j += this.s[i] + input[i % input.length];
        j %= 256;
        this._swap(i, j);
    }
};

/**
 * @returns {number} The next byte of output from the generator.
 */
RC4.prototype.next = function() {
    this.i = (this.i + 1) % 256;
    this.j = (this.j + this.s[this.i]) % 256;
    this._swap(this.i, this.j);
    return this.s[(this.s[this.i] + this.s[this.j]) % 256];
};

/**
 * Create a new random number generator with optional seed. If the
 * provided seed is a function (i.e. Math.random) it will be used as
 * the uniform number generator.
 * @param seed An arbitrary object used to seed the generator.
 * @constructor
 */
function RNG(seed) {
    if (seed == null) {
        seed = (Math.random() + Date.now()).toString();
    } else if (typeof seed === "function") {
        // Use it as a uniform number generator
        this.uniform = seed;
        this.nextByte = function() {
            return ~~(this.uniform * 256);
        };
        seed = null;
    } else if (Object.prototype.toString.call(seed) !== "[object String]") {
        seed = JSON.stringify(seed);
    }
    this._normal = null;
    if (seed) {
        this._state = new RC4(seed);
    } else {
        this._state = null;
    }
}

/**
 * @returns {number} Uniform random number between 0 and 255.
 */
RNG.prototype.nextByte = function() {
    return this._state.next();
};

/**
 * @returns {number} Uniform random number between 0 and 1.
 */
RNG.prototype.uniform = function() {
    var BYTES = 7; // 56 bits to make a 53-bit double
    var output = 0;
    for (var i = 0; i < BYTES; i++) {
        output *= 256;
        output += this.nextByte();
    }
    return output / (Math.pow(2, BYTES * 8) - 1);
};

/**
 * Produce a random integer within [n, m).
 * @param {number} [n=0]
 * @param {number} m
 *
 */
RNG.prototype.random = function(n, m) {
    if (n == null) {
        return this.uniform();
    } else if (m == null) {
        m = n;
        n = 0;
    }
    return n + Math.floor(this.uniform() * (m - n));
};

/**
 * Generates numbers using this.uniform() with the Box-Muller transform.
 * @returns {number} Normally-distributed random number of mean 0, variance 1.
 */
RNG.prototype.normal = function() {
    if (this._normal !== null) {
        var n = this._normal;
        this._normal = null;
        return n;
    } else {
        var x = this.uniform() || Math.pow(2, -53); // can't be exactly 0
        var y = this.uniform();
        this._normal = Math.sqrt(-2 * Math.log(x)) * Math.sin(2 * Math.PI * y);
        return Math.sqrt(-2 * Math.log(x)) * Math.cos(2 * Math.PI * y);
    }
};

/**
 * Generates numbers using this.uniform().
 * @returns {number} Number from the exponential distribution, lambda = 1.
 */
RNG.prototype.exponential = function() {
    return -Math.log(this.uniform() || Math.pow(2, -53));
};

/**
 * Generates numbers using this.uniform().
 * @param {number} [mean=1]
 * @returns {number} Number from the Poisson distribution.
 */
RNG.prototype.poisson = function(mean) {
    var L = Math.exp(-(mean || 1));
    var k = 0, p = 1;
    do {
        k++;
        p *= this.uniform();
    } while (p > L);
    return k - 1;
};
<commit_msg>Add note about algorithm.<commit_after>/**
 * Seedable random number generator functions.
 * @version 1.0
 * @license Public Domain
 *
 * @example
 * var rng = new RNG('Example');
 * rng.random(40, 50);  //  42
 * rng.uniform();       //  0.7972798995050903
 * rng.normal();        // -0.6698504543216376
 * rng.exponential();   //  1.0547367609131555
 * rng.poisson(4);      //  2
 */

/**
 * Get the underlying bytes of this string.
 * @returns {Array} An array of bytes
 */
String.prototype.getBytes = function() {
    var output = [];
    for (var i = 0; i < this.length; i++) {
        var c = this.charCodeAt(i);
        var bytes = [];
        do {
            bytes.push(c & 0xFF);
            c = c >> 8;
        } while (c > 0);
        output = output.concat(bytes.reverse());
    }
    return output;
};

/**
 * @param {String} seed A string to seed the generator.
 * @constructor
 */
function RC4(seed) {
    this.s = new Array(256);
    this.i = 0;
    this.j = 0;
    for (var i = 0; i < 256; i++) {
        this.s[i] = i;
    }
    if (seed) {
        this.mix(seed);
    }
}

RC4.prototype._swap = function(i, j) {
    var tmp = this.s[i];
    this.s[i] = this.s[j];
    this.s[j] = tmp;
};

/**
 * Mix additional entropy into this generator.
 * @param {String} seed
 */
RC4.prototype.mix = function(seed) {
    var input = seed.getBytes();
    var j = 0;
    for (var i = 0; i < this.s.length; i++) {
        j += this.s[i] + input[i % input.length];
        j %= 256;
        this._swap(i, j);
    }
};

/**
 * @returns {number} The next byte of output from the generator.
 */
RC4.prototype.next = function() {
    this.i = (this.i + 1) % 256;
    this.j = (this.j + this.s[this.i]) % 256;
    this._swap(this.i, this.j);
    return this.s[(this.s[this.i] + this.s[this.j]) % 256];
};

/**
 * Create a new random number generator with optional seed. If the
 * provided seed is a function (i.e. Math.random) it will be used as
 * the uniform number generator.
 * @param seed An arbitrary object used to seed the generator.
 * @constructor
 */
function RNG(seed) {
    if (seed == null) {
        seed = (Math.random() + Date.now()).toString();
    } else if (typeof seed === "function") {
        // Use it as a uniform number generator
        this.uniform = seed;
        this.nextByte = function() {
            return ~~(this.uniform * 256);
        };
        seed = null;
    } else if (Object.prototype.toString.call(seed) !== "[object String]") {
        seed = JSON.stringify(seed);
    }
    this._normal = null;
    if (seed) {
        this._state = new RC4(seed);
    } else {
        this._state = null;
    }
}

/**
 * @returns {number} Uniform random number between 0 and 255.
 */
RNG.prototype.nextByte = function() {
    return this._state.next();
};

/**
 * @returns {number} Uniform random number between 0 and 1.
 */
RNG.prototype.uniform = function() {
    var BYTES = 7; // 56 bits to make a 53-bit double
    var output = 0;
    for (var i = 0; i < BYTES; i++) {
        output *= 256;
        output += this.nextByte();
    }
    return output / (Math.pow(2, BYTES * 8) - 1);
};

/**
 * Produce a random integer within [n, m).
 * @param {number} [n=0]
 * @param {number} m
 *
 */
RNG.prototype.random = function(n, m) {
    if (n == null) {
        return this.uniform();
    } else if (m == null) {
        m = n;
        n = 0;
    }
    return n + Math.floor(this.uniform() * (m - n));
};

/**
 * Generates numbers using this.uniform() with the Box-Muller transform.
 * @returns {number} Normally-distributed random number of mean 0, variance 1.
 */
RNG.prototype.normal = function() {
    if (this._normal !== null) {
        var n = this._normal;
        this._normal = null;
        return n;
    } else {
        var x = this.uniform() || Math.pow(2, -53); // can't be exactly 0
        var y = this.uniform();
        this._normal = Math.sqrt(-2 * Math.log(x)) * Math.sin(2 * Math.PI * y);
        return Math.sqrt(-2 * Math.log(x)) * Math.cos(2 * Math.PI * y);
    }
};

/**
 * Generates numbers using this.uniform().
 * @returns {number} Number from the exponential distribution, lambda = 1.
 */
RNG.prototype.exponential = function() {
    return -Math.log(this.uniform() || Math.pow(2, -53));
};

/**
 * Generates numbers using this.uniform() and Knuth's method.
 * @param {number} [mean=1]
 * @returns {number} Number from the Poisson distribution.
 */
RNG.prototype.poisson = function(mean) {
    var L = Math.exp(-(mean || 1));
    var k = 0, p = 1;
    do {
        k++;
        p *= this.uniform();
    } while (p > L);
    return k - 1;
};
<|endoftext|>