<commit_before>/*jslint es5:true*/

var ad = require('../config/ad.json');

var ldapClient = require('../lib/ldap-client');

var mongoose = require('mongoose');
var User = mongoose.model('User');

var auth = require('../lib/auth');

var Roles = ['manager', 'admin'];

function addUser(req, res) {
  var nameFilter = ad.nameFilter.replace('_name', req.body.name);
  var opts = {
    filter: nameFilter,
    attributes: ad.objAttributes,
    scope: 'sub'
  };

  ldapClient.search(ad.searchBase, opts, false, function (err, result) {
    if (err) {
      console.error(err.name + ' : ' + err.message);
      return res.json(500, err);
    }

    if (result.length === 0) {
      return res.send(404, req.body.name + ' is not found in AD!');
    }

    if (result.length > 1) {
      return res.send(400, req.body.name + ' is not unique!');
    }

    var roles = [];
    if (req.body.manager) {
      roles.push('manager');
    }
    if (req.body.admin) {
      roles.push('admin');
    }

    var user = new User({
      adid: result[0].sAMAccountName,
      name: result[0].displayName,
      email: result[0].mail,
      office: result[0].physicalDeliveryOfficeName,
      phone: result[0].telephoneNumber,
      mobile: result[0].mobile,
      roles: roles
    });

    user.save(function (err, newUser) {
      if (err) {
        if (err.message) {
          console.error(err);
          return res.send(500, err.message);
        }
        console.log(err);
        return res.send(500, 'cannot save the new user in db.');
      }

      var url = req.protocol + '://' + req.get('host') + '/users/' + newUser.adid;
      res.set('Location', url);
      res.send(201, 'The new user is at here');
    });

  });
}

function updateUserProfile(user, res) {
  var searchFilter = ad.searchFilter.replace('_id', user.adid);
  var opts = {
    filter: searchFilter,
    attributes: ad.objAttributes,
    scope: 'sub'
  };
  ldapClient.search(ad.searchBase, opts, false, function (err, result) {
    if (err) {
      return res.json(500, err);
    }
    if (result.length === 0) {
      return res.json(500, {
        error: user.adid + ' is not found!'
      });
    }
    if (result.length > 1) {
      return res.json(500, {
        error: user.adid + ' is not unique!'
      });
    }
    var update = {
      name: result[0].displayName,
      email: result[0].mail,
      office: result[0].physicalDeliveryOfficeName,
      phone: result[0].telephoneNumber
    };

    if (result[0].mobile !== undefined) {
      update.mobile = result[0].mobile;
    }

    user.update(update, function (err) {
      if (err) {
        return res.json(500, err);
      }
      res.send(204);
    });
  });
}

module.exports = function (app) {

  app.get('/users/', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, 'only admin allowed');
    }
    return res.render('users');
  });

  app.get('/usernames/:name', auth.ensureAuthenticated, function (req, res) {
    User.findOne({
      name: req.params.name
    }).lean().exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (user) {
        return res.render('user', {
          user: user,
          myRoles: req.session.roles
        });
      }
      return res.send(404, req.params.name + ' not found');
    });
  });

  app.post('/users/', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, 'only admin allowed');
    }

    if (!req.body.name) {
      return res.send(400, 'need to know name');
    }

    // check if already in db
    User.findOne({
      name: req.body.name
    }).lean().exec(function (err, user) {
      if (err) {
        return res.send(500, err.message);
      }
      if (user) {
        var url = req.protocol + '://' + req.get('host') + '/users/' + user.adid;
        return res.send(200, 'The user is at ' + url);
      }
      addUser(req, res);
    });
  });

  app.get('/users/json', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    User.find().lean().exec(function (err, users) {
      if (err) {
        console.error(err);
        return res.json(500, {
          error: err.message
        });
      }
      res.json(users);
    });
  });

  app.get('/users/:id/', auth.ensureAuthenticated, function (req, res) {
    User.findOne({
      adid: req.params.id
    }).lean().exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (user) {
        return res.render('user', {
          user: user,
          myRoles: req.session.roles
        });
      }
      return res.send(404, req.params.id + ' has never logged into the application.');
    });
  });

  app.put('/users/:id/', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    if (!req.is('json')) {
      return res.send(415, 'json request expected.');
    }
    User.findOneAndUpdate({
      adid: req.params.id
    }, req.body).lean().exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.json(500, {
          error: err.message
        });
      }
      if (user) {
        return res.send(204);
      }
      return res.send(404, 'cannot find user ' + req.params.id);
    });
  });

  app.post('/users/:id/wbs/', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    if (!req.is('json')) {
      return res.send(415, 'json request expected.');
    }
    User.findOne({
      adid: req.params.id
    }).exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (!user) {
        return res.send(404, 'cannot find user ' + req.params.id);
      }
      if (user.wbs === undefined) {
        user.wbs = [];
      }
      user.wbs.addToSet(req.body.newwbs);
      user.save(function (err) {
        if (err) {
          console.error(err);
          return res.send(500, err.message);
        }
        return res.send(201, req.body.newwbs + ' was added to the wbs list.');
      });
    });
  });

  app.delete('/users/:id/wbs/:wbs', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    User.findOne({
      adid: req.params.id
    }).exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (!user) {
        return res.send(404, 'cannot find user ' + req.params.id);
      }
      if (user.wbs === undefined) {
        return res.send(204);
      }
      user.wbs.pull(req.params.wbs);
      user.save(function (err) {
        if (err) {
          console.error(err);
          return res.send(500, err.message);
        }
        return res.send(204);
      });
    });
  });

  // get from the db not ad
  app.get('/users/:id/json', auth.ensureAuthenticated, function (req, res) {
    User.findOne({
      adid: req.params.id
    }).lean().exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.json(500, {
          error: err.mesage
        });
      }
      return res.json(user);
    });
  });

  app.get('/users/:id/refresh', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    User.findOne({
      adid: req.params.id
    }).exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (user) {
        updateUserProfile(user, res);
      } else {
        return res.send(404, req.params.id + ' is not in the application.');
      }
    });
  });

  // resource /adusers

  app.get('/adusers/:id/', auth.ensureAuthenticated, function (req, res) {

    var searchFilter = ad.searchFilter.replace('_id', req.params.id);
    var opts = {
      filter: searchFilter,
      attributes: ad.objAttributes,
      scope: 'sub'
    };
    ldapClient.search(ad.searchBase, opts, false, function (err, result) {
      if (err) {
        return res.json(500, err);
      }
      if (result.length === 0) {
        return res.json(500, {
          error: req.params.id + ' is not found!'
        });
      }
      if (result.length > 1) {
        return res.json(500, {
          error: req.params.id + ' is not unique!'
        });
      }

      return res.json(result[0]);
    });

  });

  app.get('/adusers/:id/photo', auth.ensureAuthenticated, function (req, res) {

    var searchFilter = ad.searchFilter.replace('_id', req.params.id);
    var opts = {
      filter: searchFilter,
      attributes: ad.rawAttributes,
      scope: 'sub'
    };
    ldapClient.search(ad.searchBase, opts, true, function (err, result) {
      if (err) {
        return res.json(500, err);
      }
      if (result.length === 0) {
        return res.json(500, {
          error: req.params.id + ' is not found!'
        });
      }
      if (result.length > 1) {
        return res.json(500, {
          error: req.params.id + ' is not unique!'
        });
      }
      res.set('Content-Type', 'image/jpeg');
      return res.send(result[0].thumbnailPhoto);
    });

  });

  app.get('/adusernames', auth.ensureAuthenticated, function (req, res) {
    var query = req.query.term;
    var nameFilter, opts;
    if (query && query.length > 0) {
      nameFilter = ad.nameFilter.replace('_name', query + '*');
    } else {
      nameFilter = ad.nameFilter.replace('_name', '*');
    }
    opts = {
      filter: nameFilter,
      attributes: ['displayName'],
      paged: {
        pageSize: 200
      },
      scope: 'sub'
    };
    ldapClient.search(ad.searchBase, opts, false, function (err, result) {
      if (err) {
        return res.json(500, JSON.stringify(err));
      }
      if (result.length === 0) {
        return res.json(500, {
          error: 'Names starting with ' + query + ' are not found!'
        });
      }
      return res.json(result);
    });
  });
};
<commit_msg>console err ldapjs<commit_after>/*jslint es5:true*/

var ad = require('../config/ad.json');

var ldapClient = require('../lib/ldap-client');

var mongoose = require('mongoose');
var User = mongoose.model('User');

var auth = require('../lib/auth');

var Roles = ['manager', 'admin'];

function addUser(req, res) {
  var nameFilter = ad.nameFilter.replace('_name', req.body.name);
  var opts = {
    filter: nameFilter,
    attributes: ad.objAttributes,
    scope: 'sub'
  };

  ldapClient.search(ad.searchBase, opts, false, function (err, result) {
    if (err) {
      console.error(err.name + ' : ' + err.message);
      return res.json(500, err);
    }

    if (result.length === 0) {
      return res.send(404, req.body.name + ' is not found in AD!');
    }

    if (result.length > 1) {
      return res.send(400, req.body.name + ' is not unique!');
    }

    var roles = [];
    if (req.body.manager) {
      roles.push('manager');
    }
    if (req.body.admin) {
      roles.push('admin');
    }

    var user = new User({
      adid: result[0].sAMAccountName,
      name: result[0].displayName,
      email: result[0].mail,
      office: result[0].physicalDeliveryOfficeName,
      phone: result[0].telephoneNumber,
      mobile: result[0].mobile,
      roles: roles
    });

    user.save(function (err, newUser) {
      if (err) {
        if (err.message) {
          console.error(err);
          return res.send(500, err.message);
        }
        console.log(err);
        return res.send(500, 'cannot save the new user in db.');
      }

      var url = req.protocol + '://' + req.get('host') + '/users/' + newUser.adid;
      res.set('Location', url);
      res.send(201, 'The new user is at here');
    });

  });
}

function updateUserProfile(user, res) {
  var searchFilter = ad.searchFilter.replace('_id', user.adid);
  var opts = {
    filter: searchFilter,
    attributes: ad.objAttributes,
    scope: 'sub'
  };
  ldapClient.search(ad.searchBase, opts, false, function (err, result) {
    if (err) {
      return res.json(500, err);
    }
    if (result.length === 0) {
      return res.json(500, {
        error: user.adid + ' is not found!'
      });
    }
    if (result.length > 1) {
      return res.json(500, {
        error: user.adid + ' is not unique!'
      });
    }
    var update = {
      name: result[0].displayName,
      email: result[0].mail,
      office: result[0].physicalDeliveryOfficeName,
      phone: result[0].telephoneNumber
    };

    if (result[0].mobile !== undefined) {
      update.mobile = result[0].mobile;
    }

    user.update(update, function (err) {
      if (err) {
        return res.json(500, err);
      }
      res.send(204);
    });
  });
}

