<commit_before>/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/

/*
 * Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

var fs = require("fs");
var path = require('path');
var log4js = require("log4js");
var mkdirp = require("mkdirp");
var existsSync = fs.existsSync || path.existsSync;

function FileUtil() {
    this.logger = log4js.getLogger("FileUtil");
}

FileUtil.prototype.createDirectory = function (dirPath, callback) {

    if (!dirPath || dirPath === '') {
        this.logger.info('Directory Path is empty or undefined..');
        return;
    }

    mkdirp.sync(dirPath);

    if (callback) {
        callback();
    }

};

FileUtil.prototype.removeDirectory = function(dirPath, callback) {

    var files = [],
        stat,
        filePath,
        i;

    if (existsSync(dirPath)) { // path.existsSync is used to support node 0.6 ( use fs.existsSync for versions >= 0
        files = fs.readdirSync(dirPath);

        for (i = 0; i < files.length; i += 1) {

            filePath = path.resolve(dirPath, files[i]);
            stat = fs.statSync(filePath);

            if (stat.isDirectory()) {
                this.removeDirectory(filePath);
            } else {
                fs.unlinkSync(filePath);
            }
        }

        fs.rmdirSync(dirPath);
    }

    if (callback) {
        callback();
    }

};

FileUtil.prototype.deleteFile = function(filePath, callback) {

    try {

        if (existsSync(filePath)) {
            fs.unlinkSync(filePath);
            callback();
        } else {
            callback();
        }

    } catch (e) {
        this.logger.info('Error deleting file - ' + filePath  + 'Error:' + e);
        callback();
    }

};

module.exports = FileUtil;<commit_msg>Removing unused method<commit_after>/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/

/*
 * Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

var fs = require("fs");
var path = require('path');
var log4js = require("log4js");
var mkdirp = require("mkdirp");
var existsSync = fs.existsSync || path.existsSync;

function FileUtil() {
    this.logger = log4js.getLogger("FileUtil");
}

FileUtil.prototype.createDirectory = function (dirPath, callback) {

    if (!dirPath || dirPath === '') {
        this.logger.info('Directory Path is empty or undefined..');
        return;
    }

    mkdirp.sync(dirPath);

    if (callback) {
        callback();
    }

};

FileUtil.prototype.removeDirectory = function(dirPath, callback) {

    var files = [],
        stat,
        filePath,
        i;

    if (existsSync(dirPath)) { // path.existsSync is used to support node 0.6 ( use fs.existsSync for versions >= 0
        files = fs.readdirSync(dirPath);

        for (i = 0; i < files.length; i += 1) {

            filePath = path.resolve(dirPath, files[i]);
            stat = fs.statSync(filePath);

            if (stat.isDirectory()) {
                this.removeDirectory(filePath);
            } else {
                fs.unlinkSync(filePath);
            }
        }

        fs.rmdirSync(dirPath);
    }

    if (callback) {
        callback();
    }

};
//
//FileUtil.prototype.deleteFile = function(filePath, callback) {
//
//    try {
//
//        if (existsSync(filePath)) {
//            fs.unlinkSync(filePath);
//            callback();
//        } else {
//            callback();
//        }
//
//    } catch (e) {
//        this.logger.info('Error deleting file - ' + filePath  + 'Error:' + e);
//        callback();
//    }
//
//};

module.exports = FileUtil;<|endoftext|>


<commit_before>var http = require('http');
var https = require('https');
var fs = require('fs');
var extend = require('extend');
var fileMgr = require('./file-mgr');
var logger = require('./logger');
var parseUrl = require('./parse-url');

var cache = {};
var listeners = [];
var newUrls;
var TIMEOUT = 10000;
var MAX_RULES_LEN = 1024 * 64;
var MAX_FILE_LEN = 1024 * 256;
var MAX_INTERVAL = 1000 * 30;
var MIN_INTERVAL = 1000 * 10;
var EEXCEED = 'EEXCEED';
var OPTIONS = { encoding: 'utf8' };
var queue = [];
var queueTimer;
var FILE_RE = /^(?:[a-z]:[\\/]|~?\/)/i;

function getInterval(time, isLocal) {
  var len = Object.keys(cache).length || 1;
  var interval = isLocal ? 5000 : Math.max(MIN_INTERVAL, Math.ceil(MAX_INTERVAL / len));
  var minTime = interval - (time > 0 ? time : 0);
  return Math.max(minTime, 1000);
}

function triggerChange(data, body) {
  if (data) {
    body = body && body.trim() || '';
    if (data.body === body) {
      return;
    }
    data.body = body;
  }
  if (newUrls) {
    return;
  }
  newUrls = {};
  listeners.forEach(function(l) {
    l();
  });
  Object.keys(newUrls).forEach(function(url) {
    newUrls[url] = cache[url];
  });
  cache = newUrls;
  newUrls = null;
}

function parseOptions(options) {
  if (typeof options === 'string') {
    options = parseUrl(fullUrl);
  } else {
    var fullUrl = options.url || options.uri;
    if (fullUrl && typeof fullUrl === 'string') {
      options = extend(options, parseUrl(fullUrl));
    }
  }
  var maxLength = options.maxLength;
  if (!(maxLength > 0)) {
    options.maxLength = 0;
  }
  options.agent = false;
  options.rejectUnauthorized = false;
  return options;
}

function toString(obj) {
  if (obj == null) {
    return;
  }
  if (typeof obj === 'object') {
    return JSON.stringify(obj);
  }
  if (Buffer.isBuffer(obj)) {
    return obj;
  }
  return obj + '';
}

function request(options, callback) {
  options = parseOptions(options);
  var isHttps = options.protocol === 'https:';
  var httpModule = isHttps ? https : http;
  var done, timer, res;
  var body = '';
  var callbackHandler = function(err) {
    clearTimeout(timer);
    err && client.abort();
    if (!done) {
      done = true;
      callback(err, body, res || '');
    }
  };
  var addTimeout = function() {
    clearTimeout(timer);
    timer = setTimeout(function() {
      callbackHandler(new Error('Timeout'));
    }, TIMEOUT);
  };
  addTimeout();
  var maxLength = options.maxLength;
  options.agent = false;
  var client = httpModule.request(options, function(r) {
    res = r;
    res.on('error', callbackHandler);
    res.setEncoding('utf8');
    res.on('data', function(data) {
      body += data;
      addTimeout();
      if (maxLength && body.length > maxLength) {
        var err;
        if (!options.ignoreExceedError) {
          err = new Error('The response body exceeded length limit');
          err.code = EEXCEED;
        }
        callbackHandler(err);
      }
    });
    res.on('end', callbackHandler);
  });
  client.on('error', callbackHandler);
  client.end(toString(options.body));
  return client;
}

exports.request = request;

function readFile(url, callback) {
  var data;
  var now = Date.now();
  var execCallback = function() {
    callback(url, Date.now() - now);
  };
  fs.stat(url, function(err, stat) {
    data = cache[url];
    if (!data) {
      return execCallback();
    }
    if (err) {
      if (err.code === 'ENOENT') {
        err = null;
      } else {
        logger.error(url, err.message);
      }
      triggerChange(data);
      data.mtime = null;
      return execCallback();
    }
    if (!stat.isFile()) {
      triggerChange(data);
      data.mtime = null;
      return execCallback();
    }
    var time = stat.mtime.getTime();
    if (time === data.mtime) {
      return execCallback();
    }

    var stream = fs.createReadStream(fileMgr.convertSlash(url), OPTIONS);
    var done;
    var body = '';
    var listener = function(err) {
      if (done) {
        return;
      }
      execCallback();
      if (err && err.code !== 'ENOENT') {
        return;
      }
      done = true;
      data.mtime = time;
      stream.close();
      triggerChange(data, body);
    };
    stream.on('data', function(text) {
      if (done) {
        return;
      }
      body += text;
      if (body.length > MAX_FILE_LEN) {
        listener();
      }
    });
    stream.on('error', listener);
    stream.on('end', listener);
  });
}

function addQueue(url, consumeTime) {
  if (cache[url] && queue.indexOf(url) === -1) {
    queue.push(url);
  }
  var data;
  while(!queueTimer && !data) {
    url = queue.shift();
    if (!url) {
      return;
    }
    data = cache[url];
    if (data) {
      queueTimer = setTimeout(function() {
        queueTimer = null;
        updateBody(url, addQueue);
      }, getInterval(consumeTime, data.isLocalUrl || data.isLocaPath));
      return;
    }
  }
}

function updateBody(url, callback, init) {
  var data = cache[url];
  if (!data) {
    return callback && callback();
  }
  if (data.isLocaPath) {
    return readFile(url, addQueue);
  }
  var now = Date.now();
  var options = {
    url: url,
    maxLength: MAX_RULES_LEN,
    ignoreExceedError: true
  };
  if (data.headers) {
    options.headers = data.headers;
  }
  request(options, function(err, body, res) {
    data = cache[url];
    callback && callback(url, Date.now() - now);
    if (!data) {
      return;
    }
    var code = res.statusCode;
    if (code == 404) {
      err = body = '';
    } else if (!err && code != 200 && code != 204) {
      err = new Error('Response ' + code);
    }
    if (err) {
      logger.error(url, err.message);
      if (init) {
        updateBody(url);
        return;
      }
    }
    addQueue(url);
    if (err) {
      return;
    }
    triggerChange(data, body);
  });
  return true;
}

exports.addChangeListener = function(l) {
  listeners.push(l);
};

exports.add = function(url, headers) {
  var data = cache[url];
  if (!data) {
    cache[url] = data = {
      body: '',
      isLocalUrl: url.indexOf('http://127.0.0.1:') === 0,
      isLocaPath: FILE_RE.test(url),
      headers: headers
    };
    updateBody(url, null, true);
  }
  if (newUrls) {
    newUrls[url] = 1;
  }
  return data.body;
};

exports.forceUpdate = function(root) {
  Object.keys(cache).forEach(function(url) {
    if (url.indexOf(root) === 0) {
      updateBody(url);
    }
  });
};

exports.clean = function() {
  if (!newUrls && Object.keys(cache).length) {
    triggerChange();
  }
};
<commit_msg>chore: log request exceptions<commit_after>var http = require('http');
var https = require('https');
var fs = require('fs');
var extend = require('extend');
var fileMgr = require('./file-mgr');
var logger = require('./logger');
var parseUrl = require('./parse-url');

var cache = {};
var listeners = [];
var newUrls;
var TIMEOUT = 10000;
var MAX_RULES_LEN = 1024 * 64;
var MAX_FILE_LEN = 1024 * 256;
var MAX_INTERVAL = 1000 * 30;
var MIN_INTERVAL = 1000 * 10;
var EEXCEED = 'EEXCEED';
var OPTIONS = { encoding: 'utf8' };
var queue = [];
var queueTimer;
var FILE_RE = /^(?:[a-z]:[\\/]|~?\/)/i;

function getInterval(time, isLocal) {
  var len = Object.keys(cache).length || 1;
  var interval = isLocal ? 5000 : Math.max(MIN_INTERVAL, Math.ceil(MAX_INTERVAL / len));
  var minTime = interval - (time > 0 ? time : 0);
  return Math.max(minTime, 1000);
}

function triggerChange(data, body) {
  if (data) {
    body = body && body.trim() || '';
    if (data.body === body) {
      return;
    }
    data.body = body;
  }
  if (newUrls) {
    return;
  }
  newUrls = {};
  listeners.forEach(function(l) {
    l();
  });
  Object.keys(newUrls).forEach(function(url) {
    newUrls[url] = cache[url];
  });
  cache = newUrls;
  newUrls = null;
}

function parseOptions(options) {
  if (typeof options === 'string') {
    options = parseUrl(fullUrl);
  } else {
    var fullUrl = options.url || options.uri;
    if (fullUrl && typeof fullUrl === 'string') {
      options = extend(options, parseUrl(fullUrl));
    }
  }
  var maxLength = options.maxLength;
  if (!(maxLength > 0)) {
    options.maxLength = 0;
  }
  options.agent = false;
  options.rejectUnauthorized = false;
  return options;
}

function toString(obj) {
  if (obj == null) {
    return;
  }
  if (typeof obj === 'object') {
    return JSON.stringify(obj);
  }
  if (Buffer.isBuffer(obj)) {
    return obj;
  }
  return obj + '';
}

function request(options, callback) {
  options = parseOptions(options);
  var isHttps = options.protocol === 'https:';
  var httpModule = isHttps ? https : http;
  var done, timer, res;
  var body = '';
  var callbackHandler = function(err) {
    clearTimeout(timer);
    err && client.abort();
    if (!done) {
      done = true;
      callback(err, body, res || '');
    }
  };
  var addTimeout = function() {
    clearTimeout(timer);
    timer = setTimeout(function() {
      callbackHandler(new Error('Timeout'));
    }, TIMEOUT);
  };
  addTimeout();
  var maxLength = options.maxLength;
  options.agent = false;
  var client = httpModule.request(options, function(r) {
    res = r;
    res.on('error', callbackHandler);
    res.setEncoding('utf8');
    res.on('data', function(data) {
      body += data;
      addTimeout();
      if (maxLength && body.length > maxLength) {
        var err;
        if (!options.ignoreExceedError) {
          err = new Error('The response body exceeded length limit');
          err.code = EEXCEED;
        }
        callbackHandler(err);
      }
    });
    res.on('end', callbackHandler);
  });
  client.on('error', callbackHandler);
  client.end(toString(options.body));
  return client;
}

exports.request = request;

function readFile(url, callback) {
  var data;
  var now = Date.now();
  var execCallback = function() {
    callback(url, Date.now() - now);
  };
  fs.stat(url, function(err, stat) {
    data = cache[url];
    if (!data) {
      return execCallback();
    }
    if (err) {
      if (err.code === 'ENOENT') {
        err = null;
      } else {
        logger.error(url, err.message);
      }
      triggerChange(data);
      data.mtime = null;
      return execCallback();
    }
    if (!stat.isFile()) {
      triggerChange(data);
      data.mtime = null;
      return execCallback();
    }
    var time = stat.mtime.getTime();
    if (time === data.mtime) {
      return execCallback();
    }

    var stream = fs.createReadStream(fileMgr.convertSlash(url), OPTIONS);
    var done;
    var body = '';
    var listener = function(err) {
      if (done) {
        return;
      }
      execCallback();
      if (err && err.code !== 'ENOENT') {
        return;
      }
      done = true;
      data.mtime = time;
      stream.close();
      triggerChange(data, body);
    };
    stream.on('data', function(text) {
      if (done) {
        return;
      }
      body += text;
      if (body.length > MAX_FILE_LEN) {
        listener();
      }
    });
    stream.on('error', listener);
    stream.on('end', listener);
  });
}

function addQueue(url, consumeTime) {
  if (cache[url] && queue.indexOf(url) === -1) {
    queue.push(url);
  }
  var data;
  while(!queueTimer && !data) {
    url = queue.shift();
    if (!url) {
      return;
    }
    data = cache[url];
    if (data) {
      queueTimer = setTimeout(function() {
        queueTimer = null;
        updateBody(url, addQueue);
      }, getInterval(consumeTime, data.isLocalUrl || data.isLocaPath));
      return;
    }
  }
}

function updateBody(url, callback, init) {
  var data = cache[url];
  if (!data) {
    return callback && callback();
  }
  if (data.isLocaPath) {
    return readFile(url, addQueue);
  }
  var now = Date.now();
  var options = {
    url: url,
    maxLength: MAX_RULES_LEN,
    ignoreExceedError: true
  };
  if (data.headers) {
    options.headers = data.headers;
  }
  request(options, function(err, body, res) {
    data = cache[url];
    callback && callback(url, Date.now() - now);
    if (!data) {
      return;
    }
    var code = res.statusCode;
    if (code == 404) {
      err = body = '';
      logger.warn('[Load Rules]', url, 'status', 404);
    } else if (!err && code != 200 && code != 204) {
      err = 'response ' + code;
    }
    if (err) {
      logger.error('[Load Rules]', url, err.message || err);
      if (init) {
        updateBody(url);
        return;
      }
    }
    addQueue(url);
    if (err) {
      return;
    }
    triggerChange(data, body);
  });
  return true;
}

exports.addChangeListener = function(l) {
  listeners.push(l);
};

exports.add = function(url, headers) {
  var data = cache[url];
  if (!data) {
    cache[url] = data = {
      body: '',
      isLocalUrl: url.indexOf('http://127.0.0.1:') === 0,
      isLocaPath: FILE_RE.test(url),
      headers: headers
    };
    updateBody(url, null, true);
  }
  if (newUrls) {
    newUrls[url] = 1;
  }
  return data.body;
};

exports.forceUpdate = function(root) {
  Object.keys(cache).forEach(function(url) {
    if (url.indexOf(root) === 0) {
      updateBody(url);
    }
  });
};

exports.clean = function() {
  if (!newUrls && Object.keys(cache).length) {
    triggerChange();
  }
};
<|endoftext|>


<commit_before>
const sqreen = require('./sqreen');
const EmailBlacklist = require('../../lib/models/email-blacklist');
const IpBlacklist = require('../../lib/models/ip-blacklist');
const RISK_SCORE = 80;
const TERMINATE = 'terminate';
const VALIDATED = 'validated';
const UNKNOWN = 'unknown';

let blacklistedEmail = null;
let blacklistedIp = null;
let emailPayload = null;
let ipPayload = null;

module.exports = {

    verifyUser(email, ip) {

        return Promise.all([

            EmailBlacklist.emailExists({ 'email': email })
                .then(result => {
                    blacklistedEmail = result;
                    return blacklistedEmail;
                }),

            IpBlacklist.ipExists({ 'ip': ip })
                .then(result => {
                    blacklistedIp = result;
                    return blacklistedIp;
                }),

            sqreen.sqreenEmail(email)
                .then(payload => {
                    emailPayload = payload;
                    return emailPayload;
                }),

            sqreen.sqreenIp(ip)
                .then(payload => {
                    ipPayload = payload;
                    return emailPayload;
                })
        ])
            .then(() => {

                if (blacklistedEmail === true || blacklistedIp === true) {
                    return TERMINATE;
                }
                else if (emailPayload.risk_score >= RISK_SCORE || ipPayload.risk_score >= RISK_SCORE) {
                    return TERMINATE;
                }
                else if (emailPayload.risk_score < RISK_SCORE && ipPayload.risk_score < RISK_SCORE) {
                    return VALIDATED;
                }
                else return UNKNOWN;
            });
    }
};

// .then(() => {
//     if(emailPayload)

// })

// verifyIp(ip => {
//     return sqreen.sqreenIp(ip)
//         .then(payload => {

//             if(payload.risk_score >= RISK_SCORE) {
//                 return TERMINATE;
//             } else {
//                 return VALIDATED;
//             }});
// })

//     .then(emailPayload => {
//             if(emailPayload.risk_score >= RISK_SCORE) {
//                 return TERMINATE;
//             } else {
//                 return VALIDATED;
//             }});
//          }),<commit_msg>Clean up erroneous commented code in analyze module<commit_after>
const sqreen = require('./sqreen');
const EmailBlacklist = require('../../lib/models/email-blacklist');
const IpBlacklist = require('../../lib/models/ip-blacklist');
const RISK_SCORE = 80;
const TERMINATE = 'terminate';
const VALIDATED = 'validated';
const UNKNOWN = 'unknown';

let blacklistedEmail = null;
let blacklistedIp = null;
let emailPayload = null;
let ipPayload = null;

module.exports = {

    verifyUser(email, ip) {

        return Promise.all([

            EmailBlacklist.emailExists({ 'email': email })
                .then(result => {
                    blacklistedEmail = result;
                    return blacklistedEmail;
                }),

            IpBlacklist.ipExists({ 'ip': ip })
                .then(result => {
                    blacklistedIp = result;
                    return blacklistedIp;
                }),

            sqreen.sqreenEmail(email)
                .then(payload => {
                    emailPayload = payload;
                    return emailPayload;
                }),

            sqreen.sqreenIp(ip)
                .then(payload => {
                    ipPayload = payload;
                    return emailPayload;
                })
        ])
            .then(() => {

                if (blacklistedEmail === true || blacklistedIp === true) {
                    return TERMINATE;
                }
                else if (emailPayload.risk_score >= RISK_SCORE || ipPayload.risk_score >= RISK_SCORE) {
                    return TERMINATE;
                }
                else if (emailPayload.risk_score < RISK_SCORE && ipPayload.risk_score < RISK_SCORE) {
                    return VALIDATED;
                }
                else return UNKNOWN;
            });
    }
};<|endoftext|>


<commit_before>'use strict';

const ImplementationError = require('../error').ImplementationError;
const getFunctionArguments = require('./arguments').getFunctionArguments;
const Mode = require('./mode');

/* eslint-disable no-param-reassign */
/**
 * Walk the prototype inheritance chain until we reach the terminator and get all public methods
 * minus the constructor
 *
 * @param {Object} obj - class under test
 * @param {Array} accumulator
 * @param {Object} terminator - the prototype of the class to terminate the traversal
 * @param {Array.<Object>} [swapper] - swap swapper[1] class for swapper[0] class if it occurs in
 * the inheritance chain
 * @return {Array.<string>}
 * @private
 */
