<commit_before>'use strict';

const crypto = require('crypto');
const express = require('express');
const morgan = require('morgan');
const path = require('path');
const http = require('http');
const https = require('https');
const mixins = require('./frontend').mixins;
const hofMiddleware = require('./middleware');
const markdown = require('./lib/markdown');
const translate = require('i18n-future').middleware;
const router = require('./lib/router');
const health = require('./lib/health');
const serveStatic = require('./lib/serve-static');
const gaTagSetup = require('./lib/ga-tag');
const sessionStore = require('./lib/sessions');
const settings = require('./lib/settings');
const defaults = require('./config/hof-defaults');
const logger = require('./lib/logger');
const helmet = require('helmet');
const _ = require('lodash');
const deprecate = require('deprecate');

const customConfig = {};

const getConfig = function () {
  const args = [].slice.call(arguments);
  const config = _.merge.apply(_, [{}, defaults, customConfig].concat(args));

  if (!config.theme) {
    config.theme = require('./frontend').themes.govUK;
  } else if (typeof config.theme === 'string') {
    config.theme = require('./frontend').themes[config.theme];
  }

  config.markdown = config.markdown || {};

  return config;
};

const loadRoutes = (app, config) => {
  config.routes.forEach(route => {
    const routeConfig = Object.assign({}, config, {
      route,
      sharedViews: app.get('views')
    });
    app.use(route.baseUrl || '/', router(routeConfig));
  });
};

const applyErrorMiddlewares = (app, config) => {
  app.use(hofMiddleware.notFound({
    logger: config.logger
  }));

  app.use(hofMiddleware.errors({
    logger: config.logger,
    debug: config.env === 'development'
  }));
};

const getContentSecurityPolicy = (config, res) => {
  const csp = config.csp;

  /* eslint-disable quotes */
  const directives = {
    defaultSrc: ["'none'"],
    styleSrc: ["'self'"],
    imgSrc: ["'self'"],
    fontSrc: ["'self'", 'data:'],
    scriptSrc: ["'self'", `'nonce-${res.locals.nonce}'`],
    'frame-ancestors': ["'none'"]
  };
  /* eslint-enable quotes */

  const gaDirectives = {
    scriptSrc: ['www.google-analytics.com', 'ssl.google-analytics.com'],
    imgSrc: 'www.google-analytics.com',
    connectSrc: ['www.google-analytics.com']
  };

  if (config.gaTagId) {
    directives.scriptSrc = directives.scriptSrc.concat(gaDirectives.scriptSrc);
    directives.imgSrc = directives.imgSrc.concat(gaDirectives.imgSrc);
    directives.connectSrc = gaDirectives.connectSrc;
  }

  if (csp && !csp.disabled) {
    _.each(csp, (value, name) => {
      if (name === 'disabled') {
        return;
      }
      if (directives[name] && directives[name].length) {
        // concat unique directives with existing directives
        directives[name] = _.uniq(directives[name].concat(value));
      } else {
        directives[name] = _.isArray(value) ? value : [value];
      }
    });
  }
  return directives;
};

/**
 * Creates a new HOF application
 *
 * @param options {object} Configuration options for the HOF application
 * @param options.behaviours {object | Array<object>} The HOF behaviour(s) to invoke for all sub-applications
 * @param options.translations {string} The translations path for the application
 * @param options.routes {Array<object>} The sub-applications for this app: for example; require('./apps/example-app')
 * @param options.views {Array<string>} The view template paths for the application
 * @param options.middleware {Array<function>} An array of Express middleware functions to use
 * @param options.theme {string} Optional HOF theme - defaults to govuk
 * @param options.markdown {object} Optional markdown options
 * @param options.getTerms {boolean} Optional boolean - whether to mount the /terms endpoint
 * @param options.getCookies {boolean} Optional boolean - whether to mount the /cookies endpoint
 * @param options.noCache {boolean} Optional boolean - whether to disable caching
 *
 * @returns {object} A new HOF application using the configuration supplied in options
 */
function bootstrap(options) {
  const config = getConfig(options);

  const app = express();
  const userMiddleware = express.Router();

  app.use(helmet());

  // Add common locals all pages can access
  app.use((req, res, next) => {
    res.locals.nonce = crypto.randomBytes(16).toString('hex');
    res.locals.appName = config.appName;
    res.locals.cookieName = config.session.name;
    next();
  });

  if (config.csp !== false && !config.csp.disabled) {
    app.use((req, res, next) => {
      helmet.contentSecurityPolicy({
        directives: getContentSecurityPolicy(config, res)
      })(req, res, next);
    });
  }

  app.use(helmet.noSniff());

  if (config.noCache && config.noCache !== 'false') {
    app.use((req, res, next) => {
      res.setHeader('cache-control', ['no-store', 'no-cache', 'must-revalidate', 'proxy-revalidate']);
      res.setHeader('pragma', 'no-cache');
      next();
    });
  }

  if (!config || !config.routes || !config.routes.length) {
    throw new Error('Must be called with a list of routes');
  }

  config.routes.forEach(route => {
    if (!route.steps && !route.pages) {
      throw new Error('Each app must have steps and/or pages');
    }
  });

  if (config.middleware) {
    config.middleware.forEach(middleware => app.use(middleware));
  }

  config.logger = logger(config);

  morgan.token('id', req => _.get(req, 'session.id', 'N/A'));

  app.use(morgan('sessionId=:id ' + morgan.combined, {
    stream: config.logger.stream,
    skip: (req, res) => config.loglevel !== 'debug' &&
        (
          res.statusCode >= 300 || !_.get(req, 'session.id') ||
          config.ignoreMiddlewareLogs.some(v => req.originalUrl.includes(v))
        )
  }));

  serveStatic(app, config);
  settings(app, config);
  gaTagSetup(app, config);

  const sessions = sessionStore(app, config);
  app.use('/healthz', health(sessions));

  app.use((req, res, next) => {
    const id = _.get(req, 'session.id', 'N/A');
    req.log = config.logger.logSession(id);
    next();
  });

  app.use(translate({
    resources: config.theme.translations,
    path: path.resolve(config.root, config.translations) + '/__lng__/__ns__.json'
  }));
  app.use(mixins());
  app.use(markdown(config.markdown));

  if (config.getCookies === true) {
    deprecate(
      '`getCookies` option is deprecated and may be removed in future versions.',
      'Use `pages` to define static cookies page.'
    );
    app.get('/cookies', (req, res) => {
      const locals = Object.assign({}, req.translate('cookies'));
      res.render('cookies', locals);
    });
  }
  if (config.getTerms === true) {
    deprecate(
      '`getTerms` option is deprecated and may be removed in future versions.',
      'Use `pages` to define static terms and conditions page.'
    );
    app.get('/terms-and-conditions', (req, res) => {
      const locals = Object.assign({}, req.translate('terms'));
      res.render('terms', locals);
    });
  }

  app.use(userMiddleware);
  app.use(hofMiddleware.cookies(config));
  loadRoutes(app, config);
  applyErrorMiddlewares(app, config);

  const instance = {
    use() {
      userMiddleware.use.apply(userMiddleware, arguments);
      return instance;
    },

    server: null,

    start: sConfig => {
      let startConfig = sConfig;
      startConfig = getConfig(config, startConfig);

      const protocol = startConfig.protocol === 'http' ? http : https;

      instance.server = protocol.createServer(app);

      return new Promise((resolve, reject) => {
        instance.server.listen(startConfig.port, startConfig.host, err => {
          if (err) {
            reject(new Error('Unable to connect to server'));
          }
          config.logger.log('info', `${config.appName} started!`);
          resolve(instance);
        });
      });
    },

    stop() {
      return new Promise((resolve, reject) => instance.server.close(err => {
        if (err) {
          reject(new Error('Unable to stop server'));
        }
        config.logger.log('info', `${config.appName} stopped!`);
        resolve(instance);
      }));
    }
  };

  if (config.start !== false) {
    instance.start(config);
  }

  return instance;
}

bootstrap.configure = function (key, val) {
  if (arguments.length === 2 && typeof key === 'string') {
    customConfig[key] = val;
  } else if (typeof key === 'object') {
    Object.assign(customConfig, key);
  }
};

module.exports = bootstrap;
module.exports.build = require('./build/');
module.exports.transpiler = require('./transpiler/');
module.exports.middleware = require('./middleware');
module.exports.controller = require('./controller');
module.exports.model = require('./model');
module.exports.apis = require('./model/apis');
module.exports.wizard = require('./wizard');
module.exports.components = require('./components');
module.exports.utils = require('./utilities');
module.exports.frontend = require('./frontend');
<commit_msg>Add design system website to font src csp<commit_after>'use strict';

const crypto = require('crypto');
const express = require('express');
const morgan = require('morgan');
const path = require('path');
const http = require('http');
const https = require('https');
const mixins = require('./frontend').mixins;
const hofMiddleware = require('./middleware');
const markdown = require('./lib/markdown');
const translate = require('i18n-future').middleware;
const router = require('./lib/router');
const health = require('./lib/health');
const serveStatic = require('./lib/serve-static');
const gaTagSetup = require('./lib/ga-tag');
const sessionStore = require('./lib/sessions');
const settings = require('./lib/settings');
const defaults = require('./config/hof-defaults');
const logger = require('./lib/logger');
const helmet = require('helmet');
const _ = require('lodash');
const deprecate = require('deprecate');

const customConfig = {};

const getConfig = function () {
  const args = [].slice.call(arguments);
  const config = _.merge.apply(_, [{}, defaults, customConfig].concat(args));

  if (!config.theme) {
    config.theme = require('./frontend').themes.govUK;
  } else if (typeof config.theme === 'string') {
    config.theme = require('./frontend').themes[config.theme];
  }

  config.markdown = config.markdown || {};

  return config;
};

const loadRoutes = (app, config) => {
  config.routes.forEach(route => {
    const routeConfig = Object.assign({}, config, {
      route,
      sharedViews: app.get('views')
    });
    app.use(route.baseUrl || '/', router(routeConfig));
  });
};

const applyErrorMiddlewares = (app, config) => {
  app.use(hofMiddleware.notFound({
    logger: config.logger
  }));

  app.use(hofMiddleware.errors({
    logger: config.logger,
    debug: config.env === 'development'
  }));
};

