<commit_before>/* eslint-disable max-params, no-console */
const path = require('path')
const express = require('express')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const jwt = require('jsonwebtoken')
const get = require('lodash.get')
const { convertUuid58ToUuid: toU } = require('uuid58')
const GQL = require('./util/gql-queries')
const getGqlErrors = require('./util/gql-errors')

const JWT_COOKIE_NAME = 'jwt'
const JWT_COOKIE_PARAMS = {
  maxAge: 1000 * 60 * 60 * 24, // 1 day in milliseconds
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production',
}

const cacheHash =
  process.env.NODE_ENV === 'test' ? '_' : Date.now().toString(36)

require('express-async-errors')

const app = express()

app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())

// See https://github.com/reactjs/express-react-views#add-it-to-your-app
app.set('views', path.join(__dirname, '/views'))
app.set('view engine', 'jsx')
app.engine('jsx', require('express-react-views').createEngine())

async function ensureJwt(req, res, next) {
  if (!get(req.cookies, JWT_COOKIE_NAME)) {
    res.cookie(
      JWT_COOKIE_NAME,
      get(await GQL.rootGetAnonToken(req), 'data.getAnonymousToken.jwtToken'),
      JWT_COOKIE_PARAMS
    )
  }
  next()
}

function handleError(err, req, res, next) {
  // See express-async-errors
  if (err) res.redirect('/server-error')
  next(err)
}

function getJwt(req) {
  return jwt.decode(get(req.cookies, JWT_COOKIE_NAME))
}

function getRole(req) {
  return get(getJwt(req), 'role')
}

function isUser(req, res, next) {
  if (!['sg_user', 'sg_admin'].includes(getRole(req))) {
    return res.redirect('/log-in')
  }
  return next()
}

function isAnonymous(req, res, next) {
  if (getRole(req) !== 'sg_anonymous') {
    return res.redirect('/dashboard')
  }
  return next()
}

function handleRegular(req, res) {
  return res.render('Index', {
    location: req.url,
    query: req.query,
    cacheHash,
    role: getRole(req),
  })
}

app.use(ensureJwt)
app.use(handleError)

// /////////////////////////////////////////////////////////////////////////////

app.get('/sitemap.txt', (req, res) =>
  res.send(`
https://sagefy.org
https://sagefy.org/terms
https://sagefy.org/contact
https://sagefy.org/sign-up
https://sagefy.org/log-in
https://sagefy.org/email
https://sagefy.org/password
`)
) // Add more public routes as they are available

app.get('/sign-up', isAnonymous, handleRegular)

app.post('/sign-up', isAnonymous, async (req, res) => {
  const gqlRes = await GQL.rootNewUser(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      prevValues: req.body,
    })
  }
  return res
    .cookie(
      JWT_COOKIE_NAME,
      get(gqlRes, 'data.signUp.jwtToken'),
      JWT_COOKIE_PARAMS
    )
    .redirect(
      (req.query.redirect && decodeURIComponent(req.query.redirect)) ||
        '/dashboard'
    )
})

app.get('/log-in', isAnonymous, handleRegular)

app.post('/log-in', isAnonymous, async (req, res) => {
  const gqlRes = await GQL.rootLogInUser(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      prevValues: req.body,
    })
  }
  return res
    .cookie(
      JWT_COOKIE_NAME,
      get(gqlRes, 'data.logIn.jwtToken'),
      JWT_COOKIE_PARAMS
    )
    .redirect(
      (req.query.redirect && decodeURIComponent(req.query.redirect)) ||
        '/dashboard'
    )
})

function getQueryState(req) {
  return parseInt(req.query.state, 10) || 0
}

app.get('/email', async (req, res) => {
  const state = getQueryState(req)
  return res.render('Index', { location: req.url, cacheHash, state })
})

app.post('/email', async (req, res) => {
  if (getQueryState(req) === 2) {
    const gqlRes = await GQL.rootEditEmail({
      body: req.body,
      cookies: { [JWT_COOKIE_NAME]: req.query.token },
    })
    const gqlErrors = getGqlErrors(gqlRes)
    if (Object.keys(gqlErrors).length) {
      return res.render('Index', {
        location: req.url,
        cacheHash,
        gqlErrors,
        state: 2,
      })
    }
    return res.redirect('/log-in')
  }
  const gqlRes = await GQL.rootNewEmailToken(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      state: 0,
    })
  }
  return res.redirect('/email?state=1')
})

app.get('/password', async (req, res) => {
  const state = getQueryState(req)
  return res.render('Index', { location: req.url, cacheHash, state })
})

app.post('/password', async (req, res) => {
  if (getQueryState(req) === 2) {
    const gqlRes = await GQL.rootEditPassword({
      body: req.body,
      cookies: { [JWT_COOKIE_NAME]: req.query.token },
    })
    const gqlErrors = getGqlErrors(gqlRes)
    if (Object.keys(gqlErrors).length) {
      return res.render('Index', {
        location: req.url,
        cacheHash,
        gqlErrors,
        state: 2,
      })
    }
    return res.redirect('/log-in')
  }
  const gqlRes = await GQL.rootNewPasswordToken(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      state: 0,
    })
  }
  return res.redirect('/password?state=1')
})

app.get('/settings', isUser, async (req, res) => {
  const gqlRes = await GQL.rootGetCurrentUser(req)
  return res.render('Index', {
    location: req.url,
    cacheHash,
    prevValues: get(gqlRes, 'data.getCurrentUser'),
  })
})

app.post('/settings', isUser, async (req, res) => {
  const gqlRes = await GQL.rootEditUser(req)
  const gqlErrors = getGqlErrors(gqlRes)
  return res.render('Index', {
    location: req.url,
    cacheHash,
    gqlErrors,
    prevValues: req.body,
  })
})

app.get('/log-out', isUser, (req, res) =>
  res.clearCookie(JWT_COOKIE_NAME).redirect('/')
)

app.get('/dashboard', isUser, async (req, res) => {
  const gqlRes = await GQL.learnListUsubj(req)
  console.log(gqlRes)
  return res.render('Index', {
    location: req.url,
    cacheHash,
    role: getRole(req),
    allUserSubjects: {
      nodes: get(gqlRes, 'data.allUserSubjects.nodes', []).map(
        ({ id, subject: { entityId, name, body } }) => ({
          id,
          entityId,
          name,
          body,
        })
      ),
    },
    name: get(gqlRes, 'data.getCurrentUser.name'),
  })
})

app.get('/search-subjects', async (req, res) => {
  const gqlRes = await GQL.learnSearchSubject(req)
  return res.render('Index', {
    location: req.url,
    query: req.query,
    cacheHash,
    role: getRole(req),
    searchSubjects: get(gqlRes, 'data.searchSubjects'),
  })
})

app.get('/next', async (req, res) => {
  const role = getRole(req)
  if (role === 'sg_anonymous') {
    return res.redirect(
      `/sign-up?redirect=/next?subjectId=${req.query.subjectId}`
    )
  }
  req.query.subjectId = toU(req.query.subjectId)
  await GQL.learnNewUsubj(req)
  // TODO If a subject doesn't have enough cards,
  // suggest creating cards or just following instead.
  return res.redirect('/dashboard')
})

app.get('/', async (req, res) => {
  const gqlRes = await GQL.learnHome(req)
  return res.render('Index', {
    location: req.url,
    cacheHash,
    role: getRole(req),
    selectPopularSubjects: get(gqlRes, 'data.selectPopularSubjects'),
  })
})

// For pages that don't have specific data requirements
// and don't require being logged in or logged out:
// GET /server-error
// GET /terms
// GET /contact
// GET /
// GET * (NotFound)
app.get('*', handleRegular)

// /////////////////////////////////////////////////////////////////////////////

if (require.main === module) {
  app.listen(process.env.PORT || 5984)
}

module.exports = app
<commit_msg>Handle creating a new subject for both logged in and logged out users<commit_after>/* eslint-disable max-params, no-console */
const path = require('path')
const express = require('express')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const jwt = require('jsonwebtoken')
const get = require('lodash.get')
const { convertUuid58ToUuid: toU } = require('uuid58')
const GQL = require('./util/gql-queries')
const getGqlErrors = require('./util/gql-errors')

const JWT_COOKIE_NAME = 'jwt'
const JWT_COOKIE_PARAMS = {
  maxAge: 1000 * 60 * 60 * 24, // 1 day in milliseconds
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production',
}

const cacheHash =
  process.env.NODE_ENV === 'test' ? '_' : Date.now().toString(36)

require('express-async-errors')

const app = express()

app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())

// See https://github.com/reactjs/express-react-views#add-it-to-your-app
app.set('views', path.join(__dirname, '/views'))
app.set('view engine', 'jsx')
app.engine('jsx', require('express-react-views').createEngine())

async function ensureJwt(req, res, next) {
  if (!get(req.cookies, JWT_COOKIE_NAME)) {
    res.cookie(
      JWT_COOKIE_NAME,
      get(await GQL.rootGetAnonToken(req), 'data.getAnonymousToken.jwtToken'),
      JWT_COOKIE_PARAMS
    )
  }
  next()
}

function handleError(err, req, res, next) {
  // See express-async-errors
  if (err) res.redirect('/server-error')
  next(err)
}

function getJwt(req) {
  return jwt.decode(get(req.cookies, JWT_COOKIE_NAME))
}

function getRole(req) {
  return get(getJwt(req), 'role')
}

function isUser(req, res, next) {
  if (!['sg_user', 'sg_admin'].includes(getRole(req))) {
    return res.redirect('/log-in')
  }
  return next()
}

function isAnonymous(req, res, next) {
  if (getRole(req) !== 'sg_anonymous') {
    return res.redirect('/dashboard')
  }
  return next()
}

function handleRegular(req, res) {
  return res.render('Index', {
    location: req.url,
    query: req.query,
    cacheHash,
    role: getRole(req),
  })
}

app.use(ensureJwt)
app.use(handleError)

// /////////////////////////////////////////////////////////////////////////////

app.get('/sitemap.txt', (req, res) =>
  res.send(`
https://sagefy.org
https://sagefy.org/terms
https://sagefy.org/contact
https://sagefy.org/sign-up
https://sagefy.org/log-in
https://sagefy.org/email
https://sagefy.org/password
`)
) // Add more public routes as they are available

app.get('/sign-up', isAnonymous, handleRegular)

app.post('/sign-up', isAnonymous, async (req, res) => {
  const gqlRes = await GQL.rootNewUser(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      prevValues: req.body,
    })
  }
  return res
    .cookie(
      JWT_COOKIE_NAME,
      get(gqlRes, 'data.signUp.jwtToken'),
      JWT_COOKIE_PARAMS
    )
    .redirect(
      (req.query.redirect && decodeURIComponent(req.query.redirect)) ||
        '/dashboard'
    )
})

app.get('/log-in', isAnonymous, handleRegular)

app.post('/log-in', isAnonymous, async (req, res) => {
  const gqlRes = await GQL.rootLogInUser(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      prevValues: req.body,
    })
  }
  return res
    .cookie(
      JWT_COOKIE_NAME,
      get(gqlRes, 'data.logIn.jwtToken'),
      JWT_COOKIE_PARAMS
    )
    .redirect(
      (req.query.redirect && decodeURIComponent(req.query.redirect)) ||
        '/dashboard'
    )
})

function getQueryState(req) {
  return parseInt(req.query.state, 10) || 0
}

