<commit_before>'use strict';

const Promise = require('promise');
const geotile = require('geotile');
const isObject = require('lodash/isObject');
const json2csv = require('json2csv');
const crypto = require('crypto');
const { createFile } = require('../clients/storage/BlobStorageClient');

function withRunTime(promiseFunc) {
  function runTimer(...args) {
    return new Promise((resolve, reject) => {
      const startTime = Date.now();
      promiseFunc(...args)
      .then(returnValue => {
        const endTime = Date.now();
        if (isObject(returnValue)) {
          returnValue.runTime = endTime - startTime;
        }
        resolve(returnValue);
      })
      .catch(reject);
    });
  }

  return runTimer;
}

const MAX_IN_CLAUSES = 65535;

function limitForInClause(collection) {
  const list = collection.constructor === Array ? collection : Array.from(collection);
  if (list.length <= MAX_IN_CLAUSES) {
    return list;
  }

  console.warn(`Only ${MAX_IN_CLAUSES} items allowed for IN clause, ignoring ${list.length - MAX_IN_CLAUSES} elements`);
  return list.slice(0, MAX_IN_CLAUSES);
}

function toPipelineKey(sourceFilter) {
  if (!sourceFilter || !sourceFilter.length) {
    return 'all';
  }

  if (sourceFilter.length > 1) {
    console.warn(`Only one source filter supported, ignoring: ${sourceFilter.slice(1).join(', ')}`);
  }

  return sourceFilter[0];
}

function fromTopicListToConjunctionTopics(topicTerms, conjunctiveTopicLimit = 3) {
  let selectedFilters = topicTerms.filter(edge => !!edge).slice(0, conjunctiveTopicLimit).sort();

  if (topicTerms.length > conjunctiveTopicLimit) {
    console.warn(`Only ${conjunctiveTopicLimit} terms supported, ignoring: ${topicTerms.slice(conjunctiveTopicLimit).join(', ')}`);
  }

  while (selectedFilters.length < conjunctiveTopicLimit) {
    selectedFilters.push('');
  }

  return selectedFilters;
}

function toConjunctionTopics(mainEdge, filteredEdges) {
  if (!mainEdge) {
    console.warn('mainEdge not set');
    mainEdge = '';
  }

  if (!filteredEdges || !filteredEdges.length) {
    return [mainEdge, '', ''];
  }

  return fromTopicListToConjunctionTopics([mainEdge].concat(filteredEdges));
}

function tilesForBbox(bbox, zoomLevel) {
  const fence = {north: bbox[0], west: bbox[1], south: bbox[2], east: bbox[3]};
  return geotile.tileIdsForBoundingBox(fence, zoomLevel).map(geotile.decodeTileId);
}

function tilesForLocations(locations, zoomLevel) {
  return locations.map(([lat, lon]) => geotile.tileIdFromLatLong(lat, lon, zoomLevel)).map(geotile.decodeTileId);
}

function parseFromToDate(fromDate, toDate) { // eslint-disable-line no-unused-vars
  // TODO: implement
  return {
    fromDate: '2017-08-11 15:00:00.000000+0000',
    toDate: '2017-08-11 16:00:00.000000+0000',
    period: 'hour-2017-08-11 15',
    periodType: 'hour'
  };
}

function parseLimit(limit) {
  const DEFAULT_LIMIT = 15;

  return limit > 0 ? limit : DEFAULT_LIMIT;
}

const DEFAULT_CSV_CONTAINER = 'csv-export';
const DEFAULT_CSV_EXPIRY_MINUTES = 2 * 60;

function asCsvExporter(promiseFunc, exportPropertyName, container, expiryMinutes) {
  container = container || DEFAULT_CSV_CONTAINER;
  expiryMinutes = expiryMinutes || DEFAULT_CSV_EXPIRY_MINUTES;

  function formatCsvFilename(provenance, content) {
    const contentHash = content ? crypto.createHash('md5').update(content).digest('hex') : 'noresults';
    const now = new Date();
    const folder = `${now.getUTCFullYear()}/${now.getUTCMonth()+1}/${now.getUTCDate()}/${now.getUTCHours()}/${now.getUTCMinutes()}/${contentHash}`;
    return `${folder}/${provenance}.csv`;
  }

  function csvExporter(...args) {
    return new Promise((resolve, reject) => {
      promiseFunc(...args)
      .then(returnValue => {
        const csvItems = returnValue && returnValue[exportPropertyName];
        const csvText = csvItems && csvItems.length ? json2csv({ data: csvItems, withBOM: true }) : '';
        return createFile(container, formatCsvFilename(promiseFunc.name, csvText), csvText, expiryMinutes);
      })
      .then(resolve)
      .catch(reject);
    });
  }

  return csvExporter;
}

module.exports = {
  parseLimit,
  parseFromToDate,
  toPipelineKey,
  toConjunctionTopics,
  tilesForBbox,
  tilesForLocations,
  limitForInClause,
  fromTopicListToConjunctionTopics,
  asCsvExporter,
  withRunTime
};<commit_msg>Use uid instead of hash for url unique id<commit_after>'use strict';

const Promise = require('promise');
const geotile = require('geotile');
const isObject = require('lodash/isObject');
const json2csv = require('json2csv');
const uuidv4 = require('uuid/v4');
const { createFile } = require('../clients/storage/BlobStorageClient');

function withRunTime(promiseFunc) {
  function runTimer(...args) {
    return new Promise((resolve, reject) => {
      const startTime = Date.now();
      promiseFunc(...args)
      .then(returnValue => {
        const endTime = Date.now();
        if (isObject(returnValue)) {
          returnValue.runTime = endTime - startTime;
        }
        resolve(returnValue);
      })
      .catch(reject);
    });
  }

  return runTimer;
}

const MAX_IN_CLAUSES = 65535;

function limitForInClause(collection) {
  const list = collection.constructor === Array ? collection : Array.from(collection);
  if (list.length <= MAX_IN_CLAUSES) {
    return list;
  }

  console.warn(`Only ${MAX_IN_CLAUSES} items allowed for IN clause, ignoring ${list.length - MAX_IN_CLAUSES} elements`);
  return list.slice(0, MAX_IN_CLAUSES);
}

function toPipelineKey(sourceFilter) {
  if (!sourceFilter || !sourceFilter.length) {
    return 'all';
  }

  if (sourceFilter.length > 1) {
    console.warn(`Only one source filter supported, ignoring: ${sourceFilter.slice(1).join(', ')}`);
  }

  return sourceFilter[0];
}

function fromTopicListToConjunctionTopics(topicTerms, conjunctiveTopicLimit = 3) {
  let selectedFilters = topicTerms.filter(edge => !!edge).slice(0, conjunctiveTopicLimit).sort();

  if (topicTerms.length > conjunctiveTopicLimit) {
    console.warn(`Only ${conjunctiveTopicLimit} terms supported, ignoring: ${topicTerms.slice(conjunctiveTopicLimit).join(', ')}`);
  }

  while (selectedFilters.length < conjunctiveTopicLimit) {
    selectedFilters.push('');
  }

  return selectedFilters;
}

function toConjunctionTopics(mainEdge, filteredEdges) {
  if (!mainEdge) {
    console.warn('mainEdge not set');
    mainEdge = '';
  }

  if (!filteredEdges || !filteredEdges.length) {
    return [mainEdge, '', ''];
  }

  return fromTopicListToConjunctionTopics([mainEdge].concat(filteredEdges));
}

function tilesForBbox(bbox, zoomLevel) {
  const fence = {north: bbox[0], west: bbox[1], south: bbox[2], east: bbox[3]};
  return geotile.tileIdsForBoundingBox(fence, zoomLevel).map(geotile.decodeTileId);
}

function tilesForLocations(locations, zoomLevel) {
  return locations.map(([lat, lon]) => geotile.tileIdFromLatLong(lat, lon, zoomLevel)).map(geotile.decodeTileId);
}

function parseFromToDate(fromDate, toDate) { // eslint-disable-line no-unused-vars
  // TODO: implement
  return {
    fromDate: '2017-08-11 15:00:00.000000+0000',
    toDate: '2017-08-11 16:00:00.000000+0000',
    period: 'hour-2017-08-11 15',
    periodType: 'hour'
  };
}

function parseLimit(limit) {
  const DEFAULT_LIMIT = 15;

  return limit > 0 ? limit : DEFAULT_LIMIT;
}

const DEFAULT_CSV_CONTAINER = 'csv-export';
const DEFAULT_CSV_EXPIRY_MINUTES = 2 * 60;

function asCsvExporter(promiseFunc, exportPropertyName, container, expiryMinutes) {
  container = container || DEFAULT_CSV_CONTAINER;
  expiryMinutes = expiryMinutes || DEFAULT_CSV_EXPIRY_MINUTES;

  function formatCsvFilename(provenance) {
    const uniqueIdentifier = uuidv4();
    const now = new Date();
    const folder = `${now.getUTCFullYear()}/${now.getUTCMonth()+1}/${now.getUTCDate()}/${now.getUTCHours()}/${now.getUTCMinutes()}/${uniqueIdentifier}`;
    return `${folder}/${provenance}.csv`;
  }

  function csvExporter(...args) {
    return new Promise((resolve, reject) => {
      promiseFunc(...args)
      .then(returnValue => {
        const csvItems = returnValue && returnValue[exportPropertyName];
        const csvText = csvItems && csvItems.length ? json2csv({ data: csvItems, withBOM: true }) : '';
        return createFile(container, formatCsvFilename(promiseFunc.name), csvText, expiryMinutes);
      })
      .then(resolve)
      .catch(reject);
    });
  }

  return csvExporter;
}

module.exports = {
  parseLimit,
  parseFromToDate,
  toPipelineKey,
  toConjunctionTopics,
  tilesForBbox,
  tilesForLocations,
  limitForInClause,
  fromTopicListToConjunctionTopics,
  asCsvExporter,
  withRunTime
};<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