const getMethods = (obj, accumulator, terminator, swapper) => {
  if (swapper) {
    if (obj === swapper[0]) {
      obj = swapper[1];
    }
  }

  if (obj === terminator) {
    return accumulator;
  }

  accumulator = accumulator
    .concat(Object.getOwnPropertyNames(obj))
    // Filter private methods
    .filter(el => !el.startsWith('_'))
    // Filter constructors
    .filter(el => el !== 'constructor');

  // Filter duplicates
  accumulator = Array.from(new Set(accumulator));

  return getMethods(Object.getPrototypeOf(obj), accumulator, terminator, swapper);
};
/* eslint-enable no-param-reassign */

/**
 * Compares implementation methods to contract methods
 *
 * @param {Object} impl
 * @param {Object} contract
 * @return {Map} a map of method name to any error object
 */
const compareMethods = (impl, contract) => {
  const implMethods = impl.methods;
  const contractObj = contract.object;
  const contractMethods = contract.methods;

  return contractMethods.reduce((m, val) => {
    if (implMethods.indexOf(val) < 0) {
      m.set(val, {
        type: ImplementationError.METHOD_MISSING,
        mode: [Mode.STRICT, Mode.LOOSE],
        signature: `${val}(${getFunctionArguments(contractObj[val]).join(', ').trim()})`,
      });
    }
    return m;
  }, new Map());
};