module.exports = function (app) {

  app.get('/users/', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, 'only admin allowed');
    }
    return res.render('users');
  });

  app.get('/usernames/:name', auth.ensureAuthenticated, function (req, res) {
    User.findOne({
      name: req.params.name
    }).lean().exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (user) {
        return res.render('user', {
          user: user,
          myRoles: req.session.roles
        });
      }
      return res.send(404, req.params.name + ' not found');
    });
  });

  app.post('/users/', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, 'only admin allowed');
    }

    if (!req.body.name) {
      return res.send(400, 'need to know name');
    }

    // check if already in db
    User.findOne({
      name: req.body.name
    }).lean().exec(function (err, user) {
      if (err) {
        return res.send(500, err.message);
      }
      if (user) {
        var url = req.protocol + '://' + req.get('host') + '/users/' + user.adid;
        return res.send(200, 'The user is at ' + url);
      }
      addUser(req, res);
    });
  });

  app.get('/users/json', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    User.find().lean().exec(function (err, users) {
      if (err) {
        console.error(err);
        return res.json(500, {
          error: err.message
        });
      }
      res.json(users);
    });
  });

  app.get('/users/:id/', auth.ensureAuthenticated, function (req, res) {
    User.findOne({
      adid: req.params.id
    }).lean().exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (user) {
        return res.render('user', {
          user: user,
          myRoles: req.session.roles
        });
      }
      return res.send(404, req.params.id + ' has never logged into the application.');
    });
  });

  app.put('/users/:id/', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    if (!req.is('json')) {
      return res.send(415, 'json request expected.');
    }
    User.findOneAndUpdate({
      adid: req.params.id
    }, req.body).lean().exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.json(500, {
          error: err.message
        });
      }
      if (user) {
        return res.send(204);
      }
      return res.send(404, 'cannot find user ' + req.params.id);
    });
  });

  app.post('/users/:id/wbs/', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    if (!req.is('json')) {
      return res.send(415, 'json request expected.');
    }
    User.findOne({
      adid: req.params.id
    }).exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (!user) {
        return res.send(404, 'cannot find user ' + req.params.id);
      }
      if (user.wbs === undefined) {
        user.wbs = [];
      }
      user.wbs.addToSet(req.body.newwbs);
      user.save(function (err) {
        if (err) {
          console.error(err);
          return res.send(500, err.message);
        }
        return res.send(201, req.body.newwbs + ' was added to the wbs list.');
      });
    });
  });

  app.delete('/users/:id/wbs/:wbs', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    User.findOne({
      adid: req.params.id
    }).exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (!user) {
        return res.send(404, 'cannot find user ' + req.params.id);
      }
      if (user.wbs === undefined) {
        return res.send(204);
      }
      user.wbs.pull(req.params.wbs);
      user.save(function (err) {
        if (err) {
          console.error(err);
          return res.send(500, err.message);
        }
        return res.send(204);
      });
    });
  });

  // get from the db not ad
  app.get('/users/:id/json', auth.ensureAuthenticated, function (req, res) {
    User.findOne({
      adid: req.params.id
    }).lean().exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.json(500, {
          error: err.mesage
        });
      }
      return res.json(user);
    });
  });

  app.get('/users/:id/refresh', auth.ensureAuthenticated, function (req, res) {
    if (req.session.roles === undefined || req.session.roles.indexOf('admin') === -1) {
      return res.send(403, "You are not authorized to access this resource. ");
    }
    User.findOne({
      adid: req.params.id
    }).exec(function (err, user) {
      if (err) {
        console.error(err);
        return res.send(500, err.message);
      }
      if (user) {
        updateUserProfile(user, res);
      } else {
        return res.send(404, req.params.id + ' is not in the application.');
      }
    });
  });

  // resource /adusers

  app.get('/adusers/:id/', auth.ensureAuthenticated, function (req, res) {

    var searchFilter = ad.searchFilter.replace('_id', req.params.id);
    var opts = {
      filter: searchFilter,
      attributes: ad.objAttributes,
      scope: 'sub'
    };
    ldapClient.search(ad.searchBase, opts, false, function (err, result) {
      if (err) {
        return res.json(500, err);
      }
      if (result.length === 0) {
        return res.json(500, {
          error: req.params.id + ' is not found!'
        });
      }
      if (result.length > 1) {
        return res.json(500, {
          error: req.params.id + ' is not unique!'
        });
      }

      return res.json(result[0]);
    });

  });

  app.get('/adusers/:id/photo', auth.ensureAuthenticated, function (req, res) {

    var searchFilter = ad.searchFilter.replace('_id', req.params.id);
    var opts = {
      filter: searchFilter,
      attributes: ad.rawAttributes,
      scope: 'sub'
    };
    ldapClient.search(ad.searchBase, opts, true, function (err, result) {
      if (err) {
        return res.json(500, err);
      }
      if (result.length === 0) {
        return res.json(500, {
          error: req.params.id + ' is not found!'
        });
      }
      if (result.length > 1) {
        return res.json(500, {
          error: req.params.id + ' is not unique!'
        });
      }
      res.set('Content-Type', 'image/jpeg');
      return res.send(result[0].thumbnailPhoto);
    });

  });

  app.get('/adusernames', auth.ensureAuthenticated, function (req, res) {
    var query = req.query.term;
    var nameFilter, opts;
    if (query && query.length > 0) {
      nameFilter = ad.nameFilter.replace('_name', query + '*');
    } else {
      nameFilter = ad.nameFilter.replace('_name', '*');
    }
    opts = {
      filter: nameFilter,
      attributes: ['displayName'],
      // paged: {
      //   pageSize: 200
      // },
      scope: 'sub'
    };
    ldapClient.search(ad.searchBase, opts, false, function (err, result) {
      if (err) {
        console.error(err);
        return res.json(500, err.message);
      }
      if (result.length === 0) {
        return res.json(500, {
          error: 'Names starting with ' + query + ' are not found!'
        });
      }
      return res.json(result);
    });
  });
};
<|endoftext|>


<commit_before>var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

var shell = require('shelljs');
var SolidityCoder = require("web3/lib/solidity/coder.js");
var coverage = {};
var fs = require('fs');
var path = require('path');
var getInstrumentedVersion = require('./instrumentSolidity.js');

var childprocess = require('child_process');

//PAtch our local testrpc if necessary
if (!shell.test('-e','./node_modules/ethereumjs-vm/lib/opFns.js.orig')){
    console.log('patch local testrpc...')
    shell.exec('patch -b ./node_modules/ethereumjs-vm/lib/opFns.js ./hookIntoEvents.patch')
}
//Run the modified testrpc with large block limit
var testrpcProcess = childprocess.exec('./node_modules/ethereumjs-testrpc/bin/testrpc --gasLimit 0xfffffffffff')

if (shell.test('-d','../originalContracts')){
    console.log("There is already an 'originalContracts' directory in your truffle directory.\nThis is probably due to a previous solcover failure.\nPlease make sure the ./contracts/ directory contains your contracts (perhaps by copying them from originalContracts), and then delete the originalContracts directory.")
    process.exit(1);
}

shell.mv('./../contracts/', './../originalContracts/');
shell.mkdir('./../contracts/');
//For each contract in originalContracts, get the instrumented version
shell.ls('./../originalContracts/*.sol').forEach(function(file) {
    if (file !== 'originalContracts/Migrations.sol') {
        console.log("instrumenting ", file);
        var contract = fs.readFileSync("./" + file).toString();
        var fileName = path.basename(file);
        var instrumentedContractInfo = getInstrumentedVersion(contract, fileName, true);
        fs.writeFileSync('./../contracts/' + path.basename(file), instrumentedContractInfo.contract);
        var canonicalContractPath = path.resolve('./../originalContracts/' + path.basename(file));
        coverage[canonicalContractPath] = { "l": {}, "path": canonicalContractPath, "s": {}, "b": {}, "f": {}, "fnMap": {}, "statementMap": {}, "branchMap": {} };
        for (idx in instrumentedContractInfo.runnableLines) {
            coverage[canonicalContractPath]["l"][instrumentedContractInfo.runnableLines[idx]] = 0;
        }
        coverage[canonicalContractPath].fnMap = instrumentedContractInfo.fnMap;
        for (x=1; x<=Object.keys(instrumentedContractInfo.fnMap).length; x++ ){
            coverage[canonicalContractPath]["f"][x] = 0;
        }
        coverage[canonicalContractPath].branchMap = instrumentedContractInfo.branchMap;
        for (x=1; x<=Object.keys(instrumentedContractInfo.branchMap).length; x++ ){
            coverage[canonicalContractPath]["b"][x] = [0,0];
        }
        coverage[canonicalContractPath].statementMap= instrumentedContractInfo.statementMap;
        for (x=1; x<=Object.keys(instrumentedContractInfo.statementMap).length; x++ ){
            coverage[canonicalContractPath]["s"][x] = 0;
        }
    }
});
shell.cp("./../originalContracts/Migrations.sol", "./../contracts/Migrations.sol");

shell.rm('./allFiredEvents'); //Delete previous results
shell.exec('truffle test --network coverage');

events = fs.readFileSync('./allFiredEvents').toString().split('\n')
for (idx=0; idx < events.length-1; idx++){
    //The limit here isn't a bug - there is an empty line at the end of this file, so we don't
    //want to go to the very end of the array.
    var event = JSON.parse(events[idx]);
    if (event.topics.indexOf("b8995a65f405d9756b41a334f38d8ff0c93c4934e170d3c1429c3e7ca101014d") >= 0) {
        var data = SolidityCoder.decodeParams(["string", "uint256"], event.data.replace("0x", ""));
        var canonicalContractPath = path.resolve('./../originalContracts/' + path.basename(data[0]));
        coverage[canonicalContractPath]["l"][data[1].toNumber()] += 1;
    }else if(event.topics.indexOf("d4ce765fd23c5cc3660249353d61ecd18ca60549dd62cb9ca350a4244de7b87f")>=0){
        var data = SolidityCoder.decodeParams(["string", "uint256"], event.data.replace("0x", ""));
        var canonicalContractPath = path.resolve('./../originalContracts/' + path.basename(data[0]));
        coverage[canonicalContractPath]["f"][data[1].toNumber()] += 1;
    }else if(event.topics.indexOf("d4cf56ed5ba572684f02f889f12ac42d9583c8e3097802060e949bfbb3c1bff5")>=0){
        var data = SolidityCoder.decodeParams(["string", "uint256", "uint256"], event.data.replace("0x", ""));
        var canonicalContractPath = path.resolve('./../originalContracts/' + path.basename(data[0]));
        coverage[canonicalContractPath]["b"][data[1].toNumber()][data[2].toNumber()] += 1;
    }else if(event.topics.indexOf("b51abbff580b3a34bbc725f2dc6f736e9d4b45a41293fd0084ad865a31fde0c8")>=0){
        var data = SolidityCoder.decodeParams(["string","uint256"], event.data.replace("0x", ""));
        var canonicalContractPath = path.resolve('./../originalContracts/' + path.basename(data[0]));
        coverage[canonicalContractPath]["s"][data[1].toNumber()]+= 1;
    }
}