"use strict";
var connect = require('connect');
var http = require('http');
var optimist = require('optimist');
var path = require('path');
var reactMiddleware = require('react-page-middleware');
var convert = require('./convert.js');

var argv = optimist.argv;

var PROJECT_ROOT = path.resolve(__dirname, '..');
var FILE_SERVE_ROOT = path.join(PROJECT_ROOT, 'src');

var port = argv.port;
if (argv.$0 === 'node ./server/generate.js') {
  // Using a different port so that you can publish the website
  // and keeping the server up at the same time.
  port = 8079;
}

var buildOptions = {
  projectRoot: PROJECT_ROOT,
  pageRouteRoot: FILE_SERVE_ROOT,
  useBrowserBuiltins: false,
  logTiming: true,
  useSourceMaps: true,
  ignorePaths: function(p) {
    return p.indexOf('__tests__') !== -1;
  },
  serverRender: true,
  dev: argv.dev !== 'false',
  static: true
};

var app = connect()
  .use(function(req, res, next) {
    // convert all the md files on every request. This is not optimal
    // but fast enough that we don't really need to care right now.
    if (!server.noconvert && req.url.match(/\.html$/)) {
      convert();
    }
    next();
  })
  .use(reactMiddleware.provide(buildOptions))
  .use(connect['static'](FILE_SERVE_ROOT))
  .use(connect.favicon(path.join(FILE_SERVE_ROOT, 'elements', 'favicon', 'favicon.ico')))
  .use(connect.logger())
  .use(connect.compress())
  .use(connect.errorHandler());

var portToUse = port || 8080;
var server = http.createServer(app);
server.listen(portToUse);
console.log('Open http://localhost:' + portToUse + '/react-native/index.html');
module.exports = server;
<commit_msg>make a callback for server run only when done<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

"use strict";
var connect = require('connect');
var http = require('http');
var optimist = require('optimist');
var path = require('path');
var reactMiddleware = require('react-page-middleware');
var convert = require('./convert.js');

var argv = optimist.argv;

var PROJECT_ROOT = path.resolve(__dirname, '..');
var FILE_SERVE_ROOT = path.join(PROJECT_ROOT, 'src');

var port = argv.port;
if (argv.$0 === 'node ./server/generate.js') {
  // Using a different port so that you can publish the website
  // and keeping the server up at the same time.
  port = 8079;
}

var buildOptions = {
  projectRoot: PROJECT_ROOT,
  pageRouteRoot: FILE_SERVE_ROOT,
  useBrowserBuiltins: false,
  logTiming: true,
  useSourceMaps: true,
  ignorePaths: function(p) {
    return p.indexOf('__tests__') !== -1;
  },
  serverRender: true,
  dev: argv.dev !== 'false',
  static: true
};

var app = connect()
  .use(function(req, res, next) {
    // convert all the md files on every request. This is not optimal
    // but fast enough that we don't really need to care right now.
    if (!server.noconvert && req.url.match(/\.html$/)) {
      convert();
    }
    next();
  })
  .use(reactMiddleware.provide(buildOptions))
  .use(connect['static'](FILE_SERVE_ROOT))
  .use(connect.favicon(path.join(FILE_SERVE_ROOT, 'elements', 'favicon', 'favicon.ico')))
  .use(connect.logger())
  .use(connect.compress())
  .use(connect.errorHandler());

var portToUse = port || 8080;
var server = http.createServer(app);
server.listen(portToUse, function(){
  console.log('Open http://localhost:' + portToUse + '/react-native/index.html');
});
module.exports = server;
<|endoftext|>


<commit_before>const { app, BrowserWindow } = require('electron');
const isDev = require('electron-is-dev');
const { resolve } = require('path');

let win;

// the hack of all hacks
// electron doesn't have a built in notification thing,
// so we launch a window on which we can use the
// HTML5 `Notification` API :'(

let buffer = [];

app.on('ready', () => {
  const win_ = new BrowserWindow({
    show: false
  });
  const url = 'file://' + resolve(
    isDev ? __dirname : app.getAppPath(),
    'notify.html'
  );
  win_.loadURL(url);
  win_.webContents.on('dom-ready', () => {
    console.log('ready');
    win = win_;
    buffer.forEach(([title, body]) => {
      notify(title, body);
    });
    buffer = null;
  });
});

function notify (title, body) {
  if (win) {
    win.webContents.send('notification', { title, body });
  } else {
    buffer.push([title, body]);
  }
}

module.exports = notify;
<commit_msg>notify: remove `console.log`<commit_after>const { app, BrowserWindow } = require('electron');
const isDev = require('electron-is-dev');
const { resolve } = require('path');

let win;

// the hack of all hacks
// electron doesn't have a built in notification thing,
// so we launch a window on which we can use the
// HTML5 `Notification` API :'(

let buffer = [];

app.on('ready', () => {
  const win_ = new BrowserWindow({
    show: false
  });
  const url = 'file://' + resolve(
    isDev ? __dirname : app.getAppPath(),
    'notify.html'
  );
  win_.loadURL(url);
  win_.webContents.on('dom-ready', () => {
    win = win_;
    buffer.forEach(([title, body]) => {
      notify(title, body);
    });
    buffer = null;
  });
});

function notify (title, body) {
  if (win) {
    win.webContents.send('notification', { title, body });
  } else {
    buffer.push([title, body]);
  }
}

module.exports = notify;
<|endoftext|>


<commit_before>app.controller('ContributionsCtrl', [
    '$scope', '$localStorage', 'ProfileContribution', 'toastr',
    function($scope, $localStorage, ProfileContribution, toastr){

        $scope.profileInfo = $localStorage.profileInfo;

        // Loading contributions.
        function loadContributions(){
            ProfileContribution.get().$promise.then(function(response){
                $scope.contributions = response.results;
            });
        }

        $scope.confirmDelete = function(postId){
            mbox.confirm('¿Eliminar publicación?', function(yes) {
                if (yes) {
                    ProfileContribution.remove({id: postId}).$promise.then(function(){
                        toastr.success('Publicación eliminada correctamente.');
                        loadContributions()
                    });
                }
            });
        };

        loadContributions();
    }
])

.controller('ContributionCtrl', [
    '$scope', '$stateParams', '$localStorage', 'ProfileContribution', 'Subject', 'Area',
    function($scope, $stateParams, $localStorage, ProfileContribution, Subject, Area){

        $scope.profileInfo = $localStorage.profileInfo;

        ProfileContribution.get({id: $stateParams.postId}).$promise.then(function(response){
            $scope.post = response;

            Subject.get(
                {
                    areaId: response.subject.area.id,
                    id: response.subject.id
                }
            ).$promise.then(function(response){
                $scope.subject = response;
            });

            Area.get(
                {id: response.subject.area.id}
            ).$promise.then(function(response){
                $scope.area = response;
            });
        });
    }
])

.controller('CreatePostCtrl', [
    '$scope', '$state', '$stateParams','Area', 'Subject', 'User', 'ProfileContribution', 'toastr', 'marked',
    function($scope, $state, $stateParams, Area, Subject, User, ProfileContribution, toastr, marked){
        $scope.post = {
            isActive: true
        };

        Area.get().$promise.then(function(response){
            $scope.areas = response.results;

            reloadSelectFields();
            $scope.post.area = parseInt($stateParams.areaId);
            $scope.loadSubjects();
        });

        $scope.loadSubjects = function(){
            if($scope.post.area){
                Subject.get(
                    {
                        areaId: $scope.post.area
                    }
                ).$promise.then(function(response){
                    $scope.subjects = response.results;
                    //
                    // this function should be executed here, because
                    // material select field should be updated when data is ready.
                    //
                    reloadSelectFields();
                });
            } else {
                $scope.subjects = null;
                reloadSelectFields();
            }
        };

        //
        // Adding preloaded subject field.
        //
        $scope.loadSubjects();
        $scope.post.subject = parseInt($stateParams.subjectId);

        //
        // Autocomplete field.
        //
        $scope.availableTo = $('#multipleInput').materialize_autocomplete({
            multiple: {
                enable: true
            },
            appender: {
                el: '.ac-users'
            },
            dropdown: {
                el: '#multipleDropdown'
            },
            getData: function(value, callback){
                User.get({q: value}).$promise.then(function(response){
                    var data = response.results;
                    callback(value, data);
                });
            }
        });

        $scope.save = function(){
            $scope.post.listAvailableTo = [];

            angular.forEach($scope.availableTo.value, function(item){
                $scope.post.listAvailableTo.push(item.id);
            });

            ProfileContribution.save($scope.post).$promise.then(function(){
                toastr.success('Publicación creada correctamente');
                return $state.go(
                    'panel.posts',
                    {
                        areaId: $scope.post.area,
                        subjectId: $scope.post.subject
                    }
                );
            }).catch(function(response){
                var errorData = prepareErrorMessages(response)
                toastr.error(errorData.info, errorData.statusText);
                return $state.go('panel.contributions');
            });
        };

        $scope.generatePreview = function(){
            $scope.post.previewContent = marked($scope.post.content);
        };

        function reloadSelectFields(){
            setTimeout(function(){
                $('select').material_select();
            }, 300);
        }

        $('#content').keydown(textareaAllowTabs);

        // Initializing materialize fields.
        $('ul.tabs').tabs();

    }
])