const getContentSecurityPolicy = (config, res) => {
  const csp = config.csp;

  /* eslint-disable quotes */
  const directives = {
    defaultSrc: ["'none'"],
    styleSrc: ["'self'"],
    imgSrc: ["'self'"],
    fontSrc: ["'self'", 'data:', 'www.design-system.service.gov.uk'],
    scriptSrc: ["'self'", `'nonce-${res.locals.nonce}'`],
    'frame-ancestors': ["'none'"]
  };
  /* eslint-enable quotes */

  const gaDirectives = {
    scriptSrc: ['www.google-analytics.com', 'ssl.google-analytics.com'],
    imgSrc: 'www.google-analytics.com',
    connectSrc: ['www.google-analytics.com']
  };

  if (config.gaTagId) {
    directives.scriptSrc = directives.scriptSrc.concat(gaDirectives.scriptSrc);
    directives.imgSrc = directives.imgSrc.concat(gaDirectives.imgSrc);
    directives.connectSrc = gaDirectives.connectSrc;
  }

  if (csp && !csp.disabled) {
    _.each(csp, (value, name) => {
      if (name === 'disabled') {
        return;
      }
      if (directives[name] && directives[name].length) {
        // concat unique directives with existing directives
        directives[name] = _.uniq(directives[name].concat(value));
      } else {
        directives[name] = _.isArray(value) ? value : [value];
      }
    });
  }
  return directives;
};

/**
 * Creates a new HOF application
 *
 * @param options {object} Configuration options for the HOF application
 * @param options.behaviours {object | Array<object>} The HOF behaviour(s) to invoke for all sub-applications
 * @param options.translations {string} The translations path for the application
 * @param options.routes {Array<object>} The sub-applications for this app: for example; require('./apps/example-app')
 * @param options.views {Array<string>} The view template paths for the application
 * @param options.middleware {Array<function>} An array of Express middleware functions to use
 * @param options.theme {string} Optional HOF theme - defaults to govuk
 * @param options.markdown {object} Optional markdown options
 * @param options.getTerms {boolean} Optional boolean - whether to mount the /terms endpoint
 * @param options.getCookies {boolean} Optional boolean - whether to mount the /cookies endpoint
 * @param options.noCache {boolean} Optional boolean - whether to disable caching
 *
 * @returns {object} A new HOF application using the configuration supplied in options
 */
function bootstrap(options) {
  const config = getConfig(options);

  const app = express();
  const userMiddleware = express.Router();

  app.use(helmet());

  // Add common locals all pages can access
  app.use((req, res, next) => {
    res.locals.nonce = crypto.randomBytes(16).toString('hex');
    res.locals.appName = config.appName;
    res.locals.cookieName = config.session.name;
    next();
  });

  if (config.csp !== false && !config.csp.disabled) {
    app.use((req, res, next) => {
      helmet.contentSecurityPolicy({
        directives: getContentSecurityPolicy(config, res)
      })(req, res, next);
    });
  }

  app.use(helmet.noSniff());

  if (config.noCache && config.noCache !== 'false') {
    app.use((req, res, next) => {
      res.setHeader('cache-control', ['no-store', 'no-cache', 'must-revalidate', 'proxy-revalidate']);
      res.setHeader('pragma', 'no-cache');
      next();
    });
  }

  if (!config || !config.routes || !config.routes.length) {
    throw new Error('Must be called with a list of routes');
  }

  config.routes.forEach(route => {
    if (!route.steps && !route.pages) {
      throw new Error('Each app must have steps and/or pages');
    }
  });

  if (config.middleware) {
    config.middleware.forEach(middleware => app.use(middleware));
  }

  config.logger = logger(config);

  morgan.token('id', req => _.get(req, 'session.id', 'N/A'));

  app.use(morgan('sessionId=:id ' + morgan.combined, {
    stream: config.logger.stream,
    skip: (req, res) => config.loglevel !== 'debug' &&
        (
          res.statusCode >= 300 || !_.get(req, 'session.id') ||
          config.ignoreMiddlewareLogs.some(v => req.originalUrl.includes(v))
        )
  }));

  serveStatic(app, config);
  settings(app, config);
  gaTagSetup(app, config);

  const sessions = sessionStore(app, config);
  app.use('/healthz', health(sessions));

  app.use((req, res, next) => {
    const id = _.get(req, 'session.id', 'N/A');
    req.log = config.logger.logSession(id);
    next();
  });

  app.use(translate({
    resources: config.theme.translations,
    path: path.resolve(config.root, config.translations) + '/__lng__/__ns__.json'
  }));
  app.use(mixins());
  app.use(markdown(config.markdown));

  if (config.getCookies === true) {
    deprecate(
      '`getCookies` option is deprecated and may be removed in future versions.',
      'Use `pages` to define static cookies page.'
    );
    app.get('/cookies', (req, res) => {
      const locals = Object.assign({}, req.translate('cookies'));
      res.render('cookies', locals);
    });
  }
  if (config.getTerms === true) {
    deprecate(
      '`getTerms` option is deprecated and may be removed in future versions.',
      'Use `pages` to define static terms and conditions page.'
    );
    app.get('/terms-and-conditions', (req, res) => {
      const locals = Object.assign({}, req.translate('terms'));
      res.render('terms', locals);
    });
  }

  app.use(userMiddleware);
  app.use(hofMiddleware.cookies(config));
  loadRoutes(app, config);
  applyErrorMiddlewares(app, config);

  const instance = {
    use() {
      userMiddleware.use.apply(userMiddleware, arguments);
      return instance;
    },

    server: null,

    start: sConfig => {
      let startConfig = sConfig;
      startConfig = getConfig(config, startConfig);

      const protocol = startConfig.protocol === 'http' ? http : https;

      instance.server = protocol.createServer(app);

      return new Promise((resolve, reject) => {
        instance.server.listen(startConfig.port, startConfig.host, err => {
          if (err) {
            reject(new Error('Unable to connect to server'));
          }
          config.logger.log('info', `${config.appName} started!`);
          resolve(instance);
        });
      });
    },

    stop() {
      return new Promise((resolve, reject) => instance.server.close(err => {
        if (err) {
          reject(new Error('Unable to stop server'));
        }
        config.logger.log('info', `${config.appName} stopped!`);
        resolve(instance);
      }));
    }
  };

  if (config.start !== false) {
    instance.start(config);
  }

  return instance;
}

bootstrap.configure = function (key, val) {
  if (arguments.length === 2 && typeof key === 'string') {
    customConfig[key] = val;
  } else if (typeof key === 'object') {
    Object.assign(customConfig, key);
  }
};

module.exports = bootstrap;
module.exports.build = require('./build/');
module.exports.transpiler = require('./transpiler/');
module.exports.middleware = require('./middleware');
module.exports.controller = require('./controller');
module.exports.model = require('./model');
module.exports.apis = require('./model/apis');
module.exports.wizard = require('./wizard');
module.exports.components = require('./components');
module.exports.utils = require('./utilities');
module.exports.frontend = require('./frontend');
<|endoftext|>


<commit_before>var through = require('through');
var copy = require('shallow-copy');
var browserify = require('browserify');
var fs = require('fs');
var chokidar = require('chokidar');

module.exports = watchify;
watchify.browserify = browserify;

function watchify (opts) {
    if (!opts) opts = {};
    var b = typeof opts.bundle === 'function' ? opts : browserify(opts);
    var cache = {};
    var pkgcache = {};
    var pending = false;
    var changingDeps = {};
    var first = true;

    if (opts.cache) {
        cache = opts.cache;
        delete opts.cache;
        first = false;
    }

    if (opts.pkgcache) {
        pkgcache = opts.pkgcache;
        delete opts.pkgcache;
    }

    b.on('package', function (file, pkg) {
        pkgcache[file] = pkg;
    });

    var fwatchers = {};
    var fwatcherFiles = {};
    b.on('bundle', function (bundle) {
        bundle.on('transform', function (tr, mfile) {
            if (!fwatchers[mfile]) fwatchers[mfile] = [];
            if (!fwatcherFiles[mfile]) fwatcherFiles[mfile] = [];

            watchFile(mfile, mfile);

            tr.on('file', function (file) {
                watchFile(mfile, file);
            });
        });
    });

    function watchFile(mfile, file) {
        if (!fwatchers[mfile]) return;
        if (fwatcherFiles[mfile].indexOf(file) >= 0) return;

        var w = chokidar.watch(file, {persistent: true});
        w.on('error', b.emit.bind(b, 'error'));
        w.on('change', function () {
            invalidate(mfile);
        });
        fwatchers[mfile].push(w);
        fwatcherFiles[mfile].push(file);
    }

    function invalidate (id) {
        delete cache[id];
        if (fwatchers[id]) {
            fwatchers[id].forEach(function (w) {
                w.close();
            });
            delete fwatchers[id];
            delete fwatcherFiles[id];
        }
        changingDeps[id] = true

        // wait for the disk/editor to quiet down first:
        if (!pending) setTimeout(function () {
            pending = false;
            b.emit('update', Object.keys(changingDeps));
            changingDeps = {};

        }, opts.delay || 600);
        pending = true;
    }

    var bundle = b.bundle.bind(b);
    b.close = function () {
        Object.keys(fwatchers).forEach(function (id) {
            fwatchers[id].forEach(function (w) { w.close() });
        });
    };

    b.bundle = function (opts_, cb) {
        if (b._pending) return bundle(opts_, cb);

        if (typeof opts_ === 'function') {
            cb = opts_;
            opts_ = {};
        }
        if (!opts_) opts_ = {};
        if (!first) opts_.cache = cache;
        opts_.includePackage = true;
        opts_.packageCache = pkgcache;

        // we only want to mess with the listeners if the bundle was created
        // successfully, e.g. on the 'end' event.
        var outStream = bundle(opts_, cb);
        outStream.on('error', function (err) {
            var updated = false;
            b.once('update', function () { updated = true });

            if (err.type === 'not found') {
                (function f () {
                    if (updated) return;
                    fs.exists(err.filename, function (ex) {
                        if (ex) b.emit('update', [ err.filename ])
                        else setTimeout(f, opts.delay || 600)
                    });
                })();
            }
        });
        outStream.on('end', end);
        function end () {
            first = false;
        }
        return outStream;
    };

    return b;
}
<commit_msg>re-enable caching<commit_after>var through = require('through');
var copy = require('shallow-copy');
var browserify = require('browserify');
var fs = require('fs');
var chokidar = require('chokidar');

module.exports = watchify;
watchify.browserify = browserify;

