<commit_before>module.exports = function(robot) {
    'use strict'

    var slackmsg = require("./slackMsgs.js");
    var trello = require("./trello-api.js");
    var request = require('request');
    var Trello = require('node-trello');

    // auth
    var key = process.env.HUBOT_TRELLO_KEY;
    var token = process.env.HUBOT_TRELLO_TOKEN;
    var t = new Trello(key, token);

    function sendMessageToSlackResponseURL(responseURL, JSONmessage){
      var postOptions = {
          uri: responseURL,
          method: 'POST',
          headers: {
              'Content-type': 'application/json'
          },
          json: JSONmessage
      };
      request(postOptions, (error, response, body) => {
          if (error){
              // handle errors as you see fit
          };
      })
    }

    /*******************************************************************/
    /* trello api                 BOARDS                               */
    /*******************************************************************/

    // Associate a board with a specific Channel
    robot.hear(/trello board (.*)/i, function(res_r) {
        let board = res_r.match[1];
        // TODO!
    })

    // trello board
    robot.hear(/trello board/i, trello_board)

    function trello_board(res_r){
        // TODO: fetch the board id from other source (env, redis or mongodb)
        let boardId = 'BE7seI7e';
        let pars = {fields: "name,url,prefs"};
        trello.getBoard(boardId, pars)
            .then(function(data){
                var board_data = data;
                // customize slack's interactive message
                let msg = slackmsg.buttons();
                msg.attachments[0].title = `<${data.url}|${data.name}>`;
                msg.attachments[0].title_url = 'www.google.com'
                msg.attachments[0].author_name = 'Board'
                msg.attachments[0].callback_id = `trello_board`;
                msg.attachments[0].color = `${data.prefs.backgroundColor}`;

                // attach the board lists to buttons
                let joinBtn = {"name": "join", "text": "Join","type":"button", "value": "join"};
                let subBtn  = {"name": "sub", "text": "Subscribe","type":"button", "value": "sub"};
                let starBtn = {"name": "star", "text": "Star","type":"button", "value": "star"};
                let listsBtn= {"name": "lists", "text": "Lists","type":"button", "value": "lists"};
                let doneBtn = {"name": "done", "text": "Done","type":"button", "value": "done","style": "danger"};
                msg.attachments[0].actions.push(joinBtn);
                msg.attachments[0].actions.push(subBtn);
                msg.attachments[0].actions.push(starBtn);
                msg.attachments[0].actions.push(listsBtn);
                msg.attachments[0].actions.push(doneBtn);

                console.log(data);
                res_r.send(msg);
            })
            .fail(function(err){
                console.log(err);
            })
        /*
        t.get("/1/board/"+boardId, {lists:"all"}, function(err, data){
            if (err){
                res_r.send('Error Encountered: '+ err['responseBody']);
                return false;
            }

            // customize slack's interactive message
            let msg = slackmsg.buttons();
            msg.text = `Board Name: *${data.name}*`;
            msg.attachments[0].text = `Board's Lists`;
            msg.attachments[0].callback_id = `trello_board`;

            // attach the board lists to buttons
            let listsNum = Object.keys(data.lists).length;
            for (var i=0; i<listsNum; i++){
                let list    = data.lists[i].name;
                let listId  = data.lists[i].id;
                let item    = {"name": list, "text": list,"type":"button", "value": listId};
                msg.attachments[0].actions.push(item);
            }

            res_r.send(msg);
        })*/
    }

    /*******************************************************************/
    /*                        robot.on listeners                       */
    /*******************************************************************/

    var slackCB = 'slack:msg_action:';

    // responding to 'trello_board' interactive message
    robot.on(slackCB + 'trello_board', function(data, res){
        console.log(`robot.on: ${slackCB}trello_board`);
        let btnId = data.actions[0].value;
        let btnName = data.actions[0].name;
        let response_url = data.response_url;
        let msg;

        switch (btnId) {
          case 'join':
            break;
          case 'sub':
            break;
          case 'star':
                break;
          case 'lists':
            res.status(200).end() // best practice to respond with 200 status
            // FETCH LISTS FIRST

            // get board info to fetch lists
            let boardId = 'BE7seI7e';
            let args = {lists:"all"};
            t.get("1/board/"+boardId, args, function(err, data){
                if (err){
                    res.send(err);
                    robot.logger.error(err);
                    return;
                }
                // else if (!err)
                // create buttons msg
                let msg = slackmsg.buttons();

                let listsNum = Object.keys(data.lists).length;
                console.log(`lists: &{listsNum}`);
                console.log(data);
                for (var i=0; i<listsNum; i++){
                    // TODO change value to some id or something similar
                    let list = {"text": data.lists[i], "value": data.lists[i]};
                    msg.attachments[0].actions.push(list);
                }
                sendMessageToSlackResponseURL(response_url, msg);
            })

            // let pars = ''; //{cards: "all"};
            // let listId = '';
            // trello.getList(listId, pars)
            //     .then(function(data_list){

            //         // create buttons msg
            //         let msg = slackmsg.buttons();
            //         msg.text = `*${listName}* list`;
            //         msg.attachments[0].text = `Available Cards`;
            //         msg.attachments[0].callback_id = `trello_list`;

            //         let cardsNum = Object.keys(data_list.cards).length;
            //         console.log(`total cards: ${cardsNum}`);
            //         for (var i=0; i<cardsNum; i++){
            //             let card    = data_list.cards[i].name;
            //             let cardId  = data_list.cards[i].id;
            //             let item    = {"name": card, "text": card,"type":"button", "value": cardId};
            //             msg.attachments[0].actions.push(item);
            //         }

            //         // respond with information for that list
            //         res.send(msg);
            //         console.log(msg.attachments[0].actions);
            //         })
            //     .fail(function(err){
            //         res.send(err);
            //         console.log(err);
            // });
            // let listsNum = Object.keys(data.lists).length;
            // msg = slackmsg.menu();
            // for (var i=0; i<listsNum; i++){
            //     // TODO change value to some id or something similar
            //     let list = {"text": data.lists[i], "value": data.lists[i]};
            //     msg.attachments[0].actions[0].options.push(list);
            // }
            // sendMessageToSlackResponseURL(response_url, msg);
            break;
          case 'done':
            res.status(200).end() // best practice to respond with 200 status
            msg = slackmsg.plainText();
            sendMessageToSlackResponseURL(response_url, msg);
            // res.send(msg);
            break;
          default:
            //Statements executed when none of the values match the value of the expression
            break;
        }
    })

    // responding to 'trello_list' interactive message
    robot.on(slackCB + 'trello_list', function(data_board, res){
        robot.logger.info(`robot.on: ${slackCB}trello_list`);
        let listId = data_board.actions[0].value;
        let listName = data_board.actions[0].name;

        // call function to fetch list - provide list id
        let pars = {cards: "all"};
        trello.getList(listId, pars)
            .then(function(data_list){

                // create buttons msg
                let msg = slackmsg.buttons();
                msg.text = `*${listName}* list`;
                msg.attachments[0].text = `Available Cards`;
                msg.attachments[0].callback_id = `trello_list`;

                let cardsNum = Object.keys(data_list.cards).length;
                robot.logger.info(`total cards: ${cardsNum}`);
                for (var i=0; i<cardsNum; i++){
                    let card    = data_list.cards[i].name;
                    let cardId  = data_list.cards[i].id;
                    let item    = {"name": card, "text": card,"type":"button", "value": cardId};
                    msg.attachments[0].actions.push(item);
                }

                // respond with information for that list
                res.send(msg);
                //console.log(msg.attachments[0].actions);
                })
            .fail(function(err){
                res.send(err);
                robot.logger.error(err);
        });
    })

    /*  TODO: add more functionality */

        robot.hear(/trello test/i, function(data, res){
            var d;
            trello.test(d);
            console.log(`d: ${d}`);
        })

}

    /* template */

    // robot.respond(/trello /i, function(res_r) {
    //     t.post("/1/", function(err, data){
    //         if (err){
    //             res_r.send('Error Encountered: '+ err['responseBody']);
    //         }
    //     })
    // })

/* An example of using slack's response_url. ~For future use */
/* Add this snippet inside robot.on that u want to trigger   */

    // var response_url = data.response_url;
    // var slackMsg = require('./slackMsgs');
    // var response = slackMsg.ephemeralMsg();

    // sendMessageToSlackResponseURL(response_url, response);