.controller('CreateContributionCtrl', [
    '$scope', '$state', 'Area', 'Subject', 'User', 'ProfileContribution', 'toastr', 'marked',
    function($scope, $state, Area, Subject, User, ProfileContribution, toastr, marked){
        $scope.post = {
            isActive: true
        };

        Area.get().$promise.then(function(response){
            $scope.areas = response.results;
            reloadSelectFields();
        });

        $scope.loadSubjects = function(){
            if($scope.post.area){
                Subject.get(
                    {
                        areaId: $scope.post.area
                    }
                ).$promise.then(function(response){
                    $scope.subjects = response.results;
                    //
                    // this function should be executed here, because
                    // material select field should be updated when data is ready.
                    //
                    reloadSelectFields();
                });
            } else {
                $scope.subjects = null;
                reloadSelectFields();
            }
        };

        //
        // Autocomplete field.
        //
        $scope.availableTo = $('#multipleInput').materialize_autocomplete({
            multiple: {
                enable: true
            },
            appender: {
                el: '.ac-users'
            },
            dropdown: {
                el: '#multipleDropdown'
            },
            getData: function(value, callback){
                User.get({q: value}).$promise.then(function(response){
                    var data = response.results;
                    callback(value, data);
                });
            }
        });

        $scope.save = function(){
            $scope.post.listAvailableTo = [];

            angular.forEach($scope.availableTo.value, function(item){
                $scope.post.listAvailableTo.push(item.id);
            });

            ProfileContribution.save($scope.post).$promise.then(function(){
                toastr.success('Publicación creada correctamente');
                return $state.go('panel.contributions');
            }).catch(function(response){
                var errorData = prepareErrorMessages(response)
                toastr.error(errorData.info, errorData.statusText);
                return $state.go('panel.contributions');
            });
        };

        $scope.generatePreview = function(){
            $scope.post.previewContent = marked($scope.post.content);
        };

        function reloadSelectFields(){
            setTimeout(function(){
                $('select').material_select();
            }, 300);
        }

        $('#content').keydown(textareaAllowTabs);

        // Initializing materialize fields.
        $('ul.tabs').tabs();
    }
])

.controller('EditContributionCtrl', [
    '$scope', '$state', '$stateParams', 'Area', 'Subject', 'User', 'ProfileContribution', 'toastr', 'marked',
    function($scope, $state, $stateParams, Area, Subject, User, ProfileContribution, toastr, marked){

        Area.get().$promise.then(function(response){
            $scope.areas = response.results;

            ProfileContribution.get({id: $stateParams.postId}).$promise.then(function(response){
                $scope.post = {
                    id: response.id,
                    area: response.subject.area.id,
                    content: response.content,
                    resume: response.resume,
                    name: response.name,
                    isActive: response.isActive
                };

                $scope.loadSubjects();
                $scope.post.subject = response.subject.id;

                //
                // Autocomplete field.
                //
                $scope.availableTo = $('#multipleInput').materialize_autocomplete({
                    multiple: {
                        enable: true
                    },
                    appender: {
                        el: '.ac-users'
                    },
                    dropdown: {
                        el: '#multipleDropdown'
                    },
                    getData: function(value, callback){
                        User.get({q: value}).$promise.then(function(response){
                            var data = response.results;
                            callback(value, data);
                        });
                    }
                });

                angular.forEach(response.availableTo, function(item){
                    $scope.availableTo.setValue(item);
                });

                // Initializing select fields.
                reloadSelectFields();
                $('ul.tabs').tabs();
            });
        });

        $scope.save = function(){
            $scope.post.listAvailableTo = [];

            angular.forEach($scope.availableTo.value, function(item){
                $scope.post.listAvailableTo.push(item.id);
            });

            ProfileContribution.update({id: $stateParams.postId}, $scope.post).$promise.then(function(){
                toastr.success('Publicación actualizada correctamente');
                return $state.go('panel.contributions');
            }).catch(function(response){
                var errorData = prepareErrorMessages(response)
                toastr.error(errorData.info, errorData.statusText);
                return $state.go('panel.contributions');
            });
        };

        $scope.generatePreview = function(){
            angular.element("#post-preview").html(marked($scope.post.content));
        };

        $scope.loadSubjects = function(){
            if($scope.post.area){
                Subject.get(
                    {
                        areaId: $scope.post.area
                    }
                ).$promise.then(function(response){
                    $scope.subjects = response.results;
                    //
                    // this function should be executed here, because
                    // material select field should be updated when data is ready.
                    //
                    reloadSelectFields();
                });
            } else {
                $scope.subjects = null;
                reloadSelectFields();
            }
        };

        function reloadSelectFields(){
            setTimeout(function(){
                $('select').material_select();
                Materialize.updateTextFields();
            }, 300);
        }

        $('#content').keydown(textareaAllowTabs);
    }
]);
<commit_msg>Fixing markdown preview on post form.<commit_after>app.controller('ContributionsCtrl', [
    '$scope', '$localStorage', 'ProfileContribution', 'toastr',
    function($scope, $localStorage, ProfileContribution, toastr){

        $scope.profileInfo = $localStorage.profileInfo;

        // Loading contributions.
        function loadContributions(){
            ProfileContribution.get().$promise.then(function(response){
                $scope.contributions = response.results;
            });
        }

        $scope.confirmDelete = function(postId){
            mbox.confirm('¿Eliminar publicación?', function(yes) {
                if (yes) {
                    ProfileContribution.remove({id: postId}).$promise.then(function(){
                        toastr.success('Publicación eliminada correctamente.');
                        loadContributions()
                    });
                }
            });
        };

        loadContributions();
    }
])

.controller('ContributionCtrl', [
    '$scope', '$stateParams', '$localStorage', 'ProfileContribution', 'Subject', 'Area',
    function($scope, $stateParams, $localStorage, ProfileContribution, Subject, Area){

        $scope.profileInfo = $localStorage.profileInfo;

        ProfileContribution.get({id: $stateParams.postId}).$promise.then(function(response){
            $scope.post = response;

            Subject.get(
                {
                    areaId: response.subject.area.id,
                    id: response.subject.id
                }
            ).$promise.then(function(response){
                $scope.subject = response;
            });

            Area.get(
                {id: response.subject.area.id}
            ).$promise.then(function(response){
                $scope.area = response;
            });
        });
    }
])

.controller('CreatePostCtrl', [
    '$scope', '$state', '$stateParams','Area', 'Subject', 'User', 'ProfileContribution', 'toastr', 'marked',
    function($scope, $state, $stateParams, Area, Subject, User, ProfileContribution, toastr, marked){
        $scope.post = {
            isActive: true
        };

        Area.get().$promise.then(function(response){
            $scope.areas = response.results;

            reloadSelectFields();
            $scope.post.area = parseInt($stateParams.areaId);
            $scope.loadSubjects();
        });

        $scope.loadSubjects = function(){
            if($scope.post.area){
                Subject.get(
                    {
                        areaId: $scope.post.area
                    }
                ).$promise.then(function(response){
                    $scope.subjects = response.results;
                    //
                    // this function should be executed here, because
                    // material select field should be updated when data is ready.
                    //
                    reloadSelectFields();
                });
            } else {
                $scope.subjects = null;
                reloadSelectFields();
            }
        };

        //
        // Adding preloaded subject field.
        //
        $scope.loadSubjects();
        $scope.post.subject = parseInt($stateParams.subjectId);

        //
        // Autocomplete field.
        //
        $scope.availableTo = $('#multipleInput').materialize_autocomplete({
            multiple: {
                enable: true
            },
            appender: {
                el: '.ac-users'
            },
            dropdown: {
                el: '#multipleDropdown'
            },
            getData: function(value, callback){
                User.get({q: value}).$promise.then(function(response){
                    var data = response.results;
                    callback(value, data);
                });
            }
        });

        $scope.save = function(){
            $scope.post.listAvailableTo = [];

            angular.forEach($scope.availableTo.value, function(item){
                $scope.post.listAvailableTo.push(item.id);
            });

            ProfileContribution.save($scope.post).$promise.then(function(){
                toastr.success('Publicación creada correctamente');
                return $state.go(
                    'panel.posts',
                    {
                        areaId: $scope.post.area,
                        subjectId: $scope.post.subject
                    }
                );
            }).catch(function(response){
                var errorData = prepareErrorMessages(response)
                toastr.error(errorData.info, errorData.statusText);
                return $state.go('panel.contributions');
            });
        };

        $scope.generatePreview = function(){
            angular.element("#post-preview").html(marked($scope.post.content));
        };

        function reloadSelectFields(){
            setTimeout(function(){
                $('select').material_select();
            }, 300);
        }

        $('#content').keydown(textareaAllowTabs);

        // Initializing materialize fields.
        $('ul.tabs').tabs();

    }
])

.controller('CreateContributionCtrl', [
    '$scope', '$state', 'Area', 'Subject', 'User', 'ProfileContribution', 'toastr', 'marked',
    function($scope, $state, Area, Subject, User, ProfileContribution, toastr, marked){
        $scope.post = {
            isActive: true
        };

        Area.get().$promise.then(function(response){
            $scope.areas = response.results;
            reloadSelectFields();
        });

        $scope.loadSubjects = function(){
            if($scope.post.area){
                Subject.get(
                    {
                        areaId: $scope.post.area
                    }
                ).$promise.then(function(response){
                    $scope.subjects = response.results;
                    //
                    // this function should be executed here, because
                    // material select field should be updated when data is ready.
                    //
                    reloadSelectFields();
                });
            } else {
                $scope.subjects = null;
                reloadSelectFields();
            }
        };

        //
        // Autocomplete field.
        //
        $scope.availableTo = $('#multipleInput').materialize_autocomplete({
            multiple: {
                enable: true
            },
            appender: {
                el: '.ac-users'
            },
            dropdown: {
                el: '#multipleDropdown'
            },
            getData: function(value, callback){
                User.get({q: value}).$promise.then(function(response){
                    var data = response.results;
                    callback(value, data);
                });
            }
        });

        $scope.save = function(){
            $scope.post.listAvailableTo = [];

            angular.forEach($scope.availableTo.value, function(item){
                $scope.post.listAvailableTo.push(item.id);
            });

            ProfileContribution.save($scope.post).$promise.then(function(){
                toastr.success('Publicación creada correctamente');
                return $state.go('panel.contributions');
            }).catch(function(response){
                var errorData = prepareErrorMessages(response)
                toastr.error(errorData.info, errorData.statusText);
                return $state.go('panel.contributions');
            });
        };

        $scope.generatePreview = function(){
            angular.element("#post-preview").html(marked($scope.post.content));
        };

        function reloadSelectFields(){
            setTimeout(function(){
                $('select').material_select();
            }, 300);
        }

        $('#content').keydown(textareaAllowTabs);

        // Initializing materialize fields.
        $('ul.tabs').tabs();
    }
])