fs.writeFileSync('./coverage.json', JSON.stringify(coverage));

shell.exec("./node_modules/istanbul/lib/cli.js report html")
testrpcProcess.kill();
shell.rm('-rf', './../contracts');
shell.mv('./../originalContracts', './../contracts');
<commit_msg>Have runCoveredTests.js use coverageMap.js<commit_after>var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

var shell = require('shelljs');
var SolidityCoder = require("web3/lib/solidity/coder.js");
var fs = require('fs');
var path = require('path');
var getInstrumentedVersion = require('./instrumentSolidity.js');
var CoverageMap = require('./coverageMap.js');
var coverage = new CoverageMap();

var childprocess = require('child_process');

//PAtch our local testrpc if necessary
if (!shell.test('-e','./node_modules/ethereumjs-vm/lib/opFns.js.orig')){
    console.log('patch local testrpc...')
    shell.exec('patch -b ./node_modules/ethereumjs-vm/lib/opFns.js ./hookIntoEvents.patch')
}
//Run the modified testrpc with large block limit
var testrpcProcess = childprocess.exec('./node_modules/ethereumjs-testrpc/bin/testrpc --gasLimit 0xfffffffffff')

if (shell.test('-d','../originalContracts')){
    console.log("There is already an 'originalContracts' directory in your truffle directory.\nThis is probably due to a previous solcover failure.\nPlease make sure the ./contracts/ directory contains your contracts (perhaps by copying them from originalContracts), and then delete the originalContracts directory.")
    process.exit(1);
}

shell.mv('./../contracts/', './../originalContracts/');
shell.mkdir('./../contracts/');
//For each contract in originalContracts, get the instrumented version
shell.ls('./../originalContracts/*.sol').forEach(function(file) {
    if (file !== 'originalContracts/Migrations.sol') {
        console.log("instrumenting ", file);
        var contract = fs.readFileSync("./" + file).toString();
        var fileName = path.basename(file);
        var instrumentedContractInfo = getInstrumentedVersion(contract, fileName, true);
        fs.writeFileSync('./../contracts/' + path.basename(file), instrumentedContractInfo.contract);
        var canonicalContractPath = path.resolve('./../originalContracts/' + path.basename(file));
        coverage.addContract(instrumentedContractInfo, canonicalContractPath);
    }
});
shell.cp("./../originalContracts/Migrations.sol", "./../contracts/Migrations.sol");

shell.rm('./allFiredEvents'); //Delete previous results
shell.exec('truffle test --network coverage');

events = fs.readFileSync('./allFiredEvents').toString().split('\n')
events.pop();
//The pop here isn't a bug - there is an empty line at the end of this file, so we
//don't want to include it as an event.
coverage.generate(events, './../originalContracts/');

fs.writeFileSync('./coverage.json', JSON.stringify(coverage.coverage));

shell.exec("./node_modules/istanbul/lib/cli.js report html")
testrpcProcess.kill();
shell.rm('-rf', './../contracts');
shell.mv('./../originalContracts', './../contracts');
<|endoftext|>


<commit_before>(function(HTMLBuilder) {
	if (window.HTMLBuilder) {
		console.error(new Error("Conflict: 'window.HTMLBuilder' already exists."));
	} else {
		window.HTMLBuilder = HTMLBuilder;
	};
})(function(childNodes, parentNode) {
	if (typeof childNodes === "object") {
		if (!parentNode) parentNode = document.createDocumentFragment();
		if (!Array.isArray(childNodes)) childNodes = [childNodes];
		for (var i = 0, count = childNodes.length; i < count; i++) {
			if (childNodes[i].tagName || childNodes[i].nodeName) {
				var child = document.createElement(childNodes[i].tagName || childNodes[i].nodeName);
				delete childNodes[i].tagName && delete childNodes[i].nodeName;
				for (var prop in childNodes[i]) {
					if (prop === "classList") {
						child.classList.add(childNodes[i][prop]);
					} else if (child.hasOwnProperty(prop) && prop !== "childNodes" && prop !== "children") {
						child[prop] = childNodes[i][prop];
					};
				};
				parentNode.appendChild(child);
			} else {
				parentNode.appendChild(document.createTextNode(childNodes[i].textContent));
				var child = parentNode;
			};
			if (childNodes[i].childNodes || childNodes[i].children) HTMLBuilder(childNodes[i].childNodes || childNodes[i].children, child);
		};
		return parentNode;
	} else {
		console.error(new TypeError((typeof childNodes) + " is an invalid argument."));
	};
});
<commit_msg>added support for .children<commit_after>(function(HTMLBuilder) {
	if (window.HTMLBuilder) {
		console.error(new Error("Conflict: 'window.HTMLBuilder' already exists."));
	} else {
		window.HTMLBuilder = HTMLBuilder;
	};
})(function(childNodes, parentNode) {
	if (typeof childNodes === "object") {
		if (!parentNode) parentNode = document.createDocumentFragment();
		if (!Array.isArray(childNodes)) childNodes = [childNodes];
		for (var i = 0, count = childNodes.length; i < count; i++) {
			if (childNodes[i].tagName || childNodes[i].nodeName) {
				var child = document.createElement(childNodes[i].tagName || childNodes[i].nodeName);
				delete childNodes[i].tagName && delete childNodes[i].nodeName;
				for (var prop in childNodes[i]) {
					if (prop === "classList") {
						child.classList.add(childNodes[i][prop]);
					} else if (child.hasOwnProperty(prop) && prop !== "childNodes" && prop !== "children") {
						child[prop] = childNodes[i][prop];
					};
				};
				parentNode.appendChild(child);
			} else {
				parentNode.appendChild(document.createTextNode(childNodes[i].textContent));
				var child = parentNode;
			};
			if (childNodes[i].childNodes || childNodes[i].children) {
				HTMLBuilder(childNodes[i].childNodes || childNodes[i].children, child);
			};
		};
		return parentNode;
	} else {
		console.error(new TypeError((typeof childNodes) + " is an invalid argument."));
	};
});
<|endoftext|>


<commit_before>/*!
 * CSS Template Layout
 * Copyright (c) 2011 Pablo Escalada
 * MIT Licensed
 */
