<commit_before>var fs = require('fs');
var path = require('path');
var RSVP = require('rsvp');
var rimraf = RSVP.denodeify(require('rimraf'));
var mapSeries = require('promise-map-series');
var quickTemp = require('quick-temp');
var helpers = require('broccoli-kitchen-sink-helpers');
var symlinkOrCopy = require('symlink-or-copy');
var generateRandomString = require('./lib/generate-random-string');
var assign = require('lodash-node/modern/objects/assign');
var CoreObject = require('core-object');
var debug = require('debug')('broccoli-caching-writer');

var proto = {};

proto.init = function(inputTrees, options) {
  this._inputTreeCacheHash = [];
  this._lastKeys = [];
  this._shouldBeIgnoredCache = Object.create(null);
  this._destDir = path.resolve(path.join('tmp', 'caching-writer-dest-dir_' + generateRandomString(6) + '.tmp'));

  options = options || {};

  for (var key in options) {
    if (options.hasOwnProperty(key)) {
      this[key] = options[key];
    }
  }

  if (Array.isArray(inputTrees)) {
    if (this.enforceSingleInputTree) {
      throw new Error('You passed an array of input trees, but only a single tree is allowed.');
    }

    this.inputTrees = inputTrees;
  } else {
    this.inputTrees = [inputTrees];
  }

  if (this.filterFromCache === undefined) {
    this.filterFromCache = {};
  }

  if (this.filterFromCache.include === undefined) {
    this.filterFromCache.include = [];
  }

  if (this.filterFromCache.exclude === undefined) {
    this.filterFromCache.exclude = [];
  }

  if (!Array.isArray(this.filterFromCache.include)) {
    throw new Error('Invalid filterFromCache.include option, it must be an array or undefined.');
  }

  if (!Array.isArray(this.filterFromCache.exclude)) {
    throw new Error('Invalid filterFromCache.exclude option, it must be an array or undefined.');
  }
};

proto.enforceSingleInputTree = false;

proto.getCacheDir = function () {
  return quickTemp.makeOrReuse(this, 'tmpCacheDir');
};

proto.getCleanCacheDir = function () {
  return quickTemp.makeOrRemake(this, 'tmpCacheDir');
};

proto.read = function (readTree) {
  var self = this;

  return mapSeries(this.inputTrees, readTree)
    .then(function(inputPaths) {
      var inputTreeHashes = [];
      var invalidateCache = false;
      var key, dir, updateCacheResult;
      var lastKeys = [];

      for (var i = 0, l = inputPaths.length; i < l; i++) {
        dir = inputPaths[i];

        key = self.keyForTree(dir);
        lastKey = self._lastKeys[i];
        lastKeys.push(key);

        if (!invalidateCache /* short circuit */ && !key.equal(lastKey)) {
          invalidateCache = true;
        }
      }

      if (invalidateCache) {
        var updateCacheSrcArg = self.enforceSingleInputTree ? inputPaths[0] : inputPaths;
        updateCacheResult = self.updateCache(updateCacheSrcArg, self.getCleanCacheDir());

        self._lastKeys = lastKeys;

        self._inputTreeCacheHash = inputTreeHashes;
      }

      return updateCacheResult;
    })
    .then(function() {
      return rimraf(self._destDir);
    })
    .then(function() {
      symlinkOrCopy.sync(self.getCacheDir(), self._destDir);
    })
    .then(function() {
      return self._destDir;
    });
};

proto.cleanup = function () {
  quickTemp.remove(this, 'tmpCacheDir');

  // sadly we must use sync removal for now
  if (this._destDir) {
    rimraf.sync(this._destDir);
  }
};

proto.updateCache = function (srcDir, destDir) {
  throw new Error('You must implement updateCache.');
};

// Takes in a path and { include, exclude }. Tests the path using regular expressions and
// returns true if the path does not match any exclude patterns AND matches atleast
// one include pattern.
proto.shouldBeIgnored = function (fullPath) {
  if (this._shouldBeIgnoredCache[fullPath] !== undefined) {
    return this._shouldBeIgnoredCache[fullPath];
  }

  var excludePatterns = this.filterFromCache.exclude;
  var includePatterns = this.filterFromCache.include;
  var i = null;

  // Check exclude patterns
  for (i = 0; i < excludePatterns.length; i++) {
    // An exclude pattern that returns true should be ignored
    if (excludePatterns[i].test(fullPath) === true) {
      return (this._shouldBeIgnoredCache[fullPath] = true);
    }
  }

  // Check include patterns
  if (includePatterns !== undefined && includePatterns.length > 0) {
    for (i = 0; i < includePatterns.length; i++) {
      // An include pattern that returns true (and wasn't excluded at all)
      // should _not_ be ignored
      if (includePatterns[i].test(fullPath) === true) {
        return (this._shouldBeIgnoredCache[fullPath] = false);
      }
    }

    // If no include patterns were matched, ignore this file.
    return (this._shouldBeIgnoredCache[fullPath] = true);
  }

  // Otherwise, don't ignore this file
  return (this._shouldBeIgnoredCache[fullPath] = false);
};

var EMPTY_ARRAY;
function Key(type, fullPath, path, stat, children) {
  this.type = type;
  this.fullPath = fullPath;
  this.path = path;
  this.stat = stat;
  this.children = children || EMPTY_ARRAY;
}

Key.prototype.toString = function() {
  return ' type: '       + this.type +
         ' fullPath: '   + this.fullPath +
         ' path: '       + this.path +
         ' stat.mode: '  + this.stat.mode +
         ' stat.size: '  + this.stat.size +
         ' stat.mtime: ' + this.stat.mtime.getTime();
};

Key.prototype.inspect = function() {
  return [
    this.type,
    this.path,
    this.stat.mode,
    this.stat.size,
    this.stat.size,
    this.stat.mtime.getTime()
  ].join(', ');
};

function logNotEqual(previous, next) {
  debug(" cache eviction due to: \n     - {%o} \n     - {%o}", previous, next);
}

Key.prototype.equal = function(otherKey) {
  if (otherKey === undefined) {
    logNotEqual(this, otherKey);
    return false;
  }

  if (this.type === otherKey.type && this.type === 'directory') {
    var children = this.children;
    var otherChildren = otherKey.children;

    if (children.length === otherChildren.length) {
      for (var i = 0; i < children.length; i++) {
        if (children[i].equal(otherChildren[i])) {
          // they are the same
        } else {
          return false;
        }
      }
    } else {
      return false;
    }
  }

  // key represents a file, diff the file
  if (this.type       === otherKey.type &&
      this.path       === otherKey.path &&
      this.stat.mode  === otherKey.stat.mode &&
      this.stat.size  === otherKey.stat.size &&
      this.type === 'directory' ? true : this.stat.mtime.getTime() === otherKey.stat.mtime.getTime()) {
    return true;
  } else {
    logNotEqual(this, otherKey);
  }
};

proto.keyForTree = function (fullPath, initialRelativePath) {
  var relativePath = initialRelativePath || '.';
  var stats;
  var statKeys;
  var type;

  try {
    stats = fs.statSync(fullPath);
  } catch (err) {
    console.warn('Warning: failed to stat ' + fullPath);
    // fullPath has probably ceased to exist. Leave `stats` undefined and
    // proceed hashing.
  }

  var children;

  // has children;
  if (stats && stats.isDirectory()) {
    type = 'directory';

    var files;
    try {
      files = fs.readdirSync(fullPath).sort();
    } catch (err) {
      console.warn('Warning: Failed to read directory ' + fullPath);
      console.warn(err.stack);
    }

    if (files) {
      children = files.map(function(file) {
        return this.keyForTree(
          path.join(fullPath, file),
          path.join(relativePath, file)
        );
      }, this).filter(Boolean);
    }

  } else if (stats && stats.isFile()) {
    type = 'file';

    if (this.shouldBeIgnored(fullPath)) {
      return null;
    }
  }

  return new Key(type, fullPath, relativePath, stats, children);
};

function CachingWriter (inputTrees, options) {
  if (!(this instanceof CachingWriter)) return new CachingWriter(inputTrees, options);
  CoreObject.apply(this, arguments);
  if (this.init) {
    this.init.apply(this, arguments);
  }
}

CachingWriter.__proto__ = CoreObject;
CachingWriter.prototype = Object.create(CoreObject.prototype);
assign(CachingWriter.prototype, proto);

module.exports = CachingWriter;
<commit_msg>Allow debugging specific trees.<commit_after>var fs = require('fs');
var path = require('path');
var RSVP = require('rsvp');
var rimraf = RSVP.denodeify(require('rimraf'));
var mapSeries = require('promise-map-series');
var quickTemp = require('quick-temp');
var helpers = require('broccoli-kitchen-sink-helpers');
var symlinkOrCopy = require('symlink-or-copy');
var generateRandomString = require('./lib/generate-random-string');
var assign = require('lodash-node/modern/objects/assign');
var CoreObject = require('core-object');
var debugGenerator = require('debug');

var proto = {};

proto.init = function(inputTrees, options) {
  this._inputTreeCacheHash = [];
  this._lastKeys = [];
  this._shouldBeIgnoredCache = Object.create(null);
  this._destDir = path.resolve(path.join('tmp', 'caching-writer-dest-dir_' + generateRandomString(6) + '.tmp'));

  this.debug = debugGenerator('broccoli-caching-writer:' + (this.description || this.constructor.name));

  options = options || {};

  for (var key in options) {
    if (options.hasOwnProperty(key)) {
      this[key] = options[key];
    }
  }

  if (Array.isArray(inputTrees)) {
    if (this.enforceSingleInputTree) {
      throw new Error('You passed an array of input trees, but only a single tree is allowed.');
    }

    this.inputTrees = inputTrees;
  } else {
    this.inputTrees = [inputTrees];
  }

  if (this.filterFromCache === undefined) {
    this.filterFromCache = {};
  }

  if (this.filterFromCache.include === undefined) {
    this.filterFromCache.include = [];
  }

  if (this.filterFromCache.exclude === undefined) {
    this.filterFromCache.exclude = [];
  }

  if (!Array.isArray(this.filterFromCache.include)) {
    throw new Error('Invalid filterFromCache.include option, it must be an array or undefined.');
  }

  if (!Array.isArray(this.filterFromCache.exclude)) {
    throw new Error('Invalid filterFromCache.exclude option, it must be an array or undefined.');
  }
};

proto.enforceSingleInputTree = false;

proto.getCacheDir = function () {
  return quickTemp.makeOrReuse(this, 'tmpCacheDir');
};

proto.getCleanCacheDir = function () {
  return quickTemp.makeOrRemake(this, 'tmpCacheDir');
};

proto.read = function (readTree) {
  var self = this;

  return mapSeries(this.inputTrees, readTree)
    .then(function(inputPaths) {
      var inputTreeHashes = [];
      var invalidateCache = false;
      var key, dir, updateCacheResult;
      var lastKeys = [];

      for (var i = 0, l = inputPaths.length; i < l; i++) {
        dir = inputPaths[i];

        key = self.keyForTree(dir);
        lastKey = self._lastKeys[i];
        lastKeys.push(key);

        if (!invalidateCache /* short circuit */ && !key.equal(lastKey)) {
          invalidateCache = true;
        }
      }

      if (invalidateCache) {
        var updateCacheSrcArg = self.enforceSingleInputTree ? inputPaths[0] : inputPaths;
        updateCacheResult = self.updateCache(updateCacheSrcArg, self.getCleanCacheDir());

        self._lastKeys = lastKeys;

        self._inputTreeCacheHash = inputTreeHashes;
      }

      return updateCacheResult;
    })
    .then(function() {
      return rimraf(self._destDir);
    })
    .then(function() {
      symlinkOrCopy.sync(self.getCacheDir(), self._destDir);
    })
    .then(function() {
      return self._destDir;
    });
};

proto.cleanup = function () {
  quickTemp.remove(this, 'tmpCacheDir');

  // sadly we must use sync removal for now
  if (this._destDir) {
    rimraf.sync(this._destDir);
  }
};