function watchify (opts) {
    if (!opts) opts = {};
    var b = typeof opts.bundle === 'function' ? opts : browserify(opts);
    var cache = {};
    var pkgcache = {};
    var pending = false;
    var changingDeps = {};
    var first = true;

    if (opts.cache) {
        cache = opts.cache;
        delete opts.cache;
        first = false;
    }

    if (opts.pkgcache) {
        pkgcache = opts.pkgcache;
        delete opts.pkgcache;
    }

    b.on('package', function (file, pkg) {
        pkgcache[file] = pkg;
    });

    b.on('dep', function (dep) {
        cache[dep.id] = dep;
    });

    var fwatchers = {};
    var fwatcherFiles = {};
    b.on('bundle', function (bundle) {
        bundle.on('transform', function (tr, mfile) {
            if (!fwatchers[mfile]) fwatchers[mfile] = [];
            if (!fwatcherFiles[mfile]) fwatcherFiles[mfile] = [];

            watchFile(mfile, mfile);

            tr.on('file', function (file) {
                watchFile(mfile, file);
            });
        });
    });

    function watchFile(mfile, file) {
        if (!fwatchers[mfile]) return;
        if (fwatcherFiles[mfile].indexOf(file) >= 0) return;

        var w = chokidar.watch(file, {persistent: true});
        w.on('error', b.emit.bind(b, 'error'));
        w.on('change', function () {
            invalidate(mfile);
        });
        fwatchers[mfile].push(w);
        fwatcherFiles[mfile].push(file);
    }

    function invalidate (id) {
        delete cache[id];
        if (fwatchers[id]) {
            fwatchers[id].forEach(function (w) {
                w.close();
            });
            delete fwatchers[id];
            delete fwatcherFiles[id];
        }
        changingDeps[id] = true

        // wait for the disk/editor to quiet down first:
        if (!pending) setTimeout(function () {
            pending = false;
            b.emit('update', Object.keys(changingDeps));
            changingDeps = {};

        }, opts.delay || 600);
        pending = true;
    }

    var bundle = b.bundle.bind(b);
    b.close = function () {
        Object.keys(fwatchers).forEach(function (id) {
            fwatchers[id].forEach(function (w) { w.close() });
        });
    };

    b.bundle = function (opts_, cb) {
        if (b._pending) return bundle(opts_, cb);

        if (typeof opts_ === 'function') {
            cb = opts_;
            opts_ = {};
        }
        if (!opts_) opts_ = {};
        if (!first) opts_.cache = cache;
        opts_.includePackage = true;
        opts_.packageCache = pkgcache;

        // we only want to mess with the listeners if the bundle was created
        // successfully, e.g. on the 'end' event.
        var outStream = bundle(opts_, cb);
        outStream.on('error', function (err) {
            var updated = false;
            b.once('update', function () { updated = true });

            if (err.type === 'not found') {
                (function f () {
                    if (updated) return;
                    fs.exists(err.filename, function (ex) {
                        if (ex) b.emit('update', [ err.filename ])
                        else setTimeout(f, opts.delay || 600)
                    });
                })();
            }
        });
        outStream.on('end', end);
        function end () {
            first = false;
        }
        return outStream;
    };

    return b;
}
<|endoftext|>


<commit_before>'use strict'

const express = require('express')
const bodyParser = require('body-parser')
const request = require('request')
const auth = require('./auth');

const app = express()

app.set('port', (process.env.PORT || 5000))

// Process application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}))

// Process application/json
app.use(bodyParser.json())

const token = auth.page_token;

// Index route
app.get('/', function (req, res) {
    res.send('Hello world, I am a chat bot ' + token)
})

// for Facebook verification
app.get('/webhook/', function (req, res) {
    let messaging_events = req.body.entry[0].messaging
    for (let i = 0; i < messaging_events.length; i++) {
        let event = req.body.entry[0].messaging[i]
        let sender = event.sender.id
        if (event.message && event.message.text) {
            let text = event.message.text
            sendTextMessage(sender, "Text received, echo: " + text.substring(0, 200))
        }
    }
    res.sendStatus(200)
})

// Spin up the server
app.listen(app.get('port'), function() {
    console.log('running on port', app.get('port'))
})

function sendTextMessage(sender, text) {
  let messageData = { text:text }
  request({
      url: 'https://graph.facebook.com/v2.6/me/messages',
      qs: { access_token: BITBOT_PAGE_TOKEN },
      method: 'POST',
      json: {
          recipient: { id: sender },
          message: messageData,
      }
  }, function(error, response, body) {
      if (error) {
          console.log('Error sending messages: ', error)
      } else if (response.body.error) {
          console.log('Error: ', response.body.error)
      }
  })
}
<commit_msg>mocing webhook endpoint to POST<commit_after>'use strict'

const express = require('express')
const bodyParser = require('body-parser')
const request = require('request')
const auth = require('./auth');

const app = express()

app.set('port', (process.env.PORT || 5000))

// Process application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}))

// Process application/json
app.use(bodyParser.json())

const token = auth.page_token;

// Index route
app.get('/', function (req, res) {
    res.send('Hello world, I am a chat bot ' + token)
})

// for Facebook verification
app.post('/webhook/', function (req, res) {
  console.log(req)
  console.log(req.body);
  let messaging_events = req.body.entry[0].messaging
  for (let i = 0; i < messaging_events.length; i++) {
      let event = req.body.entry[0].messaging[i]
      let sender = event.sender.id
      if (event.message && event.message.text) {
          let text = event.message.text
          sendTextMessage(sender, "Text received, echo: " + text.substring(0, 200))
      }
  }
  res.sendStatus(200)
})

// Spin up the server
app.listen(app.get('port'), function() {
    console.log('running on port', app.get('port'))
})

function sendTextMessage(sender, text) {
  let messageData = { text:text }
  request({
      url: 'https://graph.facebook.com/v2.6/me/messages',
      qs: { access_token: BITBOT_PAGE_TOKEN },
      method: 'POST',
      json: {
          recipient: { id: sender },
          message: messageData,
      }
  }, function(error, response, body) {
      if (error) {
          console.log('Error sending messages: ', error)
      } else if (response.body.error) {
          console.log('Error: ', response.body.error)
      }
  })
}
<|endoftext|>


<commit_before>'use strict';
const fs = require('fs');
const path = require('path');
const resolve = require('resolve');
const readPkg = require('read-pkg');
const readPkgUp = require('read-pkg-up');
const DAG = require('dag-map').default;

function findPlugins(options) {
  options = options || {};
  // The directory to scan for plugins
  let dir = options.dir || process.cwd();
  // The path to the package.json that lists dependencies to check for plugins
  let pkgPath = options.pkg || (options.dir && path.join(options.dir, 'package.json')) || 'package.json';
  let pkg;
  try {
    pkg = readPkg.sync(pkgPath);
  } catch(e) {}
  // An array of additional paths to check as plugins
  let includes = options.include || [];
  // If supplied, a package will be considered a plugin if `keyword` is present in it's
  // package.json "keywords" array
  let keyword = options.keyword;

  if (!pkg && !options.configName && options.sort) {
    throw new Error('You passed sort: true to findPlugins, but did not provide a valid package.json path or configName');
  }

  let pluginCandidateDirectories = options.scanAllDirs ? findCandidatesInDir(dir) : findCandidatesFromPkg(pkg);

  // Include an manually specified packages in the list of plugin candidates
  pluginCandidateDirectories = pluginCandidateDirectories.concat(includes.map((includedDir) => {
    try {
      return {
        dir: includedDir,
        pkg: readPkg.sync(path.join(includedDir, 'package.json'))
      };
    } catch (e) {
      return false;
    }
  }));

  let plugins = pluginCandidateDirectories.filter(Boolean).filter(isPlugin);

  if (options.sort) {
    let graph = new DAG();
    plugins.forEach((plugin) => {
      let pluginConfig = plugin.pkg[options.configName || pkg.name] || {};
      graph.add(plugin.pkg.name, plugin, pluginConfig.before, pluginConfig.after);
    });
    plugins = [];
    graph.topsort((key, value) => {
      plugins.push(value);
    });
  }

  return plugins;

  function findCandidatesInDir(dir) {
    return fs.readdirSync(dir)
      // Handle scoped packages
      .reduce((candidates, name) => {
        if (name.charAt(0) === '@') {
          fs.readdirSync(path.join(dir, name))
          .forEach((scopedPackageName) => {
            candidates.push(path.join(name, scopedPackageName));
          });
        } else {
          candidates.push(name);
        }
        return candidates;
      }, [])
      // Get the full directory path
      .map((name) => path.join(dir, name))
      // Ensure it actually is a directory
      .filter((dir) => fs.statSync(dir).isDirectory())
      // Load the package.json for each
      .map((dir) => {
        try {
          return { dir, pkg: readPkg.sync(path.join(dir, 'package.json')) };
        } catch (e) {
          return false;
        }
      })
  }

  function findCandidatesFromPkg(pkg) {
    let dependencies = [];
    if (!options.excludeDependencies) {
      dependencies = dependencies.concat(Object.keys(pkg.dependencies || {}));
    }
    if (options.includeDev) {
      dependencies = dependencies.concat(Object.keys(pkg.devDependencies || {}));
    }
    if (options.includePeer) {
      dependencies = dependencies.concat(Object.keys(pkg.peerDependencies || {}));
    }
    if (options.includeBundle) {
      dependencies = dependencies.concat(Object.keys(pkg.bundleDependencies || pkg.bundledDependencies || {}));
    }
    if (options.includeOptional) {
      dependencies = dependencies.concat(Object.keys(pkg.optionalDependencies || {}));
    }
    return dependencies
      // Load package.json's from resolved package location
      .map((dep) => {
        try {
          let pkgMainPath = resolve.sync(dep, { basedir: dir });
          let foundPkg = readPkgUp.sync({ cwd: path.dirname(pkgMainPath) });
          return { dir: path.dirname(foundPkg.path), pkg: foundPkg.pkg };
        } catch (e) {
          return false;
        }
      })
  }

  // The filter function that determines whether a package is a plugin. If options.filter
  // is supplied, go with that. Otherwise, check for options.keyword match.
  function isPlugin(plugin) {
    if (options.filter) {
      return options.filter(plugin);
    }
    if (!plugin.pkg.keywords) {
      return false;
    }
    if (!keyword) {
      keyword = pkg.name;
    }
    return plugin.pkg.keywords.indexOf(keyword) > -1;
  }

}

findPlugins.default = findPlugins;

module.exports = findPlugins;
<commit_msg>debugging travis failures<commit_after>'use strict';
const fs = require('fs');
const path = require('path');
const resolve = require('resolve');
const readPkg = require('read-pkg');
const readPkgUp = require('read-pkg-up');
const DAG = require('dag-map').default;