app.get('/email', async (req, res) => {
  const state = getQueryState(req)
  return res.render('Index', { location: req.url, cacheHash, state })
})

app.post('/email', async (req, res) => {
  if (getQueryState(req) === 2) {
    const gqlRes = await GQL.rootEditEmail({
      body: req.body,
      cookies: { [JWT_COOKIE_NAME]: req.query.token },
    })
    const gqlErrors = getGqlErrors(gqlRes)
    if (Object.keys(gqlErrors).length) {
      return res.render('Index', {
        location: req.url,
        cacheHash,
        gqlErrors,
        state: 2,
      })
    }
    return res.redirect('/log-in')
  }
  const gqlRes = await GQL.rootNewEmailToken(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      state: 0,
    })
  }
  return res.redirect('/email?state=1')
})

app.get('/password', async (req, res) => {
  const state = getQueryState(req)
  return res.render('Index', { location: req.url, cacheHash, state })
})

app.post('/password', async (req, res) => {
  if (getQueryState(req) === 2) {
    const gqlRes = await GQL.rootEditPassword({
      body: req.body,
      cookies: { [JWT_COOKIE_NAME]: req.query.token },
    })
    const gqlErrors = getGqlErrors(gqlRes)
    if (Object.keys(gqlErrors).length) {
      return res.render('Index', {
        location: req.url,
        cacheHash,
        gqlErrors,
        state: 2,
      })
    }
    return res.redirect('/log-in')
  }
  const gqlRes = await GQL.rootNewPasswordToken(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      state: 0,
    })
  }
  return res.redirect('/password?state=1')
})

app.get('/settings', isUser, async (req, res) => {
  const gqlRes = await GQL.rootGetCurrentUser(req)
  return res.render('Index', {
    location: req.url,
    cacheHash,
    prevValues: get(gqlRes, 'data.getCurrentUser'),
  })
})

app.post('/settings', isUser, async (req, res) => {
  const gqlRes = await GQL.rootEditUser(req)
  const gqlErrors = getGqlErrors(gqlRes)
  return res.render('Index', {
    location: req.url,
    cacheHash,
    gqlErrors,
    prevValues: req.body,
  })
})

app.get('/log-out', isUser, (req, res) =>
  res.clearCookie(JWT_COOKIE_NAME).redirect('/')
)

app.get('/dashboard', isUser, async (req, res) => {
  const gqlRes = await GQL.learnListUsubj(req)
  return res.render('Index', {
    location: req.url,
    cacheHash,
    role: getRole(req),
    allUserSubjects: {
      nodes: get(gqlRes, 'data.allUserSubjects.nodes', []).map(
        ({ id, subject: { entityId, name, body } }) => ({
          id,
          entityId,
          name,
          body,
        })
      ),
    },
    name: get(gqlRes, 'data.getCurrentUser.name'),
  })
})

app.get('/search-subjects', async (req, res) => {
  const gqlRes = await GQL.learnSearchSubject(req)
  return res.render('Index', {
    location: req.url,
    query: req.query,
    cacheHash,
    role: getRole(req),
    searchSubjects: get(gqlRes, 'data.searchSubjects'),
  })
})

app.post('/create-subject', async (req, res) => {
  const gqlRes = await GQL.contributeNewSubject(req)
  const gqlErrors = getGqlErrors(gqlRes)
  if (Object.keys(gqlErrors).length) {
    return res.render('Index', {
      location: req.url,
      cacheHash,
      gqlErrors,
      prevValues: req.body,
    })
  }
  const role = getRole(req)
  const { entityId, name } = get(gqlRes, 'data.newSubject.subjectVersion', {})
  if (role === 'sg_anonymous') {
    return res.redirect(`/search-subjects?q=${name}`)
  }
  req.query.subjectId = entityId
  await GQL.learnNewUsubj(req)
  return res.redirect('/dashboard')
})

app.get('/next', async (req, res) => {
  const role = getRole(req)
  if (role === 'sg_anonymous') {
    return res.redirect(
      `/sign-up?redirect=/next?subjectId=${req.query.subjectId}`
    )
  }
  req.query.subjectId = toU(req.query.subjectId)
  await GQL.learnNewUsubj(req)
  // TODO If a subject doesn't have enough cards,
  // suggest creating cards or just following instead.
  return res.redirect('/dashboard')
})

app.get('/', async (req, res) => {
  const gqlRes = await GQL.learnHome(req)
  return res.render('Index', {
    location: req.url,
    cacheHash,
    role: getRole(req),
    selectPopularSubjects: get(gqlRes, 'data.selectPopularSubjects'),
  })
})

// For pages that don't have specific data requirements
// and don't require being logged in or logged out:
// GET /create-subject
// GET /server-error
// GET /terms
// GET /contact
// GET /
// GET * (NotFound)
app.get('*', handleRegular)

// /////////////////////////////////////////////////////////////////////////////

if (require.main === module) {
  app.listen(process.env.PORT || 5984)
}

module.exports = app
<|endoftext|>


<commit_before>Topics   = new Mongo.Collection("topics");
Comments = new Mongo.Collection("comments");

Meteor.subscribe("topics");
Meteor.subscribe("comments");

Meteor.startup(function() {
  GoogleMaps.load();
});

Template.sentimentmap.helpers({
  mapOptions: function() {
    if (GoogleMaps.loaded()) {
      return {
        center: new google.maps.LatLng(23.6260333, -102.5377501),
        zoom: 3,
        disableDefaultUI: true,
        scrollwheel: false,
        navigationControl: false,
        mapTypeControl: false,
        scaleControl: false,
        draggable: false
      };
    }
  }
});

Template.sentimentmap.onCreated(function() {
  // We can use the `ready` callback to interact with the map API once the map is ready.
  GoogleMaps.ready('sentimentMap', function(map) {
    // Add a marker to the map once it's ready
    var marker = new google.maps.Marker({
      position: map.options.center,
      map: map.instance
    });
  });
});

Template.body.helpers({
  topics: function () {
    return Topics.find({});
  }
});

Template.commentbox.helpers({
  comments: function () {
    var oid = this.id;
    return Comments.find({topic: oid});
  }
});

Template.commentbox.events({
  'click .close-comment-box': function (event,template) {
    template.$(".comment-box").remove();
  }
});

Template.singlecommentbox.helpers({
  sentiment: function () {
    // return this.sentiment;
  }
});

Template.singlecommentbox.rendered = function(){
  switch (this.data.sentiment) {
    case -2:
    this.$(".user-sentiment").css('background-color', '#e5596b');
    break;
    case -1:
    this.$(".user-sentiment").css('background-color', '#e5596b');
    break;
    case 0:
    this.$(".user-sentiment").css('background-color', '#fabe2c');
    break;
    case 1:
    this.$(".user-sentiment").css('background-color', '#1cb970');
    break;
    case 2:
    this.$(".user-sentiment").css('background-color', '#1cb970');
    break;
  }
};

/*
* Insert a Comment to MongoDB from CommentBox.
* Keypressed and OnClick Events...
*/

Template.commentbox.events({
  "click .comment-box-send": function (event, template) {
    var random = _.sample([-2, -1, 0, 1, 2]); //Testing Purposes

    Comments.insert({
      topic: this.id,
      // author: null,
      posted: new Date(),
      loc: {lng: 98.91, lat: 110.23},
      sentiment: random,
      keywords: ["bonito", "hermoso"],
      text: template.$(".comment-box-input").val()
    });
    // Clear form
    template.$(".comment-box-input").val("");

    // Prevent default form submit
    event.stopPropagation();
    return false;
  },

  "keypress paper-input": function (event, template) {
    var random = _.sample([-2, -1, 0, 1, 2]); //Testing Purposes

    if (event.charCode == 13) {
      Comments.insert({
        topic: this.id,
        // author: null,
        posted: new Date(),
        loc: {lng: 98.91, lat: 110.23},
        sentiment: random,
        keywords: ["bonito", "hermoso"],
        text: template.$(".comment-box-input").val()
      });
      // Clear form
      template.$(".comment-box-input").val("");

      // Prevent default form submit
      event.stopPropagation();
      return false;
    }
  }
});

Template.commentbox.rendered = function(){
  switch (this.data.avgsentiment) {
    case 0:
    this.$(".commentbox-sentiment-dot").css('background-color', '#e35a6d');
    break;
    case 1:
    this.$(".commentbox-sentiment-dot").css('background-color', '#e35a6d');
    break;
    case 2:
    this.$(".commentbox-sentiment-dot").css('background-color', '#f4bd57');
    break;
    case 3:
    this.$(".commentbox-sentiment-dot").css('background-color', '#41ca77');
    break;
    case 4:
    this.$(".commentbox-sentiment-dot").css('background-color', '#41ca77');
    break;
  }
};

/** Mongo Queries **/
// db.topics.find()
// db.topics.insert({name: "UDLAP", sentiment: 2, isActive: true,timestamp: new Date(),share: 0	});
// db.topics.insert({name: "Puebla", sentiment: 0, isActive: true,timestamp: new Date(),share: 0	});
// db.topics.insert({name: "Peña Nieto", sentiment: -2, isActive: true,timestamp: new Date(),share: 0	});
/* Positive */
//db.comments.insert({topic: ObjectId("55540d606638db2164f2aca8"), author: null, posted: new Date(), loc: {lng: 98.91, lat: 110.23}, sentiment:2, keywords: ["bonito", "hermoso"], text: "El cielo es bonito y muy hermoso"})
/* Negative */
//db.comments.insert({topic: ObjectId("55539ff2669903184654bd04"), author: null, posted: new Date(), loc: {lng: 98.91, lat: 110.23}, sentiment:-2, keywords: ["malo", "pesimo"], text: "El servicio es pesimo y muy malo"})
<commit_msg>Updated for Tinga<commit_after>Topics   = new Mongo.Collection("topics");
Comments = new Mongo.Collection("comments");

Meteor.subscribe("topics");
Meteor.subscribe("comments");

Meteor.startup(function() {
  GoogleMaps.load();
});

Template.sentimentmap.helpers({
  mapOptions: function() {
    if (GoogleMaps.loaded()) {
      return {
        center: new google.maps.LatLng(23.6260333, -102.5377501),
        zoom: 3,
        disableDefaultUI: true,
        scrollwheel: false,
        navigationControl: false,
        mapTypeControl: false,
        scaleControl: false,
        draggable: false
      };
    }
  }
});

Template.sentimentmap.onCreated(function() {
  // We can use the `ready` callback to interact with the map API once the map is ready.
  GoogleMaps.ready('sentimentMap', function(map) {
    // Add a marker to the map once it's ready
    var marker = new google.maps.Marker({
      position: map.options.center,
      map: map.instance
    });
  });
});

Template.body.helpers({
  topics: function () {
    return Topics.find({});
  }
});

Template.commentbox.helpers({
  comments: function () {
    var oid = this.id;
    return Comments.find({topic: oid});
  }
});

Template.commentbox.events({
  'click .close-comment-box': function (event,template) {
    template.$(".comment-box").remove();
  }
});

Template.singlecommentbox.helpers({
  sentiment: function () {
    // return this.sentiment;
  }
});