module.exports = {
  getMethods,
  compareMethods,
};
<commit_msg>Added null check for when inheriting classes reach the end of the prototype chain.<commit_after>'use strict';

const ImplementationError = require('../error').ImplementationError;
const getFunctionArguments = require('./arguments').getFunctionArguments;
const Mode = require('./mode');

/* eslint-disable no-param-reassign */
/**
 * Walk the prototype inheritance chain until we reach the terminator and get all public methods
 * minus the constructor
 *
 * @param {Object} obj - class under test
 * @param {Array} accumulator
 * @param {Object} terminator - the prototype of the class to terminate the traversal
 * @param {Array.<Object>} [swapper] - swap swapper[1] class for swapper[0] class if it occurs in
 * the inheritance chain
 * @return {Array.<string>}
 * @private
 */
const getMethods = (obj, accumulator, terminator, swapper) => {
  if (swapper) {
    if (obj === swapper[0]) {
      obj = swapper[1];
    }
  }

  if (obj === terminator || obj === null) {
    return accumulator;
  }

  accumulator = accumulator
    .concat(Object.getOwnPropertyNames(obj))
    // Filter private methods and builtin __methods.
    .filter(el => !el.startsWith('_'))
    // Filter constructors
    .filter(el => el !== 'constructor');

  // Filter duplicates
  accumulator = Array.from(new Set(accumulator));

  return getMethods(Object.getPrototypeOf(obj), accumulator, terminator, swapper);
};
/* eslint-enable no-param-reassign */

/**
 * Compares implementation methods to contract methods
 *
 * @param {Object} impl
 * @param {Object} contract
 * @return {Map} a map of method name to any error object
 */
const compareMethods = (impl, contract) => {
  const implMethods = impl.methods;
  const contractObj = contract.object;
  const contractMethods = contract.methods;

  return contractMethods.reduce((m, val) => {
    if (implMethods.indexOf(val) < 0) {
      m.set(val, {
        type: ImplementationError.METHOD_MISSING,
        mode: [Mode.STRICT, Mode.LOOSE],
        signature: `${val}(${getFunctionArguments(contractObj[val]).join(', ').trim()})`,
      });
    }
    return m;
  }, new Map());
};

module.exports = {
  getMethods,
  compareMethods,
};
<|endoftext|>


<commit_before>import React from 'react';

import { Grid, Segment, Header, Loader, Icon, List, Transition, Button } from 'semantic-ui-react';

const styles = {
	parent: {
		margin: '0px',
		padding: '32px 40px 32px 32px',
		height: 'calc(100vh - 240px)',
		overflowY: 'scroll'
	},
	downloadCard: {
		width: '100%'
	},
	downloadCardList: {
		paddingBottom: '32px'
	},
	noDownloads: {
		paddingTop: '16vh',
		textAlign: 'center'
	},
	loadContent: {
		fontSize: '16px',
		width: '100%'
	}
};

function DownloadCard(props) {
	const {
		name,
		size,
		status
	} = props;

	let cardStatusIndicator = null;

	switch(status) {
		case 'ongoing': cardStatusIndicator = <Loader active />; break;
		case 'done': cardStatusIndicator = <Icon name='check circle' size='big' color='green' />; break;
		case 'failed': cardStatusIndicator = <Icon name='warning circle' size='big' color='red' />; break;
	}

	return (
		<Segment compact style={styles.downloadCard}>
			<Grid columns={2}>
				<Grid.Column width={13} stretched>

							{name}
							Size {size}

				</Grid.Column>

				<Grid.Column width={3} textAlign='center' verticalAlign='middle'>
					{cardStatusIndicator}
				</Grid.Column>
			</Grid>
		</Segment>
	);
}

function renderDownloadCards(downloads) {
	const downloadCards = downloads.map((item, index) => {
		return (
			<List.Item key={index}>
				<DownloadCard name={item.name} size={item.size} status={item.status} />
			</List.Item>
		);
	});

	return (
		<Transition.Group as={List} duration={200}>
			{downloadCards}
		</Transition.Group>
	);
}

function renderNoDownloads() {
	return (

			<Icon name='download' size='huge' />

No downloads in progress.

	);
}

function isListEmpty(list) {
	let flag = true;

	if (list && list.length > 0) {
		const filteredList = list.filter(item => item); // filtering empty (null/undefined) items here

		if (filteredList.length > 0) {
			flag = false;
		}
	}

	return flag;
}

function renderLoadContentButton(clickHandler) {
	return (
		<Button
			primary
			onClick={clickHandler}
			style={styles.loadContent}
		>
			Load Content Into Plugin
		</Button>
	);
}

function renderDownloadCardsAndLoadContentButton(downloads, loadContentClickHandler) {
	return (

			{renderLoadContentButton(loadContentClickHandler)}
			{renderDownloadCards(downloads)}

	);
}

function Downloads(props) {
	const {
		downloads,
		handleLoadContentClick
	} = props;

	return (
		<Grid.Column stretched width={4} style={styles.parent}>
			{
				isListEmpty(downloads)
					? renderNoDownloads()
					: renderDownloadCardsAndLoadContentButton(downloads, handleLoadContentClick)
			}
		</Grid.Column>
	);
}

export default Downloads;<commit_msg>Remove full stop in placebolder text for download queue<commit_after>import React from 'react';

import { Grid, Segment, Header, Loader, Icon, List, Transition, Button } from 'semantic-ui-react';

const styles = {
	parent: {
		margin: '0px',
		padding: '32px 40px 32px 32px',
		height: 'calc(100vh - 240px)',
		overflowY: 'scroll'
	},
	downloadCard: {
		width: '100%'
	},
	downloadCardList: {
		paddingBottom: '32px'
	},
	noDownloads: {
		paddingTop: '16vh',
		textAlign: 'center'
	},
	loadContent: {
		fontSize: '16px',
		width: '100%'
	}
};

function DownloadCard(props) {
	const {
		name,
		size,
		status
	} = props;

	let cardStatusIndicator = null;

	switch(status) {
		case 'ongoing': cardStatusIndicator = <Loader active />; break;
		case 'done': cardStatusIndicator = <Icon name='check circle' size='big' color='green' />; break;
		case 'failed': cardStatusIndicator = <Icon name='warning circle' size='big' color='red' />; break;
	}

	return (
		<Segment compact style={styles.downloadCard}>
			<Grid columns={2}>
				<Grid.Column width={13} stretched>

							{name}
							Size {size}

				</Grid.Column>

				<Grid.Column width={3} textAlign='center' verticalAlign='middle'>
					{cardStatusIndicator}
				</Grid.Column>
			</Grid>
		</Segment>
	);
}

function renderDownloadCards(downloads) {
	const downloadCards = downloads.map((item, index) => {
		return (
			<List.Item key={index}>
				<DownloadCard name={item.name} size={item.size} status={item.status} />
			</List.Item>
		);
	});

	return (
		<Transition.Group as={List} duration={200}>
			{downloadCards}
		</Transition.Group>
	);
}

function renderNoDownloads() {
	return (

			<Icon name='download' size='huge' />

No downloads in progress

	);
}

function isListEmpty(list) {
	let flag = true;

	if (list && list.length > 0) {
		const filteredList = list.filter(item => item); // filtering empty (null/undefined) items here

		if (filteredList.length > 0) {
			flag = false;
		}
	}

	return flag;
}

function renderLoadContentButton(clickHandler) {
	return (
		<Button
			primary
			onClick={clickHandler}
			style={styles.loadContent}
		>
			Load Content Into Plugin
		</Button>
	);
}

function renderDownloadCardsAndLoadContentButton(downloads, loadContentClickHandler) {
	return (

			{renderLoadContentButton(loadContentClickHandler)}
			{renderDownloadCards(downloads)}

	);
}