proto.updateCache = function (srcDir, destDir) {
  throw new Error('You must implement updateCache.');
};

// Takes in a path and { include, exclude }. Tests the path using regular expressions and
// returns true if the path does not match any exclude patterns AND matches atleast
// one include pattern.
proto.shouldBeIgnored = function (fullPath) {
  if (this._shouldBeIgnoredCache[fullPath] !== undefined) {
    return this._shouldBeIgnoredCache[fullPath];
  }

  var excludePatterns = this.filterFromCache.exclude;
  var includePatterns = this.filterFromCache.include;
  var i = null;

  // Check exclude patterns
  for (i = 0; i < excludePatterns.length; i++) {
    // An exclude pattern that returns true should be ignored
    if (excludePatterns[i].test(fullPath) === true) {
      return (this._shouldBeIgnoredCache[fullPath] = true);
    }
  }

  // Check include patterns
  if (includePatterns !== undefined && includePatterns.length > 0) {
    for (i = 0; i < includePatterns.length; i++) {
      // An include pattern that returns true (and wasn't excluded at all)
      // should _not_ be ignored
      if (includePatterns[i].test(fullPath) === true) {
        return (this._shouldBeIgnoredCache[fullPath] = false);
      }
    }

    // If no include patterns were matched, ignore this file.
    return (this._shouldBeIgnoredCache[fullPath] = true);
  }

  // Otherwise, don't ignore this file
  return (this._shouldBeIgnoredCache[fullPath] = false);
};

var EMPTY_ARRAY;
function Key(type, fullPath, path, stat, children, debug) {
  this.type = type;
  this.fullPath = fullPath;
  this.path = path;
  this.stat = stat;
  this.children = children || EMPTY_ARRAY;
  this.debug = debug;
}

Key.prototype.toString = function() {
  return ' type: '       + this.type +
         ' fullPath: '   + this.fullPath +
         ' path: '       + this.path +
         ' stat.mode: '  + this.stat.mode +
         ' stat.size: '  + this.stat.size +
         ' stat.mtime: ' + this.stat.mtime.getTime();
};

Key.prototype.inspect = function() {
  return [
    this.type,
    this.path,
    this.stat.mode,
    this.stat.size,
    this.stat.size,
    this.stat.mtime.getTime()
  ].join(', ');
};

function logNotEqual(previous, next) {
  previous.debug(" cache eviction due to: \n     - {%o} \n     - {%o}", previous, next);
}

Key.prototype.equal = function(otherKey) {
  if (otherKey === undefined) {
    logNotEqual(this, otherKey);
    return false;
  }

  if (this.type === otherKey.type && this.type === 'directory') {
    var children = this.children;
    var otherChildren = otherKey.children;

    if (children.length === otherChildren.length) {
      for (var i = 0; i < children.length; i++) {
        if (children[i].equal(otherChildren[i])) {
          // they are the same
        } else {
          return false;
        }
      }
    } else {
      return false;
    }
  }

  // key represents a file, diff the file
  if (this.type       === otherKey.type &&
      this.path       === otherKey.path &&
      this.stat.mode  === otherKey.stat.mode &&
      this.stat.size  === otherKey.stat.size &&
      this.type === 'directory' ? true : this.stat.mtime.getTime() === otherKey.stat.mtime.getTime()) {
    return true;
  } else {
    logNotEqual(this, otherKey);
  }
};

proto.keyForTree = function (fullPath, initialRelativePath) {
  var relativePath = initialRelativePath || '.';
  var stats;
  var statKeys;
  var type;

  try {
    stats = fs.statSync(fullPath);
  } catch (err) {
    console.warn('Warning: failed to stat ' + fullPath);
    // fullPath has probably ceased to exist. Leave `stats` undefined and
    // proceed hashing.
  }

  var children;

  // has children;
  if (stats && stats.isDirectory()) {
    type = 'directory';

    var files;
    try {
      files = fs.readdirSync(fullPath).sort();
    } catch (err) {
      console.warn('Warning: Failed to read directory ' + fullPath);
      console.warn(err.stack);
    }

    if (files) {
      children = files.map(function(file) {
        return this.keyForTree(
          path.join(fullPath, file),
          path.join(relativePath, file)
        );
      }, this).filter(Boolean);
    }

  } else if (stats && stats.isFile()) {
    type = 'file';

    if (this.shouldBeIgnored(fullPath)) {
      return null;
    }
  }

  return new Key(type, fullPath, relativePath, stats, children, this.debug);
};

function CachingWriter (inputTrees, options) {
  if (!(this instanceof CachingWriter)) return new CachingWriter(inputTrees, options);
  CoreObject.apply(this, arguments);
  if (this.init) {
    this.init.apply(this, arguments);
  }
}

CachingWriter.__proto__ = CoreObject;
CachingWriter.prototype = Object.create(CoreObject.prototype);
assign(CachingWriter.prototype, proto);

module.exports = CachingWriter;
<|endoftext|>


<commit_before>// main module for SenseBase
// meant to be modular but that needs some work.

var fs = require('fs'),
  http = require('http'),
  flash = require('connect-flash'),
  express = require('express'),
  passport = require('passport'),
  util = require('util'),
  LocalStrategy = require('passport-local').Strategy;

var fileUpload = require('./lib/file-upload.js'), pubsub;

GLOBAL.authed = GLOBAL.authed || {}; //FIXME  use auth scheme that works behind proxies
var users = require('./users.json').logins;

// start server with a configuration file
exports.start = function(config) {
  config.users = users;
  config.indexer = require('./lib/indexer.js');
  config.pageCache = require('./lib/pageCache.js');
  config.onRequest = require('./lib/auth.js');
  config.onRetrieve = {
    process: function(uri, referer, is_html, pageBuffer, contentType, saveHeaders, browser_request) {
      var status = browser_request.proxy_received.statusCode;
      if (status != 200) {
        return;
      }
      // only index HTML with title
      var m = /<title.*?>(.*)<\/title>/mi.exec(pageBuffer);
      if (m && m[1]) {
        var title = m[1].replace(/<.*?>/g);
        var psMember = browser_request.psMember.username;
        GLOBAL.config.pageCache.cache(uri, referer, is_html, pageBuffer, contentType, saveHeaders, browser_request);
        GLOBAL.config.indexer.saveContentItem({ uri: uri, title: title, member: psMember, referer: referer, isHTML: browser_request.is_html, content: pageBuffer, contentType: contentType, headers: saveHeaders});
        pubsub.requestAnnotate(uri, pageBuffer);
      }
    }
  };
  config.inject = function(content) {
    if (content.toString().match(/<\/body/im)) {
      GLOBAL.debug('injecting iframe');
      content = content.toString().replace(/<\/body/im, '</body');
    }
    return content;
  };
  // globally shared context
  GLOBAL.config = config;
  pubsub = require('./lib/pubsub.js');

  // Passport stuff
  function findById(id, fn) {
    var found = null;
    users.forEach(function(u) {
      if (u.id == id) {
        found = u;
      }
    });
    if (found) {
      fn(null, found);
    } else {
      fn(new Error('User ' + id + ' does not exist'));
    }
  }

  function findByUsername(username, fn) {
    for (var i = 0, len = users.length; i < len; i++) {
      var user = users[i];
      if (user.username === username) {
        return fn(null, user);
      }
    }
    return fn(null, null);
  }

  passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

  passport.deserializeUser(function(id, done) {
    findById(id, function (err, user) {
      done(err, user);
    });
  });

  passport.use(new LocalStrategy(
    function(username, password, done) {
      // asynchronous verification
      process.nextTick(function () {
        findByUsername(username, function(err, user) {
          if (err) { return done(err); }
          if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
          if (user.password != password) { return done(null, false, { message: 'Invalid password' }); }
          if (!user.active) { return done(null, false, { message: 'Account not active' }); }
          return done(null, user);
        });
      });
    }
  ));

  // Express stuff
  var app = express();

  app.configure(function() {
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');
    app.use(express.cookieParser());
    app.use(express.logger({stream: GLOBAL.config.logStream}));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.session({ secret: 'popsicle-fish' }));
    // Initialize Passport!  Also use passport.session() middleware, to support persistent login sessions (recommended).
    app.use(flash());
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    app.use('/lib', express.static(__dirname + '/bower_components'));
    app.use('/files', express.static(GLOBAL.config.uploadDirectory));
    app.use('/__wm', express.static(__dirname + '/static/__wm'));

    app.enable('trust proxy');
  });

  app.all('/__wm/*', function(req, res, next) {
    if (req.user) {
  //console.log('USER', req.user);
      next();
    } else {
      res.redirect("/login");
    }
  });

  app.get('/', function(req, res){
  console.log('OO', req.session.user);
    if (req.user) {
      res.cookie('psMember', req.user.username, { maxAge: 900000 });
      res.cookie('psSession', req.user.id + '/' + new Date().getTime(), { maxAge: 900000 });

      res.redirect('/__wm/index.html');
  //    res.render('index', { user: req.user.username });
    } else {
      res.render('login', { user: req.user, message: req.flash('error') });
    }
  });

  // used by client for identity
  app.get('/member.js', function(req, res) {
    res.render('memberjs', { user: req.user, collab: GLOBAL.config.collab, logo: GLOBAL.config.logo, homepage: GLOBAL.config.homepage });
  });

  app.get('/login', function(req, res){
    res.render('login', { user: req.user, message: req.flash('error') });
  });

  app.post('/login',
    passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
    function(req, res) {
      GLOBAL.authed[req.ip] = req.user;
      console.log('OOOOOOO', req.ip, GLOBAL.authed);
      var oreq = req.headers['original-request'] || '/';
      if (oreq == 'undefined') { oreq = '/'; }
      res.redirect(GLOBAL.config.HOMEPAGE);
    });

  app.get('/logout', function(req, res){
    req.logout();
    res.redirect('/');
  });

  app.post('/upload', function(req, res) {
    fileUpload.uploadFile(req, function(err, resp) {
      if (err) {
       GLOBAL.error('/upload', err);
      } else {
        var content = resp.buffer || 'NOCONTENT', uri = GLOBAL.config.HOMEPAGE + '/files/' + resp.fileName;
        GLOBAL.config.indexer.saveContentItem({ uri: uri, isHTML: true, title: resp.title, member: req.user.username, content: content}, function(err, res, cItem) {
          console.log('uploaded', resp.fileName, cItem);
          pubsub.updateItem(cItem);
          pubsub.requestAnnotate(uri, content);
        });
      }
    });
    res.end();
  });

  var server = app.listen(9999);

  pubsub.start(server);

  var filterProxy = require('filter-proxy');

  filterProxy.start(GLOBAL.config);

  // interactive command line

  repl = require("repl");
  r = repl.start({ prompt: GLOBAL.config.project + "> ", useGlobal: true});
};
<commit_msg>anno after save<commit_after>// main module for SenseBase
// meant to be modular but that needs some work.

var fs = require('fs'),
  http = require('http'),
  flash = require('connect-flash'),
  express = require('express'),
  passport = require('passport'),
  util = require('util'),
  LocalStrategy = require('passport-local').Strategy;

var fileUpload = require('./lib/file-upload.js'), pubsub;

GLOBAL.authed = GLOBAL.authed || {}; //FIXME  use auth scheme that works behind proxies
var users = require('./users.json').logins;