Template.singlecommentbox.rendered = function(){
  switch (this.data.sentiment) {
    case -2:
    this.$(".user-sentiment").css('background-color', '#e5596b');
    break;
    case -1:
    this.$(".user-sentiment").css('background-color', '#e5596b');
    break;
    case 0:
    this.$(".user-sentiment").css('background-color', '#fabe2c');
    break;
    case 1:
    this.$(".user-sentiment").css('background-color', '#1cb970');
    break;
    case 2:
    this.$(".user-sentiment").css('background-color', '#1cb970');
    break;
  }
};

/*
* Insert a Comment to MongoDB from CommentBox.
* Keypressed and OnClick Events...
*/

Template.commentbox.events({
  "click .comment-box-send": function (event, template) {
    var random = _.sample([-2, -1, 0, 1, 2]); //Testing Purposes

    Comments.insert({
      topic: this.id,
      // author: null,
      posted: new Date(),
      loc: {lng: 98.91, lat: 110.23},
      sentiment: null,
      keywords: null,
      text: template.$(".comment-box-input").val(),
      source: "app"
    });
    // Clear form
    template.$(".comment-box-input").val("");

    // Prevent default form submit
    event.stopPropagation();
    return false;
  },

  "keypress paper-input": function (event, template) {
    var random = _.sample([-2, -1, 0, 1, 2]); //Testing Purposes

    if (event.charCode == 13) {
      Comments.insert({
        topic: this.id,
        // author: null,
        posted: new Date(),
        loc: {lng: 98.91, lat: 110.23},
        sentiment: null,
        keywords: null,
        text: template.$(".comment-box-input").val(),
        source: "app"
      });
      // Clear form
      template.$(".comment-box-input").val("");

      // Prevent default form submit
      event.stopPropagation();
      return false;
    }
  }
});

Template.commentbox.rendered = function(){
  switch (this.data.avgsentiment) {
    case 0:
    this.$(".commentbox-sentiment-dot").css('background-color', '#e35a6d');
    break;
    case 1:
    this.$(".commentbox-sentiment-dot").css('background-color', '#e35a6d');
    break;
    case 2:
    this.$(".commentbox-sentiment-dot").css('background-color', '#f4bd57');
    break;
    case 3:
    this.$(".commentbox-sentiment-dot").css('background-color', '#41ca77');
    break;
    case 4:
    this.$(".commentbox-sentiment-dot").css('background-color', '#41ca77');
    break;
  }
};

/** Mongo Queries **/
// db.topics.find()
// db.topics.insert({name: "UDLAP", sentiment: 2, isActive: true,timestamp: new Date(),share: 0	});
// db.topics.insert({name: "Puebla", sentiment: 0, isActive: true,timestamp: new Date(),share: 0	});
// db.topics.insert({name: "Peña Nieto", sentiment: -2, isActive: true,timestamp: new Date(),share: 0	});
/* Positive */
//db.comments.insert({topic: ObjectId("55540d606638db2164f2aca8"), author: null, posted: new Date(), loc: {lng: 98.91, lat: 110.23}, sentiment:2, keywords: ["bonito", "hermoso"], text: "El cielo es bonito y muy hermoso"})
/* Negative */
//db.comments.insert({topic: ObjectId("55539ff2669903184654bd04"), author: null, posted: new Date(), loc: {lng: 98.91, lat: 110.23}, sentiment:-2, keywords: ["malo", "pesimo"], text: "El servicio es pesimo y muy malo"})
<|endoftext|>


<commit_before>// Dependencies
var $ = require("/libs/jquery");

// Add the custom select plugin
$.jstree.defaults.conditionalselect = function (node, cb) { cb(true); };
$.jstree.plugins.conditionalselect = function (options, parent) {
    this.activate_node = function (obj, e) {
        this.settings.conditionalselect.call(this, this.get_node(obj), function (select) {
            if (select) {
                parent.activate_node.call(this, obj, e);
            }
        });
    };
};

/*!
 * init
 *
 * @name init
 * @function
 * @return {undefined}
 */
exports.init = function() {
    var self = this;

    function actionGen(action) {
        return function (node, data) {
            var item = node;
            var jsTreeInst = null;
            if (data && data.node) {
                item = data.node;
                jsTreeInst = $.jstree.reference(item);
            } else {
                jsTreeInst = $.jstree.reference(item.reference);
                item = jsTreeInst.get_node(node.reference);
            }

            function req (data, act) {
                act = act || action;
                self.link(act, function (err) {
                    if (err) { alert(err); }
                    jsTreeInst.refresh();
                }).send(null, {
                    project: self.project,
                    path: item.original.path,
                    data: data
                });
            }

            switch (action) {
                case "do_rename":
                    return jsTreeInst.edit(item);
                case "do_newFolder":
                case "do_newFile":
                    var newNode = jsTreeInst.create_node(item.parent);
                    jsTreeInst.edit(newNode);
                    self.tmp.creating = action.replace("do_", "");
                    self.tmp.path = item.original.path
                    return;
                case "renamed":
                    if (self.tmp.creating) {
                        item.original.path = self.tmp.path;
                    }
                    req({ name: item.text }, self.tmp.creating);
                    self.tmp.creating = null;
                    self.tmp.path = null;
                    return;
            }

            req();
        };
    }

    self.tmp = {};
    self.$jstree = $(self._config.container).jstree({
        plugins: ["dnd", "types", "wholerow", "contextmenu", "search", "conditionalselect"],
        types: {
            "default": {
                icon: "octicon octicon-file-text"
            },
            folder: {
                icon : "octicon octicon-file-directory"
            },
            binary: {
                icon : "octicon octicon-file-binary"
            },
            code: {
                icon : "octicon octicon-file-code"
            },
            media: {
                icon : "octicon octicon-file-media"
            },
            pdf: {
                icon : "octicon octicon-file-pdf"
            },
            symlink: {
                icon : "octicon octicon-file-symlink"
            },
            zip: {
                icon : "octicon octicon-file-zip"
            }
        },
        conditionalselect: function (node, cb) {
            if (self._config.alwaysSelect) {
                return cb(true);
            }
            self.emit("beforeSelect");
            self.on("_beforeSelectRes", function (ev, data) {
                cb(data.select);
            }, true);
        },
        core: {
            data: function (node, cb) {
                self.open(null, {
                    path: Object(node.original).path,
                    callback: function (err, data) {
                        if (err) { alert(err); }
                        cb(data);
                        self.emit("pathOpened", null, err, data);
                    }
                });
            },
            check_callback: true
        },
        contextmenu: {
            items: {
                createFolder: {
                    label: "New folder",
                    icon : "octicon octicon-file-directory",
                    action: actionGen("do_newFolder")
                },
                createFile: {
                    label: "New file",
                    icon: "octicon octicon-file-text",
                    action: actionGen("do_newFile")
                },
                rename: {
                    label: "Rename",
                    icon: "octicon octicon-pencil",
                    action: actionGen("do_rename")
                },
                deleteItem: {
                    label: "Delete",
                    icon: "octicon octicon-x",
                    action: actionGen("delete")
                }
            },
            select_node: false
        }
    }).on("changed.jstree", function (e, data) {
        if (!data.node) { return; }
        var isFolder = data.node.type === "folder";
        self[isFolder ? "selectedDir" : "selectedFile"] = data.node.original.path;
        self.emit("selected." + (isFolder ? "folder" : "file"));
        self.selected = data.node.original.path;
        self.emit("changed", e, data);
    }).on("loaded.jstree", function (e, data) {
        self.emit("loaded", e, data);
    }).on("open_node.jstree", function (e, data) {
        self.emit("nodeOpened", e, data);
    }).on("rename_node.jstree", actionGen("renamed"));
};

/**
 * setProject
 * Sets the project name internally.
 *
 * @name setProject
 * @function
 * @param {Event} ev The event object.
 * @param {Object} data An object containing the following fields:
 *
 *  - `project` (String): The project name.
 *
 */
exports.setProject = function (ev, data) {
    this.project = data.project;
};

function openPath(p, i, $parent) {
    var self = this;
    i = i || 0;
    if (typeof p === "string") {
        p = ["/"].concat(p.split("/"));
    }

    if (p[0] !== "/") {
        p.unshift("/");
    }

    var c = p[i];
    if (!c) {
        return self.emit("openPathFinished");
    }

    if (!$parent) {
        $parent = self.$jstree;
    }
    $parent = $($parent);

    var $cListItem = $parent.find(">ul>li").find(">a").filter(function () {
        return $(this).text().trim() === c;
    });

    if ($cListItem.find(">ul").length) {
        return openPath.call(self, p, i + 1, "#" + $cListItem.parent().attr("id"));
    } else {
        setTimeout(function() {
            self.on("nodeOpened", function () {
                openPath.call(self, p, i + 1, "#" + $cListItem.parent().attr("id"));
            }, true);
            if ($cListItem.find("i").hasClass("octicon-file-directory")) {
                $cListItem.dblclick();
            } else {
                $cListItem.click();
                self.emit("openPathFinished");
            }
        }, 0);
    }
}

/**
 * openPath
 * Opens a path to a file or directory.
 *
 * @name openPath
 * @function
 * @param {Event} ev The event object.
 * @param {Object} data An object containing the following fields:
 *
 *  - `path` (Strnig): The path to open.
 *  - `start` (Number): The path start index (splitted by `/`). Default is `3`.
 */
exports.openPath = function (ev, data) {
    if (!data.path) {
        return;
    }

    var splits = data.path;
    var self = this;

    if (typeof splits === "string") {
        splits = split.split("/");
    }

    openPath.call(self, splits.slice(data.start || 3));
};

/**
 * open
 * Opens a file/directory, in the current directory.
 *
 * @name open
 * @function
 * @param {Event} ev The event object.
 * @param {Object} data An object containing the following fields:
 *
 *  - `path` (Strnig): The path to open.
 */
exports.open = function (ev, data) {
    var self = this;
    var callback = data.callback || function (err) {
        if (err) { return alert(err); }
    };
    if (data.path === undefined) {
        return callback(null, [{
            path: "/",
            type: "folder",
            text: "/",
            children: true
        }]);
    }
    self.link("readDir", callback).send(null, {
        project: self.project,
        path: data.path
    });
};
<commit_msg>Removed return undefined<commit_after>// Dependencies
var $ = require("/libs/jquery");

// Add the custom select plugin
$.jstree.defaults.conditionalselect = function (node, cb) { cb(true); };
$.jstree.plugins.conditionalselect = function (options, parent) {
    this.activate_node = function (obj, e) {
        this.settings.conditionalselect.call(this, this.get_node(obj), function (select) {
            if (select) {
                parent.activate_node.call(this, obj, e);
            }
        });
    };
};

/*!
 * init
 *
 * @name init
 * @function
 */