function Downloads(props) {
	const {
		downloads,
		handleLoadContentClick
	} = props;

	return (
		<Grid.Column stretched width={4} style={styles.parent}>
			{
				isListEmpty(downloads)
					? renderNoDownloads()
					: renderDownloadCardsAndLoadContentButton(downloads, handleLoadContentClick)
			}
		</Grid.Column>
	);
}

export default Downloads;<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @noflow
 * @format
 */

'use strict';

var bin = require('./');
var spawn = require('child_process').spawn;

var input = process.argv.slice(2);

if (bin !== null) {
  spawn(bin, input, {stdio: 'inherit'}).on('exit', process.exit);
} else {
  throw new Error('Platform not supported.');
}
<commit_msg>Include platform and arch in the compiler error message<commit_after>#!/usr/bin/env node
/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @noflow
 * @format
 */

'use strict';

var bin = require('./');
var spawn = require('child_process').spawn;

var input = process.argv.slice(2);

if (bin !== null) {
  spawn(bin, input, {stdio: 'inherit'}).on('exit', process.exit);
} else {
  throw new Error(
    `Platform "${process.platform} (${process.arch})" not supported.`,
  );
}
<|endoftext|>


<commit_before>Package.describe({
  name: 'pntbr:youtube',
  version: '0.0.1',
  summary: 'Manage Youtube\'s videos',
  git: 'https://github.com/goacademie/fanhui',
  documentation: 'README.md'
})
Package.onUse(function(api) {
  api.versionsFrom('1.2.1')
  api.use(['ecmascript'])
  api.use(['iron:router', 'templating'], 'client')
  api.addFiles([
    'client/FO-youtube.html',
    'client/FO-player-vdo.html',
    'client/style.css',
    'client/router.js'
  ], 'client')
})
Package.onTest(function(api) {
  api.use(['ecmascript', 'tinytest', 'pntbr:youtube'])
  api.use(['iron:router@1.0.0', 'templating'], 'client')
})
<commit_msg>Fix delete unecessary file in package<commit_after>Package.describe({
  name: 'pntbr:youtube',
  version: '0.0.1',
  summary: 'Manage Youtube\'s videos',
  git: 'https://github.com/goacademie/fanhui',
  documentation: 'README.md'
})
Package.onUse(function(api) {
  api.versionsFrom('1.2.1')
  api.use(['ecmascript'])
  api.use(['iron:router', 'templating'], 'client')
  api.addFiles([
    'client/FO-player-vdo.html',
    'client/style.css',
    'client/router.js'
  ], 'client')
})
Package.onTest(function(api) {
  api.use(['ecmascript', 'tinytest', 'pntbr:youtube'])
  api.use(['iron:router@1.0.0', 'templating'], 'client')
})
<|endoftext|>


<commit_before>var superagent = require('superagent');
var expect = require('expect.js');
var mongodb = require('mongodb').MongoClient;

describe('activities rest api', function() {

  function cleanDatabase() {
    mongodb.connect('mongodb://localhost/journal', function(err, db) {
      var collection = db.collection('activities');
      collection.remove({});
    });
  }

  before(function() {
    cleanDatabase();
  });

  afterEach(function() {
    cleanDatabase();
  })

  it('can access the endpoint for loading activities', function(done) {
    superagent.get('http://localhost:8000/api/load')
      .end(function(error, response) {
        expect(error).to.equal(null);
        expect(response.status).to.equal(200);
        done();
      });
  });

  it('can access the endpoint for saving activities', function(done) {
    var expectedDate = 'January 15, 2015';
    var expectedActivities = [{
      name: 'Hyung',
      time: 15
    }];

    superagent.post('http://localhost:8000/api/save')
      .send({
        _id: expectedDate,
        activities: expectedActivities
      })
      .end(function(error, response) {
        expect(error).to.equal(null);
        expect(response.body._id).to.equal(expectedDate);
        expect(response.body.activities).to.eql(expectedActivities);
        done();
      });
  });

  it('can retrieve data from the database', function(done) {
    var expectedDate = 'January 15, 2015';
    var expectedActivities = [{
      name: 'Hyung',
      time: 15
    }];

    superagent.post('http://localhost:8000/api/save')
      .send({
        _id: expectedDate,
        activities: expectedActivities
      })
      .end(function(error, response) {
        expect(response.body._id).to.equal(expectedDate);
        expect(response.body.activities).to.eql(expectedActivities);
        done();
      });

    superagent.get('http://localhost:8000/api/load')
      .end(function(error, response) {
        expect(response.body.length).to.equal(1);
        expect(response.body[0]._id).to.equal(expectedDate);
        expect(response.body[0].activities).to.equal(expectedActivities);
        done();
      });
  });

  it('will update an existing record if the data was already posted on the same day', function(done) {
    var expectedDate = 'January 15, 2015';
    var originalActivities = [{
      name: 'Hyung',
      time: 15
    }];
    var updatedActivities = [{
      name: 'Hyung',
      time: 60
    }];

    superagent.post('http://localhost:8000/api/save')
      .send({
        _id: expectedDate,
        activities: originalActivities
      });

    superagent.post('http://localhost:8000/api/save')
      .send({
        _id: expectedDate,
        activities: updatedActivities
      })
      .end(function(error, response) {
        done();
      });

    superagent.get('http://localhost:8000/api/load')
      .end(function(error, response) {
        expect(response.body.length).to.equal(1);
        expect(response.body[0]._id).to.equal(expectedDate);
        expect(response.body[0].activities).to.equal(updatedActivities);
        done();
      });
  });

});
<commit_msg>Refactor urls out into constants<commit_after>var superagent = require('superagent');
var expect = require('expect.js');
var mongodb = require('mongodb').MongoClient;

var BASE_URL = 'http://localhost:8000/';
var LOAD_URL = BASE_URL + 'api/load';
var SAVE_URL = BASE_URL + 'api/save';

describe('activities rest api', function() {

  function cleanDatabase() {
    mongodb.connect('mongodb://localhost/journal', function(err, db) {
      var collection = db.collection('activities');
      collection.remove({});
    });
  }

  before(function() {
    cleanDatabase();
  });

  afterEach(function() {
    cleanDatabase();
  })

  it('can access the endpoint for loading activities', function(done) {
    superagent.get(LOAD_URL)
      .end(function(error, response) {
        expect(error).to.equal(null);
        expect(response.status).to.equal(200);
        done();
      });
  });

  it('can access the endpoint for saving activities', function(done) {
    var expectedDate = 'January 15, 2015';
    var expectedActivities = [{
      name: 'Hyung',
      time: 15
    }];

    superagent.post(SAVE_URL)
      .send({
        _id: expectedDate,
        activities: expectedActivities
      })
      .end(function(error, response) {
        expect(error).to.equal(null);
        expect(response.body._id).to.equal(expectedDate);
        expect(response.body.activities).to.eql(expectedActivities);
        done();
      });
  });

  it('can retrieve data from the database', function(done) {
    var expectedDate = 'January 15, 2015';
    var expectedActivities = [{
      name: 'Hyung',
      time: 15
    }];

    superagent.post(SAVE_URL)
      .send({
        _id: expectedDate,
        activities: expectedActivities
      })
      .end(function(error, response) {
        expect(response.body._id).to.equal(expectedDate);
        expect(response.body.activities).to.eql(expectedActivities);
        done();
      });

    superagent.get(LOAD_URL)
      .end(function(error, response) {
        expect(response.body.length).to.equal(1);
        expect(response.body[0]._id).to.equal(expectedDate);
        expect(response.body[0].activities).to.equal(expectedActivities);
        done();
      });
  });

  it('will update an existing record if the data was already posted on the same day', function(done) {
    var expectedDate = 'January 15, 2015';
    var originalActivities = [{
      name: 'Hyung',
      time: 15
    }];
    var updatedActivities = [{
      name: 'Hyung',
      time: 60
    }];

    superagent.post(SAVE_URL)
      .send({
        _id: expectedDate,
        activities: originalActivities
      });

    superagent.post(SAVE_URL)
      .send({
        _id: expectedDate,
        activities: updatedActivities
      })
      .end(function(error, response) {
        done();
      });

    superagent.get(LOAD_URL)
      .end(function(error, response) {
        expect(response.body.length).to.equal(1);
        expect(response.body[0]._id).to.equal(expectedDate);
        expect(response.body[0].activities).to.equal(updatedActivities);
        done();
      });
  });

});
<|endoftext|>


<commit_before>var superagent = require('superagent');
var expect = require('expect.js');

describe('activities rest api', function() {

  it('can access the endpoint for loading activities', function(done) {
    superagent.get('http://localhost:8000/api/load')
      .end(function(error, response) {
        expect(error).to.equal(null);
        expect(response.status).to.equal(200);
        done();
      });
  });

});
<commit_msg>Added rest test for saving activities<commit_after>var superagent = require('superagent');
var expect = require('expect.js');
var mongodb = require('mongodb').MongoClient;

describe('activities rest api', function() {

  function cleanDatabase() {
    mongodb.connect('mongodb://localhost/journal', function(err, db) {
      var collection = db.collection('activities');
      collection.remove({});
    });
  }

  before(function() {
    cleanDatabase();
  });

  afterEach(function() {
    cleanDatabase();
  })

  it('can access the endpoint for loading activities', function(done) {
    superagent.get('http://localhost:8000/api/load')
      .end(function(error, response) {
        expect(error).to.equal(null);
        expect(response.status).to.equal(200);
        done();
      });
  });

  it('can access the endpoint for saving activities', function(done) {
    var expectedDate = 'January 15, 2015';
    var expectedActivities = [{
      name: 'Hyung',
      time: 15
    }];

    superagent.post('http://localhost:8000/api/save')
      .send({
        _id: expectedDate,
        activities: expectedActivities
      })
      .end(function(error, response) {
        expect(error).to.equal(null);
        expect(response.body._id).to.equal(expectedDate);
        expect(response.body.activities).to.eql(expectedActivities);
        done();
      });
  });

});
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Rockit MediaKeys
// @namespace    https://github.com/gianlucaparadise/rockit-mediakeys/blob/master/rockit-mediakeys.user.js
// @version      0.1
// @description  Rende compatibile MediaKeys (http://sway.fm) con il player nelle recensioni di Rockit.it
// @author       Gianluca Paradiso
// @match        http://www.rockit.it/recensione/*
// @grant        none
// @require      https://s3.amazonaws.com/SwayFM/UnityShim.js
// ==/UserScript==

