<commit_before>'use strict';

angular.module('app')
    .controller('rgiNewAssessmentDialogCtrl', function (
        $scope,
        $route,
        $rootScope,
        $location,
        rgiAnswerMethodSrvc,
        rgiAssessmentMethodSrvc,
        rgiAssessmentSrvc,
        rgiCountrySrvc,
        rgiHttpResponseProcessorSrvc,
        rgiIdentitySrvc,
        MINERAL_TAGS_SET,
        rgiNotifier,
        rgiQuestionMethodSrvc,
        rgiQuestionSrvc,
        rgiUtilsSrvc
    ) {
        rgiCountrySrvc.query({country_use: true}, function(countries) {
            $scope.countries = countries;
        }, rgiHttpResponseProcessorSrvc.getDefaultHandler('Load country data failure'));

        $scope.disable_button = false;
        //TODO
        //rgiCountrySrvc.query({}, function (countries) {
        //    var country_values = {},
        //        country_selector = [];
        //
        //    countries.forEach(function (el) {
        //        var add_obj = {value: el.iso2, name: el.country};
        //        country_values[el.iso2] = el;
        //        country_values[el.iso2].index = country_selector.length;
        //        country_selector.push(add_obj);
        //    });
        //    $scope.country_values = country_values;
        //    $scope.country_selector = country_selector;
        //});

        $scope.new_assessment = {
            year: $scope.year ? parseInt($scope.year) : '',
            version: $scope.version || '',
            assessment_countries: [{}]
        };

        var currentYear = new Date().getFullYear();
        $scope.years = [];

        for (var yearIncrement = 0; yearIncrement < 6; yearIncrement++) {
            $scope.years.push(currentYear + yearIncrement);
        }
        // TODO remove country from countries scope when added to new assessments
        $scope.addCountry = function () {
            $scope.new_assessment.assessment_countries.push({country: ''});
        };

        $scope.getAvailableMinerals = function() {
            return MINERAL_TAGS_SET;
        };

        $scope.deleteCountry = function (index) {
            $scope.new_assessment.assessment_countries.splice(index, 1);
        };

        $scope.deployAssessment = function () {
            if($scope.new_assessment.year === undefined) {
                return rgiNotifier.error('Please, select the assessment year');
            } else if($scope.new_assessment.version === undefined) {
                return rgiNotifier.error('Please, select the assessment version');
            } else if(($scope.new_assessment.version === 'mining') && ($scope.new_assessment.mineral === undefined)) {
                return rgiNotifier.error('Please, select the assessment mineral');
            }

            var countrySelected = true;

            $scope.new_assessment.assessment_countries.forEach(function(countryData) {
                if(!countryData.country) {
                    countrySelected = false;
                }
            });

            if(!countrySelected) {
                return rgiNotifier.error('Please, select the assessment country');
            }

            var new_assessment_ID, new_answer_set,
                new_assessment_set = [],
                new_assessment_year = String($scope.new_assessment.year),
                new_assessment_ver = $scope.new_assessment.version.slice(0, 2).toUpperCase(),
                timestamp = new Date().toISOString();

            $scope.disable_button = true;

            rgiAssessmentSrvc.query({year: new_assessment_year, version: $scope.new_assessment.version}, function (assessments) {
                var country_deployed = {value: false};

                assessments.forEach(function (assessment) {
                    $scope.new_assessment.assessment_countries.forEach(function(country) {
                        if (country.country.country===assessment.country) {
                            country_deployed.value = true;
                            country_deployed.country = assessment.country;
                        }
                    });
                });

                if (country_deployed.value) {
                    rgiNotifier.error(country_deployed.country + ' assessment already deployed');
                    $scope.disable_button = false;
                } else {
                    rgiQuestionSrvc.query({assessment_ID: 'base'}, function (questions) {
                        questions.forEach(function (question) {
                            if (question.assessments.indexOf(new_assessment_year + "-" + new_assessment_ver) < 0) {
                                question.assessments.push(new_assessment_year + "-" + new_assessment_ver);
                            }
                        });

                        $scope.new_assessment.assessment_countries.forEach(function (assessment_country) {
                            new_answer_set = [];

                            new_assessment_ID = assessment_country.country.iso2 + "-" + new_assessment_year + "-" + new_assessment_ver;

                            new_assessment_set.push({
                                assessment_ID: new_assessment_ID,
                                ISO3: assessment_country.country.country_ID,
                                year: $scope.new_assessment.year,
                                version: $scope.new_assessment.version,
                                mineral: $scope.new_assessment.mineral,
                                country: assessment_country.country.country,
                                created: {
                                    created_by: rgiIdentitySrvc.currentUser._id,
                                    created_date: timestamp}
                            });

                            questions.forEach(function (q) {
                                new_answer_set.push({
                                    answer_ID: new_assessment_ID + '-' + String(rgiUtilsSrvc.zeroFill(q.question_order, 3)),
                                    question_ID: q._id,
                                    question_trial: q.question_trial,
                                    assessment_ID: new_assessment_ID,
                                    year: new_assessment_year,
                                    version: new_assessment_ver,
                                    question_order: q.question_order,
                                    question_v: q.question_v + 1,
                                    last_modified: {modified_by: rgiIdentitySrvc.currentUser._id}
                                });
                            });
                            rgiAnswerMethodSrvc.insertAnswerSet(new_answer_set)
                                .then(function () {
                                }, function (reason) {rgiNotifier.error(reason);}
                            );
                        });

                        //send to mongo
                        rgiAssessmentMethodSrvc.createAssessment(new_assessment_set)
                            .then(rgiQuestionMethodSrvc.updateQuestionSet(questions))
                            .then(function () {
                                rgiNotifier.notify('Assessment deployed!');
                                $scope.closeThisDialog();
                                $route.reload();
                                $location.path('admin/assessment-admin');
                            }, function (reason) {
                                rgiNotifier.error(reason);
                            });
                    }, rgiHttpResponseProcessorSrvc.getDefaultHandler('Load question data failure'));
                }
            }, rgiHttpResponseProcessorSrvc.getDefaultHandler('Load assessment data failure'));
        };
    });
<commit_msg>sort countries in the dropdown<commit_after>'use strict';

angular.module('app')
    .controller('rgiNewAssessmentDialogCtrl', function (
        $scope,
        $route,
        $rootScope,
        $location,
        rgiAnswerMethodSrvc,
        rgiAssessmentMethodSrvc,
        rgiAssessmentSrvc,
        rgiCountrySrvc,
        rgiHttpResponseProcessorSrvc,
        rgiIdentitySrvc,
        MINERAL_TAGS_SET,
        rgiNotifier,
        rgiQuestionMethodSrvc,
        rgiQuestionSrvc,
        rgiUtilsSrvc
    ) {
        rgiCountrySrvc.query({country_use: true}, function(countries) {
            countries.sort(function(countryA, countryB) {
                return countryA.country > countryB.country;
            });

            $scope.countries = countries;
        }, rgiHttpResponseProcessorSrvc.getDefaultHandler('Load country data failure'));

        $scope.disable_button = false;
        //TODO
        //rgiCountrySrvc.query({}, function (countries) {
        //    var country_values = {},
        //        country_selector = [];
        //
        //    countries.forEach(function (el) {
        //        var add_obj = {value: el.iso2, name: el.country};
        //        country_values[el.iso2] = el;
        //        country_values[el.iso2].index = country_selector.length;
        //        country_selector.push(add_obj);
        //    });
        //    $scope.country_values = country_values;
        //    $scope.country_selector = country_selector;
        //});

        $scope.new_assessment = {
            year: $scope.year ? parseInt($scope.year) : '',
            version: $scope.version || '',
            assessment_countries: [{}]
        };

        var currentYear = new Date().getFullYear();
        $scope.years = [];

        for (var yearIncrement = 0; yearIncrement < 6; yearIncrement++) {
            $scope.years.push(currentYear + yearIncrement);
        }
        // TODO remove country from countries scope when added to new assessments
        $scope.addCountry = function () {
            $scope.new_assessment.assessment_countries.push({country: ''});
        };

        $scope.getAvailableMinerals = function() {
            return MINERAL_TAGS_SET;
        };

        $scope.deleteCountry = function (index) {
            $scope.new_assessment.assessment_countries.splice(index, 1);
        };

        $scope.deployAssessment = function () {
            if($scope.new_assessment.year === undefined) {
                return rgiNotifier.error('Please, select the assessment year');
            } else if($scope.new_assessment.version === undefined) {
                return rgiNotifier.error('Please, select the assessment version');
            } else if(($scope.new_assessment.version === 'mining') && ($scope.new_assessment.mineral === undefined)) {
                return rgiNotifier.error('Please, select the assessment mineral');
            }

            var countrySelected = true;

            $scope.new_assessment.assessment_countries.forEach(function(countryData) {
                if(!countryData.country) {
                    countrySelected = false;
                }
            });

            if(!countrySelected) {
                return rgiNotifier.error('Please, select the assessment country');
            }

            var new_assessment_ID, new_answer_set,
                new_assessment_set = [],
                new_assessment_year = String($scope.new_assessment.year),
                new_assessment_ver = $scope.new_assessment.version.slice(0, 2).toUpperCase(),
                timestamp = new Date().toISOString();

            $scope.disable_button = true;

            rgiAssessmentSrvc.query({year: new_assessment_year, version: $scope.new_assessment.version}, function (assessments) {
                var country_deployed = {value: false};

                assessments.forEach(function (assessment) {
                    $scope.new_assessment.assessment_countries.forEach(function(country) {
                        if (country.country.country===assessment.country) {
                            country_deployed.value = true;
                            country_deployed.country = assessment.country;
                        }
                    });
                });

                if (country_deployed.value) {
                    rgiNotifier.error(country_deployed.country + ' assessment already deployed');
                    $scope.disable_button = false;
                } else {
                    rgiQuestionSrvc.query({assessment_ID: 'base'}, function (questions) {
                        questions.forEach(function (question) {
                            if (question.assessments.indexOf(new_assessment_year + "-" + new_assessment_ver) < 0) {
                                question.assessments.push(new_assessment_year + "-" + new_assessment_ver);
                            }
                        });

                        $scope.new_assessment.assessment_countries.forEach(function (assessment_country) {
                            new_answer_set = [];

                            new_assessment_ID = assessment_country.country.iso2 + "-" + new_assessment_year + "-" + new_assessment_ver;

                            new_assessment_set.push({
                                assessment_ID: new_assessment_ID,
                                ISO3: assessment_country.country.country_ID,
                                year: $scope.new_assessment.year,
                                version: $scope.new_assessment.version,
                                mineral: $scope.new_assessment.mineral,
                                country: assessment_country.country.country,
                                created: {
                                    created_by: rgiIdentitySrvc.currentUser._id,
                                    created_date: timestamp}
                            });

                            questions.forEach(function (q) {
                                new_answer_set.push({
                                    answer_ID: new_assessment_ID + '-' + String(rgiUtilsSrvc.zeroFill(q.question_order, 3)),
                                    question_ID: q._id,
                                    question_trial: q.question_trial,
                                    assessment_ID: new_assessment_ID,
                                    year: new_assessment_year,
                                    version: new_assessment_ver,
                                    question_order: q.question_order,
                                    question_v: q.question_v + 1,
                                    last_modified: {modified_by: rgiIdentitySrvc.currentUser._id}
                                });
                            });
                            rgiAnswerMethodSrvc.insertAnswerSet(new_answer_set)
                                .then(function () {
                                }, function (reason) {rgiNotifier.error(reason);}
                            );
                        });

                        //send to mongo
                        rgiAssessmentMethodSrvc.createAssessment(new_assessment_set)
                            .then(rgiQuestionMethodSrvc.updateQuestionSet(questions))
                            .then(function () {
                                rgiNotifier.notify('Assessment deployed!');
                                $scope.closeThisDialog();
                                $route.reload();
                                $location.path('admin/assessment-admin');
                            }, function (reason) {
                                rgiNotifier.error(reason);
                            });
                    }, rgiHttpResponseProcessorSrvc.getDefaultHandler('Load question data failure'));
                }
            }, rgiHttpResponseProcessorSrvc.getDefaultHandler('Load assessment data failure'));
        };
    });
<|endoftext|>