// start server with a configuration file
exports.start = function(config) {
  config.users = users;
  config.indexer = require('./lib/indexer.js');
  config.pageCache = require('./lib/pageCache.js');
  config.onRequest = require('./lib/auth.js');
  config.onRetrieve = {
    process: function(uri, referer, is_html, pageBuffer, contentType, saveHeaders, browser_request) {
      var status = browser_request.proxy_received.statusCode;
      if (status != 200) {
        return;
      }
      // only index HTML with title
      var m = /<title.*?>(.*)<\/title>/mi.exec(pageBuffer);
      if (m && m[1]) {
        var title = m[1].replace(/<.*?>/g);
        var psMember = browser_request.psMember.username;
        GLOBAL.config.pageCache.cache(uri, referer, is_html, pageBuffer, contentType, saveHeaders, browser_request);
        GLOBAL.config.indexer.saveContentItem({ uri: uri, title: title, member: psMember, referer: referer, isHTML: browser_request.is_html, content: pageBuffer, contentType: contentType, headers: saveHeaders},
          function(err, res) {
          pubsub.requestAnnotate(uri, pageBuffer);
        });
      }
    }
  };
  config.inject = function(content) {
    if (content.toString().match(/<\/body/im)) {
      GLOBAL.debug('injecting iframe');
      content = content.toString().replace(/<\/body/im, '</body');
    }
    return content;
  };
  // globally shared context
  GLOBAL.config = config;
  pubsub = require('./lib/pubsub.js');

  // Passport stuff
  function findById(id, fn) {
    var found = null;
    users.forEach(function(u) {
      if (u.id == id) {
        found = u;
      }
    });
    if (found) {
      fn(null, found);
    } else {
      fn(new Error('User ' + id + ' does not exist'));
    }
  }

  function findByUsername(username, fn) {
    for (var i = 0, len = users.length; i < len; i++) {
      var user = users[i];
      if (user.username === username) {
        return fn(null, user);
      }
    }
    return fn(null, null);
  }

  passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

  passport.deserializeUser(function(id, done) {
    findById(id, function (err, user) {
      done(err, user);
    });
  });

  passport.use(new LocalStrategy(
    function(username, password, done) {
      // asynchronous verification
      process.nextTick(function () {
        findByUsername(username, function(err, user) {
          if (err) { return done(err); }
          if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
          if (user.password != password) { return done(null, false, { message: 'Invalid password' }); }
          if (!user.active) { return done(null, false, { message: 'Account not active' }); }
          return done(null, user);
        });
      });
    }
  ));

  // Express stuff
  var app = express();

  app.configure(function() {
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');
    app.use(express.cookieParser());
    app.use(express.logger({stream: GLOBAL.config.logStream}));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.session({ secret: 'popsicle-fish' }));
    // Initialize Passport!  Also use passport.session() middleware, to support persistent login sessions (recommended).
    app.use(flash());
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    app.use('/lib', express.static(__dirname + '/bower_components'));
    app.use('/files', express.static(GLOBAL.config.uploadDirectory));
    app.use('/__wm', express.static(__dirname + '/static/__wm'));

    app.enable('trust proxy');
  });

  app.all('/__wm/*', function(req, res, next) {
    if (req.user) {
  //console.log('USER', req.user);
      next();
    } else {
      res.redirect("/login");
    }
  });

  app.get('/', function(req, res){
  console.log('OO', req.session.user);
    if (req.user) {
      res.cookie('psMember', req.user.username, { maxAge: 900000 });
      res.cookie('psSession', req.user.id + '/' + new Date().getTime(), { maxAge: 900000 });

      res.redirect('/__wm/index.html');
  //    res.render('index', { user: req.user.username });
    } else {
      res.render('login', { user: req.user, message: req.flash('error') });
    }
  });

  // used by client for identity
  app.get('/member.js', function(req, res) {
    res.render('memberjs', { user: req.user, collab: GLOBAL.config.collab, logo: GLOBAL.config.logo, homepage: GLOBAL.config.homepage });
  });

  app.get('/login', function(req, res){
    res.render('login', { user: req.user, message: req.flash('error') });
  });

  app.post('/login',
    passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
    function(req, res) {
      GLOBAL.authed[req.ip] = req.user;
      console.log('OOOOOOO', req.ip, GLOBAL.authed);
      var oreq = req.headers['original-request'] || '/';
      if (oreq == 'undefined') { oreq = '/'; }
      res.redirect(GLOBAL.config.HOMEPAGE);
    });

  app.get('/logout', function(req, res){
    req.logout();
    res.redirect('/');
  });

  app.post('/upload', function(req, res) {
    fileUpload.uploadFile(req, function(err, resp) {
      if (err) {
       GLOBAL.error('/upload', err);
      } else {
        var content = resp.buffer || 'NOCONTENT', uri = GLOBAL.config.HOMEPAGE + '/files/' + resp.fileName;
        GLOBAL.config.indexer.saveContentItem({ uri: uri, isHTML: true, title: resp.title, member: req.user.username, content: content}, function(err, res, cItem) {
          console.log('uploaded', resp.fileName, cItem);
          pubsub.updateItem(cItem);
          pubsub.requestAnnotate(uri, content);
        });
      }
    });
    res.end();
  });

  var server = app.listen(9999);

  pubsub.start(server);

  var filterProxy = require('filter-proxy');

  filterProxy.start(GLOBAL.config);

  // interactive command line

  repl = require("repl");
  r = repl.start({ prompt: GLOBAL.config.project + "> ", useGlobal: true});
};
<|endoftext|>


<commit_before>const memoryjs = require('./build/Release/memoryjs');

module.exports = {

  // data type constants
  INT: 'int',
  DWORD: 'dword',
  LONG: 'long',
  FLOAT: 'float',
  DOUBLE: 'double',
  BOOL: 'bool',
  BOOLEAN: 'boolean',
  PTR: 'ptr',
  POINTER: 'pointer',
  STR: 'str',
  STRING: 'string',
  VEC3: 'vec3',
  VECTOR3: 'vector3',
  VEC4: 'vec4',
  VECTOR4: 'vector4',

  // signature type constants
  NORMAL: 0x0,
  READ: 0x1,
  SUBTRACT: 0x2,

  openProcess(processIdentifier, callback) {
    if (arguments.length === 1) {
      return memoryjs.openProcess(processIdentifier);
    }

    memoryjs.openProcess(processIdentifier, callback);
  },

  getProcesses(callback) {
    if (arguments.length === 0) {
      return memoryjs.getProcesses();
    }

    memoryjs.getProcesses(callback);
  },

  findModule(moduleName, processId, callback) {
    if (arguments.length === 2) {
      return memoryjs.findModule(moduleName, processId);
    }

    memoryjs.findModule(moduleName, processId, callback);
  },

  getModules(processId, callback) {
    if (arguments.length === 1) {
      return memoryjs.getModules(processId);
    }

    memoryjs.getModules(processId, callback);
  },

  readMemory(handle, address, dataType, callback) {
    if (arguments.length === 2) {
      return memoryjs.readMemory(handle, address, dataType.toLowerCase());
    }

    memoryjs.readMemory(handle, address, dataType.toLowerCase(), callback);
  },

  writeMemory(handle, address, value, dataType, callback) {
    if (dataType === 'str' || dataType === 'string') {
      value = value + '\0'; // add terminator
    }

    if (arguments.length === 4) {
      return memoryjs.writeMemory(handle, address, value, dataType.toLowerCase());
    }

    memoryjs.writeMemory(handle, address, value, dataType.toLowerCase(), callback);
  },

  findPattern(handle, moduleName, signature, signatureType, patternOffset, addressOffset, callback) {
    if (arguments.length === 5) {
      return memoryjs.findPattern(handle, moduleName, signature, signatureType, patternOffset, addressOffset);
    }

    memoryjs.findPattern(handle, moduleName, signature, signatureType, patternOffset, addressOffset, callback);
  },

  closeProcess: memoryjs.closeProcess,
};
<commit_msg>Update index.js<commit_after>const memoryjs = require('./build/Release/memoryjs');

module.exports = {

  // data type constants
  INT: 'int',
  DWORD: 'dword',
  LONG: 'long',
  FLOAT: 'float',
  DOUBLE: 'double',
  BOOL: 'bool',
  BOOLEAN: 'boolean',
  PTR: 'ptr',
  POINTER: 'pointer',
  STR: 'str',
  STRING: 'string',
  VEC3: 'vec3',
  VECTOR3: 'vector3',
  VEC4: 'vec4',
  VECTOR4: 'vector4',

  // signature type constants
  NORMAL: 0x0,
  READ: 0x1,
  SUBTRACT: 0x2,

  openProcess(processIdentifier, callback) {
    if (arguments.length === 1) {
      return memoryjs.openProcess(processIdentifier);
    }

    memoryjs.openProcess(processIdentifier, callback);
  },

  getProcesses(callback) {
    if (arguments.length === 0) {
      return memoryjs.getProcesses();
    }

    memoryjs.getProcesses(callback);
  },

  findModule(moduleName, processId, callback) {
    if (arguments.length === 2) {
      return memoryjs.findModule(moduleName, processId);
    }

    memoryjs.findModule(moduleName, processId, callback);
  },

  getModules(processId, callback) {
    if (arguments.length === 1) {
      return memoryjs.getModules(processId);
    }

    memoryjs.getModules(processId, callback);
  },

  readMemory(handle, address, dataType, callback) {
    if (arguments.length === 2) {
      return memoryjs.readMemory(handle, address, dataType.toLowerCase());
    }

    memoryjs.readMemory(handle, address, dataType.toLowerCase(), callback);
  },

  writeMemory(handle, address, value, dataType, callback) {
    if (dataType === 'str' || dataType === 'string') {
      value = value + '\0'; // add terminator
    }

    if (arguments.length === 4) {
      return memoryjs.writeMemory(handle, address, value, dataType.toLowerCase());
    }

    memoryjs.writeMemory(handle, address, value, dataType.toLowerCase(), callback);
  },

  findPattern(handle, moduleName, signature, signatureType, patternOffset, addressOffset, callback) {
    if (arguments.length === 6) {
      return memoryjs.findPattern(handle, moduleName, signature, signatureType, patternOffset, addressOffset);
    }

    memoryjs.findPattern(handle, moduleName, signature, signatureType, patternOffset, addressOffset, callback);
  },

  closeProcess: memoryjs.closeProcess,
};
<|endoftext|>


<commit_before>var _ = require('lodash');
var endings = require('./lib/endings');
var lettersToTonify = require('./lib/letters-to-tonify');
var toneMap = require('./lib/tone-map');
var toneNumbers = [1, 2, 3, 4];

module.exports = tonifyPhrase;

/**
 * @param {string} phrase
 * @return {string}
 */
function tonifyPhrase(phrase) {
  var words = splitPhraseIntoWords(phrase);
  var tonifiedWords = words.map(tonifyWord);

  return tonifiedWords.join(' ');
}

/**
 * @param {string} word
 * @return {string}
 */
function tonifyWord(word) {
  var tone = getTone(word);
  var ending = getEnding(word);

  if (!tone || !ending) {
    return getTonelessFallback(word);
  }

  // TODO: Refactor this exception.
  if (_.includes(['nue', 'lue'], stripToneNumber(word))) {
    word = word.replace('u', 'ü');
    ending = ending.replace('u', 'ü');
  }

  var tonifiedEnding = tonifyEnding(ending, tone);
  var tonifiedWord = word.replace(ending, tonifiedEnding);

  return stripToneNumber(tonifiedWord);
}

/**
 * @param {string} word
 * @return {string}
 */
function getTonelessFallback(word) {
  switch (word) {
    case 'lv':
      return 'lü';

    case 'nv':
      return 'nü';

    case 'lue':
      return 'lüe';

    case 'nue':
      return 'nüe';

    default:
      return word;
  }
}

/**
 * @param {string} letter
 * @param {number} tone
 * @return {string}
 */
function tonifyLetter(letter, tone) {
  var keys = letter + '.' + tone;
  return _.get(toneMap, keys, letter);
}

/**
 * @param {string} ending
 * @param {number} tone
 * @return {string}
 */
function tonifyEnding(ending, tone) {
  var letter;

  _.forEach(lettersToTonify, function(letterAndPattern) {
    if (!letter && ending.match(letterAndPattern.pattern)) {
      letter = letterAndPattern.letter;
    }
  });

  if (!letter) {
    return ending;
  }

  return ending.replace(letter, tonifyLetter(letter, tone));
}

/**
 * @param {string} word
 * @return {string}
 */