var enableLogging = true;

function logg(text) {
    if (enableLogging)
    {
        console.log(text);
    }
}

function play(track) {
    $(".play a", track).click();
}

var unity = UnityMusicShim();
unity.setSupports({
    playpause: true,
    next: true,
    previous: true
});
var playerState;

function sendState(isPlaying, thisTrack, artist, albumArt) {
    //logg("Invio stato. \nPlaying: " + isPlaying + "\nTitle: " + $(".title", thisTrack).text() + "\nArtist: " + artist);
    playerState = {
        playing: isPlaying,
        title: $(".title", thisTrack).text(),
        artist: artist,
        albumArt: albumArt,
    };
    unity.sendState(playerState);
}

$(function() {
    logg("Rockit MediaKeys caricato!");

    // Controllo se ho un solo player
    if ($(".elenco-brani.griglia").length < 1)
    {
        logg("Nessun Player trovato.");
        return;
    }

    if ($(".elenco-brani.griglia").length > 1)
    {
        logg("Trovato più di un player.");
        return;
    }

    var rockitPlayer = $(".elenco-brani.griglia");
    var track;

    var imgSrc = $(".box-disco .box-img img")[0].src;
    var artistName = $("a.nome-artista").eq(0).text();

    unity.setCallbackObject({
        pause: function() {
            track = $("li[itemprop=track].paused", rockitPlayer); // Cerco una traccia in pausa
            if (track.length > 0)
            {
                logg("Trovata traccia in pausa. Premo play.");

                sendState(true, track, artistName, imgSrc);
                play(track);
                return;
            }

            track = $("li[itemprop=track].playing", rockitPlayer); // Cerco una traccia in play
            if (track.length > 0)
            {
                logg("Trovata traccia in play. Premo pausa");

                sendState(false, track, artistName, imgSrc);
                play(track);
                return;
            }

            logg("Nessuna traccia in play trovata: riproduco la prima.");

            track = $("li[itemprop=track]", rockitPlayer).eq(0);
            // Cerco la prima traccia riproducibile
            while(track.find("li.play").hasClass("off"))
            {
                track = track.next();
                if (track.length === 0)
                {
                    logg("Nessuna traccia riproducibile trovata.");
                    return;
                }
            }

            sendState(true, track, artistName, imgSrc);
            play(track);
        },
        next: function() {
            track = $("li[itemprop=track].paused", rockitPlayer); // Cerco una traccia in pausa
            if (track.length === 0)
            {
                track = $("li[itemprop=track].playing", rockitPlayer); // Cerco una traccia in play

                if (track.length === 0)
                {
                    logg("Nessuna traccia attiva trovata.");
                    return;
                }
            }

            // Cerco la prima traccia riproducibile
            do
            {
                track = track.next();
                if (track.length === 0)
                {
                    logg("Sto riproducendo l'ultima traccia dell'album.");
                    return;
                }
            } while(track.find("li.play").hasClass("off"));

            logg("Riproduco la prossima traccia.");

            sendState(true, track, artistName, imgSrc);
            play(track);
        },
        previous:function() {
            track = $("li[itemprop=track].paused", rockitPlayer); // Cerco una traccia in pausa
            if (track.length === 0)
            {
                track = $("li[itemprop=track].playing", rockitPlayer); // Cerco una traccia in play

                if (track.length === 0)
                {
                    logg("Nessuna traccia attiva trovata.");
                    return;
                }
            }

            // Cerco la prima traccia riproducibile
            do
            {
                track = track.prev();
                if (track.length === 0)
                {
                    logg("Sto riproducendo la prima traccia dell'album.");
                    return;
                }
            } while(track.find("li.play").hasClass("off"));

            logg("Riproduco la traccia precedente.");

            sendState(true, track, artistName, imgSrc);
            play(track);
        }
    });

    // Creo l'observer per vedere quando viene cambiata la traccia
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
    var playerList = document.querySelector(".elenco-brani.griglia ul");

    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'attributes') {
                track = $(mutation.target);
                //logg("Mutazione! ");
                //logg(track);

                if (track.attr("itemprop") == "track" && track.hasClass("item"))
                {
                    logg("Una traccia ha cambiato stato!");
                    sendState(track.hasClass("playing"), track, artistName, imgSrc);
                }
            }
        });
    });

    observer.observe(playerList, {
        attributes: true,
        childList: false,
        characterData: false,
		subtree: true,
		attributeFilter: ['class']
    });

    // Mi serve fare il primo sendState a true altrimenti il plugin non parte
    sendState(true, [], artistName, imgSrc);
    sendState(false, [], artistName, imgSrc); // Faccio apparire album e artista.
});
<commit_msg>Implementate notifiche<commit_after>// ==UserScript==
// @name         Rockit MediaKeys
// @namespace    https://github.com/gianlucaparadise/rockit-mediakeys/blob/master/rockit-mediakeys.js
// @version      0.2
// @description  Rende compatibile MediaKeys (http://sway.fm) con il player nelle recensioni di Rockit.it
// @author       Gianluca Paradiso
// @match        http://www.rockit.it/recensione/*
// @grant        none
// @require      https://s3.amazonaws.com/SwayFM/UnityShim.js
// ==/UserScript==

var enableLogging = false;
var enableNotifications = true;

var imgSrc;

function showNotification(theBody, theTitle, theIcon) {
    var options = {
        body: theBody,
        icon: theIcon
    }

    var n = new Notification(theTitle,options);
    setTimeout(n.close.bind(n), 4000);
}

function notify(theBody, theTitle, theIcon) {
    if (!enableNotifications) return;

    // Preso da MDN: https://developer.mozilla.org/en-US/docs/Web/API/notification#Example
    // Let's check if the browser supports notifications
    if (!("Notification" in window)) {
        logg("This browser does not support desktop notification");
        return;
    }

    // Let's check whether notification permissions have already been granted
    if (Notification.permission === "granted") {
        // If it's okay let's create a notification
        showNotification(theBody, theTitle, theIcon);
    }

    // Otherwise, we need to ask the user for permission
    else if (Notification.permission !== 'denied') {
        Notification.requestPermission(function (permission) {
            // If the user accepts, let's create a notification
            if (permission === "granted") {
                showNotification(theBody, theTitle, theIcon);
            }
        });
    }

    // At last, if the user has denied notifications, and you
    // want to be respectful there is no need to bother them any more.
}

function logg(text) {
    if (enableLogging)
    {
        console.log(text);
    }
}

function play(track) {
    var message = $(".title", track).text();
    if (track.hasClass("playing")) message = "In pausa: " + message;
    else if (track.hasClass("paused")) message = "In riproduzione: " + message;

    $(".play a", track).click();

    logg(message);
    notify(message, 'Rockit MediaKeys', imgSrc);
}

var unity = UnityMusicShim();
unity.setSupports({
    playpause: true,
    next: true,
    previous: true
});
var playerState;

function sendState(isPlaying, thisTrack, artist, albumArt) {
    //logg("Invio stato. \nPlaying: " + isPlaying + "\nTitle: " + $(".title", thisTrack).text() + "\nArtist: " + artist);
    playerState = {
        playing: isPlaying,
        title: $(".title", thisTrack).text(),
        artist: artist,
        albumArt: albumArt,
    };
    unity.sendState(playerState);
}

$(function() {
    logg("Rockit MediaKeys caricato!");

    // Controllo se ho un solo player
    if ($(".elenco-brani.griglia").length < 1)
    {
        logg("Nessun Player trovato.");
        return;
    }

    if ($(".elenco-brani.griglia").length > 1)
    {
        logg("Trovato più di un player.");
        return;
    }

    var rockitPlayer = $(".elenco-brani.griglia");
    var track;

    imgSrc = $(".box-disco .box-img img")[0].src;
    var artistName = $("a.nome-artista").eq(0).text();

    unity.setCallbackObject({
        pause: function() {
            track = $("li[itemprop=track].paused", rockitPlayer); // Cerco una traccia in pausa
            if (track.length > 0)
            {
                logg("Trovata traccia in pausa. Premo play.");

                sendState(true, track, artistName, imgSrc);
                play(track);
                return;
            }

            track = $("li[itemprop=track].playing", rockitPlayer); // Cerco una traccia in play
            if (track.length > 0)
            {
                logg("Trovata traccia in play. Premo pausa");

                sendState(false, track, artistName, imgSrc);
                play(track);
                return;
            }

            logg("Nessuna traccia in play trovata: riproduco la prima.");

            track = $("li[itemprop=track]", rockitPlayer).eq(0);
            // Cerco la prima traccia riproducibile
            while(track.find("li.play").hasClass("off"))
            {
                track = track.next();
                if (track.length === 0)
                {
                    logg("Nessuna traccia riproducibile trovata.");
                    return;
                }
            }

            sendState(true, track, artistName, imgSrc);
            play(track);
        },
        next: function() {
            track = $("li[itemprop=track].paused", rockitPlayer); // Cerco una traccia in pausa
            if (track.length === 0)
            {
                track = $("li[itemprop=track].playing", rockitPlayer); // Cerco una traccia in play

                if (track.length === 0)
                {
                    logg("Nessuna traccia attiva trovata.");
                    return;
                }
            }

            // Cerco la prima traccia riproducibile
            do
            {
                track = track.next();
                if (track.length === 0)
                {
                    logg("Sto riproducendo l'ultima traccia dell'album.");
                    return;
                }
            } while(track.find("li.play").hasClass("off"));

            logg("Riproduco la prossima traccia.");

            sendState(true, track, artistName, imgSrc);
            play(track);
        },
        previous:function() {
            track = $("li[itemprop=track].paused", rockitPlayer); // Cerco una traccia in pausa
            if (track.length === 0)
            {
                track = $("li[itemprop=track].playing", rockitPlayer); // Cerco una traccia in play

                if (track.length === 0)
                {
                    logg("Nessuna traccia attiva trovata.");
                    return;
                }
            }

            // Cerco la prima traccia riproducibile
            do
            {
                track = track.prev();
                if (track.length === 0)
                {
                    logg("Sto riproducendo la prima traccia dell'album.");
                    return;
                }
            } while(track.find("li.play").hasClass("off"));

            logg("Riproduco la traccia precedente.");

            sendState(true, track, artistName, imgSrc);
            play(track);
        }
    });

    // Creo l'observer per vedere quando viene cambiata la traccia
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
    var playerList = document.querySelector(".elenco-brani.griglia ul");

    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'attributes') {
                track = $(mutation.target);
                //logg("Mutazione! ");
                //logg(track);

                if (track.attr("itemprop") == "track" && track.hasClass("item"))
                {
                    logg("Una traccia ha cambiato stato!");
                    sendState(track.hasClass("playing"), track, artistName, imgSrc);
                }
            }
        });
    });

    observer.observe(playerList, {
        attributes: true,
        childList: false,
        characterData: false,
		subtree: true,
		attributeFilter: ['class']
    });

    // Mi serve fare il primo sendState a true altrimenti il plugin non parte
    sendState(true, [], artistName, imgSrc);
    sendState(false, [], artistName, imgSrc); // Faccio apparire album e artista.
});
<|endoftext|>


