<commit_before>import _                 from 'lodash';
import fs                from 'fs';
import express           from 'express';
import path              from 'path';
import pathExists        from 'path-exists';
import cookieParser      from 'cookie-parser';
import bodyParser        from 'body-parser';
import compression       from 'compression';
import forceDomain       from 'forcedomain';
import timeout           from 'connect-timeout';
import basicAuth         from 'basic-auth';
import responseTime      from 'response-time';
import redirect          from 'express-redirect';
import rewrite           from 'express-urlrewrite';
import httpError         from 'http-errors';
import helmet            from 'helmet';
import vhost             from 'vhost';
import logger            from 'morgan';
import fileStreamRotator from 'file-stream-rotator';
import Debug             from 'debug';
import routes            from './routes';
import {toArray}         from './utils';
import {seo}             from './middlewares';
import {
  cookies,
  // redirects,
  // rewrites,
  express as expressConfig
} from './config';

const app = express();
const cwd = process.cwd();
const debug = Debug('app:server');
const isProduction = app.get('env') == 'production';

debug(`Setup ${app.get('env')} server`);

/**
 * Устанавливаем настройки всего приложения
 */
if (_.isPlainObject(expressConfig.set)) {
  _.forEach(expressConfig.set, (val, key) => app.set(key, val));
}

/**
 * Устанавливаем переменные для шаблонов, которые будут доступны всегда
 * (если их не перезаписывать)
 */
if (_.isPlainObject(expressConfig.locals)) {
  _.assign(app.locals, expressConfig.locals);
}

/**
 * Немного seo-шной консистентности
 */
app.use(seo({
  toLower: true,
  removeHtmlSuffix: true,
  removeTrailingSlash: true
}));
// app.use(vhost('api.localhost', function (req, res) {
//   // handle req + res belonging to api.localhost
//   res.send('is api host');
// }));
//
// app.use(forceDomain({
//   hostname: 'localhost',
//   port: app.get('port'),
//   // protocol: 'https'
// }));

// redirect(app);
// Object.keys(redirects).forEach(from => {
//   let to = redirects[from];
//   app.redirect(from, to, 301, true);
// });
//
// Object.keys(rewrites).forEach(from => {
//   let to = rewrites[from];
//   app.use(rewrite(from, to));
// });
// /seo

/**
 * Шарим статику.
 * Настройка сессий должна идти после статики,
 * чтобы не создавать пустые сессии на каждый статичный файл.
 * Если нужны логи статики, то надо поместить эту мидлварю после логгирования.
 */
app.use(express.static(path.join(cwd, 'public'), expressConfig.static));

/**
 * Логирование запросов
 */
if (!isProduction) {
  // app.use(logger('dev'));
  app.use(logger('combined'));
} else {
  /** на продакшене логируем в файл, с суточной ротацией */
  let logDirectory = path.join(cwd, '/logs');
  !pathExists.sync(logDirectory) && fs.mkdirSync(logDirectory);

  app.use(logger('common', {
    stream: fileStreamRotator.getStream({
      frequency:   'daily',
      date_format: 'YYYYMMDD',
      filename:    path.join(logDirectory, 'access-%DATE%.log'),
      verbose:     false
    })
  }));
}

/**
 * Устанавливаем http-аутентификацию, если логины-пароли заданы в конфиге.
 * В конфиге можно задать несколько логинов/паролей.
 */
if (!!expressConfig.basicAuth) {
  let allowedCredentials = toArray(expressConfig.basicAuth);
  app.use(function (req, res, next) {
    req.user = {};

    let credentials = basicAuth(req);
    let user = credentials ? _.find(allowedCredentials, credentials) : null;
    if (!user) {
      res.statusCode = 401;
      res.set('WWW-Authenticate', 'Basic realm="Authentication Required"');
      return next(new httpError.Unauthorized());
    } else {
      req.user = user;
      next();
    }
  });

  /** todo: вынести логаут-урл http-аутентификации в конфиг */
  /** todo: logout косячный, нормально будет работать только если, слать сюда запрос из front-js */
  app.get('/logout', function (req, res, next) {
    res.set('WWW-Authenticate', 'Basic realm="Authentication Required"');
    req.user = {};
    res.status(401);
    // return res.render('redirect');
    return next(new httpError.Unauthorized());
  });
}

/**
 * Основные настройки - таймауты, парсеры тела запроса, кук
 */
// todo: ещё раз изучить connect-timeout
// app.use(timeout(15000));
/** Кукожим ответ */
app.use(compression({
  threshold: 128,
  filter (req, res) {
    return req.headers['x-no-compression'] ? false : compression.filter(req, res);
  }
}));
app.use(bodyParser.json({
  type: ['json', 'application/csp-report']
}));
app.use(bodyParser.urlencoded({extended: true}));
/** парсим печеньки в заголовках */
app.use(cookieParser(cookies.secret));
/** добавляем заголовок с временем ответа */
app.use(responseTime());

/**
 * Настройки безопасности.
 * Если снаружи стоит nginx для статики, то надо продублировать там все эти настройки заголовков
 */

/** Запрет на показ в айфрейме (sameorigin - можно только с того же домена) */
app.use(helmet.frameguard({action: 'sameorigin'})); // or { action: 'deny' }

/** пусть мамкины хакеры голову ломают */
app.use(helmet.hidePoweredBy({ setTo: 'PHP 4.2.0' }));

/** установим "X-DNS-Prefetch-Control: off", чтобы браузеры (которые это умеют) не префетчили ip нашего домена */
app.use(helmet.dnsPrefetchControl());

/** для старых ишаков ставим "X-Download-Options: noopen", чтобы контент, который надо скачать, они не открывали в контексте сайта */
app.use(helmet.ieNoOpen());

/** ставим "X-Content-Type-Options: nosniff", чтобы браузер доверял посланным сервером миме-типам, блочил не совпадающие и не пытался угадывать миме по содежимому загруженных файлов (а то ещё начнёт выполнять то, чего выполнять не должен) */
app.use(helmet.noSniff());

/** устанавливаем "Referrer-Policy". Честно говоря лень разбираться во всех значениях: https://www.w3.org/TR/referrer-policy/#referrer-policies */
// app.use(helmet.referrerPolicy({ policy: 'same-origin' }));

/** и поставим "X-XSS-Protection: 1; mode=block" */
app.use(helmet.xssFilter());

/** если юзается ssl, то надо послать браузеру открытые ключи, чтобы он их сохранил и при последующих запросах оберегал юзера от скомпрометированных центрах сертификации */
app.use(helmet.hpkp({
  setIf (req, res) {
    return !!req.secure;
  },
  maxAge: 9 * 24 * 60 * 60, // 9 дней в секундах
  sha256s: ['AbCdEf123=', 'ZyXwVu456='], // заменить на свои значения
  includeSubdomains: true,
  reportUri: 'https://example.com/hpkp-report',
  reportOnly: false
}));

/** опять же, если юзается ssl. говорит браузеру ходить только по https */
app.use(helmet.hsts({
  // or `force: true`
  setIf (req, res) {
    return !!req.secure;
  },
  maxAge: 5 * 24 * 60 * 60, // 6 дней в секундах
  includeSubDomains: true,
  preload: true
}));

/** csurf должен идти _после_ роута для приёма репортов */
/** todo: вынести настройки csp в конфиг */
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'", 'somecdn.com'],
    styleSrc: ["'self'", "'unsafe-inline'", 'maxcdn.bootstrapcdn.com'],
    imgSrc: ['img.com', 'data:'],
    // todo: печеньки не читаются. изучить про sandbox
    // sandbox: ['allow-forms', 'allow-scripts', 'allow-same-origin'],
    reportUri: '/report-csp-violation',
    objectSrc: ["'none'"], // An empty array allows nothing through
  },
  setAllHeaders: true,
  disableAndroid: true
}));
/** роут для приёма репортов о нарушении csp (нормальные браузеры будут слать сюда отчёты) */
app.post('/report-csp-violation', function (req, res) {
  if (!isProduction) {
    let body = req.body ? req.body : 'No data received!';
    console.error(`CSP Violation: ${body}`);
  } else {
    /** на продакшене логируем в файл, с суточной ротацией */
    let logDirectory = path.join(cwd, '/logs');
    !pathExists.sync(logDirectory) && fs.mkdirSync(logDirectory);

    /** todo: добавить генерацию логов */
    // app.use(logger('csp', {
    //   stream: fileStreamRotator.getStream({
    //     frequency:   'daily',
    //     date_format: 'YYYYMMDD',
    //     filename:    path.join(logDirectory, 'csp-%DATE%.log'),
    //     verbose:     false
    //   })
    // }));
  }

  res.status(204).end();
});

/**
 * Ну как бы можно включить парсинг sass'а на лету,
 * но как бы нехер говнокодить.
 */
// app.use(require('node-sass-middleware')({
//   src:            path.join(cwd, 'public'),
//   dest:           path.join(cwd, 'public'),
//   indentedSyntax: false,
//   sourceMap:      true
// }));

/**
 * Пошли маршруты
 */
app.use('/', routes);

/** Если дошли сюда, значит на запрос не нашлось нужного роута. Отправим 404. */
app.use(function (req, res, next) {
  return next(new httpError.NotFound());
});

/**
 * Если дошли сюда - значит пойманная/переданная ошибка.
 */
app.use(function (err, req, res, next) {
  // respect err.statusCode
  if (err.statusCode) {
    res.statusCode = err.statusCode
  }

  // respect err.status
  if (err.status) {
    res.statusCode = err.status
  }

  // default status code to 500
  if (res.statusCode < 400) {
    res.statusCode = 500
  }

  // cannot actually respond
  if (res._header) {
    return req.socket.destroy()
  }

  // todo логировать ошибки в файлы
  // console.error(err);
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error:   app.get('env') != 'production' ? err : {}
  });
});

// todo
// https://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception
// process.on('uncaughtException', (err) => {
//   fs.writeSync(1, `Caught exception: ${err}`);
// });
// process.on('unhandledRejection', (reason, p) => {
//   console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
//   // application specific logging, throwing an error, or other logic here
// });

export default app;
<commit_msg>некоторые моменты...<commit_after>import _                 from 'lodash';
import fs                from 'fs';
import express           from 'express';
import path              from 'path';
import pathExists        from 'path-exists';
import cookieParser      from 'cookie-parser';
import bodyParser        from 'body-parser';
import compression       from 'compression';
import forceDomain       from 'forcedomain';
import timeout           from 'connect-timeout';
import basicAuth         from 'basic-auth';
import responseTime      from 'response-time';
import redirect          from 'express-redirect';
import rewrite           from 'express-urlrewrite';
import httpError         from 'http-errors';
import helmet            from 'helmet';
import vhost             from 'vhost';
import logger            from 'morgan';
import fileStreamRotator from 'file-stream-rotator';
import Debug             from 'debug';
import routes            from './routes';
import {toArray}         from './utils';
import {seo}             from './middlewares';
import {
  cookies,
  // redirects,
  // rewrites,
  express as expressConfig
} from './config';

const app = express();
const cwd = process.cwd();
const debug = Debug('app:server');
const isProduction = app.get('env') == 'production';

debug(`Setup ${app.get('env')} server`);

/**
 * Устанавливаем настройки всего приложения
 */
if (_.isPlainObject(expressConfig.set)) {
  _.forEach(expressConfig.set, (val, key) => app.set(key, val));
}

/**
 * Устанавливаем переменные для шаблонов, которые будут доступны всегда
 * (если их не перезаписывать)
 */
if (_.isPlainObject(expressConfig.locals)) {
  _.assign(app.locals, expressConfig.locals);
}

/**
 * Немного seo-шной консистентности
 */
app.use(seo({
  toLower: true,
  removeHtmlSuffix: true,
  removeTrailingSlash: true
}));
// app.use(vhost('api.localhost', function (req, res) {
//   // handle req + res belonging to api.localhost
//   res.send('is api host');
// }));
//
// app.use(forceDomain({
//   hostname: 'localhost',
//   port: app.get('port'),
//   // protocol: 'https'
// }));