(function () {
    var lastEvent, buffer, parser, compiler;
    var that = {
        constants:{
            DISPLAY:"display",
            POSITION:"position"
        },
        OperationNotSupportedException: Error,

        setTemplate:function (cssFile) {
            wef.log.info("loading template...");

            function readFile(url) {
                //TODO: FIXME
                function ajaxReadFile() {
                    var request = new XMLHttpRequest();
                    request.open("get", url, false);
                    request.send("");
                    wef.log.info("request status: ", request.statusText);
                    return request.responseText;
                }

                try {
                    return ajaxReadFile(url);
                } catch (e) {
                    wef.log.error(e);
                    throw new that.OperationNotSupportedException(e);
                }
            }

            wef.fn.cssParser.parse(readFile(cssFile));
            wef.log.info("template loaded OK");
        },

        insertTemplate:function (templateSource) {
            wef.log.info("adding template...");
            wef.fn.cssParser.parse(templateSource);
            wef.log.info("template added OK");
        },

        //only for testing purposes
        getLastEvent:function () {
            return lastEvent;
        },

        getBuffer:function () {
            return buffer;
        }
    };

    function defaultCompiler() {
        var that = {
            compile: compile,
            UnexpectedValueException: Error
        };

        function template(preProcessTemplate) {
            var that = {
                parentTemplate: null,
                selectorText: preProcessTemplate.selectorText,
                selector: null,
                display: preProcessTemplate.display,
                position: preProcessTemplate.position,
                rows: null,
                isRoot: isRoot
            };

            function isRoot() {
                return that.position.position == null;
            }

            wef.log.info("new template:  ", that);
            return that;
        }

        var rootTemplate = function() {
            var that = {
                insert: insert,
                rows: {}
            };

            function insert (preProcessTemplate) {
                wef.log.warn("inserting ", preProcessTemplate.selectorText);
                var aTemplate = template(preProcessTemplate);

                if(aTemplate.isRoot()) {
                    wef.log.debug("inserting at root", aTemplate.selectorText);
                    that.rows[aTemplate.selectorText] = aTemplate;
                } else {
                    wef.log.debug("searching parent: ", aTemplate.selectorText);
                    //search in children
                }

            }

            return that;
        }();

        (function init() {
            wef.log.info("new compiler created");
        })();

        function parseDisplay(displayValue) {
            /**
             * Name:    ‘display’
             * New value:    <display-type>? && [ [ <string> [ / <row-height> ]? ]+ ] <col-width>*
             * Percentages:    N/A
             * Computed value:    specified value
             *
             * The <display-type> is one of the following keywords. An omitted keyword is equivalent to ‘block’.
             * <display-type> = inline | block | list-item | inline-block | table | inline-table
             * | table-row-group | table-header-group | table-footer-group | table-row
             * | table-column-group | table-column | table-cell | table-caption | none
             *
             * Each <string> consist of one or more at signs (“@”), letters (or digits, see <letter> below),
             * periods (“.”) and spaces
             *
             * Each <row-height> sets the height of the preceding row. The default is ‘auto’.
             * The values can be as follows:
             * <length> An explicit height for that row. Negative values make the template illegal. If the length is
             * expressed in ‘gr’ units, these refer to the inherited grid, not the grid defined by the template itself.
             * auto The row's height is determined by its contents.
             * * (asterisk) All rows with an asterisk will be of equal height.
             *
             * Each <col-width> can be one of the following:
             * <length> An explicit width for that column. Negative values make the template illegal.
             * * (asterisk.) All columns with a ‘*’ have the same width. See the algorithm below.
             * max-content, min-content, minmax(p,q), fit-content
             */
            wef.log.info("compiling display...");
            wef.log.debug("display source: ", displayValue);
            var displayMetadata = {
                displayType: null,
                grid: null
            };
            var displayTypeRegExp = /^\s*(inline|block|list-item|inline-block|table|inline-table|table-row-group|table-header-group|table-footer-group|table-row|table-column-group|table-column|table-cell|table-caption|none)?/ig;
            var stringRegExp = /\s*"([a-zA-Z0-9.@ ])+"/ig;
            if (displayValue != undefined) {
                //TODO: check invalid values
                displayMetadata.displayType = displayValue.match(displayTypeRegExp);
                displayMetadata.grid = displayValue.match(stringRegExp);
            }
            wef.log.info("display result: ", displayMetadata);
            return displayMetadata;
        }

        function parsePosition(positionValue) {
            /**
             * Name:    position
             * New value:    <letter> | same
             * Percentages:    N/A
             * Computed value:    ‘<letter>’ or ‘static’; see text
             *
             * <letter> must be a single letter or digit, with category Lu, Ll, Lt or Nd in Unicode [UNICODE]),
             * or a “@” symbol
             */
            wef.log.info("compiling position...");
            wef.log.debug("position source: ", positionValue);
            var positionMetadata = {
                position: null
            };
            var matched;
            var positionRegExp = /^\s*([a-zA-Z0-9]+|same)\s*/i;
            if (positionValue != undefined) {
                matched = positionValue.match(positionRegExp);
                if (matched == null) {
                    wef.log.error("Error: unexpected value at ", positionValue);
                    throw new that.UnexpectedValueException("Error: unexpected value at ", positionValue);
                }
                positionMetadata.position = matched[1];
            }
            wef.log.info("position result: ", positionMetadata);
            return positionMetadata;
        }

        function parseProperties(rule) {
            var preProcessTemplate = {};
            wef.log.info("compiling properties...");
            wef.log.debug("properties source: ", rule);

            preProcessTemplate.selectorText = rule.selectorText;

            wef.log.debug("* ", templateLayout.constants.DISPLAY, rule.declaration[templateLayout.constants.DISPLAY]);
            preProcessTemplate.display = parseDisplay(rule.declaration[templateLayout.constants.DISPLAY]);

            wef.log.debug("* ", templateLayout.constants.POSITION, rule.declaration[templateLayout.constants.POSITION]);
            preProcessTemplate.position = parsePosition(rule.declaration[templateLayout.constants.POSITION]);

            wef.log.info("properties result: ", preProcessTemplate);
            return preProcessTemplate;
        }

        function compile(buffer) {
            wef.log.info("compiling...");
            wef.log.debug("source: ", buffer);

            for (var selectorText in buffer) {
                wef.log.debug("next element: ", selectorText);
                var preProcessTemplate = parseProperties(buffer[selectorText]);
                wef.log.debug("result: ", preProcessTemplate);

                rootTemplate.insert(preProcessTemplate);
            }
            wef.log.debug("compiling ... OK");
        }

        return that;
    }

    (function init() {
        wef.log.info("creating templateLayout...");
        lastEvent = null;
        buffer = {};
        parser = wef.fn.cssParser;

        document.addEventListener(parser.events.PARSER_START, function (e) {
            wef.log.info("templateLayout listens: start parsing");
            lastEvent = e;
            buffer = {};
        }, false);

        document.addEventListener(parser.events.PROPERTY_FOUND, function (e) {
            wef.log.info("templateLayout listens: property found");
            lastEvent = e;
            if (isSupportedProperty(e.data)) {
                store(e.data);
            }
        }, false);

        document.addEventListener(parser.events.PARSER_DONE, function (e) {
            wef.log.info("templateLayout listens: parsing done");
            lastEvent = e;
            transform();
        }, false);

        wef.log.info("templateLayout OK");
    })();

    function transform() {
        compiler = defaultCompiler();
        wef.log.debug("transforming template ...");
        compiler.compile(buffer);
        wef.log.debug("template transformed OK");
    }

    function store(rule) {
        if (!buffer[rule.selectorText]) {
            buffer[rule.selectorText] = {selectorText:rule.selectorText, declaration:{}};
        }
        buffer[rule.selectorText].declaration[rule.declaration.property] = rule.declaration.valueText;
        wef.log.info("property stored: ", rule.declaration.property);
    }

    function isSupportedProperty(rule) {
        for (var iterator in that.constants) {
            if (that.constants[iterator] == rule.declaration.property) {
                wef.log.info("supported property found: ", rule.declaration.property);
                return true;
            }
        }
        return false;
    }

    window.templateLayout = that;
})();<commit_msg>Filter output for better template handling<commit_after>/*!
 * CSS Template Layout
 * Copyright (c) 2011 Pablo Escalada
 * MIT Licensed
 */