.controller('EditContributionCtrl', [
    '$scope', '$state', '$stateParams', 'Area', 'Subject', 'User', 'ProfileContribution', 'toastr', 'marked',
    function($scope, $state, $stateParams, Area, Subject, User, ProfileContribution, toastr, marked){

        Area.get().$promise.then(function(response){
            $scope.areas = response.results;

            ProfileContribution.get({id: $stateParams.postId}).$promise.then(function(response){
                $scope.post = {
                    id: response.id,
                    area: response.subject.area.id,
                    content: response.content,
                    resume: response.resume,
                    name: response.name,
                    isActive: response.isActive
                };

                $scope.loadSubjects();
                $scope.post.subject = response.subject.id;

                //
                // Autocomplete field.
                //
                $scope.availableTo = $('#multipleInput').materialize_autocomplete({
                    multiple: {
                        enable: true
                    },
                    appender: {
                        el: '.ac-users'
                    },
                    dropdown: {
                        el: '#multipleDropdown'
                    },
                    getData: function(value, callback){
                        User.get({q: value}).$promise.then(function(response){
                            var data = response.results;
                            callback(value, data);
                        });
                    }
                });

                angular.forEach(response.availableTo, function(item){
                    $scope.availableTo.setValue(item);
                });

                // Initializing select fields.
                reloadSelectFields();
                $('ul.tabs').tabs();
            });
        });

        $scope.save = function(){
            $scope.post.listAvailableTo = [];

            angular.forEach($scope.availableTo.value, function(item){
                $scope.post.listAvailableTo.push(item.id);
            });

            ProfileContribution.update({id: $stateParams.postId}, $scope.post).$promise.then(function(){
                toastr.success('Publicación actualizada correctamente');
                return $state.go('panel.contributions');
            }).catch(function(response){
                var errorData = prepareErrorMessages(response)
                toastr.error(errorData.info, errorData.statusText);
                return $state.go('panel.contributions');
            });
        };

        $scope.generatePreview = function(){
            angular.element("#post-preview").html(marked($scope.post.content));
        };

        $scope.loadSubjects = function(){
            if($scope.post.area){
                Subject.get(
                    {
                        areaId: $scope.post.area
                    }
                ).$promise.then(function(response){
                    $scope.subjects = response.results;
                    //
                    // this function should be executed here, because
                    // material select field should be updated when data is ready.
                    //
                    reloadSelectFields();
                });
            } else {
                $scope.subjects = null;
                reloadSelectFields();
            }
        };

        function reloadSelectFields(){
            setTimeout(function(){
                $('select').material_select();
                Materialize.updateTextFields();
            }, 300);
        }

        $('#content').keydown(textareaAllowTabs);
    }
]);
<|endoftext|>


<commit_before>function dashboard(_args) {
	var win = Titanium.UI.createWindow({
		title:_args.title
	});
	win.backgroundColor = '#13386c';

	var data = [];
	var labels = ['account','cases','calls','contacts','emps','leads','meetings','opps','tasks'];
	for (var x=0;x<2;x++)
	{
		for (var c=0;c<labels.length;c++)
		{
			var item = Titanium.UI.createDashboardItem({
				image:'/images/dashboard/'+labels[c]+'_off.png',
				selectedImage:'/images/dashboard/'+labels[c]+'_on.png',
				label:labels[c]
			});
			if (c === 0) { item.badge = 10; }
			data.push(item);
		}
	}

	var dashboard = Titanium.UI.createDashboardView({
		data:data
	});
	win.add(dashboard);

	var label = Titanium.UI.createLabel({
		text:"Click and hold to re-order or delete",
		width:"auto",
		bottom:20,
		color:"yellow",
		height:"auto"
	});
	win.add(label);

	var cancel = Titanium.UI.createButton({
		systemButton:Titanium.UI.iPhone.SystemButton.DONE
	});
	cancel.addEventListener('click', function()
	{
		dashboard.stopEditing();
	});

	var editable = Titanium.UI.createButton({
		title:'Toggle editable'
	});
	editable.addEventListener('click', function()
	{
		dashboard.editable = !dashboard.editable;
		Ti.API.info("View is now "+ ((dashboard.editable) ? "Editable" : "Uneditable"));
	});
	win.rightNavButton = editable;

	dashboard.addEventListener('edit',function()
	{
		win.rightNavButton = cancel;
	});

	dashboard.addEventListener('commit',function()
	{
		win.rightNavButton = editable;
		Ti.API.info('data ' + dashboard.data);
		for (var i=0;i<dashboard.data.length;i++)
		{
			Ti.API.info('label ' + dashboard.data[i].label);
		}
	});

	dashboard.addEventListener('move', function(e) {
		Ti.API.log('Moved item '+e.item.label);
	});

	var event1 = 'dragStart';
	var event2 = 'dragEnd';
	if (Ti.version >= '3.0.0') {
		event1 = 'dragstart';
		event2 = 'dragend';
	}

	dashboard.addEventListener(event1, function(e) {
		Ti.API.log('Dragging item '+e.item.label);
		win.rightNavButton = null;
	});

	dashboard.addEventListener(event2, function(e) {
		Ti.API.log('Drag ended: ' + e.item.label);
		win.rightNavButton = cancel;
	});

	dashboard.addEventListener('click',function(e)
	{
		if (e.item.label == 'account')
		{
			e.item.badge = 10;
		}
		else if (e.item.label == 'cases')
		{
			for (var c=0;c<data.length;c++)
			{
				if (data[c].label=='account')
				{
					data[c].badge = 0;
					break;
				}
			}
		}
		else
		{
			try
			{
				var rect = e.location;
				var transform = Ti.UI.create2DMatrix().scale(0);
				var view = Ti.UI.createView({
					backgroundColor:'black',
					transform:transform,
					opacity:0,
					top:rect.y,
					left:rect.x,
					height:rect.height,
					width:rect.width
				});
				var close = Ti.UI.createButton({
					title:'Close',
					width:100,
					height:30
				});
				view.add(close);
				win.add(view);
				var animation = Ti.UI.createAnimation();
				animation.left = 0;
				animation.right = 0;
				animation.top = 0;
				animation.bottom = 0;
				animation.width = 320;
				animation.height = 460;
				animation.opacity = 1;
				animation.duration = 500;
				animation.transform = Ti.UI.create2DMatrix();
				view.animate(animation);
				close.addEventListener('click',function()
				{
					view.animate({
						top:rect.y,
						left:rect.x,
						height:rect.height,
						width:rect.width,
						opacity:0,
						duration:400
					},function()
					{
						win.remove(view);
					});
				});
			}
			catch(E)
			{
				Ti.API.error("ERROR = "+E);
			}
		}
	});

	return win;
};

module.exports = dashboard;
<commit_msg>fixed iOS dashboard<commit_after>function dashboard(_args) {
	var win = Titanium.UI.createWindow({
		title:_args.title
	});
	win.backgroundColor = '#13386c';
	win.orientationModes = [Ti.UI.PORTRAIT];

	var data = [];
	var labels = ['account','cases','calls','contacts','emps','leads','meetings','opps','tasks'];
	for (var x=0;x<2;x++)
	{
		for (var c=0;c<labels.length;c++)
		{
			var item = Titanium.UI.createDashboardItem({
				image:'/images/dashboard/'+labels[c]+'_off.png',
				selectedImage:'/images/dashboard/'+labels[c]+'_on.png',
				label:labels[c]
			});
			if (c === 0) { item.badge = 10; }
			data.push(item);
		}
	}

	var dashboard = Titanium.UI.createDashboardView({
		data:data
	});
	win.add(dashboard);

	var label = Titanium.UI.createLabel({
		text:"Click and hold to re-order or delete",
		width:"auto",
		bottom:20,
		color:"yellow",
		height:"auto"
	});
	win.add(label);

	var cancel = Titanium.UI.createButton({
		systemButton:Titanium.UI.iPhone.SystemButton.DONE
	});
	cancel.addEventListener('click', function()
	{
		dashboard.stopEditing();
	});

	var editable = Titanium.UI.createButton({
		title:'Toggle editable'
	});
	editable.addEventListener('click', function()
	{
		dashboard.editable = !dashboard.editable;
		Ti.API.info("View is now "+ ((dashboard.editable) ? "Editable" : "Uneditable"));
	});
	win.rightNavButton = editable;

	dashboard.addEventListener('edit',function()
	{
		win.rightNavButton = cancel;
	});

	dashboard.addEventListener('commit',function()
	{
		win.rightNavButton = editable;
		Ti.API.info('data ' + dashboard.data);
		for (var i=0;i<dashboard.data.length;i++)
		{
			Ti.API.info('label ' + dashboard.data[i].label);
		}
	});

	dashboard.addEventListener('move', function(e) {
		Ti.API.log('Moved item '+e.item.label);
	});

	var event1 = 'dragStart';
	var event2 = 'dragEnd';
	if (Ti.version >= '3.0.0') {
		event1 = 'dragstart';
		event2 = 'dragend';
	}

	dashboard.addEventListener(event1, function(e) {
		Ti.API.log('Dragging item '+e.item.label);
		win.rightNavButton = null;
	});

	dashboard.addEventListener(event2, function(e) {
		Ti.API.log('Drag ended: ' + e.item.label);
		win.rightNavButton = cancel;
	});

	dashboard.addEventListener('click',function(e)
	{
		if (e.item.label == 'account')
		{
			e.item.badge = 10;
		}
		else if (e.item.label == 'cases')
		{
			for (var c=0;c<data.length;c++)
			{
				if (data[c].label=='account')
				{
					data[c].badge = 0;
					break;
				}
			}
		}
		else
		{
			try
			{
				var rect = e.location;
				var transform = Ti.UI.create2DMatrix().scale(0);
				var view = Ti.UI.createView({
					backgroundColor:'black',
					transform:transform,
					opacity:0,
					top:rect.y,
					left:rect.x,
					height:rect.height,
					width:rect.width
				});
				var close = Ti.UI.createButton({
					title:'Close',
					width:100,
					height:30
				});
				view.add(close);
				win.add(view);
				var animation = Ti.UI.createAnimation();
				animation.left = 0;
				animation.right = 0;
				animation.top = 0;
				animation.bottom = 0;
				animation.width = 320;
				animation.height = 460;
				animation.opacity = 1;
				animation.duration = 500;
				animation.transform = Ti.UI.create2DMatrix();
				view.animate(animation);
				close.addEventListener('click',function()
				{
					view.animate({
						top:rect.y,
						left:rect.x,
						height:rect.height,
						width:rect.width,
						opacity:0,
						duration:400
					},function()
					{
						win.remove(view);
					});
				});
			}
			catch(E)
			{
				Ti.API.error("ERROR = "+E);
			}
		}
	});

	return win;
};