<commit_before>var stat = require('fs').stat;
var helper = require('../../../helper');
var localPath = helper.localPath;
var basename = require('path').basename;
var joinpath = require('path').join;
var moment = require('moment');
var Entry = require('../../../models/entry');
var IgnoredFiles = require('../../../models/ignoredFiles');
var extname = require('path').extname;

var REASONS = {
        'PREVIEW': 'a preview',
        'TOO_LARGE': 'too large',
        'WRONG_TYPE': 'not a file Blot can process'
      };
module.exports = function (blog, path, callback) {

  var blogID = blog.id;

  var local = localPath(blogID, path);

  stat(local, function(err, stat){

    if (err) return callback(err);

    IgnoredFiles.getStatus(blogID, path, function(err, ignored){

      Entry.get(blogID, path, function(entry){

        if (ignored) ignored = REASONS[ignored] || 'was ignored';

        stat.path = path;
        stat.name = basename(path);

        stat.updated = moment.utc(stat.mtime).from(moment.utc(), true);

        stat.size = humanFileSize(stat.size);

        stat.directory = stat.isDirectory();
        stat.file = stat.isFile();
        stat.url = joinpath('/~', path);
        stat.entry = entry;
        stat.ignored = ignored;

        if (entry) {

          if (entry.page && entry.menu === false && ['.txt', '.md', '.html'].indexOf(extname(entry.path)) === -1) {
            entry.url = entry.path;
          }

          if (entry.draft) {
            entry.url = '/draft/view' + entry.path;
          }

          if (entry.scheduled) {
            entry.url += "?scheduled=true";
            entry.toNow = moment.utc(entry.dateStamp).fromNow();
            entry.date = moment.utc(entry.dateStamp)
                               .tz(blog.timeZone)
                               .format('MMMM Do YYYY, h:mma');
          }

        }

        return callback(null, stat);
      });
    });
  });

};

function humanFileSize(size) {

  if (size === 0) return '0 kb';

  var i = Math.floor( Math.log(size) / Math.log(1024) );

  return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['bytes', 'kB', 'MB', 'GB', 'TB'][i];
};<commit_msg>added updated to entry<commit_after>var stat = require('fs').stat;
var helper = require('../../../helper');
var localPath = helper.localPath;
var basename = require('path').basename;
var joinpath = require('path').join;
var moment = require('moment');
var Entry = require('../../../models/entry');
var IgnoredFiles = require('../../../models/ignoredFiles');
var extname = require('path').extname;

var REASONS = {
        'PREVIEW': 'a preview',
        'TOO_LARGE': 'too large',
        'WRONG_TYPE': 'not a file Blot can process'
      };
module.exports = function (blog, path, callback) {

  var blogID = blog.id;

  var local = localPath(blogID, path);

  stat(local, function(err, stat){

    if (err) return callback(err);

    IgnoredFiles.getStatus(blogID, path, function(err, ignored){

      Entry.get(blogID, path, function(entry){

        if (ignored) ignored = REASONS[ignored] || 'was ignored';

        stat.path = path;
        stat.name = basename(path);
        stat.updated = moment.utc(stat.mtime).from(moment.utc());

        stat.size = humanFileSize(stat.size);

        stat.directory = stat.isDirectory();
        stat.file = stat.isFile();
        stat.url = joinpath('/~', path);
        stat.entry = entry;
        stat.ignored = ignored;

        if (entry) {

          // Replace with human readable
          entry.updated = stat.updated;

          if (entry.page && entry.menu === false && ['.txt', '.md', '.html'].indexOf(extname(entry.path)) === -1) {
            entry.url = entry.path;
          }

          if (entry.draft) {
            entry.url = '/draft/view' + entry.path;
          }

          if (entry.scheduled) {
            entry.url += "?scheduled=true";
            entry.toNow = moment.utc(entry.dateStamp).fromNow();
            entry.date = moment.utc(entry.dateStamp)
                               .tz(blog.timeZone)
                               .format('MMMM Do YYYY, h:mma');
          }

        }
        return callback(null, stat);
      });
    });
  });

};

function humanFileSize(size) {

  if (size === 0) return '0 kb';

  var i = Math.floor( Math.log(size) / Math.log(1024) );

  return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['bytes', 'kB', 'MB', 'GB', 'TB'][i];
};<|endoftext|>


<commit_before>'use strict';

angular.module('confRegistrationWebApp')
  .directive('showAnswer', function (AnswerCache, $modal, $timeout) {
    return {
      templateUrl: 'views/adminAnswerDisplay.html',
      restrict: 'E',
      scope: {
        answers: '=',
        block: '='
      },
      controller: function ($scope) {

        var editAnswerDialogOptions = {
          templateUrl: 'views/editAnswer.html',
          controller: 'EditAnswerDialogCtrl',
          scope: $scope
        };

        $scope.createEditDialog = function () {
          $modal.open(editAnswerDialogOptions).result.then(function () {
            AnswerCache.syncBlock($scope, 'answer');
          });
        };

        $scope.$watch('answers', function () {
          if ($scope.answers) {
            var answerObject = _.find($scope.answers, { blockId: $scope.block.id });
            if (answerObject) {
              $scope.answer = answerObject;
            }
          }
        });

        $scope.getSelectedCheckboxes = function (choices) {
          return _.keys(_.pick(choices, function (val) {
            return val === true;
          }));
        };

      }
    };
  });
<commit_msg>whitespace<commit_after>'use strict';

angular.module('confRegistrationWebApp')
  .directive('showAnswer', function (AnswerCache, $modal, $timeout) {
    return {
      templateUrl: 'views/adminAnswerDisplay.html',
      restrict: 'E',
      scope: {
        answers: '=',
        block: '='
      },
      controller: function ($scope) {

        var editAnswerDialogOptions = {
          templateUrl: 'views/editAnswer.html',
          controller: 'EditAnswerDialogCtrl',
          scope: $scope
        };

        $scope.createEditDialog = function () {
          $modal.open(editAnswerDialogOptions).result.then(function () {
            AnswerCache.syncBlock($scope, 'answer');
          });
        };

        $scope.$watch('answers', function () {
          if ($scope.answers) {
            var answerObject = _.find($scope.answers, { blockId: $scope.block.id });
            if (answerObject) {
              $scope.answer = answerObject;
            }
          }
        });

        $scope.getSelectedCheckboxes = function (choices) {
          return _.keys(_.pick(choices, function (val) {
            return val === true;
          }));
        };

      }
    };
  });
<|endoftext|>


<commit_before>define(function() {
	return {
		add: function() {
			console.log('pooque');
		}
	};
});<commit_msg>redefined add-content<commit_after>define(['jquery', 'jquery-ui/jquery-ui'], function($) {
	function add(day, parent) {
		var form = $('form');
	}

	return add;
});<|endoftext|>


<commit_before>'use strict';

angular.module('jwtApp')
    .factory('rideServices', function (API_URL, $http) {
        return {
            getRidesByUserandDay: function (id) {
                return $http.post(API_URL + 'ride/getridesbylocationandday', id)
            },
            getRidesByUserandDayOneOff: function (id) {
                return $http.post(API_URL + 'ride/getoneoffridesbylocationandday', id)
            },
            getUserRides: function () {
                return $http.get(API_URL + 'ride/byuser')
            },
            addRider: function (rideid) {
                return $http.post(API_URL + 'ride/addrider', {
                    rideid: rideid
                })
            },
            addRideDetails: function (rideDetails) {
                return $http.post(API_URL + 'ride/addridedetails', rideDetails)
            },
            getCommentsByRideID: function (rideid) {
                return $http.get(API_URL + 'ride/getcomments?id=' + rideid)
            },
            getRoutesByRideDetailID: function (rideid) {
                return $http.get(API_URL + 'ride/getroutes?id=' + rideid)
            },
            getRidedetails: function (ridedetailid, rideid) {
                return $http.get(API_URL + 'ride/getridedetails?id=' + ridedetailid + '&rideid=' + rideid)
            },
            addComment: function (comment) {
                return $http.post(API_URL + 'ride/addcomment', comment)
            },
            removeRider: function (rideid) {
                return $http.post(API_URL + 'ride/removerider', {
                    rideid: rideid
                })
            },
            getRiders: function (rideid) {
                return $http.get(API_URL + 'ride/getriders?id=' + rideid)
            }
        }
    });<commit_msg>small update.<commit_after>'use strict';

angular.module('jwtApp')
    .factory('rideServices', function (API_URL, $http) {
        return {
            getRidesByUserandDay: function (id) {
                return $http.post(API_URL + 'ride/getridesbylocationandday', id)
            },
            getRidesByUserandDayOneOff: function (id) {
                return $http.post(API_URL + 'ride/getoneoffridesbylocationandday', id)
            },
            getUserRides: function () {
                return $http.get(API_URL + 'ride/byuser')
            },
            addRider: function (rideid) {
                return $http.post(API_URL + 'ride/addrider', {
                    rideid: rideid
                })
            },
            addRideDetails: function (rideDetails) {
                return $http.post(API_URL + 'ride/addridedetails', rideDetails)
            },
            getCommentsByRideID: function (rideid) {
                return $http.get(API_URL + 'ride/getcomments?id=' + rideid)
            },
            getRoutesByRideDetailID: function (rideid) {
                return $http.get(API_URL + 'ride/getroutes?id=' + rideid)
            },
            getRidedetails: function (ridedetailid, rideid) {
                return $http.get(API_URL + 'ride/getridedetails?rideid=' + rideid)
            },
            addComment: function (comment) {
                return $http.post(API_URL + 'ride/addcomment', comment)
            },
            removeRider: function (rideid) {
                return $http.post(API_URL + 'ride/removerider', {
                    rideid: rideid
                })
            },
            getRiders: function (rideid) {
                return $http.get(API_URL + 'ride/getriders?id=' + rideid)
            }
        }
    });<|endoftext|>