// redirect(app);
// Object.keys(redirects).forEach(from => {
//   let to = redirects[from];
//   app.redirect(from, to, 301, true);
// });
//
// Object.keys(rewrites).forEach(from => {
//   let to = rewrites[from];
//   app.use(rewrite(from, to));
// });
// /seo

/**
 * Шарим статику.
 * Настройка сессий должна идти после статики,
 * чтобы не создавать пустые сессии на каждый статичный файл.
 * Если нужны логи статики, то надо поместить эту мидлварю после логгирования.
 */
app.use(express.static(path.join(cwd, 'public'), expressConfig.static));

/**
 * Логирование запросов
 */
if (!isProduction) {
  // app.use(logger('dev'));
  app.use(logger('combined'));
} else {
  /** на продакшене логируем в файл, с суточной ротацией */
  let logDirectory = path.join(cwd, '/logs');
  !pathExists.sync(logDirectory) && fs.mkdirSync(logDirectory);

  app.use(logger('common', {
    stream: fileStreamRotator.getStream({
      frequency:   'daily',
      date_format: 'YYYYMMDD',
      filename:    path.join(logDirectory, 'access-%DATE%.log'),
      verbose:     false
    })
  }));
}

/**
 * Устанавливаем http-аутентификацию, если логины-пароли заданы в конфиге.
 * В конфиге можно задать несколько логинов/паролей.
 */
if (!!expressConfig.basicAuth) {
  let allowedCredentials = toArray(expressConfig.basicAuth);
  app.use(function (req, res, next) {
    req.user = {};

    let credentials = basicAuth(req);
    let user = credentials ? _.find(allowedCredentials, credentials) : null;
    if (!user) {
      res.statusCode = 401;
      res.set('WWW-Authenticate', 'Basic realm="Authentication Required"');
      return next(new httpError.Unauthorized());
    } else {
      req.user = user;
      next();
    }
  });

  /** todo: вынести логаут-урл http-аутентификации в конфиг */
  /** todo: logout косячный, нормально будет работать только если, слать сюда запрос из front-js */
  app.get('/logout', function (req, res, next) {
    res.set('WWW-Authenticate', 'Basic realm="Authentication Required"');
    req.user = {};
    res.status(401);
    // return res.render('redirect');
    return next(new httpError.Unauthorized());
  });
}

/**
 * Основные настройки - таймауты, парсеры тела запроса, кук
 */
// todo: ещё раз изучить connect-timeout
// app.use(timeout(15000));
/** Кукожим ответ */
app.use(compression({
  threshold: 128,
  filter (req, res) {
    return req.headers['x-no-compression'] ? false : compression.filter(req, res);
  }
}));
app.use(bodyParser.json({
  type: ['json', 'application/csp-report']
}));
app.use(bodyParser.urlencoded({extended: true}));
/** парсим печеньки в заголовках */
app.use(cookieParser(cookies.secret));
/** добавляем заголовок с временем ответа */
app.use(responseTime());

/**
 * Настройки безопасности.
 * Если снаружи стоит nginx для статики, то надо продублировать там все эти настройки заголовков
 */

/** Запрет на показ в айфрейме (sameorigin - можно только с того же домена) */
app.use(helmet.frameguard({action: 'sameorigin'})); // or { action: 'deny' }

/** пусть мамкины хакеры голову ломают */
app.use(helmet.hidePoweredBy({ setTo: 'PHP 4.2.0' }));

/** установим "X-DNS-Prefetch-Control: off", чтобы браузеры (которые это умеют) не префетчили ip нашего домена */
app.use(helmet.dnsPrefetchControl());

/** для старых ишаков ставим "X-Download-Options: noopen", чтобы контент, который надо скачать, они не открывали в контексте сайта */
app.use(helmet.ieNoOpen());

/** ставим "X-Content-Type-Options: nosniff", чтобы браузер доверял посланным сервером миме-типам, блочил не совпадающие и не пытался угадывать миме по содежимому загруженных файлов (а то ещё начнёт выполнять то, чего выполнять не должен) */
app.use(helmet.noSniff());

/** устанавливаем "Referrer-Policy". Честно говоря лень разбираться во всех значениях: https://www.w3.org/TR/referrer-policy/#referrer-policies */
// app.use(helmet.referrerPolicy({ policy: 'same-origin' }));

/** и поставим "X-XSS-Protection: 1; mode=block" */
app.use(helmet.xssFilter());

/** если юзается ssl, то надо послать браузеру открытые ключи, чтобы он их сохранил и при последующих запросах оберегал юзера от скомпрометированных центрах сертификации */
app.use(helmet.hpkp({
  setIf (req, res) {
    return !!req.secure;
  },
  maxAge: 9 * 24 * 60 * 60, // 9 дней в секундах
  sha256s: ['AbCdEf123=', 'ZyXwVu456='], // заменить на свои значения
  includeSubdomains: true,
  reportUri: 'https://example.com/hpkp-report',
  reportOnly: false
}));

/** опять же, если юзается ssl. говорит браузеру ходить только по https */
app.use(helmet.hsts({
  // or `force: true`
  setIf (req, res) {
    return !!req.secure;
  },
  maxAge: 5 * 24 * 60 * 60, // 6 дней в секундах
  includeSubDomains: true,
  preload: true
}));

/** todo: вынести настройки csp в конфиг */
/** https://content-security-policy.com/ */
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'", 'somecdn.com'],
    styleSrc: ["'self'", "'unsafe-inline'", 'maxcdn.bootstrapcdn.com'],
    imgSrc: ["'self'", 'data:'],
    // todo: печеньки не читаются. изучить про sandbox
    // sandbox: ['allow-forms', 'allow-scripts', 'allow-same-origin'],
    reportUri: '/report-csp-violation',
    objectSrc: ["'none'"], // An empty array allows nothing through
  },
  setAllHeaders: true,
  disableAndroid: true
}));
/** роут для приёма репортов о нарушении csp (нормальные браузеры будут слать сюда отчёты) */
/** csurf должен идти _после_ роута для приёма репортов */
app.post('/report-csp-violation', function (req, res) {
  if (!isProduction) {
    let body = req.body ? req.body : 'No data received!';
    console.error(`CSP Violation: ${body}`);
  } else {
    /** на продакшене логируем в файл, с суточной ротацией */
    let logDirectory = path.join(cwd, '/logs');
    !pathExists.sync(logDirectory) && fs.mkdirSync(logDirectory);

    /** todo: добавить генерацию логов */
    // app.use(logger('csp', {
    //   stream: fileStreamRotator.getStream({
    //     frequency:   'daily',
    //     date_format: 'YYYYMMDD',
    //     filename:    path.join(logDirectory, 'csp-%DATE%.log'),
    //     verbose:     false
    //   })
    // }));
  }

  res.status(204).end();
});

/**
 * Ну как бы можно включить парсинг sass'а на лету,
 * но как бы нехер говнокодить.
 */
// app.use(require('node-sass-middleware')({
//   src:            path.join(cwd, 'public'),
//   dest:           path.join(cwd, 'public'),
//   indentedSyntax: false,
//   sourceMap:      true
// }));

/**
 * Пошли маршруты
 */
app.use('/', routes);

/** Если дошли сюда, значит на запрос не нашлось нужного роута. Отправим 404. */
app.use(function (req, res, next) {
  return next(new httpError.NotFound());
});

/**
 * Если дошли сюда - значит пойманная/переданная ошибка.
 */
app.use(function (err, req, res, next) {
  // respect err.statusCode
  if (err.statusCode) {
    res.statusCode = err.statusCode
  }

  // respect err.status
  if (err.status) {
    res.statusCode = err.status
  }

  // default status code to 500
  if (res.statusCode < 400) {
    res.statusCode = 500
  }

  // cannot actually respond
  if (res._header) {
    return req.socket.destroy()
  }

  // todo логировать ошибки в файлы
  // console.error(err);
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error:   app.get('env') != 'production' ? err : {}
  });
});

// todo
// https://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception
// process.on('uncaughtException', (err) => {
//   fs.writeSync(1, `Caught exception: ${err}`);
// });
// process.on('unhandledRejection', (reason, p) => {
//   console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
//   // application specific logging, throwing an error, or other logic here
// });

export default app;
<|endoftext|>


<commit_before>'use strict'; // eslint-disable-line strict

const coworkers = require('coworkers');
const app = coworkers();
const logger = require('./services/LogService');
const Config = require('./services/ConfigurationService');
const uuid = require('node-uuid');

const queue = 'change-me-queue';

app.use(function * traceMessage(next) {
  this.id = uuid.v4();
  // save consumer start time
  const startTime = Date.now();
  // move on to the next middleware
  yield next;
  // all middlewares have finished
  const elapsed = Date.now() - startTime;
  logger.info(`message-trace:${this.id} | Message Transaction Time:${elapsed}`);
});

app.queue(queue, function * dequeueMessage() {
  this.ack = true;
});

app.on('error', function * errorReceived(err, channel, context) {
  logger.error(`${context.queueName} consumer error`, err);
  if (channel) {
    channel.nack(context.message).catch((nackErr) => {
      logger.error(nackErr);
    });
  }
});

const rabbitHost = Config.get('RABBITMQ_HOST') || 'localhost';
const rabbitPort = Config.get('RABBITMQ_PORT') || 12345;
const connectionString = `amqp://${rabbitHost}:${rabbitPort}`;
app.connect(connectionString);
<commit_msg>added worker stats for health check<commit_after>'use strict'; // eslint-disable-line strict

const coworkers = require('coworkers');
const app = coworkers();
const logger = require('./services/LogService');
const Config = require('./services/ConfigurationService');
const uuid = require('node-uuid');
const kardia = require('kardia');

const queue = 'change-me-queue';

app.use(function * traceMessage(next) {
  // Increment the request throughput, so we can
  // monitor it, and use it to dynamically scale
  // additional workers if needed.
  kardia.throughput('incoming-requests');
  // Increment total messages received, so we can
  // track of how much work this service has received
  // since it was started.
  kardia.increment('total-messages-received', 1);
  // generate a unique message id, so we can track
  // it throughout it's lifecycle.
  this.id = uuid.v4();
  // save consumer start time
  const startTime = Date.now();
  // move on to the next middleware
  yield next;
  // all middlewares have finished
  const elapsed = Date.now() - startTime;
  logger.info(`message-trace:${this.id} | Message Transaction Time:${elapsed}`);
  // Increment our request completed throughput, again so
  // we can utilize the overal health of the service.
  kardia.throughput('completed-requests');
});

app.queue(queue, function * dequeueMessage() {
  this.ack = true;
});

app.on('error', function * errorReceived(err, channel, context) {
  // Increment total messages failed, so we can keep
  // tabs on any potential outages.
  kardia.increment('total-messages-failed', 1);
  logger.error(`${context.queueName} consumer error`, err);
  if (channel) {
    channel.nack(context.message).catch((nackErr) => {
      logger.error(nackErr);
    });
  }
});

const rabbitHost = Config.get('RABBITMQ_HOST') || 'localhost';
const rabbitPort = Config.get('RABBITMQ_PORT') || 12345;
const connectionString = `amqp://${rabbitHost}:${rabbitPort}`;
app.connect(connectionString);
<|endoftext|>