exports.init = function() {
    var self = this;

    function actionGen(action) {
        return function (node, data) {
            var item = node;
            var jsTreeInst = null;
            if (data && data.node) {
                item = data.node;
                jsTreeInst = $.jstree.reference(item);
            } else {
                jsTreeInst = $.jstree.reference(item.reference);
                item = jsTreeInst.get_node(node.reference);
            }

            function req (data, act) {
                act = act || action;
                self.link(act, function (err) {
                    if (err) { alert(err); }
                    jsTreeInst.refresh();
                }).send(null, {
                    project: self.project,
                    path: item.original.path,
                    data: data
                });
            }

            switch (action) {
                case "do_rename":
                    return jsTreeInst.edit(item);
                case "do_newFolder":
                case "do_newFile":
                    var newNode = jsTreeInst.create_node(item.parent);
                    jsTreeInst.edit(newNode);
                    self.tmp.creating = action.replace("do_", "");
                    self.tmp.path = item.original.path
                    return;
                case "renamed":
                    if (self.tmp.creating) {
                        item.original.path = self.tmp.path;
                    }
                    req({ name: item.text }, self.tmp.creating);
                    self.tmp.creating = null;
                    self.tmp.path = null;
                    return;
            }

            req();
        };
    }

    self.tmp = {};
    self.$jstree = $(self._config.container).jstree({
        plugins: ["dnd", "types", "wholerow", "contextmenu", "search", "conditionalselect"],
        types: {
            "default": {
                icon: "octicon octicon-file-text"
            },
            folder: {
                icon : "octicon octicon-file-directory"
            },
            binary: {
                icon : "octicon octicon-file-binary"
            },
            code: {
                icon : "octicon octicon-file-code"
            },
            media: {
                icon : "octicon octicon-file-media"
            },
            pdf: {
                icon : "octicon octicon-file-pdf"
            },
            symlink: {
                icon : "octicon octicon-file-symlink"
            },
            zip: {
                icon : "octicon octicon-file-zip"
            }
        },
        conditionalselect: function (node, cb) {
            if (self._config.alwaysSelect) {
                return cb(true);
            }
            self.emit("beforeSelect");
            self.on("_beforeSelectRes", function (ev, data) {
                cb(data.select);
            }, true);
        },
        core: {
            data: function (node, cb) {
                self.open(null, {
                    path: Object(node.original).path,
                    callback: function (err, data) {
                        if (err) { alert(err); }
                        cb(data);
                        self.emit("pathOpened", null, err, data);
                    }
                });
            },
            check_callback: true
        },
        contextmenu: {
            items: {
                createFolder: {
                    label: "New folder",
                    icon : "octicon octicon-file-directory",
                    action: actionGen("do_newFolder")
                },
                createFile: {
                    label: "New file",
                    icon: "octicon octicon-file-text",
                    action: actionGen("do_newFile")
                },
                rename: {
                    label: "Rename",
                    icon: "octicon octicon-pencil",
                    action: actionGen("do_rename")
                },
                deleteItem: {
                    label: "Delete",
                    icon: "octicon octicon-x",
                    action: actionGen("delete")
                }
            },
            select_node: false
        }
    }).on("changed.jstree", function (e, data) {
        if (!data.node) { return; }
        var isFolder = data.node.type === "folder";
        self[isFolder ? "selectedDir" : "selectedFile"] = data.node.original.path;
        self.emit("selected." + (isFolder ? "folder" : "file"));
        self.selected = data.node.original.path;
        self.emit("changed", e, data);
    }).on("loaded.jstree", function (e, data) {
        self.emit("loaded", e, data);
    }).on("open_node.jstree", function (e, data) {
        self.emit("nodeOpened", e, data);
    }).on("rename_node.jstree", actionGen("renamed"));
};

/**
 * setProject
 * Sets the project name internally.
 *
 * @name setProject
 * @function
 * @param {Event} ev The event object.
 * @param {Object} data An object containing the following fields:
 *
 *  - `project` (String): The project name.
 *
 */
exports.setProject = function (ev, data) {
    this.project = data.project;
};

function openPath(p, i, $parent) {
    var self = this;
    i = i || 0;
    if (typeof p === "string") {
        p = ["/"].concat(p.split("/"));
    }

    if (p[0] !== "/") {
        p.unshift("/");
    }

    var c = p[i];
    if (!c) {
        return self.emit("openPathFinished");
    }

    if (!$parent) {
        $parent = self.$jstree;
    }
    $parent = $($parent);

    var $cListItem = $parent.find(">ul>li").find(">a").filter(function () {
        return $(this).text().trim() === c;
    });

    if ($cListItem.find(">ul").length) {
        return openPath.call(self, p, i + 1, "#" + $cListItem.parent().attr("id"));
    } else {
        setTimeout(function() {
            self.on("nodeOpened", function () {
                openPath.call(self, p, i + 1, "#" + $cListItem.parent().attr("id"));
            }, true);
            if ($cListItem.find("i").hasClass("octicon-file-directory")) {
                $cListItem.dblclick();
            } else {
                $cListItem.click();
                self.emit("openPathFinished");
            }
        }, 0);
    }
}

/**
 * openPath
 * Opens a path to a file or directory.
 *
 * @name openPath
 * @function
 * @param {Event} ev The event object.
 * @param {Object} data An object containing the following fields:
 *
 *  - `path` (Strnig): The path to open.
 *  - `start` (Number): The path start index (splitted by `/`). Default is `3`.
 */
exports.openPath = function (ev, data) {
    if (!data.path) {
        return;
    }

    var splits = data.path;
    var self = this;

    if (typeof splits === "string") {
        splits = split.split("/");
    }

    openPath.call(self, splits.slice(data.start || 3));
};

/**
 * open
 * Opens a file/directory, in the current directory.
 *
 * @name open
 * @function
 * @param {Event} ev The event object.
 * @param {Object} data An object containing the following fields:
 *
 *  - `path` (Strnig): The path to open.
 */
exports.open = function (ev, data) {
    var self = this;
    var callback = data.callback || function (err) {
        if (err) { return alert(err); }
    };
    if (data.path === undefined) {
        return callback(null, [{
            path: "/",
            type: "folder",
            text: "/",
            children: true
        }]);
    }
    self.link("readDir", callback).send(null, {
        project: self.project,
        path: data.path
    });
};
<|endoftext|>


<commit_before>// tempUrl='http://192.168.10.106:8080/api/temperature' temperatureExecutable='../../temp' deviceId='babys room' node index.js
var request = require('request');
var moment = require('moment');
var unirest = require('unirest');
var spawn = require('child_process').spawn;

var baseUrl  = process.env.tempUrl || 'http://192.168.10.106:8080/api/temperature';
var path     = process.env.temperatureExecutable || '../c/bin/temp';
var deviceId = process.env.deviceId || 'raspberryPi';

var child = spawn(path, []);
console.log('Starting at ... ', moment().format())

child.stdout.on('data', function(chunk) {
    console.log('Received event! ', moment().format())
    var lines = chunk.toString().split('\n')

    var sumTemp = 0, sumHumdity = 0, count = 0;
    for(var i = 0; i < lines.length; i++) {
        var line = lines[i]
        var data = jsonString(line)

        if(data){
            sumTemp += data.Temp;
            sumHumdity += data.Humidity;
            count++;
        }
    }

    postData(sumTemp/count, sumHumdity/count);
});

child.on('close', function(code) {
    console.log('Exited with code: ${code}')
});

child.stderr.on('data', function (data) {
    console.log('stderr: ' + data);
});

function postData(temp, humidity){
    var obj = {}
    obj.temp = temp
    obj.humidity = humidity
    obj.dateOfOccurance = moment().format()
    obj.deviceId = deviceId

    console.log('posting this: ', JSON.stringify(obj))
    unirest.post(baseUrl)
        .headers({'Accept': 'application/json', 'Content-Type': 'application/json'})
        .send({
            "temp":"68.0",
            "humidity": "32.1",
            "dateOfOccurance":"2016-12-17 23:13:00",
            "deviceId":"babys room"
        })
        .end(function (response) {
            console.log("Response: ", response.body);
        });
}

function jsonString(str) {
    try {
        return JSON.parse(str)
    } catch (e) {
        return null
    }
}<commit_msg>forgot to swap obj<commit_after>// tempUrl='http://192.168.10.106:8080/api/temperature' temperatureExecutable='../../temp' deviceId='babys room' node index.js
var request = require('request');
var moment = require('moment');
var unirest = require('unirest');
var spawn = require('child_process').spawn;

var baseUrl  = process.env.tempUrl || 'http://192.168.10.106:8080/api/temperature';
var path     = process.env.temperatureExecutable || '../c/bin/temp';
var deviceId = process.env.deviceId || 'raspberryPi';

var child = spawn(path, []);
console.log('Starting at ... ', moment().format())

child.stdout.on('data', function(chunk) {
    console.log('Received event! ', moment().format())
    var lines = chunk.toString().split('\n')

    var sumTemp = 0, sumHumdity = 0, count = 0;
    for(var i = 0; i < lines.length; i++) {
        var line = lines[i]
        var data = jsonString(line)

        if(data){
            sumTemp += data.Temp;
            sumHumdity += data.Humidity;
            count++;
        }
    }

    postData(sumTemp/count, sumHumdity/count);
});

child.on('close', function(code) {
    console.log('Exited with code: ${code}')
});

child.stderr.on('data', function (data) {
    console.log('stderr: ' + data);
});

function postData(temp, humidity){
    var obj = {}
    obj.temp = temp
    obj.humidity = humidity
    obj.dateOfOccurance = moment().format()
    obj.deviceId = deviceId

    console.log('posting this: ', JSON.stringify(obj))
    unirest.post(baseUrl)
        .headers({'Accept': 'application/json', 'Content-Type': 'application/json'})
        .send(obj)
        .end(function (response) {
            console.log("Response: ", response.body);
        });
}

function jsonString(str) {
    try {
        return JSON.parse(str)
    } catch (e) {
        return null
    }
}<|endoftext|>


<commit_before>/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * This module provides generic DB functions for performing SQL queries.
 *
 * @module JS API: low level database access
 */

const sqlite = require('sqlite3')
const fs = require('fs')
const env = require('../util/env.js')
const util = require('../util/util.js')
const dbEnum = require('./db-enum.js')

/**
 * Returns a promise to begin a transaction
 *
 * @export
 * @param {*} db
 * @returns A promise that resolves without an argument and rejects with an error from BEGIN TRANSACTION query.
 */
function dbBeginTransaction(db) {
  return new Promise((resolve, reject) => {
    db.run('BEGIN TRANSACTION', [], function (err) {
      if (err) {
        env.logError('Failed to BEGIN TRANSACTION')
        reject(err)
      } else {
        env.logSql('Executed BEGIN TRANSACTION')
        resolve()
      }
    })
  })
}
exports.dbBeginTransaction = dbBeginTransaction

/**
 * Returns a promise to execute a commit.
 *
 * @export
 * @param {*} db
 * @returns A promise that resolves without an argument or rejects with an error from COMMIT query.
 */
function dbCommit(db) {
  return new Promise((resolve, reject) => {
    db.run('COMMIT', [], function (err) {
      if (err) {
        env.logError('Failed to COMMIT')
        reject(err)
      } else {
        env.logSql('Executed COMMIT')
        resolve()
      }
    })
  })
}
exports.dbCommit = dbCommit

/**
 * Returns a promise to execute a DELETE FROM query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolve with the number of delete rows, or rejects with an error from query.
 */
function dbRemove(db, query, args) {
  return new Promise((resolve, reject) => {
    db.run(query, args, function (err) {
      if (err) {
        env.logError(`Failed remove: ${query}: ${args}`)
        reject(err)
      } else {
        env.logSql(`Executed remove: ${query}: ${args}`)
        resolve(this.changes)
      }
    })
  })
}
exports.dbRemove = dbRemove

/**
 * Returns a promise to execute an update query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolves without an argument, or rejects with an error from the query.
 */
function dbUpdate(db, query, args) {
  return new Promise((resolve, reject) => {
    db.run(query, args, function (err) {
      if (err) {
        env.logError(`Failed update: ${query}: ${args}`)
        reject(err)
      } else {
        env.logSql(`Executed update: ${query}: ${args}`)
        resolve()
      }
    })
  })
}
exports.dbUpdate = dbUpdate