module.exports = dashboard;
<|endoftext|>


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

  var _ = require("lodash");
  var DSL = require("./lib/dsl");
  var Path = require("./lib/path");
  var HistoryLocation = require("./locations/history");
  var when = require("when");

  // Cached regular expressions for matching named param parts and splatted
  // parts of route strings.
  var optionalParam = /\((.*?)\)/g;
  var namedParam = /(\(\?)?:\w+/g;
  var splatParam = /\*\w+/g;
  var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;

  var CherrytreeRouter = function () {
    this.initialize.apply(this, arguments);
  };

  _.extend(CherrytreeRouter.prototype, {

    initialize: function (options) {
      this.handlers = {};
      this.dispatchHandlers = [];
      this.state = {};
      this.options = _.extend({
        location: false
      }, options);
    },

    // Convert a route string into a regular expression, suitable for matching
    // against the current location hash.
    _routeToRegExp: function(route) {
      route = route.replace(escapeRegExp, '\\$&')
                   .replace(optionalParam, '(?:$1)?')
                   .replace(namedParam, function(match, optional) {
                     return optional ? match : '([^/?]+)';
                   })
                   .replace(splatParam, '([^?]*?)');
      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
    },

    // Given a route, and a URL fragment that it matches, return the array of
    // extracted decoded parameters. Empty or unmatched parameters will be
    // treated as `null` to normalize cross-browser behavior.
    _extractParameters: function(pattern, path) {
      path = path.split("?")[0];
      var params = Path.extractParams(pattern, path);
      params.queryParams = {};
      return params;
      // var params = route.exec(fragment).slice(1);
      // return _.map(params, function(param, i) {
      //   // Don't decode the search params.
      //   if (i === params.length - 1) return param || null;
      //   return param ? decodeURIComponent(param) : null;
      // });
    },

    use: function (dispatchHandler) {
      this.dispatchHandlers.push(dispatchHandler);
    },

    map: function (routes) {
      var self = this;

      this.routes = DSL.map(routes);

      this.matchers = [];

      eachBranch(this.routes, function (routes) {
        var path = _.map(routes, function (r) {
          return r.path;
        }).join("/");
        path = path.replace("//", "");
        if (path === "/") {
          path = "";
        }
        // register routes
        var routeRegExp = new RegExp(self._routeToRegExp(path));
        self.matchers.push({
          regExp: routeRegExp,
          routes: routes,
          name: routes[routes.length - 1].name,
          path: path
        });
      }, this);

      function eachBranch(node, memo, fn, context) {
        if (!context) {
          fn = memo;
          context = fn;
          memo = [];
          node = {routes: node};
        }
        _.each(node.routes, function (route) {
          if (!route.routes || route.routes.length === 0) {
            fn.call(context, memo.concat(route));
          } else {
            eachBranch(route, memo.concat(route), fn, context);
          }
        });
      }

      return this;
    },

    loadUrl: function(fragment) {
      fragment = this.fragment = this.getFragment(fragment);
      return _.any(this.handlers, function(handler) {
        if (handler.route.test(fragment)) {
          handler.callback(fragment);
          return true;
        }
      });
    },

    computeRoutes: function (path) {
      var found = false;
      var routes = [];
      _.each(this.matchers, function (matcher) {
        if (!found && matcher.regExp.test(path)) {
          found = true;
          routes = matcher.routes;
        }
      });
      return routes;
    },

    extractParams: function (path) {
      var found = false;
      var params;
      _.each(this.matchers, function (matcher) {
        if (!found && matcher.regExp.test(path)) {
          found = true;
          params = this._extractParameters(matcher.path, path);
        }
      }, this);
      return params;
    },

    dispatch: function (path) {
      var routes, params, router = this;

      if (this.activeTransition) {
        var cancelErr = new Error("TransitionRedirected");
        cancelErr.type = "TransitionRedirected";
        this.activeTransition.cancel(cancelErr);
      }

      path = path.substr(1);

      routes = this.computeRoutes(path);
      params = this.extractParams(path);

      var resolve, reject;
      var promise = new Promise(function (res, rej) {
        resolve = res;
        reject = rej;
      });

      var cancelled = false;

      var transition = this.activeTransition = {
        prevRoutes: router.state.routes || [],
        nextRoutes: routes,
        params: params,
        path: path,
        cancel: function (err) {
          if (!err) {
            err = new Error("TransitionCancelled");
            err.type = "TransitionCancelled";
          }
          cancelled = err;
          reject(err);
        },
        redirectTo: function () {
          router.transitionTo.apply(router, arguments);
        },
        promise: promise,
        then: promise.then.bind(promise),
        catch: promise.catch.bind(promise)
      };

      setTimeout(function () {
        when.reduce(router.dispatchHandlers, function(arg, task) {
          if (cancelled) {
            throw cancelled;
          }
          return task(transition, arg);
        }, null).then(function () {
          router.activeTransition = null;
          router.state = {
            routes: transition.nextRoutes,
            params: params,
            path: path
          };
          resolve();
        }).catch(function (err) {
          if (err.type !== "TransitionCancelled") {
            reject(err);
          }
        });
      }, 1);

      return transition;
    },

    listen: function (location) {
      var self = this;
      var location = this.location = location || this.defaultLocation();
      this.previousUrl = location.getURL();
      location.onChange(function(url) {
        self.dispatch(url).then(function () {
          self.previousUrl = url;
        }).catch(function (err) {
          if (err.type === 'TransitionCancelled') {
            location.replaceURL(self.previousUrl, {trigger: false});
          }
        });
      });
      return this.dispatch(location.getURL());
    },

    defaultLocation: function () {
      var locationOptions = _.pick(this.options, ["pushState", "root", "interceptLinks"]);
      return new HistoryLocation(locationOptions);
    },

    transitionTo: function(url) {
      if (this.activeTransition) {
        return this.replaceWith.apply(this, arguments);
      }

      var location = this.location;
      if (url[0] !== "/") {
        url = this.generate.apply(this, arguments);
      }
      this.previousUrl = location.getURL();
      location.setURL(url);
      return this.activeTransition;
    },

    replaceWith: function(url) {
      var location = this.location;
      if (url[0] !== "/") {
        url = this.generate.apply(this, arguments);
      }
      this.previousUrl = location.getURL();
      location.replaceURL(url);
      return this.activeTransition;
    },

    generate: function(name, params) {
      var matcher, currentParams, pattern, paramNames, args;
      _.each(this.matchers, function (m) {
        if (m.name === name) {
          matcher = m;
        }
      });
      if (matcher) {
        currentParams = _.clone(this.state.params || {});
        delete currentParams.queryParams;
        pattern = matcher.path;
        paramNames = Path.extractParamNames(pattern);
        if (_.isObject(params)) {
          currentParams = _.extend(currentParams, params);
        } else {
          args = _.rest(arguments, 1);
          _.each(args, function (val, i) {
            var paramName = paramNames[paramNames.length - 1 - i];
            currentParams[paramName] = val;
          });
        }

        return this.location.formatURL(Path.injectParams(matcher.path, currentParams));
      } else {
        throw new Error('No route is named ' + name);
      }
    },

    destroy: function () {
      if (this.location.destroy) {
        this.location.destroy();
      }
    },

    /**
      Resets the state of the router by clearing the current route
      handlers and deactivating them.

      @method reset
     */
    reset: function() {

    }
  });

  return function cherrytree(options) {
    return new CherrytreeRouter(options);
  };

});
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });<commit_msg>Store activeTransition in the router's state<commit_after>(function (define) { 'use strict';
define(function (require) {

  var _ = require("lodash");
  var DSL = require("./lib/dsl");
  var Path = require("./lib/path");
  var HistoryLocation = require("./locations/history");
  var when = require("when");

  // Cached regular expressions for matching named param parts and splatted
  // parts of route strings.
  var optionalParam = /\((.*?)\)/g;
  var namedParam = /(\(\?)?:\w+/g;
  var splatParam = /\*\w+/g;
  var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;

  var CherrytreeRouter = function () {
    this.initialize.apply(this, arguments);
  };

  _.extend(CherrytreeRouter.prototype, {

    initialize: function (options) {
      this.handlers = {};
      this.dispatchHandlers = [];
      this.state = {};
      this.options = _.extend({
        location: false
      }, options);
    },

    // Convert a route string into a regular expression, suitable for matching
    // against the current location hash.
    _routeToRegExp: function(route) {
      route = route.replace(escapeRegExp, '\\$&')
                   .replace(optionalParam, '(?:$1)?')
                   .replace(namedParam, function(match, optional) {
                     return optional ? match : '([^/?]+)';
                   })
                   .replace(splatParam, '([^?]*?)');
      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
    },

    // Given a route, and a URL fragment that it matches, return the array of
    // extracted decoded parameters. Empty or unmatched parameters will be
    // treated as `null` to normalize cross-browser behavior.
    _extractParameters: function(pattern, path) {
      path = path.split("?")[0];
      var params = Path.extractParams(pattern, path);
      params.queryParams = {};
      return params;
      // var params = route.exec(fragment).slice(1);
      // return _.map(params, function(param, i) {
      //   // Don't decode the search params.
      //   if (i === params.length - 1) return param || null;
      //   return param ? decodeURIComponent(param) : null;
      // });
    },

    use: function (dispatchHandler) {
      this.dispatchHandlers.push(dispatchHandler);
    },

    map: function (routes) {
      var self = this;

      this.routes = DSL.map(routes);

      this.matchers = [];

      eachBranch(this.routes, function (routes) {
        var path = _.map(routes, function (r) {
          return r.path;
        }).join("/");
        path = path.replace("//", "");
        if (path === "/") {
          path = "";
        }
        // register routes
        var routeRegExp = new RegExp(self._routeToRegExp(path));
        self.matchers.push({
          regExp: routeRegExp,
          routes: routes,
          name: routes[routes.length - 1].name,
          path: path
        });
      }, this);

      function eachBranch(node, memo, fn, context) {
        if (!context) {
          fn = memo;
          context = fn;
          memo = [];
          node = {routes: node};
        }
        _.each(node.routes, function (route) {
          if (!route.routes || route.routes.length === 0) {
            fn.call(context, memo.concat(route));
          } else {
            eachBranch(route, memo.concat(route), fn, context);
          }
        });
      }

      return this;
    },

    loadUrl: function(fragment) {
      fragment = this.fragment = this.getFragment(fragment);
      return _.any(this.handlers, function(handler) {
        if (handler.route.test(fragment)) {
          handler.callback(fragment);
          return true;
        }
      });
    },

    computeRoutes: function (path) {
      var found = false;
      var routes = [];
      _.each(this.matchers, function (matcher) {
        if (!found && matcher.regExp.test(path)) {
          found = true;
          routes = matcher.routes;
        }
      });
      return routes;
    },

    extractParams: function (path) {
      var found = false;
      var params;
      _.each(this.matchers, function (matcher) {
        if (!found && matcher.regExp.test(path)) {
          found = true;
          params = this._extractParameters(matcher.path, path);
        }
      }, this);
      return params;
    },

    dispatch: function (path) {
      var routes, params, router = this;

      if (this.state.activeTransition) {
        var cancelErr = new Error("TransitionRedirected");
        cancelErr.type = "TransitionRedirected";
        this.state.activeTransition.cancel(cancelErr);
      }

      path = path.substr(1);

      routes = this.computeRoutes(path);
      params = this.extractParams(path);

      var resolve, reject;
      var promise = new Promise(function (res, rej) {
        resolve = res;
        reject = rej;
      });

      var cancelled = false;

      var transition = this.state.activeTransition = {
        prevRoutes: router.state.routes || [],
        nextRoutes: routes,
        params: params,
        path: path,
        cancel: function (err) {
          if (!err) {
            err = new Error("TransitionCancelled");
            err.type = "TransitionCancelled";
          }
          cancelled = err;
          reject(err);
        },
        redirectTo: function () {
          router.transitionTo.apply(router, arguments);
        },
        promise: promise,
        then: promise.then.bind(promise),
        catch: promise.catch.bind(promise)
      };

      setTimeout(function () {
        when.reduce(router.dispatchHandlers, function(arg, task) {
          if (cancelled) {
            throw cancelled;
          }
          return task(transition, arg);
        }, null).then(function () {
          router.state = {
            activeTransition: null,
            routes: transition.nextRoutes,
            params: params,
            path: path
          };
          resolve();
        }).catch(function (err) {
          if (err.type !== "TransitionCancelled") {
            reject(err);
          }
        });
      }, 1);

      return transition;
    },

    listen: function (location) {
      var self = this;
      var location = this.location = location || this.defaultLocation();
      this.previousUrl = location.getURL();
      location.onChange(function(url) {
        self.dispatch(url).then(function () {
          self.previousUrl = url;
        }).catch(function (err) {
          if (err.type === 'TransitionCancelled') {
            location.replaceURL(self.previousUrl, {trigger: false});
          }
        });
      });
      return this.dispatch(location.getURL());
    },

    defaultLocation: function () {
      var locationOptions = _.pick(this.options, ["pushState", "root", "interceptLinks"]);
      return new HistoryLocation(locationOptions);
    },

    transitionTo: function(url) {
      if (this.state.activeTransition) {
        return this.replaceWith.apply(this, arguments);
      }

      var location = this.location;
      if (url[0] !== "/") {
        url = this.generate.apply(this, arguments);
      }
      this.previousUrl = location.getURL();
      location.setURL(url);
      return this.state.activeTransition;
    },

    replaceWith: function(url) {
      var location = this.location;
      if (url[0] !== "/") {
        url = this.generate.apply(this, arguments);
      }
      this.previousUrl = location.getURL();
      location.replaceURL(url);
      return this.state.activeTransition;
    },

    generate: function(name, params) {
      var matcher, currentParams, pattern, paramNames, args;
      _.each(this.matchers, function (m) {
        if (m.name === name) {
          matcher = m;
        }
      });
      if (matcher) {
        currentParams = _.clone(this.state.params || {});
        delete currentParams.queryParams;
        pattern = matcher.path;
        paramNames = Path.extractParamNames(pattern);
        if (_.isObject(params)) {
          currentParams = _.extend(currentParams, params);
        } else {
          args = _.rest(arguments, 1);
          _.each(args, function (val, i) {
            var paramName = paramNames[paramNames.length - 1 - i];
            currentParams[paramName] = val;
          });
        }

        return this.location.formatURL(Path.injectParams(matcher.path, currentParams));
      } else {
        throw new Error('No route is named ' + name);
      }
    },

    destroy: function () {
      if (this.location.destroy) {
        this.location.destroy();
      }
    },

    /**
      Resets the state of the router by clearing the current route
      handlers and deactivating them.

      @method reset
     */
    reset: function() {

    }
  });

  return function cherrytree(options) {
    return new CherrytreeRouter(options);
  };

});
})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); });<|endoftext|>