function stripToneNumber(word) {
  return _.trim(word, toneNumbers);
}

/**
 * @param {string} phrase
 * @return {array}
 */
function splitPhraseIntoWords(phrase) {
  return phrase.split(' ');
}

/**
 * @param {string} word
 * @return {number|null}
 */
function getTone(word) {
  var lastCharacter = parseInt(_.last(word), 10);
  return _.includes(toneNumbers, lastCharacter) ? lastCharacter : null;
}

/**
 * @param {string} word
 * @return {string|null}
 */
function getEnding(word) {
  var ending = null;

  _.forEach(endings, function(pattern, plainEnding) {
    if (word.match(pattern)) {
      ending = plainEnding;
    }
  });

  return ending;
}
<commit_msg>Refactor and simplify switch statement<commit_after>var _ = require('lodash');
var endings = require('./lib/endings');
var lettersToTonify = require('./lib/letters-to-tonify');
var toneMap = require('./lib/tone-map');
var toneNumbers = [1, 2, 3, 4];

module.exports = tonifyPhrase;

/**
 * @param {string} phrase
 * @return {string}
 */
function tonifyPhrase(phrase) {
  var words = splitPhraseIntoWords(phrase);
  var tonifiedWords = words.map(tonifyWord);

  return tonifiedWords.join(' ');
}

/**
 * @param {string} word
 * @return {string}
 */
function tonifyWord(word) {
  var tone = getTone(word);
  var ending = getEnding(word);

  if (!tone || !ending) {
    return getTonelessFallback(word);
  }

  // TODO: Refactor this exception.
  if (_.includes(['nue', 'lue'], stripToneNumber(word))) {
    word = word.replace('u', 'ü');
    ending = ending.replace('u', 'ü');
  }

  var tonifiedEnding = tonifyEnding(ending, tone);
  var tonifiedWord = word.replace(ending, tonifiedEnding);

  return stripToneNumber(tonifiedWord);
}

/**
 * @param {string} word
 * @return {string}
 */
function getTonelessFallback(word) {
  var fallbackIoMap = {
    lv: 'lü',
    nv: 'nü',
    lue: 'lüe',
    nue: 'nüe'
  };

  return _.get(fallbackIoMap, word, word);
}

/**
 * @param {string} letter
 * @param {number} tone
 * @return {string}
 */
function tonifyLetter(letter, tone) {
  var keys = letter + '.' + tone;
  return _.get(toneMap, keys, letter);
}

/**
 * @param {string} ending
 * @param {number} tone
 * @return {string}
 */
function tonifyEnding(ending, tone) {
  var letter;

  _.forEach(lettersToTonify, function(letterAndPattern) {
    if (!letter && ending.match(letterAndPattern.pattern)) {
      letter = letterAndPattern.letter;
    }
  });

  if (!letter) {
    return ending;
  }

  return ending.replace(letter, tonifyLetter(letter, tone));
}

/**
 * @param {string} word
 * @return {string}
 */
function stripToneNumber(word) {
  return _.trim(word, toneNumbers);
}

/**
 * @param {string} phrase
 * @return {array}
 */
function splitPhraseIntoWords(phrase) {
  return phrase.split(' ');
}

/**
 * @param {string} word
 * @return {number|null}
 */
function getTone(word) {
  var lastCharacter = parseInt(_.last(word), 10);
  return _.includes(toneNumbers, lastCharacter) ? lastCharacter : null;
}

/**
 * @param {string} word
 * @return {string|null}
 */
function getEnding(word) {
  var ending = null;

  _.forEach(endings, function(pattern, plainEnding) {
    if (word.match(pattern)) {
      ending = plainEnding;
    }
  });

  return ending;
}
<|endoftext|>


<commit_before>var map = require('pull-stream').map
//split lines into csv, including escaping commas

var splitter = /(\s*"[^"]*"\s*|[^,]*)/

exports.parseLine = function (line) {
  return line.split(splitter).filter(function (_, i) {
    return i % 2
  }).map(function (cell) {
    cell = cell.trim()
    return (
      /^"[^"]*"$/.test(cell)
      ? cell.substring(1, cell.length - 1)
      : cell
    )
  }
}
exports.stringifyLine = function (line) {
  return line.map(function (cell) {
    cell = cell.toString()
    return ~cell.indexOf(',') ? '"' + cell + '"' : cell
  }) + '\n'
}

exports.decode =
exports.parse = function () {
  return map(exports.parseLine)
  })
}

exports.encode =
exports.stringify = function () {
  return map(exports.stringifyLine)
}

<commit_msg>syntax<commit_after>var map = require('pull-stream').map
//split lines into csv, including escaping commas

var splitter = /(\s*"[^"]*"\s*|[^,]*)/

exports.parseLine = function (line) {
  return line.split(splitter).filter(function (_, i) {
    return i % 2
  }).map(function (cell) {
    cell = cell.trim()
    return (
      /^"[^"]*"$/.test(cell)
      ? cell.substring(1, cell.length - 1)
      : cell
    )
  })
}
exports.stringifyLine = function (line) {
  return line.map(function (cell) {
    cell = cell.toString()
    return ~cell.indexOf(',') ? '"' + cell + '"' : cell
  }) + '\n'
}

exports.decode =
exports.parse = function () {
  return map(exports.parseLine)
}

exports.encode =
exports.stringify = function () {
  return map(exports.stringifyLine)
}

<|endoftext|>


<commit_before>
var crypto = require('crypto');

var hotp = {};

/**
 * Generate a counter based One Time Password
 *
 * @return {String} the one time password
 *
 * Arguments:
 *
 *  args
 *     key - Key for the one time password.  This should be unique and secret for
 *         every user as this is the seed that is used to calculate the HMAC
 *
 *     counter - Counter value.  This should be stored by the application, must
 *         be user specific, and be incremented for each request.
 *
 */
hotp.gen = function(key, opt) {
	key = key || '';
	opt = opt || {};
	var counter = opt.counter || 0;
	var characters = opt.characters || 4;
	var modulo = '1';

	for(var x = characters; x--;) modulo = modulo + '0';

	// Create the byte array
	var b = new Buffer(intToBytes(counter));

	var hmac = crypto.createHmac('sha1', new Buffer(key));

	// Update the HMAC with the byte array
	var digest = hmac.update(b).digest('hex');

	// Get byte array
	var h = hexToBytes(digest);

	// Truncate
	var offset = h[19] & 0xf;
	var v = (h[offset] & 0x7f) << 24 |
		(h[offset + 1] & 0xff) << 16 |
		(h[offset + 2] & 0xff) << 8  |
		(h[offset + 3] & 0xff);
		console.log(v);

	v = (v % parseInt(modulo)) + '';

	return Array((characters + 1)-v.length).join('0') + v;
};

/**
 * Check a One Time Password based on a counter.
 *
 * @return {Object} null if failure, { delta: # } on success
 * delta is the time step difference between the client and the server
 *
 * Arguments:
 *
 *  args
 *     key - Key for the one time password.  This should be unique and secret for
 *         every user as it is the seed used to calculate the HMAC
 *
 *     token - Passcode to validate.
 *
 *     window - The allowable margin for the counter.  The function will check
 *         'W' codes in the future against the provided passcode.  Note,
 *         it is the calling applications responsibility to keep track of
 *         'W' and increment it for each password check, and also to adjust
 *         it accordingly in the case where the client and server become
 *         out of sync (second argument returns non zero).
 *         E.g. if W = 100, and C = 5, this function will check the passcode
 *         against all One Time Passcodes between 5 and 105.
 *
 *         Default - 50
 *
 *     counter - Counter value.  This should be stored by the application, must
 *         be user specific, and be incremented for each request.
 *
 */
hotp.verify = function(token, key, opt) {
	opt = opt || {};
	var window = opt.window || 50;
	var counter = opt.counter || 0;

	// Now loop through from C to C + W to determine if there is
	// a correct code
	for(var i = counter - window; i <=  counter + window; ++i) {
		opt.counter = i;
		if(this.gen(key, opt) === token) {
			// We have found a matching code, trigger callback
			// and pass offset
			return { delta: i - counter };
		}
	}

	// If we get to here then no codes have matched, return null
	return null;
};

var totp = {};

/**
 * Generate a time based One Time Password
 *
 * @return {String} the one time password
 *
 * Arguments:
 *
 *  args
 *     key - Key for the one time password.  This should be unique and secret for
 *         every user as it is the seed used to calculate the HMAC
 *
 *     time - The time step of the counter.  This must be the same for
 *         every request and is used to calculat C.
 *
 *         Default - 30
 *
 */
totp.gen = function(key, opt) {
	opt = opt || {};
	var time = opt.time || 30;
	var _t = new Date().getTime();

	// Time has been overwritten.
	if(opt._t) {
		if(process.env.NODE_ENV != 'test') {
			throw new Error('cannot overwrite time in non-test environment!');
		}
		_t = opt._t;
	}

	// Determine the value of the counter, C
	// This is the number of time steps in seconds since T0
	opt.counter = Math.floor((_t / 1000) / time);

	return hotp.gen(key, opt);
};

/**
 * Check a One Time Password based on a timer.
 *
 * @return {Object} null if failure, { delta: # } on success
 * delta is the time step difference between the client and the server
 *
 * Arguments:
 *
 *  args
 *     key - Key for the one time password.  This should be unique and secret for
 *         every user as it is the seed used to calculate the HMAC
 *
 *     token - Passcode to validate.
 *
 *     window - The allowable margin for the counter.  The function will check
 *         'W' codes either side of the provided counter.  Note,
 *         it is the calling applications responsibility to keep track of
 *         'W' and increment it for each password check, and also to adjust
 *         it accordingly in the case where the client and server become
 *         out of sync (second argument returns non zero).
 *         E.g. if W = 5, and C = 1000, this function will check the passcode
 *         against all One Time Passcodes between 995 and 1005.
 *
 *         Default - 6
 *
 *     time - The time step of the counter.  This must be the same for
 *         every request and is used to calculate C.
 *
 *         Default - 30
 *
 */
totp.verify = function(token, key, opt) {
	opt = opt || {};
	var time = opt.time || 30;
	var _t = new Date().getTime();

	// Time has been overwritten.
	if(opt._t) {
		if(process.env.NODE_ENV != 'test') {
			throw new Error('cannot overwrite time in non-test environment!');
		}
		_t = opt._t;
	}

	// Determine the value of the counter, C
	// This is the number of time steps in seconds since T0
	opt.counter = Math.floor((_t / 1000) / time);

	return hotp.verify(token, key, opt);
};

module.exports.hotp = hotp;
module.exports.totp = totp;

/**
 * convert an integer to a byte array
 * @param {Integer} num
 * @return {Array} bytes
 */
var intToBytes = function(num) {
	var bytes = [];

	for(var i=7 ; i>=0 ; --i) {
		bytes[i] = num & (255);
		num = num >> 8;
	}

	return bytes;
};

/**
 * convert a hex value to a byte array
 * @param {String} hex string of hex to convert to a byte array
 * @return {Array} bytes
 */
var hexToBytes = function(hex) {
	var bytes = [];
	for(var c = 0, C = hex.length; c < C; c += 2) {
		bytes.push(parseInt(hex.substr(c, 2), 16));
	}
	return bytes;
};
<commit_msg>update index.js<commit_after>
var crypto = require('crypto');

var hotp = {};

/**
 * Generate a counter based One Time Password
 *
 * @return {String} the one time password
 *
 * Arguments:
 *
 *  args
 *     key - Key for the one time password.  This should be unique and secret for
 *         every user as this is the seed that is used to calculate the HMAC
 *
 *     counter - Counter value.  This should be stored by the application, must
 *         be user specific, and be incremented for each request.
 *
 */