<commit_msg>update trello-integration file<commit_after>module.exports = function(robot) {
    'use strict'

    var slackmsg = require("./slackMsgs.js");
    var trello = require("./trello-api.js");
    var request = require('request');
    var Trello = require('node-trello');

    // auth
    var key = process.env.HUBOT_TRELLO_KEY;
    var token = process.env.HUBOT_TRELLO_TOKEN;
    var t = new Trello(key, token);

    function sendMessageToSlackResponseURL(responseURL, JSONmessage){
      var postOptions = {
          uri: responseURL,
          method: 'POST',
          headers: {
              'Content-type': 'application/json'
          },
          json: JSONmessage
      };
      request(postOptions, (error, response, body) => {
          if (error){
              // handle errors as you see fit
          };
      })
    }

    /*******************************************************************/
    /* trello api                 BOARDS                               */
    /*******************************************************************/

    // Associate a board with a specific Channel
    robot.hear(/trello board (.*)/i, function(res_r) {
        let board = res_r.match[1];
        // TODO!
    })

    // trello board
    robot.hear(/trello board/i, trello_board)

    function trello_board(res_r){
        // TODO: fetch the board id from other source (env, redis or mongodb)
        let boardId = 'BE7seI7e';
        let pars = {fields: "name,url,prefs"};
        trello.getBoard(boardId, pars)
            .then(function(data){
                var board_data = data;
                // customize slack's interactive message
                let msg = slackmsg.buttons();
                msg.attachments[0].title = `<${data.url}|${data.name}>`;
                msg.attachments[0].title_url = 'www.google.com'
                msg.attachments[0].author_name = 'Board'
                msg.attachments[0].callback_id = `trello_board`;
                msg.attachments[0].color = `${data.prefs.backgroundColor}`;

                // attach the board lists to buttons
                let joinBtn = {"name": "join", "text": "Join","type":"button", "value": "join"};
                let subBtn  = {"name": "sub", "text": "Subscribe","type":"button", "value": "sub"};
                let starBtn = {"name": "star", "text": "Star","type":"button", "value": "star"};
                let listsBtn= {"name": "lists", "text": "Lists","type":"button", "value": "lists"};
                let doneBtn = {"name": "done", "text": "Done","type":"button", "value": "done","style": "danger"};
                msg.attachments[0].actions.push(joinBtn);
                msg.attachments[0].actions.push(subBtn);
                msg.attachments[0].actions.push(starBtn);
                msg.attachments[0].actions.push(listsBtn);
                msg.attachments[0].actions.push(doneBtn);

                console.log(data);
                res_r.send(msg);
            })
            .fail(function(err){
                console.log(err);
            })
        /*
        t.get("/1/board/"+boardId, {lists:"all"}, function(err, data){
            if (err){
                res_r.send('Error Encountered: '+ err['responseBody']);
                return false;
            }

            // customize slack's interactive message
            let msg = slackmsg.buttons();
            msg.text = `Board Name: *${data.name}*`;
            msg.attachments[0].text = `Board's Lists`;
            msg.attachments[0].callback_id = `trello_board`;

            // attach the board lists to buttons
            let listsNum = Object.keys(data.lists).length;
            for (var i=0; i<listsNum; i++){
                let list    = data.lists[i].name;
                let listId  = data.lists[i].id;
                let item    = {"name": list, "text": list,"type":"button", "value": listId};
                msg.attachments[0].actions.push(item);
            }

            res_r.send(msg);
        })*/
    }

    /*******************************************************************/
    /*                        robot.on listeners                       */
    /*******************************************************************/

    var slackCB = 'slack:msg_action:';

    // responding to 'trello_board' interactive message
    robot.on(slackCB + 'trello_board', function(data, res){
        console.log(`robot.on: ${slackCB}trello_board`);
        let btnId = data.actions[0].value;
        let btnName = data.actions[0].name;
        let response_url = data.response_url;
        let msg;

        switch (btnId) {
          case 'join':
            break;
          case 'sub':
            break;
          case 'star':
                break;
          case 'lists':
            res.status(200).end() // best practice to respond with 200 status
            // FETCH LISTS FIRST

            // get board info to fetch lists
            let boardId = 'BE7seI7e';
            let args = {lists:"all"};
            t.get("1/board/"+boardId, args, function(err, data){
                if (err){
                    res.send(err);
                    robot.logger.error(err);
                    return;
                }
                // else if (!err)
                // create buttons msg
                let msg = slackmsg.buttons();

                let listsNum = Object.keys(data.lists).length;
                console.log(`lists: ${listsNum}`);
                console.log(data);
                for (var i=0; i<listsNum; i++){
                    // TODO change value to some id or something similar
                    let list = {"text": data.lists[i].name, "value": data.lists[i].name};
                    msg.attachments[0].actions.push(list);
                }
                sendMessageToSlackResponseURL(response_url, msg);
            })

            // let pars = ''; //{cards: "all"};
            // let listId = '';
            // trello.getList(listId, pars)
            //     .then(function(data_list){

            //         // create buttons msg
            //         let msg = slackmsg.buttons();
            //         msg.text = `*${listName}* list`;
            //         msg.attachments[0].text = `Available Cards`;
            //         msg.attachments[0].callback_id = `trello_list`;

            //         let cardsNum = Object.keys(data_list.cards).length;
            //         console.log(`total cards: ${cardsNum}`);
            //         for (var i=0; i<cardsNum; i++){
            //             let card    = data_list.cards[i].name;
            //             let cardId  = data_list.cards[i].id;
            //             let item    = {"name": card, "text": card,"type":"button", "value": cardId};
            //             msg.attachments[0].actions.push(item);
            //         }

            //         // respond with information for that list
            //         res.send(msg);
            //         console.log(msg.attachments[0].actions);
            //         })
            //     .fail(function(err){
            //         res.send(err);
            //         console.log(err);
            // });
            // let listsNum = Object.keys(data.lists).length;
            // msg = slackmsg.menu();
            // for (var i=0; i<listsNum; i++){
            //     // TODO change value to some id or something similar
            //     let list = {"text": data.lists[i], "value": data.lists[i]};
            //     msg.attachments[0].actions[0].options.push(list);
            // }
            // sendMessageToSlackResponseURL(response_url, msg);
            break;
          case 'done':
            res.status(200).end() // best practice to respond with 200 status
            msg = slackmsg.plainText();
            sendMessageToSlackResponseURL(response_url, msg);
            // res.send(msg);
            break;
          default:
            //Statements executed when none of the values match the value of the expression
            break;
        }
    })

    // responding to 'trello_list' interactive message
    robot.on(slackCB + 'trello_list', function(data_board, res){
        robot.logger.info(`robot.on: ${slackCB}trello_list`);
        let listId = data_board.actions[0].value;
        let listName = data_board.actions[0].name;

        // call function to fetch list - provide list id
        let pars = {cards: "all"};
        trello.getList(listId, pars)
            .then(function(data_list){

                // create buttons msg
                let msg = slackmsg.buttons();
                msg.text = `*${listName}* list`;
                msg.attachments[0].text = `Available Cards`;
                msg.attachments[0].callback_id = `trello_list`;

                let cardsNum = Object.keys(data_list.cards).length;
                robot.logger.info(`total cards: ${cardsNum}`);
                for (var i=0; i<cardsNum; i++){
                    let card    = data_list.cards[i].name;
                    let cardId  = data_list.cards[i].id;
                    let item    = {"name": card, "text": card,"type":"button", "value": cardId};
                    msg.attachments[0].actions.push(item);
                }

                // respond with information for that list
                res.send(msg);
                //console.log(msg.attachments[0].actions);
                })
            .fail(function(err){
                res.send(err);
                robot.logger.error(err);
        });
    })

    /*  TODO: add more functionality */

        robot.hear(/trello test/i, function(data, res){
            var d;
            trello.test(d);
            console.log(`d: ${d}`);
        })

}

    /* template */

    // robot.respond(/trello /i, function(res_r) {
    //     t.post("/1/", function(err, data){
    //         if (err){
    //             res_r.send('Error Encountered: '+ err['responseBody']);
    //         }
    //     })
    // })

/* An example of using slack's response_url. ~For future use */
/* Add this snippet inside robot.on that u want to trigger   */

    // var response_url = data.response_url;
    // var slackMsg = require('./slackMsgs');
    // var response = slackMsg.ephemeralMsg();

    // sendMessageToSlackResponseURL(response_url, response);

<|endoftext|>


<commit_before>/*jslint node: true, vars: true, nomen: true */
'use strict';

var express = require('express');
var Http = require('http');
var debug = require('debug')('xpl-db:server');
var async = require('async');
var noCache = require('connect-nocache')();
var bodyParser = require('body-parser');
var serve_static = require('serve-static');
var compress = require('compression');

class Server {
  constructor(configuration, store) {
    this.configuration = configuration || {};
    this.store = store;

    this.app = this.configuration.express || express();

    if (this.configuration.compression !== false) {
      try {
        var compression = require('compression');
        this.app.use(compression())
      } catch (x) {
        console.error("No compression module !");
      }
    }
  }

  listen(callback) {
    var app = this.app;

    app.enable('etag');
    app.use(compress());
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({
      extended: true
    }));
//    app.use(noCache);

    app.get(/^\/last\/(.*)$/, this.getLast.bind(this));
    app.get(/^\/history\/(.*)$/, this.getHistory.bind(this));
    app.get(/^\/minMaxAvgSum\/(.*)$/, this.getMinMaxAvgSum.bind(this));

    app.post('/last', this.getLastSet.bind(this));
    app.post('/history', this.getHistorySet.bind(this));
    app.post('/minMaxAvgSum', this.getMinMaxAvgSumSet.bind(this));

    if (this.configuration.configPath) {

      var oneYear = 1000*60*60*24*365;

      app.use(express.static(__dirname + '/public', {  }));

      app.use("/config", serve_static(this.configuration.configPath, {
        index : false,
        maxAge: oneYear
      }));
    }

    app.use(function(req, res, next) {
      res.status(404).send('Sorry cant find that!');
    });