<commit_before>module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  var params = {
    app: 'app',
    test: 'test',
    e2etests: 'e2e-tests',
    build: 'build',
    coverage: 'build/coverage',
    dist: 'build/dist',
    tmp: 'build/tmp'
  };

  // Project configuration.
  grunt.initConfig({
    params: params,
    pkg: grunt.file.readJSON('package.json'),

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= params.app %>/{,*/}{,*/}{,*/}{,*/}!(*.spec|e2e)+(.js)',
          '<%= params.app %>/{,*/}{,*/}{,*/}{,*/}*.html',
          '<%= params.tmp %>/styles/{,*/}*.css',
          '<%= params.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}']
      },
      styles: {
        files: ['<%= params.app %>/styles/{,*/}*.less'],
        tasks: ['less', 'newer:copy:styles', 'autoprefixer'],
        options: {
          livereload: '<%= connect.options.livereload %>'
        }
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: grunt.option('serverPort') || 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: grunt.option('livereloadPort') || 35729
      },
      proxies: [{
        context: '/resume-hal', // the context of the data service
        host: 'localhost', // wherever the data service is running
        port: 18080 // the port that the data service is running on
      }],
      livereload: {
        options: {
          open: true,
          middleware: function (connect) {
            return [
              require('grunt-connect-proxy/lib/utils').proxyRequest,
              connect.static(params.tmp),
              connect().use('/bower_components', connect.static('./bower_components')),
              connect.static(params.app)];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              connect.static('build/tmp'),
              connect.static('test'),
              connect().use('/bower_components', connect.static('./bower_components')),
              connect.static(params.app)];
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= params.dist %>'
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      prod: {
        src: [
          'Gruntfile.js',
          '<%= params.app %>/**/!(*.spec|*.e2e|*.mock)+(.js)']
      },
      test: {
        options: {
          jshintrc: 'test.jshintrc'
        },
        src: [
          '<%= params.app %>/**/*.spec.js',
          '<%= params.app %>/**/*.mock.js',
          '<%= params.app %>/**/*.e2e.js']
      }
    },

    // Empties folders to start fresh
    clean: {
      build: ['<%= params.build %>'],
      server: '<%= params.tmp %>',
      release: 'build'
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= params.tmp %>/styles/',
          src: '{,*/}*.css',
          dest: '<%= params.tmp %>/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    wiredep: {
      app: {
        src: ['<%= params.app %>/index.html'],
        ignorePath: /\.\.\//
      }
    },

    // Renames files for browser caching purposes
    filerev: {
      dist: {
        src: [
          '<%= params.dist %>/scripts/{,*/}*.js',
          '<%= params.dist %>/styles/{,*/}*.css',
          '<%= params.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= params.dist %>/styles/fonts/*']
      }
    },

    useminPrepare: {
      options: {
        dest: '<%= params.dist %>',
        staging: '<%= params.tmp %>',
        flow: {
          dev: {
            steps: {
              js: ['concat'],
              css: ['cssmin']
            },
            post: {}
          },
          prod: {
            steps: {
              js: ['concat', 'uglifyjs'],
              css: ['cssmin']
            },
            post: {}
          }
        }
      },
      prod: {
        src: '<%= params.app %>/index.html'
      },
      dev: {
        src: '<%= params.app %>/index.html'
      }
    },

    // Performs rewrites based on filerev and the useminPrepare configuration
    usemin: {
      html: ['<%= params.dist %>/{,*/}*.html'],
      css: ['<%= params.dist %>/styles/{,*/}*.css'],
      options: {
        assetsDirs: ['<%= params.dist %>', '<%= params.dist %>/images']
      }
    },

    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= params.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= params.dist %>/images'
        }]
      }
    },

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= params.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= params.dist %>/images'
        }]
      }
    },

    ngAnnotate: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= params.tmp %>/concat/scripts',
          src: '*.js',
          dest: '<%= params.tmp %>/concat/scripts'
        }]
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= params.app %>',
          dest: '<%= params.dist %>',
          src: [
            '*.html',
            'images/{,*/}*.{webp}',
            'fonts/*']
        }, {
          expand: true,
          cwd: '<%= params.tmp %>/images',
          dest: '<%= params.dist %>/images',
          src: ['generated/*']
        }]
      },
      js: {
        expand: true,
        cwd: '<%= params.tmp %>/concat/scripts/',
        dest: '<%= params.dist %>/scripts/',
        src: '{,*/}*.js'
      },
      templates: {
        expand: true,
        cwd: '<%= params.tmp %>',
        dest: '<%= params.dist %>/scripts/',
        src: '{,*/}templates.js'
      },
      styles: {
        expand: true,
        cwd: '<%= params.app %>/styles',
        dest: '<%= params.tmp %>/styles/',
        src: '{,*/}*.css'
      },
      lcov: {
        expand: false,
        src: '<%= params.coverage %>/*/lcov.info',
        dest: '<%= params.coverage %>/lcov.info'
      }
    },

    concurrent: {
      server: ['copy:styles'],
      test: ['copy:styles'],
      dist: [
        'copy:styles',
        'imagemin',
        'svgmin']
    },

    'code-coverage-enforcer': {
      options: {
        lcovfile: '<%= params.coverage %>/lcov.info',
        lines: 95,
        functions: 95,
        branches: 95,
        src: '<%= params.app %>',
        includes: ['<%= params.app %>/**/*.js'],
        excludes: [
          '<%= params.app %>/**/*.mock.js',
          '<%= params.app %>/**/*.e2e.js',
          '<%= params.app %>/**/*.spec.js']
      }
    },

    // Test settings
    karma: {
      unit: {
        configFile: 'karma.conf.js',
        singleRun: true
      }
    },

    protractor: {
      options: {
        configFile: '<%= params.e2etests %>/protractor.conf.js',
        keepAlive: true
      },
      run: {},
      debug: {
        options: {
          debug: true
        }
      }
    },

    ngtemplates: {
      // name myApp, must match the top-level module name.
      myApp: {
        cwd: '<%= params.app %>',
        src: '{,*/}{,*/}{,*/}*.html',
        dest: '<%= params.tmp %>/templates.js',
        options: {
          htmlmin: {
            collapseBooleanAttributes: true,
            collapseWhitespace: true,
            removeAttributeQuotes: true,
            removeComments: true, // Only if you don't use comment directives!
            removeEmptyAttributes: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true
          }
        }
      }
    },

    compress: {
      main: {
        options: {
          archive: '<%= params.build %>/zip/<%= pkg.name %>-<%= pkg.version %>.zip'
        },
        files: [
          {expand: true, cwd: '<%= params.dist %>', src: ['scripts/*'], ext: '-<%= pkg.version %>.js'},
          {expand: true, cwd: '<%= params.dist %>', src: ['styles/*'], ext: '-<%= pkg.version %>.css'},
          {expand: true, cwd: '<%= params.dist %>', src: ['fonts/*']}
        ]
      }
    },

    less: {
      development: {
        options: {},
        files: {
          'build/tmp/styles/app.css': 'app/styles/app.less'
        }
      }
    },

    bower: {
      install: {
        options: {
          cleanup: false,
          copy: false,
          verbose: true
        }
      }
    },

    htmlangular: {
      files: {
        src: ['<%= params.app %>/**/*.html', '!<%= params.app %>/index.html']
      },
      options: {
        customattrs: [
          'msd-elastic'
        ],
        customtags: [],
        reportpath: 'build/html-angular-validate-report.json',
        tmplext: 'html'
      }
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // Default task(s).
  grunt.registerTask('default', ['uglify']);

  grunt.registerTask('validate', ['test', 'jshint', 'force:htmlangular']);

  grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'less',
      'wiredep',
      'concurrent:server',
      'autoprefixer',
      'configureProxies:server',
      'connect:livereload',
      'watch']);
  });

  grunt.registerTask('test', [
    'clean:server',
    'concurrent:test',
    'autoprefixer',
    'connect:test',
    'karma',
    'copy:lcov',
    'code-coverage-enforcer']);

  grunt.registerTask('build', [
    'clean:build',
    'less',
    'wiredep',
    'useminPrepare:prod',
    'ngtemplates',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'copy:templates',
    'cssmin',
    'uglify',
    'filerev',
    'usemin']);

  grunt.registerTask('buildDev', [
    'clean:build',
    'less',
    'wiredep',
    'useminPrepare:dev',
    'ngtemplates',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'copy:templates',
    'copy:js',
    'cssmin',
    'filerev',
    'usemin']);

  grunt.registerTask('default', [
    'newer:jshint',
    'test',
    'build']);

};
<commit_msg>do not include template html files html files in the root folder are not templates.<commit_after>module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  var params = {
    app: 'app',
    test: 'test',
    e2etests: 'e2e-tests',
    build: 'build',
    coverage: 'build/coverage',
    dist: 'build/dist',
    tmp: 'build/tmp'
  };

  // Project configuration.
  grunt.initConfig({
    params: params,
    pkg: grunt.file.readJSON('package.json'),

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= params.app %>/{,*/}{,*/}{,*/}{,*/}!(*.spec|e2e)+(.js)',
          '<%= params.app %>/{,*/}{,*/}{,*/}{,*/}*.html',
          '<%= params.tmp %>/styles/{,*/}*.css',
          '<%= params.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}']
      },
      styles: {
        files: ['<%= params.app %>/styles/{,*/}*.less'],
        tasks: ['less', 'newer:copy:styles', 'autoprefixer'],
        options: {
          livereload: '<%= connect.options.livereload %>'
        }
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: grunt.option('serverPort') || 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: grunt.option('livereloadPort') || 35729
      },
      proxies: [{
        context: '/resume-hal', // the context of the data service
        host: 'localhost', // wherever the data service is running
        port: 18080 // the port that the data service is running on
      }],
      livereload: {
        options: {
          open: true,
          middleware: function (connect) {
            return [
              require('grunt-connect-proxy/lib/utils').proxyRequest,
              connect.static(params.tmp),
              connect().use('/bower_components', connect.static('./bower_components')),
              connect.static(params.app)];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              connect.static('build/tmp'),
              connect.static('test'),
              connect().use('/bower_components', connect.static('./bower_components')),
              connect.static(params.app)];
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= params.dist %>'
        }
      }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      prod: {
        src: [
          'Gruntfile.js',
          '<%= params.app %>/**/!(*.spec|*.e2e|*.mock)+(.js)']
      },
      test: {
        options: {
          jshintrc: 'test.jshintrc'
        },
        src: [
          '<%= params.app %>/**/*.spec.js',
          '<%= params.app %>/**/*.mock.js',
          '<%= params.app %>/**/*.e2e.js']
      }
    },

    // Empties folders to start fresh
    clean: {
      build: ['<%= params.build %>'],
      server: '<%= params.tmp %>',
      release: 'build'
    },

    // Add vendor prefixed styles
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= params.tmp %>/styles/',
          src: '{,*/}*.css',
          dest: '<%= params.tmp %>/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    wiredep: {
      app: {
        src: ['<%= params.app %>/index.html'],
        ignorePath: /\.\.\//
      }
    },

    // Renames files for browser caching purposes
    filerev: {
      dist: {
        src: [
          '<%= params.dist %>/scripts/{,*/}*.js',
          '<%= params.dist %>/styles/{,*/}*.css',
          '<%= params.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '<%= params.dist %>/styles/fonts/*']
      }
    },

    useminPrepare: {
      options: {
        dest: '<%= params.dist %>',
        staging: '<%= params.tmp %>',
        flow: {
          dev: {
            steps: {
              js: ['concat'],
              css: ['cssmin']
            },
            post: {}
          },
          prod: {
            steps: {
              js: ['concat', 'uglifyjs'],
              css: ['cssmin']
            },
            post: {}
          }
        }
      },
      prod: {
        src: '<%= params.app %>/index.html'
      },
      dev: {
        src: '<%= params.app %>/index.html'
      }
    },

    // Performs rewrites based on filerev and the useminPrepare configuration
    usemin: {
      html: ['<%= params.dist %>/{,*/}*.html'],
      css: ['<%= params.dist %>/styles/{,*/}*.css'],
      options: {
        assetsDirs: ['<%= params.dist %>', '<%= params.dist %>/images']
      }
    },

    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= params.app %>/images',
          src: '{,*/}*.{png,jpg,jpeg,gif}',
          dest: '<%= params.dist %>/images'
        }]
      }
    },

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= params.app %>/images',
          src: '{,*/}*.svg',
          dest: '<%= params.dist %>/images'
        }]
      }
    },

    ngAnnotate: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= params.tmp %>/concat/scripts',
          src: '*.js',
          dest: '<%= params.tmp %>/concat/scripts'
        }]
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= params.app %>',
          dest: '<%= params.dist %>',
          src: [
            '*.html',
            'images/{,*/}*.{webp}',
            'fonts/*']
        }, {
          expand: true,
          cwd: '<%= params.tmp %>/images',
          dest: '<%= params.dist %>/images',
          src: ['generated/*']
        }]
      },
      js: {
        expand: true,
        cwd: '<%= params.tmp %>/concat/scripts/',
        dest: '<%= params.dist %>/scripts/',
        src: '{,*/}*.js'
      },
      templates: {
        expand: true,
        cwd: '<%= params.tmp %>',
        dest: '<%= params.dist %>/scripts/',
        src: '{,*/}templates.js'
      },
      styles: {
        expand: true,
        cwd: '<%= params.app %>/styles',
        dest: '<%= params.tmp %>/styles/',
        src: '{,*/}*.css'
      },
      lcov: {
        expand: false,
        src: '<%= params.coverage %>/*/lcov.info',
        dest: '<%= params.coverage %>/lcov.info'
      }
    },

    concurrent: {
      server: ['copy:styles'],
      test: ['copy:styles'],
      dist: [
        'copy:styles',
        'imagemin',
        'svgmin']
    },

    'code-coverage-enforcer': {
      options: {
        lcovfile: '<%= params.coverage %>/lcov.info',
        lines: 95,
        functions: 95,
        branches: 95,
        src: '<%= params.app %>',
        includes: ['<%= params.app %>/**/*.js'],
        excludes: [
          '<%= params.app %>/**/*.mock.js',
          '<%= params.app %>/**/*.e2e.js',
          '<%= params.app %>/**/*.spec.js']
      }
    },

    // Test settings
    karma: {
      unit: {
        configFile: 'karma.conf.js',
        singleRun: true
      }
    },

    protractor: {
      options: {
        configFile: '<%= params.e2etests %>/protractor.conf.js',
        keepAlive: true
      },
      run: {},
      debug: {
        options: {
          debug: true
        }
      }
    },

    ngtemplates: {
      // name myApp, must match the top-level module name.
      myApp: {
        cwd: '<%= params.app %>',
        src: '*/{,*/}{,*/}*.html',
        dest: '<%= params.tmp %>/templates.js',
        options: {
          htmlmin: {
            collapseBooleanAttributes: true,
            collapseWhitespace: true,
            removeAttributeQuotes: true,
            removeComments: true, // Only if you don't use comment directives!
            removeEmptyAttributes: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true
          }
        }
      }
    },

    compress: {
      main: {
        options: {
          archive: '<%= params.build %>/zip/<%= pkg.name %>-<%= pkg.version %>.zip'
        },
        files: [
          {expand: true, cwd: '<%= params.dist %>', src: ['scripts/*'], ext: '-<%= pkg.version %>.js'},
          {expand: true, cwd: '<%= params.dist %>', src: ['styles/*'], ext: '-<%= pkg.version %>.css'},
          {expand: true, cwd: '<%= params.dist %>', src: ['fonts/*']}
        ]
      }
    },

    less: {
      development: {
        options: {},
        files: {
          'build/tmp/styles/app.css': 'app/styles/app.less'
        }
      }
    },

    bower: {
      install: {
        options: {
          cleanup: false,
          copy: false,
          verbose: true
        }
      }
    },

    htmlangular: {
      files: {
        src: ['<%= params.app %>/**/*.html', '!<%= params.app %>/index.html']
      },
      options: {
        customattrs: [
          'msd-elastic'
        ],
        customtags: [],
        reportpath: 'build/html-angular-validate-report.json',
        tmplext: 'html'
      }
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // Default task(s).
  grunt.registerTask('default', ['uglify']);

  grunt.registerTask('validate', ['test', 'jshint', 'force:htmlangular']);

  grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'less',
      'wiredep',
      'concurrent:server',
      'autoprefixer',
      'configureProxies:server',
      'connect:livereload',
      'watch']);
  });

  grunt.registerTask('test', [
    'clean:server',
    'concurrent:test',
    'autoprefixer',
    'connect:test',
    'karma',
    'copy:lcov',
    'code-coverage-enforcer']);

  grunt.registerTask('build', [
    'clean:build',
    'less',
    'wiredep',
    'useminPrepare:prod',
    'ngtemplates',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'copy:templates',
    'cssmin',
    'uglify',
    'filerev',
    'usemin']);

  grunt.registerTask('buildDev', [
    'clean:build',
    'less',
    'wiredep',
    'useminPrepare:dev',
    'ngtemplates',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'copy:templates',
    'copy:js',
    'cssmin',
    'filerev',
    'usemin']);

  grunt.registerTask('default', [
    'newer:jshint',
    'test',
    'build']);

};
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { Link } from 'react-router'