<commit_before>(function(root) {
    'use strict';

    /**
    * Represents a Fov in the game map. requires ROT.js
    * @class Fov
    * @constructor
    * @param {Object} game - Game instance this obj is attached to.
    */
    var Fov = function Fov(game) {
        this.game = game;
        this.fovMap = new RL.Array2d();
    };

    Fov.prototype = {
        constructor: Fov,

        /**
        * Game instance this obj is attached to.
        * @property game
        * @type Game
        */
        game: null,

        /**
        * Array2d storing fov visibility fovMap
        * @property fovMap
        * @type Array2d
        */
        fovMap: null,

        /**
        * Max visible distance in tiles
        * @property maxViewDistance
        * @type Number
        */
        maxViewDistance: 10,

        /**
        * Calculates the fov data relative to given coords;
        * @method update
        * @param {Number} x - The map coordinate position to calculate Fov from on the x axis.
        * @param {Number} y - The map coordinate position to calculate Fov from on the y axis.
        * @param {Number} [maxViewDistance] - Max visible distance (this.maxViewDistance used if not set).
        */
        update: function(x, y, maxViewDistance){

            if(maxViewDistance === void 0){
                maxViewDistance = this.maxViewDistance;
            }

            this.fovMap.reset();

            var radius = maxViewDistance,
                i, j;

            for (i = -radius; i <= radius; i++){
                for (j = -radius; j <= radius; j++){
                    if(i * i + j * j < radius * radius){
                        var x2 = x + i,
                            y2 = y + j,
                            visible = this.checkLos(x, y, x2, y2);
                        if(visible){
                            var tile = this.game.map.get(x2, y2);
                            // mark all drawn tiles as explored
                            tile.explored = true;
                            this.fovMap.set(x2, y2, 1);
                        }
                    }
                }
            }
        },

        /**
        * Retrieves the visibility of the tile at given coords
        * @method get
        * @param {Number} x - The map coordinate position to get Fov visibility from on the x axis.
        * @param {Number} y - The map coordinate position to get Fov visibility from on the y axis.
        */
        get: function(x, y){
            return this.fovMap.get(x, y);
        },

        /**
        * Checks if a tile blocks line of sight
        * @method checkMapTileVisible
        */
        checkMapTileVisible: function(x, y){
            var tile = this.game.map.get(x, y);
            return tile && !tile.blocksLos;
        },

        /**
        * Checks if an unobstructed line can be drawn from coords 0 to 1. Typically used for Line of Sight checks
        * @method checkLos
        * @param {Number} x0 - Start coord x.
        * @param {Number} y0 - Start coord y.
        * @param {Number} x1 - End coord x.
        * @param {Number} y1 - End coord y.
        */
        checkLos: function(x0, y0, x1, y1){

            var sx, sy, xnext, ynext, dx, dy, denom, dist;
            dx = x1 - x0;
            dy = y1 - y0;
            if (x0 < x1){
                sx = 1;
            }
            else{
                sx = -1;
            }

            if (y0 < y1){
                sy = 1;
            }
            else{
                sy = -1;
            }
            // sx and sy are switches that enable us to compute the LOS in a single quarter of x/y plan
            xnext = x0;
            ynext = y0;
            denom = Math.sqrt(dx * dx + dy * dy);
            while (xnext != x1 || ynext != y1){
                if (!this.checkMapTileVisible(xnext, ynext)){
                    return false;
                }
                // Line-to-point distance formula < 0.5
                if(Math.abs(dy * (xnext - x0 + sx) - dx * (ynext - y0)) / denom < 0.5){
                    xnext += sx;
                }
                else if(Math.abs(dy * (xnext - x0) - dx * (ynext - y0 + sy)) / denom < 0.5){
                    ynext += sy;
                }
                else {
                    xnext += sx;
                    ynext += sy;
                }
            }
            return true;
        },

        /**
        * Sets the size of the map to mange fov within.
        * @method setSize
        * @param {Number} width - Width of current map in tiles.
        * @param {Number} height - Height of current map in tiles.
        */
        setSize: function(width, height){
            this.fovMap.setSize(width, height);
        }

    };

    root.RL.Fov = Fov;

}(this));
<commit_msg>fov adjustment. added map object override option. better comments and naming.<commit_after>(function(root) {
    'use strict';

    /**
    * Represents a Fov in the game map. requires ROT.js
    * @class Fov
    * @constructor
    * @param {Game} game - Game instance this obj is attached to.
    */
    var Fov = function Fov(game) {
        this.game = game;
        this.fovMap = new RL.Array2d();
    };

    Fov.prototype = {
        constructor: Fov,

        /**
        * Game instance this obj is attached to.
        * @property game
        * @type Game
        */
        game: null,

        /**
        * Array2d storing fov visibility fovMap
        * @property fovMap
        * @type Array2d
        */
        fovMap: null,

        /**
        * Max visible distance in tiles
        * @property maxViewDistance
        * @type Number
        */
        maxViewDistance: 10,

        /**
        * Calculates the fov data relative to given coords;
        * @method update
        * @param {Number} x - The map coordinate position to calculate Fov from on the x axis.
        * @param {Number} y - The map coordinate position to calculate Fov from on the y axis.
        * @param {Number} [maxViewDistance] - Max visible distance (this.maxViewDistance used if not set).
        * @param {Array2d} [map=this.game.map] - The map to check the fov of.
        */
        update: function(x, y, maxViewDistance, map){
            map = map || this.game.map;
            if(maxViewDistance === void 0){
                maxViewDistance = this.maxViewDistance;
            }

            this.fovMap.reset();

            var radius = maxViewDistance,
                i, j;

            for (i = -radius; i <= radius; i++){
                for (j = -radius; j <= radius; j++){
                    if(i * i + j * j < radius * radius){
                        var x2 = x + i,
                            y2 = y + j,
                            visible = this.checkLos(x, y, x2, y2);
                        if(visible){
                            var tile = map.get(x2, y2);
                            // mark all drawn tiles as explored
                            tile.explored = true;
                            this.fovMap.set(x2, y2, 1);
                        }
                    }
                }
            }
        },

        /**
        * Retrieves the visibility of the tile at given coords
        * @method get
        * @param {Number} x - The x map tile coordinate to get Fov visibility of.
        * @param {Number} y - The y map tile coordinate to get Fov visibility of.
        */
        get: function(x, y){
            return this.fovMap.get(x, y);
        },

        /**
        * Checks if a tile blocks line of sight
        * @method mapTileBlocksLos
        * @param {Number} x - The x map tile coord to check blocks line of sight.
        * @param {Number} y - The y map tile coord to check blocks line of sight.
        * @param {Array2d} [map=this.game.map] - The map to check tiles of.
        */
        mapTileBlocksLos: function(x, y, map){
            var tile = this.game.map.get(x, y);
            return !tile || tile.blocksLos;
        },

        /**
        * Checks if an unobstructed line can be drawn from coords 0 to 1. Typically used for Line of Sight checks
        * @method checkLos
        * @param {Number} x0 - Start coord x.
        * @param {Number} y0 - Start coord y.
        * @param {Number} x1 - End coord x.
        * @param {Number} y1 - End coord y.
        */
        checkLos: function(x0, y0, x1, y1){

            var sx, sy, xnext, ynext, dx, dy, denom, dist;
            dx = x1 - x0;
            dy = y1 - y0;
            if (x0 < x1){
                sx = 1;
            }
            else{
                sx = -1;
            }

            if (y0 < y1){
                sy = 1;
            }
            else{
                sy = -1;
            }
            // sx and sy are switches that enable us to compute the LOS in a single quarter of x/y plan
            xnext = x0;
            ynext = y0;
            denom = Math.sqrt(dx * dx + dy * dy);
            while (xnext != x1 || ynext != y1){
                if (this.mapTileBlocksLos(xnext, ynext)){
                    return false;
                }
                // Line-to-point distance formula < 0.5
                if(Math.abs(dy * (xnext - x0 + sx) - dx * (ynext - y0)) / denom < 0.5){
                    xnext += sx;
                }
                else if(Math.abs(dy * (xnext - x0) - dx * (ynext - y0 + sy)) / denom < 0.5){
                    ynext += sy;
                }
                else {
                    xnext += sx;
                    ynext += sy;
                }
            }
            return true;
        },

        /**
        * Sets the size of the map to mange fov within.
        * @method setSize
        * @param {Number} width - Width of current map in tiles.
        * @param {Number} height - Height of current map in tiles.
        */
        setSize: function(width, height){
            this.fovMap.setSize(width, height);
        }

    };

    root.RL.Fov = Fov;

}(this));
<|endoftext|>


<commit_before>'use strict';

angular
    .module('dreamfactoryApp')
    .constant('LICENSE_DATA_URL', 'https://updates.dreamfactory.com/check')
    .service('LicenseDataService', ['$http', '$location', '$q', 'SystemConfigDataService', 'LICENSE_DATA_URL', function ($http, $location, $q, SystemConfigDataService, LICENSE_DATA_URL) {

        this.licensesWithRequiredSubscription = ['GOLD', 'SILVER'];

        this.isLicenseRequiredSubscription = function (licence) {
            return this.licensesWithRequiredSubscription.indexOf(licence) !== -1;
        };

        this.getSubscriptionData = function () {

            var systemConfig = SystemConfigDataService.getSystemConfig();
            var licenseKey = systemConfig.platform.license_key;

            if (licenseKeyExist(licenseKey)) {
                return getShowBannerResponse();
            } else {
                var headers = getHeadersForCheckingLicenseKey(licenseKey);
                return $http.get(LICENSE_DATA_URL, {headers: headers})
                    .then(function successCallback(response) {
                            return response.data;
                        },
                        function errorCallback(response) {
                            return response.data;
                        })
                    .then(function finallyCallback(data) {
                        return redirectToLicenseExpiredPageIfDisableUIEnabled(data)
                    })
            }

        };

        function licenseKeyExist(licenseKey) {
            return licenseKey == '' || licenseKey == undefined
        }

        function redirectToLicenseExpiredPageIfDisableUIEnabled(data) {
            if (JSON.parse(data.disable_ui)) {
                $location.url('/license-expired');
            }
            return data;
        }

        function getShowBannerResponse() {
            var deferred = $q.defer();
            deferred.resolve({renewal_date: "", message: "License key is invalid.", status_code: 401});
            return deferred.promise;
        }

        function getHeadersForCheckingLicenseKey(licenseKey) {
            return {
                'Content-Type': 'application/json',
                'X-DreamFactory-License-Key': licenseKey,
                'X-DreamFactory-API-Key': undefined,
                'X-DreamFactory-Session-Token': undefined
            };
        }
    }]);

<commit_msg>DP-181 Investigate how DreamFactory can be on the AWS Marketplace<commit_after>'use strict';

angular
    .module('dreamfactoryApp')
    .constant('LICENSE_DATA_URL', 'https://updates.dreamfactory.com/check')
    .service('LicenseDataService', ['$http', '$location', '$q', 'SystemConfigDataService', 'LICENSE_DATA_URL', function ($http, $location, $q, SystemConfigDataService, LICENSE_DATA_URL) {

        this.licensesWithRequiredSubscription = ['GOLD', 'SILVER'];

        this.isLicenseRequiredSubscription = function (licence) {
            return this.licensesWithRequiredSubscription.indexOf(licence) !== -1;
        };

        this.getSubscriptionData = function () {

            var systemConfig = SystemConfigDataService.getSystemConfig();
            var licenseKey = systemConfig.platform.license_key;
            var awsInstanceId = systemConfig.platform.aws_instance_id;

            if (licenseKeyExist(licenseKey)) {
                return getShowBannerResponse();
            } else {
                var headers = getHeadersForCheckingLicenseKey(licenseKey, awsInstanceId);
                return $http.get(LICENSE_DATA_URL, {headers: headers})
                    .then(function successCallback(response) {
                            return response.data;
                        },
                        function errorCallback(response) {
                            return response.data;
                        })
                    .then(function finallyCallback(data) {
                        return redirectToLicenseExpiredPageIfDisableUIEnabled(data)
                    })
            }

        };

        function licenseKeyExist(licenseKey) {
            return licenseKey == '' || licenseKey == undefined
        }

        function redirectToLicenseExpiredPageIfDisableUIEnabled(data) {
            if (JSON.parse(data.disable_ui)) {
                $location.url('/license-expired');
            }
            return data;
        }

        function getShowBannerResponse() {
            var deferred = $q.defer();
            deferred.resolve({renewal_date: "", message: "License key is invalid.", status_code: 401});
            return deferred.promise;
        }

        function getHeadersForCheckingLicenseKey(licenseKey, awsInstanceId) {
            return {
                'Content-Type': 'application/json',
                'X-DreamFactory-License-Key': licenseKey,
                'X-DreamFactory-API-Key': undefined,
                'X-DreamFactory-Session-Token': undefined,
                'X-DreamFactory-Instance-Id': awsInstanceId || undefined
            };
        }
    }]);

<|endoftext|>


<commit_before>'use strict';

(function (module) {
    var fs = require('fs');

    var util = require('util');
    function pad(n) {
        return n < 10 ? '0' + n : n;
    }
    function buildTime(t) {
        return '.' + t.getUTCFullYear() +
            pad(t.getUTCMonth() + 1) + pad(t.getUTCDate()) + '.' +
            pad(t.getUTCHours()) + pad(t.getUTCMinutes()) +
            pad(t.getUTCSeconds());
    }
    var tstream = require('stream').Transform;
    function ReplaceVersionStream(options) {
        var t = options.buildTime;
        this.buildTime = buildTime(t);
        tstream.call(this, options);
    }
    util.inherits(ReplaceVersionStream, tstream);
    ReplaceVersionStream.prototype._transform = function (chunk, encoding, cb) {
        var buildTime = this.buildTime;
        this.push(chunk.toString().replace(/v=([0-9A-Za-z._-]*)\.[0-9]{8}\.[0-9]{6}/g, function (str, version) {
            return 'v=' + version + buildTime;
        }));
        cb();
    };
    function PrependVersionStream(options) {
        this.buildTime = buildTime(options.buildTime);
        this._prepended = false;
        tstream.call(this, options);
    }
    util.inherits(PrependVersionStream, tstream);
    PrependVersionStream.prototype._transform = function (chunk, encoding, cb) {
        if (!this._prepended) {
            var ox = {
                base: 'v=7.x.x' + this.buildTime,
                version: '7.x.x' + this.buildTime
            };
            this._prepended = true;
            this.push('if (!window.ox) window.ox = {};');
            //TODO: if ox object gets larger (for whatever reason), add a loop here
            this.push('window.ox.base = "' + ox.base + '";');
            this.push('window.ox.version = "' + ox.version + '";');
        }
        this.push(chunk);
        cb();
    };
    function newestBuild(prefixes) {
        return prefixes
            .filter(fs.existsSync)
            .map(function (p) {
                return fs.statSync(p).mtime;
            })
            .reduce(function (acc, time) {
                return (acc.getTime() < time.getTime()) ? time : acc;
            }, new Date(0));
    }

    module.exports = {
        createReplaceStream: function (prefixes) {
            return new ReplaceVersionStream({buildTime: newestBuild(prefixes)});
        },
        createPrependStream: function (prefixes) {
            return new PrependVersionStream({buildTime: newestBuild(prefixes)});
        }
    };
}(module));
<commit_msg>enforce new version on restart of appserver<commit_after>'use strict';