<commit_before>///////////////////////////////////////
//get requests
///////////////////////////////////////

app.get('/HV', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/HV.jade');
});

app.get('/GRIFFIN', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('detectors/GRIFFIN.jade');
});

app.get('/DAQ', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/DAQ.jade');
});

app.get('/PPG', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/PPG.jade');
});

app.get('/Clocks', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/Clock.jade');
});

app.get('/Filter', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/Filter.jade');
});

///////////////////////////////////////
//post routes
///////////////////////////////////////

app.post('/postHV', function(req, res){

	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Variables/Demand["+req.body.chIndex+"] " + req.body.demandVoltage]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Up Speed["+req.body.chIndex+"]' " + req.body.voltageUp]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Down Speed["+req.body.chIndex+"]' " + req.body.voltageDown]);

	if(req.body.powerSwitch == 'off')
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 0"]);
	else
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 1"]);

	return res.redirect('/HV?crate=0&channel='+req.body.chName);
});

app.post('/registerCycle', function(req, res){
	var cycle = (req.body.cycleString) ? JSON.parse(req.body.cycleString) : null,
		i,
		steps = [],
		durations = [];

	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.loadTarget]);
		return res.redirect('/PPG');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.deleteTarget]);
		return res.redirect('/PPG');
	}

	//register a new cycle
	for(i=0; i<cycle.length; i++){
		steps[i] = parseInt(cycle[i].PPGcode, 10);
		durations[i] = parseInt(cycle[i].duration, 10);
	}

	spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "mkdir /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/PPGcodes[" + steps.length + "]"]);
	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/durations[" + steps.length + "]"]);
	for(i=0; i<cycle.length; i++){
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/PPGcodes["+ i +"]  " + Math.round(steps[i]) ]);
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/durations["+ i +"]  " + Math.round(durations[i]) ]);
	}

	if(req.body.applyCycle == 'on'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.cycleName]);
	}

	return res.redirect('/PPG');
});

app.post('/registerFilter', function(req, res){
	var filter = (req.body.filterString) ? JSON.parse(req.body.filterString) : null,
		odbManipulationFile = '',
		i, j,
		steps = [],
		durations = [];
console.log(req.body.filterString)
/*
	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.loadTarget]);
		return res.redirect('/PPG');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.deleteTarget]);
		return res.redirect('/PPG');
	}
*/
	//register a new filter - build file and run with execFile for most robust execution (spawn seems to create a race condition, consider removing).
	odbManipulationFile += 'odbedit -c "rm /Filter/Filters/' + req.body.filterName + '"\n';
	odbManipulationFile += 'odbedit -c "mkdir /Filter/Filters/' + req.body.filterName + '"\n';
	for(i=0; i<filter.length; i++){
		odbManipulationFile += 'odbedit -c "create string /Filter/Filters/' + req.body.filterName + '/orCondition'+i+'[' + filter[i].length + ']"\n';
		for(j=0; j<filter[i].length; j++){
			odbManipulationFile += 'odbedit -c "set /Filter/Filters/' + req.body.filterName + '/orCondition'+i + '['+j+'] ' + filter[i][j] + '"\n';
		}
	}

	fs.writeFile('odbManipulation.sh', odbManipulationFile, function(){
		fs.chmod('./odbManipulation.sh', '777', function(){
			execFile('./odbManipulation.sh', function(error, stdout, stderr){
				console.log('Writing ' + req.body.filterName + ' filter to ODB, process [error, stdout, stderr]:');
				console.log([error, stdout, stderr]);
			});
		});
	});

	if(req.body.applyFilter == 'on'){
		spawn('odbedit', ['-c', "set /Filter/Current " + req.body.cycleName]);
	}

	return res.redirect('/Filter');

});