hotp.gen = function(key, opt) {
	key = key || '';
	opt = opt || {};
	var counter = opt.counter || 0;
	var characters = opt.characters || 4;
	var modulo = '1';

	for(var x = characters; x--;) modulo = modulo + '0';

	// Create the byte array
	var b = new Buffer(intToBytes(counter));

	var hmac = crypto.createHmac('sha1', new Buffer(key));

	// Update the HMAC with the byte array
	var digest = hmac.update(b).digest('hex');

	// Get byte array
	var h = hexToBytes(digest);

	// Truncate
	var offset = h[19] & 0xf;
	var v = (h[offset] & 0x7f) << 24 |
		(h[offset + 1] & 0xff) << 16 |
		(h[offset + 2] & 0xff) << 8  |
		(h[offset + 3] & 0xff);

	v = (v % parseInt(modulo)) + '';

	return Array((characters + 1)-v.length).join('0') + v;
};

/**
 * Check a One Time Password based on a counter.
 *
 * @return {Object} null if failure, { delta: # } on success
 * delta is the time step difference between the client and the server
 *
 * Arguments:
 *
 *  args
 *     key - Key for the one time password.  This should be unique and secret for
 *         every user as it is the seed used to calculate the HMAC
 *
 *     token - Passcode to validate.
 *
 *     window - The allowable margin for the counter.  The function will check
 *         'W' codes in the future against the provided passcode.  Note,
 *         it is the calling applications responsibility to keep track of
 *         'W' and increment it for each password check, and also to adjust
 *         it accordingly in the case where the client and server become
 *         out of sync (second argument returns non zero).
 *         E.g. if W = 100, and C = 5, this function will check the passcode
 *         against all One Time Passcodes between 5 and 105.
 *
 *         Default - 50
 *
 *     counter - Counter value.  This should be stored by the application, must
 *         be user specific, and be incremented for each request.
 *
 */
hotp.verify = function(token, key, opt) {
	opt = opt || {};
	var window = opt.window || 50;
	var counter = opt.counter || 0;

	// Now loop through from C to C + W to determine if there is
	// a correct code
	for(var i = counter - window; i <=  counter + window; ++i) {
		opt.counter = i;
		if(this.gen(key, opt) === token) {
			// We have found a matching code, trigger callback
			// and pass offset
			return { delta: i - counter };
		}
	}

	// If we get to here then no codes have matched, return null
	return null;
};

var totp = {};

/**
 * Generate a time based One Time Password
 *
 * @return {String} the one time password
 *
 * Arguments:
 *
 *  args
 *     key - Key for the one time password.  This should be unique and secret for
 *         every user as it is the seed used to calculate the HMAC
 *
 *     time - The time step of the counter.  This must be the same for
 *         every request and is used to calculat C.
 *
 *         Default - 30
 *
 */
totp.gen = function(key, opt) {
	opt = opt || {};
	var time = opt.time || 30;
	var _t = new Date().getTime();

	// Time has been overwritten.
	if(opt._t) {
		if(process.env.NODE_ENV != 'test') {
			throw new Error('cannot overwrite time in non-test environment!');
		}
		_t = opt._t;
	}

	// Determine the value of the counter, C
	// This is the number of time steps in seconds since T0
	opt.counter = Math.floor((_t / 1000) / time);

	return hotp.gen(key, opt);
};

/**
 * Check a One Time Password based on a timer.
 *
 * @return {Object} null if failure, { delta: # } on success
 * delta is the time step difference between the client and the server
 *
 * Arguments:
 *
 *  args
 *     key - Key for the one time password.  This should be unique and secret for
 *         every user as it is the seed used to calculate the HMAC
 *
 *     token - Passcode to validate.
 *
 *     window - The allowable margin for the counter.  The function will check
 *         'W' codes either side of the provided counter.  Note,
 *         it is the calling applications responsibility to keep track of
 *         'W' and increment it for each password check, and also to adjust
 *         it accordingly in the case where the client and server become
 *         out of sync (second argument returns non zero).
 *         E.g. if W = 5, and C = 1000, this function will check the passcode
 *         against all One Time Passcodes between 995 and 1005.
 *
 *         Default - 6
 *
 *     time - The time step of the counter.  This must be the same for
 *         every request and is used to calculate C.
 *
 *         Default - 30
 *
 */
totp.verify = function(token, key, opt) {
	opt = opt || {};
	var time = opt.time || 30;
	var _t = new Date().getTime();

	// Time has been overwritten.
	if(opt._t) {
		if(process.env.NODE_ENV != 'test') {
			throw new Error('cannot overwrite time in non-test environment!');
		}
		_t = opt._t;
	}

	// Determine the value of the counter, C
	// This is the number of time steps in seconds since T0
	opt.counter = Math.floor((_t / 1000) / time);

	return hotp.verify(token, key, opt);
};

module.exports.hotp = hotp;
module.exports.totp = totp;

/**
 * convert an integer to a byte array
 * @param {Integer} num
 * @return {Array} bytes
 */
var intToBytes = function(num) {
	var bytes = [];

	for(var i=7 ; i>=0 ; --i) {
		bytes[i] = num & (255);
		num = num >> 8;
	}

	return bytes;
};

/**
 * convert a hex value to a byte array
 * @param {String} hex string of hex to convert to a byte array
 * @return {Array} bytes
 */
var hexToBytes = function(hex) {
	var bytes = [];
	for(var c = 0, C = hex.length; c < C; c += 2) {
		bytes.push(parseInt(hex.substr(c, 2), 16));
	}
	return bytes;
};
<|endoftext|>


<commit_before>var cheerio = require('cheerio');

var variableRE = /\{\{(.*?)\}\}/g;
var blankRE = /^[\s]*$/;
var debug = false;
var count;

function getVariableArray(string) {
  var array = [];
  var lastOffset = 0;

  string.replace(variableRE, function(match, p1, offset, string) {
    // Add intermediate text
    var text = string.slice(lastOffset, offset);
    if (text.length) {
      array.push(text);
    }

    // Add variables
    array.push({ variable: p1 });

    lastOffset = offset + match.length;

    return match;
  });

  // Add the last bit of text
  if (lastOffset !== string.length) {
    array.push(string.slice(lastOffset));
  }

  return array;
}

function isBlank(string) {
  return !!string.match(blankRE);
}

function makeVariableExpression(string) {
  if (!usesVariables(string)) {
    return safe(string);
  }

  var expression = '';
  var pieces = getVariableArray(string);
  pieces.forEach(function(piece, index) {
    // Concat pieces together
    if (index !== 0) {
      expression += '+';
    }

    if (typeof piece === 'string') {
      // Include text directly
      expression += safe(piece);
    }
    else {
      // Substitute variables
      expression += 'data['+safe(piece.variable)+']';
    }
  });

  return expression;
}

function safe(string) {
  return JSON.stringify(string);
}

function createElement(elName, tag, elHandle) {
  var statement = 'var '+elName+' = ';
  var handleUsesDollar;
  var elHandleBare;
  var handleProperty;

  if (elHandle) {
    handleUsesDollar = elHandle.charAt(0) === '$';
    elHandleBare = handleUsesDollar ? elHandle.slice(1) : elHandle;
    handleProperty = 'this['+safe(elHandleBare)+']';
  }

  if (elHandle) {
    statement += handleProperty+' = ';
  }
  statement += 'document.createElement("'+tag+'");\n';

  if (elHandle && handleUsesDollar) {
    statement += 'this['+safe(elHandle)+'] = $('+elName+');\n';
  }

  return statement;
}

function setAttribute(elName, attr, value) {
  return elName+'.setAttribute('+safe(attr)+', '+makeVariableExpression(value)+');\n';
}

function setTextContent(elName, text) {
  return elName+'.textContent = '+makeVariableExpression(text)+';\n';
}

function usesVariables(string) {
  return string.match(variableRE);
}

function createTextNode(elName, text) {
  return 'var '+elName+' = document.createTextNode('+makeVariableExpression(text)+');\n';
}

function dataWrap(str) {
  return 'data['+safe(str)+']';
}

function buildFunctionBody($, el, options, parentName) {
  var func = '';
  var text;

  el.children.forEach(function(el) {
    var elName = 'el'+(count++);
    var doAppend = true;
    var needsClose = false;
    var elseEl;
    if (el.type === 'tag') {
      // Process special tags
      if (el.name === 'if') {
        // Anything inside of the if should be inserted in the parent
        elName = parentName;
        doAppend = false;
        needsClose = true;
        func += 'if ('+Object.keys(el.attribs).map(dataWrap).join('&&')+') {\n';

        // Find else statement
        elseEl = $(el).children('else');
        if (elseEl.length) {
          $(elseEl).remove();
        }
      }
      else if (el.name === 'else') {
        throw new Error('Found <else> without <if>');
      }
      else {
        func += createElement(elName, el.name, el.attribs['data-handle']);

        var attrs = el.attribs;
        for (var attr in attrs) {
          // Skip internal handles
          if (attr === 'data-handle') {
            continue;
          }
          func += setAttribute(elName, attr, attrs[attr]);
        }
      }

      var children = el.children;
      if (children.length) {
        func += buildFunctionBody($, el, options, elName);
      }
      else {
        text = $(el).text();

        if (!(options.stripWhitespace && isBlank(text)) || text.length) {
          // Set text content directly if there are no children
          func += setTextContent(elName, text);
        }
      }

      if (needsClose) {
        func += '}\n';

        if (elseEl.length) {
          func += 'else {\n';
          func += buildFunctionBody($, elseEl[0], options, elName);
          func += '}\n';
        }
      }
    }
    else if (el.type === 'text') {
      text = $(el).text();

      // Don't include blank text nodes
      if ((options.stripWhitespace && isBlank(text)) || !text.length) {
        return;
      }

      func += createTextNode(elName, text);
    }

    if (parentName && doAppend) {
      func += parentName+'.appendChild('+elName+');\n';
    }
  });

  return func;
}

function indent(spaces) {
  return (new Array(spaces)).join('\t');
}

function prettyPrint(node, spaces) {
  var isFirst = spaces === undefined;

  spaces = spaces || 0;

  var name = node.type === 'tag' ? node.name : 'text';
  var desc = '';

  if (node.type === 'text') {
    desc = node.data;
  }
  else {
    for (var attr in node.attribs) {
      desc += attr+'='+node.attribs[attr]+' ';
    }
  }

  if (!isFirst) {
    console.log(indent(spaces), name, desc);
  }

  if (node.children) {
    node.children.forEach(function(child) {
      prettyPrint(child, spaces+1);
    })
  }
}