(function (module) {
    var fs = require('fs');
    var startDate = new Date();

    var util = require('util');
    function pad(n) {
        return n < 10 ? '0' + n : n;
    }
    function buildTime(t) {
        return '.' + t.getUTCFullYear() +
            pad(t.getUTCMonth() + 1) + pad(t.getUTCDate()) + '.' +
            pad(t.getUTCHours()) + pad(t.getUTCMinutes()) +
            pad(t.getUTCSeconds());
    }
    var tstream = require('stream').Transform;
    function ReplaceVersionStream(options) {
        var t = options.buildTime;
        this.buildTime = buildTime(t);
        tstream.call(this, options);
    }
    util.inherits(ReplaceVersionStream, tstream);
    ReplaceVersionStream.prototype._transform = function (chunk, encoding, cb) {
        var buildTime = this.buildTime;
        this.push(chunk.toString().replace(/v=([0-9A-Za-z._-]*)\.[0-9]{8}\.[0-9]{6}/g, function (str, version) {
            return 'v=' + version + buildTime;
        }));
        cb();
    };
    function PrependVersionStream(options) {
        this.buildTime = buildTime(options.buildTime);
        this._prepended = false;
        tstream.call(this, options);
    }
    util.inherits(PrependVersionStream, tstream);
    PrependVersionStream.prototype._transform = function (chunk, encoding, cb) {
        if (!this._prepended) {
            var ox = {
                base: 'v=7.x.x' + this.buildTime,
                version: '7.x.x' + this.buildTime
            };
            this._prepended = true;
            this.push('if (!window.ox) window.ox = {};');
            //TODO: if ox object gets larger (for whatever reason), add a loop here
            this.push('window.ox.base = "' + ox.base + '";');
            this.push('window.ox.version = "' + ox.version + '";');
        }
        this.push(chunk);
        cb();
    };
    function newestBuild(prefixes) {
        return prefixes
            .filter(fs.existsSync)
            .map(function (p) {
                return fs.statSync(p).mtime;
            })
            .reduce(function (acc, time) {
                return (acc.getTime() < time.getTime()) ? time : acc;
            }, startDate);
    }

    module.exports = {
        createReplaceStream: function (prefixes) {
            return new ReplaceVersionStream({buildTime: newestBuild(prefixes)});
        },
        createPrependStream: function (prefixes) {
            return new PrependVersionStream({buildTime: newestBuild(prefixes)});
        }
    };
}(module));
<|endoftext|>


<commit_before>'use strict';

const chalk = require('chalk');
const ttest = require('ttest');
const Table = require('cli-table');

function table (result, urls) {
  let head, rows;

  if (!urls || urls.length === 1) {
    head = ['metric', 'mean', 'min', 'max'];
    rows = Object.keys(result[0])
      .map((metric) => [
        metric,
        result[0][metric].mean.toFixed(3),
        result[0][metric].min.toFixed(3),
        result[0][metric].max.toFixed(3)
      ]);
  } else if (urls.length === 2) {
    head = ['metric'];
    urls.forEach(url => head.push(url));
    head.push('p < 0.05');
    rows = Object.keys(result[0])
      .map((metric) => {
        const row = result.map((res) => {
          return res[metric] && res[metric].mean;
        });
        const min = Math.min.apply(Math, row);
        const max = Math.max.apply(Math, row);

        const colored = row.reduce((r, m) => {
          if (m === min) {
            r.push(chalk.green(m.toFixed(3)));
          } else if (m === max) {
            r.push(chalk.red(m.toFixed(3)));
          } else {
            r.push(typeof m === 'number' ? m.toFixed(3) : '-');
          }
          return r;
        }, [metric]);
        if (result[0][metric] && result[1][metric]) {
          const tt = ttest(result[0][metric].raw, result[1][metric].raw, { varEqual: true });
          if (!tt.valid()) {
            colored.push(tt.pValue().toFixed(3) + ' ' + chalk.green('✔'));
          } else {
            colored.push(tt.pValue().toFixed(3) + ' ' + chalk.red('✘'));
          }
        } else {
          colored.push('-');
        }
        return colored;
      });
  }

  const table = new Table({ head: head });
  table.push.apply(table, rows);
  return table.toString();
}

module.exports = table;
<commit_msg>Do not calculate p-values for short runs<commit_after>'use strict';

const chalk = require('chalk');
const ttest = require('ttest');
const Table = require('cli-table');

function table (result, urls) {
  let head, rows;

  if (!urls || urls.length === 1) {
    head = ['metric', 'mean', 'min', 'max'];
    rows = Object.keys(result[0])
      .map((metric) => [
        metric,
        result[0][metric].mean.toFixed(3),
        result[0][metric].min.toFixed(3),
        result[0][metric].max.toFixed(3)
      ]);
  } else if (urls.length === 2) {
    head = ['metric'];
    urls.forEach(url => head.push(url));
    head.push('p < 0.05');
    rows = Object.keys(result[0])
      .map((metric) => {
        const row = result.map((res) => {
          return res[metric] && res[metric].mean;
        });
        const min = Math.min.apply(Math, row);
        const max = Math.max.apply(Math, row);

        const colored = row.reduce((r, m) => {
          if (m === min) {
            r.push(chalk.green(m.toFixed(3)));
          } else if (m === max) {
            r.push(chalk.red(m.toFixed(3)));
          } else {
            r.push(typeof m === 'number' ? m.toFixed(3) : '-');
          }
          return r;
        }, [metric]);
        if (result[0][metric] && result[1][metric] && result[0][metric].raw.length > 1 && result[1][metric].raw.length > 1) {
          const tt = ttest(result[0][metric].raw, result[1][metric].raw, { varEqual: true });
          if (!tt.valid()) {
            colored.push(tt.pValue().toFixed(3) + ' ' + chalk.green('✔'));
          } else {
            colored.push(tt.pValue().toFixed(3) + ' ' + chalk.red('✘'));
          }
        } else {
          colored.push('-');
        }
        return colored;
      });
  }

  const table = new Table({ head: head });
  table.push.apply(table, rows);
  return table.toString();
}

module.exports = table;
<|endoftext|>


<commit_before>var _ = require('lodash');
var λ = require('contra');
var escapeRegExp = require('escape-regexp');
var HashIndex = require('level-hash-index');
var toPaddedBase36 = require('./utils/toPaddedBase36');

var escapeVar = function(elm){
  return _.isString(elm) ? elm.replace(/^\\/, "\\\\").replace(/^\?/, "\\?") : elm;
};

var unEscapeVar = function(elm){
  return _.isString(elm) ? elm.replace(/^\\/, "") : elm;
};

var isVar = function(elm){
  return _.isString(elm) && elm[0] === '?';
};

var isTheThrowAwayVar = function(elm){
  return elm === '?_';
};

var bindToTuple = function(tuple, binding){
  return tuple.map(function(e){
    if(binding.hasOwnProperty(e)){
      return escapeVar(binding[e]);
    }
    return e;
  });
};

var parseElement = function(hindex, tuple, i, callback){
  var elm = tuple.length < i + 1 ? '?_' : tuple[i];
  if(isTheThrowAwayVar(elm)){
    callback(null, {is_blank: true});
  }else if(isVar(elm)){
    callback(null, {var_name: elm});
  }else if(i < 3 && _.isString(elm)){
    elm = unEscapeVar(elm);
    hindex.getHash(elm, function(err, hash){
      if(err) callback(err);
      else callback(null, {value: elm, hash: hash});
    });
  }else if(i === 3 && _.isNumber(elm)){
    var txn = toPaddedBase36(elm, 6);
    callback(null, {value: txn, hash: txn});
  }else if(i === 4 && (elm === true || elm === false)){
    callback(null, {value: elm, hash: elm});
  }else{
    callback(new Error('element ' + i + ' in tuple has invalid type'));
  }
};

var parseTuple = function(hindex, tuple, callback){
  λ.concurrent({
    e: λ.curry(parseElement, hindex, tuple, 0),
    a: λ.curry(parseElement, hindex, tuple, 1),
    v: λ.curry(parseElement, hindex, tuple, 2),
    t: λ.curry(parseElement, hindex, tuple, 3),
    o: λ.curry(parseElement, hindex, tuple, 4)
  }, callback);
};

var selectIndex = (function(){
  var getKnowns = function(q_fact){
    var knowns = [];
    "eav".split("").forEach(function(key){
      if(q_fact[key].hasOwnProperty("hash")){
        knowns.push(key);
      }
    });
    return knowns.sort().join("");
  };
  var mapping = {
    '': 'eavto',
    'e': 'eavto',
    'a': 'aevto',
    'v': 'vaeto',
    'av': 'aveto',
    'ev': 'eavto',
    'ae': 'eavto',
    'aev': 'eavto',
  };
  return function(q_fact){
    return 'eavto';//TODO select the index based on attribute schema
    return mapping[getKnowns(q_fact)];
  };
}());

var toMatcher = function(index_to_use, q_fact){

  var prefix = index_to_use + '!';
  var prefix_parts = [];
  var found_a_gap = false;

  var regex = escapeRegExp(prefix) + index_to_use.split("").map(function(k){
    if(q_fact[k].hasOwnProperty('hash')){
      if(!found_a_gap){
        prefix_parts.push(q_fact[k].hash);
      }
      return escapeRegExp(q_fact[k].hash);
    }else{
      found_a_gap = true;
      return '.*';
    }
  }).join(escapeRegExp('!'));

  return {
    prefix: prefix + prefix_parts.join('!'),
    matchRegExp: new RegExp(regex)
  };
};

var findMatchingKeys = function(db, matcher, callback){
  var results = [];
  db.createReadStream({
    keys: true,
    values: false,
    gte: matcher.prefix + '\x00',
    lte: matcher.prefix + '\xFF',
  }).on('data', function(data){
    if(matcher.matchRegExp.test(data)){
      results.push(data);
    }
  }).on('error', function(err){
    callback(err);
  }).on('end', function(){
    callback(null, results);
  });
};

var keyToFact = function(key){
  var parts = key.split("!");
  var index_name = parts[0];
  var fact = {};
  index_name.split('').forEach(function(k, i){
    var part = parts[i + 1];
    if(k === 't'){
      fact[k] = {value: parseInt(part, 36)};
    }else if(k === 'o'){
      fact[k] = {value: part === '1'};
    }else{
      fact[k] = part;
    }
  });
  return fact;
};

var bindKeys = function(matching_keys, q_fact){
  var binding = {};//to ensure unique-ness

  var only_the_latest = q_fact.t.is_blank;//TODO also based on the cardiality of q_fact.a's schema
  var latest_for = {};//latest for the same e+a

  var var_names = "eavto".split('').filter(function(k){
    return q_fact[k].hasOwnProperty('var_name');
  }).map(function(k){
    return [q_fact[k].var_name, k];
  });

  matching_keys.forEach(function(key, i){
    var fact = keyToFact(key);

    var key_for_latest_for = only_the_latest ? fact.e + fact.a : i;

    if(latest_for.hasOwnProperty(key_for_latest_for)){
      if(latest_for[key_for_latest_for].txn > fact.t.value){
        return;//not the latest, so skip the rest
      }
    }

    var vars = {};
    var hash_key = '';
    var_names.forEach(function(p){
      var k = p[1];
      vars[p[0]] = fact[k];
      hash_key += _.isString(fact[k]) ? fact[k] : fact[k].value;
    });
    binding[hash_key] = vars;
    latest_for[key_for_latest_for] = {txn: fact.t.value, hash_key: hash_key};
  });
  return _.unique(_.pluck(latest_for, 'hash_key')).map(function(key){
    return binding[key];
  });
};