function findPlugins(options) {
  options = options || {};
  // The directory to scan for plugins
  let dir = options.dir || process.cwd();
  // The path to the package.json that lists dependencies to check for plugins
  let pkgPath = options.pkg || (options.dir && path.join(options.dir, 'package.json')) || 'package.json';
  let pkg;
  try {
    pkg = readPkg.sync(pkgPath);
  } catch(e) {}
  // An array of additional paths to check as plugins
  let includes = options.include || [];
  // If supplied, a package will be considered a plugin if `keyword` is present in it's
  // package.json "keywords" array
  let keyword = options.keyword;

  if (!pkg && !options.configName && options.sort) {
    throw new Error('You passed sort: true to findPlugins, but did not provide a valid package.json path or configName');
  }

  let pluginCandidateDirectories = options.scanAllDirs ? findCandidatesInDir(dir) : findCandidatesFromPkg(pkg);

  // Include an manually specified packages in the list of plugin candidates
  pluginCandidateDirectories = pluginCandidateDirectories.concat(includes.map((includedDir) => {
    try {
      return {
        dir: includedDir,
        pkg: readPkg.sync(path.join(includedDir, 'package.json'))
      };
    } catch (e) {
      return false;
    }
  }));

  console.log('candidates', pluginCandidateDirectories);

  let plugins = pluginCandidateDirectories.filter(Boolean).filter(isPlugin);

  if (options.sort) {
    let graph = new DAG();
    plugins.forEach((plugin) => {
      let pluginConfig = plugin.pkg[options.configName || pkg.name] || {};
      graph.add(plugin.pkg.name, plugin, pluginConfig.before, pluginConfig.after);
    });
    plugins = [];
    graph.topsort((key, value) => {
      plugins.push(value);
    });
  }

  return plugins;

  function findCandidatesInDir(dir) {
    return fs.readdirSync(dir)
      // Handle scoped packages
      .reduce((candidates, name) => {
        if (name.charAt(0) === '@') {
          fs.readdirSync(path.join(dir, name))
          .forEach((scopedPackageName) => {
            candidates.push(path.join(name, scopedPackageName));
          });
        } else {
          candidates.push(name);
        }
        return candidates;
      }, [])
      // Get the full directory path
      .map((name) => path.join(dir, name))
      // Ensure it actually is a directory
      .filter((dir) => fs.statSync(dir).isDirectory())
      // Load the package.json for each
      .map((dir) => {
        try {
          return { dir, pkg: readPkg.sync(path.join(dir, 'package.json')) };
        } catch (e) {
          return false;
        }
      })
  }

  function findCandidatesFromPkg(pkg) {
    let dependencies = [];
    if (!options.excludeDependencies) {
      dependencies = dependencies.concat(Object.keys(pkg.dependencies || {}));
    }
    if (options.includeDev) {
      dependencies = dependencies.concat(Object.keys(pkg.devDependencies || {}));
    }
    if (options.includePeer) {
      dependencies = dependencies.concat(Object.keys(pkg.peerDependencies || {}));
    }
    if (options.includeBundle) {
      dependencies = dependencies.concat(Object.keys(pkg.bundleDependencies || pkg.bundledDependencies || {}));
    }
    if (options.includeOptional) {
      dependencies = dependencies.concat(Object.keys(pkg.optionalDependencies || {}));
    }
    console.log('deps:', dependencies);
    return dependencies
      // Load package.json's from resolved package location
      .map((dep) => {
        try {
          let pkgMainPath = resolve.sync(dep, { basedir: dir });
          let foundPkg = readPkgUp.sync({ cwd: path.dirname(pkgMainPath) });
          return { dir: path.dirname(foundPkg.path), pkg: foundPkg.pkg };
        } catch (e) {
          console.log('error loading from deps');
          console.log(e);
          return false;
        }
      })
  }

  // The filter function that determines whether a package is a plugin. If options.filter
  // is supplied, go with that. Otherwise, check for options.keyword match.
  function isPlugin(plugin) {
    if (options.filter) {
      return options.filter(plugin);
    }
    if (!plugin.pkg.keywords) {
      return false;
    }
    if (!keyword) {
      keyword = pkg.name;
    }
    return plugin.pkg.keywords.indexOf(keyword) > -1;
  }

}

findPlugins.default = findPlugins;

module.exports = findPlugins;
<|endoftext|>


<commit_before>var traverse = require('traverse');
var _slice = Array.prototype.slice;

var _isPromise = function(v){
	if (v && v.then) return true; // i don't know if there is a right way to do this. halp!

	return false;
};

var _intercept = function(self, name, fn){
	return function(){
		var callInfo = {
			name: name,
			arguments: _slice.call(arguments)
		};

		var result = callInfo.value = fn.apply(self, arguments);

		if (_isPromise(result)){
			result.done(function(v){
				result = callInfo.value = v;
			});
		}

		self.nostalgorithm.calls.push(callInfo);

		return result;
	};
};

function _getParentObjectFromPath(o, path){
	for (var i = 0; i<path.length-1; i++){
		o = o[path[i]];
	}

	return o;
}

function _replaceFunctions(o, fn){
	traverse(o).forEach(function(p){
		if (typeof p !== 'function') return;

		var self = this;

		fn.call(this, p, function(newFunc){
			var parent = _getParentObjectFromPath(o, self.path);

			if (self.key){
				parent[self.key] = newFunc;
			} else { // when p===obj is the root, i.e. when the root is a function
				o = newFunc;
				o.nostalgorithm = p.nostalgorithm;
			}
		});
	});

	return o;
}

var _watch = function(obj){
	obj.nostalgorithm = obj.nostalgorithm || {
		calls: []
	};

	obj = _replaceFunctions(obj, function(p, doReplace){
		var newFunc =  _intercept(obj, this.path.join('.'), p);
		newFunc.__nostalgorithmfunc = p;

		doReplace(newFunc);
	});

	return obj;
};

var _ignore = function(obj){
	if (!obj) return obj;

	var n = obj.nostalgorithm;

	obj = _replaceFunctions(obj, function(p, doReplace){
		if (!p.__nostalgorithmfunc) return;

		doReplace(p.__nostalgorithmfunc);
	});

	obj.nostalgorithm = n;

	return obj;
};

module.exports = {
	watch: _watch,
	ignore: _ignore
};
<commit_msg>ever so slightly better promise check<commit_after>var traverse = require('traverse');
var _slice = Array.prototype.slice;

var _isPromise = function(v){
	if (v && typeof v.then === 'function') return true; // i don't know if there is a right way to do this. halp!

	return false;
};

var _intercept = function(self, name, fn){
	return function(){
		var callInfo = {
			name: name,
			arguments: _slice.call(arguments)
		};

		var result = callInfo.value = fn.apply(self, arguments);

		if (_isPromise(result)){
			result.done(function(v){
				result = callInfo.value = v;
			});
		}

		self.nostalgorithm.calls.push(callInfo);

		return result;
	};
};

function _getParentObjectFromPath(o, path){
	for (var i = 0; i<path.length-1; i++){
		o = o[path[i]];
	}

	return o;
}

function _replaceFunctions(o, fn){
	traverse(o).forEach(function(p){
		if (typeof p !== 'function') return;

		var self = this;

		fn.call(this, p, function(newFunc){
			var parent = _getParentObjectFromPath(o, self.path);

			if (self.key){
				parent[self.key] = newFunc;
			} else { // when p===obj is the root, i.e. when the root is a function
				o = newFunc;
				o.nostalgorithm = p.nostalgorithm;
			}
		});
	});

	return o;
}

var _watch = function(obj){
	obj.nostalgorithm = obj.nostalgorithm || {
		calls: []
	};

	obj = _replaceFunctions(obj, function(p, doReplace){
		var newFunc =  _intercept(obj, this.path.join('.'), p);
		newFunc.__nostalgorithmfunc = p;

		doReplace(newFunc);
	});

	return obj;
};

var _ignore = function(obj){
	if (!obj) return obj;

	var n = obj.nostalgorithm;

	obj = _replaceFunctions(obj, function(p, doReplace){
		if (!p.__nostalgorithmfunc) return;

		doReplace(p.__nostalgorithmfunc);
	});

	obj.nostalgorithm = n;

	return obj;
};

module.exports = {
	watch: _watch,
	ignore: _ignore
};
<|endoftext|>


<commit_before>var parseMessage = require("irc-message").parseMessage;
var lstream = require("lstream");
var through = require("through");

module.exports = function messageStream () {
    var lineStream = new lstream();

    var stream = through(function (data) {
        lineStream.write(data);
    }, function () {
        lineStream = null;
    });

    lineStream.on("data", function (line) {
        var message = parseMessage(line);
        stream.queue(message);
    });

    return stream;
}
<commit_msg>fix error handling<commit_after>var parseMessage = require("irc-message").parseMessage;
var lstream = require("lstream");
var through = require("through");