    var server = app.listen(this.configuration.httpPort || 8480, (error) => {
      if (error) {
        console.error("Server can not listen", error);
        return;
      }
      debug("listen", "Server is listening ", server.address());

      callback(error);
    });
  };

  _set(name, request, response, func) {
    var keys = Object.keys(request.body);
    debug("_set", name, "set keys=", keys);

    var options = formatOptions(request);

    var results = {};
    keys.forEach(key => results[key]=null);

    async.eachLimit(keys, 8, (key, callback) => {
      var reg=/(.*)\/([^/]+)$/.exec(key);
      if (reg) {
        key=reg[1]+"@"+reg[2]; // Transform @ to /
      }

      func.call(this.store, key, options, (error, value) => {
        debug("_set", name, " set key=", key, "value=", value, "error=", error);
        if (error) {
          return callback(error);
        }

        var reg2=/(.*)\@([^@]+)$/.exec(key);
        if (reg2) {
          key=reg2[1]+"/"+reg[2]; // Transform / to @
        }

        results[key] = value;

        callback();
      });

    }, (error) => {
      if (error) {
        // send 500
        if (error.code === 'NOT_FOUND') {
          response.status(404).body("Key '" + error.key + "' not found");
          return;
        }

        response.status(500).body(String(error));
        return;
      }

      response.json(results);
    });
  };

  _get(name, request, response, func) {
    var key = request.params[0];
    debug("_get", "type=", name, "key=", key);

    var reg=/(.*)\/([^/]+)$/.exec(key);
    if (reg) {
      key=reg[1]+"@"+reg[2]; // Transform @ to /
    }

    var options = formatOptions(request);

    func.call(this.store, key, options, (error, values) => {
      debug("_get", "type=", name, "key=", key, "values=", values);
      if (error) {
        // send 500
        if (error.code === 'NOT_FOUND') {
          response.status(404).send('Key not found');
          return;
        }

        response.status(500).send(String(error));
        return;
      }

      response.json(values);
    });
  }

  getLast(request, response) {
    this._get("getLast", request, response, this.store.getLast);
  }

  getHistory(request, response) {
    this._get("getHistory", request, response, this.store.getHistory);
  }

  getMinMaxAvgSum(request, response) {
    this._get("getMinMaxAvgSum", request, response, this.store.getMinMaxAvgSum);
  }

  getLastSet(request, response) {
    this._set("getLastSet", request, response, this.store.getLast);
  }

  getHistorySet(request, response) {
    this._set("getHistorySet", request, response, this.store.getHistory);
  }

  getMinMaxAvgSumSet(request, response) {
    this._set("getMinMaxAvgSumSet", request, response, this.store.getMinMaxAvgSum);
  }
}

function formatOptions(request) {
  var ret = {};

  var query = request.query;
  if (query.limit) {
    ret.limit = parseInt(query.limit, 10);
  }

  if (query.minDate) {
    ret.minDate = new Date(query.minDate);
  }

  if (query.maxDate) {
    ret.maxDate = new Date(query.maxDate);
  }

  if (query.averageMs) {
    ret.averageMs = parseInt(query.averageMs, 10);
  }

  if (query.step) {
    ret.stepMs = parseInt(query.step, 10) * 1000;
  }

  return ret;
}

module.exports = Server;
<commit_msg>Implements last modified<commit_after>/*jslint node: true, vars: true, nomen: true */
'use strict';

var express = require('express');
var Http = require('http');
var debug = require('debug')('xpl-db:server');
var async = require('async');
var noCache = require('connect-nocache')();
var bodyParser = require('body-parser');
var serve_static = require('serve-static');
var compress = require('compression');

class Server {
  constructor(configuration, store) {
    this.configuration = configuration || {};
    this.store = store;

    this.app = this.configuration.express || express();

    if (this.configuration.compression !== false) {
      try {
        var compression = require('compression');
        this.app.use(compression())
      } catch (x) {
        console.error("No compression module !");
      }
    }
  }

  listen(callback) {
    var app = this.app;

    app.enable('etag');
    app.use(compress());
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({
      extended: true
    }));
//    app.use(noCache);

    app.get(/^\/last\/(.*)$/, this.getLast.bind(this));
    app.get(/^\/history\/(.*)$/, this.getHistory.bind(this));
    app.get(/^\/minMaxAvgSum\/(.*)$/, this.getMinMaxAvgSum.bind(this));

    app.post('/last', this.getLastSet.bind(this));
    app.post('/history', this.getHistorySet.bind(this));
    app.post('/minMaxAvgSum', this.getMinMaxAvgSumSet.bind(this));

    if (this.configuration.configPath) {

      var oneYear = 1000*60*60*24*365;

      app.use(express.static(__dirname + '/public', {  }));

      app.use("/config", serve_static(this.configuration.configPath, {
        index : false,
        maxAge: oneYear
      }));
    }

    app.use(function(req, res, next) {
      res.status(404).send('Sorry cant find that!');
    });

    var server = app.listen(this.configuration.httpPort || 8480, (error) => {
      if (error) {
        console.error("Server can not listen", error);
        return;
      }
      debug("listen", "Server is listening ", server.address());

      callback(error);
    });
  };

  _set(name, request, response, func) {
    var keys = Object.keys(request.body);
    debug("_set", name, "set keys=", keys);

    var options = formatOptions(request);

    var results = {};
    var lastDate=null;

    async.eachLimit(keys, 8, (key, callback) => {
      var reg=/(.*)\/([^/]+)$/.exec(key);
      if (reg) {
        key=reg[1]+"@"+reg[2]; // Transform @ to /
      }

      func.call(this.store, key, options, (error, value) => {
        debug("_set", name, " set key=", key, "value=", value, "error=", error);
        if (error) {
          return callback(error);
        }

        var reg2=/(.*)\@([^@]+)$/.exec(key);
        if (reg2) {
          key=reg2[1]+"/"+reg[2]; // Transform / to @
        }

        results[key] = value;

        if (value.date) {
          if (!lastDate || lastDate<value.date) {
            lastDate=value.date;
          }
        }

        callback();
      });

    }, (error) => {
      if (error) {
        // send 500
        if (error.code === 'NOT_FOUND') {
          response.status(404).body("Key '" + error.key + "' not found");
          return;
        }

        response.status(500).body(String(error));
        return;
      }

      if (lastDate) {
        var since=request.getHeader('If-Modified-Since');
        console.log("Since=",since);

        if (since && since==lastDate) {
          response.status(304).body("Not modified");
          return;
        }

        response.setHeader("Last-Modified", lastDate);
      }

      response.json(results);
    });
  };

  _get(name, request, response, func) {
    var key = request.params[0];
    debug("_get", "type=", name, "key=", key);

    var reg=/(.*)\/([^/]+)$/.exec(key);
    if (reg) {
      key=reg[1]+"@"+reg[2]; // Transform @ to /
    }

    var options = formatOptions(request);

    func.call(this.store, key, options, (error, values) => {
      debug("_get", "type=", name, "key=", key, "values=", values);
      if (error) {
        // send 500
        if (error.code === 'NOT_FOUND') {
          response.status(404).send('Key not found');
          return;
        }

        response.status(500).send(String(error));
        return;
      }

      response.json(values);
    });
  }

  getLast(request, response) {
    this._get("getLast", request, response, this.store.getLast);
  }

  getHistory(request, response) {
    this._get("getHistory", request, response, this.store.getHistory);
  }

  getMinMaxAvgSum(request, response) {
    this._get("getMinMaxAvgSum", request, response, this.store.getMinMaxAvgSum);
  }

  getLastSet(request, response) {
    this._set("getLastSet", request, response, this.store.getLast);
  }

  getHistorySet(request, response) {
    this._set("getHistorySet", request, response, this.store.getHistory);
  }

  getMinMaxAvgSumSet(request, response) {
    this._set("getMinMaxAvgSumSet", request, response, this.store.getMinMaxAvgSum);
  }
}

function formatOptions(request) {
  var ret = {};

  var query = request.query;
  if (query.limit) {
    ret.limit = parseInt(query.limit, 10);
  }

  if (query.minDate) {
    ret.minDate = new Date(query.minDate);
  }

  if (query.maxDate) {
    ret.maxDate = new Date(query.maxDate);
  }

  if (query.averageMs) {
    ret.averageMs = parseInt(query.averageMs, 10);
  }

  if (query.step) {
    ret.stepMs = parseInt(query.step, 10) * 1000;
  }

  return ret;
}

module.exports = Server;
<|endoftext|>


<commit_before>/*
Process Flow:
1. Pass the Google Search Query to Wolfram|Alpha and get the result as XML
2. Parse that XML to get a HTML-Object of the Result
3. Inject this object beautifully into the Google Site
*/

// Start when DOM is ready
$( document ).ready(function() {
    requestWolframResult(getSearchQuery());
});

/*
Get search query string (eg. sunrise+munich)
returns searcg query
*/
function getSearchQuery() {
	var searchQuery = document.getElementById('gbqfq').value.replace(/ /g, "+");
	console.log("searchQuery: "+searchQuery);
	return searchQuery;
}

/*
Get and Parse the Wolfram|Alpha result XML
*/
function requestWolframResult(searchQuery) {
	var xmlhttp = new XMLHttpRequest();

	xmlhttp.onreadystatechange = function(){
	  if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
			xmlDoc=xmlhttp.responseXML;
			/* Plaintext Result */
			var pods = xmlDoc.getElementsByTagName("pod");
			var plaintexts = xmlDoc.getElementsByTagName("plaintext");
			txt = "";
			// Skip first pod
			for (i=1; i<4; i++){
				// Get pod title
				txt = txt + pods[i].getAttribute("title") + ": ";
				console.log("pod #"+i+" title: "+pods[i].getAttribute("title"));
				// Get value of "plaintext"-node
				txt = txt + plaintexts[i].textContent + ".  ";
				console.log("plaintext #"+i+" : "+plaintexts[i].textContent);
			}

			// inject and fill result div
			displayResults(plaintexts[1].textContent, pods[1].getAttribute("title"), searchQuery);
		}
	  }
	xmlhttp.open("GET","http://api.wolframalpha.com/v2/query?input="+searchQuery+"&appid=8X6XE5-Q5887TY7TE",true);
	xmlhttp.send();
}

function displayResults(result, description, searchQuery) {
	// Result
	var resultDiv = document.createElement("div");
	resultDiv.id = "resultDiv";
	// Description
	var descriptionDiv = document.createElement("div");
	descriptionDiv.id = "description";
	// More link
	var moreLink = document.createElement("a");
	moreLink.id = "moreLink";

	// Set content of result div and description
	resultDiv.innerHTML = result;
	descriptionDiv.innerHTML = description;
	// More link
	moreLink.appendChild(document.createTextNode("More"));
	moreLink.title = "More2";
	moreLink.href = "http://www.wolframalpha.com/input/?i="+searchQuery;
	moreLink.target = "_blank";

	// Insert result div into DOM
	document.getElementById("rcnt").parentNode.insertBefore(resultDiv, document.getElementById("rcnt"));
	// Add Description and more link into resultDiv
	document.getElementById("resultDiv").appendChild(descriptionDiv);
	document.getElementById("resultDiv").appendChild(moreLink);
}<commit_msg>Only integrade 1st pod<commit_after>/*
Process Flow:
1. Pass the Google Search Query to Wolfram|Alpha and get the result as XML
2. Parse that XML to get a HTML-Object of the Result
3. Inject this object beautifully into the Google Site
*/