<commit_before>(function () {
    'use strict';
    const userNameInput = document.getElementById('user-name');
    const assessmentButton = document.getElementById('assessment');
    const resultDivided = document.getElementById('result-area');
    const tweetDivided = document.getElementById('tweet-area');

    /**
    * 指定した要素の子どもを全て除去する
    * @param {HTMLElement} element HTMLの要素
    */
    function removeAllChildren(element) {
        while (element.firstChild) { // 子どもの要素があるかぎり削除
            element.removeChild(element.firstChild);
        }
    }

    assessmentButton.onclick = () => {
        const userName = userNameInput.value;
        if (userName.length === 0) { // 名前が空の時は処理を終了する
            return;
        }

        // 診断結果表示エリアの作成
        removeAllChildren(resultDivided);
        const header = document.createElement('h3');
        header.innerText = '診断結果';
        resultDivided.appendChild(header);

        const paragraph = document.createElement('p');
        const result = assessment(userName);
        paragraph.innerText = result;
        resultDivided.appendChild(paragraph);

        // ツイートエリアの作成
        removeAllChildren(tweetDivided);
        const anchor = document.createElement('a');
        const hrefValue = 'https://twitter.com/intent/tweet?button_hashtag=%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E3%81%84%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D&text='
        + encodeURIComponent(result);
        anchor.setAttribute('href', hrefValue);
        anchor.className = 'twitter-hashtag-button';
        anchor.innerText = 'Tweet #%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E3%81%84%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D';
        tweetDivided.appendChild(anchor);

        twttr.widgets.load();
    };

    userNameInput.onkeydown = (event) => {
        if (event.keyCode === 13) {
            assessmentButton.onclick();
        }
    };

    const answers = [
        '{userName}のいいところは声です。{userName}の特徴的な声はみなを惹きつけ、心に残ります。',
        '{userName}のいいところはまなざしです。{userName}に見つめられた人は、気になって仕方がないでしょう。',
        '{userName}のいいところは情熱です。{userName}の情熱に周りの人は感化されます。',
        '{userName}のいいところは厳しさです。{userName}の厳しさがものごとをいつも成功に導きます。',
        '{userName}のいいところは知識です。博識な{userName}を多くの人が頼りにしています。',
        '{userName}のいいところはユニークさです。{userName}だけのその特徴が皆を楽しくさせます。',
        '{userName}のいいところは用心深さです。{userName}の洞察に、多くの人が助けられます。',
        '{userName}のいいところは見た目です。内側から溢れ出る{userName}の良さに皆が気を惹かれます。',
        '{userName}のいいところは決断力です。{userName}がする決断にいつも助けられる人がいます。',
        '{userName}のいいところは思いやりです。{userName}に気をかけてもらった多くの人が感謝しています。',
        '{userName}のいいところは感受性です。{userName}が感じたことに皆が共感し、わかりあうことができます。',
        '{userName}のいいところは節度です。強引すぎない{userName}の考えに皆が感謝しています。',
        '{userName}のいいところは好奇心です。新しいことに向かっていく{userName}の心構えが多くの人に魅力的に映ります。',
        '{userName}のいいところは気配りです。{userName}の配慮が多くの人を救っています。',
        '{userName}のいいところはその全てです。ありのままの{userName}自身がいいところなのです。',
        '{userName}のいいところは自制心です。やばいと思ったときにしっかりと衝動を抑えられる{userName}が皆から評価されています。'
        '{userName}のいいところは優しさです。{userName}の優しい雰囲気や立ち振舞に多くの人が癒やされています。'
    ];

    /**
    * 名前の文字列を渡すと診断結果を返す関数
    * @param {string} userName ユーザーの名前
    * @return {string} 診断結果
    */
    function assessment(userName) {
        // 全文字のコード番号を取得してそれを足し合わせる
        let sumOfcharCode = 0;
        for (let i = 0; i < userName.length; i++) {
            sumOfcharCode = sumOfcharCode + userName.charCodeAt(i);
        }

        // 文字のコード番号の合計を回答の数で割って添字の数値を求める
        const index = sumOfcharCode % answers.length;
        let result = answers[index];

        result = result.replace(/{userName}/g, userName);
        return result;
    }

    // テストコード
    console.assert(
        assessment('太郎') === '太郎のいいところは決断力です。太郎がする決断にいつも助けられる人がいます。',
        '診断結果の文言の特定の部分を名前に置き換える処理が正しくありません。'
    );
    console.assert(
        assessment('太郎') === assessment('太郎'),
        '入力が同じ名前なら同じ診断結果を出力する処理が正しくありません。'
    );
})();
<commit_msg>#1 に対する対応を行いました<commit_after>(function () {
    'use strict';
    const userNameInput = document.getElementById('user-name');
    const assessmentButton = document.getElementById('assessment');
    const resultDivided = document.getElementById('result-area');
    const tweetDivided = document.getElementById('tweet-area');

    /**
    * 指定した要素の子どもを全て除去する
    * @param {HTMLElement} element HTMLの要素
    */
    function removeAllChildren(element) {
        while (element.firstChild) { // 子どもの要素があるかぎり削除
            element.removeChild(element.firstChild);
        }
    }

    assessmentButton.onclick = () => {
        const userName = userNameInput.value;
        if (userName.length === 0) { // 名前が空の時は処理を終了する
            return;
        }

        // 診断結果表示エリアの作成
        removeAllChildren(resultDivided);
        const header = document.createElement('h3');
        header.innerText = '診断結果';
        resultDivided.appendChild(header);

        const paragraph = document.createElement('p');
        const result = assessment(userName);
        paragraph.innerText = result;
        resultDivided.appendChild(paragraph);

        // ツイートエリアの作成
        removeAllChildren(tweetDivided);
        const anchor = document.createElement('a');
        const hrefValue = 'https://twitter.com/intent/tweet?button_hashtag=%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E3%81%84%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D&text='
        + encodeURIComponent(result);
        anchor.setAttribute('href', hrefValue);
        anchor.className = 'twitter-hashtag-button';
        anchor.innerText = 'Tweet #%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E3%81%84%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D';
        tweetDivided.appendChild(anchor);

        twttr.widgets.load();
    };

    userNameInput.onkeydown = (event) => {
        if (event.keyCode === 13) {
            assessmentButton.onclick();
        }
    };

    const answers = [
        '{userName}のいいところは声です。{userName}の特徴的な声はみなを惹きつけ、心に残ります。',
        '{userName}のいいところはまなざしです。{userName}に見つめられた人は、気になって仕方がないでしょう。',
        '{userName}のいいところは情熱です。{userName}の情熱に周りの人は感化されます。',
        '{userName}のいいところは厳しさです。{userName}の厳しさがものごとをいつも成功に導きます。',
        '{userName}のいいところは知識です。博識な{userName}を多くの人が頼りにしています。',
        '{userName}のいいところはユニークさです。{userName}だけのその特徴が皆を楽しくさせます。',
        '{userName}のいいところは用心深さです。{userName}の洞察に、多くの人が助けられます。',
        '{userName}のいいところは見た目です。内側から溢れ出る{userName}の良さに皆が気を惹かれます。',
        '{userName}のいいところは決断力です。{userName}がする決断にいつも助けられる人がいます。',
        '{userName}のいいところは思いやりです。{userName}に気をかけてもらった多くの人が感謝しています。',
        '{userName}のいいところは感受性です。{userName}が感じたことに皆が共感し、わかりあうことができます。',
        '{userName}のいいところは節度です。強引すぎない{userName}の考えに皆が感謝しています。',
        '{userName}のいいところは好奇心です。新しいことに向かっていく{userName}の心構えが多くの人に魅力的に映ります。',
        '{userName}のいいところは気配りです。{userName}の配慮が多くの人を救っています。',
        '{userName}のいいところはその全てです。ありのままの{userName}自身がいいところなのです。',
        '{userName}のいいところは自制心です。やばいと思ったときにしっかりと衝動を抑えられる{userName}が皆から評価されています。'
        '{userName}のいいところは優しさです。{userName}の優しい雰囲気や立ち振舞に多くの人が癒やされています。'
    ];

    /**
    * 名前の文字列を渡すと診断結果を返す関数
    * @param {string} userName ユーザーの名前
    * @return {string} 診断結果
    */
    function assessment(userName) {
        // 全文字のコード番号を取得してそれを足し合わせる
        let sumOfcharCode = 0;
        for (let i = 0; i < userName.length; i++) {
            sumOfcharCode = sumOfcharCode + userName.charCodeAt(i);
        }

        // 文字のコード番号の合計を回答の数で割って添字の数値を求める
        const index = sumOfcharCode % answers.length;
        let result = answers[index];

        result = result.replace(/{userName}/g, userName);
        return result;
    }

    // テストコード
    console.assert(
        assessment('太郎') === '太郎のいいところは決断力です。太郎がする決断にいつも助けられる人がいます。',
        '診断結果の文言の特定の部分を名前に置き換える処理が正しくありません。'
    );
    console.assert(
        assessment('太郎') === assessment('太郎'),
        '入力が同じ名前なら同じ診断結果を出力する処理が正しくありません。'
    );
})();

<|endoftext|>


<commit_before>var express = require( 'express' );
var r = require( 'rethinkdb' );
var cors = require( './cors' );
var _ = require( 'underscore' );
// Create app and use cors
var app = express();
app.use(cors);

// Connect to DB
var conn;
r.connect(
  { host:'localhost', port:28015 },
  function( connection ) {
    conn = connection;
    // Select the correct DB
    conn.use('pdb_compounds');
  },
  function( err ) {
    throw "Connection Failed";
  }
);

app.get('/pdb_compounds/:cifIDs', function( req, res ){
  var queries = req.params.cifIDs.split('&');
  // Uppercase queries before querying the database
  var upperQueries = _.map( queries, function( qry ){
    return qry.toUpperCase();
  });
  // Query the DB
  r.expr( upperQueries ).map(function( query ){
    return r.table( 'compounds' ).get( query, '_chem_comp.id' );
  }).run().collect(function( results ){
    var data = _.object( queries, results );
    res.send( data );
  });
});

app.listen(80);
console.log('express listeing at: %d', 80);<commit_msg>Updated aws server to use ap url.<commit_after>var express = require( 'express' );
var r = require( 'rethinkdb' );
var cors = require( './cors' );
var _ = require( 'underscore' );
// Create app and use cors
var app = express();
app.use(cors);

// Connect to DB
var conn;
r.connect(
  { host:'localhost', port:28015 },
  function( connection ) {
    conn = connection;
    // Select the correct DB
    conn.use('pdb_compounds');
  },
  function( err ) {
    throw "Connection Failed";
  }
);

app.get('/api/pdb_compounds/:cifIDs', function( req, res ){
  var queries = req.params.cifIDs.split('&');
  // Uppercase queries before querying the database
  var upperQueries = _.map( queries, function( qry ){
    return qry.toUpperCase();
  });
  // Query the DB
  r.expr( upperQueries ).map(function( query ){
    return r.table( 'compounds' ).get( query, '_chem_comp.id' );
  }).run().collect(function( results ){
    var data = _.object( queries, results );
    res.send( data );
  });
});

app.listen(80);
console.log('express listeing at: %d', 80);<|endoftext|>


<commit_before>/**
 * @fileOverview Parser for linear problems
 */

var parse = module.exports = {};

/**
 * Throws syntax error
 * @param  {String} msg The syntax error message
 */
parse.error = function(msg) {
  throw {
    name: 'SyntaxError',
    message: msg,
    at: at,
    text: text
  };
}

/**
 * Parse the 'min' or 'max' string
 * @param  {String} minMaxString The string which will contain either 'min' or 'max'
 */
parse.parseMinMax = function(minMaxString) {

};

/**
 * Parse coefficients
 * @param  {Array} coeffList An array for storing coeeficients
 * @param  {String} monomial  The monomial which will be destructured into its coeffs
 */
parse.parseCoeffs = function(coeffList, monomial) {

  // Check which pattern matches. Valid are: (s)(n)lv
  // parenthesis indicate optional existence
  // s is + or - (absence means +)
  // n is a number (coefficient, absence means 1)
  // l is a lowercase latin letter (variable letter)
  // v is a number, probably incremental (variable number)

};

/**
 * Parse 'min' or 'max' keyword
 * @param  {Array} numArray  The array in which the number results will be added
 * @param  {Array} signArray The array in which the sign results will be added
 * @param  {String} string    The input string
 */
parse.parseConstants = function(numArray, signArray, string) {

};

/**
 * Main parse function. Parses linear problems of lp format
 * @param  {String} dataString A string which includes the input lp format
 * @return {Object} Returns an object with the parsed values
 */
parse.lpParser = function(dataString) {

  var at; // current index
  var ch; // current character

};
<commit_msg>add parse.next function<commit_after>/**
 * @fileOverview Parser for linear problems
 */