(function () {
    var lastEvent, buffer, parser, compiler;
    var that = {
        constants:{
            DISPLAY:"display",
            POSITION:"position"
        },
        OperationNotSupportedException: Error,

        setTemplate:function (cssFile) {
            wef.log.info("loading template...");

            function readFile(url) {
                //TODO: FIXME
                function ajaxReadFile() {
                    var request = new XMLHttpRequest();
                    request.open("get", url, false);
                    request.send("");
                    wef.log.info("request status: ", request.statusText);
                    return request.responseText;
                }

                try {
                    return ajaxReadFile(url);
                } catch (e) {
                    wef.log.error(e);
                    throw new that.OperationNotSupportedException(e);
                }
            }

            wef.fn.cssParser.parse(readFile(cssFile));
            wef.log.info("template loaded OK");
        },

        insertTemplate:function (templateSource) {
            wef.log.info("adding template...");
            wef.fn.cssParser.parse(templateSource);
            wef.log.info("template added OK");
        },

        //only for testing purposes
        getLastEvent:function () {
            return lastEvent;
        },

        getBuffer:function () {
            return buffer;
        }
    };

    function defaultCompiler() {
        var that = {
            compile: compile,
            UnexpectedValueException: Error
        };

        function template(preProcessTemplate) {
            var that = {
                parentTemplate: null,
                selectorText: preProcessTemplate.selectorText,
                selector: null,
                display: preProcessTemplate.display,
                position: preProcessTemplate.position,
                rows: null,
                isRoot: isRoot
            };

            function isRoot() {
                return that.position.position == null;
            }

            wef.log.info("new template:  ", that);
            return that;
        }

        var rootTemplate = function() {
            var that = {
                insert: insert,
                rows: {}
            };

            function insert (preProcessTemplate) {
                wef.log.warn("inserting ", preProcessTemplate.selectorText);
                var aTemplate = template(preProcessTemplate);

                if(aTemplate.isRoot()) {
                    wef.log.debug("inserting at root", aTemplate.selectorText);
                    that.rows[aTemplate.selectorText] = aTemplate;
                } else {
                    wef.log.debug("searching parent: ", aTemplate.selectorText);
                    //search in children
                }

            }

            return that;
        }();

        (function init() {
            wef.log.info("new compiler created");
        })();

        function parseDisplay(displayValue) {
            /**
             * Name:    ‘display’
             * New value:    <display-type>? && [ [ <string> [ / <row-height> ]? ]+ ] <col-width>*
             * Percentages:    N/A
             * Computed value:    specified value
             *
             * The <display-type> is one of the following keywords. An omitted keyword is equivalent to ‘block’.
             * <display-type> = inline | block | list-item | inline-block | table | inline-table
             * | table-row-group | table-header-group | table-footer-group | table-row
             * | table-column-group | table-column | table-cell | table-caption | none
             *
             * Each <string> consist of one or more at signs (“@”), letters (or digits, see <letter> below),
             * periods (“.”) and spaces
             *
             * Each <row-height> sets the height of the preceding row. The default is ‘auto’.
             * The values can be as follows:
             * <length> An explicit height for that row. Negative values make the template illegal. If the length is
             * expressed in ‘gr’ units, these refer to the inherited grid, not the grid defined by the template itself.
             * auto The row's height is determined by its contents.
             * * (asterisk) All rows with an asterisk will be of equal height.
             *
             * Each <col-width> can be one of the following:
             * <length> An explicit width for that column. Negative values make the template illegal.
             * * (asterisk.) All columns with a ‘*’ have the same width. See the algorithm below.
             * max-content, min-content, minmax(p,q), fit-content
             */
            wef.log.info("compiling display...");
            wef.log.debug("display source: ", displayValue);
            var displayMetadata = {
                displayType: null,
                grid: null
            };
            var displayTypeRegExp = /^\s*(inline|block|list-item|inline-block|table|inline-table|table-row-group|table-header-group|table-footer-group|table-row|table-column-group|table-column|table-cell|table-caption|none)?/ig;
            var stringRegExp = /\s*"([a-zA-Z0-9.@ ])+"/ig;
            if (displayValue != undefined) {
                //TODO: check invalid values
                displayMetadata.displayType = displayValue.match(displayTypeRegExp);
                displayMetadata.grid = displayValue.match(stringRegExp).map(function(element) {
                    return element.replace(/"/g, "").replace(/\s*/, "");
                });
            }
            wef.log.info("display result: ", displayMetadata);
            return displayMetadata;
        }

        function parsePosition(positionValue) {
            /**
             * Name:    position
             * New value:    <letter> | same
             * Percentages:    N/A
             * Computed value:    ‘<letter>’ or ‘static’; see text
             *
             * <letter> must be a single letter or digit, with category Lu, Ll, Lt or Nd in Unicode [UNICODE]),
             * or a “@” symbol
             */
            wef.log.info("compiling position...");
            wef.log.debug("position source: ", positionValue);
            var positionMetadata = {
                position: null
            };
            var matched;
            var positionRegExp = /^\s*([a-zA-Z0-9]+|same)\s*/i;
            if (positionValue != undefined) {
                matched = positionValue.match(positionRegExp);
                if (matched == null) {
                    wef.log.error("Error: unexpected value at ", positionValue);
                    throw new that.UnexpectedValueException("Error: unexpected value at ", positionValue);
                }
                positionMetadata.position = matched[1];
            }
            wef.log.info("position result: ", positionMetadata);
            return positionMetadata;
        }

        function parseProperties(rule) {
            var preProcessTemplate = {};
            wef.log.info("compiling properties...");
            wef.log.debug("properties source: ", rule);

            preProcessTemplate.selectorText = rule.selectorText;

            wef.log.debug("* ", templateLayout.constants.DISPLAY, rule.declaration[templateLayout.constants.DISPLAY]);
            preProcessTemplate.display = parseDisplay(rule.declaration[templateLayout.constants.DISPLAY]);

            wef.log.debug("* ", templateLayout.constants.POSITION, rule.declaration[templateLayout.constants.POSITION]);
            preProcessTemplate.position = parsePosition(rule.declaration[templateLayout.constants.POSITION]);

            wef.log.info("properties result: ", preProcessTemplate);
            return preProcessTemplate;
        }

        function compile(buffer) {
            wef.log.info("compiling...");
            wef.log.debug("source: ", buffer);

            for (var selectorText in buffer) {
                wef.log.debug("next element: ", selectorText);
                var preProcessTemplate = parseProperties(buffer[selectorText]);
                wef.log.debug("result: ", preProcessTemplate);

                rootTemplate.insert(preProcessTemplate);
            }
            wef.log.debug("compiling ... OK");
        }

        return that;
    }

    (function init() {
        wef.log.info("creating templateLayout...");
        lastEvent = null;
        buffer = {};
        parser = wef.fn.cssParser;

        document.addEventListener(parser.events.PARSER_START, function (e) {
            wef.log.info("templateLayout listens: start parsing");
            lastEvent = e;
            buffer = {};
        }, false);

        document.addEventListener(parser.events.PROPERTY_FOUND, function (e) {
            wef.log.info("templateLayout listens: property found");
            lastEvent = e;
            if (isSupportedProperty(e.data)) {
                store(e.data);
            }
        }, false);

        document.addEventListener(parser.events.PARSER_DONE, function (e) {
            wef.log.info("templateLayout listens: parsing done");
            lastEvent = e;
            transform();
        }, false);

        wef.log.info("templateLayout OK");
    })();

    function transform() {
        compiler = defaultCompiler();
        wef.log.debug("transforming template ...");
        compiler.compile(buffer);
        wef.log.debug("template transformed OK");
    }

    function store(rule) {
        if (!buffer[rule.selectorText]) {
            buffer[rule.selectorText] = {selectorText:rule.selectorText, declaration:{}};
        }
        buffer[rule.selectorText].declaration[rule.declaration.property] = rule.declaration.valueText;
        wef.log.info("property stored: ", rule.declaration.property);
    }

    function isSupportedProperty(rule) {
        for (var iterator in that.constants) {
            if (that.constants[iterator] == rule.declaration.property) {
                wef.log.info("supported property found: ", rule.declaration.property);
                return true;
            }
        }
        return false;
    }

    window.templateLayout = that;
})();<|endoftext|>


<commit_before>function Bridge () {

	function browserIsAndroid(){
		return navigator.userAgent.match(/Android/i);
	}

	function browserIsRapid(){
		return (typeof ___androidExists !== "undefined");
	}

	function browserSupportsPhoneGap(){
		return (typeof device !== "undefined" &&
				typeof device.phonegap !== "undefined");
	}

	function recommendUserSwitchesToRapid(){
		if(confirm("Do you want to run this website with the PhoneBridge browser?")) {
			switchThisURLToRapid();
		}
	}

	function switchThisURLToRapid(){
		changeURLTo("bridge://" + document.URL);
	}

	function changeURLTo(newUrl){
            location.replace(newUrl);
	}

//=========================================
//client Android Switch to Rapid
//=========================================

	this.android = {};

    this.android.recommendNative = function () {
		if (browserIsAndroid() && !browserIsRapid()){
			recommendUserSwitchesToRapid();
        }
    };

    this.android.browserIsBridge = function() {
        return browserIsRapid();
    };

    this.android.requireNative = function () {
		if (browserIsAndroid() && !browserIsRapid()){
			switchThisURLToRapid();
        }
    };

//=========================================
//Accelerometer wrapper
//=========================================
//API:
//	bridge.accelerometer.getCurrentAcceleration(onSuccess, onError)
//	bridge.accelerometer.watchAcceleration(onSuccess, onError)
//=========================================
	this.accelerometer = {};

	function browserSupportsWebkitAccelerometer(){
		return true; //TODO: I don't know how to actually check this
	}

	if (browserIsRapid()){
		this.accelerometer.getCurrentAcceleration = navigator.accelerometer.getCurentAcceleration;
		this.accelerometer.watchAcceleration = navigator.accelerometer.watchAcceleration;
	}
	else if (browserSupportsPhoneGap()){
		this.accelerometer.getCurrentAcceleration = navigator.accelerometer.getCurentAcceleration;
		this.accelerometer.watchAcceleration = navigator.accelerometer.watchAcceleration;
	}
	else if (browserSupportsWebkitAccelerometer()){

		var fnsWatchingAccelerometerOnSuccess = {};
		var nextIDForFnsWatchingAccelerometerOnSuccess = 0;
		var fnsWatchingAccelerometerOnError = {};
		var nextIDForFnsWatchingAccelerometerOnFail = 0;

		var lastEvent = null;

		window.ondevicemotion = function(event){
			lastEvent = event;
			for (fnId in fnsWatchingAccelerometerOnSuccess) {
				fnsWatchingAccelerometerOnSuccess[fnId](event);
			}
		}
		this.accelerometer.getCurrentAcceleration = function(onSuccess, onError){
			if (typeof lastEvent !== null){
				onSuccess(lastEvent);
			}
			else {
				onError();
			}
		}
		this.accelerometer.watchAcceleration = function(onSuccess, onError){
			fnsWatchingAccelerometerOnSuccess[nextIDForFnsWatchingAccelerometerOnSuccess] = onSuccess
			nextIDForFnsWatchingAccelerometerOnSuccess += 1;
			fnsWatchingAccelerometerOnError[nextIDForFnsWatchingAccelerometerOnError] = onError
			nextIDForFnsWatchingAccelerometerOnSuccess += 1;
		}
	}
	else {
		console.log("Device does not accept accelerometer!");
	}
	//accelerometer.getCurrentAcceleration =
	//accelerometer.watchAcceleration =

//=========================================
//Button wrapper
//=========================================
//API:
//	bridge.android.on.backButton(isSuper, callback)
//	bridge.android.on.volumedownButton(isSuper, callback)
//	bridge.android.on.volumeupButton(isSuper, callback)
//	bridge.android.on.menuButton(isSuper, callback)
//	bridge.android.on.homeButton(isSuper, callback)
//=========================================
    this.android.on = navigator.on;

//=========================================
//Geolocation wrapper
//=========================================
//API:
//	bridge.geolocation.getCurrentPosition(onSuccess, onError)
//	bridge.geolocation.isEnabled()
//	bridge.geolocation.enableLocationService()
//	bridge.geolocation.disableLocationService()
//=========================================
    this.geolocation = {};

	function browserSupportsWebkitGeolocation(){
		return true; //TODO: I don't know how to actually check this
	}

    //TODO: Support the options parameter like in the HTML5 and PhoneGap spec
	if (browserIsRapid()){
		this.geolocation.getCurrentPosition = navigator.geolocation.getCurrentPosition;
		this.geolocation.isEnabled = navigator.geolocation.isEnabled;
		this.geolocation.enableLocationService = navigator.geolocation.enableLocationService;
		this.geolocation.disableLocationService = navigator.geolocation.disableLocationService;
	}
	else if (browserSupportsPhoneGap()){
		this.geolocation.getCurrentPosition = navigator.geolocation.getCurrentPosition;
		this.geolocation.isEnabled = navigator.geolocation.isEnabled;
		this.geolocation.enableLocationService = navigator.geolocation.enableLocationService;
		this.geolocation.disableLocationService = navigator.geolocation.disableLocationService;
	}

	else if (browserSupportsWebkitGeolocation()){
		this.geolocation.getCurrentPosition = navigator.geolocation.getCurrentPosition;
		this.geolocation.isEnabled = navigator.geolocation.isEnabled;
		this.geolocation.enableLocationService = navigator.geolocation.enableLocationService;
		this.geolocation.disableLocationService = navigator.geolocation.disableLocationService;
    }
	else {
		console.log("Device does not accept geolocation!");
	}
//=========================================
//Device wrapper
//=========================================
//API:
//	bridge.device.getCurrentPosition(onSuccess, onError)
//	bridge.geolocation.isEnabled()
//	bridge.geolocation.enableLocationService()
//	bridge.geolocation.disableLocationService()
//=========================================

}

var bridge = new Bridge();

<commit_msg>modified compass<commit_after>function Bridge () {

	function browserIsAndroid(){
		return navigator.userAgent.match(/Android/i);
	}

	function browserIsRapid(){
		return (typeof ___androidExists !== "undefined");
	}

	function browserSupportsPhoneGap(){
		return (typeof device !== "undefined" &&
				typeof device.phonegap !== "undefined");
	}

	function recommendUserSwitchesToRapid(){
		if(confirm("Do you want to run this website with the PhoneBridge browser?")) {
			switchThisURLToRapid();
		}
	}

	function switchThisURLToRapid(){
		changeURLTo("bridge://" + document.URL);
	}

	function changeURLTo(newUrl){
            location.replace(newUrl);
	}

//=========================================
//client Android Switch to Rapid
//=========================================

	this.android = {};

    this.android.recommendNative = function () {
		if (browserIsAndroid() && !browserIsRapid()){
			recommendUserSwitchesToRapid();
        }
    };

    this.android.browserIsBridge = function() {
        return browserIsRapid();
    };

    this.android.requireNative = function () {
		if (browserIsAndroid() && !browserIsRapid()){
			switchThisURLToRapid();
        }
    };

//=========================================
//Accelerometer wrapper
//=========================================
//API:
//	bridge.accelerometer.getCurrentAcceleration(onSuccess, onError)
//	bridge.accelerometer.watchAcceleration(onSuccess, onError)
//=========================================
	this.accelerometer = {};

	function browserSupportsWebkitAccelerometer(){
		return true; //TODO: I don't know how to actually check this
	}

	if (browserIsRapid()){
		this.accelerometer.getCurrentAcceleration = navigator.accelerometer.getCurentAcceleration;
		this.accelerometer.watchAcceleration = navigator.accelerometer.watchAcceleration;
	}
	else if (browserSupportsPhoneGap()){
		this.accelerometer.getCurrentAcceleration = navigator.accelerometer.getCurentAcceleration;
		this.accelerometer.watchAcceleration = navigator.accelerometer.watchAcceleration;
	}
	else if (browserSupportsWebkitAccelerometer()){

		var fnsWatchingAccelerometerOnSuccess = {};
		var nextIDForFnsWatchingAccelerometerOnSuccess = 0;
		var fnsWatchingAccelerometerOnError = {};
		var nextIDForFnsWatchingAccelerometerOnFail = 0;

		var lastEvent = null;

		window.ondevicemotion = function(event){
			lastEvent = event;
			for (fnId in fnsWatchingAccelerometerOnSuccess) {
				fnsWatchingAccelerometerOnSuccess[fnId](event);
			}
		}
		this.accelerometer.getCurrentAcceleration = function(onSuccess, onError){
			if (typeof lastEvent !== null){
				onSuccess(lastEvent);
			}
			else {
				onError();
			}
		}
		this.accelerometer.watchAcceleration = function(onSuccess, onError){
			fnsWatchingAccelerometerOnSuccess[nextIDForFnsWatchingAccelerometerOnSuccess] = onSuccess
			nextIDForFnsWatchingAccelerometerOnSuccess += 1;
			fnsWatchingAccelerometerOnError[nextIDForFnsWatchingAccelerometerOnError] = onError
			nextIDForFnsWatchingAccelerometerOnSuccess += 1;
		}
	}
	else {
		console.log("Device does not accept accelerometer!");
	}
	//accelerometer.getCurrentAcceleration =
	//accelerometer.watchAcceleration =

//=========================================
//Button wrapper
//=========================================
//API:
//	bridge.android.on.backButton(isSuper, callback)
//=========================================
    this.android.on = navigator.on;

//=========================================
//Geolocation wrapper
//=========================================
//API:
//	bridge.geolocation.getCurrentPosition(onSuccess, onError)
//	bridge.geolocation.isEnabled()
//	bridge.geolocation.enableLocationService()
//	bridge.geolocation.disableLocationService()
//=========================================
    this.geolocation = {};

	function browserSupportsWebkitGeolocation(){
		return true; //TODO: I don't know how to actually check this
	}

    //TODO: Support the options parameter like in the HTML5 and PhoneGap spec
	if (browserIsRapid()){
		this.geolocation.getCurrentPosition = navigator.geolocation.getCurrentPosition;
		this.geolocation.isEnabled = navigator.geolocation.isEnabled;
		this.geolocation.enableLocationService = navigator.geolocation.enableLocationService;
		this.geolocation.disableLocationService = navigator.geolocation.disableLocationService;
	}
	else if (browserSupportsPhoneGap()){
		this.geolocation.getCurrentPosition = navigator.geolocation.getCurrentPosition;
		this.geolocation.isEnabled = navigator.geolocation.isEnabled;
		this.geolocation.enableLocationService = navigator.geolocation.enableLocationService;
		this.geolocation.disableLocationService = navigator.geolocation.disableLocationService;
	}

	else if (browserSupportsWebkitGeolocation()){
		this.geolocation.getCurrentPosition = navigator.geolocation.getCurrentPosition;
		this.geolocation.isEnabled = navigator.geolocation.isEnabled;
		this.geolocation.enableLocationService = navigator.geolocation.enableLocationService;
		this.geolocation.disableLocationService = navigator.geolocation.disableLocationService;
    }
	else {
		console.log("Device does not accept geolocation!");
	}
//=========================================
//Device wrapper
//=========================================
//API:
//	bridge.device.getCurrentPosition(onSuccess, onError)
//	bridge.geolocation.isEnabled()
//	bridge.geolocation.enableLocationService()
//	bridge.geolocation.disableLocationService()
//=========================================

//=========================================
//Orientation Wrapper
//=========================================
//API:
//	bridge.orientation.getCurrentOrientation(onSuccess,onError)
//=========================================
    this.orientation = {};

	function browserSupportsWebkitCompass(){
		return true; //TODO: I don't know how to actually check this
	}
    //TODO: Support the options parameter like in the HTML5 and PhoneGap spec
	if (browserIsRapid()){
		this.orientation.getCurrentOrientation = navigator.compass.getCurrentOrientation;
	}
	else if (browserSupportsPhoneGap()){
		this.orientation.getCurrentOrientation = navigator.compass.getCurrentOrientation;
	}

	else if (browserSupportsWebkitCompass()){
		this.orientation.getCurrentOrientation = navigator.compass.getCurrentOrientation;
	}
	else {
		console.log("Device does not accept Orientation!");
	}
}

var bridge = new Bridge();

<|endoftext|>


<commit_before>["Jennifer","Courtney S","Courtney N","Kristen","Liz","Emma","Jenna","Lindsay","Mary Sue"]
<commit_msg>wild for uneven<commit_after>["Jennifer","Courtney S","Courtney N","Kristen","Liz","Emma","Jenna","Lindsay","Mary Sue","Wild Card"]
<|endoftext|>


<commit_before>/*
Copyright 2018 New Vector Ltd

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 assert = require('assert');

module.exports.scrollToTimelineTop = async function(session) {
    session.log.step(`scrolls to the top of the timeline`);
    await session.page.evaluate(() => {
        return Promise.resolve().then(async () => {
            const timelineScrollView = document.querySelector(".mx_RoomView .gm-scroll-view");
            let timedOut = false;
            let timeoutHandle = null;
            // set scrollTop to 0 in a loop and check every 50ms
            // if content became available (scrollTop not being 0 anymore),
            // assume everything is loaded after 1000ms
            do {
                if (timelineScrollView.scrollTop !== 0) {
                    if (timeoutHandle) {
                        clearTimeout(timeoutHandle);
                    }
                    timeoutHandle = setTimeout(() => timedOut = true, 1000);
                    timelineScrollView.scrollTop = 0;
                } else {
                    await new Promise((resolve) => setTimeout(resolve, 50));
                }
            } while (!timedOut)
        });
    })
    session.log.done();
}

module.exports.receiveMessage = async function(session, expectedMessage) {
    session.log.step(`receives message "${expectedMessage.body}" from ${expectedMessage.sender}`);
    // wait for a response to come in that contains the message
    // crude, but effective
    await session.page.waitForResponse(async (response) => {
        if (response.request().url().indexOf("/sync") === -1) {
            return false;
        }
        const body = await response.text();
        if (expectedMessage.encrypted) {
            return body.indexOf(expectedMessage.sender) !== -1 &&
                         body.indexOf("m.room.encrypted") !== -1;
        } else {
            return body.indexOf(expectedMessage.body) !== -1;
        }
    });
    // wait a bit for the incoming event to be rendered
    await session.delay(1000);
    const lastTile = await getLastEventTile(session);
    const foundMessage = await getMessageFromEventTile(lastTile);
    assertMessage(foundMessage, expectedMessage);
    session.log.done();
}

module.exports.checkTimelineContains = async function (session, expectedMessages, sendersDescription) {
    session.log.step(`checks timeline contains ${expectedMessages.length} ` +
        `given messages${sendersDescription ? ` from ${sendersDescription}`:""}`);
    const eventTiles = await getAllEventTiles(session);
    let timelineMessages = await Promise.all(eventTiles.map((eventTile) => {
        return getMessageFromEventTile(eventTile);
    }));
    //filter out tiles that were not messages
    timelineMessages = timelineMessages .filter((m) => !!m);
    expectedMessages.forEach((expectedMessage) => {
        const foundMessage = timelineMessages.find((message) => {
            return message.sender === expectedMessage.sender &&
                   message.body === expectedMessage.body;
        });
        assertMessage(foundMessage, expectedMessage);
    });

    session.log.done();
}

function assertMessage(foundMessage, expectedMessage) {
    assert(foundMessage, `message ${JSON.stringify(expectedMessage)} not found in timeline`);
    assert.equal(foundMessage.body, expectedMessage.body);
    assert.equal(foundMessage.sender, expectedMessage.sender);
    if (expectedMessage.hasOwnProperty("encrypted")) {
        assert.equal(foundMessage.encrypted, expectedMessage.encrypted);
    }
}

function getLastEventTile(session) {
    return session.query(".mx_EventTile_last");
}

function getAllEventTiles(session) {
    return session.queryAll(".mx_RoomView_MessageList > *");
}

async function getMessageFromEventTile(eventTile) {
    const senderElement = await eventTile.$(".mx_SenderProfile_name");
    const bodyElement = await eventTile.$(".mx_EventTile_body");
    let sender = null;
    if (senderElement) {
        sender = await(await senderElement.getProperty("innerText")).jsonValue();
    }
    if (!bodyElement) {
        return null;
    }
    const body = await(await bodyElement.getProperty("innerText")).jsonValue();
    const e2eIcon = await eventTile.$(".mx_EventTile_e2eIcon");

    return {
        sender,
        body,
        encrypted: !!e2eIcon
    };
}
<commit_msg>increase timeout here in case this wouldnt be enough for the CI server<commit_after>/*
Copyright 2018 New Vector Ltd

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 assert = require('assert');

module.exports.scrollToTimelineTop = async function(session) {
    session.log.step(`scrolls to the top of the timeline`);
    await session.page.evaluate(() => {
        return Promise.resolve().then(async () => {
            const timelineScrollView = document.querySelector(".mx_RoomView .gm-scroll-view");
            let timedOut = false;
            let timeoutHandle = null;
            // set scrollTop to 0 in a loop and check every 50ms
            // if content became available (scrollTop not being 0 anymore),
            // assume everything is loaded after 3s
            do {
                if (timelineScrollView.scrollTop !== 0) {
                    if (timeoutHandle) {
                        clearTimeout(timeoutHandle);
                    }
                    timeoutHandle = setTimeout(() => timedOut = true, 3000);
                    timelineScrollView.scrollTop = 0;
                } else {
                    await new Promise((resolve) => setTimeout(resolve, 50));
                }
            } while (!timedOut)
        });
    })
    session.log.done();
}

module.exports.receiveMessage = async function(session, expectedMessage) {
    session.log.step(`receives message "${expectedMessage.body}" from ${expectedMessage.sender}`);
    // wait for a response to come in that contains the message
    // crude, but effective
    await session.page.waitForResponse(async (response) => {
        if (response.request().url().indexOf("/sync") === -1) {
            return false;
        }
        const body = await response.text();
        if (expectedMessage.encrypted) {
            return body.indexOf(expectedMessage.sender) !== -1 &&
                         body.indexOf("m.room.encrypted") !== -1;
        } else {
            return body.indexOf(expectedMessage.body) !== -1;
        }
    });
    // wait a bit for the incoming event to be rendered
    await session.delay(1000);
    const lastTile = await getLastEventTile(session);
    const foundMessage = await getMessageFromEventTile(lastTile);
    assertMessage(foundMessage, expectedMessage);
    session.log.done();
}

module.exports.checkTimelineContains = async function (session, expectedMessages, sendersDescription) {
    session.log.step(`checks timeline contains ${expectedMessages.length} ` +
        `given messages${sendersDescription ? ` from ${sendersDescription}`:""}`);
    const eventTiles = await getAllEventTiles(session);
    let timelineMessages = await Promise.all(eventTiles.map((eventTile) => {
        return getMessageFromEventTile(eventTile);
    }));
    //filter out tiles that were not messages
    timelineMessages = timelineMessages .filter((m) => !!m);
    expectedMessages.forEach((expectedMessage) => {
        const foundMessage = timelineMessages.find((message) => {
            return message.sender === expectedMessage.sender &&
                   message.body === expectedMessage.body;
        });
        assertMessage(foundMessage, expectedMessage);
    });

    session.log.done();
}

function assertMessage(foundMessage, expectedMessage) {
    assert(foundMessage, `message ${JSON.stringify(expectedMessage)} not found in timeline`);
    assert.equal(foundMessage.body, expectedMessage.body);
    assert.equal(foundMessage.sender, expectedMessage.sender);
    if (expectedMessage.hasOwnProperty("encrypted")) {
        assert.equal(foundMessage.encrypted, expectedMessage.encrypted);
    }
}

function getLastEventTile(session) {
    return session.query(".mx_EventTile_last");
}

function getAllEventTiles(session) {
    return session.queryAll(".mx_RoomView_MessageList > *");
}

async function getMessageFromEventTile(eventTile) {
    const senderElement = await eventTile.$(".mx_SenderProfile_name");
    const bodyElement = await eventTile.$(".mx_EventTile_body");
    let sender = null;
    if (senderElement) {
        sender = await(await senderElement.getProperty("innerText")).jsonValue();
    }
    if (!bodyElement) {
        return null;
    }
    const body = await(await bodyElement.getProperty("innerText")).jsonValue();
    const e2eIcon = await eventTile.$(".mx_EventTile_e2eIcon");

    return {
        sender,
        body,
        encrypted: !!e2eIcon
    };
}
<|endoftext|>


<commit_before>import d3 from 'd3';
import _dataJoin from '../util/dataJoin';
import line from '../annotation/line';
import _multi from '../series/multi';
import {noop} from '../util/fn';
import {noSnap} from '../util/snap';
import point from '../series/point';
import {range} from '../util/scale';
import {rebind} from '../util/rebind';

export default function() {

    var event = d3.dispatch('trackingstart', 'trackingmove', 'trackingend'),
        xScale = d3.time.scale(),
        yScale = d3.scale.linear(),
        snap = function(_x, _y) {
            return noSnap(xScale, yScale)(_x, _y);
        },
        decorate = noop;

    var x = function(d) { return d.x; },
        y = function(d) { return d.y; };

    var dataJoin = _dataJoin()
        .children(true)
        .selector('g.crosshair')
        .element('g')
        .attr('class', 'crosshair');

    var pointSeries = point()
        .xValue(x)
        .yValue(y);

    var horizontalLine = line()
        .value(y)
        .label(function(d) { return d.y; });

    var verticalLine = line()
        .orient('vertical')
        .value(x)
        .label(function(d) { return d.x; });

    // the line annotations used to render the crosshair are positioned using
    // screen coordinates. This function constructs a suitable scale for rendering
    // these annotations.
    function identityScale(scale) {
        return d3.scale.identity()
            .range(range(scale));
    }

    var crosshair = function(selection) {

        selection.each(function(data, index) {

            var container = d3.select(this)
                .style('pointer-events', 'all')
                .on('mouseenter.crosshair', mouseenter)
                .on('mousemove.crosshair', mousemove)
                .on('wheel.crosshair', mousewheel)
                .on('mouseleave.crosshair', mouseleave);

            var overlay = container.selectAll('rect')
                .data([data]);

            overlay.enter()
                .append('rect')
                .style('visibility', 'hidden');

            container.select('rect')
                .attr('x', range(xScale)[0])
                .attr('y', range(yScale)[1])
                .attr('width', range(xScale)[1])
                .attr('height', range(yScale)[0]);

            var crosshairElement = dataJoin(container, data);

            crosshairElement.enter()
                .style('pointer-events', 'none');

            var multi = _multi()
                .series([horizontalLine, verticalLine, pointSeries])
                .xScale(identityScale(xScale))
                .yScale(identityScale(yScale))
                .mapping(function() {
                    return [this];
                });

            crosshairElement.call(multi);

            decorate(crosshairElement, data, index);
        });
    };

    function mouseenter() {
        var mouse = d3.mouse(this);
        var container = d3.select(this);
        var snapped = snap.apply(this, mouse);
        var data = container.datum();
        data.push(snapped);
        container.call(crosshair);
        event.trackingstart.apply(this, arguments);
    }

    function mousemove() {
        var mouse = d3.mouse(this);
        var container = d3.select(this);
        var snapped = snap.apply(this, mouse);
        var data = container.datum();
        data[data.length - 1] = snapped;
        container.call(crosshair);
        event.trackingmove.apply(this, arguments);
    }

    function mousewheel() {
        var mouse = d3.mouse(this);
        var container = d3.select(this);
        var snapped = snap.apply(this, mouse);
        var data = container.datum();
        data[data.length - 1] = snapped;
        container.call(crosshair);
        event.trackingmove.apply(this, arguments);
    }

    function mouseleave() {
        var container = d3.select(this);
        var data = container.datum();
        data.pop();
        container.call(crosshair);
        event.trackingend.apply(this, arguments);
    }

    crosshair.xScale = function(_x) {
        if (!arguments.length) {
            return xScale;
        }
        xScale = _x;
        return crosshair;
    };
    crosshair.yScale = function(_x) {
        if (!arguments.length) {
            return yScale;
        }
        yScale = _x;
        return crosshair;
    };
    crosshair.snap = function(_x) {
        if (!arguments.length) {
            return snap;
        }
        snap = _x;
        return crosshair;
    };
    crosshair.decorate = function(_x) {
        if (!arguments.length) {
            return decorate;
        }
        decorate = _x;
        return crosshair;
    };

    d3.rebind(crosshair, event, 'on');

    rebind(crosshair, horizontalLine, {
        yLabel: 'label'
    });

    rebind(crosshair, verticalLine, {
        xLabel: 'label'
    });

    return crosshair;
}
<commit_msg>mousemove and wheel events can trigger same function<commit_after>import d3 from 'd3';
import _dataJoin from '../util/dataJoin';
import line from '../annotation/line';
import _multi from '../series/multi';
import {noop} from '../util/fn';
import {noSnap} from '../util/snap';
import point from '../series/point';
import {range} from '../util/scale';
import {rebind} from '../util/rebind';

export default function() {

    var event = d3.dispatch('trackingstart', 'trackingmove', 'trackingend'),
        xScale = d3.time.scale(),
        yScale = d3.scale.linear(),
        snap = function(_x, _y) {
            return noSnap(xScale, yScale)(_x, _y);
        },
        decorate = noop;

    var x = function(d) { return d.x; },
        y = function(d) { return d.y; };

    var dataJoin = _dataJoin()
        .children(true)
        .selector('g.crosshair')
        .element('g')
        .attr('class', 'crosshair');

    var pointSeries = point()
        .xValue(x)
        .yValue(y);

    var horizontalLine = line()
        .value(y)
        .label(function(d) { return d.y; });

    var verticalLine = line()
        .orient('vertical')
        .value(x)
        .label(function(d) { return d.x; });

    // the line annotations used to render the crosshair are positioned using
    // screen coordinates. This function constructs a suitable scale for rendering
    // these annotations.
    function identityScale(scale) {
        return d3.scale.identity()
            .range(range(scale));
    }

    var crosshair = function(selection) {

        selection.each(function(data, index) {

            var container = d3.select(this)
                .style('pointer-events', 'all')
                .on('mouseenter.crosshair', mouseenter)
                .on('mousemove.crosshair', mousemove)
                .on('wheel.crosshair', mousemove)
                .on('mouseleave.crosshair', mouseleave);

            var overlay = container.selectAll('rect')
                .data([data]);

            overlay.enter()
                .append('rect')
                .style('visibility', 'hidden');

            container.select('rect')
                .attr('x', range(xScale)[0])
                .attr('y', range(yScale)[1])
                .attr('width', range(xScale)[1])
                .attr('height', range(yScale)[0]);

            var crosshairElement = dataJoin(container, data);

            crosshairElement.enter()
                .style('pointer-events', 'none');

            var multi = _multi()
                .series([horizontalLine, verticalLine, pointSeries])
                .xScale(identityScale(xScale))
                .yScale(identityScale(yScale))
                .mapping(function() {
                    return [this];
                });

            crosshairElement.call(multi);

            decorate(crosshairElement, data, index);
        });
    };

    function mouseenter() {
        var mouse = d3.mouse(this);
        var container = d3.select(this);
        var snapped = snap.apply(this, mouse);
        var data = container.datum();
        data.push(snapped);
        container.call(crosshair);
        event.trackingstart.apply(this, arguments);
    }

    function mousemove() {
        var mouse = d3.mouse(this);
        var container = d3.select(this);
        var snapped = snap.apply(this, mouse);
        var data = container.datum();
        data[data.length - 1] = snapped;
        container.call(crosshair);
        event.trackingmove.apply(this, arguments);
    }

    function mouseleave() {
        var container = d3.select(this);
        var data = container.datum();
        data.pop();
        container.call(crosshair);
        event.trackingend.apply(this, arguments);
    }

    crosshair.xScale = function(_x) {
        if (!arguments.length) {
            return xScale;
        }
        xScale = _x;
        return crosshair;
    };
    crosshair.yScale = function(_x) {
        if (!arguments.length) {
            return yScale;
        }
        yScale = _x;
        return crosshair;
    };
    crosshair.snap = function(_x) {
        if (!arguments.length) {
            return snap;
        }
        snap = _x;
        return crosshair;
    };
    crosshair.decorate = function(_x) {
        if (!arguments.length) {
            return decorate;
        }
        decorate = _x;
        return crosshair;
    };

    d3.rebind(crosshair, event, 'on');

    rebind(crosshair, horizontalLine, {
        yLabel: 'label'
    });

    rebind(crosshair, verticalLine, {
        xLabel: 'label'
    });

    return crosshair;
}
<|endoftext|>


<commit_before>/**
 * Toolbar Dialog
 *
 * @param {Element} link The toolbar link which causes the dialog to show up
 * @param {Element} container The dialog container
 *
 * @example
 *
 *    insert an image
 *
 *
 *

 *
 *        URL: <input data-wysihtml5-dialog-field="src" value="http://">
 *
 *
 *        Alternative text: <input data-wysihtml5-dialog-field="alt" value="">
 *
 *

 *
 *
 */
(function(wysihtml5) {
  var dom                     = wysihtml5.dom,
      CLASS_NAME_OPENED       = "wysihtml5-command-dialog-opened",
      SELECTOR_FORM_ELEMENTS  = "input, select, textarea",
      SELECTOR_FIELDS         = "[data-wysihtml5-dialog-field]",
      ATTRIBUTE_FIELDS        = "data-wysihtml5-dialog-field";

  wysihtml5.toolbar.Dialog = wysihtml5.lang.Dispatcher.extend(
    /** @scope wysihtml5.toolbar.Dialog.prototype */ {
    constructor: function(link, container) {
      this.link       = link;
      this.container  = container;
    },

    _observe: function() {
      if (this._observed) {
        return;
      }

      var that = this,
          callbackWrapper = function(event) {
            var attributes = that._serialize();
            if (attributes == that.elementToChange) {
              that.fire("edit", attributes);
            } else {
              that.fire("save", attributes);
            }
            that.hide();
            event.preventDefault();
            event.stopPropagation();
          };

      dom.observe(that.link, "click", function() {
        if (dom.hasClass(that.link, CLASS_NAME_OPENED)) {
          setTimeout(function() { that.hide(); }, 0);
        }
      });

      dom.observe(this.container, "keydown", function(event) {
        var keyCode = event.keyCode;
        if (keyCode === wysihtml5.ENTER_KEY) {
          callbackWrapper(event);
        }
        if (keyCode === wysihtml5.ESCAPE_KEY) {
          that.fire("cancel");
          that.hide();
        }
      });

      dom.delegate(this.container, "[data-wysihtml5-dialog-action=save]", "click", callbackWrapper);

      dom.delegate(this.container, "[data-wysihtml5-dialog-action=cancel]", "click", function(event) {
        that.fire("cancel");
        that.hide();
        event.preventDefault();
        event.stopPropagation();
      });

      var formElements  = this.container.querySelectorAll(SELECTOR_FORM_ELEMENTS),
          i             = 0,
          length        = formElements.length,
          _clearInterval = function() { clearInterval(that.interval); };
      for (; i<length; i++) {
        dom.observe(formElements[i], "change", _clearInterval);
      }

      this._observed = true;
    },

    /**
     * Grabs all fields in the dialog and puts them in key=>value style in an object which
     * then gets returned
     */
    _serialize: function() {
      var data    = this.elementToChange || {},
          fields  = this.container.querySelectorAll(SELECTOR_FIELDS),
          length  = fields.length,
          i       = 0;
      for (; i<length; i++) {
        data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
      }
      return data;
    },

    /**
     * Takes the attributes of the "elementToChange"
     * and inserts them in their corresponding dialog input fields
     *
     * Assume the "elementToChange" looks like this:
     *    foo
     *
     * and we have the following dialog:
     *    <input type="text" data-wysihtml5-dialog-field="href" value="">
     *    <input type="text" data-wysihtml5-dialog-field="target" value="">
     *
     * after calling _interpolate() the dialog will look like this
     *    <input type="text" data-wysihtml5-dialog-field="href" value="http://www.google.com">
     *    <input type="text" data-wysihtml5-dialog-field="target" value="_blank">
     *
     * Basically it adopted the attribute values into the corresponding input fields
     *
     */
    _interpolate: function(avoidHiddenFields) {
      var field,
          fieldName,
          newValue,
          focusedElement = document.querySelector(":focus"),
          fields         = this.container.querySelectorAll(SELECTOR_FIELDS),
          length         = fields.length,
          i              = 0;
      for (; i<length; i++) {
        field = fields[i];

        // Never change elements where the user is currently typing in
        if (field === focusedElement) {
          continue;
        }

        // Don't update hidden fields
        // See https://github.com/xing/wysihtml5/pull/14
        if (avoidHiddenFields && field.type === "hidden") {
          continue;
        }

        fieldName = field.getAttribute(ATTRIBUTE_FIELDS);
        newValue  = this.elementToChange ? (this.elementToChange[fieldName] || "") : field.defaultValue;
        field.value = newValue;
      }
    },

    /**
     * Show the dialog element
     */
    show: function(elementToChange) {
      if (dom.hasClass(this.link, CLASS_NAME_OPENED)) {
        return;
      }

      var that        = this,
          firstField  = this.container.querySelector(SELECTOR_FORM_ELEMENTS);
      this.elementToChange = elementToChange;
      this._observe();
      this._interpolate();
      if (elementToChange) {
        this.interval = setInterval(function() { that._interpolate(true); }, 500);
      }
      dom.addClass(this.link, CLASS_NAME_OPENED);
      this.container.style.display = "";
      this.fire("show");
      if (firstField && !elementToChange) {
        try {
          firstField.focus();
        } catch(e) {}
      }
    },

    /**
     * Hide the dialog element
     */
    hide: function() {
      clearInterval(this.interval);
      this.elementToChange = null;
      dom.removeClass(this.link, CLASS_NAME_OPENED);
      this.container.style.display = "none";
      this.fire("hide");
    }
  });
})(wysihtml5);
<commit_msg>Hide currently opened dialog when it is shown for another element.<commit_after>/**
 * Toolbar Dialog
 *
 * @param {Element} link The toolbar link which causes the dialog to show up
 * @param {Element} container The dialog container
 *
 * @example
 *
 *    insert an image
 *
 *
 *

 *
 *        URL: <input data-wysihtml5-dialog-field="src" value="http://">
 *
 *
 *        Alternative text: <input data-wysihtml5-dialog-field="alt" value="">
 *
 *

 *
 *
 */
(function(wysihtml5) {
  var dom                     = wysihtml5.dom,
      CLASS_NAME_OPENED       = "wysihtml5-command-dialog-opened",
      SELECTOR_FORM_ELEMENTS  = "input, select, textarea",
      SELECTOR_FIELDS         = "[data-wysihtml5-dialog-field]",
      ATTRIBUTE_FIELDS        = "data-wysihtml5-dialog-field";

  wysihtml5.toolbar.Dialog = wysihtml5.lang.Dispatcher.extend(
    /** @scope wysihtml5.toolbar.Dialog.prototype */ {
    constructor: function(link, container) {
      this.link       = link;
      this.container  = container;
    },

    _observe: function() {
      if (this._observed) {
        return;
      }

      var that = this,
          callbackWrapper = function(event) {
            var attributes = that._serialize();
            if (attributes == that.elementToChange) {
              that.fire("edit", attributes);
            } else {
              that.fire("save", attributes);
            }
            that.hide();
            event.preventDefault();
            event.stopPropagation();
          };

      dom.observe(that.link, "click", function() {
        if (dom.hasClass(that.link, CLASS_NAME_OPENED)) {
          setTimeout(function() { that.hide(); }, 0);
        }
      });

      dom.observe(this.container, "keydown", function(event) {
        var keyCode = event.keyCode;
        if (keyCode === wysihtml5.ENTER_KEY) {
          callbackWrapper(event);
        }
        if (keyCode === wysihtml5.ESCAPE_KEY) {
          that.fire("cancel");
          that.hide();
        }
      });

      dom.delegate(this.container, "[data-wysihtml5-dialog-action=save]", "click", callbackWrapper);

      dom.delegate(this.container, "[data-wysihtml5-dialog-action=cancel]", "click", function(event) {
        that.fire("cancel");
        that.hide();
        event.preventDefault();
        event.stopPropagation();
      });

      var formElements  = this.container.querySelectorAll(SELECTOR_FORM_ELEMENTS),
          i             = 0,
          length        = formElements.length,
          _clearInterval = function() { clearInterval(that.interval); };
      for (; i<length; i++) {
        dom.observe(formElements[i], "change", _clearInterval);
      }

      this._observed = true;
    },

    /**
     * Grabs all fields in the dialog and puts them in key=>value style in an object which
     * then gets returned
     */
    _serialize: function() {
      var data    = this.elementToChange || {},
          fields  = this.container.querySelectorAll(SELECTOR_FIELDS),
          length  = fields.length,
          i       = 0;
      for (; i<length; i++) {
        data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
      }
      return data;
    },

    /**
     * Takes the attributes of the "elementToChange"
     * and inserts them in their corresponding dialog input fields
     *
     * Assume the "elementToChange" looks like this:
     *    foo
     *
     * and we have the following dialog:
     *    <input type="text" data-wysihtml5-dialog-field="href" value="">
     *    <input type="text" data-wysihtml5-dialog-field="target" value="">
     *
     * after calling _interpolate() the dialog will look like this
     *    <input type="text" data-wysihtml5-dialog-field="href" value="http://www.google.com">
     *    <input type="text" data-wysihtml5-dialog-field="target" value="_blank">
     *
     * Basically it adopted the attribute values into the corresponding input fields
     *
     */
    _interpolate: function(avoidHiddenFields) {
      var field,
          fieldName,
          newValue,
          focusedElement = document.querySelector(":focus"),
          fields         = this.container.querySelectorAll(SELECTOR_FIELDS),
          length         = fields.length,
          i              = 0;
      for (; i<length; i++) {
        field = fields[i];

        // Never change elements where the user is currently typing in
        if (field === focusedElement) {
          continue;
        }

        // Don't update hidden fields
        // See https://github.com/xing/wysihtml5/pull/14
        if (avoidHiddenFields && field.type === "hidden") {
          continue;
        }

        fieldName = field.getAttribute(ATTRIBUTE_FIELDS);
        newValue  = this.elementToChange ? (this.elementToChange[fieldName] || "") : field.defaultValue;
        field.value = newValue;
      }
    },

    /**
     * Show the dialog element
     */
    show: function(elementToChange) {
      if (this.opened) {
        if (this.elementToChange == elementToChange) {
          return;
        }
        else {
          this.hide();
        }
      }

      var that        = this,
          firstField  = this.container.querySelector(SELECTOR_FORM_ELEMENTS);
      this.elementToChange = elementToChange;
      this._observe();
      this._interpolate();
      if (elementToChange) {
        this.interval = setInterval(function() { that._interpolate(true); }, 500);
      }
      dom.addClass(this.link, CLASS_NAME_OPENED);
      this.opened = true;
      this.container.style.display = "";
      this.fire("show");
      if (firstField && !elementToChange) {
        try {
          firstField.focus();
        } catch(e) {}
      }
    },

    /**
     * Hide the dialog element
     */
    hide: function() {
      if (!this.opened) {
        return;
      }

      clearInterval(this.interval);
      this.elementToChange = null;
      dom.removeClass(this.link, CLASS_NAME_OPENED);
      this.opened = false;
      this.container.style.display = "none";
      this.fire("hide");
    }
  });
})(wysihtml5);
<|endoftext|>