// Start when DOM is ready
$( document ).ready(function() {
    requestWolframResult(getSearchQuery());
});

/*
Get search query string (eg. sunrise+munich)
returns searcg query
*/
function getSearchQuery() {
	var searchQuery = document.getElementById('gbqfq').value.replace(/ /g, "+");
	console.log("searchQuery: "+searchQuery);
	return searchQuery;
}

/*
Get and Parse the Wolfram|Alpha result XML
*/
function requestWolframResult(searchQuery) {
	var xmlhttp = new XMLHttpRequest();

	xmlhttp.onreadystatechange = function(){
	  if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
			xmlDoc=xmlhttp.responseXML;
			/* Plaintext Result */
			var pods = xmlDoc.getElementsByTagName("pod");
			var plaintexts = xmlDoc.getElementsByTagName("plaintext");
			txt = "";
			// Skip first pod
			/* for (i=1; i<4; i++){
				// Get pod title
				txt = txt + pods[i].getAttribute("title") + ": ";
				console.log("pod #"+i+" title: "+pods[i].getAttribute("title"));
				// Get value of "plaintext"-node
				txt = txt + plaintexts[i].textContent + ".  ";
				console.log("plaintext #"+i+" : "+plaintexts[i].textContent);
			} */

			console.log(searchQuery);
			console.log(plaintexts[1].textContent);
			console.log(pods[1].getAttribute("title"));

			// inject and fill result div
			displayResults(plaintexts[1].textContent, pods[1].getAttribute("title"), searchQuery);
		}
	  }
	xmlhttp.open("GET","http://api.wolframalpha.com/v2/query?input="+searchQuery+"&appid=8X6XE5-Q5887TY7TE",true);
	xmlhttp.send();
}

function displayResults(result, description, searchQuery) {
	// Result
	var resultDiv = document.createElement("div");
	resultDiv.id = "resultDiv";
	// Description
	var descriptionDiv = document.createElement("div");
	descriptionDiv.id = "description";
	// More link
	var moreLink = document.createElement("a");
	moreLink.id = "moreLink";

	// Set content of result div and description
	resultDiv.innerHTML = result;
	descriptionDiv.innerHTML = description;
	// More link
	moreLink.appendChild(document.createTextNode("More"));
	moreLink.title = "More2";
	moreLink.href = "http://www.wolframalpha.com/input/?i="+searchQuery;
	moreLink.target = "_blank";

	// Insert result div into DOM
	document.getElementById("rcnt").parentNode.insertBefore(resultDiv, document.getElementById("rcnt"));
	// Add Description and more link into resultDiv
	document.getElementById("resultDiv").appendChild(descriptionDiv);
	document.getElementById("resultDiv").appendChild(moreLink);
}<|endoftext|>