var parse = module.exports = {};

/**
 * Throws syntax error
 * @param  {String} msg The syntax error message
 */
parse.error = function(msg) {
  throw {
    name: 'SyntaxError',
    message: msg,
    at: at,
    text: text
  };
}

/**
 * Returns next character to be parsed
 * @param  {String}   character Character expected to be parsed
 */
parse.next = function(character) {

  // If a c parameter is provided, verify that it matches the current character.
  if (character && character !== parse.ch) {
    error('Expected \'' + character + '\' instead of \'' + parse.ch + '\'');
  }

  // Get the next character. When there are no more characters,
  // return the empty string.
  ch = parse.dataString.charAt(parse.at);
  at += 1;
  return parse.ch;
}

/**
 * Parse the 'min' or 'max' string
 * @param  {String} minMaxString The string which will contain either 'min' or 'max'
 */
parse.parseMinMax = function(minMaxString) {

};

/**
 * Parse coefficients
 * @param  {Array} coeffList An array for storing coeeficients
 * @param  {String} monomial  The monomial which will be destructured into its coeffs
 */
parse.parseCoeffs = function(coeffList, monomial) {

  // Check which pattern matches. Valid are: (s)(n)lv
  // parenthesis indicate optional existence
  // s is + or - (absence means +)
  // n is a number (coefficient, absence means 1)
  // l is a lowercase latin letter (variable letter)
  // v is a number, probably incremental (variable number)

};

/**
 * Parse 'min' or 'max' keyword
 * @param  {Array} numArray  The array in which the number results will be added
 * @param  {Array} signArray The array in which the sign results will be added
 * @param  {String} string    The input string
 */
parse.parseConstants = function(numArray, signArray, string) {

};

/**
 * Main parse function. Parses linear problems of lp format
 * @param  {String} dataString A string which includes the input lp format
 * @return {Object} Returns an object with the parsed values
 */
parse.lpParser = function(dataString) {

  var at; // current index
  var ch; // current character

};
<|endoftext|>


<commit_before>browser.runtime.onMessage.addListener(
  function(message, sender, response) {
    if (message.action == "getNetflixCountries") {
      return getNetflixCountries(message, sender, response);
    }
  }
);

browser.webRequest.onBeforeSendHeaders.addListener(
  addUnogsRefererHeader,
  {urls: ["https://unogs.com/api/search*"]},
  ["blocking", "requestHeaders", "extraHeaders"]
);

function getNetflixCountries(message, sender, response) {
  var token = null;

  var promise = getUnogsToken()
  .then(function(unogsToken) {
    token = unogsToken;
    return getNetflixId(message.title, message.imdbId, token);
  })
  .then(function(response) {
    return processSearchResponse(response, message.imdbId);
  })
  .then(function(netflixId) {
    return getNetflixCountriesFromUnogs(netflixId, token)
  })
  .then(function(response) {
    return processNetflixCountries(response);
  })
  .catch(function(err) {
    console.log('getNetflixCountries error');
    console.error(err);
  });

  // getNetflixId(message.title, message.imdbId, getNetflixCountries)

  return promise;
}

/*
 * Get a valid uNoGS token:
 *   - first try to get a token from Storage.
 *   - otherwise fetch a new token from uNoGS
 */
function getUnogsToken() {
  promise = browser.storage.local.get(['unogsCredentials'])
  .then(function(credentials) {
    return processUnogsCredentials(credentials);
  })
  .catch((err) => {
    console.log('refreshUnogsToken error');
    console.error(err)
  });

  return promise;
}

/*
 * Return token from Storage if it's valid. Otherwise request a new token.
 */
function processUnogsCredentials(object) {
  credentials = object.unogsCredentials;

  if (isValidCredentials(credentials)) {
    return credentials.token;
  }

  var promise = requestUnogsToken()
  .then(function(response) {
    return processUnogsResponse(response);
  })
  .catch((err) => {
    console.log("processUnogsCredentials error");
    console.error(err);
  });

  return promise;
}

/*
 * Make a request to get token from uNoGS authentication endpoint.
 */
function requestUnogsToken() {
  currDate = new Date();
  url = 'http://unogs.com/api/user?user_name=' + currDate / 10

  var promise = fetch(url, {method: 'POST'})
  .then(function(response) {
    return response.json();
  })
  .catch((err) => {
    console.log('requestUnogsToken error');
    console.error(err);
  });

  return promise;
}

function processUnogsResponse(data) {
  token = data["token"]["access_token"];

  if (!token) {
    throw new Error('Invalid token returned from uNoGS');
  }

  currDate = new Date();
  expirationDate = new Date(currDate.getTime() + 1000 * 60 * 60 * 24 - 1000 * 15);

  unogsCredentials = {
    token: token,
    expirationTime: expirationDate.getTime()
  }

  var promise = browser.storage.local.set({unogsCredentials: unogsCredentials})
  .then(function() {
    return token;
  })
  .catch((err) => {
    console.log("processUnogsResponse error");
    console.error(err);
  });

  return promise;
}

function getNetflixId(title, imdbId, unogsToken) {
  var baseUrl = "https://unogs.com/api/search";
  var limit = 5;
  var offset = 0;
  var query = encodeURI(title);
  var url = baseUrl + '?limit=' + limit + '&offset=' + offset + '&query=' + query;

  var promise = fetch(url, {
    method: 'GET',
    headers: {
      'authorization': 'Bearer ' + unogsToken,
      'referrer': 'http://unogs.com',
    }
  })
  .then(function(response) {
    return response.json();
  })
  .catch((err) => {
    console.log('requestUnogsToken error');
    console.error(err);
  });

  return promise;
}

function addUnogsRefererHeader(e) {
  foundReferer = false;
  refererValue = 'https://unogs.com/';

  for (var header of e.requestHeaders) {
    if (header.name.toLowerCase() === "referer") {
      header.value = refererValue;
      foundReferer = true;
      break;
    }
  }

  if (!foundReferer) {
    e.requestHeaders.push({name:"Referer", value:refererValue});
  }

  return {requestHeaders: e.requestHeaders};
}

function processSearchResponse(data, imdbId) {
for (const searchResult of data["results"]) {
    if (searchResult.imdbid == imdbId) {
      return searchResult.nfid;
    }
  }

  return undefined;
  //throw new Error('IMDb entry not found in uNoGS search results');
}

function getNetflixCountriesFromUnogs(netflixId, unogsToken) {
  var baseUrl = "https://unogs.com/api/title/countries";
  var url = baseUrl + '?netflixid=' + netflixId;

  var promise = fetch(url, {
    method: 'GET',
    headers: {
      'authorization': 'Bearer ' + unogsToken,
    }
  })
  .then(function(response) {
    return response.json();
  })
  .catch((err) => {
    console.log('requestUnogsToken error');
    console.error(err);
  });

  return promise;
}

function processNetflixCountries(data) {
  return data.map(x => x.cc);

}

function isValidCredentials(credentials) {
  if (isEmptyObject(credentials)) {
    return false;
  }

  if (credentials.token == null || credentials.token === '') {
    return false;
  }

  if (credentials.expirationTime <= new Date().getTime()) {
    return false;
  }

  return true;
}

function isEmptyObject(obj) {
  return Object.keys(obj).length === 0 && obj.constructor === Object
}
<commit_msg>Add documentation for each method<commit_after>browser.runtime.onMessage.addListener(
  function(message, sender, response) {
    if (message.action == "getNetflixCountries") {
      return getNetflixCountries(message, sender, response);
    }
  }
);

browser.webRequest.onBeforeSendHeaders.addListener(
  addUnogsRefererHeader,
  {urls: ["https://unogs.com/api/search*"]},
  ["blocking", "requestHeaders", "extraHeaders"]
);

/*
 * Retrieve the list of countries in which the film appears in the the Netflix catalogue.
 */
function getNetflixCountries(message, sender, response) {
  var token = null;

  var promise = getUnogsToken()
  .then(function(unogsToken) {
    token = unogsToken;
    return getNetflixId(message.title, message.imdbId, token);
  })
  .then(function(response) {
    return processSearchResponse(response, message.imdbId);
  })
  .then(function(netflixId) {
    return getNetflixCountriesFromUnogs(netflixId, token)
  })
  .then(function(response) {
    return processNetflixCountries(response);
  })
  .catch(function(err) {
    console.log('getNetflixCountries error');
    console.error(err);
  });

  return promise;
}

/*
 * Get a valid uNoGS token:
 *   - first try to get a token from Storage
 *   - otherwise fetch a new token from uNoGS
 */
function getUnogsToken() {
  promise = browser.storage.local.get(['unogsCredentials'])
  .then(function(credentials) {
    return processUnogsCredentials(credentials);
  })
  .catch((err) => {
    console.log('refreshUnogsToken error');
    console.error(err)
  });

  return promise;
}

/*
 * Return token from Storage if it's valid. Otherwise request a new token.
 */
function processUnogsCredentials(object) {
  credentials = object.unogsCredentials;

  if (isValidCredentials(credentials)) {
    return credentials.token;
  }

  var promise = requestUnogsToken()
  .then(function(response) {
    return processUnogsResponse(response);
  })
  .catch((err) => {
    console.log("processUnogsCredentials error");
    console.error(err);
  });

  return promise;
}

/*
 * Make a request to get token from uNoGS authentication endpoint.
 */
function requestUnogsToken() {
  currDate = new Date();
  url = 'http://unogs.com/api/user?user_name=' + currDate / 10

  var promise = fetch(url, {method: 'POST'})
  .then(function(response) {
    return response.json();
  })
  .catch((err) => {
    console.log('requestUnogsToken error');
    console.error(err);
  });

  return promise;
}

/*
 * Save the new token and it's expiration timestamp using the Storage API.
 */
function processUnogsResponse(data) {
  token = data["token"]["access_token"];

  if (!token) {
    throw new Error('Invalid token returned from uNoGS');
  }

  currDate = new Date();
  expirationDate = new Date(currDate.getTime() + 1000 * 60 * 60 * 24 - 1000 * 15);

  unogsCredentials = {
    token: token,
    expirationTime: expirationDate.getTime()
  }

  var promise = browser.storage.local.set({unogsCredentials: unogsCredentials})
  .then(function() {
    return token;
  })
  .catch((err) => {
    console.log("processUnogsResponse error");
    console.error(err);
  });

  return promise;
}

/*
 * Search the uNoGS catalogue to find the Netflix ID that corresponds to the IMDb ID.
 */
function getNetflixId(title, imdbId, unogsToken) {
  var baseUrl = "https://unogs.com/api/search";
  var limit = 5;
  var offset = 0;
  var query = encodeURI(title);
  var url = baseUrl + '?limit=' + limit + '&offset=' + offset + '&query=' + query;

  var promise = fetch(url, {
    method: 'GET',
    headers: {
      'authorization': 'Bearer ' + unogsToken,
      'referrer': 'http://unogs.com',
    }
  })
  .then(function(response) {
    return response.json();
  })
  .catch((err) => {
    console.log('requestUnogsToken error');
    console.error(err);
  });

  return promise;
}

/*
 * Add uNoGS referer header to search requests to make the request valid.
 */
function addUnogsRefererHeader(e) {
  foundReferer = false;
  refererValue = 'https://unogs.com/';

  for (var header of e.requestHeaders) {
    if (header.name.toLowerCase() === "referer") {
      header.value = refererValue;
      foundReferer = true;
      break;
    }
  }

  if (!foundReferer) {
    e.requestHeaders.push({name:"Referer", value:refererValue});
  }

  return {requestHeaders: e.requestHeaders};
}

/*
 * Check whether any of the search results correspond to the IMDb entry.
 */
function processSearchResponse(data, imdbId) {
for (const searchResult of data["results"]) {
    if (searchResult.imdbid == imdbId) {
      return searchResult.nfid;
    }
  }

  return undefined;
  //throw new Error('IMDb entry not found in uNoGS search results');
}

/*
 * Send a request to uNoGS to get the list of countries in which the film appears in the the Netflix catalogue
 */