var qTuple = function(db, hindex, tuple, orig_binding, callback){
  parseTuple(hindex, bindToTuple(tuple, orig_binding), function(err, q_fact){
    if(err){
      if(err.type === 'NotFoundError'){
        //one of the tuple values were not found in the hash, so there must be no results
        return callback(null, []);
      }
      return callback(err);
    }
    var index_to_use = selectIndex(q_fact);

    findMatchingKeys(db, toMatcher(index_to_use, q_fact), function(err, matching_keys){
      if(err) return callback(err);

      var bindings = bindKeys(matching_keys, q_fact);

      //de-hash the bindings
      λ.map(bindings, function(binding, callback){
        λ.map(_.pairs(binding), function(p, callback){
          if(_.isString(p[1])){
            hindex.get(p[1], function(err, val){
              callback(err, [p[0], val]);
            });
          }else{
            callback(null, [p[0], p[1].value]);
          }
        }, function(err, pairs){
          callback(err, _.assign({}, orig_binding, _.object(pairs)));
        });
      }, callback);
    });
  });
};

module.exports = function(db, options){
  options = options || {};

  var hindex = options.HashIndex || HashIndex(db);
  var qTuple_bound = function(tuple, binding, callback){
    if(!_.isArray(tuple)){
      return callback(new Error("tuple must be an array"));
    }
    if(!_.isPlainObject(binding)){
      return callback(new Error("binding must be a plain object"));
    }
    qTuple(db, hindex, tuple, binding, callback);
  };
  var q = function(tuples, bindings, callback){
    if(!_.isArray(tuples)){
      return callback(new Error("q expects an array of tuples"));
    }
    if(!_.isArray(bindings)){
      return callback(new Error("q expects an array bindings"));
    }

    var memo = bindings;
    λ.each.series(tuples, function(tuple, callback){
      λ.map(memo, function(binding, callback){
        qTuple(db, hindex, tuple, binding, callback);
      }, function(err, next_bindings){
        if(err) return callback(err);
        memo = _.flatten(next_bindings);
        callback();
      });
    }, function(err){
      if(err) callback(err);
      else callback(null, memo);
    });
  };
  return {
    qTuple: qTuple_bound,
    q: q,
    getEntity: function(e, callback){
      q([["?e", "?a", "?v"]], [{"?e": e}], function(err, results){
        if(err) return callback(err);
        var o = {};
        results.forEach(function(result){
          o[result["?a"]] = result["?v"];
          //TODO cardinality = multiple
        });
        callback(null, o);
      });
    }
  };
};
<commit_msg>starting work for "fb" i.e. how to represent the database as a "value"<commit_after>var _ = require('lodash');
var λ = require('contra');
var escapeRegExp = require('escape-regexp');
var HashIndex = require('level-hash-index');
var toPaddedBase36 = require('./utils/toPaddedBase36');

var escapeVar = function(elm){
  return _.isString(elm) ? elm.replace(/^\\/, "\\\\").replace(/^\?/, "\\?") : elm;
};

var unEscapeVar = function(elm){
  return _.isString(elm) ? elm.replace(/^\\/, "") : elm;
};

var isVar = function(elm){
  return _.isString(elm) && elm[0] === '?';
};

var isTheThrowAwayVar = function(elm){
  return elm === '?_';
};

var bindToTuple = function(tuple, binding){
  return tuple.map(function(e){
    if(binding.hasOwnProperty(e)){
      return escapeVar(binding[e]);
    }
    return e;
  });
};

var parseElement = function(hindex, tuple, i, callback){
  var elm = tuple.length < i + 1 ? '?_' : tuple[i];
  if(isTheThrowAwayVar(elm)){
    callback(null, {is_blank: true});
  }else if(isVar(elm)){
    callback(null, {var_name: elm});
  }else if(i < 3 && _.isString(elm)){
    elm = unEscapeVar(elm);
    hindex.getHash(elm, function(err, hash){
      if(err) callback(err);
      else callback(null, {value: elm, hash: hash});
    });
  }else if(i === 3 && _.isNumber(elm)){
    var txn = toPaddedBase36(elm, 6);
    callback(null, {value: txn, hash: txn});
  }else if(i === 4 && (elm === true || elm === false)){
    callback(null, {value: elm, hash: elm});
  }else{
    callback(new Error('element ' + i + ' in tuple has invalid type'));
  }
};

var parseTuple = function(hindex, tuple, callback){
  λ.concurrent({
    e: λ.curry(parseElement, hindex, tuple, 0),
    a: λ.curry(parseElement, hindex, tuple, 1),
    v: λ.curry(parseElement, hindex, tuple, 2),
    t: λ.curry(parseElement, hindex, tuple, 3),
    o: λ.curry(parseElement, hindex, tuple, 4)
  }, callback);
};

var selectIndex = (function(){
  var getKnowns = function(q_fact){
    var knowns = [];
    "eav".split("").forEach(function(key){
      if(q_fact[key].hasOwnProperty("hash")){
        knowns.push(key);
      }
    });
    return knowns.sort().join("");
  };
  var mapping = {
    '': 'eavto',
    'e': 'eavto',
    'a': 'aevto',
    'v': 'vaeto',
    'av': 'aveto',
    'ev': 'eavto',
    'ae': 'eavto',
    'aev': 'eavto',
  };
  return function(q_fact){
    return 'eavto';//TODO select the index based on attribute schema
    return mapping[getKnowns(q_fact)];
  };
}());

var toMatcher = function(index_to_use, q_fact){

  var prefix = index_to_use + '!';
  var prefix_parts = [];
  var found_a_gap = false;

  var regex = escapeRegExp(prefix) + index_to_use.split("").map(function(k){
    if(q_fact[k].hasOwnProperty('hash')){
      if(!found_a_gap){
        prefix_parts.push(q_fact[k].hash);
      }
      return escapeRegExp(q_fact[k].hash);
    }else{
      found_a_gap = true;
      return '.*';
    }
  }).join(escapeRegExp('!'));

  return {
    prefix: prefix + prefix_parts.join('!'),
    matchRegExp: new RegExp(regex)
  };
};

var findMatchingKeys = function(db, matcher, callback){
  var results = [];
  db.createReadStream({
    keys: true,
    values: false,
    gte: matcher.prefix + '\x00',
    lte: matcher.prefix + '\xFF',
  }).on('data', function(data){
    if(matcher.matchRegExp.test(data)){
      results.push(data);
    }
  }).on('error', function(err){
    callback(err);
  }).on('end', function(){
    callback(null, results);
  });
};

var keyToFact = function(key){
  var parts = key.split("!");
  var index_name = parts[0];
  var fact = {};
  index_name.split('').forEach(function(k, i){
    var part = parts[i + 1];
    if(k === 't'){
      fact[k] = {value: parseInt(part, 36)};
    }else if(k === 'o'){
      fact[k] = {value: part === '1'};
    }else{
      fact[k] = part;
    }
  });
  return fact;
};

var bindKeys = function(matching_keys, q_fact){
  var binding = {};//to ensure unique-ness

  var only_the_latest = q_fact.t.is_blank;//TODO also based on the cardiality of q_fact.a's schema
  var latest_for = {};//latest for the same e+a

  var var_names = "eavto".split('').filter(function(k){
    return q_fact[k].hasOwnProperty('var_name');
  }).map(function(k){
    return [q_fact[k].var_name, k];
  });

  matching_keys.forEach(function(key, i){
    var fact = keyToFact(key);

    var key_for_latest_for = only_the_latest ? fact.e + fact.a : i;

    if(latest_for.hasOwnProperty(key_for_latest_for)){
      if(latest_for[key_for_latest_for].txn > fact.t.value){
        return;//not the latest, so skip the rest
      }
    }

    var vars = {};
    var hash_key = '';
    var_names.forEach(function(p){
      var k = p[1];
      vars[p[0]] = fact[k];
      hash_key += _.isString(fact[k]) ? fact[k] : fact[k].value;
    });
    binding[hash_key] = vars;
    latest_for[key_for_latest_for] = {txn: fact.t.value, hash_key: hash_key};
  });
  return _.unique(_.pluck(latest_for, 'hash_key')).map(function(key){
    return binding[key];
  });
};

var qTuple = function(fb, tuple, orig_binding, callback){
  var db = fb.db;
  var hindex = fb.hindex;

  if(!_.isArray(tuple)){
    return callback(new Error("tuple must be an array"));
  }
  if(!_.isPlainObject(orig_binding)){
    return callback(new Error("binding must be a plain object"));
  }

  parseTuple(hindex, bindToTuple(tuple, orig_binding), function(err, q_fact){
    if(err){
      if(err.type === 'NotFoundError'){
        //one of the tuple values were not found in the hash, so there must be no results
        return callback(null, []);
      }
      return callback(err);
    }
    var index_to_use = selectIndex(q_fact);

    findMatchingKeys(db, toMatcher(index_to_use, q_fact), function(err, matching_keys){
      if(err) return callback(err);

      var bindings = bindKeys(matching_keys, q_fact);

      //de-hash the bindings
      λ.map(bindings, function(binding, callback){
        λ.map(_.pairs(binding), function(p, callback){
          if(_.isString(p[1])){
            hindex.get(p[1], function(err, val){
              callback(err, [p[0], val]);
            });
          }else{
            callback(null, [p[0], p[1].value]);
          }
        }, function(err, pairs){
          callback(err, _.assign({}, orig_binding, _.object(pairs)));
        });
      }, callback);
    });
  });
};

var q = function(fb, tuples, bindings, callback){
  if(!_.isArray(tuples)){
    return callback(new Error("q expects an array of tuples"));
  }
  if(!_.isArray(bindings)){
    return callback(new Error("q expects an array bindings"));
  }

  var memo = bindings;
  λ.each.series(tuples, function(tuple, callback){
    λ.map(memo, function(binding, callback){
      qTuple(fb, tuple, binding, callback);
    }, function(err, next_bindings){
      if(err) return callback(err);
      memo = _.flatten(next_bindings);
      callback();
    });
  }, function(err){
    if(err) callback(err);
    else callback(null, memo);
  });
};