app.post('/updateClock', function(req, res){
	var ClockEnB = 0,
		powerOn,
		stepdown = parseInt(req.body.freqStepdown,10);

	//channel on / off
	for(i=0; i<6; i++){
		powerOn = req.body['eSATAtoggle' + i] == 1
		ClockEnB = ClockEnB | ((powerOn) ? (0xF << 4*i) : 0);
	}
	spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[0] " + ClockEnB]);

	//freq. stepdown
	if(stepdown && req.body.isMaster=='1'){
		for(i=0; i<8; i++){
			spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[" + (11+4*i) + "] " + stepdown]);
			spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[" + (12+4*i) + "] " + stepdown]);
		}
	}

	return res.redirect('/Clocks');
});

app.post('/toggleClock', function(req, res){
	spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[1] " + req.body['radio'+req.body.clockIndex] ]);

	return res.redirect('/Clocks');
})

<commit_msg>setting current filter in ODB<commit_after>///////////////////////////////////////
//get requests
///////////////////////////////////////

app.get('/HV', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/HV.jade');
});

app.get('/GRIFFIN', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('detectors/GRIFFIN.jade');
});

app.get('/DAQ', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/DAQ.jade');
});

app.get('/PPG', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/PPG.jade');
});

app.get('/Clocks', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/Clock.jade');
});

app.get('/Filter', function(req, res){
	if(!req.cookies.midas_pwd) res.redirect(MIDAS)

	res.render('widgets/Filter.jade');
});

///////////////////////////////////////
//post routes
///////////////////////////////////////

app.post('/postHV', function(req, res){

	spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Variables/Demand["+req.body.chIndex+"] " + req.body.demandVoltage]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Up Speed["+req.body.chIndex+"]' " + req.body.voltageUp]);
	spawn('odbedit', ['-c', "set '/Equipment/HV-"+req.body.crateIndex+"/Settings/Ramp Down Speed["+req.body.chIndex+"]' " + req.body.voltageDown]);

	if(req.body.powerSwitch == 'off')
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 0"]);
	else
		spawn('odbedit', ['-c', "set /Equipment/HV-"+req.body.crateIndex+"/Settings/ChState["+req.body.chIndex+"] 1"]);

	return res.redirect('/HV?crate=0&channel='+req.body.chName);
});

app.post('/registerCycle', function(req, res){
	var cycle = (req.body.cycleString) ? JSON.parse(req.body.cycleString) : null,
		i,
		steps = [],
		durations = [];

	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.loadTarget]);
		return res.redirect('/PPG');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.deleteTarget]);
		return res.redirect('/PPG');
	}

	//register a new cycle
	for(i=0; i<cycle.length; i++){
		steps[i] = parseInt(cycle[i].PPGcode, 10);
		durations[i] = parseInt(cycle[i].duration, 10);
	}

	spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "mkdir /PPG/Cycles/" + req.body.cycleName]);

	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/PPGcodes[" + steps.length + "]"]);
	spawn('odbedit', ['-c', "create int /PPG/Cycles/" + req.body.cycleName + "/durations[" + steps.length + "]"]);
	for(i=0; i<cycle.length; i++){
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/PPGcodes["+ i +"]  " + Math.round(steps[i]) ]);
		spawn('odbedit', ['-c', "set /PPG/Cycles/" + req.body.cycleName + "/durations["+ i +"]  " + Math.round(durations[i]) ]);
	}

	if(req.body.applyCycle == 'on'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.cycleName]);
	}

	return res.redirect('/PPG');
});

app.post('/registerFilter', function(req, res){
	var filter = (req.body.filterString) ? JSON.parse(req.body.filterString) : null,
		odbManipulationFile = '',
		i, j,
		steps = [],
		durations = [];
console.log(req.body)
/*
	//just load an existing cycle
	if(req.body.loadTarget != 'null'){
		spawn('odbedit', ['-c', "set /PPG/Current " + req.body.loadTarget]);
		return res.redirect('/PPG');
	}

	//delete an existing cycle
	if(req.body.deleteTarget != 'null'){
		spawn('odbedit', ['-c', "rm /PPG/Cycles/" + req.body.deleteTarget]);
		return res.redirect('/PPG');
	}
*/
	//register a new filter - build file and run with execFile for most robust execution (spawn seems to create a race condition, consider removing).
	odbManipulationFile += 'odbedit -c "rm /Filter/Filters/' + req.body.filterName + '"\n';
	odbManipulationFile += 'odbedit -c "mkdir /Filter/Filters/' + req.body.filterName + '"\n';
	for(i=0; i<filter.length; i++){
		odbManipulationFile += 'odbedit -c "create string /Filter/Filters/' + req.body.filterName + '/orCondition'+i+'[' + filter[i].length + ']"\n';
		for(j=0; j<filter[i].length; j++){
			odbManipulationFile += 'odbedit -c "set /Filter/Filters/' + req.body.filterName + '/orCondition'+i + '['+j+'] ' + filter[i][j] + '"\n';
		}
	}

	fs.writeFile('odbManipulation.sh', odbManipulationFile, function(){
		fs.chmod('./odbManipulation.sh', '777', function(){
			execFile('./odbManipulation.sh', function(error, stdout, stderr){
				console.log('Writing ' + req.body.filterName + ' filter to ODB, process [error, stdout, stderr]:');
				console.log([error, stdout, stderr]);
			});
		});
	});

	if(req.body.applyFilter == 'on'){
		spawn('odbedit', ['-c', "set /Filter/Current " + req.body.cycleName]);
	}

	return res.redirect('/Filter');

});

app.post('/updateClock', function(req, res){
	var ClockEnB = 0,
		powerOn,
		stepdown = parseInt(req.body.freqStepdown,10);

	//channel on / off
	for(i=0; i<6; i++){
		powerOn = req.body['eSATAtoggle' + i] == 1
		ClockEnB = ClockEnB | ((powerOn) ? (0xF << 4*i) : 0);
	}
	spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[0] " + ClockEnB]);

	//freq. stepdown
	if(stepdown && req.body.isMaster=='1'){
		for(i=0; i<8; i++){
			spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[" + (11+4*i) + "] " + stepdown]);
			spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[" + (12+4*i) + "] " + stepdown]);
		}
	}

	return res.redirect('/Clocks');
});

app.post('/toggleClock', function(req, res){
	spawn('odbedit', ['-c', "set /Equipment/GRIF-Clk" + req.body.clockIndex + "/Variables/Output[1] " + req.body['radio'+req.body.clockIndex] ]);

	return res.redirect('/Clocks');
})

<|endoftext|>