function getNetflixCountriesFromUnogs(netflixId, unogsToken) {
  var baseUrl = "https://unogs.com/api/title/countries";
  var url = baseUrl + '?netflixid=' + netflixId;

  var promise = fetch(url, {
    method: 'GET',
    headers: {
      'authorization': 'Bearer ' + unogsToken,
    }
  })
  .then(function(response) {
    return response.json();
  })
  .catch((err) => {
    console.log('requestUnogsToken error');
    console.error(err);
  });

  return promise;
}

function processNetflixCountries(data) {
  return data.map(x => x.cc);

}

function isValidCredentials(credentials) {
  if (isEmptyObject(credentials)) {
    return false;
  }

  if (credentials.token == null || credentials.token === '') {
    return false;
  }

  if (credentials.expirationTime <= new Date().getTime()) {
    return false;
  }

  return true;
}

function isEmptyObject(obj) {
  return Object.keys(obj).length === 0 && obj.constructor === Object
}
<|endoftext|>


<commit_before>"use strict";
/**
* Background JS
*/

var optionTitleSearch = false;

// escape string for omnibox use
var escapeUrl = function(url){
    return url.replace(/\&/g, "&").replace(/\"/g, """).replace(/\'/g, "'").replace(/\</g, "<").replace(/\>/g, ">")
};

// unescape string for omnibox use
var unescapeUrl = function(url){
    return url.replace(/\&quot\;/g, '"').replace(/\&apos\;/g, "'").replace(/\&lt\;/g, "<").replace(/\&gt\;/g, ">").replace(/\&amp\;/g, "&");
};

// on do search - when user typed in the omnibox
var onSearch = function(text, suggest){
    var found = [];
    var s = text.trim().split(" ");
    var sRegex = s;
    for(var i in sRegex) {
        sRegex[i] = {"regex" : new RegExp(sRegex[i].replace(/[^0-9a-z]/ig, "\\$&"), "ig"), "val" : s[i]};
    }

    // go through each item and do the search thingy
    itemsCache.forEach(function(item){
        // not search in chrome url
        if(item.url.match(/^chrome/)) return true;
        var ok = true;
        sRegex.forEach(function(val){
            if(optionTitleSearch && !(item.title.match(val.regex) || item.url.match(val.regex))) ok = false;
            else if(!optionTitleSearch && !item.url.match(val.regex)) ok = false;
            if(!ok) return false;
        });
        if(ok) found.push(item);
    });

    // resort by visit count
    found.sort(function(a, b){
        if(a.visitCount > b.visitCount) return -1;
        if(a.visitCount < b.visitCount) return 1;
        return 0;
    });

    // just slice the best 50 entries
    found = found.slice(0, 50);

    // generate suggestions array
    var suggestions = [];
    found.forEach(function(item){
        var uDesc = item.url;
        var highlightedTitle = item.title;
        sRegex.forEach(function(val){
            uDesc = uDesc.replace(val.regex, '{match}'+val.val+'{/match}');
            if(optionTitleSearch) highlightedTitle = highlightedTitle.replace(val.regex, '{match}'+val.val+'{/match}');
        });
        uDesc = escapeUrl(uDesc).replace(/{match}/ig, "<match>").replace(/{\/match}/ig, "</match>");
        if(optionTitleSearch) highlightedTitle = escapeUrl(highlightedTitle).replace(/{match}/ig, "<match>").replace(/{\/match}/ig, "</match>");

        suggestions.push({
            "content" : escapeUrl(item.url),
            "description" : '<url>'+uDesc+'</url> :: <dim>'+item.visitCount+' '+chrome.i18n.getMessage("visits")+'</dim> '+highlightedTitle
        });
    });

    // omnibox suggest
    if(suggest) suggest(suggestions);
    return suggestions;
};

// cache history entries
var itemsCache = [];
var updateCache = function(){
    chrome.history.search({"text" : "", "maxResults" : 2147483647, "startTime" : 0}, function(items){
        itemsCache = items;
    });
};

// refresh items cache every 5 minutes
setInterval(updateCache, 5 * 60 * 1000);

// on init create the cache
updateCache();

// default suggestion text
chrome.omnibox.setDefaultSuggestion({"description" : chrome.i18n.getMessage("omniboxDefault")});

// when user typed in the omnibox
chrome.omnibox.onInputChanged.addListener(onSearch);

// on enter or select the current entry
chrome.omnibox.onInputEntered.addListener(function(text, type){
    if(type == "newForegroundTab"){
        chrome.tabs.create({url : text, active : type == "newForegroundTab"});
    }else{
        chrome.tabs.query({lastFocusedWindow : true, windowType : "normal"}, function(tab){
            chrome.tabs.update(tab.id, {url : text}, function(){});
        });
    }
});

// key shortcuts
chrome.commands.onCommand.addListener(function(command) {
    if(command == "open"){
        var w = 600;
        var h = 400;
        var l = screen.width / 2 - w / 2;
        var t = screen.height / 2 - h / 2;
        chrome.windows.create({"url" : chrome.extension.getURL("options.html"), "type" : "popup", "width" : w, "height" : h, "left" : l, "top" : t}, function(){

        });
    }
});

// on connect from options page
chrome.extension.onConnect.addListener(function(port) {
    if(port.name == "bomnibox"){
        port.onMessage.addListener(function(data) {
            if(data.action == "search"){
                if(port) {
                    port.postMessage({"action" : "search-callback", "suggestions" : onSearch(data.text, null)});
                }
            }
            if(data.action == "delete"){
                if(port) {
                    chrome.history.deleteUrl({"url" : unescapeUrl(data.url)}, updateCache);
                }
            }
        });
    }
    port.onDisconnect.addListener(function(){
        port = null;
    });
});

// interval for get options if they have changed
setInterval(function(){
    // get options
    chrome.storage.sync.get(["optionTitleSearch"], function(data){
        optionTitleSearch = false;
        if(data && data.optionTitleSearch) optionTitleSearch = true;
    });
}, 1000);<commit_msg>* try fix for currentTab onEnter<commit_after>"use strict";
/**
* Background JS
*/

var optionTitleSearch = false;

// escape string for omnibox use
var escapeUrl = function(url){
    return url.replace(/\&/g, "&").replace(/\"/g, """).replace(/\'/g, "'").replace(/\</g, "<").replace(/\>/g, ">")
};

// unescape string for omnibox use
var unescapeUrl = function(url){
    return url.replace(/\&quot\;/g, '"').replace(/\&apos\;/g, "'").replace(/\&lt\;/g, "<").replace(/\&gt\;/g, ">").replace(/\&amp\;/g, "&");
};

// on do search - when user typed in the omnibox
var onSearch = function(text, suggest){
    var found = [];
    var s = text.trim().split(" ");
    var sRegex = s;
    for(var i in sRegex) {
        sRegex[i] = {"regex" : new RegExp(sRegex[i].replace(/[^0-9a-z]/ig, "\\$&"), "ig"), "val" : s[i]};
    }

    // go through each item and do the search thingy
    itemsCache.forEach(function(item){
        // not search in chrome url
        if(item.url.match(/^chrome/)) return true;
        var ok = true;
        sRegex.forEach(function(val){
            if(optionTitleSearch && !(item.title.match(val.regex) || item.url.match(val.regex))) ok = false;
            else if(!optionTitleSearch && !item.url.match(val.regex)) ok = false;
            if(!ok) return false;
        });
        if(ok) found.push(item);
    });

    // resort by visit count
    found.sort(function(a, b){
        if(a.visitCount > b.visitCount) return -1;
        if(a.visitCount < b.visitCount) return 1;
        return 0;
    });

    // just slice the best 50 entries
    found = found.slice(0, 50);

    // generate suggestions array
    var suggestions = [];
    found.forEach(function(item){
        var uDesc = item.url;
        var highlightedTitle = item.title;
        sRegex.forEach(function(val){
            uDesc = uDesc.replace(val.regex, '{match}'+val.val+'{/match}');
            if(optionTitleSearch) highlightedTitle = highlightedTitle.replace(val.regex, '{match}'+val.val+'{/match}');
        });
        uDesc = escapeUrl(uDesc).replace(/{match}/ig, "<match>").replace(/{\/match}/ig, "</match>");
        if(optionTitleSearch) highlightedTitle = escapeUrl(highlightedTitle).replace(/{match}/ig, "<match>").replace(/{\/match}/ig, "</match>");

        suggestions.push({
            "content" : escapeUrl(item.url),
            "description" : '<url>'+uDesc+'</url> :: <dim>'+item.visitCount+' '+chrome.i18n.getMessage("visits")+'</dim> '+highlightedTitle
        });
    });

    // omnibox suggest
    if(suggest) suggest(suggestions);
    return suggestions;
};

// cache history entries
var itemsCache = [];
var updateCache = function(){
    chrome.history.search({"text" : "", "maxResults" : 2147483647, "startTime" : 0}, function(items){
        itemsCache = items;
    });
};

// refresh items cache every 5 minutes
setInterval(updateCache, 5 * 60 * 1000);

// on init create the cache
updateCache();

// default suggestion text
chrome.omnibox.setDefaultSuggestion({"description" : chrome.i18n.getMessage("omniboxDefault")});

// when user typed in the omnibox
chrome.omnibox.onInputChanged.addListener(onSearch);

// on enter or select the current entry
chrome.omnibox.onInputEntered.addListener(function(text, type){
    if(type != "currentTab"){
        chrome.tabs.create({url : text, active : type == "newForegroundTab"});
    }else{
        chrome.tabs.query({lastFocusedWindow : true, windowType : "normal"}, function(tab){
            chrome.tabs.update(tab.id, {url : text}, function(){});
        });
    }
});

// key shortcuts
chrome.commands.onCommand.addListener(function(command) {
    if(command == "open"){
        var w = 600;
        var h = 400;
        var l = screen.width / 2 - w / 2;
        var t = screen.height / 2 - h / 2;
        chrome.windows.create({"url" : chrome.extension.getURL("options.html"), "type" : "popup", "width" : w, "height" : h, "left" : l, "top" : t}, function(){

        });
    }
});

// on connect from options page
chrome.extension.onConnect.addListener(function(port) {
    if(port.name == "bomnibox"){
        port.onMessage.addListener(function(data) {
            if(data.action == "search"){
                if(port) {
                    port.postMessage({"action" : "search-callback", "suggestions" : onSearch(data.text, null)});
                }
            }
            if(data.action == "delete"){
                if(port) {
                    chrome.history.deleteUrl({"url" : unescapeUrl(data.url)}, updateCache);
                }
            }
        });
    }
    port.onDisconnect.addListener(function(){
        port = null;
    });
});

// interval for get options if they have changed
setInterval(function(){
    // get options
    chrome.storage.sync.get(["optionTitleSearch"], function(data){
        optionTitleSearch = false;
        if(data && data.optionTitleSearch) optionTitleSearch = true;
    });
}, 1000);<|endoftext|>


<commit_before>// Copyright (c) 2016 H@mdi.

if( storage == null){
var storage = chrome.storage.local;

var state = 'state';

var obj= {};

obj[state] = true;

storage.set(obj);

storage.get(state,function(result){
  console.log('hamdi');
  //console output = myVariableKeyName {myTestVar:'my test var'}
});}

function Storage(p1, p2) {
    return p1 * p2;              // The function returns the product of p1 and p2
}

storage.get(state,function(result){
  if(result.state == true){
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {

  console.log('bareUrl' + tab.url);
  origin_url = tab.url;
  var arr = origin_url.split('/');
    if((arr[2].indexOf('ieeexplore.ieee') >= 0
      || arr[2].indexOf('link.springer')>=0
      || arr[2].indexOf('sciencedirect')>=0
      || arr[2].indexOf('dl.acm')>=0
 )
     && arr[2].indexOf('sci-hub') == -1 && changeInfo.status == "loading") {
       arr[2] = arr[2] + ".sci-hub.io";
       var new_url = arr.join('/');

      console.log('Redirecting ' + tab.url + ' to ' + new_url);

      chrome.tabs.update(tab.id, {url: new_url});

    }
});}
});

chrome.browserAction.onClicked.addListener(function(tab) {

storage.get(state,function(result){
  if(result.state == true){

chrome.browserAction.setIcon({path:"icon/disabled.png"});
obj[state] = false;
storage.set(obj);
}else{
chrome.browserAction.setIcon({path:"icon/enabled.png"});
obj[state] = true;
storage.set(obj);}

});

});
<commit_msg>Update<commit_after>// Copyright (c) 2016 H@mdi.

if( storage == null){
var storage = chrome.storage.local;

var state = 'state';

var obj= {};

obj[state] = true;

storage.set(obj);

storage.get(state,function(result){
  console.log('hamdi');
  //console output = myVariableKeyName {myTestVar:'my test var'}
});}

storage.get(state,function(result){
  if(result.state == true){
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {

  console.log('bareUrl' + tab.url);
  origin_url = tab.url;
  var arr = origin_url.split('/');
    if((arr[2].indexOf('ieeexplore.ieee') >= 0
      || arr[2].indexOf('link.springer')>=0
      || arr[2].indexOf('sciencedirect')>=0
      || arr[2].indexOf('dl.acm')>=0
 )
     && arr[2].indexOf('sci-hub') == -1 && changeInfo.status == "loading") {
       arr[2] = arr[2] + ".sci-hub.io";
       var new_url = arr.join('/');

      console.log('Redirecting ' + tab.url + ' to ' + new_url);

      chrome.tabs.update(tab.id, {url: new_url});

    }
});}
});