module.exports = function(db, options){
  options = options || {};
  var hindex = options.HashIndex || HashIndex(db);

  var fb = {db: db, hindex: hindex};

  return {
    qTuple: function(tuple, binding, callback){
      qTuple(fb, tuple, binding, callback);
    },
    q: function(tuples, bindings, callback){
      q(fb, tuples, bindings, callback);
    },
    getEntity: function(e, callback){
      q(fb, [["?e", "?a", "?v"]], [{"?e": e}], function(err, results){
        if(err) return callback(err);
        var o = {};
        results.forEach(function(result){
          o[result["?a"]] = result["?v"];
          //TODO cardinality = multiple
        });
        callback(null, o);
      });
    }
  };
};
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular.module('app.services')
        .factory('FlipIt', FlipIt);

    FlipIt.$inject = ['$http', '$log', 'Items'];

    function FlipIt($http, $log, Items) {
        var vm = this;

        // All items
        vm.osrsServiceItems = 'https://rsbuddy.com/exchange/summary.json';
        // All items with store prices.
        vm.osrsServiceStorePrices = 'https://rsbuddy.com/exchange/names.json';
        //  Hourly Pricepoint
        vm.osrsServiceEndpoint = 'https://api.rsbuddy.com/grandExchange?a=guidePrice&i=';
        // Plot points for recent trades based on timespan. Replace timespan with a value in vm.osrsTradeSpan
        vm.osrsServiceGraph = 'https://api.rsbuddy.com/grandExchange?a=graph&start=1425921352106&g=timespan&i=';
        /* Trades within a certain span of time
         * 180 - 3hrs, 1440 - 1day, 4320 - 3days
         */
        vm.osrsTradeSpan = [4320, 1440, 180];
        vm.trendingItems = [];
        vm.trendingItemsSize = 100;
        vm.marketDB = [];
        vm.db = [];
        vm.dbSize = 0;

        function loadDB() {
            var loadPromise = $http.get('./app/db.json')
                .then(function (response) {
                    vm.db = response.data;
                    vm.dbSize = response.data.length;
                }, function (error) {
                    $log.error(error);
                });
            return loadPromise;
        }

        function loadTrendingItems() {
            for (var i = 0; i < vm.dbSize; i++) {
                var itemID = vm.db[i].id;
                $http.get(vm.osrsServiceEndpoint + itemID)
                    .then(function (response) {
                        var regex = /(\d+)(?!.*\d)/;
                        var itemName = vm.db[regex.exec(response.config.url)[0]].name;
                        addItem(itemName, response.data);
                        //addTrendingItem(vm.db[i].name, response.data);
                    }, function (error) {
                        $log.error(error);
                    });
            }
        }

        function addItem(data) {
            var item = {
                name: itemName,
                buyPrice: data.buying,
                sellPrice: data.selling,
                revenue: data.selling - data.buying,
                demandQuantity: data.buyingQuantity - data.sellingQuantity,
                demandPercentage: ((data.buyingQuantity / data.sellingQuantity) - 1) * 100
            }

            vm.marketDB.push(item);
        }

        function addTrendingItem(itemName, data) {
            if (vm.trendingItems.length < vm.trendingItemsSize) {
                if (vm.trendingItems[0]) {
                    vm.trendingItems.unshift(data);
                } else if (parseFloat(vm.trendingItems[vm.trendingItems.length - 1].day30.change) > parseFloat(data.day30.change)) {
                    vm.trendingItems.push(data);
                } else {
                    for (var i = 0; i < vm.trendingItems.length; i++) {
                        if (parseFloat(vm.trendingItems[i].day30.change) < parseFloat(data.day30.change)) {
                            vm.trendingItems.splice(i + 1, 0, data);
                        }
                    }
                }
            } else if (vm.trendingItems.length == vm.trendingItemsSize) {
                var lastIndex = vm.trendingItems.length - 1;
                if (parseFloat(data.day30.change) > parseFloat(vm.trendingItems[lastIndex].day30.change)) {
                    for (var i = lastIndex; i >= 0; i--) {
                        if (parseFloat(vm.trendingItems[i].day30.change) > parseFloat(data.day30.change)) {
                            vm.trendingItems.splice(i + 1, 0, data);
                            vm.trendingItems.pop();
                        }
                    }
                }
            }
        }

        function activate() {
            var loadPromise = loadDB().then(function (response) {
                loadTrendingItems();
            });
        }

        function getTrendingItems() {
            activate();
            return vm.trendingItems;
        }

        function getAllItems() {
            activate();
            return vm.marketDB;
        }

        return {
            getTrendingItems: getTrendingItems,
            getAllItems: getAllItems
        }
    }
})();<commit_msg>whoops<commit_after>(function () {
    'use strict';

    angular.module('app.services')
        .factory('FlipIt', FlipIt);

    FlipIt.$inject = ['$http', '$log', 'Items'];

    function FlipIt($http, $log, Items) {
        var vm = this;

        // All items
        vm.osrsServiceItems = 'https://rsbuddy.com/exchange/summary.json';
        // All items with store prices.
        vm.osrsServiceStorePrices = 'https://rsbuddy.com/exchange/names.json';
        //  Hourly Pricepoint
        vm.osrsServiceEndpoint = 'https://api.rsbuddy.com/grandExchange?a=guidePrice&i=';
        // Plot points for recent trades based on timespan. Replace timespan with a value in vm.osrsTradeSpan
        vm.osrsServiceGraph = 'https://api.rsbuddy.com/grandExchange?a=graph&start=1425921352106&g=timespan&i=';
        /* Trades within a certain span of time
         * 180 - 3hrs, 1440 - 1day, 4320 - 3days
         */
        vm.osrsTradeSpan = [4320, 1440, 180];
        vm.trendingItems = [];
        vm.trendingItemsSize = 100;
        vm.marketDB = [];
        vm.db = [];
        vm.dbSize = 0;

        function loadDB() {
            var loadPromise = $http.get('./app/db.json')
                .then(function (response) {
                    vm.db = response.data;
                    vm.dbSize = response.data.length;
                }, function (error) {
                    $log.error(error);
                });
            return loadPromise;
        }

        function loadTrendingItems() {
            for (var i = 0; i < vm.dbSize; i++) {
                var itemID = vm.db[i].id;
                $http.get(vm.osrsServiceEndpoint + itemID)
                    .then(function (response) {
                        var regex = /(\d+)(?!.*\d)/;
                        var itemName = vm.db[regex.exec(response.config.url)[0]].name;
                        addItem(itemName, response.data);
                        //addTrendingItem(vm.db[i].name, response.data);
                    }, function (error) {
                        $log.error(error);
                    });
            }
        }

        function addItem(itemName, data) {
            var item = {
                name: itemName,
                buyPrice: data.buying,
                sellPrice: data.selling,
                revenue: data.selling - data.buying,
                demandQuantity: data.buyingQuantity - data.sellingQuantity,
                demandPercentage: ((data.buyingQuantity / data.sellingQuantity) - 1) * 100
            }

            vm.marketDB.push(item);
        }

        function addTrendingItem(itemName, data) {
            if (vm.trendingItems.length < vm.trendingItemsSize) {
                if (vm.trendingItems[0]) {
                    vm.trendingItems.unshift(data);
                } else if (parseFloat(vm.trendingItems[vm.trendingItems.length - 1].day30.change) > parseFloat(data.day30.change)) {
                    vm.trendingItems.push(data);
                } else {
                    for (var i = 0; i < vm.trendingItems.length; i++) {
                        if (parseFloat(vm.trendingItems[i].day30.change) < parseFloat(data.day30.change)) {
                            vm.trendingItems.splice(i + 1, 0, data);
                        }
                    }
                }
            } else if (vm.trendingItems.length == vm.trendingItemsSize) {
                var lastIndex = vm.trendingItems.length - 1;
                if (parseFloat(data.day30.change) > parseFloat(vm.trendingItems[lastIndex].day30.change)) {
                    for (var i = lastIndex; i >= 0; i--) {
                        if (parseFloat(vm.trendingItems[i].day30.change) > parseFloat(data.day30.change)) {
                            vm.trendingItems.splice(i + 1, 0, data);
                            vm.trendingItems.pop();
                        }
                    }
                }
            }
        }

        function activate() {
            var loadPromise = loadDB().then(function (response) {
                loadTrendingItems();
            });
        }

        function getTrendingItems() {
            activate();
            return vm.trendingItems;
        }

        function getAllItems() {
            activate();
            return vm.marketDB;
        }

        return {
            getTrendingItems: getTrendingItems,
            getAllItems: getAllItems
        }
    }
})();<|endoftext|>


<commit_before>/**
 * A list of all shareable constants for the application.
 */