/**
 * Returns a promise to execute an insert query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolves with the rowid from the inserted row, or rejects with an error from the query.
 */
function dbInsert(db, query, args) {
  return new Promise((resolve, reject) => {
    db.run(query, args, function (err) {
      if (err) {
        env.logError(`Failed insert: ${query}: ${args} : ${err}`)
        reject(err)
      } else {
        env.logSql(
          `Executed insert: ${query}: ${args} => rowid: ${this.lastID}`
        )
        resolve(this.lastID)
      }
    })
  })
}
exports.dbInsert = dbInsert

/**
 * Returns a promise to execute a query to perform a select that returns all rows that match a query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolves with the rows that got retrieved from the database, or rejects with an error from the query.
 */
function dbAll(db, query, args) {
  return new Promise((resolve, reject) => {
    db.all(query, args, (err, rows) => {
      if (err) {
        env.logSql(`Failed all: ${query}: ${args} : ${err}`)
        reject(err)
      } else {
        env.logSql(`Executed all: ${query}: ${args}`)
        resolve(rows)
      }
    })
  })
}
exports.dbAll = dbAll

/**
 * Returns a promise to execute a query to perform a select that returns first row that matches a query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolves with a single row that got retrieved from the database, or rejects with an error from the query.
 */
function dbGet(db, query, args) {
  return new Promise((resolve, reject) => {
    db.get(query, args, (err, row) => {
      if (err) {
        env.logError(`Failed get: ${query}: ${args} : ${err}`)
        reject(err)
      } else {
        env.logSql(`Executed get: ${query}: ${args}`)
        resolve(row)
      }
    })
  })
}
exports.dbGet = dbGet

/**
 * Returns a promise to perform a prepared statement, using data from array for SQL parameters.
 * It resolves with an array of rows, containing the data, or rejects with an error.
 *
 * @param {*} db
 * @param {*} sql
 * @param {*} arrayOfArrays
 */
function dbMultiSelect(db, sql, arrayOfArrays) {
  return new Promise((resolve, reject) => {
    env.logSql(
      `Preparing statement: ${sql} to select ${arrayOfArrays.length} rows.`
    )
    var rows = []
    var statement = db.prepare(sql, function (err) {
      if (err) reject(err)
      for (const singleArray of arrayOfArrays) {
        statement.get(singleArray, (err, row) => {
          if (err) {
            reject(err)
          } else {
            rows.push(row)
          }
        })
      }
      statement.finalize((err) => {
        if (err) {
          reject(err)
        } else {
          resolve(rows)
        }
      })
    })
  })
}
exports.dbMultiSelect = dbMultiSelect

/**
 * Returns a promise to perfom a prepared statement, using data from array for SQL parameters.
 * It resolves with an array of rowids, or rejects with an error.
 *
 * @export
 * @param {*} db
 * @param {*} sql
 * @param {*} arrayOfArrays
 * @returns A promise that resolves with the array of rowids for the rows that got inserted, or rejects with an error from the query.
 */
function dbMultiInsert(db, sql, arrayOfArrays) {
  return new Promise((resolve, reject) => {
    env.logSql(
      `Preparing statement: ${sql} to insert ${arrayOfArrays.length} records.`
    )
    var lastIds = []
    var statement = db.prepare(sql, function (err) {
      if (err) reject(err)
      for (const singleArray of arrayOfArrays) {
        statement.run(singleArray, (err) => {
          if (err) reject(err)
          lastIds.push(this.lastID)
        })
      }
      statement.finalize((err) => {
        if (err) reject(err)
        resolve(lastIds)
      })
    })
  })
}
exports.dbMultiInsert = dbMultiInsert

/**
 * Returns a promise that will resolve when the database in question is closed.
 * Rejects with an error if closing fails.
 *
 * @export
 * @param {*} database
 * @returns A promise that resolves without an argument or rejects with error from the database closing.
 */
function closeDatabase(database) {
  return new Promise((resolve, reject) => {
    env.logSql('About to close database.')
    database.close((err) => {
      if (err) return reject(err)
      env.logSql('Database is closed.')
      resolve()
    })
  })
}
exports.closeDatabase = closeDatabase

/**
 * Returns a promise to initialize a database.
 *
 * @export
 * @param {*} sqlitePath
 * @returns A promise that resolves with the database object that got created, or rejects with an error if something went wrong.
 */
function initDatabase(sqlitePath) {
  return new Promise((resolve, reject) => {
    var db = new sqlite.Database(sqlitePath, (err) => {
      if (err) {
        return reject(err)
      } else {
        env.logSql(`Connected to the database at: ${sqlitePath}`)
        resolve(db)
      }
    })
  })
}
exports.initDatabase = initDatabase

/**
 * Returns a promise to insert or replace a setting into the database.
 *
 * @param {*} db
 * @param {*} version
 * @returns  A promise that resolves with a rowid of created setting row or rejects with error if something goes wrong.
 */
function insertOrReplaceSetting(db, category, key, value) {
  return dbInsert(
    db,
    'INSERT OR REPLACE INTO SETTING ( CATEGORY, KEY, VALUE ) VALUES ( ?, ?, ? )',
    [category, key, value]
  )
}

function determineIfSchemaShouldLoad(db, context) {
  return new Promise((resolve, reject) => {
    return dbGet(db, 'SELECT CRC FROM PACKAGE WHERE PATH = ?', [
      context.filePath,
    ])
      .then((row) => {
        if (row == null) {
          context.mustLoad = true
        } else {
          context.mustLoad = row.CRC != context.crc
        }
        resolve(context)
      })
      .catch((err) => {
        // Fall through, do nothing
        context.mustLoad = true
        resolve(context)
      })
  })
}

function updateCurrentSchemaCrc(db, context) {
  return new Promise((resolve, reject) => {
    dbInsert(
      db,
      'INSERT OR REPLACE INTO PACKAGE (PATH, CRC, TYPE) VALUES ( ?, ?, ? )',
      [context.filePath, context.crc, dbEnum.packageType.sqlSchema]
    ).then(() => {
      resolve(context)
    })
  })
}

/**
 * Returns a promise to load schema into a blank database, and inserts a version to the settings table.j
 *
 * @export
 * @param {*} db
 * @param {*} schemaPath
 * @param {*} appVersion
 * @returns A promise that resolves with the same db that got passed in, or rejects with an error.
 */
function loadSchema(db, schemaPath, appVersion) {
  return new Promise((resolve, reject) => {
    fs.readFile(schemaPath, 'utf8', (err, data) => {
      if (err) return reject(err)
      resolve(data)
    })
  })
    .then((data) => util.calculateCrc({ filePath: schemaPath, data: data }))
    .then((context) => determineIfSchemaShouldLoad(db, context))
    .then(
      (context) =>
        new Promise((resolve, reject) => {
          if (context.mustLoad) {
            env.logSql('Schema load: must be done.')
            db.serialize(() => {
              db.exec(context.data, (err) => {
                if (err) {
                  env.logError('Failed to populate schema')
                  env.logError(err)
                  reject(err)
                }
                resolve(context)
              })
            })
          } else {
            env.logSql('Schema load: skipped.')
            resolve(context)
          }
        })
    )
    .then((context) => updateCurrentSchemaCrc(db, context))
    .then((context) => insertOrReplaceSetting(db, 'APP', 'VERSION', appVersion))
    .then((rowid) => Promise.resolve(db))
}
exports.loadSchema = loadSchema
<commit_msg>Stop reporting on an expected failure.<commit_after>/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * This module provides generic DB functions for performing SQL queries.
 *
 * @module JS API: low level database access
 */

const sqlite = require('sqlite3')
const fs = require('fs')
const env = require('../util/env.js')
const util = require('../util/util.js')
const dbEnum = require('./db-enum.js')

/**
 * Returns a promise to begin a transaction
 *
 * @export
 * @param {*} db
 * @returns A promise that resolves without an argument and rejects with an error from BEGIN TRANSACTION query.
 */
function dbBeginTransaction(db) {
  return new Promise((resolve, reject) => {
    db.run('BEGIN TRANSACTION', [], function (err) {
      if (err) {
        env.logError('Failed to BEGIN TRANSACTION')
        reject(err)
      } else {
        env.logSql('Executed BEGIN TRANSACTION')
        resolve()
      }
    })
  })
}
exports.dbBeginTransaction = dbBeginTransaction

/**
 * Returns a promise to execute a commit.
 *
 * @export
 * @param {*} db
 * @returns A promise that resolves without an argument or rejects with an error from COMMIT query.
 */
function dbCommit(db) {
  return new Promise((resolve, reject) => {
    db.run('COMMIT', [], function (err) {
      if (err) {
        env.logError('Failed to COMMIT')
        reject(err)
      } else {
        env.logSql('Executed COMMIT')
        resolve()
      }
    })
  })
}
exports.dbCommit = dbCommit

/**
 * Returns a promise to execute a DELETE FROM query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolve with the number of delete rows, or rejects with an error from query.
 */
function dbRemove(db, query, args) {
  return new Promise((resolve, reject) => {
    db.run(query, args, function (err) {
      if (err) {
        env.logError(`Failed remove: ${query}: ${args}`)
        reject(err)
      } else {
        env.logSql(`Executed remove: ${query}: ${args}`)
        resolve(this.changes)
      }
    })
  })
}
exports.dbRemove = dbRemove

/**
 * Returns a promise to execute an update query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolves without an argument, or rejects with an error from the query.
 */
function dbUpdate(db, query, args) {
  return new Promise((resolve, reject) => {
    db.run(query, args, function (err) {
      if (err) {
        env.logError(`Failed update: ${query}: ${args}`)
        reject(err)
      } else {
        env.logSql(`Executed update: ${query}: ${args}`)
        resolve()
      }
    })
  })
}
exports.dbUpdate = dbUpdate

/**
 * Returns a promise to execute an insert query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolves with the rowid from the inserted row, or rejects with an error from the query.
 */
function dbInsert(db, query, args) {
  return new Promise((resolve, reject) => {
    db.run(query, args, function (err) {
      if (err) {
        env.logError(`Failed insert: ${query}: ${args} : ${err}`)
        reject(err)
      } else {
        env.logSql(
          `Executed insert: ${query}: ${args} => rowid: ${this.lastID}`
        )
        resolve(this.lastID)
      }
    })
  })
}
exports.dbInsert = dbInsert

/**
 * Returns a promise to execute a query to perform a select that returns all rows that match a query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolves with the rows that got retrieved from the database, or rejects with an error from the query.
 */
function dbAll(db, query, args) {
  return new Promise((resolve, reject) => {
    db.all(query, args, (err, rows) => {
      if (err) {
        env.logSql(`Failed all: ${query}: ${args} : ${err}`)
        reject(err)
      } else {
        env.logSql(`Executed all: ${query}: ${args}`)
        resolve(rows)
      }
    })
  })
}
exports.dbAll = dbAll

/**
 * Returns a promise to execute a query to perform a select that returns first row that matches a query.
 *
 * @export
 * @param {*} db
 * @param {*} query
 * @param {*} args
 * @returns A promise that resolves with a single row that got retrieved from the database, or rejects with an error from the query.
 */