function compile(html, options) {
  var $ = cheerio.load('
'+html+'
');

  var root = $('#__template-root__')[0];

  if (debug) {
    prettyPrint(root);
  }

  // Reset count
  count = 0;

  // Build function body
  var functionBody = buildFunctionBody($, root, options || {});

  if (root.children.length === 1) {
    // Return the root element, if there's only one
    functionBody += 'return el0;\n';
  }

  return new Function('data', functionBody);
}

module.exports = compile;
<commit_msg>Simplify handling of statements<commit_after>var cheerio = require('cheerio');

var variableRE = /\{\{(.*?)\}\}/g;
var blankRE = /^[\s]*$/;
var debug = false;
var count;

function getVariableArray(string) {
  var array = [];
  var lastOffset = 0;

  string.replace(variableRE, function(match, p1, offset, string) {
    // Add intermediate text
    var text = string.slice(lastOffset, offset);
    if (text.length) {
      array.push(text);
    }

    // Add variables
    array.push({ variable: p1 });

    lastOffset = offset + match.length;

    return match;
  });

  // Add the last bit of text
  if (lastOffset !== string.length) {
    array.push(string.slice(lastOffset));
  }

  return array;
}

function isBlank(string) {
  return !!string.match(blankRE);
}

function makeVariableExpression(string) {
  if (!usesVariables(string)) {
    return safe(string);
  }

  var expression = '';
  var pieces = getVariableArray(string);
  pieces.forEach(function(piece, index) {
    // Concat pieces together
    if (index !== 0) {
      expression += '+';
    }

    if (typeof piece === 'string') {
      // Include text directly
      expression += safe(piece);
    }
    else {
      // Substitute variables
      expression += 'data['+safe(piece.variable)+']';
    }
  });

  return expression;
}

function safe(string) {
  return JSON.stringify(string);
}

function createElement(elName, tag, elHandle) {
  var statement = 'var '+elName+' = ';
  var handleUsesDollar;
  var elHandleBare;
  var handleProperty;

  if (elHandle) {
    handleUsesDollar = elHandle.charAt(0) === '$';
    elHandleBare = handleUsesDollar ? elHandle.slice(1) : elHandle;
    handleProperty = 'this['+safe(elHandleBare)+']';
  }

  if (elHandle) {
    statement += handleProperty+' = ';
  }
  statement += 'document.createElement("'+tag+'");\n';

  if (elHandle && handleUsesDollar) {
    statement += 'this['+safe(elHandle)+'] = $('+elName+');\n';
  }

  return statement;
}

function setAttribute(elName, attr, value) {
  return elName+'.setAttribute('+safe(attr)+', '+makeVariableExpression(value)+');\n';
}

function setTextContent(elName, text) {
  return elName+'.textContent = '+makeVariableExpression(text)+';\n';
}

function usesVariables(string) {
  return string.match(variableRE);
}

function createTextNode(elName, text) {
  return 'var '+elName+' = document.createTextNode('+makeVariableExpression(text)+');\n';
}

function dataWrap(str) {
  return 'data['+safe(str)+']';
}

function buildFunctionBody($, el, options, parentName) {
  var func = '';
  var text;

  el.children.forEach(function(el) {
    var elName = 'el'+(count++);
    var elseEl;
    if (el.type === 'tag') {
      // Process special tags
      if (el.name === 'if') {
        // Find else statement
        elseEl = $(el).children('else');
        if (elseEl.length) {
          $(elseEl).remove();
        }

        func += 'if ('+Object.keys(el.attribs).map(dataWrap).join('&&')+') {\n';
        func += buildFunctionBody($, el, options, parentName);
        func += '}\n';

        if (elseEl.length) {
          func += 'else {\n';
          func += buildFunctionBody($, elseEl[0], options, parentName);
          func += '}\n';
        }

        return;
      }
      else if (el.name === 'else') {
        throw new Error('Found <else> without <if>');
      }
      else {
        func += createElement(elName, el.name, el.attribs['data-handle']);

        var attrs = el.attribs;
        for (var attr in attrs) {
          // Skip internal handles
          if (attr === 'data-handle') {
            continue;
          }
          func += setAttribute(elName, attr, attrs[attr]);
        }

        var children = el.children;
        if (children.length) {
          func += buildFunctionBody($, el, options, elName);
        }
        else {
          text = $(el).text();

          if (!(options.stripWhitespace && isBlank(text)) || text.length) {
            // Set text content directly if there are no children
            func += setTextContent(elName, text);
          }
        }
      }
    }
    else if (el.type === 'text') {
      text = $(el).text();

      // Don't include blank text nodes
      if ((options.stripWhitespace && isBlank(text)) || !text.length) {
        return;
      }

      func += createTextNode(elName, text);
    }

    if (parentName) {
      func += parentName+'.appendChild('+elName+');\n';
    }
  });

  return func;
}

function indent(spaces) {
  return (new Array(spaces)).join('\t');
}

function prettyPrint(node, spaces) {
  var isFirst = spaces === undefined;

  spaces = spaces || 0;

  var name = node.type === 'tag' ? node.name : 'text';
  var desc = '';

  if (node.type === 'text') {
    desc = node.data;
  }
  else {
    for (var attr in node.attribs) {
      desc += attr+'='+node.attribs[attr]+' ';
    }
  }

  if (!isFirst) {
    console.log(indent(spaces), name, desc);
  }

  if (node.children) {
    node.children.forEach(function(child) {
      prettyPrint(child, spaces+1);
    })
  }
}

function compile(html, options) {
  var $ = cheerio.load('
'+html+'
');

  var root = $('#__template-root__')[0];

  if (debug) {
    prettyPrint(root);
  }

  // Reset count
  count = 0;

  // Build function body
  var functionBody = buildFunctionBody($, root, options || {});

  if (root.children.length === 1) {
    // Return the root element, if there's only one
    functionBody += 'return el0;\n';
  }

  if (debug) {
    console.log(functionBody);
  }

  return new Function('data', functionBody);
}

module.exports = compile;
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';
import { Link } from 'routes';

// Components
import Title from 'components/ui/Title';
import Button from 'components/ui/Button';
import DatasetWidgetChart from 'components/app/explore/DatasetWidgetChart';
import DatasetLayerChart from 'components/app/explore/DatasetLayerChart';
import DatasetPlaceholderChart from 'components/app/explore/DatasetPlaceholderChart';
import { toggleDatasetActive, setUrlParams, setDatasetsHidden } from 'redactions/explore';

class DatasetWidget extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      active: props.active,
      dataset: props.dataset,
      widget: props.widget,
      layer: props.layer,
      hasWidget: !!props.widget,
      hasLayer: !!props.layer,
      mode: props.mode
    };

    // BINDINGS
    this.triggerToggleLayer = this.triggerToggleLayer.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      active: nextProps.active,
      dataset: nextProps.dataset,
      widget: nextProps.widget,
      layer: nextProps.layer,
      hasWidget: !!nextProps.widget,
      hasLayer: !!nextProps.layer,
      mode: nextProps.mode
    });
  }

  /**
   * HELPERS
   * - hideLayer
   * - getWidgetOrLayer
   * - getDescription
   * - getButton
  */
  getButton() {
    const { active, layer } = this.state;
    const buttonText = (active) ? 'Active' : 'Add to map';
    const buttonClass = (active) ? '-active' : '';

    if (layer) {
      return (
        <Button
          properties={{
            className: `-primary -fullwidth ${buttonClass}`
          }}
          onClick={this.triggerToggleLayer}
        >
          {buttonText}
        </Button>
      );
    }
    return (
      <Button
        properties={{
          disabled: true,
          className: '-primary -fullwidth -disabled'
        }}
        onClick={this.triggerToggleLayer}
      >
        Not displayable
      </Button>

    );
  }

  getWidgetOrLayer() {
    if (this.state.hasWidget) {
      return {
        ...this.state.widget.attributes,
        id: this.state.widget.id
      };
    }
    if (this.state.hasLayer) {
      return {
        ...this.state.layer.attributes,
        id: this.state.layer.id
      };
    }
    return null;
  }

  getDescription(_text) {
    let text = _text;
    if (typeof text === 'string' && text.length > 70) {
      text = text.replace(/^(.{70}[^\s]*).*/, '$1');
      return `${text}...`;
    }
    return text;
  }

  hideLayer(dataset) {
    let newLayersHidden = this.props.layersHidden.slice();
    if (this.props.layersHidden.includes(dataset)) {
      newLayersHidden = this.props.layersHidden.filter(l => l !== dataset);
    } else {
      newLayersHidden.push(dataset);
    }

    this.props.setDatasetsHidden(newLayersHidden);
  }

  /**
   * UI EVENTS
   * - triggerToggleLayer (e)
  */
  triggerToggleLayer() {
    const { dataset } = this.state;
    this.props.toggleDatasetActive(dataset.id);
    if (this.props.layersHidden.includes(dataset.id)) {
      this.hideLayer(dataset.id);
    }
  }

  render() {
    const { hasWidget, hasLayer, mode, dataset } = this.state;
    const { showActions } = this.props;
    const gridMode = (mode === 'grid');
    const element = this.getWidgetOrLayer();

    return (
      <div className={`c-dataset-list-item -${mode}`}>
        {/* If it has widget we want to renderize the default widget one */}
        {hasWidget && gridMode &&
          <DatasetWidgetChart widget={element} />
        }
        {/* If it doesn't have widget but has layer we want to renderize the default layer one */}
        {!hasWidget && hasLayer && gridMode &&
          <DatasetLayerChart layer={element} />
        }

        {!hasWidget && !hasLayer && gridMode &&
          <DatasetPlaceholderChart />
        }

            {/* Title */}
            <Title className="-default -primary">
              <Link
                route={'explore_detail'}
                params={{ id: dataset.id }}
              >
                {dataset.attributes.name}
              </Link>
            </Title>

            {/* Description */}
            {dataset.attributes.metadata && (dataset.attributes.metadata.length > 0)
              && dataset.attributes.metadata[0].attributes.description &&

{this.getDescription(dataset.attributes.metadata[0].attributes.description)}

            }

            {/* Source */}
            {dataset.attributes.metadata && (dataset.attributes.metadata.length > 0)
              && dataset.attributes.metadata[0].attributes.source &&

Source: {dataset.attributes.metadata[0].attributes.source}

            }

            {/* Layer Button */}
            {showActions && this.getButton()}

    );
  }
}

DatasetWidget.propTypes = {
  // STATE
  active: PropTypes.bool,
  layersHidden: PropTypes.array,
  dataset: PropTypes.object,
  widget: PropTypes.object,
  layer: PropTypes.object,
  mode: PropTypes.string,
  showActions: PropTypes.bool,
  // ACTIONS
  toggleDatasetActive: PropTypes.func,
  setDatasetsHidden: PropTypes.func
};

const mapStateToProps = state => ({
  layersHidden: state.explore.datasets.hidden
});

const mapDispatchToProps = dispatch => ({
  toggleDatasetActive: (id) => {
    dispatch(toggleDatasetActive(id));
    dispatch(setUrlParams());
  },
  setDatasetsHidden: (id) => { dispatch(setDatasetsHidden(id)); }
});

export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(DatasetWidget);
<commit_msg>Make dataset widget card clickable and linkable to Explore detail (excep add to map button)<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { Autobind } from 'es-decorators';

// Redux
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';
import { Link, Router } from 'routes';

// Components
import Title from 'components/ui/Title';
import Button from 'components/ui/Button';
import DatasetWidgetChart from 'components/app/explore/DatasetWidgetChart';
import DatasetLayerChart from 'components/app/explore/DatasetLayerChart';
import DatasetPlaceholderChart from 'components/app/explore/DatasetPlaceholderChart';
import { toggleDatasetActive, setUrlParams, setDatasetsHidden } from 'redactions/explore';