export const ROOT_URL = (() => {
  // This is an "absolute path reference (a URL without the domain name)"
  // according to the Django docs
  let rootPath = document.head.querySelector('meta[name=kpi-root-path]');
  if (rootPath === null) {
    console.error('no kpi-root-path meta tag set. defaulting to ""');
    rootPath = '';
  } else {
    // Strip trailing slashes
    rootPath = rootPath.content.replace(/\/*$/, '');
  }
  return `${window.location.protocol}//${window.location.host}${rootPath}`;
})();

export const ANON_USERNAME = 'AnonymousUser';

/**
 * BAD CODE™ A hardcoded list of permissions codenames.
 *
 * All of them are really defined on backend, and we get them through the
 * permissions config endpoint, but as we need these names to reference them in
 * the code to build the UI it's a necessary evil.
 *
 * NOTE: to know what these permissions permit see `kpi/permissions.py` file,
 * where you have to match the classes with endpoints and their HTTP methods.
 */
export const PERMISSIONS_CODENAMES = {};
new Set([
  'view_asset',
  'change_asset',
  'discover_asset',
  'manage_asset',
  'add_submissions',
  'view_submissions',
  'partial_submissions',
  'change_submissions',
  'delete_submissions',
  'validate_submissions',
]).forEach((codename) => {PERMISSIONS_CODENAMES[codename] = codename;});
Object.freeze(PERMISSIONS_CODENAMES);

export const HOOK_LOG_STATUSES = {
  SUCCESS: 2,
  PENDING: 1,
  FAILED: 0,
};

export const KEY_CODES = Object.freeze({
  TAB: 9,
  ENTER: 13,
  ESC: 27,
  SPACE: 32,
  NBSP: 160, // non-breakable space
});

export const MODAL_TYPES = {
  SHARING: 'sharing',
  UPLOADING_XLS: 'uploading-xls',
  NEW_FORM: 'new-form',
  LIBRARY_NEW_ITEM: 'library-new-item',
  LIBRARY_TEMPLATE: 'library-template',
  LIBRARY_COLLECTION: 'library-collection',
  LIBRARY_UPLOAD: 'library-upload',
  ENKETO_PREVIEW: 'enketo-preview',
  SUBMISSION: 'submission',
  REPLACE_PROJECT: 'replace-project',
  TABLE_COLUMNS: 'table-columns',
  REST_SERVICES: 'rest-services',
  FORM_LANGUAGES: 'form-languages',
  FORM_TRANSLATIONS_TABLE: 'form-translation-table',
  ASSET_TAGS: 'asset-tags',
  ENCRYPT_FORM: 'encrypt-form',
  BULK_EDIT_SUBMISSIONS: 'bulk-edit-submissions',
};

export const PROJECT_SETTINGS_CONTEXTS = Object.freeze({
  NEW: 'newForm',
  EXISTING: 'existingForm',
  REPLACE: 'replaceProject',
  BUILDER: 'formBuilderAside',
});

export const update_states = {
  UNSAVED_CHANGES: -1,
  UP_TO_DATE: true,
  PENDING_UPDATE: false,
  SAVE_FAILED: 'SAVE_FAILED',
};

export const AVAILABLE_FORM_STYLES = [
  {value: '', label: t('Default - single page')},
  {value: 'theme-grid no-text-transform', label: t('Grid theme')},
  {value: 'theme-grid', label: t('Grid theme with headings in ALL CAPS')},
  {value: 'pages', label: t('Multiple pages')},
  {value: 'theme-grid pages no-text-transform', label: t('Grid theme + Multiple pages')},
  {value: 'theme-grid pages', label: t('Grid theme + Multiple pages + headings in ALL CAPS')},
];

export const VALIDATION_STATUSES = {
  no_status: {
    value: null,
    label: '—',
  },
  validation_status_not_approved: {
    value: 'validation_status_not_approved',
    label: t('Not Approved'),
  },
  validation_status_approved: {
    value: 'validation_status_approved',
    label: t('Approved'),
  },
  validation_status_on_hold: {
    value: 'validation_status_on_hold',
    label: t('On Hold'),
  },
};

export const VALIDATION_STATUSES_LIST = [
  VALIDATION_STATUSES.no_status,
  VALIDATION_STATUSES.validation_status_not_approved,
  VALIDATION_STATUSES.validation_status_approved,
  VALIDATION_STATUSES.validation_status_on_hold,
];

export const ASSET_TYPES = {
  question: {
    id: 'question',
    label: t('question'),
  },
  block: {
    id: 'block',
    label: t('block'),
  },
  template: {
    id: 'template',
    label: t('template'),
  },
  survey: {
    id: 'survey',
    label: t('project'),
  },
  collection: {
    id: 'collection',
    label: t('collection'),
  },
};

export const QUESTION_TYPES = Object.freeze({
  acknowledge: {label: t('Acknowledge'), icon: 'qt-acknowledge', id: 'acknowledge'},
  audio: {label: t('Audio'), icon: 'qt-audio', id: 'audio'},
  barcode: {label: t('Barcode / QR Code'), icon: 'qt-barcode', id: 'barcode'},
  calculate: {label: t('Calculate'), icon: 'qt-calculate', id: 'calculate'},
  date: {label: t('Date'), icon: 'qt-date', id: 'date'},
  datetime: {label: t('Date & time'), icon: 'qt-date-time', id: 'datetime'},
  decimal: {label: t('Decimal'), icon: 'qt-decimal', id: 'decimal'},
  'external-xml': {label: t('External XML'), icon: 'qt-external-xml', id: 'external-xml'},
  file: {label: t('File'), icon: 'qt-file', id: 'file'},
  geopoint: {label: t('Point'), icon: 'qt-point', id: 'geopoint'},
  geoshape: {label: t('Area'), icon: 'qt-area', id: 'geoshape'},
  geotrace: {label: t('Line'), icon: 'qt-line', id: 'geotrace'},
  hidden: {label: t('Hidden'), icon: 'qt-hidden', id: 'hidden'},
  image: {label: t('Photo'), icon: 'qt-photo', id: 'image'},
  integer: {label: t('Number'), icon: 'qt-number', id: 'integer'},
  kobomatrix: {label: t('Question Matrix'), icon: 'qt-question-matrix', id: 'kobomatrix'},
  note: {label: t('Note'), icon: 'qt-note', id: 'note'},
  range: {label: t('Range'), icon: 'qt-range', id: 'range'},
  rank: {label: t('Ranking'), icon: 'qt-ranking', id: 'rank'},
  score: {label: t('Rating'), icon: 'qt-rating', id: 'score'},
  select_multiple: {label: t('Select Many'), icon: 'qt-select-many', id: 'select_multiple'},
  select_one: {label: t('Select One'), icon: 'qt-select-one', id: 'select_one'},
  text: {label: t('Text'), icon: 'qt-text', id: 'text'},
  time: {label: t('Time'), icon: 'qt-time', id: 'time'},
  video: {label: t('Video'), icon: 'qt-video', id: 'video'},
});

export const META_QUESTION_TYPES = {};
new Set([
  'start',
  'end',
  'today',
  'username',
  'simserial',
  'subscriberid',
  'deviceid',
  'phonenumber',
  'audit',
]).forEach((codename) => {META_QUESTION_TYPES[codename] = codename;});
Object.freeze(META_QUESTION_TYPES);

// submission data extras being added by backend. see both of these:
// 1. https://github.com/kobotoolbox/kobocat/blob/78133d519f7b7674636c871e3ba5670cd64a7227/onadata/apps/viewer/models/parsed_instance.py#L242-L260
// 2. https://github.com/kobotoolbox/kpi/blob/7db39015866c905edc645677d72b9c1ea16067b1/jsapp/js/constants.es6#L284-L294
export const ADDITIONAL_SUBMISSION_PROPS = {};
new Set([
  // match the ordering of (Python) kpi.models.import_export_task.ExportTask.COPY_FIELDS
  '_id',
  '_uuid',
  '_submission_time',
  '_validation_status',
  '_notes',
  '_status',
  '_submitted_by',
  '_tags',
]).forEach((codename) => {ADDITIONAL_SUBMISSION_PROPS[codename] = codename;});
Object.freeze(ADDITIONAL_SUBMISSION_PROPS);

export const NAME_MAX_LENGTH = 255;

/**
 * for Backend calls, see their definitions at `kpi/filters.py`
 * NOTE: ORs require a parenthesis to work
 */
export const COMMON_QUERIES = Object.freeze({
  b: 'asset_type:block',
  q: 'asset_type:question',
  t: 'asset_type:template',
  s: 'asset_type:survey',
  c: 'asset_type:collection',
  qb: '(asset_type:question OR asset_type:block)',
  qbt: '(asset_type:question OR asset_type:block OR asset_type:template)',
  qbtc: '(asset_type:question OR asset_type:block OR asset_type:template OR asset_type:collection)',
});

export const ACCESS_TYPES = {};
new Set([
  'owned',
  'shared',
  'public',
  'subscribed',
]).forEach((codename) => {ACCESS_TYPES[codename] = codename;});
Object.freeze(ACCESS_TYPES);

export const GROUP_TYPES_BEGIN = {};
new Set([
  'begin_group',
  'begin_score',
  'begin_rank',
  'begin_kobomatrix',
  'begin_repeat',
]).forEach((kind) => {GROUP_TYPES_BEGIN[kind] = kind;});
Object.freeze(GROUP_TYPES_BEGIN);

export const GROUP_TYPES_END = {};
new Set([
  'end_group',
  'end_score',
  'end_rank',
  'end_kobomatrix',
  'end_repeat',
]).forEach((kind) => {GROUP_TYPES_END[kind] = kind;});
Object.freeze(GROUP_TYPES_END);

// a custom question type for score
export const SCORE_ROW_TYPE = 'score__row';

// a custom question type for rank
export const RANK_LEVEL_TYPE = 'rank__level';

export const CHOICE_LISTS = Object.freeze({
  SELECT: 'select_from_list_name',
  MATRIX: 'kobo--matrix_list',
  SCORE: 'kobo--score-choices',
  RANK: 'kobo--rank-items',
});

export const MATRIX_PAIR_PROPS = {
  inSurvey: CHOICE_LISTS.MATRIX,
  inChoices: 'list_name',
};

export const DEPLOYMENT_CATEGORIES = Object.freeze({
  Deployed: {id: 'Deployed', label: t('Deployed')},
  Draft: {id: 'Draft', label: t('Draft')},
  Archived: {id: 'Archived', label: t('Archived')},
});

export const QUERY_LIMIT_DEFAULT = 5000;

export const ROUTES = Object.freeze({
  ACCOUNT_SETTINGS: '/account-settings',
  CHANGE_PASSWORD: '/change-password',
  LIBRARY: '/library',
  MY_LIBRARY: '/library/my-library',
  PUBLIC_COLLECTIONS: '/library/public-collections',
  NEW_LIBRARY_ITEM: '/library/asset/new',
  LIBRARY_ITEM: '/library/asset/:uid',
  EDIT_LIBRARY_ITEM: '/library/asset/:uid/edit',
  NEW_LIBRARY_CHILD: '/library/asset/:uid/new',
  LIBRARY_ITEM_JSON: '/library/asset/:uid/json',
  LIBRARY_ITEM_XFORM: '/library/asset/:uid/xform',
  FORMS: '/forms',
  FORM: '/forms/:uid',
  FORM_JSON: '/forms/:uid/json',
  FORM_XFORM: '/forms/:uid/xform',
  FORM_EDIT: '/forms/:uid/edit',
  FORM_SUMMARY: '/forms/:uid/summary',
  FORM_LANDING: '/forms/:uid/landing',
  FORM_DATA: '/forms/:uid/data',
  FORM_REPORT: '/forms/:uid/data/report',
  FORM_REPORT_OLD: '/forms/:uid/data/report-legacy',
  FORM_TABLE: '/forms/:uid/data/table',
  FORM_DOWNLOADS: '/forms/:uid/data/downloads',
  FORM_GALLERY: '/forms/:uid/data/gallery',
  FORM_MAP: '/forms/:uid/data/map',
  FORM_MAP_BY: '/forms/:uid/data/map/:viewby',
  FORM_SETTINGS: '/forms/:uid/settings',
  FORM_MEDIA: '/forms/:uid/settings/media',
  FORM_SHARING: '/forms/:uid/settings/sharing',
  FORM_REST: '/forms/:uid/settings/rest',
  FORM_REST_HOOK: '/forms/:uid/settings/rest/:hookUid',
  FORM_KOBOCAT: '/forms/:uid/settings/kobocat',
  FORM_RESET: '/forms/:uid/reset',
});

export const COLLECTION_METHODS = Object.freeze({
  offline_url: {
    id: 'offline_url',
    label: t('Online-Offline (multiple submission)'),
    desc: t('This allows online and offline submissions and is the best option for collecting data in the field.'),
  },
  url: {
    id: 'url',
    label: t('Online-Only (multiple submissions)'),
    desc: t('This is the best option when entering many records at once on a computer, e.g. for transcribing paper records.'),
  },
  single_url: {
    id: 'single_url',
    label: t('Online-Only (single submission)'),
    desc: t('This allows a single submission, and can be paired with the "return_url" parameter to redirect the user to a URL of your choice after the form has been submitted.'),
  },
  single_once_url: {
    id: 'single_once_url',
    label: t('Online-only (once per respondent)'),
    desc: t('This allows your web form to only be submitted once per user, using basic protection to prevent the same user (on the same browser & device) from submitting more than once.'),
  },
  iframe_url: {
    id: 'iframe_url',
    label: t('Embeddable web form code'),
    desc: t('Use this html5 code snippet to integrate your form on your own website using smaller margins.'),
  },
  preview_url: {
    id: 'preview_url',
    label: t('View only'),
    desc: t('Use this version for testing, getting feedback. Does not allow submitting data.'),
  },
  android: {
    id: 'android',
    label: t('Android application'),
    desc: t('Use this option to collect data in the field with your Android device.'),
    url: 'https://play.google.com/store/apps/details?id=org.koboc.collect.android&hl=en',
  },
});

// NOTE: The default export is mainly for tests
const constants = {
  ROOT_URL,
  ANON_USERNAME,
  PERMISSIONS_CODENAMES,
  HOOK_LOG_STATUSES,
  KEY_CODES,
  MODAL_TYPES,
  PROJECT_SETTINGS_CONTEXTS,
  update_states,
  AVAILABLE_FORM_STYLES,
  VALIDATION_STATUSES,
  VALIDATION_STATUSES_LIST,
  ASSET_TYPES,
  QUESTION_TYPES,
  META_QUESTION_TYPES,
  ADDITIONAL_SUBMISSION_PROPS,
  NAME_MAX_LENGTH,
  COMMON_QUERIES,
  ACCESS_TYPES,
  GROUP_TYPES_BEGIN,
  GROUP_TYPES_END,
  SCORE_ROW_TYPE,
  RANK_LEVEL_TYPE,
  DEPLOYMENT_CATEGORIES,
  ROUTES,
  QUERY_LIMIT_DEFAULT,
  CHOICE_LISTS,
};

export default constants;
<commit_msg>add comment about what to update when adding new question type<commit_after>/**
 * A list of all shareable constants for the application.
 */

export const ROOT_URL = (() => {
  // This is an "absolute path reference (a URL without the domain name)"
  // according to the Django docs
  let rootPath = document.head.querySelector('meta[name=kpi-root-path]');
  if (rootPath === null) {
    console.error('no kpi-root-path meta tag set. defaulting to ""');
    rootPath = '';
  } else {
    // Strip trailing slashes
    rootPath = rootPath.content.replace(/\/*$/, '');
  }
  return `${window.location.protocol}//${window.location.host}${rootPath}`;
})();

export const ANON_USERNAME = 'AnonymousUser';

/**
 * BAD CODE™ A hardcoded list of permissions codenames.
 *
 * All of them are really defined on backend, and we get them through the
 * permissions config endpoint, but as we need these names to reference them in
 * the code to build the UI it's a necessary evil.
 *
 * NOTE: to know what these permissions permit see `kpi/permissions.py` file,
 * where you have to match the classes with endpoints and their HTTP methods.
 */
export const PERMISSIONS_CODENAMES = {};
new Set([
  'view_asset',
  'change_asset',
  'discover_asset',
  'manage_asset',
  'add_submissions',
  'view_submissions',
  'partial_submissions',
  'change_submissions',
  'delete_submissions',
  'validate_submissions',
]).forEach((codename) => {PERMISSIONS_CODENAMES[codename] = codename;});
Object.freeze(PERMISSIONS_CODENAMES);

export const HOOK_LOG_STATUSES = {
  SUCCESS: 2,
  PENDING: 1,
  FAILED: 0,
};

export const KEY_CODES = Object.freeze({
  TAB: 9,
  ENTER: 13,
  ESC: 27,
  SPACE: 32,
  NBSP: 160, // non-breakable space
});

export const MODAL_TYPES = {
  SHARING: 'sharing',
  UPLOADING_XLS: 'uploading-xls',
  NEW_FORM: 'new-form',
  LIBRARY_NEW_ITEM: 'library-new-item',
  LIBRARY_TEMPLATE: 'library-template',
  LIBRARY_COLLECTION: 'library-collection',
  LIBRARY_UPLOAD: 'library-upload',
  ENKETO_PREVIEW: 'enketo-preview',
  SUBMISSION: 'submission',
  REPLACE_PROJECT: 'replace-project',
  TABLE_COLUMNS: 'table-columns',
  REST_SERVICES: 'rest-services',
  FORM_LANGUAGES: 'form-languages',
  FORM_TRANSLATIONS_TABLE: 'form-translation-table',
  ASSET_TAGS: 'asset-tags',
  ENCRYPT_FORM: 'encrypt-form',
  BULK_EDIT_SUBMISSIONS: 'bulk-edit-submissions',
};

export const PROJECT_SETTINGS_CONTEXTS = Object.freeze({
  NEW: 'newForm',
  EXISTING: 'existingForm',
  REPLACE: 'replaceProject',
  BUILDER: 'formBuilderAside',
});

export const update_states = {
  UNSAVED_CHANGES: -1,
  UP_TO_DATE: true,
  PENDING_UPDATE: false,
  SAVE_FAILED: 'SAVE_FAILED',
};

export const AVAILABLE_FORM_STYLES = [
  {value: '', label: t('Default - single page')},
  {value: 'theme-grid no-text-transform', label: t('Grid theme')},
  {value: 'theme-grid', label: t('Grid theme with headings in ALL CAPS')},
  {value: 'pages', label: t('Multiple pages')},
  {value: 'theme-grid pages no-text-transform', label: t('Grid theme + Multiple pages')},
  {value: 'theme-grid pages', label: t('Grid theme + Multiple pages + headings in ALL CAPS')},
];

export const VALIDATION_STATUSES = {
  no_status: {
    value: null,
    label: '—',
  },
  validation_status_not_approved: {
    value: 'validation_status_not_approved',
    label: t('Not Approved'),
  },
  validation_status_approved: {
    value: 'validation_status_approved',
    label: t('Approved'),
  },
  validation_status_on_hold: {
    value: 'validation_status_on_hold',
    label: t('On Hold'),
  },
};

export const VALIDATION_STATUSES_LIST = [
  VALIDATION_STATUSES.no_status,
  VALIDATION_STATUSES.validation_status_not_approved,
  VALIDATION_STATUSES.validation_status_approved,
  VALIDATION_STATUSES.validation_status_on_hold,
];

export const ASSET_TYPES = {
  question: {
    id: 'question',
    label: t('question'),
  },
  block: {
    id: 'block',
    label: t('block'),
  },
  template: {
    id: 'template',
    label: t('template'),
  },
  survey: {
    id: 'survey',
    label: t('project'),
  },
  collection: {
    id: 'collection',
    label: t('collection'),
  },
};

/**
 * When adding new question type please remember to update those places:
 * 1. Add question type here
 * 2. Add new SVG icon to jsapp/svg-icons
 * 3. Add icon to row view.icons.coffee
 * 4. If it's non-regular type, you might need to update:
 *   - isRowSpecialLabelHolder in assetUtils.es6
 *   - renderQuestionTypeIcon in assetUtils.es6
 * 5. If question doesn't hold data, update:
 *   - getDisplayData in bulkEditSubmissionsForm.es6
 *   - getDisplayedColumns in table.es6
 * 6. Update renderResponseData in submissionDataTable.es6
 * 7. Update getSubmissionDisplayData in submissionUtils.es6
 * 8. If it's media type update renderAttachment in submissionDataTable.es6
 */
export const QUESTION_TYPES = Object.freeze({
  acknowledge: {label: t('Acknowledge'), icon: 'qt-acknowledge', id: 'acknowledge'},
  audio: {label: t('Audio'), icon: 'qt-audio', id: 'audio'},
  barcode: {label: t('Barcode / QR Code'), icon: 'qt-barcode', id: 'barcode'},
  calculate: {label: t('Calculate'), icon: 'qt-calculate', id: 'calculate'},
  date: {label: t('Date'), icon: 'qt-date', id: 'date'},
  datetime: {label: t('Date & time'), icon: 'qt-date-time', id: 'datetime'},
  decimal: {label: t('Decimal'), icon: 'qt-decimal', id: 'decimal'},
  'external-xml': {label: t('External XML'), icon: 'qt-external-xml', id: 'external-xml'},
  file: {label: t('File'), icon: 'qt-file', id: 'file'},
  geopoint: {label: t('Point'), icon: 'qt-point', id: 'geopoint'},
  geoshape: {label: t('Area'), icon: 'qt-area', id: 'geoshape'},
  geotrace: {label: t('Line'), icon: 'qt-line', id: 'geotrace'},
  hidden: {label: t('Hidden'), icon: 'qt-hidden', id: 'hidden'},
  image: {label: t('Photo'), icon: 'qt-photo', id: 'image'},
  integer: {label: t('Number'), icon: 'qt-number', id: 'integer'},
  kobomatrix: {label: t('Question Matrix'), icon: 'qt-question-matrix', id: 'kobomatrix'},
  note: {label: t('Note'), icon: 'qt-note', id: 'note'},
  range: {label: t('Range'), icon: 'qt-range', id: 'range'},
  rank: {label: t('Ranking'), icon: 'qt-ranking', id: 'rank'},
  score: {label: t('Rating'), icon: 'qt-rating', id: 'score'},
  select_multiple: {label: t('Select Many'), icon: 'qt-select-many', id: 'select_multiple'},
  select_one: {label: t('Select One'), icon: 'qt-select-one', id: 'select_one'},
  text: {label: t('Text'), icon: 'qt-text', id: 'text'},
  time: {label: t('Time'), icon: 'qt-time', id: 'time'},
  video: {label: t('Video'), icon: 'qt-video', id: 'video'},
});

export const META_QUESTION_TYPES = {};
new Set([
  'start',
  'end',
  'today',
  'username',
  'simserial',
  'subscriberid',
  'deviceid',
  'phonenumber',
  'audit',
]).forEach((codename) => {META_QUESTION_TYPES[codename] = codename;});
Object.freeze(META_QUESTION_TYPES);

// submission data extras being added by backend. see both of these:
// 1. https://github.com/kobotoolbox/kobocat/blob/78133d519f7b7674636c871e3ba5670cd64a7227/onadata/apps/viewer/models/parsed_instance.py#L242-L260
// 2. https://github.com/kobotoolbox/kpi/blob/7db39015866c905edc645677d72b9c1ea16067b1/jsapp/js/constants.es6#L284-L294
export const ADDITIONAL_SUBMISSION_PROPS = {};
new Set([
  // match the ordering of (Python) kpi.models.import_export_task.ExportTask.COPY_FIELDS
  '_id',
  '_uuid',
  '_submission_time',
  '_validation_status',
  '_notes',
  '_status',
  '_submitted_by',
  '_tags',
]).forEach((codename) => {ADDITIONAL_SUBMISSION_PROPS[codename] = codename;});
Object.freeze(ADDITIONAL_SUBMISSION_PROPS);

export const NAME_MAX_LENGTH = 255;

/**
 * for Backend calls, see their definitions at `kpi/filters.py`
 * NOTE: ORs require a parenthesis to work
 */
export const COMMON_QUERIES = Object.freeze({
  b: 'asset_type:block',
  q: 'asset_type:question',
  t: 'asset_type:template',
  s: 'asset_type:survey',
  c: 'asset_type:collection',
  qb: '(asset_type:question OR asset_type:block)',
  qbt: '(asset_type:question OR asset_type:block OR asset_type:template)',
  qbtc: '(asset_type:question OR asset_type:block OR asset_type:template OR asset_type:collection)',
});

export const ACCESS_TYPES = {};
new Set([
  'owned',
  'shared',
  'public',
  'subscribed',
]).forEach((codename) => {ACCESS_TYPES[codename] = codename;});
Object.freeze(ACCESS_TYPES);

export const GROUP_TYPES_BEGIN = {};
new Set([
  'begin_group',
  'begin_score',
  'begin_rank',
  'begin_kobomatrix',
  'begin_repeat',
]).forEach((kind) => {GROUP_TYPES_BEGIN[kind] = kind;});
Object.freeze(GROUP_TYPES_BEGIN);

export const GROUP_TYPES_END = {};
new Set([
  'end_group',
  'end_score',
  'end_rank',
  'end_kobomatrix',
  'end_repeat',
]).forEach((kind) => {GROUP_TYPES_END[kind] = kind;});
Object.freeze(GROUP_TYPES_END);

// a custom question type for score
export const SCORE_ROW_TYPE = 'score__row';

// a custom question type for rank
export const RANK_LEVEL_TYPE = 'rank__level';

export const CHOICE_LISTS = Object.freeze({
  SELECT: 'select_from_list_name',
  MATRIX: 'kobo--matrix_list',
  SCORE: 'kobo--score-choices',
  RANK: 'kobo--rank-items',
});

export const MATRIX_PAIR_PROPS = {
  inSurvey: CHOICE_LISTS.MATRIX,
  inChoices: 'list_name',
};

export const DEPLOYMENT_CATEGORIES = Object.freeze({
  Deployed: {id: 'Deployed', label: t('Deployed')},
  Draft: {id: 'Draft', label: t('Draft')},
  Archived: {id: 'Archived', label: t('Archived')},
});

export const QUERY_LIMIT_DEFAULT = 5000;

export const ROUTES = Object.freeze({
  ACCOUNT_SETTINGS: '/account-settings',
  CHANGE_PASSWORD: '/change-password',
  LIBRARY: '/library',
  MY_LIBRARY: '/library/my-library',
  PUBLIC_COLLECTIONS: '/library/public-collections',
  NEW_LIBRARY_ITEM: '/library/asset/new',
  LIBRARY_ITEM: '/library/asset/:uid',
  EDIT_LIBRARY_ITEM: '/library/asset/:uid/edit',
  NEW_LIBRARY_CHILD: '/library/asset/:uid/new',
  LIBRARY_ITEM_JSON: '/library/asset/:uid/json',
  LIBRARY_ITEM_XFORM: '/library/asset/:uid/xform',
  FORMS: '/forms',
  FORM: '/forms/:uid',
  FORM_JSON: '/forms/:uid/json',
  FORM_XFORM: '/forms/:uid/xform',
  FORM_EDIT: '/forms/:uid/edit',
  FORM_SUMMARY: '/forms/:uid/summary',
  FORM_LANDING: '/forms/:uid/landing',
  FORM_DATA: '/forms/:uid/data',
  FORM_REPORT: '/forms/:uid/data/report',
  FORM_REPORT_OLD: '/forms/:uid/data/report-legacy',
  FORM_TABLE: '/forms/:uid/data/table',
  FORM_DOWNLOADS: '/forms/:uid/data/downloads',
  FORM_GALLERY: '/forms/:uid/data/gallery',
  FORM_MAP: '/forms/:uid/data/map',
  FORM_MAP_BY: '/forms/:uid/data/map/:viewby',
  FORM_SETTINGS: '/forms/:uid/settings',
  FORM_MEDIA: '/forms/:uid/settings/media',
  FORM_SHARING: '/forms/:uid/settings/sharing',
  FORM_REST: '/forms/:uid/settings/rest',
  FORM_REST_HOOK: '/forms/:uid/settings/rest/:hookUid',
  FORM_KOBOCAT: '/forms/:uid/settings/kobocat',
  FORM_RESET: '/forms/:uid/reset',
});

export const COLLECTION_METHODS = Object.freeze({
  offline_url: {
    id: 'offline_url',
    label: t('Online-Offline (multiple submission)'),
    desc: t('This allows online and offline submissions and is the best option for collecting data in the field.'),
  },
  url: {
    id: 'url',
    label: t('Online-Only (multiple submissions)'),
    desc: t('This is the best option when entering many records at once on a computer, e.g. for transcribing paper records.'),
  },
  single_url: {
    id: 'single_url',
    label: t('Online-Only (single submission)'),
    desc: t('This allows a single submission, and can be paired with the "return_url" parameter to redirect the user to a URL of your choice after the form has been submitted.'),
  },
  single_once_url: {
    id: 'single_once_url',
    label: t('Online-only (once per respondent)'),
    desc: t('This allows your web form to only be submitted once per user, using basic protection to prevent the same user (on the same browser & device) from submitting more than once.'),
  },
  iframe_url: {
    id: 'iframe_url',
    label: t('Embeddable web form code'),
    desc: t('Use this html5 code snippet to integrate your form on your own website using smaller margins.'),
  },
  preview_url: {
    id: 'preview_url',
    label: t('View only'),
    desc: t('Use this version for testing, getting feedback. Does not allow submitting data.'),
  },
  android: {
    id: 'android',
    label: t('Android application'),
    desc: t('Use this option to collect data in the field with your Android device.'),
    url: 'https://play.google.com/store/apps/details?id=org.koboc.collect.android&hl=en',
  },
});

// NOTE: The default export is mainly for tests
const constants = {
  ROOT_URL,
  ANON_USERNAME,
  PERMISSIONS_CODENAMES,
  HOOK_LOG_STATUSES,
  KEY_CODES,
  MODAL_TYPES,
  PROJECT_SETTINGS_CONTEXTS,
  update_states,
  AVAILABLE_FORM_STYLES,
  VALIDATION_STATUSES,
  VALIDATION_STATUSES_LIST,
  ASSET_TYPES,
  QUESTION_TYPES,
  META_QUESTION_TYPES,
  ADDITIONAL_SUBMISSION_PROPS,
  NAME_MAX_LENGTH,
  COMMON_QUERIES,
  ACCESS_TYPES,
  GROUP_TYPES_BEGIN,
  GROUP_TYPES_END,
  SCORE_ROW_TYPE,
  RANK_LEVEL_TYPE,
  DEPLOYMENT_CATEGORIES,
  ROUTES,
  QUERY_LIMIT_DEFAULT,
  CHOICE_LISTS,
};

export default constants;
<|endoftext|>