function dbGet(db, query, args, reportError = true) {
  return new Promise((resolve, reject) => {
    db.get(query, args, (err, row) => {
      if (err) {
        if (reportError) env.logError(`Failed get: ${query}: ${args} : ${err}`)
        reject(err)
      } else {
        env.logSql(`Executed get: ${query}: ${args}`)
        resolve(row)
      }
    })
  })
}
exports.dbGet = dbGet

/**
 * Returns a promise to perform a prepared statement, using data from array for SQL parameters.
 * It resolves with an array of rows, containing the data, or rejects with an error.
 *
 * @param {*} db
 * @param {*} sql
 * @param {*} arrayOfArrays
 */
function dbMultiSelect(db, sql, arrayOfArrays) {
  return new Promise((resolve, reject) => {
    env.logSql(
      `Preparing statement: ${sql} to select ${arrayOfArrays.length} rows.`
    )
    var rows = []
    var statement = db.prepare(sql, function (err) {
      if (err) reject(err)
      for (const singleArray of arrayOfArrays) {
        statement.get(singleArray, (err, row) => {
          if (err) {
            reject(err)
          } else {
            rows.push(row)
          }
        })
      }
      statement.finalize((err) => {
        if (err) {
          reject(err)
        } else {
          resolve(rows)
        }
      })
    })
  })
}
exports.dbMultiSelect = dbMultiSelect

/**
 * Returns a promise to perfom a prepared statement, using data from array for SQL parameters.
 * It resolves with an array of rowids, or rejects with an error.
 *
 * @export
 * @param {*} db
 * @param {*} sql
 * @param {*} arrayOfArrays
 * @returns A promise that resolves with the array of rowids for the rows that got inserted, or rejects with an error from the query.
 */
function dbMultiInsert(db, sql, arrayOfArrays) {
  return new Promise((resolve, reject) => {
    env.logSql(
      `Preparing statement: ${sql} to insert ${arrayOfArrays.length} records.`
    )
    var lastIds = []
    var statement = db.prepare(sql, function (err) {
      if (err) reject(err)
      for (const singleArray of arrayOfArrays) {
        statement.run(singleArray, (err) => {
          if (err) reject(err)
          lastIds.push(this.lastID)
        })
      }
      statement.finalize((err) => {
        if (err) reject(err)
        resolve(lastIds)
      })
    })
  })
}
exports.dbMultiInsert = dbMultiInsert

/**
 * Returns a promise that will resolve when the database in question is closed.
 * Rejects with an error if closing fails.
 *
 * @export
 * @param {*} database
 * @returns A promise that resolves without an argument or rejects with error from the database closing.
 */
function closeDatabase(database) {
  return new Promise((resolve, reject) => {
    env.logSql('About to close database.')
    database.close((err) => {
      if (err) return reject(err)
      env.logSql('Database is closed.')
      resolve()
    })
  })
}
exports.closeDatabase = closeDatabase

/**
 * Returns a promise to initialize a database.
 *
 * @export
 * @param {*} sqlitePath
 * @returns A promise that resolves with the database object that got created, or rejects with an error if something went wrong.
 */
function initDatabase(sqlitePath) {
  return new Promise((resolve, reject) => {
    var db = new sqlite.Database(sqlitePath, (err) => {
      if (err) {
        return reject(err)
      } else {
        env.logSql(`Connected to the database at: ${sqlitePath}`)
        resolve(db)
      }
    })
  })
}
exports.initDatabase = initDatabase

/**
 * Returns a promise to insert or replace a setting into the database.
 *
 * @param {*} db
 * @param {*} version
 * @returns  A promise that resolves with a rowid of created setting row or rejects with error if something goes wrong.
 */
function insertOrReplaceSetting(db, category, key, value) {
  return dbInsert(
    db,
    'INSERT OR REPLACE INTO SETTING ( CATEGORY, KEY, VALUE ) VALUES ( ?, ?, ? )',
    [category, key, value]
  )
}

function determineIfSchemaShouldLoad(db, context) {
  return new Promise((resolve, reject) => {
    return dbGet(
      db,
      'SELECT CRC FROM PACKAGE WHERE PATH = ?',
      [context.filePath],
      false
    )
      .then((row) => {
        if (row == null) {
          context.mustLoad = true
        } else {
          context.mustLoad = row.CRC != context.crc
        }
        resolve(context)
      })
      .catch((err) => {
        // Fall through, do nothing
        context.mustLoad = true
        resolve(context)
      })
  })
}

function updateCurrentSchemaCrc(db, context) {
  return new Promise((resolve, reject) => {
    dbInsert(
      db,
      'INSERT OR REPLACE INTO PACKAGE (PATH, CRC, TYPE) VALUES ( ?, ?, ? )',
      [context.filePath, context.crc, dbEnum.packageType.sqlSchema]
    ).then(() => {
      resolve(context)
    })
  })
}

/**
 * Returns a promise to load schema into a blank database, and inserts a version to the settings table.j
 *
 * @export
 * @param {*} db
 * @param {*} schemaPath
 * @param {*} appVersion
 * @returns A promise that resolves with the same db that got passed in, or rejects with an error.
 */
function loadSchema(db, schemaPath, appVersion) {
  return new Promise((resolve, reject) => {
    fs.readFile(schemaPath, 'utf8', (err, data) => {
      if (err) return reject(err)
      resolve(data)
    })
  })
    .then((data) => util.calculateCrc({ filePath: schemaPath, data: data }))
    .then((context) => determineIfSchemaShouldLoad(db, context))
    .then(
      (context) =>
        new Promise((resolve, reject) => {
          if (context.mustLoad) {
            env.logSql('Schema load: must be done.')
            db.serialize(() => {
              db.exec(context.data, (err) => {
                if (err) {
                  env.logError('Failed to populate schema')
                  env.logError(err)
                  reject(err)
                }
                resolve(context)
              })
            })
          } else {
            env.logSql('Schema load: skipped.')
            resolve(context)
          }
        })
    )
    .then((context) => updateCurrentSchemaCrc(db, context))
    .then((context) => insertOrReplaceSetting(db, 'APP', 'VERSION', appVersion))
    .then((rowid) => Promise.resolve(db))
}
exports.loadSchema = loadSchema
<|endoftext|>


<commit_before>// array : homogenous collection of values

export default class arrays {
    constructor() {
        var numbers = [1, 2, 3, 4, 5];
        console.log("first element", numbers[0]);

        //array.length property
        console.log("array length", numbers.length);

        //Array object
        var arrayNew = new Array(5);
        for (let index; index < arrayNew.length; index++) {
            arrayNew[index] = index * 2;
            console.log(arrayNew[index]);
        }

        //array constructor accepts comma separated values
        var employees = new Array('person1', 'person2', 'person3');

        //ES6 Array Methods
        //Array.prototype.find : iterates through array, find first element which
        //satisfy given condition in callback function
        var number = [2, 3, 4, 5, 6];
        var oddNumber = number.find((x) => x % 2 == 1);
        console.log("array oddNumber", oddNumber);

        //Array.prototype.findIndex : return index of element
        var numberIndex = [5, 5, 3, 2, 5, 6];
        var oddNumberIndex = numberIndex.findIndex((x) => x % 2 == 1);
        console.log("array index of oddNumber", oddNumberIndex);
    }
}<commit_msg>Array<commit_after>// array : homogenous collection of values

export default class arrays {
    constructor() {
        var numbers = [1, 2, 3, 4, 5];
        console.log("first element", numbers[0]);

        //array.length property
        console.log("array length", numbers.length);

        //Array object
        var arrayNew = new Array(5);
        for (let index; index < arrayNew.length; index++) {
            arrayNew[index] = index * 2;
            console.log(arrayNew[index]);
        }

        //array constructor accepts comma separated values
        var employees = new Array('person1', 'person2', 'person3');

        //ES6 Array Methods
        //Array.prototype.find : iterates through array, find first element which
        //satisfy given condition in callback function
        var number = [2, 3, 4, 5, 6],
            oddNumber = number.find((x) => x % 2 == 1);
        console.log("array oddNumber", oddNumber);

        //Array.prototype.findIndex : return index of element
        var numberIndex = [5, 5, 3, 2, 5, 6],
            oddNumberIndex = numberIndex.findIndex((x) => x % 2 == 1);
        console.log("array index of oddNumber", oddNumberIndex);

        //Array.prototype.entries : returns array of arrays
        // : child array [index, value]
        var arrayEntries = [1, 2, 3],
            resultArray = arrayEntries.entries();
        console.log("array Entries - 1", resultArray.next().value);
        console.log("array Entries - 2", [...resultArray]);

        //Array.from : create array from array like values, object, Iterables : Set/Map
        var Str1 = "Hello Ankit",
            arrayFrom = Array.from(Str1);
        for (let index of arrayFrom) {
            console.log("arrayFrom", index);
        }

        //Array.from.keys() : returns the array indexes
        var arrayKeys = Array.from(arrayFrom.keys());
        console.log("Array.from.keys()", arrayKeys);

        // destructure the array and store in individual variable
        var arrayDestruct = ['a', 'b', 'c'],
            [x, y, z] = arrayDestruct;
        console.log("arrayDestruct x", x);
        console.log("arrayDestruct y", y);

    }
}<|endoftext|>


<commit_before>//= require jquery/jquery
//= require jquery-mobile-events/jquery-mobile-events
//= require underscore/underscore
//= require backbone/backbone
//= require config
//= require request-animation-frame-polyfill
//= require player
//= require player-collection
//= require drawer
//= require assets

(function () {
  'use strict';

  var $ = window.jQuery;
  var _ = window._;
  var config = window.config;
  var io = window.io;

  var app = window.app = {

    users: window.NodeKick.PlayerCollection,

    socketReady: function () {
      app.socket.on('step', app.updateUsers);
    },

    domReady: function () {
      $('html').addClass(config.mobile ? 'js-mobile' : 'js-desktop');
      NodeKick.Drawer.init();
      window.NodeKick.Assets.init();
    },

    draw: function() {

      if (!NodeKick.Drawer.canvas || !NodeKick.Assets.isLoaded) {
        console.log('assets not yet loaded');
        return; //DOM is not yet loaded or image assets have not loaded, so no need to draw yet!
      }

      NodeKick.Drawer.drawBackground();
      NodeKick.Drawer.drawUsers(this.users);
    },

    updateUsers: function (users) {
      _.each(users, function (user) {
        var obj = app.users[user.id];
        if (!obj) obj = app.users[user.id] = {};
        _.extend(obj, user);
      });
    },

    move: function (dir) {
      $.post('/move/' + dir);
      var $ack = $('.js-move-ack');
      $ack.removeClass('js-transition js-up js-left js-right')
        .addClass('js-flash js-' + dir)
        .height();
      $ack.addClass('js-transition').removeClass('js-flash');
    }
  };

  if (!config.mobile) {
    app.socket = io.connect();
    app.socket.on('connect', app.socketReady);
  }

  (function () {
    var x0, y0, dx, dy;
    $(document).on({
      touchstart: function (ev) {
        ev = ev.originalEvent;
        if (ev.touches.length !== 1) return;
        var touch = ev.touches[0];
        x0 = touch.screenX;
        y0 = touch.screenY;
      },
      touchmove: function (ev) {
        ev.preventDefault();
        ev = ev.originalEvent;
        if (ev.touches.length !== 1 || dx !== null || dy !== null) return;
        var touch = ev.touches[0];
        dx = touch.screenX - x0;
        dy = touch.screenY - y0;
        var rightLeft = dx > 0 ? 'right' : 'left';
        var downUp = dy > 0 ? 'down' : 'up';
        var val = Math.abs(dx) > Math.abs(dy) ? rightLeft : downUp;
        app.move(val === 'down' ? rightLeft : val);
      },
      touchend: function (ev) {
        if (!ev.originalEvent.touches.length) dx = dy = null;
      },
      keydown: function (ev) {
        switch (ev.which) {
        case 37:
        case 65:
          app.move('left');
          break;
        case 38:
        case 87:
          app.move('up');
          break;
        case 39:
        case 68:
          app.move('right');
        }
      }
    });
  })();

  $(app.domReady);

  function drawLoop() {
    window.requestAnimationFrame(drawLoop);
    app.draw();
  }

  drawLoop();

  // /* ====== TEMP: REMOVE WHEN WE HAVE LIVE SOCKET PEOPLE ======== */

  // console.log('stuff', window.NodeKick, app)

  var player1 = new window.NodeKick.Player('bob');
  player1.x = 70;
  player1.y = 0;
  player1.state = 'stand';
  player1.dir = -1;

  // console.log('the player', player1);

  var player2 = new window.NodeKick.Player('fred');
  player2.x = 500;
  player2.y = -300;
  player2.state = 'jump';
  player2.dir = 1;

  // app.users[player1.handle] = player1;
  // app.users[player2.handle] = player2;

  setInterval(function() {
    player2.x += 10;
  }, 100);

  // /* ============================================================ */

})();
<commit_msg>Remove test dummies<commit_after>//= require jquery/jquery
//= require jquery-mobile-events/jquery-mobile-events
//= require underscore/underscore
//= require backbone/backbone
//= require config
//= require request-animation-frame-polyfill
//= require player
//= require player-collection
//= require drawer
//= require assets