import './SetupCompletion.css'

class SetupCompletion extends Component {
  render() {
    return (

You're all set

Your smart home is now ready to use

        <Link to="setup/tutorial">Watch tutorial</Link>

    );
  }
}

export default SetupCompletion
<commit_msg>Call on-boarding finalization endpoint<commit_after>import React, { Component } from 'react'
import { Link } from 'react-router'

import './SetupCompletion.css'

class SetupCompletion extends Component {
  render() {
    return (

You're all set

Your smart home is now ready to use

        <Link to="setup/tutorial">Watch tutorial</Link>

    );
  }

  componentDidMount() {
    fetch('/-/setup/config', {method: 'POST'})
  }
}

export default SetupCompletion
<|endoftext|>


<commit_before>var AprilApril = function(options){

    if(typeof options === 'object'){
        this.effects = {};
        for(var effect in options){
            if(options[effect] && this.effectTypes[effect]){
                this.effects[effect] = options[effect];
            }
        }
    }else{
        if(options in this.effectTypes){
            this.effect = options;
        }else{
            throw new Error('Effect name not recognized.');
        }
    }

};

AprilApril.prototype.effectTypes = {

    /**
     *   When the user's not looking, swap words around.
     */
    scrambleText: function(){
        var DELAY = 1000,
            paragraphs = [].slice.call(document.querySelectorAll('p'));

        var scrambler = function(){
            var randomParagraph = paragraphs[Math.round(Math.random() * (paragraphs.length - 1))],
            randomParagraphWords = randomParagraph.textContent.split(/\s/);

            if(!isElementInViewport(randomParagraph)){
                randomParagraph.textContent = switchRandomElements(randomParagraphWords).join(' ');
            }
        };

        var switchRandomElements = function(array){
            var firstRandomIndex = Math.round(Math.random() * (array.length - 1)),
            SecondRandomIndex = Math.round(Math.random() * (array.length - 1)),
            temp = array[firstRandomIndex];

            array[firstRandomIndex] = array[SecondRandomIndex];
            array[SecondRandomIndex] = temp;

            return array;
        };

        var isElementInViewport = function(el) {
            var rect = el.getBoundingClientRect();

            return (
                rect.top >= 0 &&
                rect.left >= 0 &&
                rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
                rect.right <= (window.innerWidth || document.documentElement.clientWidth)
                );
        };

        setInterval(scrambler, DELAY);
    },

    /**
     *   Grab all links on a page (that actually go somewhere) and swap their hrefs around.
     */
    scrambleLinks: function(){
        var links = [].slice.call(document.links),
            hrefs = [];

        var getRandomElement = function(array){
            var randomIndex = Math.round((Math.random() * (array.length - 1))),
            elementToReturn = array[randomIndex];

            array.splice(randomIndex, 1); //Gotta remove the element returned.

            return elementToReturn;
        };

        //Get all links from the page with an actual URL
        for(var i = 0, max = links.length; i < max; i++){
            var href = links[i].href;

            if(href !== window.location.href + '#' && href.match(/http/)){
                hrefs.push(href);
            }
        }

        //Set a new href for all links with an actual URL
        for(var i = 0, max = links.length; i < max; i++){
            var href = links[i].href;

            if(href !== window.location.href + '#' && href.match(/http/)){
                links[i].href = getRandomElement(hrefs);
            }
        }
    },

    /**
     *   Shrink the body element to 70% over the course of 30 minutes.
     */
    shrink: function(){
        var body = document.body,
            DURATION = '3600s',
            animPrefixes = ['webkitAnimation', 'MozAnimation', 'OAnimation', 'MSAnimation', 'animation'],
            keyframeRule = '@-webkit-keyframes shrink {100%{-webkit-transform: scale(.7);}}@-moz-keyframes shrink {100%{-moz-transform: scale(.7);}}@-o-keyframes shrink {100%{-o-transform: scale(.7);}}@keyframes shrink {100%{transform: scale(.7);}}';

        var injectCSS = function(css){
                var style = document.createElement('style');

                style.type = 'text/css';
                style.appendChild(document.createTextNode(css));
                document.getElementsByTagName('head')[0].appendChild(style);
        };

        injectCSS(keyframeRule);

        for(var i = 0; i < animPrefixes.length; i++){
            if([animPrefixes[i] + 'Duration'] in body.style){
                body.style[animPrefixes[i] + 'Duration'] = DURATION;
                body.style[animPrefixes[i] + 'FillMode'] = 'forwards';
                body.style[animPrefixes[i] + 'Name'] = 'shrink';
            }
        }
    },

    /**
     *   Replace all images on the page with random ones featuring kittens and Bill Murray.
     */
    replaceImages: function(){
        var images = document.querySelectorAll('img'),
            newImageBaseURLs = [
                'http://placekitten.com/',
                'http://www.fillmurray.com/',
                'http://www.nicenicejpg.com/',
                'http://www.placecage.com/',
                'http://www.stevensegallery.com/'];

        for(var i = 0, max = images.length; i < max; i++){
            var image  = images[i],
                width  = image.naturalWidth || image.clientWidth,
                height = image.naturalHeight || image.clientHeight;

            image.src = newImageBaseURLs[Math.round(Math.random() * (newImageBaseURLs.length - 1))] + width + '/' + height;
        }
    },

    sayPlease: function(){
        var links = [].slice.call(document.links),
            prompts = ['Say please.', 'My goodness, where are your manners? Say please.', 'Just say please. I can do this all day.', 'You\'re really not going to say it, are you?', 'OK, now you\'re just testing how many of these there are.', 'This is the last one. Say please.'],
            count = 0;

        for(var i = 0, max = links.length; i < max; i++){
            var link = links[i];

            link.addEventListener('click', function(e){
                e.preventDefault();

                var response = window.prompt(prompts[count]);

                if(response && response.toLowerCase() === 'please'){
                    window.location = this.href;
                }else{
                    if(count < prompts.length - 1){
                        count++;
                    }else{
                        count = 0;
                    }
                }

            }, false);
        }
    }
};