class DatasetWidget extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      active: props.active,
      dataset: props.dataset,
      widget: props.widget,
      layer: props.layer,
      hasWidget: !!props.widget,
      hasLayer: !!props.layer,
      mode: props.mode
    };

    // BINDINGS
    this.triggerToggleLayer = this.triggerToggleLayer.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      active: nextProps.active,
      dataset: nextProps.dataset,
      widget: nextProps.widget,
      layer: nextProps.layer,
      hasWidget: !!nextProps.widget,
      hasLayer: !!nextProps.layer,
      mode: nextProps.mode
    });
  }

  /**
   * HELPERS
   * - hideLayer
   * - getWidgetOrLayer
   * - getDescription
   * - getButton
  */
  getButton() {
    const { active, layer } = this.state;
    const buttonText = (active) ? 'Active' : 'Add to map';
    const buttonClass = (active) ? '-active' : '';

    if (layer) {
      return (
        <Button
          properties={{
            className: `-primary -fullwidth ${buttonClass}`
          }}
          onClick={this.triggerToggleLayer}
        >
          {buttonText}
        </Button>
      );
    }
    return (
      <Button
        properties={{
          disabled: true,
          className: '-primary -fullwidth -disabled'
        }}
        onClick={this.triggerToggleLayer}
      >
        Not displayable
      </Button>

    );
  }

  getWidgetOrLayer() {
    if (this.state.hasWidget) {
      return {
        ...this.state.widget.attributes,
        id: this.state.widget.id
      };
    }
    if (this.state.hasLayer) {
      return {
        ...this.state.layer.attributes,
        id: this.state.layer.id
      };
    }
    return null;
  }

  getDescription(_text) {
    let text = _text;
    if (typeof text === 'string' && text.length > 70) {
      text = text.replace(/^(.{70}[^\s]*).*/, '$1');
      return `${text}...`;
    }
    return text;
  }

  hideLayer(dataset) {
    let newLayersHidden = this.props.layersHidden.slice();
    if (this.props.layersHidden.includes(dataset)) {
      newLayersHidden = this.props.layersHidden.filter(l => l !== dataset);
    } else {
      newLayersHidden.push(dataset);
    }

    this.props.setDatasetsHidden(newLayersHidden);
  }

  /**
   * UI EVENTS
   * - triggerToggleLayer (e)
   * - handleClick
  */
  triggerToggleLayer() {
    const { dataset } = this.state;
    this.props.toggleDatasetActive(dataset.id);
    if (this.props.layersHidden.includes(dataset.id)) {
      this.hideLayer(dataset.id);
    }
  }
  @Autobind
  handleClick(event) {
    if (event.target.type !== 'submit') {
      Router.pushRoute('explore_detail', { id: this.props.dataset.id });
    }
  }

  render() {
    const { hasWidget, hasLayer, mode, dataset } = this.state;
    const { showActions } = this.props;
    const gridMode = (mode === 'grid');
    const element = this.getWidgetOrLayer();

    return (
      <div
        className={`c-dataset-list-item -${mode}`}
        onClick={this.handleClick}
      >
        {/* If it has widget we want to renderize the default widget one */}
        {hasWidget && gridMode &&
          <DatasetWidgetChart widget={element} />
        }
        {/* If it doesn't have widget but has layer we want to renderize the default layer one */}
        {!hasWidget && hasLayer && gridMode &&
          <DatasetLayerChart layer={element} />
        }

        {!hasWidget && !hasLayer && gridMode &&
          <DatasetPlaceholderChart />
        }

            {/* Title */}
            <Title className="-default -primary">
              <Link
                route={'explore_detail'}
                params={{ id: dataset.id }}
              >
                {dataset.attributes.name}
              </Link>
            </Title>

            {/* Description */}
            {dataset.attributes.metadata && (dataset.attributes.metadata.length > 0)
              && dataset.attributes.metadata[0].attributes.description &&

{this.getDescription(dataset.attributes.metadata[0].attributes.description)}

            }

            {/* Source */}
            {dataset.attributes.metadata && (dataset.attributes.metadata.length > 0)
              && dataset.attributes.metadata[0].attributes.source &&

Source: {dataset.attributes.metadata[0].attributes.source}

            }

            {/* Layer Button */}
            {showActions && this.getButton()}

    );
  }
}

DatasetWidget.propTypes = {
  // STATE
  active: PropTypes.bool,
  layersHidden: PropTypes.array,
  dataset: PropTypes.object,
  widget: PropTypes.object,
  layer: PropTypes.object,
  mode: PropTypes.string,
  showActions: PropTypes.bool,
  // ACTIONS
  toggleDatasetActive: PropTypes.func,
  setDatasetsHidden: PropTypes.func
};

const mapStateToProps = state => ({
  layersHidden: state.explore.datasets.hidden
});

const mapDispatchToProps = dispatch => ({
  toggleDatasetActive: (id) => {
    dispatch(toggleDatasetActive(id));
    dispatch(setUrlParams());
  },
  setDatasetsHidden: (id) => { dispatch(setDatasetsHidden(id)); }
});

export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(DatasetWidget);
<|endoftext|>


<commit_before>import React from 'react-native';
const {
  PixelRatio,
  StatusBarIOS,
  Component,
  Text,
  View,
  PropTypes
} = React;
import NavbarButton from './NavbarButton';
import styles from './styles';

const ButtonShape = {
  title: PropTypes.string.isRequired,
  style: PropTypes.object,
  handler: PropTypes.func,
};

const TitleShape = {
  title: PropTypes.string.isRequired,
  tintColor: PropTypes.string,
};

const StatusBarShape = {
  style: PropTypes.oneOf(['light-content', 'default', ]),
  hidden: PropTypes.bool,
  tintColor: PropTypes.string,
  hideAnimation: PropTypes.oneOf(['fade', 'slide', 'none', ]),
  showAnimation: PropTypes.oneOf(['fade', 'slide', 'none', ])
};

function customizeStatusBar(data) {
  if (data.style) {
    StatusBarIOS.setStyle(data.style, true);
  }
  const animation = data.hidden ?
    (data.hideAnimation || NavigationBar.defaultProps.statusBar.hideAnimation) :
    (data.showAnimation || NavigationBar.defaultProps.statusBar.showAnimation);

  StatusBarIOS.setHidden(data.hidden, animation);
}

module.exports = class NavigationBar extends Component {
  componentDidMount() {
    customizeStatusBar(this.props.statusBar);
  }

  componentWillReceiveProps(props) {
    customizeStatusBar(this.props.statusBar);
  }

  getButtonElement(data = {}, style) {
    if (!!data.props) {
      return <View style={styles.navBarButton}>{data}</View>;
    }

    return <NavbarButton
      title={data.title}
      style={[data.style, style, ]}
      tintColor={data.tintColor}
      handler={data.handler} />;
  }

  getTitleElement(data) {
    if (!!data.props) {
      return <View style={styles.customTitle}>{data}</View>;
    }

    const colorStyle = data.tintColor ? { color: data.tintColor, } : null;

    return (
      <Text
        style={[styles.navBarTitleText, colorStyle, ]}>
        {data.title}
      </Text>
    );
  }

  render() {
    const customTintColor = this.props.tintColor ?
      { backgroundColor: this.props.tintColor } : null;

    const statusBar = !this.props.statusBar.hidden ?
      <View style={[styles.statusBar, ]} /> : null;

    return (
      <View style={[styles.navBarContainer, customTintColor, ]}>
        {statusBar}
        <View style={[styles.navBar, this.props.style, ]}>
          {this.getTitleElement(this.props.title)}
          {this.getButtonElement(this.props.leftButton, { marginLeft: 8, })}
          {this.getButtonElement(this.props.rightButton, { marginRight: 8, })}
        </View>
      </View>
    );
  }

  static propTypes = {
    tintColor: PropTypes.string,
    statusBar: PropTypes.shape(StatusBarShape),
    leftButton: PropTypes.oneOfType([
      PropTypes.shape(ButtonShape),
      PropTypes.element,
    ]),
    rightButton: PropTypes.oneOfType([
      PropTypes.shape(ButtonShape),
      PropTypes.element,
    ]),
    title: PropTypes.oneOfType([
      PropTypes.shape(TitleShape),
      PropTypes.element,
    ]),
  }

  static defaultProps = {
    statusBar: {
      style: 'default',
      hidden: false,
      hideAnimation: 'slide',
      showAnimation: 'slide',
    },
    title: {
      title: '',
    },
  }
}
<commit_msg>module.exports<commit_after>import React from 'react-native';
const {
  PixelRatio,
  StatusBarIOS,
  Component,
  Text,
  View,
  PropTypes
} = React;
import NavbarButton from './NavbarButton';
import styles from './styles';

const ButtonShape = {
  title: PropTypes.string.isRequired,
  style: PropTypes.object,
  handler: PropTypes.func,
};

const TitleShape = {
  title: PropTypes.string.isRequired,
  tintColor: PropTypes.string,
};

const StatusBarShape = {
  style: PropTypes.oneOf(['light-content', 'default', ]),
  hidden: PropTypes.bool,
  tintColor: PropTypes.string,
  hideAnimation: PropTypes.oneOf(['fade', 'slide', 'none', ]),
  showAnimation: PropTypes.oneOf(['fade', 'slide', 'none', ])
};

function customizeStatusBar(data) {
  if (data.style) {
    StatusBarIOS.setStyle(data.style, true);
  }
  const animation = data.hidden ?
    (data.hideAnimation || NavigationBar.defaultProps.statusBar.hideAnimation) :
    (data.showAnimation || NavigationBar.defaultProps.statusBar.showAnimation);

  StatusBarIOS.setHidden(data.hidden, animation);
}

class NavigationBar extends Component {
  componentDidMount() {
    customizeStatusBar(this.props.statusBar);
  }

  componentWillReceiveProps(props) {
    customizeStatusBar(this.props.statusBar);
  }

  getButtonElement(data = {}, style) {
    if (!!data.props) {
      return <View style={styles.navBarButton}>{data}</View>;
    }

    return <NavbarButton
      title={data.title}
      style={[data.style, style, ]}
      tintColor={data.tintColor}
      handler={data.handler} />;
  }

  getTitleElement(data) {
    if (!!data.props) {
      return <View style={styles.customTitle}>{data}</View>;
    }

    const colorStyle = data.tintColor ? { color: data.tintColor, } : null;

    return (
      <Text
        style={[styles.navBarTitleText, colorStyle, ]}>
        {data.title}
      </Text>
    );
  }

  render() {
    const customTintColor = this.props.tintColor ?
      { backgroundColor: this.props.tintColor } : null;

    const statusBar = !this.props.statusBar.hidden ?
      <View style={[styles.statusBar, ]} /> : null;

    return (
      <View style={[styles.navBarContainer, customTintColor, ]}>
        {statusBar}
        <View style={[styles.navBar, this.props.style, ]}>
          {this.getTitleElement(this.props.title)}
          {this.getButtonElement(this.props.leftButton, { marginLeft: 8, })}
          {this.getButtonElement(this.props.rightButton, { marginRight: 8, })}
        </View>
      </View>
    );
  }

  static propTypes = {
    tintColor: PropTypes.string,
    statusBar: PropTypes.shape(StatusBarShape),
    leftButton: PropTypes.oneOfType([
      PropTypes.shape(ButtonShape),
      PropTypes.element,
    ]),
    rightButton: PropTypes.oneOfType([
      PropTypes.shape(ButtonShape),
      PropTypes.element,
    ]),
    title: PropTypes.oneOfType([
      PropTypes.shape(TitleShape),
      PropTypes.element,
    ]),
  }

  static defaultProps = {
    statusBar: {
      style: 'default',
      hidden: false,
      hideAnimation: 'slide',
      showAnimation: 'slide',
    },
    title: {
      title: '',
    },
  }
}
module.exports = NavigationBar;
<|endoftext|>


<commit_before>var parser = require('./lib/parser_wrap'),
    console = require('console'),
    fs = require('fs'),
    util = require('util'),
    tc = require('./lib/type_conv'),
    pu = require('./lib/proxy_helpers');

var opt_legal = {
  ConfigFile: { type: 'string', spec: 'fileexists' },
  ConfigHash: { type: 'hash' },
  String: { type: ['array','string'] },
  AllowMultiOptions: { type: 'boolean' },
  LowerCaseNames: { type: 'boolean' },
  UseApacheInclude: { type: 'boolean' },
  IncludeRelative: { type: 'boolean' },
  IncludeGlob: { type: 'boolean' },
  IncludeAgain: { type: 'boolean' },
  IncludeDirectories: { type: 'boolean' },
  ConfigPath: { type: 'array' },
  MergeDuplicateBlocks: { type: 'boolean' },
  MergeDuplicateOptions: { type: 'boolean' },
  AutoTrue: { type: 'boolean' },
  FlagBits: { type: 'hash' },
  DefaultConfig: { type: ['string','hash'] },
  InterPolateVars: { type: 'boolean' },
  InterPolateEnv: { type: 'boolean' },
  AllowSingleQuoteInterpolation: { type: 'boolean' },
  ExtendedAccess: { type: 'boolean' },
  StrictObjects: { type: 'boolean' },
  StrictVars: { type: 'boolean' },
  SplitPolicy: { type: 'string', spec: { name: 'oneof', values: ['guess','whitespace','equalsign','custom'] } },
  SplitDelimiter: { type: ['string','regexp'] },
  StoreDelimiter: { type: 'string' },
  CComments: { type: 'boolean' },
  SlashIsDirectory: { type: 'boolean' },
  ApacheCompatible: { type: 'boolean' },
  NormalizeBlock: { type: 'function' },
  NormalizeOption: { type: 'function' },
  NormalizeValue: { type: 'function' }
};