chrome.browserAction.onClicked.addListener(function(tab) {

storage.get(state,function(result){
  if(result.state == true){

chrome.browserAction.setIcon({path:"icon/disabled.png"});
obj[state] = false;
storage.set(obj);
}else{

chrome.browserAction.setIcon({path:"icon/enabled.png"});
obj[state] = true;
storage.set(obj);}

});

});
<|endoftext|>


<commit_before>const openInTab = {};

function toggleState(tab, open) {
    openInTab[tab.id] = open;
    browser.browserAction.setIcon({
        tabId: tab.id,
        path: `icons/64-${open ? 'on' : 'off'}.png`
    });
}

browser.browserAction.onClicked.addListener((tab) => {

    // Toggle carousel.
    browser.tabs.executeScript(
        openInTab[tab.id] ?
            {code: 'window.postMessage("close-media-carousel", "*")'} :
            {file: 'inject-overlay.js'}
    );

    // Handle carousel reporting open/closed.
    chrome.runtime.onMessage.addListener((message, sender) => {
        if (sender.tab.id === tab.id) {
            if (message.action === 'open') {
                toggleState(tab, true);
            } else if (message.action === 'close') {
                toggleState(tab, false);
            }
        }
    });

});
<commit_msg>Toggle state when navigating to another page<commit_after>const tabsWithCarousel = {};

// Toggle icon for tab.
function toggleState(tabId, open) {
    tabsWithCarousel[tabId] = open;
    browser.browserAction.setIcon({
        tabId: tabId,
        path: `icons/64-${open ? 'on' : 'off'}.png`
    });
}

// Handle toolbar button click.
browser.browserAction.onClicked.addListener((tab) => {

    // Toggle carousel.
    browser.tabs.executeScript(
        tabsWithCarousel[tab.id] ?
            {code: 'window.postMessage("close-media-carousel", "*")'} :
            {file: 'inject-overlay.js'}
    );

    // Handle carousel reporting open/closed.
    chrome.runtime.onMessage.addListener((message, sender) => {
        if (sender.tab.id === tab.id) {
            if (message.action === 'open') {
                toggleState(tab.id, true);
            } else if (message.action === 'close') {
                toggleState(tab.id, false);
            }
        }
    });

});

// Toggle state when navigating to another page.
browser.tabs.onUpdated.addListener((tabId) => {
    if (tabsWithCarousel[tabId]) {
        toggleState(tabId, false);
    }
});
<|endoftext|>


<commit_before>/*
Eventually this should become an event driven page instead of a pure background
page. However, only webRequest is currently not availble on event driven pages
for builds outside of the dev channel.
*/

//Used for logging to the background page (bkg.Console.log('foo'))
var bkg = chrome.extension.getBackgroundPage();

/*
Listener for requests coming from Google
*/
chrome.webRequest.onBeforeRequest.addListener(
    function(details){
    var subs;
        var positive = false;
        var index = details.url.search(/q=/);
        if(index != -1){
            subs = details.url.substring(index);
            subs = subs.substring(2, subs.indexOf('&'));
            positive = checkForBitcoin(subs);
        }
        if(positive){
            //Positive bitcoin match
            updateData();
            bkg.console.log("Bazinga: " + subs);
        }
        return;
    },
    {urls: ["https://www.google.com/*"]} //Do this for all google urls
);

//Core data
var data = {
    lastUpdated: {},
    baseURL: "http://bitcoincharts.com/charts/chart.png?",
    options: {
        width: "660",
        height: "192",
        m: "bitfinexUSD",
        SubmitButton: "Draw",
        c: "",
        s: "",
        e: "",
        Prev: "",
        Next: "",
        t: "M",
        b: "",
        a1: "",
        m1: "10",
        a2: "",
        m2: "25",
        x: "0",
        i1: "",
        i2: "",
        i3: "",
        i4: "",
        v: "1",
        cv: "0",
        ps: "0",
        l: "0",
        p: "0",
        ranges: {
            d1: {
                i: "",
                r: ""
            },
            d5: {
                i: "",
                r: ""
            },
            m1: {
                i: "",
                r: ""
            },
            m6: {
                i: "",
                r: ""
            },
            y1: {
                i: "",
                r: ""
            },
            y5: {
                i: "",
                r: ""
            },
            max: {
                i: "",
                r: ""
            }
        }
    },
    result: {}
};

$(document).bind("ajaxStop", function(){
    buildContainer();
});

function updateData() {
    getHashRate();
    getDifficulity();
    getCardData();
    getYesterdayAvg();
}

/*
*/
function buildURL(range) {
    var url = data.baseURl;

    var first = true; //Control the placement of '&'
    for(var key in data.options) {
        if(data.options.hasOwnProperty(key) && key) {
            if(key == "ranges") {
                if(first) {
                    url += "i";
                    first = false;
                } else {
                    url += "&i";
                }

                url += "=" + data.options.ranges[range].i;
                url += "&r" + "=" + data.options.ranges[range].r;
            }

            if(!first) {
                url += "&" + key + "=" + data.options.key;
            } else {
                url += key + "=" + data.options.key;
                first = false;
            }
        }
    }
}

/*
Function to be called when the user selects a range button. Causes the image to
be updated by replacing the image src URL with a new one
*/
function updateRange(range) {
    $('#fmob_chart').attr('src', buildURL(range));
}

/*
Checks strings for matches to bitcoin
*/
function checkForBitcoin(subs){
    subs = subs.toLowerCase();
    if( (subs == 'bit%20coin') ||
        (subs == 'bit+coin')   ||
        (subs == 'bitcoin')    ||
        (subs == 'btc')){
        return true;
    }
    return false;
}

/**
 * Fetches the data for the card population
 * returns an array with values
 * avg, cvolume (currency volume), difficulty, ghashrate, high, low, and btc volume
 *
 **/
function getCardData(){
    $.ajax({
    	url:"http://api.bitcoincharts.com/v1/markets.json",
    	dataType: 'json',
    	success : function( json ){
    	    $.each( json , function(key,val){
        		if(val['symbol'] == data.options.m){
        		    data.result = json[val];
        		}
    	    });
    	},
        error: ajaxError
    });
}
getYesterdayAvg();

function formatDate(val){
	if(val < 10){
        return "0" + val;

    } else {
        return val;
	}
}
function getYesterdayAvg() {
	$.ajax({
		url:"http://api.coindesk.com/v1/bpi/historical/close.json?for=yesterday",
		dataType: 'json',
		success: function ( json ){
			var d = new Date();
			d.setDate(d.getDate()-1);
			var formatted = d.getFullYear()+'-'+formatDate(d.getMonth()+1)+'-'+formatDate((d.getDay()-1));
			bkg.console.log(json['bpi']);
			data.result.yesterday_avg = json['bpi'][formatted];

			getChange();
		},
		error: ajaxError
	});
}
function getChange(){
	data.result.change = data.result.close - data.result.yesterday_avg;
}
function getHashRate() {
    $.ajax({
        url:"http://blockchain.info/q/hashrate",
        success: function( text ){
            data.result.hashrate = Number(text).toPrecision(3);
        },
        error: ajaxError
    });
}

/**
 *Returns the Difficulity rate currently for bitcoin
 **/
function getDifficulity() {
    $.ajax({
        url:"http://blockchain.info/q/getdifficulty",
        success: function( text ){
           data.result.difficulity = Number(text).toPrecision(2);
        },
        error: ajaxError
    });
}

function ajaxError(jqXHR, textStatus, errorThrown) {
    bkg.console.log("AJAX error: " + errorThrown + ": " + textStatus);
}

function buildContainer() {
var d = new Date();
var domElement = "

Bitcoin

                                " + data.options.m + ":
                                BTC
                                 -
                                " + d.toLocalString() + "
                                ET

                                         " + data.result.close + "
                                        -" + data.result.change + " (" + ((data.result.change >= 0) ? "+" : "-") + data.result.change + "%)

                                                    1d
                                                    1d

                                                    5d
                                                    5d

                                                    1m
                                                    1m

                                                    6m
                                                    6m

                                                    1y
                                                    1y

                                                    5y
                                                    5y

                                                    max
                                                    max

Avg

High

Low

" + data.result.avg + "

" + data.result.high + "

" + data.result.low + "

Volume

Currency Volume

Network Total

" + data.result.volume + "

" + data.result.currency_volume + "

" + data.result.hashrate + " Ghash/s

            Data is not promised to be accurate. Most data delayed 15 or more minutes.

";

$('#rso').prepend(domElement);
}
<commit_msg>backslashes for giant string<commit_after>/*
Eventually this should become an event driven page instead of a pure background
page. However, only webRequest is currently not availble on event driven pages
for builds outside of the dev channel.
*/

//Used for logging to the background page (bkg.Console.log('foo'))
var bkg = chrome.extension.getBackgroundPage();

/*
Listener for requests coming from Google
*/
chrome.webRequest.onBeforeRequest.addListener(
    function(details){
    var subs;
        var positive = false;
        var index = details.url.search(/q=/);
        if(index != -1){
            subs = details.url.substring(index);
            subs = subs.substring(2, subs.indexOf('&'));
            positive = checkForBitcoin(subs);
        }
        if(positive){
            //Positive bitcoin match
            updateData();
            bkg.console.log("Bazinga: " + subs);
        }
        return;
    },
    {urls: ["https://www.google.com/*"]} //Do this for all google urls
);

//Core data
var data = {
    lastUpdated: {},
    baseURL: "http://bitcoincharts.com/charts/chart.png?",
    options: {
        width: "660",
        height: "192",
        m: "bitfinexUSD",
        SubmitButton: "Draw",
        c: "",
        s: "",
        e: "",
        Prev: "",
        Next: "",
        t: "M",
        b: "",
        a1: "",
        m1: "10",
        a2: "",
        m2: "25",
        x: "0",
        i1: "",
        i2: "",
        i3: "",
        i4: "",
        v: "1",
        cv: "0",
        ps: "0",
        l: "0",
        p: "0",
        ranges: {
            d1: {
                i: "",
                r: ""
            },
            d5: {
                i: "",
                r: ""
            },
            m1: {
                i: "",
                r: ""
            },
            m6: {
                i: "",
                r: ""
            },
            y1: {
                i: "",
                r: ""
            },
            y5: {
                i: "",
                r: ""
            },
            max: {
                i: "",
                r: ""
            }
        }
    },
    result: {}
};

$(document).bind("ajaxStop", function(){
    buildContainer();
});