<commit_before>"use strict";
const express = require('express');
const router = express.Router();
const cms = require('../cms.js');
const mongoose = require('mongoose');
const Shuttle = require("../schema/shuttle.js");
const helperLib = require("../helper.js").helpers;
const eventEmitter = require('../app').eventEmitter;
const moment = require('moment');
const helper = new helperLib();
module.exports = router;
router.post('/', function(req, res) {
	if (!req.session || !req.session.cas_user) {
		res.redirect("/login");
		return;
	}
	var rcs_id = req.session.cas_user.toLowerCase();
	var shuttleID = req.body.id;
	var numGuests = req.body.numGuests;
	var guestsOnly = req.body.guestsOnly;
	// Now let's do some basic validation of the request body
	if (typeof numGuests != "number" || typeof guestsOnly != "boolean") {
		res.status(400);
		res.send("Your request appears to be malformed.");
		return;
	}
	var query = Shuttle.find({
		_id: shuttleID
	}).lean();

	// Remove unnecessary fields from the query for performance improvement
	query.select('riders');
	query.select('waitlist');
	query.select('vacancies');

	query.exec(function(err, docs) {
		if (err) {
			res.send("There was an error signing up for shuttle " + shuttleID);
			return;
		}
		// Let's assume that this is the only shuttle with this ID (if not, we have issues).
		var shuttle = docs[0];
		if (shuttle == null) {
			res.send("That shuttle doesn't exist.");
			return;
		}
		var riders = shuttle.riders;
		var waitlist = shuttle.waitlist;
		var vacancies = shuttle.vacancies;
		// Let's check to make sure the shuttle is active.
		if (!shuttle.isActive) {
			res.send("This shuttle is inactive.");
			return;
		}
		// Let's check to ensure it has not passed the admin defined close-signup date and time
		if (moment(Date).isSameOrAfter(shuttle.closeSignup)) {
			res.send("Signups for this shuttle have ended.");
			return;
		}

		// Great, they're not bringing guests.
		if (numGuests === 0) {
			// Let's go ahead and add them to the list
			// Let's make sure they're not already signed up for a shuttle.
			if (riders.indexOf(rcs_id) != -1) {
				res.send("You've already signed up for shuttle " + shuttleID);
				return;
			}
			else if (waitlist.indexOf(rcs_id) != -1) {
				res.send("You're already on the waitlist for shuttle " + shuttleID + ". You're currently number " + waitlist.indexOf(rcs_id) + " in line.");
				return;
			}
			// If the shuttle currently has a vacancy
			if (vacancies >= 1) {
				riders.push(rcs_id);
				//vacancies--;
				Shuttle.findOneAndUpdate({
					_id: shuttleID
				}, {
					riders: riders,
					//vacancies: vacancies
				}, function(err) {
					if (err) {
						console.log(err);
						res.send("There was an error signing up for shuttle " + shuttleID);
						return;
					}
					res.send("OK, you're signed up for shuttle " + shuttleID);
					var webSocketResponseAdmin = {type: "signup-shuttle", shuttle: [shuttleID, riders, vacancies]};
					eventEmitter.emit('websocket-admin', JSON.stringify(webSocketResponseAdmin));
					var webSocketResponse = {type: "signup-shuttle", shuttle: [shuttleID, vacancies]};
					eventEmitter.emit('websocket', JSON.stringify(webSocketResponse));
					return;
				});
			}

			else {
				// This means there aren't any vacancies on the shuttle
				waitlist.push(rcs_id);
				Shuttle.findOneAndUpdate({
					_id: shuttleID
				}, {
					waitlist: waitlist
				}, function(err) {
					if (err) {
						res.send("There was an error adding you to the waitlist for shuttle " + shuttleID);
						return;
					}
					res.send("You've been added to the waitlist for shuttle " + shuttleID + ". You're currently number " + waitlist.length + " in line.");
					var webSocketResponseAdmin = {type: "signup-shuttle-waitlist", shuttle: [shuttleID, waitlist]};
					eventEmitter.emit('websocket-admin', JSON.stringify(webSocketResponseAdmin));
					var webSocketResponse = {type: "signup-shuttle-waitlist", shuttle: [shuttleID, waitlist.length]};
					eventEmitter.emit('websocket', JSON.stringify(webSocketResponse));
					return;
				});
			}
		}
		// ... They're bringing guests (or at least have indicated their willingness to do so)
		else if (numGuests > 0) {
			if (riders.indexOf(rcs_id) != -1) {
				res.send("You've already signed up for shuttle " + shuttleID + ". To add guests, you'll need to unsignup, and then resignup with your guests.");
				return;
			}
			else if (waitlist.indexOf(rcs_id) != -1) {
				res.send("You're already on the waitlist for shuttle " + shuttleID + ". You're currently number " + waitlist.indexOf(rcs_id) + " in line.");
				return;
			}
			// Let's check to see if guests are even allowed
			if (shuttle.guestsAllowed === 0) {
				res.send("Guests aren't allowed on this shuttle.");
				return;
			}
			// Check to make sure the waitlist doesn't have riders on it (this will fix the condition explained by JCBird1012 in issue #3 on the repo)
			if (waitlist.length > 0) {
				res.send("This shuttle has a waitlist. Guests aren't allowed when a shuttle has an outstanding waitlist.");
				return;
			}
			else if (vacancies < numGuests + 1) {
				res.send("There isn't enough room on this shuttle.");
				return;
			}

			riders.push(rcs_id);
			vacancies--;

			// Not sure if I like this formatting.
			// Currently, a guest is formatted like: RCSID-guest#
			for (var i = 0; i < numGuests; i++) {
				riders.push(rcs_id + "-guest" + i);
				vacancies--;
			}
			Shuttle.findOneAndUpdate({
				_id: shuttleID
			}, {
				riders: riders,
				vacancies: vacancies
			}, function(err) {
				if (err) {
					res.send("There was an error adding your guests and you to the shuttle " + shuttleID);
					return;
				}
				res.send("Your " + numGuests + " guests and you have signed up for shuttle " + shuttleID);
				var webSocketResponseAdmin = {type: "signup-shuttle", shuttle: [shuttleID, riders, vacancies]};
				eventEmitter.emit('websocket-admin', JSON.stringify(webSocketResponseAdmin));
				var webSocketResponse = {type: "signup-shuttle", shuttle: [shuttleID, vacancies]};
				eventEmitter.emit('websocket', JSON.stringify(webSocketResponse));
				return;
			});
		}
	});
});
<commit_msg>Update code syntax in shuttle-signup route<commit_after>"use strict";
const express = require('express');
const router = express.Router();
const cms = require('../cms.js');
const mongoose = require('mongoose');
const Shuttle = require("../schema/shuttle.js");
const helperLib = require("../helper.js").helpers;
const eventEmitter = require('../app').eventEmitter;
const moment = require('moment');
const helper = new helperLib();
module.exports = router;
router.post('/', function(req, res) {
	if (!req.session || !req.session.cas_user) {
		res.redirect("/login");
		return;
	}
	var rcs_id = req.session.cas_user.toLowerCase();
	var shuttleID = req.body.id;
	var numGuests = req.body.numGuests;
	var guestsOnly = req.body.guestsOnly;
	// Now let's do some basic validation of the request body
	if (typeof numGuests !== "number" || typeof guestsOnly !== "boolean") {
		res.status(400);
		res.send("Your request appears to be malformed.");
		return;
	}
	var query = Shuttle.find({
		_id: shuttleID
	}).lean();

	// Remove unnecessary fields from the query for performance improvement
	query.select('riders');
	query.select('waitlist');
	query.select('vacancies');

	query.exec(function(err, docs) {
		if (err) {
			res.send("There was an error signing up for shuttle " + shuttleID);
			return;
		}
		// Let's assume that this is the only shuttle with this ID (if not, we have issues).
		var shuttle = docs[0];
		if (shuttle === null) {
			res.send("That shuttle doesn't exist.");
			return;
		}
		var riders = shuttle.riders;
		var waitlist = shuttle.waitlist;
		var vacancies = shuttle.vacancies;
		// Let's check to make sure the shuttle is active.
		if (!shuttle.isActive) {
			res.send("This shuttle is inactive.");
			return;
		}
		// Let's check to ensure it has not passed the admin defined close-signup date and time
		if (moment(Date).isSameOrAfter(shuttle.closeSignup)) {
			res.send("Signups for this shuttle have ended.");
			return;
		}

		// Great, they're not bringing guests.
		if (numGuests === 0) {
			// Let's go ahead and add them to the list
			// Let's make sure they're not already signed up for a shuttle.
			if (riders.indexOf(rcs_id) !== -1) {
				res.send("You've already signed up for shuttle " + shuttleID);
				return;
			}
			else if (waitlist.indexOf(rcs_id) !== -1) {
				res.send("You're already on the waitlist for shuttle " + shuttleID + ". You're currently number " + waitlist.indexOf(rcs_id) + " in line.");
				return;
			}
			// If the shuttle currently has a vacancy
			if (vacancies >= 1) {
				riders.push(rcs_id);
				//vacancies--;
				Shuttle.findOneAndUpdate({
					_id: shuttleID
				}, {
					riders: riders,
					//vacancies: vacancies
				}, function(err) {
					if (err) {
						console.log(err);
						res.send("There was an error signing up for shuttle " + shuttleID);
						return;
					}
					res.send("OK, you're signed up for shuttle " + shuttleID);
					var webSocketResponseAdmin = {type: "signup-shuttle", shuttle: [shuttleID, riders, vacancies]};
					eventEmitter.emit('websocket-admin', JSON.stringify(webSocketResponseAdmin));
					var webSocketResponse = {type: "signup-shuttle", shuttle: [shuttleID, vacancies]};
					eventEmitter.emit('websocket', JSON.stringify(webSocketResponse));
					return;
				});
			}

			else {
				// This means there aren't any vacancies on the shuttle
				waitlist.push(rcs_id);
				Shuttle.findOneAndUpdate({
					_id: shuttleID
				}, {
					waitlist: waitlist
				}, function(err) {
					if (err) {
						res.send("There was an error adding you to the waitlist for shuttle " + shuttleID);
						return;
					}
					res.send("You've been added to the waitlist for shuttle " + shuttleID + ". You're currently number " + waitlist.length + " in line.");
					var webSocketResponseAdmin = {type: "signup-shuttle-waitlist", shuttle: [shuttleID, waitlist]};
					eventEmitter.emit('websocket-admin', JSON.stringify(webSocketResponseAdmin));
					var webSocketResponse = {type: "signup-shuttle-waitlist", shuttle: [shuttleID, waitlist.length]};
					eventEmitter.emit('websocket', JSON.stringify(webSocketResponse));
					return;
				});
			}
		}
		// ... They're bringing guests (or at least have indicated their willingness to do so)
		else if (numGuests > 0) {
			if (riders.indexOf(rcs_id) !== -1) {
				res.send("You've already signed up for shuttle " + shuttleID + ". To add guests, you'll need to unsignup, and then resignup with your guests.");
				return;
			}
			else if (waitlist.indexOf(rcs_id) !== -1) {
				res.send("You're already on the waitlist for shuttle " + shuttleID + ". You're currently number " + waitlist.indexOf(rcs_id) + " in line.");
				return;
			}
			// Let's check to see if guests are even allowed
			if (shuttle.guestsAllowed === 0) {
				res.send("Guests aren't allowed on this shuttle.");
				return;
			}
			// Check to make sure the waitlist doesn't have riders on it (this will fix the condition explained by JCBird1012 in issue #3 on the repo)
			if (waitlist.length > 0) {
				res.send("This shuttle has a waitlist. Guests aren't allowed when a shuttle has an outstanding waitlist.");
				return;
			}
			else if (vacancies < numGuests + 1) {
				res.send("There isn't enough room on this shuttle.");
				return;
			}

			riders.push(rcs_id);
			vacancies--;

			// Not sure if I like this formatting.
			// Currently, a guest is formatted like: RCSID-guest#
			for (var i = 0; i < numGuests; i++) {
				riders.push(rcs_id + "-guest" + i);
				vacancies--;
			}
			Shuttle.findOneAndUpdate({
				_id: shuttleID
			}, {
				riders: riders,
				vacancies: vacancies
			}, function(err) {
				if (err) {
					res.send("There was an error adding your guests and you to the shuttle " + shuttleID);
					return;
				}
				res.send("Your " + numGuests + " guests and you have signed up for shuttle " + shuttleID);
				var webSocketResponseAdmin = {type: "signup-shuttle", shuttle: [shuttleID, riders, vacancies]};
				eventEmitter.emit('websocket-admin', JSON.stringify(webSocketResponseAdmin));
				var webSocketResponse = {type: "signup-shuttle", shuttle: [shuttleID, vacancies]};
				eventEmitter.emit('websocket', JSON.stringify(webSocketResponse));
				return;
			});
		}
	});
});
<|endoftext|>