AprilApril.prototype.applyEffect = function(effect){
    this.effectTypes[effect].call();
};

AprilApril.prototype.fool = function(){
    if(this.effects){
        for(var effect in this.effects){
            this.applyEffect(effect);
        }
    }else{
        this.applyEffect(this.effect);
    }
};

<commit_msg>Missing tab<commit_after>var AprilApril = function(options){

    if(typeof options === 'object'){
        this.effects = {};
        for(var effect in options){
            if(options[effect] && this.effectTypes[effect]){
                this.effects[effect] = options[effect];
            }
        }
    }else{
        if(options in this.effectTypes){
            this.effect = options;
        }else{
            throw new Error('Effect name not recognized.');
        }
    }

};

AprilApril.prototype.effectTypes = {

    /**
     *   When the user's not looking, swap words around.
     */
    scrambleText: function(){
        var DELAY = 1000,
            paragraphs = [].slice.call(document.querySelectorAll('p'));

        var scrambler = function(){
            var randomParagraph = paragraphs[Math.round(Math.random() * (paragraphs.length - 1))],
                randomParagraphWords = randomParagraph.textContent.split(/\s/);

            if(!isElementInViewport(randomParagraph)){
                randomParagraph.textContent = switchRandomElements(randomParagraphWords).join(' ');
            }
        };

        var switchRandomElements = function(array){
            var firstRandomIndex = Math.round(Math.random() * (array.length - 1)),
            SecondRandomIndex = Math.round(Math.random() * (array.length - 1)),
            temp = array[firstRandomIndex];

            array[firstRandomIndex] = array[SecondRandomIndex];
            array[SecondRandomIndex] = temp;

            return array;
        };

        var isElementInViewport = function(el) {
            var rect = el.getBoundingClientRect();

            return (
                rect.top >= 0 &&
                rect.left >= 0 &&
                rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
                rect.right <= (window.innerWidth || document.documentElement.clientWidth)
                );
        };

        setInterval(scrambler, DELAY);
    },

    /**
     *   Grab all links on a page (that actually go somewhere) and swap their hrefs around.
     */
    scrambleLinks: function(){
        var links = [].slice.call(document.links),
            hrefs = [];

        var getRandomElement = function(array){
            var randomIndex = Math.round((Math.random() * (array.length - 1))),
            elementToReturn = array[randomIndex];

            array.splice(randomIndex, 1); //Gotta remove the element returned.

            return elementToReturn;
        };

        //Get all links from the page with an actual URL
        for(var i = 0, max = links.length; i < max; i++){
            var href = links[i].href;

            if(href !== window.location.href + '#' && href.match(/http/)){
                hrefs.push(href);
            }
        }

        //Set a new href for all links with an actual URL
        for(var i = 0, max = links.length; i < max; i++){
            var href = links[i].href;

            if(href !== window.location.href + '#' && href.match(/http/)){
                links[i].href = getRandomElement(hrefs);
            }
        }
    },

    /**
     *   Shrink the body element to 70% over the course of 30 minutes.
     */
    shrink: function(){
        var body = document.body,
            DURATION = '3600s',
            animPrefixes = ['webkitAnimation', 'MozAnimation', 'OAnimation', 'MSAnimation', 'animation'],
            keyframeRule = '@-webkit-keyframes shrink {100%{-webkit-transform: scale(.7);}}@-moz-keyframes shrink {100%{-moz-transform: scale(.7);}}@-o-keyframes shrink {100%{-o-transform: scale(.7);}}@keyframes shrink {100%{transform: scale(.7);}}';

        var injectCSS = function(css){
                var style = document.createElement('style');

                style.type = 'text/css';
                style.appendChild(document.createTextNode(css));
                document.getElementsByTagName('head')[0].appendChild(style);
        };

        injectCSS(keyframeRule);

        for(var i = 0; i < animPrefixes.length; i++){
            if([animPrefixes[i] + 'Duration'] in body.style){
                body.style[animPrefixes[i] + 'Duration'] = DURATION;
                body.style[animPrefixes[i] + 'FillMode'] = 'forwards';
                body.style[animPrefixes[i] + 'Name'] = 'shrink';
            }
        }
    },

    /**
     *   Replace all images on the page with random ones featuring kittens and Bill Murray.
     */
    replaceImages: function(){
        var images = document.querySelectorAll('img'),
            newImageBaseURLs = [
                'http://placekitten.com/',
                'http://www.fillmurray.com/',
                'http://www.nicenicejpg.com/',
                'http://www.placecage.com/',
                'http://www.stevensegallery.com/'];

        for(var i = 0, max = images.length; i < max; i++){
            var image  = images[i],
                width  = image.naturalWidth || image.clientWidth,
                height = image.naturalHeight || image.clientHeight;

            image.src = newImageBaseURLs[Math.round(Math.random() * (newImageBaseURLs.length - 1))] + width + '/' + height;
        }
    },

    sayPlease: function(){
        var links = [].slice.call(document.links),
            prompts = ['Say please.', 'My goodness, where are your manners? Say please.', 'Just say please. I can do this all day.', 'You\'re really not going to say it, are you?', 'OK, now you\'re just testing how many of these there are.', 'This is the last one. Say please.'],
            count = 0;

        for(var i = 0, max = links.length; i < max; i++){
            var link = links[i];

            link.addEventListener('click', function(e){
                e.preventDefault();

                var response = window.prompt(prompts[count]);

                if(response && response.toLowerCase() === 'please'){
                    window.location = this.href;
                }else{
                    if(count < prompts.length - 1){
                        count++;
                    }else{
                        count = 0;
                    }
                }

            }, false);
        }
    }
};

AprilApril.prototype.applyEffect = function(effect){
    this.effectTypes[effect].call();
};

AprilApril.prototype.fool = function(){
    if(this.effects){
        for(var effect in this.effects){
            this.applyEffect(effect);
        }
    }else{
        this.applyEffect(this.effect);
    }
};

<|endoftext|>