function updateData() {
    getHashRate();
    getDifficulity();
    getCardData();
    getYesterdayAvg();
}

/*
*/
function buildURL(range) {
    var url = data.baseURl;

    var first = true; //Control the placement of '&'
    for(var key in data.options) {
        if(data.options.hasOwnProperty(key) && key) {
            if(key == "ranges") {
                if(first) {
                    url += "i";
                    first = false;
                } else {
                    url += "&i";
                }

                url += "=" + data.options.ranges[range].i;
                url += "&r" + "=" + data.options.ranges[range].r;
            }

            if(!first) {
                url += "&" + key + "=" + data.options.key;
            } else {
                url += key + "=" + data.options.key;
                first = false;
            }
        }
    }
}

/*
Function to be called when the user selects a range button. Causes the image to
be updated by replacing the image src URL with a new one
*/
function updateRange(range) {
    $('#fmob_chart').attr('src', buildURL(range));
}

/*
Checks strings for matches to bitcoin
*/
function checkForBitcoin(subs){
    subs = subs.toLowerCase();
    if( (subs == 'bit%20coin') ||
        (subs == 'bit+coin')   ||
        (subs == 'bitcoin')    ||
        (subs == 'btc')){
        return true;
    }
    return false;
}

/**
 * Fetches the data for the card population
 * returns an array with values
 * avg, cvolume (currency volume), difficulty, ghashrate, high, low, and btc volume
 *
 **/
function getCardData(){
    $.ajax({
    	url:"http://api.bitcoincharts.com/v1/markets.json",
    	dataType: 'json',
    	success : function( json ){
    	    $.each( json , function(key,val){
        		if(val['symbol'] == data.options.m){
        		    data.result = json[val];
        		}
    	    });
    	},
        error: ajaxError
    });
}
getYesterdayAvg();

function formatDate(val){
	if(val < 10){
        return "0" + val;

    } else {
        return val;
	}
}
function getYesterdayAvg() {
	$.ajax({
		url:"http://api.coindesk.com/v1/bpi/historical/close.json?for=yesterday",
		dataType: 'json',
		success: function ( json ){
			var d = new Date();
			d.setDate(d.getDate()-1);
			var formatted = d.getFullYear()+'-'+formatDate(d.getMonth()+1)+'-'+formatDate((d.getDay()-1));
			bkg.console.log(json['bpi']);
			data.result.yesterday_avg = json['bpi'][formatted];

			getChange();
		},
		error: ajaxError
	});
}
function getChange(){
	data.result.change = data.result.close - data.result.yesterday_avg;
}
function getHashRate() {
    $.ajax({
        url:"http://blockchain.info/q/hashrate",
        success: function( text ){
            data.result.hashrate = Number(text).toPrecision(3);
        },
        error: ajaxError
    });
}

/**
 *Returns the Difficulity rate currently for bitcoin
 **/
function getDifficulity() {
    $.ajax({
        url:"http://blockchain.info/q/getdifficulty",
        success: function( text ){
           data.result.difficulity = Number(text).toPrecision(2);
        },
        error: ajaxError
    });
}

function ajaxError(jqXHR, textStatus, errorThrown) {
    bkg.console.log("AJAX error: " + errorThrown + ": " + textStatus);
}

function buildContainer() {
    var d = new Date();
    var domElement = "
\
    \

\

\

\

\

\

\

\

\

Bitcoin
\
                                    " + data.options.m + ": \
                                    BTC\
                                     -  \
                                    " + d.toLocalString() + " \
                                    ET\

\

\

\

\
                                             " + data.result.close + "\
                                            -" + data.result.change + " (" + ((data.result.change >= 0) ? "+" : "-") + data.result.change + "%)\

\

\

\
                                                \
                                                    \
                                                \

\

\
                                                        1d\
                                                        1d\

\

\
                                                        5d\
                                                        5d\

\

\
                                                        1m\
                                                        1m\

\

\
                                                        6m\
                                                        6m\

\

\
                                                        1y\
                                                        1y\

\

\
                                                        5y\
                                                        5y\

\

\
                                                        max
                                                        max\

\

\

\

\

\

\

Avg
\

High
\

Low
\

\

\

" + data.result.avg + "
\

" + data.result.high + "
\

" + data.result.low + "
\

\

\

\

\

Volume
\

Currency Volume
\

Network Total
\

\

\

" + data.result.volume + "
\

" + data.result.currency_volume + "
\

" + data.result.hashrate + " Ghash/s
\

\

\

\

\

\

\

\

\

\

\

\

\

\
                Data is not promised to be accurate. Most data delayed 15 or more minutes.\

\

\
    \

";

    $('#rso').prepend(domElement);
}
<|endoftext|>


<commit_before>var logging = false;
var checkType;
var blacklistDefaults =
        "googleleads.g.doubleclick.net\n" +
        "doubleclick.net\n" +
        "googleadservices.com\n" +
        "www.googleadservices.com\n" +
        "googlesyndication.com\n" +
        "adservices.google.com\n" +
        "appliedsemantics.com";

var checkTypeDefault = "GET";
var cacheDefault = "false";
var noFollowDefault = "false";
chrome.extension.onMessage.addListener(onRequest);

chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript(tab.id, {file:'check.js'}, function () {
        // Set up the defaults if no values are present in LocalStorage
        if (getItem("blacklist") === null) {
            setItem("blacklist", blacklistDefaults);
        }

        if(getItem("checkType") == null){
          setItem("checkType", checkTypeDefault);
        }

        if(getItem("cache") == null){
          setItem("cache", cacheDefault);
        }
        var blacklist = getItem("blacklist");
        var nofollow = getItem("noFollow");
        checkType = getItem("checkType");
        var cacheType = getItem("cache");
        var optionsURL = chrome.extension.getURL("options.html");

        chrome.tabs.sendMessage(tab.id, {bl:blacklist, ct:checkType, ca:cacheType, op:optionsURL, nf:nofollow});
    });
});

function onRequest(request, sender, callback) {
    if (request.action == "check") {
        if (request.url) {
            if (getItem("cache")=='true'){
                indexedDBHelper.getLink(request.url).then(function(link){
                    if(typeof(link) != "undefined" && (200 <= link.status && link.status < 400)){
                        log("found");
                        log(link);
                        return callback(link.status);
                    }
                    else{
                        check(request.url, callback);
                        log("not in db");
                        log(request.url);
                        log("added");
                    }
                }, function(err){
                    log(err);
                });
            }
            else{
                // do not use cache
                check(request.url, callback);
            }
        }
    }
    return true;
}

// Timeout for each link is 60+1 seconds
var timeout = 30000;

function check(url, callback) {
    var XMLHttpTimeout = null;
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function (data) {
        if (xhr.readyState == 4) {
            log(xhr);
            clearTimeout(XMLHttpTimeout);
            if (200 <= xhr.status && xhr.status < 400){
                // If there is a hashtag in the URL
                if(url.indexOf("#")!=-1){
                    var parser = new DOMParser ();
                    var responseDoc = parser.parseFromString (xhr.responseText, "text/html");
                    var fragID = url.substring(url.indexOf("#")+1,url.length);
                    log (responseDoc.getElementById(fragID) || responseDoc.getElementsByName(fragID));
                    if( responseDoc.getElementById(fragID) || responseDoc.getElementsByName(fragID) ){
                        // Element with id that matches hashtag was found
                        if(getItem("cache")=='true'){
                            indexedDBHelper.addLink(url, xhr.status);
                        }
                        return callback(xhr.status);
                    }
                    else{
                        // Page resolved, but element with id that matches hashtag was not found
                        return callback(404);
                    }
                }
                else{
                    // No hashtag
                    if (getItem("cache")=='true'){
                        indexedDBHelper.addLink(url, xhr.status);
                    }
                }
            }
            return callback(xhr.status);
        }
    };

    try {
      xhr.open(getItem("checkType"), url, true);
      xhr.send();
    }
    catch(e){
      console.log(e);
    }

    XMLHttpTimeout=setTimeout(function (){return callback(408); xhr.abort();}, timeout += 1000);
}

// OPTIONS: Management

// OPTIONS: Set items in localstore
function setItem(key, value) {
    try {
      log("Inside setItem:" + key + ":" + value);
      window.localStorage.removeItem(key);
      window.localStorage.setItem(key, value);
    }catch(e) {
      log("Error inside setItem");
      log(e);
    }
    log("Return from setItem" + key + ":" +  value);
}

// OPTIONS: Get items from localstore
function getItem(key) {
    var value;
    log('Get Item:' + key);
    try {
      value = window.localStorage.getItem(key);
    }catch(e) {
      log("Error inside getItem() for key:" + key);
      log(e);
      value = "null";
    }
    log("Returning value: " + value);
    return value;
}

// OPTIONS: Zap all items in localstore
function clearStrg() {
    log('about to clear local storage');
    window.localStorage.clear();
    log('cleared');
}

function log(txt) {
    if(logging) {
      console.log(txt);
    }
}
<commit_msg>Check for elements with name and noFollow default<commit_after>var logging = false;
var checkType;
var blacklistDefaults =
        "googleleads.g.doubleclick.net\n" +
        "doubleclick.net\n" +
        "googleadservices.com\n" +
        "www.googleadservices.com\n" +
        "googlesyndication.com\n" +
        "adservices.google.com\n" +
        "appliedsemantics.com";

var checkTypeDefault = "GET";
var cacheDefault = "false";
var noFollowDefault = "false";
chrome.extension.onMessage.addListener(onRequest);

chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.executeScript(tab.id, {file:'check.js'}, function () {
        // Set up the defaults if no values are present in LocalStorage
        if (getItem("blacklist") === null) {
            setItem("blacklist", blacklistDefaults);
        }

        if(getItem("checkType") == null){
          setItem("checkType", checkTypeDefault);
        }

        if(getItem("cache") == null){
          setItem("cache", cacheDefault);
        }

        if(getItem("noFollow") == null){
          setItem("noFollow", noFollowDefault);
        }

        var blacklist = getItem("blacklist");
        var nofollow = getItem("noFollow");
        checkType = getItem("checkType");
        var cacheType = getItem("cache");
        var optionsURL = chrome.extension.getURL("options.html");

        chrome.tabs.sendMessage(tab.id, {bl:blacklist, ct:checkType, ca:cacheType, op:optionsURL, nf:nofollow});
    });
});

function onRequest(request, sender, callback) {
    if (request.action == "check") {
        if (request.url) {
            if (getItem("cache")=='true'){
                indexedDBHelper.getLink(request.url).then(function(link){
                    if(typeof(link) != "undefined" && (200 <= link.status && link.status < 400)){
                        log("found");
                        log(link);
                        return callback(link.status);
                    }
                    else{
                        check(request.url, callback);
                        log("not in db");
                        log(request.url);
                        log("added");
                    }
                }, function(err){
                    log(err);
                });
            }
            else{
                // do not use cache
                check(request.url, callback);
            }
        }
    }
    return true;
}

// Timeout for each link is 60+1 seconds
var timeout = 30000;

function check(url, callback) {
    var XMLHttpTimeout = null;
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function (data) {
        if (xhr.readyState == 4) {
            log(xhr);
            clearTimeout(XMLHttpTimeout);
            if (200 <= xhr.status && xhr.status < 400){
                // If there is a hashtag in the URL
                if(url.indexOf("#")!=-1){
                    var parser = new DOMParser ();
                    var responseDoc = parser.parseFromString (xhr.responseText, "text/html");
                    var fragID = url.substring(url.indexOf("#")+1,url.length);
                    log (responseDoc.getElementById(fragID) || responseDoc.getElementsByName(fragID));
                    if( responseDoc.getElementById(fragID) || responseDoc.getElementsByName(fragID).length > 0 ){
                        // Element with id that matches hashtag was found
                        if(getItem("cache")=='true'){
                            indexedDBHelper.addLink(url, xhr.status);
                        }
                        return callback(xhr.status);
                    }
                    else{
                        // Page resolved, but element with id that matches hashtag was not found
                        return callback(404);
                    }
                }
                else{
                    // No hashtag
                    if (getItem("cache")=='true'){
                        indexedDBHelper.addLink(url, xhr.status);
                    }
                }
            }
            return callback(xhr.status);
        }
    };

    try {
      xhr.open(getItem("checkType"), url, true);
      xhr.send();
    }
    catch(e){
      console.log(e);
    }

    XMLHttpTimeout=setTimeout(function (){return callback(408); xhr.abort();}, timeout += 1000);
}