function checkOption(optname,optval) {
  var optspec = opt_legal[optname];

  if( optspec === undefined )
    return false;

  if( !Array.isArray(optspec.type) ) {
    if( optspec.type == "hash" ) {
      if( Array.isArray(optval) ||
          'object' != typeof(optval) )
        return false;
    } else if( optspec.type == 'array' ) {
        if( !Array.isArray(optval) )
          return false;
    } else if( optspec.type != typeof optval ) {
      return false;
    }
  } else {
    var n = typeof optval;
    var in_list = false;
    optspec.type.forEach( function(e,i,a) {
      if( e == 'hash' ) {
        if( !Array.isArray(optval) &&
            'object' == typeof optval )
          in_list = true;
      } else if( e == 'array' ) {
        if( Array.isArray(optval) )
          in_list = true;
      } else if( n == e )
          in_list = true;
    });

    if( !in_list )
      return false;
  }

  if( optspec.spec !== undefined ) {
    switch( optspec.spec ) {
      case 'fileexists':
      return fs.existsSync( optval );
      break;
      case 'oneof':
      return (optval in optspec.spec);
      break;
      default:
      return false;
    }
  }

  return true;
}

function cons() {
  var opts = {};
  var argv = arguments[0];
  var p = null; // this is where the parser will be

  if( 'string' == typeof argv )
    opts.ConfigFile = argv;
  else if( 'object' == typeof argv )
    opts = argv;

  Object.keys(opts).forEach( function( e,i,a ) {
    if(!checkOption(e,opts[e]))
      throw new Error('Invalid parameter '+opts[e]+' for option '+e);
  });

  p = new parser.parser(opts);

  if( opts.ExtendedAccess !== undefined && opts.ExtendedAccess ) {
    return Proxy.create(pu.handlerMakerMparse(p));
  } else
    return p;
}

module.exports.parser = cons;
<commit_msg>fix bad logic in options parameter validation<commit_after>var parser = require('./lib/parser_wrap'),
    console = require('console'),
    fs = require('fs'),
    util = require('util'),
    tc = require('./lib/type_conv'),
    pu = require('./lib/proxy_helpers');

var opt_legal = {
  ConfigFile: { type: 'string', spec: { name: 'fileexists' } },
  ConfigHash: { type: 'hash' },
  String: { type: ['array','string'] },
  AllowMultiOptions: { type: 'boolean' },
  LowerCaseNames: { type: 'boolean' },
  UseApacheInclude: { type: 'boolean' },
  IncludeRelative: { type: 'boolean' },
  IncludeGlob: { type: 'boolean' },
  IncludeAgain: { type: 'boolean' },
  IncludeDirectories: { type: 'boolean' },
  ConfigPath: { type: 'array' },
  MergeDuplicateBlocks: { type: 'boolean' },
  MergeDuplicateOptions: { type: 'boolean' },
  AutoTrue: { type: 'boolean' },
  FlagBits: { type: 'hash' },
  DefaultConfig: { type: ['string','hash'] },
  InterPolateVars: { type: 'boolean' },
  InterPolateEnv: { type: 'boolean' },
  AllowSingleQuoteInterpolation: { type: 'boolean' },
  ExtendedAccess: { type: 'boolean' },
  StrictObjects: { type: 'boolean' },
  StrictVars: { type: 'boolean' },
  SplitPolicy: { type: 'string', spec: { name: 'oneof', values: ['guess','whitespace','equalsign','custom'] } },
  SplitDelimiter: { type: ['string','regexp'] },
  StoreDelimiter: { type: 'string' },
  CComments: { type: 'boolean' },
  SlashIsDirectory: { type: 'boolean' },
  ApacheCompatible: { type: 'boolean' },
  NormalizeBlock: { type: 'function' },
  NormalizeOption: { type: 'function' },
  NormalizeValue: { type: 'function' }
};

function checkOption(optname,optval) {
  var optspec = opt_legal[optname];

  if( optspec === undefined )
    return false;

  if( !Array.isArray(optspec.type) ) {
    if( optspec.type == "hash" ) {
      if( Array.isArray(optval) ||
          'object' != typeof(optval) )
        return false;
    } else if( optspec.spec !== undefined ) {
      if( typeof optval != optspec.type ) {
        return false;
      }

      switch(optspec.spec.name) {
        case 'fileexists':
        if( fs.existsSync(optval) === false )
          return false;
        break;
        case 'oneof':
        var ins = false;
        optspec.spec.values.forEach( function(e,i,a) {
          if( optval == e )
            ins = true;
        });
        if( ins === false )
          return false;
        break;
        default:
        throw new Error('Unknown special compare type for parameter '+optspec.spec.name);
        }
    } else if( optspec.type == 'array' ) {
        if( !Array.isArray(optval) )
          return false;
    } else if( optspec.type != typeof optval ) {
      return false;
    }
  } else {
    var n = typeof optval;
    var in_list = false;
    optspec.type.forEach( function(e,i,a) {
      if( e == 'hash' ) {
        if( !Array.isArray(optval) &&
            'object' == typeof optval )
          in_list = true;
      } else if( e == 'array' ) {
        if( Array.isArray(optval) )
          in_list = true;
      } else if( n == e )
          in_list = true;
    });

    if( !in_list )
      return false;
  }

  if( optspec.spec !== undefined ) {
    switch( optspec.spec ) {
      case 'fileexists':
      return fs.existsSync( optval );
      case 'oneof':
      return (optval in optspec.spec);
      default:
      return false;
    }
  }

  return true;
}

function cons() {
  var opts = {};
  var argv = arguments[0];
  var p = null; // this is where the parser will be

  if( 'string' == typeof argv )
    opts.ConfigFile = argv;
  else if( 'object' == typeof argv )
    opts = argv;

  Object.keys(opts).forEach( function( e,i,a ) {
    if(!checkOption(e,opts[e]))
      throw new Error('Invalid parameter '+opts[e]+' for option '+e);
  });

  p = new parser.parser(opts);

  if( opts.ExtendedAccess !== undefined && opts.ExtendedAccess ) {
    return Proxy.create(pu.handlerMakerMparse(p));
  } else
    return p;
}

module.exports.parser = cons;
<|endoftext|>


<commit_before>var url = require('url');

/**
 * Github image tag
 *
 * Syntax:
 *   {% img_p slug [title]%}
 */
hexo.extend.tag.register('img_p', function(args){
    var classes = args[1] || "";
    var imgAttr = args[2] || "{}";
    var slug = args[0] || "";

    console.log(hexo);

    var PostAsset = hexo.model('PostAsset');

    var asset = PostAsset.findOne({post: this._id, slug: slug});

    classes = classes.split(',');
    imgAttr = JSON.parse(imgAttr);

    imgAttr.src   = githubResourceUrl + imageId;
    imgAttr.class = classes.join(' ');

    return '';

});<commit_msg>updates<commit_after>var url = require('url');

/**
 * Github image tag
 *
 * Syntax:
 *   {% img_p slug [title]%}
 */
hexo.extend.tag.register('img_p', function(args){
    var classes = args[1] || "";
    var imgAttr = args[2] || "{}";
    var slug = args[0] || "";

    console.log(hexo);

    var PostAsset = hexo.model('PostAsset');

    var asset = PostAsset.findOne({post: this._id, slug: slug});

    classes = classes.split(',');
    imgAttr = JSON.parse(imgAttr);
    imgAttr.class = classes.join(' ');

    return '';

});<|endoftext|>


<commit_before>// Define server
var express = require('express');
var app = express();

var bodyParser = require('body-parser');

// Define rest client
const AXIOS = require('axios');
// The port is being used by server
const SERVER_PORT = 3000;

// API keys
const GIPHY_PUBLIC_API_KEY = 'dc6zaTOxFJmzC';
const {GIPHYFY_TELEGRAM_BOT_API_KEY} = require('constants');

// URL Endpoints
const TELEGRAM_BASE_URL = 'https://api.telegram.org';
const GIPHY_BASE_URL = 'http://api.giphy.com';
const GIPHY_API_KEY_SUFIX = 'api_key=' + GIPHY_PUBLIC_API_KEY;
const GIPHY_SEARCH_ENDPOINT = '/v1/gifs/search';

const BOT_INCOMING_MESSAGE_ENDPOINT = '/new-message';

// For parsing application/json
app.use(bodyParser.json());
// For parsing application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
    extended: true
}));

//This is the route the API will call
app.post(BOT_INCOMING_MESSAGE_ENDPOINT, function (req, res) {
    const message = req.body;

    //Each message contains "text" and a "chat" object, which has an "id" which is the chat id
    if (!message) {
        // In case a message is not present => do nothing and return an empty response
        return res.end();
    }

    var searchString = message.text.replace(/\s+/g, '+');
    var url = GIPHY_BASE_URL + GIPHY_SEARCH_ENDPOINT + '?q=' + searchString + '&' + GIPHY_API_KEY_SUFIX;

    AXIOS.get(url).then(response => {
        console.log(response);

        // Remember to use your own API toked instead of the one below  "https://api.telegram.org/bot<your_api_token>/sendMessage"
        AXIOS.post(TELEGRAM_BASE_URL + '/bot' +  + '/sendMessage', {
            chat_id: message.chat.id,
            text: 'Got it'
        }).then(response => {
            // We get here if the message was successfully posted
            console.log('Message posted');
            res.end('ok');
        }).catch(err => {
            // ...and here if it was not
            console.log('Error :', err);
            res.end('Error :' + err);
        });
    }).catch(error => {
        // Log the error
        console.log(error);
        res.end('Error :' + err);
    });
});

// Finally, start our server
app.listen(SERVER_PORT, function() {
    console.log('Telegram giphyfy bot listening on port 3000!');
});<commit_msg>Add forgotten api key<commit_after>// Define server
var express = require('express');
var app = express();

var bodyParser = require('body-parser');

// Define rest client
const AXIOS = require('axios');
// The port is being used by server
const SERVER_PORT = 3000;

// API keys
const GIPHY_PUBLIC_API_KEY = 'dc6zaTOxFJmzC';
const {GIPHYFY_TELEGRAM_BOT_API_KEY} = require('constants');

// URL Endpoints
const TELEGRAM_BASE_URL = 'https://api.telegram.org';
const GIPHY_BASE_URL = 'http://api.giphy.com';
const GIPHY_API_KEY_SUFIX = 'api_key=' + GIPHY_PUBLIC_API_KEY;
const GIPHY_SEARCH_ENDPOINT = '/v1/gifs/search';

const BOT_INCOMING_MESSAGE_ENDPOINT = '/new-message';

// For parsing application/json
app.use(bodyParser.json());
// For parsing application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
    extended: true
}));

//This is the route the API will call
app.post(BOT_INCOMING_MESSAGE_ENDPOINT, function (req, res) {
    const message = req.body;

    //Each message contains "text" and a "chat" object, which has an "id" which is the chat id
    if (!message) {
        // In case a message is not present => do nothing and return an empty response
        return res.end();
    }

    var searchString = message.text.replace(/\s+/g, '+');
    var url = GIPHY_BASE_URL + GIPHY_SEARCH_ENDPOINT + '?q=' + searchString + '&' + GIPHY_API_KEY_SUFIX;

    AXIOS.get(url).then(response => {
        console.log(response);

        // Remember to use your own API toked instead of the one below  "https://api.telegram.org/bot<your_api_token>/sendMessage"
        AXIOS.post(TELEGRAM_BASE_URL + '/bot' + GIPHYFY_TELEGRAM_BOT_API_KEY + '/sendMessage', {
            chat_id: message.chat.id,
            text: 'Got it'
        }).then(response => {
            // We get here if the message was successfully posted
            console.log('Message posted');
            res.end('ok');
        }).catch(err => {
            // ...and here if it was not
            console.log('Error :', err);
            res.end('Error :' + err);
        });
    }).catch(error => {
        // Log the error
        console.log(error);
        res.end('Error :' + err);
    });
});

// Finally, start our server
app.listen(SERVER_PORT, function() {
    console.log('Telegram giphyfy bot listening on port 3000!');
});<|endoftext|>