(function () {
  'use strict';

  var $ = window.jQuery;
  var _ = window._;
  var config = window.config;
  var io = window.io;

  var app = window.app = {

    users: window.NodeKick.PlayerCollection,

    socketReady: function () {
      app.socket.on('step', app.updateUsers);
    },

    domReady: function () {
      $('html').addClass(config.mobile ? 'js-mobile' : 'js-desktop');
      NodeKick.Drawer.init();
      window.NodeKick.Assets.init();
    },

    draw: function() {

      if (!NodeKick.Drawer.canvas || !NodeKick.Assets.isLoaded) {
        console.log('assets not yet loaded');
        return; //DOM is not yet loaded or image assets have not loaded, so no need to draw yet!
      }

      NodeKick.Drawer.drawBackground();
      NodeKick.Drawer.drawUsers(this.users);
    },

    updateUsers: function (users) {
      _.each(users, function (user) {
        var obj = app.users[user.id];
        if (!obj) obj = app.users[user.id] = {};
        _.extend(obj, user);
      });
    },

    move: function (dir) {
      $.post('/move/' + dir);
      var $ack = $('.js-move-ack');
      $ack.removeClass('js-transition js-up js-left js-right')
        .addClass('js-flash js-' + dir)
        .height();
      $ack.addClass('js-transition').removeClass('js-flash');
    }
  };

  if (!config.mobile) {
    app.socket = io.connect();
    app.socket.on('connect', app.socketReady);
  }

  (function () {
    var x0, y0, dx, dy;
    $(document).on({
      touchstart: function (ev) {
        ev = ev.originalEvent;
        if (ev.touches.length !== 1) return;
        var touch = ev.touches[0];
        x0 = touch.screenX;
        y0 = touch.screenY;
      },
      touchmove: function (ev) {
        ev.preventDefault();
        ev = ev.originalEvent;
        if (ev.touches.length !== 1 || dx !== null || dy !== null) return;
        var touch = ev.touches[0];
        dx = touch.screenX - x0;
        dy = touch.screenY - y0;
        var rightLeft = dx > 0 ? 'right' : 'left';
        var downUp = dy > 0 ? 'down' : 'up';
        var val = Math.abs(dx) > Math.abs(dy) ? rightLeft : downUp;
        app.move(val === 'down' ? rightLeft : val);
      },
      touchend: function (ev) {
        if (!ev.originalEvent.touches.length) dx = dy = null;
      },
      keydown: function (ev) {
        switch (ev.which) {
        case 37:
        case 65:
          app.move('left');
          break;
        case 38:
        case 87:
          app.move('up');
          break;
        case 39:
        case 68:
          app.move('right');
        }
      }
    });
  })();

  $(app.domReady);

  function drawLoop() {
    window.requestAnimationFrame(drawLoop);
    app.draw();
  }

  drawLoop();
})();
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Internet of Protocols Alliance (IOPA)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const FreeList = require('../util/freelist').FreeList,
    Events = require('events'),
    URL = require('url'),

    CancellationTokenSource = require('../util/cancellation').default,
    contextExtensionsAddTo = require('./contextExtensions').addTo,

    constants = require('./constants'),
    IOPA = constants.IOPA,
    SERVER = constants.SERVER,

    mergeContext = require('../util/shallow').mergeContext,
    cloneDoubleLayer = require('../util/shallow').cloneDoubleLayer,
    merge = require('../util/shallow').merge

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/* *********************************************************
 * IOPA CONTEXT
 * ********************************************************* */

/**
 * Represents IOPA Context object for any REST Request/Response
 * See http://iopa.io for further details
 *
 * @class IopaContext
 * @constructor
 */
function IopaContext() {
    return this;
}

/**
* Initialize blank IopaContext object
* Generic properties common to all server types included
*
* @method Init
*/
IopaContext.prototype.init = function init() {
    this[IOPA.Version] = "1.2";
    var _cancellationTokenSource = new CancellationTokenSource();
    this[SERVER.CancelTokenSource] = _cancellationTokenSource;
    this[SERVER.Capabilities] = {};
    this[IOPA.CancelToken] = _cancellationTokenSource.token;
    this[IOPA.Events] = new Events.EventEmitter();
    this[IOPA.Seq] = "#" + _nextSequence();
    return this;
};

// INITIALIZATION
contextExtensionsAddTo(IopaContext.prototype);

/**
 * Represents IopaContext Factory of up to 100 items
 *
 * @instance IopaContextFactory

 * @method alloc()  get new IopaContext from pool or by creation if none available; remember to call context.init();
 * @method free(context)   return IopaContext to the pool for reuse
 */
function Factory(options) {
    _classCallCheck(this, Factory);

    options = options || {};
    var size = options["factory.Size"] || 100;

    this._logger = options[SERVER.Logger] || console;

    this._factory = new FreeList('IopaContext', size, function () { return IopaContext.apply(Object.create(IopaContext.prototype)); });
}

Object.defineProperty(Factory.prototype, SERVER.Logger, {
    get: function () { return this._logger; },
    set: function (value) { this._logger = value; }
});

/**
* Create a new barebones IOPA Request with or without a response record
*/
Factory.prototype._create = function factory_create() {
    var context = this._factory.alloc().init();
    context.dispose = this._dispose.bind(this, context);
    context[SERVER.Logger] = this._logger;
    context[SERVER.Factory] = this;
     return context;
};

/**
* Release the memory used by a given IOPA Context
*
* @param context the context to free
*/
Factory.prototype._dispose = function factory_dispose(context) {
   if (context == null || context[SERVER.CancelTokenSource] == null)
        return;

 //  if (!(context[IOPA.CancelToken].isCancelled))
 //      context[SERVER.CancelTokenSource].cancel(IOPA.EVENTS.Finish);

    if (context.response) {
        var response = context.response;
        for (var prop in response) { if (response.hasOwnProperty(prop)) { response[prop] = null; } }
        this._factory.free(response);
    }

    for (var prop in context) { if (context.hasOwnProperty(prop)) { context[prop] = null; } };

    this._factory.free(context);
};

/**
* Create a new IOPA Context, with default [iopa.*] values populated
*/
Factory.prototype.createContext = function factory_createContext() {
    var context = this._create();
    var response = this._create();
    context.response = response;
    context.response[SERVER.ParentContext] = context;

    context[IOPA.Headers] = {};
    context[IOPA.Method] = "";
    context[IOPA.Host] = "";
    context[IOPA.Path] = "";
    context[IOPA.PathBase] = "";
    context[IOPA.Protocol] = "";
    context[IOPA.QueryString] = "";
    context[IOPA.Scheme] = "";
    context[IOPA.Body] = null;

    response[IOPA.Headers] = {};
    response[IOPA.StatusCode] = null;
    response[IOPA.ReasonPhrase] = "";
    response[IOPA.Protocol] = "";
    response[IOPA.Body] = null;
    response[IOPA.Headers]["Content-Length"] = null;

    return context;
};

/**
* Create a new IOPA Context, with default [iopa.*] values populated
*/
Factory.prototype.mergeCapabilities = function factory_mergeCapabilities(childContext, parentContext) {

    childContext[SERVER.ParentContext] = parentContext;
    merge(childContext[SERVER.Capabilities], cloneDoubleLayer(parentContext[SERVER.Capabilities]));

    if (childContext.response)
       merge(childContext.response[SERVER.Capabilities], cloneDoubleLayer(parentContext.response[SERVER.Capabilities]));

};

/**
* Create a new IOPA Context, with default [iopa.*] values populated
*/
Factory.prototype.createRequest = function createRequest(urlStr, options) {

    if (typeof options === 'string' || options instanceof String)
        options = { "iopa.Method": options };

    options = options || {};

    var context = this._create();
    context[SERVER.IsLocalOrigin] = true;
    context[SERVER.IsRequest] = true;
    context[SERVER.OriginalUrl] = urlStr;
    context[IOPA.Method] = options[IOPA.Method] || IOPA.METHODS.GET;

    var urlParsed = URL.parse(urlStr);
    context[IOPA.PathBase] = "";
    context[IOPA.Path] = urlParsed.pathname || "";
    context[IOPA.QueryString] = urlParsed.query;
    context[IOPA.Scheme] = urlParsed.protocol;
    context[SERVER.RemoteAddress] = urlParsed.hostname;
    context[IOPA.Host] = urlParsed.hostname;
    context[IOPA.Headers] = {};
    context[IOPA.Body] = null;

    const SCHEMES = IOPA.SCHEMES,
        PROTOCOLS = IOPA.PROTOCOLS,
        PORTS = IOPA.PORTS

    switch (urlParsed.protocol) {
        case SCHEMES.HTTP:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = false;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = urlParsed.port || PORTS.HTTP;
            break;
        case SCHEMES.HTTPS:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = true;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = urlParsed.port || PORTS.HTTPS;
            break;
        case SCHEMES.COAP:
            context[IOPA.Protocol] = PROTOCOLS.COAP;
            context[SERVER.TLS] = false;
            context[SERVER.RemotePort] = urlParsed.port || PORTS.COAP;
            break;
        case SCHEMES.COAPS:
            context[IOPA.Protocol] = PROTOCOLS.COAP;
            context[SERVER.TLS] = true;
            context[SERVER.RemotePort] = urlParsed.port || PORTS.COAPS;
            break;
        case SCHEMES.MQTT:
            context[IOPA.Protocol] = PROTOCOLS.MQTT;
            context[SERVER.TLS] = false;
            context[SERVER.RemotePort] = urlParsed.port || PORTS.MQTT;
            break;
        case SCHEMES.MQTTS:
            context[IOPA.Protocol] = PROTOCOLS.MQTT;
            context[SERVER.TLS] = true;
            context[SERVER.RemotePort] = urlParsed.port || PORTS.MQTTS;
            break;
        default:
            context[IOPA.Protocol] = urlParsed.protocol;
            context[SERVER.TLS] = false;
            context[SERVER.RemotePort] = urlParsed.port || 0;
    };

    mergeContext(context, options);

    return context;
};