// OPTIONS: Management

// OPTIONS: Set items in localstore
function setItem(key, value) {
    try {
      log("Inside setItem:" + key + ":" + value);
      window.localStorage.removeItem(key);
      window.localStorage.setItem(key, value);
    }catch(e) {
      log("Error inside setItem");
      log(e);
    }
    log("Return from setItem" + key + ":" +  value);
}

// OPTIONS: Get items from localstore
function getItem(key) {
    var value;
    log('Get Item:' + key);
    try {
      value = window.localStorage.getItem(key);
    }catch(e) {
      log("Error inside getItem() for key:" + key);
      log(e);
      value = "null";
    }
    log("Returning value: " + value);
    return value;
}

// OPTIONS: Zap all items in localstore
function clearStrg() {
    log('about to clear local storage');
    window.localStorage.clear();
    log('cleared');
}

function log(txt) {
    if(logging) {
      console.log(txt);
    }
}
<|endoftext|>


<commit_before>chrome.browserAction.setBadgeBackgroundColor({ color: '#00FF00' });

chrome.browserAction.onClicked.addListener(function() {

    chrome.tabs.query({active:true}, function(tabs) {
        var tab = tabs[0];

        new Promise(function(resolve, reject) {
            chrome.browserAction.getBadgeText(
                { tabId : tab.id },
                function(badgeText) { resolve(badgeText) }
            );
        }).then(function(badgeText) {
            if (badgeText === 'on') {
                chrome.tabs.sendMessage(tab.id, {command:'imazip:end'});
                chrome.browserAction.setBadgeText({ tabId: tab.id, text: '' })
            } else {
                chrome.tabs.executeScript(tab.id, {file: "js/jquery-2.0.3.js"});
                chrome.tabs.executeScript(tab.id, {file: "js/pick-url.js"}, function(result) {
                    chrome.tabs.sendMessage(tab.id, {
                        command:'imazip:start',
                        filter: localStorage.s
                    });
                });
                chrome.browserAction.setBadgeText({ tabId: tab.id, text: 'on' })
            }
        });
    });
});

chrome.runtime.onMessage.addListener(function(req, sender, sendResponse) {
    if (req.name === 'imazip:url:picked') {
        chrome.browserAction.setBadgeText({ tabId: sender.tab.id, text: '' });
        chrome.tabs.create({url:"html/download.html"}, function(tab) {
            chrome.tabs.sendMessage(tab.id, {urls:req.urls});
        });
    }
    if (req.name === 'imazip:close') {
        chrome.browserAction.setBadgeText({ tabId: sender.tab.id, text: '' })
    }
    if (req.name !== 'imazip') return;
    var page_url = req.page_url;
    var urls     = req.urls;
    var filename = req.filename.replace(/[:\/|"*<>?]/g, '');
    filename += filename.match(/\.zip$/) ? '' : '.zip';

    var zip = new JSZip();

    var promises = urls.map(function (url) {
        var resolvedUrl = URI.resolve(page_url, url);
        return new Promise(function(resolve, reject) {
            var xhr = new XMLHttpRequest();
            xhr.open("GET", resolvedUrl);
            xhr.responseType = "arraybuffer";

            xhr.onload = function (event) {
                var arrayBuffer = xhr.response;
                var filename = resolvedUrl.replace(/^(.*)\//, '');
                var mime = xhr.getResponseHeader('Content-Type');
                var ext  = mimeTypes[mime];
                filename += filename.match(new RegExp('\\.' + ext + '$')) ? '' : '.' + ext;
                zip.file(filename, arrayBuffer, { binary : true });
                resolve(true);
            };
            xhr.onerror = function (event) {
                resolve(false);
            };
            xhr.send();
        });
    });
    Promise.all(promises).then(function () {
        var blob = zip.generate({ type: "blob" });
        var objectUrl = URL.createObjectURL(blob);

        chrome.downloads.download({
            url:objectUrl,
            filename:filename
        }, function() {
            console.log('complete');
            sendResponse('complete');
        })
    });
});

var mimeTypes = {
    'image/bmp'                      : 'bmp',
    'image/cgm'                      : 'cgm',
    'image/g3fax'                    : 'g3',
    'image/gif'                      : 'gif',
    'image/ief'                      : 'ief',
    'image/jpeg'                     : 'jpg',
    'image/ktx'                      : 'ktx',
    'image/png'                      : 'png',
    'image/prs.btif'                 : 'btif',
    'image/sgi'                      : 'sgi',
    'image/svg+xml'                  : 'svg',
    'image/tiff'                     : 'tiff',
    'image/vnd.adobe.photoshop'      : 'psd',
    'image/vnd.dece.graphic'         : 'uvi',
    'image/vnd.dvb.subtitle'         : 'sub',
    'image/vnd.djvu'                 : 'djvu',
    'image/vnd.dwg'                  : 'dwg',
    'image/vnd.dxf'                  : 'dxf',
    'image/vnd.fastbidsheet'         : 'fbs',
    'image/vnd.fpx'                  : 'fpx',
    'image/vnd.fst'                  : 'fst',
    'image/vnd.fujixerox.edmics-mmr' : 'mmr',
    'image/vnd.fujixerox.edmics-rlc' : 'rlc',
    'image/vnd.ms-modi'              : 'mdi',
    'image/vnd.ms-photo'             : 'wdp',
    'image/vnd.net-fpx'              : 'npx',
    'image/vnd.wap.wbmp'             : 'wbmp',
    'image/vnd.xiff'                 : 'xif',
    'image/webp'                     : 'webp',
    'image/x-3ds'                    : '3ds',
    'image/x-cmu-raster'             : 'ras',
    'image/x-cmx'                    : 'cmx',
    'image/x-freehand'               : 'fh',
    'image/x-icon'                   : 'ico',
    'image/x-mrsid-image'            : 'sid',
    'image/x-pcx'                    : 'pcx',
    'image/x-pict'                   : 'pic',
    'image/x-portable-anymap'        : 'pnm',
    'image/x-portable-bitmap'        : 'pbm',
    'image/x-portable-graymap'       : 'pgm',
    'image/x-portable-pixmap'        : 'ppm',
    'image/x-rgb'                    : 'rgb',
    'image/x-tga'                    : 'tga',
    'image/x-xbitmap'                : 'xbm',
    'image/x-xpixmap'                : 'xpm',
    'image/x-xwindowdump'            : 'xwd'
}
<commit_msg>remove code<commit_after>chrome.browserAction.setBadgeBackgroundColor({ color: '#00FF00' });

chrome.browserAction.onClicked.addListener(function() {

    chrome.tabs.query({active:true}, function(tabs) {
        var tab = tabs[0];

        new Promise(function(resolve, reject) {
            chrome.browserAction.getBadgeText(
                { tabId : tab.id },
                function(badgeText) { resolve(badgeText) }
            );
        }).then(function(badgeText) {
            if (badgeText === 'on') {
                chrome.tabs.sendMessage(tab.id, {command:'imazip:end'});
                chrome.browserAction.setBadgeText({ tabId: tab.id, text: '' })
            } else {
                chrome.tabs.executeScript(tab.id, {file: "js/jquery-2.0.3.js"});
                chrome.tabs.executeScript(tab.id, {file: "js/pick-url.js"}, function(result) {
                    chrome.tabs.sendMessage(tab.id, {
                        command:'imazip:start',
                        filter: localStorage.s
                    });
                });
                chrome.browserAction.setBadgeText({ tabId: tab.id, text: 'on' })
            }
        });
    });
});

chrome.runtime.onMessage.addListener(function(req, sender, sendResponse) {
    if (req.name === 'imazip:url:picked') {
        chrome.browserAction.setBadgeText({ tabId: sender.tab.id, text: '' });
        chrome.tabs.create({url:"html/download.html"}, function(tab) {
            chrome.tabs.sendMessage(tab.id, {urls:req.urls});
        });
    }

    if (req.name !== 'imazip') return;
    var page_url = req.page_url;
    var urls     = req.urls;
    var filename = req.filename.replace(/[:\/|"*<>?]/g, '');
    filename += filename.match(/\.zip$/) ? '' : '.zip';

    var zip = new JSZip();

    var promises = urls.map(function (url) {
        var resolvedUrl = URI.resolve(page_url, url);
        return new Promise(function(resolve, reject) {
            var xhr = new XMLHttpRequest();
            xhr.open("GET", resolvedUrl);
            xhr.responseType = "arraybuffer";

            xhr.onload = function (event) {
                var arrayBuffer = xhr.response;
                var filename = resolvedUrl.replace(/^(.*)\//, '');
                var mime = xhr.getResponseHeader('Content-Type');
                var ext  = mimeTypes[mime];
                filename += filename.match(new RegExp('\\.' + ext + '$')) ? '' : '.' + ext;
                zip.file(filename, arrayBuffer, { binary : true });
                resolve(true);
            };
            xhr.onerror = function (event) {
                resolve(false);
            };
            xhr.send();
        });
    });

    Promise.all(promises).then(function () {
        var blob = zip.generate({ type: "blob" });
        var objectUrl = URL.createObjectURL(blob);

        chrome.downloads.download({
            url:objectUrl,
            filename:filename
        }, function() {
            console.log('complete');
            sendResponse('complete');
        })
    });
});

var mimeTypes = {
    'image/bmp'                      : 'bmp',
    'image/cgm'                      : 'cgm',
    'image/g3fax'                    : 'g3',
    'image/gif'                      : 'gif',
    'image/ief'                      : 'ief',
    'image/jpeg'                     : 'jpg',
    'image/ktx'                      : 'ktx',
    'image/png'                      : 'png',
    'image/prs.btif'                 : 'btif',
    'image/sgi'                      : 'sgi',
    'image/svg+xml'                  : 'svg',
    'image/tiff'                     : 'tiff',
    'image/vnd.adobe.photoshop'      : 'psd',
    'image/vnd.dece.graphic'         : 'uvi',
    'image/vnd.dvb.subtitle'         : 'sub',
    'image/vnd.djvu'                 : 'djvu',
    'image/vnd.dwg'                  : 'dwg',
    'image/vnd.dxf'                  : 'dxf',
    'image/vnd.fastbidsheet'         : 'fbs',
    'image/vnd.fpx'                  : 'fpx',
    'image/vnd.fst'                  : 'fst',
    'image/vnd.fujixerox.edmics-mmr' : 'mmr',
    'image/vnd.fujixerox.edmics-rlc' : 'rlc',
    'image/vnd.ms-modi'              : 'mdi',
    'image/vnd.ms-photo'             : 'wdp',
    'image/vnd.net-fpx'              : 'npx',
    'image/vnd.wap.wbmp'             : 'wbmp',
    'image/vnd.xiff'                 : 'xif',
    'image/webp'                     : 'webp',
    'image/x-3ds'                    : '3ds',
    'image/x-cmu-raster'             : 'ras',
    'image/x-cmx'                    : 'cmx',
    'image/x-freehand'               : 'fh',
    'image/x-icon'                   : 'ico',
    'image/x-mrsid-image'            : 'sid',
    'image/x-pcx'                    : 'pcx',
    'image/x-pict'                   : 'pic',
    'image/x-portable-anymap'        : 'pnm',
    'image/x-portable-bitmap'        : 'pbm',
    'image/x-portable-graymap'       : 'pgm',
    'image/x-portable-pixmap'        : 'ppm',
    'image/x-rgb'                    : 'rgb',
    'image/x-tga'                    : 'tga',
    'image/x-xbitmap'                : 'xbm',
    'image/x-xpixmap'                : 'xpm',
    'image/x-xwindowdump'            : 'xwd'
}
<|endoftext|>