module.exports = function messageStream () {
    var lineStream = new lstream();

    var stream = through(function (data) {
        lineStream.write(data);
    }, function () {
        lineStream = null;
    });

    lineStream.on("data", function (line) {
        var message = parseMessage(line);

        if (message === null) {
            var error = new Error("Invalid line read: " + line);
            return stream.emit("error", error);
        }

        stream.queue(message);
    });

    return stream;
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 * @private
 */

var express = require('express');

/**
 * Module exports.
 */

module.exports = expresschannels;
module.exports.router = router;
module.exports.stack = stack;

function expresschannels(options) {
  var opts = options || {};

  // option defaults
  var channels = opts.channels || [];
  var set = opts.set || function () { return opts.default; };

  // option validation
  if (!Array.isArray(channels) || channels.length === 0) {
    throw new Error('Option `channels` must be defined as an array of length >= 1');
  }

  return function setChannelMiddleware(req, res, next) {
    // promise support
    var selectChannel;
    if (typeof set === 'function') {
      selectChannel = Promise.resolve(set(req));
    } else {
      selectChannel = Promise.resolve(set);
    }

    selectChannel.then(function (channelKey) {
      // no channel selection
      if (!channelKey) {
        req._channels = [];
        return next();
      }

      // invalid channel selection
      if (channels.indexOf(channelKey) === -1) {
        return next(new Error('Channel `' + channelKey + '` not found in list of channels: ' + channels));
      }

      req._channels = channels.slice(channels.indexOf(channelKey));

      next();
    }, next);
  };
};

function stack(hash) {
  if (!hash) {
    throw new Error('Must provide hash for channel-specific content.');
  }

  return function (req, res, next) {
    if (!req._channels || !Array.isArray(req._channels)) {
      return next(new Error('Must register the expressChannels middleware before using `stack`.'));
    }

    // Get the list of available channel content
    var channelContent = req._channels
      .map(function (channel) {
        return hash[channel];
      });

    function load(i) {
      var n;
      if (i === channelContent.length - 1) {
        n = next; // At the last middleware, exit out via parent next
      }
      else {
        n = load.bind(null, i+1); // Load the next middleware
      }

      // This particular channel wasn't provided to the stack
      if (!channelContent[i]) {
        return n();
      }

      channelContent[i](req, res, n);
    }

    load(0);
  };
}

function router(original, hash, options) {
  var opts = options || {};

  opts.cascade = opts.cascade == null ? true : opts.cascade;

  if (!hash) {
    throw new Error('Must provide hash for channel-specific content.');
  }
  if (!original) {
    throw new Error('Must provide original middleware/router for non-channel content.');
  }

  // create router for URL branching
  var router = express.Router({ mergeParams: true });

  router.use(function (req, res, next) {
    if (!req._channels || !Array.isArray(req._channels)) {
      return next(new Error('Must register the expressChannels middleware before using `router`.'));
    }

    next();
  });

  // modify the URL with a new segment specific to each channel key
  router.use(flagUrlMiddleware(hash, opts.cascade));

  // register provided channel-specific content under the appropriate segments
  Object.keys(hash).forEach(function (channelKey) {
    router.use(routeFlag(channelKey), hash[channelKey]);
  });

  // use the original router lastly under a route so its mututally exclusive with channel content
  // if you don't do this, registering routes /foo and /bar on the original with /baz on a channel,
  // being on the channel will serve /foo, /bar and /baz.  This might be unexpected behavior.
  router.use(routeFlag(''), original);

  // restore the URL back to the original for future handlers
  router.use(restoreUrlMiddleware);

  return router;
}

function routeFlag(key) {
  return '/__' + key.toUpperCase() + '__';
}

function flagUrlMiddleware(hash, cascade) {
  return function (req, res, next) {
    var channelContent;
    var channelKey;
    var url = req.url;
    var i = 0;

    // req defines channels A, B, and C (therfore A is user's choice)
    // IF version A is defined, channel key is A
    // ELSE IF version B is defined, channel key is B, etc

    // req defines channels B and C (therefore B is user's choice)
    // IF version A is defined, channel key is undefined
    // ELSE IF version B is defined, channel key is B, etc

    if (cascade) {
      while (i < req._channels.length && !channelContent) {
        channelKey = req._channels[i];
        channelContent = hash[channelKey];
        i++;
      }
    } else {
      channelKey = req._channels[0];
      channelContent = hash[channelKey];
    }

    // If there is no channel content, use the original
    if (!channelContent) {
      channelKey = '';
    }

    req._originalUrl = url;

    req.url = routeFlag(channelKey);

    if (url[0] !== '/') {
      req.url += '/';
    }

    req.url += url;

    next();
  };
}

function restoreUrlMiddleware(req, res, next) {
  if (req._originalUrl) {
    req.url = req._originalUrl;
    delete req._originalUrl;
  }
  next();
}

<commit_msg>Fixing error in stack creating infinite loop when the user is not subscribed to a channel<commit_after>'use strict';

/**
 * Module dependencies.
 * @private
 */

var express = require('express');

/**
 * Module exports.
 */

module.exports = expresschannels;
module.exports.router = router;
module.exports.stack = stack;

function expresschannels(options) {
  var opts = options || {};

  // option defaults
  var channels = opts.channels || [];
  var set = opts.set || function () { return opts.default; };

  // option validation
  if (!Array.isArray(channels) || channels.length === 0) {
    throw new Error('Option `channels` must be defined as an array of length >= 1');
  }

  return function setChannelMiddleware(req, res, next) {
    // promise support
    var selectChannel;
    if (typeof set === 'function') {
      selectChannel = Promise.resolve(set(req));
    } else {
      selectChannel = Promise.resolve(set);
    }

    selectChannel.then(function (channelKey) {
      // no channel selection
      if (!channelKey) {
        req._channels = [];
        return next();
      }

      // invalid channel selection
      if (channels.indexOf(channelKey) === -1) {
        return next(new Error('Channel `' + channelKey + '` not found in list of channels: ' + channels));
      }

      req._channels = channels.slice(channels.indexOf(channelKey));

      next();
    }, next);
  };
};

function stack(hash) {
  if (!hash) {
    throw new Error('Must provide hash for channel-specific content.');
  }

  return function (req, res, next) {
    if (!req._channels || !Array.isArray(req._channels)) {
      return next(new Error('Must register the expressChannels middleware before using `stack`.'));
    }

    // No channels or no channel content
    if (!req._channels.length || !Object.keys(hash).length) {
      return next();
    }

    // Get the list of available channel content
    var channelContent = req._channels
      .map(function (channel) {
        return hash[channel];
      });

    function load(i) {
      var n;
      if (i === channelContent.length - 1) {
        n = next; // At the last middleware, exit out via parent next
      }
      else {
        n = load.bind(null, i+1); // Load the next middleware
      }

      // This particular channel wasn't provided to the stack
      if (!channelContent[i]) {
        return n();
      }

      channelContent[i](req, res, n);
    }

    load(0);
  };
}

function router(original, hash, options) {
  var opts = options || {};

  opts.cascade = opts.cascade == null ? true : opts.cascade;

  if (!hash) {
    throw new Error('Must provide hash for channel-specific content.');
  }
  if (!original) {
    throw new Error('Must provide original middleware/router for non-channel content.');
  }

  // create router for URL branching
  var router = express.Router({ mergeParams: true });

  router.use(function (req, res, next) {
    if (!req._channels || !Array.isArray(req._channels)) {
      return next(new Error('Must register the expressChannels middleware before using `router`.'));
    }

    next();
  });

  // modify the URL with a new segment specific to each channel key
  router.use(flagUrlMiddleware(hash, opts.cascade));

  // register provided channel-specific content under the appropriate segments
  Object.keys(hash).forEach(function (channelKey) {
    router.use(routeFlag(channelKey), hash[channelKey]);
  });

  // use the original router lastly under a route so its mututally exclusive with channel content
  // if you don't do this, registering routes /foo and /bar on the original with /baz on a channel,
  // being on the channel will serve /foo, /bar and /baz.  This might be unexpected behavior.
  router.use(routeFlag(''), original);

  // restore the URL back to the original for future handlers
  router.use(restoreUrlMiddleware);

  return router;
}

function routeFlag(key) {
  return '/__' + key.toUpperCase() + '__';
}

function flagUrlMiddleware(hash, cascade) {
  return function (req, res, next) {
    var channelContent;
    var channelKey;
    var url = req.url;
    var i = 0;

    // req defines channels A, B, and C (therfore A is user's choice)
    // IF version A is defined, channel key is A
    // ELSE IF version B is defined, channel key is B, etc

    // req defines channels B and C (therefore B is user's choice)
    // IF version A is defined, channel key is undefined
    // ELSE IF version B is defined, channel key is B, etc

    if (cascade) {
      while (i < req._channels.length && !channelContent) {
        channelKey = req._channels[i];
        channelContent = hash[channelKey];
        i++;
      }
    } else {
      channelKey = req._channels[0];
      channelContent = hash[channelKey];
    }

    // If there is no channel content, use the original
    if (!channelContent) {
      channelKey = '';
    }

    req._originalUrl = url;

    req.url = routeFlag(channelKey);

    if (url[0] !== '/') {
      req.url += '/';
    }

    req.url += url;

    next();
  };
}

function restoreUrlMiddleware(req, res, next) {
  if (req._originalUrl) {
    req.url = req._originalUrl;
    delete req._originalUrl;
  }
  next();
}

<|endoftext|>


<commit_before>/**
 * gulp-html-dependencies
 * Copyright(c) 2016 Sébastien Demanou
 * MIT Licensed
 */

'use strict';

/**
 * Module dependencies.
 * @private
 */

var es = require('event-stream')
  , gutil = require('gulp-util')
  , mkdirp = require("mkdirp")
  , path = require('path')
  , fs = require('fs')
  , url = require('url');

const PLUGIN_NAME = 'gulp-html-dependencies';
const REGEX = /(href|src)=("|')(.*((bower_components|node_modules)\/([a-z0-9\.+@~$!;:\/\\{}()\[\]|=&*£%§-]+\.[\w\d]+)))("|')/gi;

module.exports = (options) => {
    options = options || {};

    options.prefix = options.prefix || '/';

    return es.map((file, done) => {
        let dest = options.dest || path.dirname(file.path);

        dest = path.join(dest, options.prefix);

        file.contents = new Buffer(file.contents.toString().replace(REGEX, (match, attr, quote, uri, pathname, engine, filename) => {
            const f = options.flat ? path.basename(filename) : filename;
            const dest_file = path.join(dest, f);
            const url_file = url.resolve(options.prefix, f);

            try {
                mkdirp.sync(path.dirname(dest_file));
                fs.createReadStream(path.resolve(path.dirname(file.path), uri))
                    .pipe(fs.createWriteStream(dest_file));
            } catch(err) {
                return done(new gutil.PluginError(PLUGIN_NAME, err));
            }

            return attr + '=' + quote + url_file + quote;
        }));

        done(null, file);
    });
};
<commit_msg>fix options.prefix<commit_after>/**
 * gulp-html-dependencies
 * Copyright(c) 2016 Sébastien Demanou
 * MIT Licensed
 */

'use strict';

/**
 * Module dependencies.
 * @private
 */

var es = require('event-stream')
  , gutil = require('gulp-util')
  , mkdirp = require("mkdirp")
  , path = require('path')
  , fs = require('fs')
  , url = require('url');

const PLUGIN_NAME = 'gulp-html-dependencies';
const REGEX = /(href|src)=("|')(.*((bower_components|node_modules)\/([a-z0-9\.+@~$!;:\/\\{}()\[\]|=&*£%§-]+\.[\w\d]+)))("|')/gi;

module.exports = (options) => {
    options = options || {};

    options.prefix = options.prefix || '/';

    if (options.prefix.length > 1) {
        if (options.prefix[options.prefix.length - 1] != '/') {
            options.prefix += '/';
        }
    }

    return es.map((file, done) => {
        let dest = options.dest || path.dirname(file.path);

        dest = path.join(dest, options.prefix);

        file.contents = new Buffer(file.contents.toString().replace(REGEX, (match, attr, quote, uri, pathname, engine, filename) => {
            const f = options.flat ? path.basename(filename) : filename;
            const dest_file = path.join(dest, f);
            const url_file = url.resolve(options.prefix, f);

            try {
                mkdirp.sync(path.dirname(dest_file));
                fs.createReadStream(path.resolve(path.dirname(file.path), uri))
                    .pipe(fs.createWriteStream(dest_file));
            } catch(err) {
                return done(new gutil.PluginError(PLUGIN_NAME, err));
            }

            return attr + '=' + quote + url_file + quote;
        }));

        done(null, file);
    });
};
<|endoftext|>


<commit_before>// var allowCrossDomain = function(req, res, next) {
//     res.header('Access-Control-Allow-Origin', '*');
//     res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
//     res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

//     // intercept OPTIONS method
//     if ('OPTIONS' == req.method) {
//       res.send(200);
//     }
//     else {
//       next();
//     }
// };

var app = require('express')();
var http = require('http').Server(app);
// var cors = require('cors');
var io = require('socket.io')(http);

// io.set('transports', [
//         	'websocket',
//         	'flashsocket',
//         	'htmlfile',
//         	'xhr-polling',
//         	'jsonp-polling'
// 		    ]);

// // io.configure( function(){
//     io.set('origin', '*:*');
    // io.set('origins', "http://yaps.herokuapp.com" );
// });
// io.set("origins", "https://yaps.herokuapp.com");
io.set("origins","*:*");

// Enables CORS
// var enableCORS = function(req, res, next) {
//     res.header('Access-Control-Allow-Origin', '*');
//     res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
//     res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

//     // intercept OPTIONS method
//     if ('OPTIONS' == req.method) {
//       res.send(200);
//     }
//     else {
//       next();
//     }
// };

// // enable CORS!
// app.use(enableCORS);
// app.use(cors({credentials: true}));

// var allowCrossDomain = function(req, res, next) {
//     res.header('Access-Control-Allow-Origin', '*:*');
//     res.header('Access-Control-Allow-Credentials', true);
//     res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
//     res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
//     // debugger;
//     // intercept OPTIONS method
//     if ('OPTIONS' == req.method) {
//       res.send(200);
//     }
//     else {
//       next();
//     }
// };

// app.use(allowCrossDomain);

// app.use(allowCrossDomain);

// // app.configure(function () {
// //   app.use(express.bodyParser());
// //   app.use(express.methodOverride());
// //   app.use(allowCrossDomain);
// //   app.use(app.router);
// //   app.use(express.static(path.join(application_root, "public")));
// //   app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
// // });
// // io.configure(function () {
// //   io.set("transports", ["xhr-polling"]);
// //   io.set("polling duration", 10);
// // });

// // var cors = require('cors'); app.use(cors());

// // io.set('transports', [            // all transports (optional if you want flashsocket)
// //         'websocket'
// //         , 'flashsocket'
// //         , 'htmlfile'
// //         , 'xhr-polling'
// //         , 'jsonp-polling'
// //     ]);
// // io.set('origins', '*:*');

// // app.configure(function () {
// //   app.use(allowCrossDomain);
// //   app.use(express.bodyParser());
// //   app.use(express.methodOverride());
// //   app.use(app.router);
// //   app.use(express.static(path.join(application_root, "public")));
// //   app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
// // });

// // var username = confirm("Username?");
// var url = "http://yaps.herokuapp.com/"

var url = "/"

app.get(url, function(req, res){
  res.sendfile('index.html');
});

io.on('connection', function(socket){
	console.log('a user connected');
	socket.on('disconnect', function(){
		console.log('user disconnected');
	});
});

io.on('connection', function(socket){
	socket.on('chat message', function(msg){
		console.log('message: ' + msg);
	});
});

// // // broadcast to all
// // io.emit('some event', { for: 'everyone' });

// // // broadcast to everyone except for certain socket
// // io.on('connection', function(socket){
// // 	socket.broadcast.emit('hi');
// // });

io.on('connection', function(socket){
	socket.on('chat message', function(msg){
		io.emit('chat message', msg);
	});
});

// // http.listen(3001, function(){
// //   console.log('listening on *:3001');
// // });

// http.listen(url, function(){
//   console.log('listening to' + url);
// });

// // io.connect('http://yaps.herokuapp.com');
<commit_msg>lanlknalkn<commit_after>var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

io.set('transports', [
    	'websocket',
    	'flashsocket',
    	'htmlfile',
    	'xhr-polling',
    	'jsonp-polling'
    ]);

io.set("origins","*:*");

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*:*');
    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
    if ('OPTIONS' == req.method) {
      res.send(200);
    }
    else {
      next();
    }
};

// app.use(allowCrossDomain);

app.configure(function () {
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(allowCrossDomain);
  app.use(app.router);
  app.use(express.static(path.join(application_root, "public")));
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
io.configure(function () {
  io.set("transports", ["xhr-polling"]);
  io.set("polling duration", 10);
});

// // var username = confirm("Username?");
// var url = "http://yaps.herokuapp.com/"

var url = "/"

app.get(url, function(req, res){
  res.sendfile('index.html');
});

io.on('connection', function(socket){
	console.log('a user connected');
	socket.on('disconnect', function(){
		console.log('user disconnected');
	});
});

io.on('connection', function(socket){
	socket.on('chat message', function(msg){
		console.log('message: ' + msg);
	});
});

// // // broadcast to all
// // io.emit('some event', { for: 'everyone' });

// // // broadcast to everyone except for certain socket
// // io.on('connection', function(socket){
// // 	socket.broadcast.emit('hi');
// // });

io.on('connection', function(socket){
	socket.on('chat message', function(msg){
		io.emit('chat message', msg);
	});
});

// // http.listen(3001, function(){
// //   console.log('listening on *:3001');
// // });

// http.listen(url, function(){
//   console.log('listening to' + url);
// });

// // io.connect('http://yaps.herokuapp.com');
<|endoftext|>


<commit_before>var predator = require('predator');
var scrollIntoView = require('scroll-into-view');

// List of tagNames ordered by their likeliness to be the target of a click event
var textWeighting = ['h1', 'h2', 'h3', 'h4', 'label', 'p', 'a', 'button'];
var clickWeighting = ['button', 'input', 'a', 'h1', 'h2', 'h3', 'h4', 'i', 'label'];
var valueWeighting = ['input', 'textarea', 'select', 'label'];

var types = {
        'button': ['button', 'a'],
        'label': ['label', 'span', 'div'],
        'heading': ['h1', 'h2', 'h3', 'h4'],
        'image': ['img', 'svg'],
        'field': ['input', 'textarea', 'select', 'label'],
        'all': ['*'],
        'text': ['*']
    },
    noElementOfType = 'no elements of type ',
    documentScope,
    windowScope,
    runDelay,
    initialised;

function _pressKey(key, done) {
    var element = documentScope.activeElement;

    element.value += key;

    var keydownEvent = new windowScope.KeyboardEvent('keydown'),
        keyupEvent = new windowScope.KeyboardEvent('keyup'),
        pressKeyEvent = new windowScope.KeyboardEvent('pressKey');

    var method = 'initKeyboardEvent' in keydownEvent ? 'initKeyboardEvent' : 'initKeyEvent';

    keydownEvent[method]('keydown', true, true, windowScope, key, 3, true, false, true, false, false);
    keyupEvent[method]('keyup', true, true, windowScope, key, 3, true, false, true, false, false);
    pressKeyEvent[method]('pressKey', true, true, windowScope, key, 3, true, false, true, false, false);

    element.dispatchEvent(keydownEvent);
    element.dispatchEvent(keyupEvent);
    element.dispatchEvent(pressKeyEvent);

    done(null, element);
}

function _pressKeys(keys, done) {
    var nextKey = String(keys).charAt(0);

    if(nextKey === ''){
        return done(null, documentScope.activeElement);
    }

    _pressKey(nextKey, function() {
        setTimeout(function(){
            _pressKeys(String(keys).slice(1), done);
        }, 50);
    });
}

function findUi(selectors) {
    return Array.prototype.slice.call(documentScope.querySelectorAll(selectors))
        .sort(function(a, b){
            return !a.contains(b) ? -1 : 0;
        }); // deeper elements take precedence.
}

function _navigate(location, previousElement, done) {
    var callbackTimer;

    function handlewindowScopeError(error) {
        clearTimeout(callbackTimer);

        done(error);
        windowScope.removeEventListener('error', handlewindowScopeError);
    }

    windowScope.addEventListener('error', handlewindowScopeError);
    windowScope.location = location;

    callbackTimer = setTimeout(done, 150);
}

function _getLocation(done) {
    setTimeout(function() {
        done(null, windowScope.location);
    }, 500);
}

function matchElementValue(element, value) {
    return (
            element.textContent.toLowerCase() === value.toLowerCase() ||
            (element.title && element.title.toLowerCase() === value.toLowerCase())
        );
}

function findMatchingElements(value, type, elementsList) {
    return Array.prototype.slice.call(elementsList)
        .filter(function(element) {
            return matchElementValue(element, value);
        });
}

function getElementTextWeight(element) {
    var index = textWeighting.indexOf(element.tagName.toLowerCase());
    return textWeighting.length - (index < 0 ? Infinity : index);
}

function getElementClickWeight(element) {
    var index = clickWeighting.indexOf(element.tagName.toLowerCase());
    return clickWeighting.length - (index < 0 ? Infinity : index);
}

function getElementValueWeight(element) {
    var index = valueWeighting.indexOf(element.tagName.toLowerCase());
    return valueWeighting.length - (index < 0 ? Infinity : index);
}

function _findAllUi(value, type, done){
    if(!type){
        type = 'all';
    }

    var elementTypes = types[type];

    if(!elementTypes) {
        return done(new Error(type + ' is not a valid ui type'));
    }

    var elements = findUi(elementTypes);

    if(!elements.length) {
        return done(new Error(noElementOfType + type));
    }

    var results = findMatchingElements(value, type, elements)
        .sort(function(a, b) {
            return getElementTextWeight(a) < getElementTextWeight(b);
        });

    done(null, results);
}

function _findUi(value, type, returnArray, done) {
    if(!done) {
        done = returnArray;
        returnArray = false;
    }

    _findAllUi(value, type, function(error, elements){
        if(error){
            return done(error);
        }

        var results = Array.prototype.slice.call(elements)
            .filter(function(element){
                return !predator(element).hidden;
            });

        if(!results.length){
            return done(new Error('"' + value + '" was found but not visible on screen'));
        }

        done(null, returnArray ? results : results.shift());
    });
}

function _setValue(value, type, text, done) {
    _focus(value, type, function(error, element) {
        if(error){
            return done(error);
        }

        element.value = text;

        done(null, element);
    });
}

function _wait(time, done) {
    setTimeout(done, time || 0);
}

function findClickable(elements){
    for(var i = 0; i < elements.length; i++){
        var element = elements[i];
            rect = element.getBoundingClientRect(),
            clickElement = documentScope.elementFromPoint(rect.left + rect.width / 2, rect.top + rect.height / 2),
            clickElementInElement = element.contains(clickElement),
            elementInClickElement = clickElement.contains(element);

        if(clickElementInElement || elementInClickElement || clickElement === element){
            return clickElement;
        }
    }
}

function executeClick(value, type, done) {
    _findUi(value, 'all', true, function(error, elements) {
        if(error) {
            return done(error);
        }

        var clickableElements = elements
            .sort(function(a, b) {
                return getElementClickWeight(a) < getElementClickWeight(b);
            });

        var element = findClickable(elements);

        if(!element) {
            return done(new Error('could not find clickable element matching "' + value + '"'));
        }

        // SVG paths
        while(!element.click){
            element = element.parentNode;
        }

        element.click();

        setTimeout(function(){
            done(null, element);
        }, clickDelay)

    });
}

function _focus(value, type, done) {
   _findUi(value, type, true, function(error, elements){
        if(error){
            return done(error);
        }

        var result = elements
            .sort(function(a, b) {
                return getElementValueWeight(a) < getElementValueWeight(b);
            })
            .shift();

        result.focus();

        done(null, result);
   });
}

function _changeValue(value, type, text, done) {
    _focus(value, type, function(error, element) {
        if(error){
            return done(error);
        }

        _pressKeys(text, function(error){
            if(error){
                return done(error);
            }

            element.blur();

            var event = document.createEvent('HTMLEvents');

            event.initEvent('change', false, true);
            element.dispatchEvent(event);

            done(null, element);
        });
    });
}

function _getValue(value, type, done) {
    _focus(value, type, function(error, element) {
        if(error){
            return done(error);
        }

        done(null, 'value' in element ? element.value : element.textContent);
    });
}

function _blur(done) {
    var element = documentScope.activeElement;
    element.blur();

    done(null, element);
}

function _scrollTo(value, type, done){
    _findAllUi(value, type, function(error, elements) {
        if(error) {
            return done(error);
        }

        var targetElement = elements.shift();

        scrollIntoView(targetElement, function(){
            done(null, targetElement);
        });
    });
}

function runTasks(state, tasks, callback) {
    if(tasks.length) {
        tasks.shift()(function(error, result) {
            if(error) {
                return callback(error);
            } else {
                state.lastResult = result;

                if(tasks.length === 0) {
                    callback(null, result);
                } else {
                    runTasks(state, tasks, callback);
                }
            }
        });
    }
}

function driveUi(){
    var tasks = [],
        driverFunctions = {},
        state = {};

    function addTask(task){
        tasks.push(task);

        return driverFunctions;
    }

    driverFunctions = {
        navigate: function(location){
            return addTask(_navigate.bind(state, location));
        },
        findUi: function(value, type){
            return addTask(_findUi.bind(state, value, type));
        },
        getLocation: function() {
            return addTask(_getLocation.bind(state));
        },
        focus: function(value, type) {
            return addTask(_focus.bind(state, value, type));
        },
        blur: function() {
            return addTask(_blur.bind(state));
        },
        click: function(value, type){
            return addTask(executeClick.bind(state, value, type));
        },
        pressKey: function(value) {
            return addTask(_pressKey.bind(state, value));
        },
        pressKeys: function(value) {
            return addTask(_pressKeys.bind(state, value));
        },
        changeValue: function(value, type, text) {
            return addTask(_changeValue.bind(state, value, type, text));
        },
        setValue: function(value, type, text) {
            return addTask(_setValue.bind(state, value, type, text));
        },
        getValue: function(value, type) {
            return addTask(_getValue.bind(state, value, type));
        },
        wait: function(time) {
            if(!arguments.length) {
                time = runDelay;
            }

            return addTask(_wait.bind(state, time));
        },
        do: function(driver){
            return addTask(driver.go);
        },
        check: function(task){
            return addTask(function(callback){
                task(state.lastResult, callback);
            });
        },
        scrollTo: function(value, type){
            return addTask(_scrollTo.bind(state, value, type));
        },
        go: function(callback) {
            if(!initialised) {
                throw(new Error('init must becalled before calling go'));
            }

            if(tasks.length) {
                tasks.unshift(_wait.bind(state, runDelay));
                runTasks(state, tasks, callback);
            } else {
                callback(new Error('No tasks defined'));
            }
        }
    };

    return driverFunctions;
}

driveUi.init = function(settings) {
    documentScope = settings.document || document;
    windowScope = settings.window || window;
    runDelay = settings.runDelay || 0;
    clickDelay = settings.clickDelay || 100;

    initialised = true;
};

module.exports = driveUi;
<commit_msg>Added in, contextual searching<commit_after>var predator = require('predator');
var scrollIntoView = require('scroll-into-view');

// List of tagNames ordered by their likeliness to be the target of a click event
var textWeighting = ['h1', 'h2', 'h3', 'h4', 'label', 'p', 'a', 'button'];
var clickWeighting = ['button', 'input', 'a', 'h1', 'h2', 'h3', 'h4', 'i', 'label'];
var valueWeighting = ['input', 'textarea', 'select', 'label'];

var types = {
        'button': ['button', 'a'],
        'label': ['label', 'span', 'div'],
        'heading': ['h1', 'h2', 'h3', 'h4'],
        'image': ['img', 'svg'],
        'field': ['input', 'textarea', 'select', 'label'],
        'all': ['*'],
        'text': ['*']
    },
    noElementOfType = 'no elements of type ',
    documentScope,
    windowScope,
    runDelay,
    initialised;

function _pressKey(key, done) {
    var element = this.currentContext.activeElement;

    element.value += key;

    var keydownEvent = new windowScope.KeyboardEvent('keydown'),
        keyupEvent = new windowScope.KeyboardEvent('keyup'),
        pressKeyEvent = new windowScope.KeyboardEvent('pressKey');

    var method = 'initKeyboardEvent' in keydownEvent ? 'initKeyboardEvent' : 'initKeyEvent';

    keydownEvent[method]('keydown', true, true, windowScope, key, 3, true, false, true, false, false);
    keyupEvent[method]('keyup', true, true, windowScope, key, 3, true, false, true, false, false);
    pressKeyEvent[method]('pressKey', true, true, windowScope, key, 3, true, false, true, false, false);

    element.dispatchEvent(keydownEvent);
    element.dispatchEvent(keyupEvent);
    element.dispatchEvent(pressKeyEvent);

    done(null, element);
}

function _pressKeys(keys, done) {
    var state = this,
        nextKey = String(keys).charAt(0);

    if(nextKey === ''){
        return done(null, this.currentContext.activeElement);
    }

    _pressKey.call(state, nextKey, function() {
        setTimeout(function(){
            _pressKeys.call(state, String(keys).slice(1), done);
        }, 50);
    });
}

function findUi(currentContex, selectors) {
    return Array.prototype.slice.call(currentContex.querySelectorAll(selectors))
        .sort(function(a, b){
            return !a.contains(b) ? -1 : 0;
        }); // deeper elements take precedence.
}

function _navigate(location, previousElement, done) {
    var callbackTimer;

    function handlewindowScopeError(error) {
        clearTimeout(callbackTimer);

        done(error);
        windowScope.removeEventListener('error', handlewindowScopeError);
    }

    windowScope.addEventListener('error', handlewindowScopeError);
    windowScope.location = location;

    callbackTimer = setTimeout(done, 150);
}

function _getLocation(done) {
    setTimeout(function() {
        done(null, windowScope.location);
    }, 500);
}

function matchElementValue(element, value) {
    return (
            element.textContent.toLowerCase() === value.toLowerCase() ||
            (element.title && element.title.toLowerCase() === value.toLowerCase())
        );
}

function findMatchingElements(value, type, elementsList) {
    return Array.prototype.slice.call(elementsList)
        .filter(function(element) {
            return matchElementValue(element, value);
        });
}

function getElementTextWeight(element) {
    var index = textWeighting.indexOf(element.tagName.toLowerCase());
    return textWeighting.length - (index < 0 ? Infinity : index);
}

function getElementClickWeight(element) {
    var index = clickWeighting.indexOf(element.tagName.toLowerCase());
    return clickWeighting.length - (index < 0 ? Infinity : index);
}

function getElementValueWeight(element) {
    var index = valueWeighting.indexOf(element.tagName.toLowerCase());
    return valueWeighting.length - (index < 0 ? Infinity : index);
}

function _findAllUi(value, type, done){
    if(!type){
        type = 'all';
    }

    var elementTypes = types[type];

    if(!elementTypes) {
        return done(new Error(type + ' is not a valid ui type'));
    }

    var elements = findUi(this.currentContext, elementTypes);

    if(!elements.length) {
        return done(new Error(noElementOfType + type));
    }

    var results = findMatchingElements(value, type, elements)
        .sort(function(a, b) {
            return getElementTextWeight(a) < getElementTextWeight(b);
        });

    done(null, results);
}

function _findUi(value, type, returnArray, done) {
    if(!done) {
        done = returnArray;
        returnArray = false;
    }

    _findAllUi.call(this, value, type, function(error, elements){
        if(error){
            return done(error);
        }

        var results = Array.prototype.slice.call(elements)
            .filter(function(element){
                return !predator(element).hidden;
            });

        if(!results.length){
            return done(new Error('"' + value + '" was found but not visible on screen'));
        }

        done(null, returnArray ? results : results.shift());
    });
}

function _setValue(value, type, text, done) {
    _focus.call(this, value, type, function(error, element) {
        if(error){
            return done(error);
        }

        element.value = text;

        done(null, element);
    });
}

function _wait(time, done) {
    setTimeout(done, time || 0);
}

function findClickable(currentContext, elements){
    for(var i = 0; i < elements.length; i++){
        var element = elements[i];
            rect = element.getBoundingClientRect(),
            clickElement = currentContext.elementFromPoint(rect.left + rect.width / 2, rect.top + rect.height / 2),
            clickElementInElement = element.contains(clickElement),
            elementInClickElement = clickElement.contains(element);

        if(clickElementInElement || elementInClickElement || clickElement === element){
            return clickElement;
        }
    }
}

function executeClick(value, type, done) {
    var state = this;
    _findUi.call(state, value, 'all', true, function(error, elements) {
        if(error) {
            return done(error);
        }

        var clickableElements = elements
            .sort(function(a, b) {
                return getElementClickWeight(a) < getElementClickWeight(b);
            });

        var element = findClickable(state.currentContext, elements);

        if(!element) {
            return done(new Error('could not find clickable element matching "' + value + '"'));
        }

        // SVG paths
        while(!element.click){
            element = element.parentNode;
        }

        element.click();

        setTimeout(function(){
            done(null, element);
        }, clickDelay)

    });
}

function _focus(value, type, done) {
   _findUi.call(this, value, type, true, function(error, elements){
        if(error){
            return done(error);
        }

        var result = elements
            .sort(function(a, b) {
                return getElementValueWeight(a) < getElementValueWeight(b);
            })
            .shift();

        result.focus();

        done(null, result);
   });
}

function _changeValue(value, type, text, done) {
    var state = this;

    _focus.call(state, value, type, function(error, element) {
        if(error){
            return done(error);
        }

        _pressKeys.call(state, text, function(error){
            if(error){
                return done(error);
            }

            element.blur();

            var event = document.createEvent('HTMLEvents');

            event.initEvent('change', false, true);
            element.dispatchEvent(event);

            done(null, element);
        });
    });
}

function _getValue(value, type, done) {
    _focus.call(this, value, type, function(error, element) {
        if(error){
            return done(error);
        }

        done(null, 'value' in element ? element.value : element.textContent);
    });
}

function _blur(done) {
    var element = this.currentContext.activeElement;
    element.blur();

    done(null, element);
}

function _scrollTo(value, type, done){
    _findAllUi.call(this, value, type, function(error, elements) {
        if(error) {
            return done(error);
        }

        var targetElement = elements.shift();

        scrollIntoView(targetElement, function(){
            done(null, targetElement);
        });
    });
}

function runTasks(state, tasks, callback) {
    if(tasks.length) {
        tasks.shift()(function(error, result) {
            if(error) {
                return callback(error);
            } else {
                state.lastResult = result;

                if(tasks.length === 0) {
                    callback(null, result);
                } else {
                    runTasks(state, tasks, callback);
                }
            }
        });
    }
}

function driveUi(currentContext){
    var tasks = [],
        driverFunctions = {},
        state = {
            currentContext: currentContext || documentScope
        };

    function addTask(task){
        tasks.push(task);

        return driverFunctions;
    }

    driverFunctions = {
        navigate: function(location){
            return addTask(_navigate.bind(state, location));
        },
        findUi: function(value, type){
            return addTask(_findUi.bind(state, value, type));
        },
        getLocation: function() {
            return addTask(_getLocation.bind(state));
        },
        focus: function(value, type) {
            return addTask(_focus.bind(state, value, type));
        },
        blur: function() {
            return addTask(_blur.bind(state));
        },
        click: function(value, type){
            return addTask(executeClick.bind(state, value, type));
        },
        pressKey: function(value) {
            return addTask(_pressKey.bind(state, value));
        },
        pressKeys: function(value) {
            return addTask(_pressKeys.bind(state, value));
        },
        changeValue: function(value, type, text) {
            return addTask(_changeValue.bind(state, value, type, text));
        },
        setValue: function(value, type, text) {
            return addTask(_setValue.bind(state, value, type, text));
        },
        getValue: function(value, type) {
            return addTask(_getValue.bind(state, value, type));
        },
        wait: function(time) {
            if(!arguments.length) {
                time = runDelay;
            }

            return addTask(_wait.bind(state, time));
        },
        do: function(driver){
            return addTask(driver.go);
        },
        in: function(value, type, addSubTasks){
            return addTask(function(done){
                _findUi.call(state, value, type, function(error, element){
                    if(error){
                        return done(error);
                    }

                    var newDriver = driveUi(element);

                    addSubTasks(newDriver);

                    newDriver.go(done);
                });
            });
        },
        check: function(task){
            return addTask(function(callback){
                task(state.lastResult, callback);
            });
        },
        scrollTo: function(value, type){
            return addTask(_scrollTo.bind(state, value, type));
        },
        go: function(callback) {
            if(!initialised) {
                throw(new Error('init must becalled before calling go'));
            }

            if(tasks.length) {
                tasks.unshift(_wait.bind(state, runDelay));
                runTasks(state, tasks, callback);
            } else {
                callback(new Error('No tasks defined'));
            }
        }
    };

    return driverFunctions;
}

driveUi.init = function(settings) {
    documentScope = settings.document || document;
    windowScope = settings.window || window;
    runDelay = settings.runDelay || 0;
    clickDelay = settings.clickDelay || 100;

    initialised = true;
};

module.exports = driveUi;
<|endoftext|>


<commit_before>'use strict';

require('./block_arduino');
require('./block_sensorboard');
require('./block_joystick');
require('./block_dplay');
require('./block_nemoino');
require('./block_ardublock');
require('./block_arduino_nano');
require('./block_roboid');
require('./block_mkboard');
require('./block_memaker');
require('./block_smartboard');
require('./block_rokoboard');
require('./block_albert');
require('./block_altino');
require('./block_arduino_ext');
require('./block_coding_box');
require('./block_bitbrick');
require('./block_blacksmith');
require('./block_byrobot_dronefighter_controller');
require('./block_byrobot_dronefighter_drive');
require('./block_byrobot_dronefighter_flight');
require('./block_byrobot_petrone_v2_controller');
require('./block_byrobot_petrone_v2_drive');
require('./block_byrobot_petrone_v2_flight');
require('./block_chocopi');
require('./block_cobl');
require('./block_coconut');
require('./block_codeino');
require('./block_codestar');
require('./block_dadublock');
require('./block_edumaker');
require('./block_ev3');
require('./block_hamster');
require('./block_hummingbird');
require('./block_iboard');
require('./block_jdkit');
require('./block_mechatronics_4d');
require('./block_modi');
require('./block_neobot');
require('./block_neobot_sensor_theme');
require('./block_roborobo');
require('./block_robotis');
require('./block_robotori');
require('./block_truerobot');
require('./block_turtle');
require('./block_xbot');
require('./block_playcode');
require('./block_mechatro');
require('./block_creamo');
require('./block_funboard');
require('./block_microbit');
require('./block_mrt');
require('./block_dash');
require('./block_bingles');
require('./block_codingmachine');

Entry.HARDWARE_LIST = {
    '1.1': Entry.Arduino,
    '1.2': Entry.SensorBoard,
    '1.3': Entry.CODEino,
    '1.4': Entry.joystick,
    '1.5': Entry.dplay,
    '1.6': Entry.nemoino,
    '1.7': Entry.Xbot,
    '1.8': Entry.ardublock,
    '1.9': Entry.ArduinoExt,
    '1.10': Entry.ArduinoNano,
    '1.A': Entry.Cobl,
    '1.B': Entry.Blacksmith,
    '1.C': Entry.CodingBox,
    '2.4': Entry.Hamster,
    '2.5': Entry.Albert,
    '2.9': Entry.Turtle,
    '2.FF': Entry.Roboid,
    '3.1': Entry.Bitbrick,
    '4.2': Entry.Arduino,
    '5.1': Entry.Neobot,
    '5.2': Entry.NeobotSensorTheme,
    '6.1': Entry.mkboard,
    '6.2': Entry.memaker,
    '7.1': Entry.Robotis_carCont,
    '7.2': Entry.Robotis_openCM70,
    '8.1': Entry.Arduino,
    '9.1': Entry.iboard,
    'A.1': Entry.SmartBoard,
    'B.1': Entry.Codestar,
    'C.1': Entry.DaduBlock,
    'C.2': Entry.DaduBlock_Car,
    'D.1': Entry.robotori,
    'F.1': Entry.byrobot_dronefighter_controller,
    'F.2': Entry.byrobot_dronefighter_drive,
    'F.3': Entry.byrobot_dronefighter_flight,
    'F.4': Entry.byrobot_petrone_v2_controller,
    'F.5': Entry.byrobot_petrone_v2_drive,
    'F.6': Entry.byrobot_petrone_v2_flight,
    '10.1': Entry.Roborobo_Roduino,
    '10.2': Entry.Roborobo_SchoolKit,
    '12.1': Entry.EV3,
    '13.1': Entry.rokoboard,
    '14.1': Entry.Chocopi,
    '15.1': Entry.coconut,
    '16.1': Entry.MODI,
    '18.1': Entry.Altino,
    '19.1': Entry.trueRobot,
    '1A.1': Entry.ArduinoNano,
    '1B.1': Entry.EduMaker,
    '1C.1': Entry.hummingbird,
    '1D.1': Entry.JDKit,
    '1E.1': Entry.playcode,
    '1F.1': Entry.mechatro,
    '20.1': Entry.Creamo,
    '21.1': Entry.FunBoard,
    '22.1': Entry.Microbit,
    '23.1': Entry.MRT,
    '24.1': Entry.Dash,
    '1.D': Entry.BINGLES,
    'FF.FF': Entry.Codingmachine
};

const startBlock = require('./block_start');
const flowBlock = require('./block_flow');
const movingBlock = require('./block_moving');
const looksBlock = require('./block_looks');
const brushBlock = require('./block_brush');
const textBlock = require('./block_text');
const soundBlock = require('./block_sound');
const judgementBlock = require('./block_judgement');
const calcBlock = require('./block_calc');
const variableBlock = require('./block_variable');
const funcBlock = require('./block_func');

require('./block_expansion_weather');
Entry.EXPANSION_BLOCK = {};
Entry.EXPANSION_BLOCK_LIST = {
    'weather' : Entry.Expansion_Weather
};

function getBlockObject(items) {
    const blockObject = {};
    items.forEach((item)=> {
        if('getBlocks' in item) {
            Object.assign(blockObject, item.getBlocks());
        }
    });
    return blockObject;
}

module.exports = {
    getBlocks() {
        const basicBlockList = [
            startBlock,
            flowBlock,
            movingBlock,
            looksBlock,
            brushBlock,
            textBlock,
            soundBlock,
            judgementBlock,
            calcBlock,
            variableBlock,
            funcBlock
        ];
        const expansionBlockList = Object.values(Entry.EXPANSION_BLOCK_LIST);
        const hardwareList = Object.values(Entry.HARDWARE_LIST);
        return getBlockObject(basicBlockList.concat(hardwareList).concat(expansionBlockList));
    }
}
<commit_msg>Delete index.js<commit_after><|endoftext|>