<commit_before>var InfoBoxView = new function() {
  var infoBoxes;

  this.init = function() {
    infoBoxes = {
      about: new InfoBox("Assets taken from Awesomenauts, data gathered by <button onclick='MessageBoxView.displayContributors()'>the community.</button>
" +
        "Nautsbuilder V2 made with love by Blatoy.
" +
        "If you want to support this tool consider making a small donation to help me pay the server!
" +
        "<button onclick='MessageBoxView.displayErrorReport()'>Report errors</button> - Github" +
        " - Forum - " +
        "Discord" +
        '

', "about"),
      skills: new InfoBox("", "skill-description"),
      lore: new InfoBox("", "naut-description"),
      buildInfo1: new InfoBox("displayBuildSummary() error. Please retry.", "build-info-1"),
      buildInfo2: new InfoBox("...", "build-info-2"),
      buildInfo3: new InfoBox("...", "build-info-3"),
      buildInfo4: new InfoBox("...", "build-info-4"),
      buildSummary: new InfoBox("...", "build-summary")
    };
  };

  // TODO: Add desc
  this.displayLore = function(naut){
    infoBoxes.lore.setContent("
" + naut.getRole() + " - " + naut.getAttackType() + " - " + naut.getMobility() + "
" +
                              "" + htmlToText(naut.getDescription()) + "");
    infoBoxes.lore.setVisibility(true, true);
    infoBoxes.about.setVisibility(false, true);
  };

  // TODO: Add desc
  this.displaySkills = function(naut){
    var content = "";
    var element = $("
");
    element.append("
Skills
");

    for(var i = 0; i < naut.getSkills().length; ++i) {
      var skill = naut.getSkills(i);
      var skillImage = $("").attr("src", skill.getIcon());
      element.append(skillImage);
      element.append("" + skill.getDescription() + "
")
      Tooltip.createDefault(skillImage, skill.toString());
    }

    infoBoxes.skills.setContent(element);
    infoBoxes.skills.setVisibility(true, true);
  };

  // TODO: Add desc
  this.displayBuildSummary = function() {
    for(var i = 1; i < 5; ++i) {
      infoBoxes["buildInfo" + i].setVisibility(true, true);
    }
    infoBoxes.buildSummary.setVisibility(true, true);
  };

  // TODO: Add desc
  this.hideBuildSummary = function() {
    for(var i = 1; i < 5; ++i) {
      infoBoxes["buildInfo" + i].setVisibility(false, true);
    }
    infoBoxes.buildSummary.setVisibility(false, true);
  };

  // TODO: Add desc
  this.setBuildSummaryContent = function() {
    for(var i = 0; i < 4; ++i) {
      infoBoxes["buildInfo" + (i + 1)].setContent("");
      var effects = Build.current.getRowEffects(i);
      var content = "";

      for(var k in effects) {
        content += Effect.toString({unit: effects[k].unit, value: effects[k].value, key: k}) + effects[k].scaleType + "
";
      }

      content += "" + Build.current.getRowPrice(i) + ""
      infoBoxes["buildInfo" + (i + 1)].setContent(content);
    }

    infoBoxes.buildSummary.setContent(
      "Total cost: " + Build.current.getPrice() + " " +
      "" +
      "
Forum link:<input type='text' value='[build]" + Build.current.toString() + "[/build]'>" +
      "
Team level: " + Setting.get("teamLevel") + "<input oninput='InfoBoxView.setTeamLevelDisplay(this.value)' onmouseup='Setting.setTeamLevel(this.value)' id='team-level' type='range' min='1' max='20' value='" + Setting.get("teamLevel") + "' step='1'>" +
      "
<button onclick='MessageBoxView.displayExportImage()'>Export as image</button> - <button onclick='BuildController.setRandomBuild()'>Random build</button>"
    );
  };

  // TODO: Add desc
  this.setTeamLevelDisplay = function(level) {
    $("#team-level-label").text(level);
  };

  // TODO: Add desc
  this.hideSkills = function() {
    infoBoxes.skills.setVisibility(false, true);
  };

  // TODO: Add desc
  this.hideLore = function() {
    infoBoxes.lore.setVisibility(false, true);
  };

  // TODO: Add desc
  this.displayAbout = function() {
    infoBoxes.about.setVisibility(true, true);
  };

  // TODO: Add desc
  this.displayRandomNaut = function(){
    this.hideLore();
    this.hideSkills();
    this.displayAbout();
  };

  this.onLoaded = function() {
    infoBoxes.about.getElement().fadeIn(200);
    infoBoxes.about.setVisibility(true, true);
  };
  this.setAboutVisibility = function(visible){
    infoBoxes.about.setVisibility(visible, true);
  };
};
<commit_msg>Removes debug info<commit_after>var InfoBoxView = new function() {
  var infoBoxes;

  this.init = function() {
    infoBoxes = {
      about: new InfoBox("Assets taken from Awesomenauts, data gathered by <button onclick='MessageBoxView.displayContributors()'>the community.</button>
" +
        "Nautsbuilder V2 made with love by Blatoy.
" +
        "If you want to support this tool consider making a small donation to help me pay the server!
" +
        "<button onclick='MessageBoxView.displayErrorReport()'>Report errors</button> - Github" +
        " - Forum - " +
        "Discord" +
        '

', "about"),
      skills: new InfoBox("", "skill-description"),
      lore: new InfoBox("", "naut-description"),
      buildInfo1: new InfoBox("displayBuildSummary() error. Please retry.", "build-info-1"),
      buildInfo2: new InfoBox("...", "build-info-2"),
      buildInfo3: new InfoBox("...", "build-info-3"),
      buildInfo4: new InfoBox("...", "build-info-4"),
      buildSummary: new InfoBox("...", "build-summary")
    };
  };

  // TODO: Add desc
  this.displayLore = function(naut){
    infoBoxes.lore.setContent("
" + naut.getRole() + " - " + naut.getAttackType() + " - " + naut.getMobility() + "
" +
                              "" + htmlToText(naut.getDescription()) + "");
    infoBoxes.lore.setVisibility(true, true);
    infoBoxes.about.setVisibility(false, true);
  };

  // TODO: Add desc
  this.displaySkills = function(naut){
    var content = "";
    var element = $("
");
    element.append("
Skills
");

    for(var i = 0; i < naut.getSkills().length; ++i) {
      var skill = naut.getSkills(i);
      var skillImage = $("").attr("src", skill.getIcon());
      element.append(skillImage);
      element.append("" + skill.getDescription() + "
")
      Tooltip.createDefault(skillImage, skill.toString());
    }

    infoBoxes.skills.setContent(element);
    infoBoxes.skills.setVisibility(true, true);
  };

  // TODO: Add desc
  this.displayBuildSummary = function() {
    for(var i = 1; i < 5; ++i) {
      infoBoxes["buildInfo" + i].setVisibility(true, true);
    }
    infoBoxes.buildSummary.setVisibility(true, true);
  };

  // TODO: Add desc
  this.hideBuildSummary = function() {
    for(var i = 1; i < 5; ++i) {
      infoBoxes["buildInfo" + i].setVisibility(false, true);
    }
    infoBoxes.buildSummary.setVisibility(false, true);
  };

  // TODO: Add desc
  this.setBuildSummaryContent = function() {
    for(var i = 0; i < 4; ++i) {
      infoBoxes["buildInfo" + (i + 1)].setContent("");
      var effects = Build.current.getRowEffects(i);
      var content = "";

      for(var k in effects) {
        content += Effect.toString({unit: effects[k].unit, value: effects[k].value, key: k}) + "
";
      }

      content += "" + Build.current.getRowPrice(i) + ""
      infoBoxes["buildInfo" + (i + 1)].setContent(content);
    }

    infoBoxes.buildSummary.setContent(
      "Total cost: " + Build.current.getPrice() + " " +
      "" +
      "
Forum link:<input type='text' value='[build]" + Build.current.toString() + "[/build]'>" +
      "
Team level: " + Setting.get("teamLevel") + "<input oninput='InfoBoxView.setTeamLevelDisplay(this.value)' onmouseup='Setting.setTeamLevel(this.value)' id='team-level' type='range' min='1' max='20' value='" + Setting.get("teamLevel") + "' step='1'>" +
      "
<button onclick='MessageBoxView.displayExportImage()'>Export as image</button> - <button onclick='BuildController.setRandomBuild()'>Random build</button>"
    );
  };

  // TODO: Add desc
  this.setTeamLevelDisplay = function(level) {
    $("#team-level-label").text(level);
  };

  // TODO: Add desc
  this.hideSkills = function() {
    infoBoxes.skills.setVisibility(false, true);
  };

  // TODO: Add desc
  this.hideLore = function() {
    infoBoxes.lore.setVisibility(false, true);
  };

  // TODO: Add desc
  this.displayAbout = function() {
    infoBoxes.about.setVisibility(true, true);
  };

  // TODO: Add desc
  this.displayRandomNaut = function(){
    this.hideLore();
    this.hideSkills();
    this.displayAbout();
  };

  this.onLoaded = function() {
    infoBoxes.about.getElement().fadeIn(200);
    infoBoxes.about.setVisibility(true, true);
  };
  this.setAboutVisibility = function(visible){
    infoBoxes.about.setVisibility(visible, true);
  };
};
<|endoftext|>


<commit_before>var s = document.createElement('script');
s.src = "https://rawgit.com/joshisa/huemix-blopscotch/master/js/hopscotch.highlight.js";
s.onload = function() {
    this.parentNode.removeChild(this);
};
(document.head || document.documentElement).appendChild(s);

chrome.extension.sendMessage({}, function(response) {
    var readyStateCheckInterval = setInterval(function() {
      if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);
        var prefix = "[Huemix Blopscotch]] ";
        console.log(prefix + "current page URL is: " + location.href);
        // https://api.github.com/repos/joshisa/huemix-blopscotch/git/trees/master?recursive=1
        whitelist = ["tourlets/demo.js",
                    "tourlets/jstart.js",
                    "tourlets/jupyter.js",
                    "tourlets/spark.js"];
        console.log(prefix + "Number of Tourlets defined : " + whitelist.length);
        var i = 0;
        while (whitelist[i]) {
            // https://rawgit.com/joshisa/huemix-blopscotch/master/ + tourlets.path
            console.log(prefix + "Loading " + whitelist[i].path);
            proxyXHR.get('https://rawgit.com/joshisa/huemix-blopscotch/master/' + whitelist[i].path).onSuccess(function (data) {
                eval(data);
            }).onFailure(function (status) {
               console.log("HTTP Error " + status + " while retrieving data for the Huemix Blopscotch Tour Chrome Plugin");
            });
            i++;
        }
        console.log(prefix + "Hopscotch Dependencies successfully injected");
      }
    }, 10);
});
<commit_msg>Update inject.js<commit_after>var s = document.createElement('script');
s.src = "https://rawgit.com/joshisa/huemix-blopscotch/master/js/hopscotch.highlight.js";
s.onload = function() {
    this.parentNode.removeChild(this);
};
(document.head || document.documentElement).appendChild(s);

chrome.extension.sendMessage({}, function(response) {
    var readyStateCheckInterval = setInterval(function() {
      if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);
        var prefix = "[Huemix Blopscotch]] ";
        console.log(prefix + "current page URL is: " + location.href);
        // https://api.github.com/repos/joshisa/huemix-blopscotch/git/trees/master?recursive=1
        whitelist = ["hoplet/demo.js",
                    "hoplet/jstart.js",
                    "hoplet/jupyter.js",
                    "hoplet/spark.js"];
        console.log(prefix + "Number of Tourlets defined : " + whitelist.length);
        var i = 0;
        while (whitelist[i]) {
            // https://rawgit.com/joshisa/huemix-blopscotch/master/ + whitelist.path
            console.log(prefix + "Loading " + whitelist[i].path);
            proxyXHR.get('https://rawgit.com/joshisa/huemix-blopscotch/master/' + whitelist[i].path).onSuccess(function (data) {
                eval(data);
            }).onFailure(function (status) {
               console.log("HTTP Error " + status + " while retrieving data for the Huemix Blopscotch Tour Chrome Plugin");
            });
            i++;
        }
        console.log(prefix + "Hopscotch Dependencies successfully injected");
      }
    }, 10);
});
<|endoftext|>


<commit_before>'use strict';

function getUsers(){
  $.getJSON('/getAllUsers') .then(function(usersjson){
    $('body').append(createUsersList(usersjson,'userList'));
  })
}
getUsers();

function createUsersList(users, DOMID ){
  let userContainer = $(document.createElement('div'))
  let frontContainer = userContainer.clone();
  frontContainer.attr('id',DOMID)
  users.forEach(function(userPix){
    let photoContainer = userContainer.clone();
    photoContainer.append(`<img class="stylePhoto" src=${userPix.urlphoto}>`)
    photoContainer.append(`<img src=${userPix.urlphoto}>`)
    photoContainer.attr(`data-course`, userPix.course)
    photoContainer.attr(`data-userid`, userPix.userid)
    photoContainer.data('data', userPix)
    frontContainer.append(photoContainer)
  })
  return frontContainer
}
<commit_msg>add fix to users<commit_after>'use strict';

function getUsers(){
  $.getJSON('/getAllUsers') .then(function(usersjson){
    $('body').append(createUsersList(usersjson,'userList'));
  })
}
getUsers();

function createUsersList(users, DOMID ){
  let userContainer = $(document.createElement('div'))
  let frontContainer = userContainer.clone();
  frontContainer.attr('id',DOMID)
  users.forEach(function(userPix){
    let photoContainer = userContainer.clone();
    photoContainer.append(`<img class="stylePhoto" src=${userPix.urlphoto}>`)
    photoContainer.attr(`data-course`, userPix.course)
    photoContainer.attr(`data-userid`, userPix.userid)
    photoContainer.data('data', userPix)
    frontContainer.append(photoContainer)
  })
  return frontContainer
}
<|endoftext|>


<commit_before>Readium.Views.OptionsView = Backbone.View.extend({

	el: '#viewer-settings-modal',
	DEFAULT_VOICES: [ 'Alex', 'native' ],

	initialize: function() {
		console.log("Initializing options menu.");
		this.model.on("change:current_margin", this.renderMarginRadio, this);
		this.model.on("change:current_theme", this.renderTheme, this);

		var that = this;

		// hide inapplicable settings when pagination not available
		if (!this.model.get("controller").get("columns_supported")) {
			$('#setting-header-display-legend').toggle(false);
			$('#pagination_mode').toggle(false);
		}

		// hide scrolling setting for iOS devices
		if (this.model.get("controller").get("isIosDevice")) {
			$('#scrolling-option').toggle(false);
		}

		// set TTS visibility based on browser support
		$('.ttsOnly').toggle(BookshareUtils.hasSpeechAPI() || (!!window.chrome && !!window.chrome.tts));

		Acc.rg = {
			theme: new Acc.RadioGroup('theme-radio-group', ' .' + this.model.get("current_theme"),
				function(el){
					var id = el.id;
					if(id === "default-theme-option" ) that.model.set("current_theme", "default-theme");
					if(id === "night-theme-option" ) that.model.set("current_theme", "night-theme");
					if(id === "parchment-theme-option" ) that.model.set("current_theme", "parchment-theme");
					if(id === "beeline-theme-option" ) that.model.set("current_theme", "beeline-theme");
				}
			),
			margin: new Acc.RadioGroup('margin-radio-wrapper', ' #margin-option-' + this.model.get("current_margin"),
				function(el){
					var id = el.id,
					num = id[id.length - 1];
					if(num === "1" ) that.model.set("current_margin", 1);
					if(num === "2" ) that.model.set("current_margin", 2);
					if(num === "3" ) that.model.set("current_margin", 3);
					if(num === "4" ) that.model.set("current_margin", 4);
					if(num === "5" ) that.model.set("current_margin", 5);
				}
			)
		};
		$('#options-btn').attr('aria-pressed', 'false');
		$('#viewer-settings-modal').on('show', function(){
			that.render();
		});
		$('#viewer-settings-modal').on('shown', function(){
			that.model.get("controller").set("options-view-shown", true);
			$('#options-heading').focus();
			setTimeout(function(){
				$('#options-btn').attr('aria-pressed', 'true');
			}, 1);
		}).on('hidden', function(){
			that.model.get("controller").set("options-view-shown", false);
			setTimeout(function(){
				$('#options-btn').attr('aria-pressed', 'false').focus();
			}, 1);
		});
	},

	renderBeelineMenu: function() {
		var vis = false;
		var beeline = this.model.get("controller").get("beeline");
		console.log("renderBeelineMenu: " + beeline);
		if( beeline && beeline == 'on') {
			vis = true;
		}
		// Only display if beta option was selected
		this.$("#beeline-beta-menu").toggle(vis);
		this.$("#beeline-theme-option").toggle(vis);
		this.renderBeelineOption();

	},

	renderBeelineOption: function() {
		var theme = this.model.get("beeline_theme");
		$("ul#beeline-beta-menu li").removeClass("active");
		$("li#" + theme + "-button").addClass("active");
	},

	renderBeelineNotification: function() {
		alert("Something");

		//var vis = false;
		//var beeline = this.model.get("controller").get("beeline");
		//console.log("renderBeelineMenu: " + beeline);
		//if( beeline && beeline == 'on') {
		//	vis = true;
		//}
		// Only display if beta option was selected
		//this.$("#beeline-beta-menu").toggle(vis);
		//this.$("#beeline-theme-option").toggle(vis);
		//this.renderBeelineOption();
	},

	render: function() {
		this.renderPagination();
		this.renderTheme();
		this.renderBeelineMenu();
		this.renderBeelineNotification();
		this.renderMarginRadio();
		this.renderFontSize();
        this.renderFontFace();
		this.renderDisplayPageNumbers();
		if (BookshareUtils.hasSpeechAPI()) {
			this.renderSpeechRate();
			this.renderVoiceOptions();
			if (!!window.chrome) {
				speechSynthesis.onvoiceschanged = _.bind(this.renderVoiceOptions, this);
			}
		}
		return this;
	},

	renderTheme: function() {
		var themePref = this.model.get("current_theme");
		this.$("#default-theme-option").toggleClass("selected", (themePref == 'default-theme'));
		this.$("#night-theme-option").toggleClass("selected", (themePref == 'night-theme'));
		this.$("#parchment-theme-option").toggleClass("selected", (themePref == 'parchment-theme'));
		this.$("#beeline-theme-option").toggleClass("selected", (themePref == 'beeline-theme'));
		return this;
	},

	renderMarginRadio: function() {
		var id = "#margin-option-" + this.model.get("current_margin");
		this.$('.margin-radio').toggleClass("selected", false);
		this.$(id).toggleClass("selected", true);
		return this;
	},

	renderFontSize: function() {
		var val = this.model.get("font_size");
		this.$("#font-size-input").val(val);
	},

	renderFontFace: function() {
		var val = this.model.get("font_face");
		this.$("#font-face-input").val(val);
	},

	renderPagination: function() {
		var val = this.model.get("pagination_mode");
		this.$("#pagination-mode-input").val(val);
	},

	filterVoiceOptions: function(v) {
		return v.localService && (v.name == "US English Female TTS (by Google)" || !/google/i.test(v.voiceURI));
	},

	renderVoiceOptions: function() {
		var voiceDefault;
		var select = $("#voice-input");
		select.children().remove();
		var voices = speechSynthesis.getVoices().filter(this.filterVoiceOptions);
		for (i = 0; i < voices.length; i++) {
			var voice = voices[i];
			var option = $("<option>").text(voice.name).val(voice.voiceURI);
			select.append(option);
			// Default to first available voice, "Alex", or "native", whichever's last
			if (i == 0 || this.DEFAULT_VOICES.indexOf(voice.name) >= 0) {
				voiceDefault = voice.voiceURI;
			}
		}
		// update the default one
		var defaultOption = select.find("option[value='" + voiceDefault + "']");
		defaultOption.text(defaultOption.text() + ' (default)');
		var voicePref = this.model.get("voice_uri");
        select.val(voicePref ? voicePref : voiceDefault);
        var controller = this.model.get("controller");
        controller.set("voice_uri", select.val());
        controller.trigger("change:voice_uri");
	},

    renderSpeechRate: function() {
        var val = this.model.get("speech_rate");
        this.$("#speech-rate-input").val(val);
    },

	renderDisplayPageNumbers: function() {
		this.$("#display-page-numbers").prop('checked', this.model.get("display_page_numbers"));
	},

	events: {
    	"click .theme-option": 			"selectTheme",
    	"click .margin-radio": 			"selectMargin",
    	"click #cancel-settings-but": 	"cancelSettings",
		"click #save-settings-but": 	"applySettings",
		"click #bright-button": 	function() {
			this.selectBeelineTheme("bright");
		},
		"click #dark-button": 	function() {
			this.selectBeelineTheme("dark");
		},
		"click #blues-button": 	function() {
			this.selectBeelineTheme("blues");
		},
		"click #gray-button": 	function() {
			this.selectBeelineTheme("gray");
		},
		"click #night_gray-button": 	function() {
			this.selectBeelineTheme("night_gray");
		}
  	},

  	selectBeelineTheme: function(theme) {
  		if(theme == "gray") {
  			console.log("Selecting gray theme.");
  		}
		this.model.set("current_theme", "beeline-theme");
  		this.model.set("beeline_theme", theme);
  		this.renderTheme();
		this.renderBeelineOption();
  	},

  	selectTheme: function(e) {
  		var id = e.srcElement ? e.srcElement.id : '';
		if (id && e.srcElement && Acc.rg && Acc.rg.theme && e.srcElement != Acc.rg.theme.selected) Acc.rg.theme.set(id);
  		if(id === "default-theme-option" ) this.model.set("current_theme", "default-theme");
		if(id === "night-theme-option" ) this.model.set("current_theme", "night-theme");
		if(id === "parchment-theme-option" ) this.model.set("current_theme", "parchment-theme");
		if(id === "beeline-theme-option" ) this.model.set("current_theme", "beeline-theme");
		e.stopPropagation();
  	},

  	selectMargin: function(e) {
  		var id = e.srcElement.id;
		if (e.srcElement && Acc.rg && Acc.rg.margin && e.srcElement != Acc.rg.margin.selected) Acc.rg.margin.set(id);
  		var num = id[id.length - 1];
  		if(num === "1" ) this.model.set("current_margin", 1);
		if(num === "2" ) this.model.set("current_margin", 2);
		if(num === "3" ) this.model.set("current_margin", 3);
		if(num === "4" ) this.model.set("current_margin", 4);
		if(num === "5" ) this.model.set("current_margin", 5);
		e.stopPropagation();
  	},

  	cancelSettings: function(e) {
  		this.$el.modal('hide');
  		this.model.resetOptions();
		$('#options-btn').focus();
  	},

  	applySettings: function(e) {
  		// extract options from non-fancy UI elements
		this.model.set("display_page_numbers", this.$("#display-page-numbers").prop('checked'));
		this.model.set("pagination_mode", $("#pagination-mode-input").val());
		this.model.set("font_size", parseInt($("#font-size-input").val(), 10));
		this.model.set("font_face", $("#font-face-input").val());
		this.model.set("speech_rate", parseFloat($("#speech-rate-input").val()));
		this.model.set("voice_uri", $("#voice-input").val());

  		this.model.applyOptions();
  		this.$el.modal('hide');
		$('#options-btn').focus();
  	}

});
<commit_msg>Revert "READ-301 renderBeelineNotification"<commit_after>Readium.Views.OptionsView = Backbone.View.extend({

	el: '#viewer-settings-modal',
	DEFAULT_VOICES: [ 'Alex', 'native' ],

	initialize: function() {
		console.log("Initializing options menu.");
		this.model.on("change:current_margin", this.renderMarginRadio, this);
		this.model.on("change:current_theme", this.renderTheme, this);

		var that = this;

		// hide inapplicable settings when pagination not available
		if (!this.model.get("controller").get("columns_supported")) {
			$('#setting-header-display-legend').toggle(false);
			$('#pagination_mode').toggle(false);
		}

		// hide scrolling setting for iOS devices
		if (this.model.get("controller").get("isIosDevice")) {
			$('#scrolling-option').toggle(false);
		}

		// set TTS visibility based on browser support
		$('.ttsOnly').toggle(BookshareUtils.hasSpeechAPI() || (!!window.chrome && !!window.chrome.tts));

		Acc.rg = {
			theme: new Acc.RadioGroup('theme-radio-group', ' .' + this.model.get("current_theme"),
				function(el){
					var id = el.id;
					if(id === "default-theme-option" ) that.model.set("current_theme", "default-theme");
					if(id === "night-theme-option" ) that.model.set("current_theme", "night-theme");
					if(id === "parchment-theme-option" ) that.model.set("current_theme", "parchment-theme");
					if(id === "beeline-theme-option" ) that.model.set("current_theme", "beeline-theme");
				}
			),
			margin: new Acc.RadioGroup('margin-radio-wrapper', ' #margin-option-' + this.model.get("current_margin"),
				function(el){
					var id = el.id,
					num = id[id.length - 1];
					if(num === "1" ) that.model.set("current_margin", 1);
					if(num === "2" ) that.model.set("current_margin", 2);
					if(num === "3" ) that.model.set("current_margin", 3);
					if(num === "4" ) that.model.set("current_margin", 4);
					if(num === "5" ) that.model.set("current_margin", 5);
				}
			)
		};
		$('#options-btn').attr('aria-pressed', 'false');
		$('#viewer-settings-modal').on('show', function(){
			that.render();
		});
		$('#viewer-settings-modal').on('shown', function(){
			that.model.get("controller").set("options-view-shown", true);
			$('#options-heading').focus();
			setTimeout(function(){
				$('#options-btn').attr('aria-pressed', 'true');
			}, 1);
		}).on('hidden', function(){
			that.model.get("controller").set("options-view-shown", false);
			setTimeout(function(){
				$('#options-btn').attr('aria-pressed', 'false').focus();
			}, 1);
		});
	},

	renderBeelineMenu: function() {
		var vis = false;
		var beeline = this.model.get("controller").get("beeline");
		console.log("renderBeelineMenu: " + beeline);
		if( beeline && beeline == 'on') {
			vis = true;
		}
		// Only display if beta option was selected
		this.$("#beeline-beta-menu").toggle(vis);
		this.$("#beeline-theme-option").toggle(vis);
		this.renderBeelineOption();

	},

	renderBeelineOption: function() {
		var theme = this.model.get("beeline_theme");
		$("ul#beeline-beta-menu li").removeClass("active");
		$("li#" + theme + "-button").addClass("active");
	},

	render: function() {
		this.renderPagination();
		this.renderTheme();
		this.renderBeelineMenu();
		this.renderMarginRadio();
		this.renderFontSize();
        this.renderFontFace();
		this.renderDisplayPageNumbers();
		if (BookshareUtils.hasSpeechAPI()) {
			this.renderSpeechRate();
			this.renderVoiceOptions();
			if (!!window.chrome) {
				speechSynthesis.onvoiceschanged = _.bind(this.renderVoiceOptions, this);
			}
		}
		return this;
	},

	renderTheme: function() {
		var themePref = this.model.get("current_theme");
		this.$("#default-theme-option").toggleClass("selected", (themePref == 'default-theme'));
		this.$("#night-theme-option").toggleClass("selected", (themePref == 'night-theme'));
		this.$("#parchment-theme-option").toggleClass("selected", (themePref == 'parchment-theme'));
		this.$("#beeline-theme-option").toggleClass("selected", (themePref == 'beeline-theme'));
		return this;
	},

	renderMarginRadio: function() {
		var id = "#margin-option-" + this.model.get("current_margin");
		this.$('.margin-radio').toggleClass("selected", false);
		this.$(id).toggleClass("selected", true);
		return this;
	},

	renderFontSize: function() {
		var val = this.model.get("font_size");
		this.$("#font-size-input").val(val);
	},

	renderFontFace: function() {
		var val = this.model.get("font_face");
		this.$("#font-face-input").val(val);
	},

	renderPagination: function() {
		var val = this.model.get("pagination_mode");
		this.$("#pagination-mode-input").val(val);
	},

	filterVoiceOptions: function(v) {
		return v.localService && (v.name == "US English Female TTS (by Google)" || !/google/i.test(v.voiceURI));
	},

	renderVoiceOptions: function() {
		var voiceDefault;
		var select = $("#voice-input");
		select.children().remove();
		var voices = speechSynthesis.getVoices().filter(this.filterVoiceOptions);
		for (i = 0; i < voices.length; i++) {
			var voice = voices[i];
			var option = $("<option>").text(voice.name).val(voice.voiceURI);
			select.append(option);
			// Default to first available voice, "Alex", or "native", whichever's last
			if (i == 0 || this.DEFAULT_VOICES.indexOf(voice.name) >= 0) {
				voiceDefault = voice.voiceURI;
			}
		}
		// update the default one
		var defaultOption = select.find("option[value='" + voiceDefault + "']");
		defaultOption.text(defaultOption.text() + ' (default)');
		var voicePref = this.model.get("voice_uri");
        select.val(voicePref ? voicePref : voiceDefault);
        var controller = this.model.get("controller");
        controller.set("voice_uri", select.val());
        controller.trigger("change:voice_uri");
	},

    renderSpeechRate: function() {
        var val = this.model.get("speech_rate");
        this.$("#speech-rate-input").val(val);
    },

	renderDisplayPageNumbers: function() {
		this.$("#display-page-numbers").prop('checked', this.model.get("display_page_numbers"));
	},

	events: {
    	"click .theme-option": 			"selectTheme",
    	"click .margin-radio": 			"selectMargin",
    	"click #cancel-settings-but": 	"cancelSettings",
		"click #save-settings-but": 	"applySettings",
		"click #bright-button": 	function() {
			this.selectBeelineTheme("bright");
		},
		"click #dark-button": 	function() {
			this.selectBeelineTheme("dark");
		},
		"click #blues-button": 	function() {
			this.selectBeelineTheme("blues");
		},
		"click #gray-button": 	function() {
			this.selectBeelineTheme("gray");
		},
		"click #night_gray-button": 	function() {
			this.selectBeelineTheme("night_gray");
		}
  	},

  	selectBeelineTheme: function(theme) {
  		if(theme == "gray") {
  			console.log("Selecting gray theme.");
  		}
		this.model.set("current_theme", "beeline-theme");
  		this.model.set("beeline_theme", theme);
  		this.renderTheme();
		this.renderBeelineOption();
  	},

  	selectTheme: function(e) {
  		var id = e.srcElement ? e.srcElement.id : '';
		if (id && e.srcElement && Acc.rg && Acc.rg.theme && e.srcElement != Acc.rg.theme.selected) Acc.rg.theme.set(id);
  		if(id === "default-theme-option" ) this.model.set("current_theme", "default-theme");
		if(id === "night-theme-option" ) this.model.set("current_theme", "night-theme");
		if(id === "parchment-theme-option" ) this.model.set("current_theme", "parchment-theme");
		if(id === "beeline-theme-option" ) this.model.set("current_theme", "beeline-theme");
		e.stopPropagation();
  	},

  	selectMargin: function(e) {
  		var id = e.srcElement.id;
		if (e.srcElement && Acc.rg && Acc.rg.margin && e.srcElement != Acc.rg.margin.selected) Acc.rg.margin.set(id);
  		var num = id[id.length - 1];
  		if(num === "1" ) this.model.set("current_margin", 1);
		if(num === "2" ) this.model.set("current_margin", 2);
		if(num === "3" ) this.model.set("current_margin", 3);
		if(num === "4" ) this.model.set("current_margin", 4);
		if(num === "5" ) this.model.set("current_margin", 5);
		e.stopPropagation();
  	},

  	cancelSettings: function(e) {
  		this.$el.modal('hide');
  		this.model.resetOptions();
		$('#options-btn').focus();
  	},

  	applySettings: function(e) {
  		// extract options from non-fancy UI elements
		this.model.set("display_page_numbers", this.$("#display-page-numbers").prop('checked'));
		this.model.set("pagination_mode", $("#pagination-mode-input").val());
		this.model.set("font_size", parseInt($("#font-size-input").val(), 10));
		this.model.set("font_face", $("#font-face-input").val());
		this.model.set("speech_rate", parseFloat($("#speech-rate-input").val()));
		this.model.set("voice_uri", $("#voice-input").val());

  		this.model.applyOptions();
  		this.$el.modal('hide');
		$('#options-btn').focus();
  	}

});
<|endoftext|>


<commit_before>/*jshint strict:true node:true es5:true onevar:true laxcomma:true
laxbreak:true eqeqeq:true immed:true latedef:true undef:true unused:true */
(function () {
  "use strict";

  var connect = require('connect')
    , fs = require('fs')
    , path = require('path')
    ;

  function defaultPermalinkify(oldUrl) {
    // get everything except the domain
    return oldUrl.replace(/https?:\/\/[^\/]*/, '');
  }

  function createServer(pub, servepath, opts) {
    opts = opts || {};
    var server
      , permalinkify = opts.permalinkify || defaultPermalinkify
      ;

    servepath = '/' + (servepath || '').replace(/[\/\\]/g, '');

    server = connect.createServer()
      .use(connect.query())
      .use(function (request, response, next) {
          //console.log('fixRedir', request.url);

          function fixRedirectPost() {
            // Permament Redirect
            response.statusCode = 301;
            response.setHeader(
                'Location'
              , path.normalize(servepath + '/' + permalinkify(request.query.blogger))
            );
            response.end();
          }

          if (request.query.blogger) {
            fixRedirectPost();
            return;
          }

          function fixDoubleDash() {
            // Permament Redirect
            response.statusCode = 301;
            response.setHeader('Location', request.url.replace(/-+/g, '-'));
            response.end();
          }

          if (/--/.test(request.url)) {
            fixDoubleDash();
            return;
          }

          next();
        })
      // fuzzy redirect
      .use(path.normalize('/' + servepath), function (request, response, next) {
          //console.log('fuzzyRedir', request.url);
          var pathPart = request.url.split('/')
            , requestedFile = request.url.split('/').pop()
            , realDirPath
            ;

          pathPart.pop();
          pathPart = pathPart.join('/');

          //console.log('pathPart', pathPart);
          function sanatize(str) {
            return str
              .replace(/\.\w+$/, '')     // remove .html
              .replace(/%[\dA-Z]+/g, '') // remove %20
              .replace(/\ban?\b/g, '')   // ignore a/an
              .replace(/\bthe\b/g, '')   // ignore the
              .replace(/\bof\b/g, '')    // ignore of
              .replace(/[^a-z0-9]/g, '') // remove non-alphanumerics
              ;
          }

          function alphabetSoup(existingFile) {
            var shorter = sanatize(existingFile)
              , longer = sanatize(requestedFile.split('/').pop())
              , len = Math.min(25, shorter.length, longer.length) - 1
              ;

            if (existingFile === requestedFile) {
              // just in case connect.static() is being loaded late
              return;
            }

            if (shorter.substr(0, len) !== longer.substr(0, len)) {
              // console.log(shorter, longer);
              return;
            }

            response.statusCode = 301;
            response.setHeader(
                'Location'
              , path.normalize(servepath + '/' + pathPart + '/' + existingFile)
            );
            response.end();
            return true;
          }

          function fuzzy301(err, nodes) {
            if (err) { next(); return; }
            if (!nodes.some(alphabetSoup)) {
              next();
            }
          }

          // joining /rootdir, /sub/dir/ -> /rootdir/sub/dir/
          realDirPath = path.join(pub, servepath.replace(/[\/\\]/g, '/'), pathPart);

          //console.log('searchdir', realDirPath);
          fs.readdir(
              realDirPath
            , fuzzy301
          );
        })
      ;
    return server;
  }

  module.exports = createServer;
}());
<commit_msg>made easier to comment out servers (for debugging)<commit_after>/*jshint strict:true node:true es5:true onevar:true laxcomma:true
laxbreak:true eqeqeq:true immed:true latedef:true undef:true unused:true */
(function () {
  "use strict";

  var connect = require('connect')
    , fs = require('fs')
    , path = require('path')
    ;

  function defaultPermalinkify(oldUrl) {
    // get everything except the domain
    return oldUrl.replace(/https?:\/\/[^\/]*/, '');
  }

  function createServer(pub, servepath, opts) {
    opts = opts || {};
    var server
      , permalinkify
      ;

    function fuzzyRedirect(request, response, next) {
      //console.log('fuzzyRedir', request.url);
      var pathPart = request.url.split('/')
        , requestedFile = request.url.split('/').pop()
        , realDirPath
        ;

      pathPart.pop();
      pathPart = pathPart.join('/');

      //console.log('pathPart', pathPart);
      function sanatize(str) {
        return str
          .replace(/\.\w+$/, '')     // remove .html
          .replace(/%[\dA-Z]+/g, '') // remove %20
          .replace(/\ban?\b/g, '')   // ignore a/an
          .replace(/\bthe\b/g, '')   // ignore the
          .replace(/\bof\b/g, '')    // ignore of
          .replace(/[^a-z0-9]/g, '') // remove non-alphanumerics
          ;
      }

      function alphabetSoup(existingFile) {
        var shorter = sanatize(existingFile)
          , longer = sanatize(requestedFile.split('/').pop())
          , len = Math.min(25, shorter.length, longer.length) - 1
          ;

        if (existingFile === requestedFile) {
          // just in case connect.static() is being loaded late
          return;
        }

        if (shorter.substr(0, len) !== longer.substr(0, len)) {
          // console.log(shorter, longer);
          return;
        }

        response.statusCode = 301;
        response.setHeader(
            'Location'
          , path.normalize(servepath + '/' + pathPart + '/' + existingFile)
        );
        response.end();
        return true;
      }

      function fuzzy301(err, nodes) {
        if (err) { next(); return; }
        if (!nodes.some(alphabetSoup)) {
          next();
        }
      }

      // joining /rootdir, /sub/dir/ -> /rootdir/sub/dir/
      realDirPath = path.join(pub, servepath.replace(/[\/\\]/g, '/'), pathPart);

      //console.log('searchdir', realDirPath);
      fs.readdir(
          realDirPath
        , fuzzy301
      );
    }

    function solidRedirect(request, response, next) {
      //console.log('fixRedir', request.url);

      function fixRedirectPost() {
        // Permament Redirect
        response.statusCode = 301;
        response.setHeader(
            'Location'
          , path.normalize(servepath + '/' + permalinkify(request.query.blogger))
        );
        response.end();
      }

      if (request.query.blogger) {
        fixRedirectPost();
        return;
      }

      function fixDoubleDash() {
        // Permament Redirect
        response.statusCode = 301;
        response.setHeader('Location', request.url.replace(/-+/g, '-'));
        response.end();
      }

      if (/--/.test(request.url)) {
        fixDoubleDash();
        return;
      }

      next();
    }

    permalinkify = opts.permalinkify || defaultPermalinkify;
    servepath = '/' + (servepath || '').replace(/[\/\\]/g, '');

    server = connect.createServer()
      .use(connect.query())
      .use(solidRedirect)
      // fuzzy redirect
      .use(path.normalize('/' + servepath), fuzzyRedirect)
      ;

    return server;
  }

  module.exports = createServer;
}());
<|endoftext|>


<commit_before>import {join} from "path";
import assign from "lodash/object/assign";
import app from "./app";
import express from "express";
import htmlSrc from "./html.jst";
import template from "lodash/string/template";
import compress from "compression";
import http from "http";
import log from "appcore-log";
import config from "appcore-config";
import {resolve} from "path";
import socketio from "socket.io";
var morgan = require("morgan");

const SFDIR = resolve(process.cwd(), ".superfast");

app.set({
	superfast: { dir: SFDIR, seq: 0 },
	browserKeys: ["env","log","name","version","superfast.seq"]
});

app.use(config({
	filesKey: "config",
	files: [ "package.json", "config.json" ],
	cli: {
		string: [ "config" ],
		alias: {
			c: "config",
			p: "port"
		}
	},
	env: {
		PORT: "port"
	}
}));

app.use(log);

let htmlTpl = template(htmlSrc, { variable: "$" });

let options = assign({
	log: false,
	logLevel: "debug",
	compress: app.env === "production",
	"x-powered-by": false
}, app.get("router"));

let router = app.router = express();

// in case other things what to create static routes
router.static = express.static;

// creates a new express router object
router.create = function(opts) {
	return new express.Router(opts);
};

// base configuration
router.set("env", app.env);
assign(router.settings, app.get("express"));

// create a fresh server instance
let server = app.server = http.createServer(router);
server.on('error', app.error.bind(app));

// create socket.io instance
let io = app.io = socketio(server);
io.on("connection", function(socket) {
	socket.on("seq", function(fn) { fn(app.get("superfast.seq")); });
});

process.on("message", function(msg) {
	if (msg.match(/^SEQ/)) {
		let seq = parseInt(msg.substr(3).trim(), 10);
		if (!isNaN(seq) && app.get("superfast.seq") !== seq) {
			app.set("superfast.seq", seq);
			io.sockets.emit("seq", seq);
		}
	}
});

// setup router logger
if (options.log) router.use(morgan(app.env === "development" ? "dev" : "short", {
	stream: { write: function(l) { ((app.log && app.log[options.logLevel]) || console.log)(l.trim()); } }
}));

// gzip in production
if (options.compress) router.use(compress());

// phonehome router
router.use("/-methods", app.phone.http());

app.ready(function() {
	router.get(/^\/_app\.(js|css)$/, function(req, res) {
		res.sendFile(join(SFDIR, "client." + req.params[0]));
	});

	router.use(express.static("public"));

	router.use(function(req, res, next) {
		if (req.method !== "GET") return next();
		res.type("html");
		res.send(htmlTpl({
			config: app.getBrowserOptions(),
			scripts: [ "/_app.js" ],
			styles: [ "/_app.css" ]
		}));
	});

	let port = app.get("port") || 3000;
	server.listen(port, "0.0.0.0", app.wait());
});

// let parent process know that that app is running
app.running(function() {
	if (typeof process.send === "function") {
		process.send("READY " + JSON.stringify(server.address()));
	}
});
<commit_msg>get sequence before starting the app<commit_after>import {join} from "path";
import assign from "lodash/object/assign";
import app from "./app";
import express from "express";
import htmlSrc from "./html.jst";
import template from "lodash/string/template";
import compress from "compression";
import http from "http";
import log from "appcore-log";
import config from "appcore-config";
import {resolve} from "path";
import socketio from "socket.io";
var morgan = require("morgan");

const SFDIR = resolve(process.cwd(), ".superfast");

app.set({
	superfast: { dir: SFDIR, seq: 0 },
	browserKeys: ["env","log","name","version","superfast.seq"]
});

app.use(config({
	filesKey: "config",
	files: [ "package.json", "config.json" ],
	cli: {
		string: [ "config" ],
		alias: {
			c: "config",
			p: "port"
		}
	},
	env: {
		PORT: "port"
	}
}));

app.use(log);

let htmlTpl = template(htmlSrc, { variable: "$" });

let options = assign({
	log: false,
	logLevel: "debug",
	compress: app.env === "production",
	"x-powered-by": false
}, app.get("router"));

let router = app.router = express();

// in case other things what to create static routes
router.static = express.static;

// creates a new express router object
router.create = function(opts) {
	return new express.Router(opts);
};

// base configuration
router.set("env", app.env);
assign(router.settings, app.get("express"));

// create a fresh server instance
let server = app.server = http.createServer(router);
server.on('error', app.error.bind(app));

// create socket.io instance
let io = app.io = socketio(server);
io.on("connection", function(socket) {
	socket.on("seq", function(fn) { fn(app.get("superfast.seq")); });
});

// receive messages from the parent runner
process.on("message", app.wait(function(msg) {
	if (msg.match(/^SEQ/)) {
		let seq = parseInt(msg.substr(3).trim(), 10);
		if (!isNaN(seq) && app.get("superfast.seq") !== seq) {
			app.set("superfast.seq", seq);
			io.sockets.emit("seq", seq);
		}
	}
}));

// immediately ask for sequence information
if (typeof process.send === "function") {
	process.send("SEQ");
}

// setup router logger
if (options.log) router.use(morgan(app.env === "development" ? "dev" : "short", {
	stream: { write: function(l) { ((app.log && app.log[options.logLevel]) || console.log)(l.trim()); } }
}));

// gzip in production
if (options.compress) router.use(compress());

// phonehome router
router.use("/-methods", app.phone.http());

app.ready(function() {
	router.get(/^\/_app\.(js|css)$/, function(req, res) {
		res.sendFile(join(SFDIR, "client." + req.params[0]));
	});

	router.use(express.static("public"));

	router.use(function(req, res, next) {
		if (req.method !== "GET") return next();
		res.type("html");
		res.send(htmlTpl({
			config: app.getBrowserOptions(),
			scripts: [ "/_app.js" ],
			styles: [ "/_app.css" ]
		}));
	});

	let port = app.get("port") || 3000;
	server.listen(port, "0.0.0.0", app.wait());
});

// let parent process know that that app is running
app.running(function() {
	if (typeof process.send === "function") {
		process.send("READY " + JSON.stringify(server.address()));
	}
});
<|endoftext|>


<commit_before><commit_msg>We don't need jQuery, it's included in Wordpress.<commit_after><|endoftext|>