/**
* Create a new IOPA Context, with default [iopa.*] values populated
*/
Factory.prototype.createRequestResponse = function createRequestResponse(urlStr, options) {
    var context = this.createRequest(urlStr, options);

    var response = this._create();
    context.response = response;
    context.response[SERVER.ParentContext] = context;

    response[IOPA.Headers] = {};
    response[IOPA.StatusCode] = null;
    response[IOPA.ReasonPhrase] = "";
    response[IOPA.Protocol] = context[IOPA.Protocol];
    response[IOPA.Body] = null;
    response[SERVER.TLS] = context[SERVER.TLS];
    response[SERVER.RemoteAddress] = context[SERVER.RemoteAddress];
    response[SERVER.RemotePort] = context[SERVER.RemotePort];
    response[SERVER.IsLocalOrigin] = false;
    response[SERVER.IsRequest] = false;
    response[SERVER.Logger] = context[SERVER.Logger];

    return context;
}

const maxSequence = Math.pow(2, 16);
var _lastSequence = Math.floor(Math.random() * (maxSequence - 1));

function _nextSequence() {
    if (++_lastSequence === maxSequence)
        _lastSequence = 1;

    return _lastSequence.toString();
};

// EXPORTS
exports.default = Factory;<commit_msg>dev test<commit_after>/*
 * Copyright (c) 2015 Internet of Protocols Alliance (IOPA)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const FreeList = require('../util/freelist').FreeList,
    Events = require('events'),
    URL = require('url'),

    CancellationTokenSource = require('../util/cancellation').default,
    contextExtensionsAddTo = require('./contextExtensions').addTo,

    constants = require('./constants'),
    IOPA = constants.IOPA,
    SERVER = constants.SERVER,

    mergeContext = require('../util/shallow').mergeContext,
    cloneDoubleLayer = require('../util/shallow').cloneDoubleLayer,
    merge = require('../util/shallow').merge

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/* *********************************************************
 * IOPA CONTEXT
 * ********************************************************* */

/**
 * Represents IOPA Context object for any REST Request/Response
 * See http://iopa.io for further details
 *
 * @class IopaContext
 * @constructor
 */
function IopaContext() {
    return this;
}

/**
* Initialize blank IopaContext object
* Generic properties common to all server types included
*
* @method Init
*/
IopaContext.prototype.init = function init() {
    this[IOPA.Version] = "1.2";
    var _cancellationTokenSource = new CancellationTokenSource();
    this[SERVER.CancelTokenSource] = _cancellationTokenSource;
    this[SERVER.Capabilities] = {};
    this[IOPA.CancelToken] = _cancellationTokenSource.token;
    this[IOPA.Events] = new Events.EventEmitter();
    this[IOPA.Seq] = "#" + _nextSequence();
    return this;
};

// INITIALIZATION
contextExtensionsAddTo(IopaContext.prototype);

/**
 * Represents IopaContext Factory of up to 100 items
 *
 * @instance IopaContextFactory

 * @method alloc()  get new IopaContext from pool or by creation if none available; remember to call context.init();
 * @method free(context)   return IopaContext to the pool for reuse
 */
function Factory(options) {
    _classCallCheck(this, Factory);

    options = options || {};
    var size = options["factory.Size"] || 100;

    this._logger = options[SERVER.Logger] || console;

    this._factory = new FreeList('IopaContext', size, function () { return IopaContext.apply(Object.create(IopaContext.prototype)); });
}

Object.defineProperty(Factory.prototype, SERVER.Logger, {
    get: function () { return this._logger; },
    set: function (value) { this._logger = value; }
});

/**
* Create a new barebones IOPA Request with or without a response record
*/
Factory.prototype._create = function factory_create() {
    var context = this._factory.alloc().init();
    context.dispose = this._dispose.bind(this, context);
    context[SERVER.Logger] = this._logger;
    context[SERVER.Factory] = this;
     return context;
};

/**
* Release the memory used by a given IOPA Context
*
* @param context the context to free
*/
Factory.prototype._dispose = function factory_dispose(context) {
   if (context == null || context[SERVER.CancelTokenSource] == null)
        return;

 //  if (!(context[IOPA.CancelToken].isCancelled))
 //      context[SERVER.CancelTokenSource].cancel(IOPA.EVENTS.Finish);

    if (context.response) {
        var response = context.response;
        for (var prop in response) { if (response.hasOwnProperty(prop)) { response[prop] = null; } }
        this._factory.free(response);
    }

    for (var prop in context) { if (context.hasOwnProperty(prop)) { context[prop] = null; } };

    this._factory.free(context);
};

/**
* Create a new IOPA Context, with default [iopa.*] values populated
*/
Factory.prototype.createContext = function factory_createContext() {
    var context = this._create();
    var response = this._create();
    context.response = response;
    context.response[SERVER.ParentContext] = context;

    context[IOPA.Headers] = {};
    context[IOPA.Method] = "";
    context[IOPA.Host] = "";
    context[IOPA.Path] = "";
    context[IOPA.PathBase] = "";
    context[IOPA.Protocol] = "";
    context[IOPA.QueryString] = "";
    context[IOPA.Scheme] = "";
    context[IOPA.Body] = null;

    response[IOPA.Headers] = {};
    response[IOPA.StatusCode] = null;
    response[IOPA.ReasonPhrase] = "";
    response[IOPA.Protocol] = "";
    response[IOPA.Body] = null;
    response[IOPA.Headers]["Content-Length"] = null;

    return context;
};

/**
* Create a new IOPA Context, with default [iopa.*] values populated
*/
Factory.prototype.mergeCapabilities = function factory_mergeCapabilities(childContext, parentContext) {

    childContext[SERVER.ParentContext] = parentContext;
    merge(childContext[SERVER.Capabilities], cloneDoubleLayer(parentContext[SERVER.Capabilities]));

    if (childContext.response)
       merge(childContext.response[SERVER.Capabilities], cloneDoubleLayer(parentContext.response[SERVER.Capabilities]));

};

/**
* Create a new IOPA Context, with default [iopa.*] values populated
*/
Factory.prototype.createRequest = function createRequest(urlStr, options) {

    if (typeof options === 'string' || options instanceof String)
        options = { "iopa.Method": options };

    options = options || {};

    var context = this._create();
    context[SERVER.IsLocalOrigin] = true;
    context[SERVER.IsRequest] = true;
    context[SERVER.OriginalUrl] = urlStr;
    context[IOPA.Method] = options[IOPA.Method] || IOPA.METHODS.GET;

    var urlParsed = URL.parse(urlStr);
    context[IOPA.PathBase] = "";
    context[IOPA.Path] = urlParsed.pathname || "";
    context[IOPA.QueryString] = urlParsed.query;
    context[IOPA.Scheme] = urlParsed.protocol;
    context[SERVER.RemoteAddress] = urlParsed.hostname;
    context[IOPA.Host] = urlParsed.hostname;
    context[IOPA.Headers] = {};
    context[IOPA.Body] = null;

    const SCHEMES = IOPA.SCHEMES,
        PROTOCOLS = IOPA.PROTOCOLS,
        PORTS = IOPA.PORTS

    switch (urlParsed.protocol) {
        case SCHEMES.HTTP:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = false;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.HTTP;
            break;
        case SCHEMES.HTTPS:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = true;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.HTTPS;
            break;
        case SCHEMES.COAP:
            context[IOPA.Protocol] = PROTOCOLS.COAP;
            context[SERVER.TLS] = false;
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.HTTP;
            break;
        case SCHEMES.HTTPS:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = true;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.COAP;
            break;
        case SCHEMES.COAPS:
            context[IOPA.Protocol] = PROTOCOLS.COAP;
            context[SERVER.TLS] = true;
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.HTTP;
            break;
        case SCHEMES.HTTPS:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = true;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.COAPS;
            break;
        case SCHEMES.MQTT:
            context[IOPA.Protocol] = PROTOCOLS.MQTT;
            context[SERVER.TLS] = false;
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.HTTP;
            break;
        case SCHEMES.HTTPS:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = true;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.MQTT;
            break;
        case SCHEMES.MQTTS:
            context[IOPA.Protocol] = PROTOCOLS.MQTT;
            context[SERVER.TLS] = true;
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.HTTP;
            break;
        case SCHEMES.HTTPS:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = true;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.MQTTS;
            break;
        default:
            context[IOPA.Protocol] = urlParsed.protocol;
            context[SERVER.TLS] = false;
            context[SERVER.RemotePort] =parseInt(urlParsed.port) || PORTS.HTTP;
            break;
        case SCHEMES.HTTPS:
            context[IOPA.Protocol] = PROTOCOLS.HTTP;
            context[SERVER.TLS] = true;
            context[IOPA.Headers]["Host"] = context[IOPA.Host];
            context[SERVER.RemotePort] = parseInt(urlParsed.port) || PORTS.HTTPS;
    };

    mergeContext(context, options);

    return context;
};

/**
* Create a new IOPA Context, with default [iopa.*] values populated
*/
Factory.prototype.createRequestResponse = function createRequestResponse(urlStr, options) {
    var context = this.createRequest(urlStr, options);

    var response = this._create();
    context.response = response;
    context.response[SERVER.ParentContext] = context;

    response[IOPA.Headers] = {};
    response[IOPA.StatusCode] = null;
    response[IOPA.ReasonPhrase] = "";
    response[IOPA.Protocol] = context[IOPA.Protocol];
    response[IOPA.Body] = null;
    response[SERVER.TLS] = context[SERVER.TLS];
    response[SERVER.RemoteAddress] = context[SERVER.RemoteAddress];
    response[SERVER.RemotePort] = context[SERVER.RemotePort];
    response[SERVER.IsLocalOrigin] = false;
    response[SERVER.IsRequest] = false;
    response[SERVER.Logger] = context[SERVER.Logger];

    return context;
}

const maxSequence = Math.pow(2, 16);
var _lastSequence = Math.floor(Math.random() * (maxSequence - 1));

function _nextSequence() {
    if (++_lastSequence === maxSequence)
        _lastSequence = 1;

    return _lastSequence.toString();
};

// EXPORTS
exports.default = Factory;<|endoftext|>


<commit_before>//= require signature_pad
$( document ).ready(function() {

  var canvas = document.getElementById("JohnHancock-canvas"),
      hidden_field = document.getElementById("JohnHancock-hidden"),
      parent_form = $(canvas).closest("form"),
      signaturePad;

  signaturePad = new SignaturePad(canvas);

  $(parent_form).submit(function(e) {
    $(hidden_field).val(signaturePad.toDataURL());
  });
})
<commit_msg>Prevent js errors when canvas isn't present<commit_after>//= require signature_pad
$( document ).ready(function() {
  if(document.getElementById("JohnHancock-canvas")){
    var canvas = document.getElementById("JohnHancock-canvas"),
        hidden_field = document.getElementById("JohnHancock-hidden"),
        parent_form = $(canvas).closest("form"),
        signaturePad;

    signaturePad = new SignaturePad(canvas);

    $(parent_form).submit(function(e) {
      $(hidden_field).val(signaturePad.toDataURL());
    });
  }
})
<|endoftext|>