<commit_before>////////////////////////////////////////////////////
//                   Imports
////////////////////////////////////////////////////
var PromiseThrottle = require('promise-throttle');
var parseXML = require('xml2js').parseString;
var querystring = require('querystring');
var CryptoJS = require('crypto-js');
var Promise = require('promise');
const https = require('https');
var _ = require('lodash');

var PRODUCTION = 'mechanicalturk.amazonaws.com';
var SANDBOX = 'mechanicalturk.sandbox.amazonaws.com';
var SERVICE = 'AWSMechanicalTurkRequester';
var VERSION = '2014-08-15';
var METHOD = 'POST';

var specialResponses = {};
specialResponses['CreateQualificationType'] = 'QualificationType';
specialResponses['CreateHIT'] = 'HIT';
specialResponses['GetHIT'] = 'HIT';

//Legacy support
var npmPackageVersion = 2; //Latest by default

var promiseThrottle = new PromiseThrottle({
    requestsPerSecond: 3,           // up to 1 request per second
    promiseImplementation: Promise  // the Promise library you are using
});

function MTurkAPI() {

    var api = this;

    //Legacy support for V1 methods (temporary)
    api.connect = function(options){
        return new Promise(function(resolve, reject){
            var client = api.createClient(options);
            var error = new Error('Could not initialize client. Please notify the mantainer (ERR1-3-5L)');
            if(client){
                resolve(client);
                npmPackageVersion = 1;
            } else { reject(error); }
        })
    };

    api.createClient = function(options) {

        var client = {};
        // add some items to the queue
        client.req = function (operation, params) {
            return new Promise(function(resolve, reject){
                promiseThrottle.add(throttledRequest.bind(this, client, options, operation, params))
                .then(resolve)
                .catch(reject);
            })
        };

        //TODO: Improve method by using JSON schemas
        //      for error checking

        //Checks for two types of errors:
        //OPERATION ERR: (wrong API keys, etc) which are located in the OPERATION response group
        //RESULTS ERR: (wrong params, etc) which are located in the RESULT response group
        client.isValidResponse = function(response){
            var result = {};
            result.errorType =  [];
            result.errorMessage = null;
            result.isValid = null;

            var responseKey = Object.keys(response)[0];
            var charIndex = responseKey.indexOf("Response");
            var operationName = responseKey.slice(0, charIndex)

            //OPERATION ERROR CHECK
            var responseProperty = operationName + 'Response';
            var hasResponse = response.hasOwnProperty(responseProperty);
            var responseGroup = hasResponse? response[operationName + 'Response'] : null;
            var operationRequest = responseGroup? responseGroup.OperationRequest[0] : null;
            var operationErrors = operationRequest? operationRequest.hasOwnProperty('Errors') : null;
            var operationError = operationErrors? true : false;
            var error = operationError? operationRequest.Errors[0].Error[0]: null;
            var errCode = error? error.Code[0] : '';
            var errMsg = error? error.Message[0] : '';
            var errKey = error && error.hasOwnProperty('Data')? error.Data[0].Key : '';
            var errVal = error && error.hasOwnProperty('Data')? error.Data[0].Value : '';
            var errData = errKey && errVal? errKey +': '+errVal : '';
            result.errorMessage = error? errCode +' - '+ errMsg + ' - '+ errData: '';
            result.isValid = error? false : true;
            if(error){return result}

            //RESULT ERROR CHECK
            var specialCase = specialResponses.hasOwnProperty(operationName);
            var resultProperty = specialCase ? specialResponses[operationName] : operationName + 'Result';
            var hasResult = responseGroup.hasOwnProperty(resultProperty);
            var requestResult = hasResult? responseGroup[resultProperty][0].Request[0] : null;
            var hasValidity = requestResult? requestResult.hasOwnProperty('IsValid'): null;
            var validResult = hasValidity? requestResult.IsValid[0] === 'True': false;
            var resultError = hasResult && !validResult;
            var error = resultError? requestResult.Errors[0].Error[0]: null;
            var errCode = error? error.Code[0] : '';
            var errMsg = error? error.Message[0] : '';
            var errKey = error && error.hasOwnProperty('Data')? error.Data[0].Key : '';
            var errVal = error && error.hasOwnProperty('Data')? error.Data[0].Value : '';
            var errData = errKey && errVal? errKey +': '+errVal : '';
            result.errorMessage = error? errCode +' - '+ errMsg + ' - '+ errData : '';
            result.isValid = error? false : true;

            //Returns object
            // with various props
            // isValid, errMessage, etc
            return result;
        }

        return client;
    }

    return api;
}

function restify(params){
    _.forOwn(params, function(value, key, obj) {

        if(_.isArray(value)){
            _.forEach(value, function(item, index){
                _.forEach(item, function(value, subkey){
                    params[key+'.'+index+'.'+subkey] = value;
                });
            });
        }

        if(_.isPlainObject(value)){
            var subkeys = _.keys(value);
            _.forEach(subkeys, function(subkey){
                var path = key +'.1.'+subkey;
                params[path] = value[subkey];
            })
        }
    });
    return params;
}

function throttledRequest(client, options, operation, params){
    var params = params || {};
    params = restify(params);
    params.RequestGroup = params.RequestGroup || 'Request, Minimal';
    params.Operation = operation;
    params.Version = VERSION;

    return new Promise(function(resolve, reject){
        var signedRequest = signRequest(options, params);
        signedRequest = querystring.stringify(signedRequest);
        var payloadSize = Buffer.byteLength(signedRequest);

        var reqOptions = {};
        reqOptions.host = options.sandbox? SANDBOX : PRODUCTION;
        reqOptions.method= METHOD;
        reqOptions.headers = {};
        reqOptions.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        reqOptions.headers['Content-Length'] = payloadSize;

        var req = https.request(reqOptions, function(res) {

            if(res.statusCode !== 200){
                var error = new Error(res.statusCode +' - '+ res.statusMessage)
                reject(error);
            }

            var xmlBuffer = new Buffer([]);
            res.on('data', function(chunk) {
                xmlBuffer = Buffer.concat([xmlBuffer, chunk]);
            })

            res.on('end', function(){
                var xmlString = xmlBuffer.toString('utf-8');
                convertXMLToJSObject(xmlString).then(function(response){
                    var test = client.isValidResponse(response);
                    if(test.isValid){
                        response = formatResponse(npmPackageVersion, response)
                        resolve(response);
                    } else {
                        reject(new Error(test.errorMessage))
                    }
                }).catch(reject);
            })

            res.on('error', reject)
        });

        req.write(signedRequest);
        req.end();
    })
};

function formatResponse(version, res){
    switch( version ){
        case 1:
            var keys = Object.keys(res);
            var rootKey = keys[0];
            return res[rootKey];
            break;
        default:
            return res;
    }
}

function convertXMLToJSObject(xml){
    return new Promise(function(resolve, reject){
        parseXML(xml, function (err, response) {
            err? reject(err) : resolve(response);
        });
    })
};

function signRequest(credentials, params){
    params.AWSAccessKeyId=  credentials.access;
    params.Timestamp = new Date().toISOString();
    var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA1, credentials.secret);
    hmac.update(SERVICE + params.Operation + params.Timestamp);
    params.Signature = hmac.finalize().toString(CryptoJS.enc.Base64);
    return params;
}

//EXPORT
module.exports = new MTurkAPI();
<commit_msg>Improved error messages so they can be actionable. Now the error.name will have the information ncesary to  programmatically  handle errors<commit_after>////////////////////////////////////////////////////
//                   Imports
////////////////////////////////////////////////////
var PromiseThrottle = require('promise-throttle');
var parseXML = require('xml2js').parseString;
var querystring = require('querystring');
var CryptoJS = require('crypto-js');
var Promise = require('promise');
const https = require('https');
var _ = require('lodash');

var PRODUCTION = 'mechanicalturk.amazonaws.com';
var SANDBOX = 'mechanicalturk.sandbox.amazonaws.com';
var SERVICE = 'AWSMechanicalTurkRequester';
var VERSION = '2014-08-15';
var METHOD = 'POST';

var specialResponses = {};
specialResponses['CreateQualificationType'] = 'QualificationType';
specialResponses['CreateHIT'] = 'HIT';
specialResponses['GetHIT'] = 'HIT';

//Legacy support
var npmPackageVersion = 2; //Latest by default

var promiseThrottle = new PromiseThrottle({
    requestsPerSecond: 3,           // up to 1 request per second
    promiseImplementation: Promise  // the Promise library you are using
});

function MTurkAPI() {

    var api = this;

    //Legacy support for V1 methods (temporary)
    api.connect = function(options){
        return new Promise(function(resolve, reject){
            var client = api.createClient(options);
            var error = new Error('Could not initialize client. Please notify the mantainer (ERR1-3-5L)');
            if(client){
                resolve(client);
                npmPackageVersion = 1;
            } else { reject(error); }
        })
    };

    api.createClient = function(options) {

        var client = {};
        // add some items to the queue
        client.req = function (operation, params) {
            return new Promise(function(resolve, reject){
                promiseThrottle.add(throttledRequest.bind(this, client, options, operation, params))
                .then(resolve)
                .catch(reject);
            })
        };

        //TODO: Improve method by using JSON schemas
        //      for error checking

        //Checks for two types of errors:
        //OPERATION ERR: (wrong API keys, etc) which are located in the OPERATION response group
        //RESULTS ERR: (wrong params, etc) which are located in the RESULT response group
        client.isValidResponse = function(response){
            var result = {};
            result.errorType =  [];
            result.errorMessage = null;
            result.isValid = null;

            var responseKey = Object.keys(response)[0];
            var charIndex = responseKey.indexOf("Response");
            var operationName = responseKey.slice(0, charIndex)

            //OPERATION ERROR CHECK
            var responseProperty = operationName + 'Response';
            var hasResponse = response.hasOwnProperty(responseProperty);
            var responseGroup = hasResponse? response[operationName + 'Response'] : null;
            var operationRequest = responseGroup? responseGroup.OperationRequest[0] : null;
            var operationErrors = operationRequest? operationRequest.hasOwnProperty('Errors') : null;
            var operationError = operationErrors? true : false;
            var error = operationError? operationRequest.Errors[0].Error[0]: null;
            var errCode = error? error.Code[0] : '';
            var errMsg = error? error.Message[0] : '';
            var errKey = error && error.hasOwnProperty('Data')? error.Data[0].Key : '';
            var errVal = error && error.hasOwnProperty('Data')? error.Data[0].Value : '';
            var errData = errKey && errVal? errKey +': '+errVal : '';
            result.errMessage = error? errCode +' - '+ errMsg + ' - '+ errData: '';
            result.isValid = error? false : true;
            result.errData = errData;
            result.errVal = errVal[0];
            result.errKey = errKey[0];
            result.errCode = errCode;
            if(error){return result}

            //RESULT ERROR CHECK
            var specialCase = specialResponses.hasOwnProperty(operationName);
            var resultProperty = specialCase ? specialResponses[operationName] : operationName + 'Result';
            var hasResult = responseGroup.hasOwnProperty(resultProperty);
            var requestResult = hasResult? responseGroup[resultProperty][0].Request[0] : null;
            var hasValidity = requestResult? requestResult.hasOwnProperty('IsValid'): null;
            var validResult = hasValidity? requestResult.IsValid[0] === 'True': false;
            var resultError = hasResult && !validResult;
            var error = resultError? requestResult.Errors[0].Error[0]: null;
            var errCode = error? error.Code[0] : '';
            var errMsg = error? error.Message[0] : '';
            var errKey = error && error.hasOwnProperty('Data')? error.Data[0].Key : '';
            var errVal = error && error.hasOwnProperty('Data')? error.Data[0].Value : '';
            var errData = errKey && errVal? errKey +': '+errVal : '';
            result.errMessage = error? errCode +' - '+ errMsg + ' - '+ errData : '';
            result.isValid = error? false : true;
            result.errData = errData;
            result.errVal = errVal[0];
            result.errKey = errKey[0];
            result.errCode = errCode;
            //Returns object
            // with various props
            // isValid, errMessage, etc
            return result;
        }

        return client;
    }

    return api;
}

function restify(params){
    _.forOwn(params, function(value, key, obj) {

        if(_.isArray(value)){
            _.forEach(value, function(item, index){
                _.forEach(item, function(value, subkey){
                    params[key+'.'+index+'.'+subkey] = value;
                });
            });
        }

        if(_.isPlainObject(value)){
            var subkeys = _.keys(value);
            _.forEach(subkeys, function(subkey){
                var path = key +'.1.'+subkey;
                params[path] = value[subkey];
            })
        }
    });
    return params;
}

function throttledRequest(client, options, operation, params){
    var params = params || {};
    params = restify(params);
    params.RequestGroup = params.RequestGroup || 'Request, Minimal';
    params.Operation = operation;
    params.Version = VERSION;

    return new Promise(function(resolve, reject){
        var signedRequest = signRequest(options, params);
        signedRequest = querystring.stringify(signedRequest);
        var payloadSize = Buffer.byteLength(signedRequest);

        var reqOptions = {};
        reqOptions.host = options.sandbox? SANDBOX : PRODUCTION;
        reqOptions.method= METHOD;
        reqOptions.headers = {};
        reqOptions.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        reqOptions.headers['Content-Length'] = payloadSize;

        var req = https.request(reqOptions, function(res) {

            if(res.statusCode !== 200){
                var error = new Error(res.statusCode +' - '+ res.statusMessage)
                reject(error);
            }

            var xmlBuffer = new Buffer([]);
            res.on('data', function(chunk) {
                xmlBuffer = Buffer.concat([xmlBuffer, chunk]);
            })

            res.on('end', function(){
                var xmlString = xmlBuffer.toString('utf-8');
                convertXMLToJSObject(xmlString).then(function(response){
                    var test = client.isValidResponse(response);
                    if(test.isValid){
                        response = formatResponse(npmPackageVersion, response)
                        resolve(response);
                    } else {
                        var customError = new Error();
                        customError.name = test.errVal;
                        customError.message = test.errMessage;
                        reject(new Error(customError))
                    }
                }).catch(reject);
            })

            res.on('error', reject)
        });

        req.write(signedRequest);
        req.end();
    })
};

function formatResponse(version, res){
    switch( version ){
        case 1:
            var keys = Object.keys(res);
            var rootKey = keys[0];
            return res[rootKey];
            break;
        default:
            return res;
    }
}

function convertXMLToJSObject(xml){
    return new Promise(function(resolve, reject){
        parseXML(xml, function (err, response) {
            err? reject(err) : resolve(response);
        });
    })
};

function signRequest(credentials, params){
    params.AWSAccessKeyId=  credentials.access;
    params.Timestamp = new Date().toISOString();
    var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA1, credentials.secret);
    hmac.update(SERVICE + params.Operation + params.Timestamp);
    params.Signature = hmac.finalize().toString(CryptoJS.enc.Base64);
    return params;
}

//EXPORT
module.exports = new MTurkAPI();
<|endoftext|>


<commit_before>/* global $ */
'use strict'
// let $ = require('meeko') 作为全局 不在加载，否则会加载两次
let co = require('co')
let pack = require('./package.json')

let DbOpt = function (mysql, tbName, field, exColumn) {
  let me = this
  let sql = ''
  let _name = tbName
  /*
  TODO: 列可见性
  let ex = exColumn || {'d_flag': 1, 'm_time': 1, 'w_state': 1, 'name': 1}
  let tableField = field */
  function _log (sql, ifShowSql) {
    if (ifShowSql) {
      $.option.logTime = false
      $.log(sql)
      $.option.logTime = true
    }
  }
  /*

  TODO: 列可见性
  function _columnFilter (colObj) {
  let o = {}
  tableField.map(item => {
  if (!ex[item]) o[item] = 1
  })
  for (let i in colObj) {
  if (colObj[i] === 1 && ex[i] === 1) o[i] = 1
  }

  return o
  } */
  me.get = function () {
    // 返回生成的sql
    let s = sql
    sql = ''
    return s
  }
  me.cmd = function (s) {
    let _tail = (~s.indexOf(';')) ? '' : ';'
    sql += s + _tail
    return me
  }
  me.exec = function * (ifTrans, ifShowSql) {
    let sql = me.get()
    let r
    if (ifTrans) {
      try {
        sql = `begin;${sql}commit;`
        _log(sql, ifShowSql)
        r = yield mysql.query(sql)
        return r
      } catch (e) {
        yield mysql.query('rollback;')
        let err = e.toString()
        new RegExp('(.+)', 'gm').test(err)
        let light = RegExp.$1
        // NOTICE:不要使用ctrl+alt+F 格式化代码
        $.err(sql.replace(light, `${$.c.r(light)}`), `\n${err.replace(/('.+')/gm, `${$.c.y(RegExp.$1)}`)}`)
        $.log(`${$.c.g('Rollback')}`)
        return -1
      }
    } else {
      try {
        _log(sql, ifShowSql)
        return yield mysql.query(sql)
      } catch (e) {
        let err = e.toString()
        new RegExp('\'([^\']+)\'', 'gm').test(err)
        let light = RegExp.$1
        // NOTICE:不要使用ctrl+alt+F 格式化代码
        $.err(sql.replace(light, `${$.c.r(light)}`), `\n${err.replace(/('[^']+')/gm, `${$.c.y(RegExp.$1)}`)}`)
        return -1
      }
    }
  }
  me.run = co.wrap(function * (ifTrans, ifShowSql) {
    return yield me.exec(ifTrans, ifShowSql)
  })
  me.where = function (o, type) {
    let _item
    let a = []
    for (let i in o) {
      switch (typeof o[i]) {
        case 'string':
        {
          let _pre = '\''
          ;/[0-9a-zA-z_]+\(.+\)/g.test(o[i]) && (_pre = '') // NOTICE: 注意前面的分号
          _item = `\`${i}\`=${_pre}${o[i]}${_pre}`
          break
        }
        case 'number':
          _item = `\`${i}\`=${o[i]}`
          break
        case 'boolean':
          _item = `\`${i}\`=${o[i]}`
          break
        case 'object':
        {
          if (type === 'update') {
            let _preStr = o[i] instanceof Date ? '' : '\''
            _item = `\`${i}\` = ${o[i] ? _preStr + (JSON.stringify(o[i]) + _preStr) : 'NULL'}`
            break
          }
          if (!o[i]) {
            // NOTICE: 不能严格等于
            _item = `\`${i}\` is NULL`
            break
          }
          if (o[i] instanceof Date) {
            _item = `\`${i}\`='${o[i].date2Str()}'`
            break
          }
          if (o[i] instanceof Array) {
            _item = `\`${i}\` in ${JSON.stringify(o[i]).replaceAll('[', '(').replaceAll(']', ')').replaceAll('"', '\'')}`
            break
          }
          if (o[i] instanceof RegExp) {
            _item = `\`${i}\` like '${o[i].toString().replaceAll('/g', '').replaceAll('/', '')}'`
            break
          }
          let _objAry = []
          for (let i2 in o[i]) {
            let _pre1 = (typeof o[i][i2] === 'string') ? '\'' : ''
            let _pre2 = (/[0-9a-zA-z_]+\(.+\)/g).test(i) ? '' : '`'
            _objAry.push(`${_pre2}${i}${_pre2}${i2}${_pre1}${o[i][i2]}${_pre1}`)
          }
          _item = _objAry.join(' and ')
          break
        }
        case 'undefined':
          _item = `\`${i}\` = NULL`
          break
        default:
      }
      a.push(_item)
    }
    return a
  }
  me.find = function (a, b, c, d) {
    /*
    a where
    b col
    c order by
    d limit
    */
    let cols = []
    let colsStr = ''
    let whereStr = ''
    let order = []
    let orderStr = ''
    let limitStr = +d
    for (let i in c) {
      order.push('`' + i + '`' + ` ${(+c[i]) === -1 ? 'desc' : 'asc'}`)
    }
    orderStr = order.join(', ')
    // if (b === 0) b = _columnFilter(b) //TODO: 列可见性加强
    for (let i in b) {
      cols.push('`' + i + '`')
    }
    colsStr = cols.join(',')
    whereStr = me.where(a).join(' and ')
    sql += `select ${colsStr || '*'} from \`${_name}\`${whereStr ? ' where ' + whereStr : ''}${orderStr ? ' order by ' + orderStr : ''}${limitStr ? (' limit ' + limitStr) : ''};`
    return me
  }
  me.findOne = function (a, b, c) {
    return me.find(a, b, c, 1)
  }
  me.remove = function (a, ifEmpty) {
    let whereStr = me.where(a).join(' and ')
    if (whereStr || (ifEmpty && !whereStr)) {
      sql += `delete from \`${_name}\`${whereStr ? ' where ' + whereStr : ''};`
      return me
    } else {
      sql += '[Empty!!]'
      return me
    }
  }
  me.update = function (a, b, ifEmpty) {
    let whereStr = me.where(a).join(' and ')
    let colsStr = me.where(b, 'update').join(',')
    if (!colsStr) {
      sql += '[Empty!!]'
      return me
    }
    if (whereStr || (ifEmpty && !whereStr)) {
      sql += `update \`${_name}\` set ${colsStr}${whereStr ? ' where ' + whereStr : ''};`
      return me
    } else {
      sql += '[Empty!!]'
      return me
    }
  }
  me.insert = function (a, uniqCol) {
    let cols = []
    let values = []
    let vals = []
    let colsStr = ''
    let valuesStr = ''
    for (let i in a) {
      cols.push('`' + i + '`')
      values.push(a[i])
    }
    colsStr = cols.join(',')
    values = me.where(a, 'update')
    for (let i = 0; i < values.length; i++) {
      let a = values[i].split('=')
      a.shift(0)
      vals.push(a.join('='))
    }
    valuesStr = vals.join(',')
    if (!colsStr && !valuesStr) {
      sql += '[Empty!!]'
    } else {
      if (!uniqCol) {
        sql += `insert into \`${_name}\` (${colsStr}) values (${valuesStr});`
      } else {
        let _v = me.where({
          'c': a[uniqCol]
        })
        let _a = _v[0].split('=')
        _a.shift(0)
        let _c = _a.join('=')
        sql += `insert into \`${_name}\` (${colsStr}) select ${valuesStr} from dual WHERE NOT EXISTS(SELECT \`${uniqCol}\` FROM \`${_name}\` WHERE \`${uniqCol}\` = ${_c}) limit 1;`
      }
    }
    return me
  }
  me.C = function (a, uniqCol) {
    return me.insert(a, uniqCol)
  }
  me.R = function (a, b, c, d) {
    return me.find(a, b, c, d)
  }
  me.U = function (a, b, ifEmpty) {
    return me.update(a, b, ifEmpty)
  }
  me.D = function (a, ifEmpty) {
    return me.remove(a, ifEmpty)
  }
  me.select = function (a, b, c, d) {
    return me.find(a, b, c, d)
  }
  me.delete = function (a, ifEmpty) {
    return me.remove(a, ifEmpty)
  }
  return me
}
function getDB (dbObj) {
  let dbName = dbObj.database || 'test'
  let exColumn = dbObj.exColumn
  let [mysqlWrapper, Mysql] = [require('co-mysql'), require('promise-mysql')]
  let pool = Mysql.createPool(dbObj)
  let mysql = mysqlWrapper(pool)
  $.option.logTime = false
  pool.on('connection', function () {
    // $.log(`<-- J2sql (${pack.version}) [${$.c.yellow}${dbObj.host} : ${dbObj.port}${$.c.none}] pool connect!`)
  })
  pool.on('enqueue', function () {
    // $.log('<-- J2sql pool enqueue!')
  })
  // $.log('--> J2sql Obj Init start...')
  function finishLoadDB (n, mysql, _name, _field, exColumn) {
    $.log($.c.g('✔'), `J2sql (${pack.version}) [${$.c.y(`${dbObj.host} : ${dbObj.port}`)}] [${$.c.y(n)}] tables`)
    db['_mysql'] = pool
    db['cmd'] = new DbOpt(mysql, _name, _field, exColumn).cmd
    $.option.logTime = true
  }
  let [_r, n] = [0, 0]
  let db = {}
  co(function * () {
    _r = yield mysql.query(`use \`${dbName}\`;show tables;`)
    let tableSize = _r[1].length
    let unLoadTable = tableSize
    if (tableSize === 0) {
      $.log($.c.r('✘'), `J2sql (${pack.version}) [${$.c.y(0)} tables]`)
      return
    }
    _r[1].forEach(function (item) {
      let _name = item['Tables_in_' + dbName]
      db[_name] = {}
      co(function * () {
        let _field = (yield mysql.query(`desc \`${_name}\`;`)).map(item => {
          return item['Field']
        })
        $.ext(db[_name], new DbOpt(mysql, _name, _field, exColumn))
        db[_name].field = _field
        unLoadTable--
        db['_nowPercent'] = ~~((tableSize - unLoadTable) / tableSize * 100)
        // $.log('DB Obj loading =>', db['_nowPercent'], '%')
        if (unLoadTable <= 0) {
          finishLoadDB(n, mysql, _name, _field, exColumn)
        } else {

        }
      })
      n++
    })
  }).then(function () {

  }).catch(function (e) {
    $.log($.c.r('✘'), `Mysql: ${e.message}`)
  })
  return db
}
module.exports = getDB
<commit_msg>:children_crossing:<commit_after>/* global $ */
'use strict'
// let $ = require('meeko') 作为全局 不在加载，否则会加载两次
let co = require('co')
let pack = require('./package.json')

let DbOpt = function (mysql, tbName, field, exColumn) {
  let me = this
  let sql = ''
  let _name = tbName
  /*
  TODO: 列可见性
  let ex = exColumn || {'d_flag': 1, 'm_time': 1, 'w_state': 1, 'name': 1}
  let tableField = field */
  function _log (sql, ifShowSql) {
    if (ifShowSql) {
      $.option.logTime = false
      $.log(sql)
      $.option.logTime = true
    }
  }
  /*

  TODO: 列可见性
  function _columnFilter (colObj) {
  let o = {}
  tableField.map(item => {
  if (!ex[item]) o[item] = 1
  })
  for (let i in colObj) {
  if (colObj[i] === 1 && ex[i] === 1) o[i] = 1
  }

  return o
  } */
  me.get = function () {
    // 返回生成的sql
    let s = sql
    sql = ''
    return s
  }
  me.cmd = function (s) {
    let _tail = (~s.indexOf(';')) ? '' : ';'
    sql += s + _tail
    return me
  }
  me.exec = function * (ifTrans, ifShowSql) {
    let sql = me.get()
    let r
    if (ifTrans) {
      try {
        sql = `begin;${sql}commit;`
        _log(sql, ifShowSql)
        r = yield mysql.query(sql)
        return r
      } catch (e) {
        yield mysql.query('rollback;')
        let err = e.toString()
        new RegExp('(.+)', 'gm').test(err)
        let light = RegExp.$1
        // NOTICE:不要使用ctrl+alt+F 格式化代码
        $.err(sql.replace(light, `${$.c.r(light)}`), `\n${err.replace(/('.+')/gm, `${$.c.y(RegExp.$1)}`)}`)
        $.log(`${$.c.g('Rollback')}`)
        return -1
      }
    } else {
      try {
        _log(sql, ifShowSql)
        return yield mysql.query(sql)
      } catch (e) {
        let err = e.toString()
        new RegExp('\'([^\']+)\'', 'gm').test(err)
        let light = RegExp.$1
        // NOTICE:不要使用ctrl+alt+F 格式化代码
        $.err(sql.replace(light, `${$.c.r(light)}`), `\n${err.replace(/('[^']+')/gm, `${$.c.y(RegExp.$1)}`)}`)
        return -1
      }
    }
  }
  me.run = co.wrap(function * (ifTrans, ifShowSql) {
    return yield me.exec(ifTrans, ifShowSql)
  })
  me.where = function (o, type) {
    let _item
    let a = []
    for (let i in o) {
      switch (typeof o[i]) {
        case 'string':
        {
          let _pre = '\''
          ;/[0-9a-zA-z_]+\(.+\)/g.test(o[i]) && (_pre = '') // NOTICE: 注意前面的分号
          _item = `\`${i}\`=${_pre}${o[i]}${_pre}`
          break
        }
        case 'number':
          _item = `\`${i}\`=${o[i]}`
          break
        case 'boolean':
          _item = `\`${i}\`=${o[i]}`
          break
        case 'object':
        {
          if (type === 'update') {
            let _preStr = o[i] instanceof Date ? '' : '\''
            _item = `\`${i}\` = ${o[i] ? _preStr + (JSON.stringify(o[i]) + _preStr) : 'NULL'}`
            break
          }
          if (!o[i]) {
            // NOTICE: 不能严格等于
            _item = `\`${i}\` is NULL`
            break
          }
          if (o[i] instanceof Date) {
            _item = `\`${i}\`='${o[i].date2Str()}'`
            break
          }
          if (o[i] instanceof Array) {
            _item = `\`${i}\` in ${JSON.stringify(o[i]).replaceAll('[', '(').replaceAll(']', ')').replaceAll('"', '\'')}`
            break
          }
          if (o[i] instanceof RegExp) {
            _item = `\`${i}\` like '${o[i].toString().replaceAll('/g', '').replaceAll('/', '')}'`
            break
          }
          let _objAry = []
          for (let i2 in o[i]) {
            let _pre1 = (typeof o[i][i2] === 'string') ? '\'' : ''
            let _pre2 = (/[0-9a-zA-z_]+\(.+\)/g).test(i) ? '' : '`'
            _objAry.push(`${_pre2}${i}${_pre2}${i2}${_pre1}${o[i][i2]}${_pre1}`)
          }
          _item = _objAry.join(' and ')
          break
        }
        case 'undefined':
          _item = `\`${i}\` = NULL`
          break
        default:
      }
      a.push(_item)
    }
    return a
  }
  me.find = function (a, b, c, d) {
    /*
    a where
    b col
    c order by
    d limit
    */
    let cols = []
    let colsStr = ''
    let whereStr = ''
    let order = []
    let orderStr = ''
    let limitStr = +d
    for (let i in c) {
      order.push('`' + i + '`' + ` ${(+c[i]) === -1 ? 'desc' : 'asc'}`)
    }
    orderStr = order.join(', ')
    // if (b === 0) b = _columnFilter(b) //TODO: 列可见性加强
    for (let i in b) {
      cols.push('`' + i + '`')
    }
    colsStr = cols.join(',')
    whereStr = me.where(a).join(' and ')
    sql += `select ${colsStr || '*'} from \`${_name}\`${whereStr ? ' where ' + whereStr : ''}${orderStr ? ' order by ' + orderStr : ''}${limitStr ? (' limit ' + limitStr) : ''};`
    return me
  }
  me.findOne = function (a, b, c) {
    return me.find(a, b, c, 1)
  }
  me.remove = function (a, ifEmpty) {
    let whereStr = me.where(a).join(' and ')
    if (whereStr || (ifEmpty && !whereStr)) {
      sql += `delete from \`${_name}\`${whereStr ? ' where ' + whereStr : ''};`
      return me
    } else {
      sql += '[Empty!!]'
      return me
    }
  }
  me.update = function (a, b, ifEmpty) {
    let whereStr = me.where(a).join(' and ')
    let colsStr = me.where(b, 'update').join(',')
    if (!colsStr) {
      sql += '[Empty!!]'
      return me
    }
    if (whereStr || (ifEmpty && !whereStr)) {
      sql += `update \`${_name}\` set ${colsStr}${whereStr ? ' where ' + whereStr : ''};`
      return me
    } else {
      sql += '[Empty!!]'
      return me
    }
  }
  me.insert = function (a, uniqCol) {
    let cols = []
    let values = []
    let vals = []
    let colsStr = ''
    let valuesStr = ''
    for (let i in a) {
      cols.push('`' + i + '`')
      values.push(a[i])
    }
    colsStr = cols.join(',')
    values = me.where(a, 'update')
    for (let i = 0; i < values.length; i++) {
      let a = values[i].split('=')
      a.shift(0)
      vals.push(a.join('='))
    }
    valuesStr = vals.join(',')
    if (!colsStr && !valuesStr) {
      sql += '[Empty!!]'
    } else {
      if (!uniqCol) {
        sql += `insert into \`${_name}\` (${colsStr}) values (${valuesStr});`
      } else {
        let _v = me.where({
          'c': a[uniqCol]
        })
        let _a = _v[0].split('=')
        _a.shift(0)
        let _c = _a.join('=')
        sql += `insert into \`${_name}\` (${colsStr}) select ${valuesStr} from dual WHERE NOT EXISTS(SELECT \`${uniqCol}\` FROM \`${_name}\` WHERE \`${uniqCol}\` = ${_c}) limit 1;`
      }
    }
    return me
  }
  me.C = function (a, uniqCol) {
    return me.insert(a, uniqCol)
  }
  me.R = function (a, b, c, d) {
    return me.find(a, b, c, d)
  }
  me.U = function (a, b, ifEmpty) {
    return me.update(a, b, ifEmpty)
  }
  me.D = function (a, ifEmpty) {
    return me.remove(a, ifEmpty)
  }
  me.select = function (a, b, c, d) {
    return me.find(a, b, c, d)
  }
  me.delete = function (a, ifEmpty) {
    return me.remove(a, ifEmpty)
  }
  return me
}
function getDB (dbObj) {
  let dbName = dbObj.database || 'test'
  let exColumn = dbObj.exColumn
  let [mysqlWrapper, Mysql] = [require('co-mysql'), require('promise-mysql')]
  let pool = Mysql.createPool(dbObj)
  let mysql = mysqlWrapper(pool)
  $.option.logTime = false
  pool.on('connection', function () {
    // $.log(`<-- J2sql (${pack.version}) [${$.c.yellow}${dbObj.host} : ${dbObj.port}${$.c.none}] pool connect!`)
  })
  pool.on('enqueue', function () {
    // $.log('<-- J2sql pool enqueue!')
  })
  // $.log('--> J2sql Obj Init start...')
  function finishLoadDB (n, mysql, _name, _field, exColumn) {
    $.log($.c.g('✔'), `J2sql (${pack.version}) [${$.c.y(`${dbObj.host} : ${dbObj.port}`)}] [${$.c.y(n)}] tables`)
    db['_mysql'] = pool
    db['cmd'] = new DbOpt(mysql, _name, _field, exColumn).cmd
  }
  let [_r, n] = [0, 0]
  let db = {}
  co(function * () {
    _r = yield mysql.query(`use \`${dbName}\`;show tables;`)
    let tableSize = _r[1].length
    let unLoadTable = tableSize
    if (tableSize === 0) {
      $.log($.c.r('✘'), `J2sql (${pack.version}) [${$.c.y(0)} tables]`)
      return
    }
    _r[1].forEach(function (item) {
      let _name = item['Tables_in_' + dbName]
      db[_name] = {}
      co(function * () {
        let _field = (yield mysql.query(`desc \`${_name}\`;`)).map(item => {
          return item['Field']
        })
        $.ext(db[_name], new DbOpt(mysql, _name, _field, exColumn))
        db[_name].field = _field
        unLoadTable--
        db['_nowPercent'] = ~~((tableSize - unLoadTable) / tableSize * 100)
        // $.log('DB Obj loading =>', db['_nowPercent'], '%')
        if (unLoadTable <= 0) {
          finishLoadDB(n, mysql, _name, _field, exColumn)
        } else {

        }
      })
      n++
    })
  }).then(function () {

  }).catch(function (e) {
    $.log($.c.r('✘'), `Mysql: ${e.message}`)
  })
  return db
}
module.exports = getDB
<|endoftext|>


<commit_before>//
// bloader.js: node.js-based file loader and command line shell for arduino
//
//	Copyright 2012 Bill Roy (MIT License)
//

////////////////////
//
// Parse the options
//
var opt = require('optimist');
var argv = opt.usage('Usage: $0 [flags]')
	.alias('p', 'port')
	.describe('p', 'virtual serial port name (auto-detects FTDI ports on Mac/Linux)')
	.alias('b', 'baud')
	.describe('b', 'virtual serial port baud rate')
	.alias('f', 'file')
	.describe('f', 'file or URL to send')
	.alias('r', 'repeat')
	.describe('r', 'interval to re-send file (seconds)')
	.argv;

if (argv.help) {
	opt.showHelp();
	process.exit();
}

////////////////////
//
// Which serial port?
//
shell = require("shelljs");
var portlist, portname;

if (argv.port) portlist = [argv.port];
else if (process.platform === 'darwin') portlist = shell.ls("/dev/tty.usb*");
else if (process.platform === 'linux') portlist = shell.ls("/dev/ttyUSB*");

if (portlist.length == 0) {
	process.stdout.write('No ports found.\n');
	process.exit(-1);
}
else if (portlist.length > 1) {
	process.stdout.write('Trying first of multiple ports:\n' + portlist.join('\n'));
}
portname = portlist[0];

////////////////////
//
// Open serial port
//
var SerialPort = require('serialport').SerialPort;
try {
	var port = new SerialPort(portname, {
		baudrate: argv.baud || 57600,
		buffersize: 20480
	});
} catch(e) {
	process.stdout.write('Cannot open serial device.');
	process.exit(-2);
}

////////////////////
//
// Serial port listener
//
var lines;		// array of commands to send to target

port.on('data', function(data) {	// port input goes to stdout
	process.stdout.write(data);

	// when we see the prompt go by, send the next command if we have one
	if (lines && lines.length && data.toString().match("\n> ")) {
		var line = lines.shift();
		port.write(line + '\n');
	}
});

////////////////////
//
// Send file
//
var fs = require('fs');
var url = require('url');
var http = require('http');

function sendFile(filename) {

	// If the file begins with http: fetch it from the web
	if (filename.indexOf("http:") == 0) {

		var target = url.parse(filename);
		//console.log(target);
		var options = {
			host: target.host,
			port: target.port | 80,
			path: target.path,
			method: 'GET'
		};

		var req = http.request(options, function(res) {
			//console.log('STATUS: ' + res.statusCode);
			//console.log('HEADERS: ' + JSON.stringify(res.headers));
			res.setEncoding('utf8');
			res.on('data', function (chunk) {
				//console.log('BODY: ' + chunk);
				lines = chunk.split('\n')
				port.write('\n');	// get a prompt
			});
		});
		req.on('error', function(e) {
			console.log('problem with request: ' + e.message);
			process.exit(-3);
		});
		req.end();
	}
	else {		// local file
		var filetext = fs.readFileSync(argv.file, 'utf8');		// specifying 'utf8' to get a string result
		lines = filetext.split('\n');
		port.write('\n');	// get a prompt
	}
}

if (argv.file) {
	sendFile(argv.file);
	if (argv.repeat) setInterval(sendFile, argv.repeat*1000, argv.file);
}

////////////////////
//
// Enter terminal mode
//
if (port) {
//	port.on('data', function(data) {	// port input goes to stdout
//		process.stdout.write(data);
//	});
	process.stdin.resume();
	process.stdin.setEncoding('utf8');
	process.stdin.setRawMode(true);			// pass ^C through to serial port
	process.stdin.on('data', function (data) {	// keyboard input goes to port
		if (data === '\x1d') process.exit(0);	// ^] to quit
		else if (port) port.write(data);
	});
}<commit_msg>handle prompt detection in fragmented serialin stream<commit_after>//
// bloader.js: node.js-based file loader and command line shell for arduino
//
//	Copyright 2012 Bill Roy (MIT License)
//

////////////////////
//
// Parse the options
//
var opt = require('optimist');
var argv = opt.usage('Usage: $0 [flags]')
	.alias('p', 'port')
	.describe('p', 'virtual serial port name (auto-detects FTDI ports on Mac/Linux)')
	.alias('b', 'baud')
	.describe('b', 'virtual serial port baud rate')
	.alias('f', 'file')
	.describe('f', 'file or URL to send')
	.alias('r', 'repeat')
	.describe('r', 'interval to re-send file (seconds)')
	.argv;

if (argv.help) {
	opt.showHelp();
	process.exit();
}

////////////////////
//
// Which serial port?
//
shell = require("shelljs");
var portlist, portname;

if (argv.port) portlist = [argv.port];
else if (process.platform === 'darwin') portlist = shell.ls("/dev/tty.usb*");
else if (process.platform === 'linux') portlist = shell.ls("/dev/ttyUSB*");

if (portlist.length == 0) {
	process.stdout.write('No ports found.\n');
	process.exit(-1);
}
else if (portlist.length > 1) {
	process.stdout.write('Trying first of multiple ports:\n' + portlist.join('\n'));
}
portname = portlist[0];

////////////////////
//
// Open serial port
//
var SerialPort = require('serialport').SerialPort;
try {
	var port = new SerialPort(portname, {
		baudrate: argv.baud || 57600,
		buffersize: 20480
	});
} catch(e) {
	process.stdout.write('Cannot open serial device.');
	process.exit(-2);
}

////////////////////
//
// Serial port listener
//
var prompt = "\n> ";
var lines;		// array of commands to send to target
var instream;

port.on('data', function(data) {	// port input goes to stdout
	process.stdout.write(data);

	//console.log("Data: [" + data + "]");
	instream = "" + instream + data.toString();

	// when we see the prompt go by, send the next command if we have one
	if (lines && lines.length) {
		var match = instream.match(prompt);
		if (match != undefined) {
//console.log(match);
			var line = lines.shift();
			port.write(line + '\n');
			//instream.slice(match.index);
			instream = "";
		}
	}
});

////////////////////
//
// Send file
//
var fs = require('fs');
var url = require('url');
var http = require('http');
var https = require('https');

function sendFile(filename) {

	// If the file begins with http: fetch it from the web
	var is_http = filename.indexOf("http://") == 0;
	var is_https = filename.indexOf("https://") == 0;

	if (is_http || is_https) {

		var target = url.parse(filename);
		//console.log(target);
		var options = {
			host: target.host,
			port: target.port | 80,
			path: target.path,
			method: 'GET'
		};

		var client = http;
		if (is_https) client = https;
		var req = client.request(options, function(res) {
			res.setEncoding('utf8');
			res.on('data', function (chunk) {
				lines = chunk.split('\n')
				port.write('\n');	// get a prompt
			});
		});
		req.on('error', function(e) {
			console.log('problem with request: ' + e.message);
			process.exit(-3);
		});
		req.end();
	}
	else {		// local file
		var filetext = fs.readFileSync(argv.file, 'utf8');		// specifying 'utf8' to get a string result
		lines = filetext.split('\n');
		port.write('\n');	// get a prompt
	}
}

if (argv.file) {
	sendFile(argv.file);
	if (argv.repeat) setInterval(sendFile, argv.repeat*1000, argv.file);
}

////////////////////
//
// Enter terminal mode
//
if (port) {
//	port.on('data', function(data) {	// port input goes to stdout
//		process.stdout.write(data);
//	});
	process.stdin.resume();
	process.stdin.setEncoding('utf8');
	process.stdin.setRawMode(true);			// pass ^C through to serial port
	process.stdin.on('data', function (data) {	// keyboard input goes to port
		if (data === '\x1d') process.exit(0);	// ^] to quit
		else if (port) port.write(data);
	});
}<|endoftext|>


<commit_before>module.exports = {
    each : require("./lib/each")
  , extend : require("./lib/extend")
  , filter : require("./lib/filter")
  , reject : require("./lib/reject")
  , map : require("./lib/map")
  , pluck : require("./lib/pluck")
  , reduce : require("./lib/reduce")
  , reduceRight : require("./lib/reduceRight")
  , getKeys : require("./lib/getKeys")
  , getValues : require("./lib/getValues")
  , getPairs : require("./lib/getPairs")
  , getSize : require("./lib/getSize")
  , indexOf : require("./lib/indexOf")
  , contains : require("./lib/contains")
  , lastIndexOf : require("./lib/lastIndexOf")
}
<commit_msg>exposed clone method<commit_after>module.exports = {
    each : require("./lib/each")
  , extend : require("./lib/extend")
  , filter : require("./lib/filter")
  , reject : require("./lib/reject")
  , map : require("./lib/map")
  , pluck : require("./lib/pluck")
  , reduce : require("./lib/reduce")
  , reduceRight : require("./lib/reduceRight")
  , getKeys : require("./lib/getKeys")
  , getValues : require("./lib/getValues")
  , getPairs : require("./lib/getPairs")
  , getSize : require("./lib/getSize")
  , indexOf : require("./lib/indexOf")
  , contains : require("./lib/contains")
  , clone : require("./lib/clone")
  , lastIndexOf : require("./lib/lastIndexOf")
}
<|endoftext|>


<commit_before>const currencySymbolMap = require('../core/map.js')
const getSymbolFromCurrency = (currencyCode) => {
  if (typeof currencyCode !== 'string') return undefined
  var code = currencyCode.toUpperCase()
  if (!currencySymbolMap.hasOwnProperty(code)) return undefined
  return currencySymbolMap[code]
}
module.exports = getSymbolFromCurrency
<commit_msg>Make currency service more readable<commit_after>const currencySymbolMap = require('../core/map.js')
const getSymbolFromCurrency = (currencyCode) => {
  if (typeof currencyCode !== 'string') {
    return undefined
  }

  const code = currencyCode.toUpperCase()

  if (!currencySymbolMap.hasOwnProperty(code)) {
    return undefined
  }

  return currencySymbolMap[code]
}
module.exports = getSymbolFromCurrency
<|endoftext|>


<commit_before>var collect = require('collect-stream')
var hyperdrive = require('hyperdrive')
var speedometer = require('speedometer')
var pump = require('pump')
var webrtcSwarm = require('webrtc-swarm')
var signalhub = require('signalhub')
var series = require('run-series')
var subLevel = require('subleveldown')
var discoverySwarm = require('discovery-swarm')
var debug = require('debug')('dat')

module.exports = Dat

var DEFAULT_PORT = 3282
var DEFAULT_DISCOVERY = ['discovery.publicbits.org', 'discovery.publicbits.org:5300']
var DEFAULT_SIGNALHUB = 'https://signalhub.publicbits.org'
var DAT_DOMAIN = 'dat.local'

function Dat (opts) {
  if (!(this instanceof Dat)) return new Dat(opts)
  if (!opts) opts = {}
  this.fs = opts.fs || require('./fs.js')
  this.level = opts.db || require('./db.js')(opts)
  var drive = hyperdrive(this.level)
  this.drive = drive
  this.allPeers = {}
  this.blacklist = {}

  var discovery = opts.discovery !== false
  this.swarm = discoverySwarm({
    id: drive.core.id,
    dns: discovery && {server: DEFAULT_DISCOVERY, domain: DAT_DOMAIN},
    dht: discovery,
    stream: function () {
      return drive.createPeerStream()
    }
  })
}

Dat.prototype.scan = function (dirs, each, done) {
  var self = this

  if (!Array.isArray(dirs)) dirs = [dirs]

  var tasks = dirs.map(function (dir) {
    return function (cb) {
      self.fs.listEach({dir: dir}, each, cb)
    }
  })

  series(tasks, function (err) {
    if (err) return done(err)
    done()
  })
}

Dat.prototype.fileStats = function (dirs, cb) {
  this.scan(dirs, eachItem, done)

  var stats = {
    files: 0,
    directories: 0,
    size: 0,
    latest: null
  }

  function eachItem (item, next) {
    if (item.type === 'file') {
      stats.files++
      stats.size += item.size
      if (item.mtime > stats.latest) stats.latest = item.mtime
    } else if (item.type === 'directory') {
      stats.directories++
    }
    next()
  }

  function done (err) {
    if (err) return cb(err)
    cb(null, stats)
  }

  return stats
}

Dat.prototype.addFiles = function (dirs, cb) {
  var pack = this.drive.add('.')
  this.scan(dirs, eachItem, done)

  var stats = {
    totalStats: pack.stats,
    files: []
  }

  return stats

  function eachItem (item, next) {
    var appendStats = pack.appendFile(item.path, item.name, next)
    // This could accumulate too many objects if
    // logspeed is high & scanning many files.
    if (item.type === 'file') {
      stats.files.push({
        name: item.name,
        stats: appendStats
      })
    }
  }

  function done (err) {
    if (err) return cb(err)
    pack.finalize(function (err) {
      if (err) return cb(err)
      var link = pack.id.toString('hex')
      cb(null, link)
      // TODO pack cleanup
    })
  }
}

Dat.prototype.joinWebrtcSwarm = function (link, opts) {
  if (!opts) opts = {}
  opts.signalhub = opts.signalhub || DEFAULT_SIGNALHUB
  var self = this
  link = link.replace('dat://', '').replace('dat:', '')
  var key = link.toString('hex')
  var hub = signalhub('hyperdrive/' + key, [opts.signalhub])
  var swarm = webrtcSwarm(hub, opts)

  swarm.on('peer', function (peer) {
    pump(peer, self.drive.createPeerStream(), peer, function () {
      debug('found a peer for', link, peer)
    })
  })

  return swarm
}

Dat.prototype.joinTcpSwarm = function (opts, cb) {
  var self = this
  if (typeof opts === 'string') opts = {link: opts}
  var link = opts.link
  link = link.replace('dat://', '').replace('dat:', '')
  var key = new Buffer(link, 'hex')
  var metaLevel = subLevel(this.level, 'metadata')

  this.swarm.once('listening', function () {
    self.swarm.link = link // backwards compat
    self.swarm.add(key)
    metaLevel.put(link + '-port', self.swarm.address().port)
    cb(null, self.swarm)
  })

  this.swarm.once('error', function (err) {
    if (err.code === 'EADDRINUSE') self.swarm.listen(0) // asks OS for first open port
    else throw err
  })

  if (opts.port) return swarmListen()
  metaLevel.get(link + '-port', function (err, value) {
    if (err && err.notFound) return swarmListen() // no old port
    if (err) return cb(err)
    opts.port = Number(value)
    swarmListen()
  })

  function swarmListen () {
    self.swarm.listen(opts.port || DEFAULT_PORT)
  }
}

Dat.prototype.close = function (cb) {
  this.drive.core.db.close()
  this.swarm.destroy(cb)
}

Dat.prototype.metadata = function (link, cb) {
  var self = this
  var archive = self.drive.get(link)
  collect(archive.createEntryStream(), cb)
}

// returns object that is used to render progress bars
Dat.prototype.download = function (link, dir, cb) {
  var self = this
  if (!cb) cb = function noop () {}

  var stats = {}

  self.joinTcpSwarm(link, function (err, swarm) {
    if (err) return cb(err)
    swarm.downloading = true
    stats.downloadRate = speedometer()
    stats.downloaded = 0
    stats.swarm = swarm
    var archive = self.drive.get(swarm.link, dir)

    archive.ready(function (err) {
      if (err) return cb(err)
      swarm.blocks = archive.entries
      var download = self.fs.createDownloadStream(archive, stats)
      pump(archive.createEntryStream(), download, function (err) {
        cb(err, swarm)
      })
    })

    archive.on('file-download', function (entry, data, block) {
      stats.downloaded += data.length
      stats.downloadRate(data.length)
    })
  })

  return stats
}
<commit_msg>use discovery2 as well<commit_after>var collect = require('collect-stream')
var hyperdrive = require('hyperdrive')
var speedometer = require('speedometer')
var pump = require('pump')
var webrtcSwarm = require('webrtc-swarm')
var signalhub = require('signalhub')
var series = require('run-series')
var subLevel = require('subleveldown')
var discoverySwarm = require('discovery-swarm')
var debug = require('debug')('dat')

module.exports = Dat

var DEFAULT_PORT = 3282
var DEFAULT_DISCOVERY = [
  'discovery.publicbits.org',
  'discovery.publicbits.org:5300',
  'discovery2.publicbits.org:5300'
]

var DEFAULT_SIGNALHUB = 'https://signalhub.publicbits.org'
var DAT_DOMAIN = 'dat.local'

function Dat (opts) {
  if (!(this instanceof Dat)) return new Dat(opts)
  if (!opts) opts = {}
  this.fs = opts.fs || require('./fs.js')
  this.level = opts.db || require('./db.js')(opts)
  var drive = hyperdrive(this.level)
  this.drive = drive
  this.allPeers = {}
  this.blacklist = {}

  var discovery = opts.discovery !== false
  this.swarm = discoverySwarm({
    id: drive.core.id,
    dns: discovery && {server: DEFAULT_DISCOVERY, domain: DAT_DOMAIN},
    dht: discovery,
    stream: function () {
      return drive.createPeerStream()
    }
  })
}

Dat.prototype.scan = function (dirs, each, done) {
  var self = this

  if (!Array.isArray(dirs)) dirs = [dirs]

  var tasks = dirs.map(function (dir) {
    return function (cb) {
      self.fs.listEach({dir: dir}, each, cb)
    }
  })

  series(tasks, function (err) {
    if (err) return done(err)
    done()
  })
}

Dat.prototype.fileStats = function (dirs, cb) {
  this.scan(dirs, eachItem, done)

  var stats = {
    files: 0,
    directories: 0,
    size: 0,
    latest: null
  }

  function eachItem (item, next) {
    if (item.type === 'file') {
      stats.files++
      stats.size += item.size
      if (item.mtime > stats.latest) stats.latest = item.mtime
    } else if (item.type === 'directory') {
      stats.directories++
    }
    next()
  }

  function done (err) {
    if (err) return cb(err)
    cb(null, stats)
  }

  return stats
}

Dat.prototype.addFiles = function (dirs, cb) {
  var pack = this.drive.add('.')
  this.scan(dirs, eachItem, done)

  var stats = {
    totalStats: pack.stats,
    files: []
  }

  return stats

  function eachItem (item, next) {
    var appendStats = pack.appendFile(item.path, item.name, next)
    // This could accumulate too many objects if
    // logspeed is high & scanning many files.
    if (item.type === 'file') {
      stats.files.push({
        name: item.name,
        stats: appendStats
      })
    }
  }

  function done (err) {
    if (err) return cb(err)
    pack.finalize(function (err) {
      if (err) return cb(err)
      var link = pack.id.toString('hex')
      cb(null, link)
      // TODO pack cleanup
    })
  }
}

Dat.prototype.joinWebrtcSwarm = function (link, opts) {
  if (!opts) opts = {}
  opts.signalhub = opts.signalhub || DEFAULT_SIGNALHUB
  var self = this
  link = link.replace('dat://', '').replace('dat:', '')
  var key = link.toString('hex')
  var hub = signalhub('hyperdrive/' + key, [opts.signalhub])
  var swarm = webrtcSwarm(hub, opts)

  swarm.on('peer', function (peer) {
    pump(peer, self.drive.createPeerStream(), peer, function () {
      debug('found a peer for', link, peer)
    })
  })

  return swarm
}

Dat.prototype.joinTcpSwarm = function (opts, cb) {
  var self = this
  if (typeof opts === 'string') opts = {link: opts}
  var link = opts.link
  link = link.replace('dat://', '').replace('dat:', '')
  var key = new Buffer(link, 'hex')
  var metaLevel = subLevel(this.level, 'metadata')

  this.swarm.once('listening', function () {
    self.swarm.link = link // backwards compat
    self.swarm.add(key)
    metaLevel.put(link + '-port', self.swarm.address().port)
    cb(null, self.swarm)
  })

  this.swarm.once('error', function (err) {
    if (err.code === 'EADDRINUSE') self.swarm.listen(0) // asks OS for first open port
    else throw err
  })

  if (opts.port) return swarmListen()
  metaLevel.get(link + '-port', function (err, value) {
    if (err && err.notFound) return swarmListen() // no old port
    if (err) return cb(err)
    opts.port = Number(value)
    swarmListen()
  })

  function swarmListen () {
    self.swarm.listen(opts.port || DEFAULT_PORT)
  }
}

Dat.prototype.close = function (cb) {
  this.drive.core.db.close()
  this.swarm.destroy(cb)
}

Dat.prototype.metadata = function (link, cb) {
  var self = this
  var archive = self.drive.get(link)
  collect(archive.createEntryStream(), cb)
}

// returns object that is used to render progress bars
Dat.prototype.download = function (link, dir, cb) {
  var self = this
  if (!cb) cb = function noop () {}

  var stats = {}

  self.joinTcpSwarm(link, function (err, swarm) {
    if (err) return cb(err)
    swarm.downloading = true
    stats.downloadRate = speedometer()
    stats.downloaded = 0
    stats.swarm = swarm
    var archive = self.drive.get(swarm.link, dir)

    archive.ready(function (err) {
      if (err) return cb(err)
      swarm.blocks = archive.entries
      var download = self.fs.createDownloadStream(archive, stats)
      pump(archive.createEntryStream(), download, function (err) {
        cb(err, swarm)
      })
    })

    archive.on('file-download', function (entry, data, block) {
      stats.downloaded += data.length
      stats.downloadRate(data.length)
    })
  })

  return stats
}
<|endoftext|>


<commit_before>var CachingWriter = require('broccoli-caching-writer');
var path = require('path');
var fs = require('fs');
var merge = require('lodash.merge');
var omit = require('lodash.omit');
var uniq = require('lodash.uniq');
var mkdirp = require('mkdirp');

module.exports = ConcatWithMaps;
ConcatWithMaps.prototype = Object.create(CachingWriter.prototype);
ConcatWithMaps.prototype.constructor = ConcatWithMaps;

function ConcatWithMaps(inputNode, options, Strategy) {
  if (!(this instanceof ConcatWithMaps)) {
    return new ConcatWithMaps(inputNode, options, Strategy);
  }

  if (!options || !options.outputFile || !options.inputFiles) {
    throw new Error('inputFiles and outputFile options ware required');
  }

  CachingWriter.call(this, [inputNode], {
    inputFiles: options.inputFiles,
    annotation: options.annotation,
    name: (Strategy.name || 'Unknown') + 'Concat'
  });

  if (Strategy === undefined) {
    throw new TypeError('ConcatWithMaps requires a concat Strategy');
  }

  this.Strategy = Strategy;
  this.sourceMapConfig = omit(options.sourceMapConfig || {}, 'enabled');
  this.inputFiles = options.inputFiles;
  this.outputFile = options.outputFile;
  this.allowNone = options.allowNone;
  this.header = options.header;
  this.headerFiles = options.headerFiles;
  this._headerFooterFilesIndex = makeIndex(options.headerFiles, options.footerFiles);
  this.footer = options.footer;
  this.footerFiles = options.footerFiles;
  this.separator = (options.separator != null) ? options.separator : '\n';

  ensureNoMagic('headerFiles', this.headerFiles);
  ensureNoMagic('footerFiles', this.footerFiles);

  this.encoderCache = {};
}

var MAGIC = /[\{\}\*\[\]]/;

function ensureNoMagic(name, list) {
  (list || []).forEach(function(a) {
    if (MAGIC.test(a)) {
      throw new TypeError(name + ' cannot contain a glob,  `' + a + '`');
    }
  });
}

function makeIndex(a, b) {
  var index = Object.create(null);

  ((a || []).concat(b ||[])).forEach(function(a) {
    index[a] = true;
  });

  return index;
}

ConcatWithMaps.prototype.build = function() {
  var separator = this.separator;
  var firstSection = true;
  var outputFile = path.join(this.outputPath, this.outputFile);

  mkdirp.sync(path.dirname(outputFile));

  this.concat = new this.Strategy(merge(this.sourceMapConfig, {
    outputFile: outputFile,
    sourceRoot: this.sourceRoot,
    baseDir: this.inputPaths[0],
    cache: this.encoderCache
  }));

  return this.concat.end(function(concat) {
    function beginSection() {
      if (firstSection) {
        firstSection = false;
      } else {
        concat.addSpace(separator);
      }
    }

    if (this.header) {
      beginSection();
      concat.addSpace(this.header);
    }

    if (this.headerFiles) {
      this.headerFiles.forEach(function(file) {
        beginSection();
        concat.addFile(file);
      });
    }

    this.addFiles(beginSection);

    if (this.footerFiles) {
      this.footerFiles.forEach(function(file) {
        beginSection();
        concat.addFile(file);
      });
    }

    if (this.footer) {
      beginSection();
      concat.addSpace(this.footer + '\n');
    }
  }, this);
};

function isDirectory(fullPath) {
  // files returned from listFiles are directories if they end in /
  // see: https://github.com/joliss/node-walk-sync
  // "Note that directories come before their contents, and have a trailing slash"
  return fullPath.charAt(fullPath.length - 1) === '/';
}

ConcatWithMaps.prototype.addFiles = function(beginSection) {
  var headerFooterFileOverlap = false;
  var posixInputPath = ensurePosix(this.inputPaths[0]);

  var files = uniq(this.listFiles().map(ensurePosix)).filter(function(file){
    var relativePath = file.replace(posixInputPath + '/', '');

    // * remove inputFiles that are already contained within headerFiles and footerFiles
    // * alow duplicates between headerFiles and footerFiles

    if (this._headerFooterFilesIndex[relativePath] === true) {
      headerFooterFileOverlap = true;
      return false;
    }

    return !isDirectory(file);
  }, this);

  // raise IFF:
  //   * headerFiles or footerFiles overlapped with inputFiles
  //   * nothing matched inputFiles
  if (headerFooterFileOverlap === false &&
      files.length === 0 &&
      !this.allowNone) {
    throw new Error('ConcatWithMaps: nothing matched [' + this.inputFiles + ']');
  }

  files.forEach(function(file) {
    beginSection();
    this.concat.addFile(file.replace(posixInputPath + '/', ''));
  }, this);
};

function ensurePosix(filepath) {
  if (path.sep !== '/') {
    return filepath.split(path.sep).join('/');
  }
  return filepath;
}
<commit_msg>Remove unused this.sourceRoot (it was never set)<commit_after>var CachingWriter = require('broccoli-caching-writer');
var path = require('path');
var fs = require('fs');
var merge = require('lodash.merge');
var omit = require('lodash.omit');
var uniq = require('lodash.uniq');
var mkdirp = require('mkdirp');

module.exports = ConcatWithMaps;
ConcatWithMaps.prototype = Object.create(CachingWriter.prototype);
ConcatWithMaps.prototype.constructor = ConcatWithMaps;

function ConcatWithMaps(inputNode, options, Strategy) {
  if (!(this instanceof ConcatWithMaps)) {
    return new ConcatWithMaps(inputNode, options, Strategy);
  }

  if (!options || !options.outputFile || !options.inputFiles) {
    throw new Error('inputFiles and outputFile options ware required');
  }

  CachingWriter.call(this, [inputNode], {
    inputFiles: options.inputFiles,
    annotation: options.annotation,
    name: (Strategy.name || 'Unknown') + 'Concat'
  });

  if (Strategy === undefined) {
    throw new TypeError('ConcatWithMaps requires a concat Strategy');
  }

  this.Strategy = Strategy;
  this.sourceMapConfig = omit(options.sourceMapConfig || {}, 'enabled');
  this.inputFiles = options.inputFiles;
  this.outputFile = options.outputFile;
  this.allowNone = options.allowNone;
  this.header = options.header;
  this.headerFiles = options.headerFiles;
  this._headerFooterFilesIndex = makeIndex(options.headerFiles, options.footerFiles);
  this.footer = options.footer;
  this.footerFiles = options.footerFiles;
  this.separator = (options.separator != null) ? options.separator : '\n';

  ensureNoMagic('headerFiles', this.headerFiles);
  ensureNoMagic('footerFiles', this.footerFiles);

  this.encoderCache = {};
}

var MAGIC = /[\{\}\*\[\]]/;

function ensureNoMagic(name, list) {
  (list || []).forEach(function(a) {
    if (MAGIC.test(a)) {
      throw new TypeError(name + ' cannot contain a glob,  `' + a + '`');
    }
  });
}

function makeIndex(a, b) {
  var index = Object.create(null);

  ((a || []).concat(b ||[])).forEach(function(a) {
    index[a] = true;
  });

  return index;
}

ConcatWithMaps.prototype.build = function() {
  var separator = this.separator;
  var firstSection = true;
  var outputFile = path.join(this.outputPath, this.outputFile);

  mkdirp.sync(path.dirname(outputFile));

  this.concat = new this.Strategy(merge(this.sourceMapConfig, {
    outputFile: outputFile,
    baseDir: this.inputPaths[0],
    cache: this.encoderCache
  }));

  return this.concat.end(function(concat) {
    function beginSection() {
      if (firstSection) {
        firstSection = false;
      } else {
        concat.addSpace(separator);
      }
    }

    if (this.header) {
      beginSection();
      concat.addSpace(this.header);
    }

    if (this.headerFiles) {
      this.headerFiles.forEach(function(file) {
        beginSection();
        concat.addFile(file);
      });
    }

    this.addFiles(beginSection);

    if (this.footerFiles) {
      this.footerFiles.forEach(function(file) {
        beginSection();
        concat.addFile(file);
      });
    }

    if (this.footer) {
      beginSection();
      concat.addSpace(this.footer + '\n');
    }
  }, this);
};

function isDirectory(fullPath) {
  // files returned from listFiles are directories if they end in /
  // see: https://github.com/joliss/node-walk-sync
  // "Note that directories come before their contents, and have a trailing slash"
  return fullPath.charAt(fullPath.length - 1) === '/';
}

ConcatWithMaps.prototype.addFiles = function(beginSection) {
  var headerFooterFileOverlap = false;
  var posixInputPath = ensurePosix(this.inputPaths[0]);

  var files = uniq(this.listFiles().map(ensurePosix)).filter(function(file){
    var relativePath = file.replace(posixInputPath + '/', '');

    // * remove inputFiles that are already contained within headerFiles and footerFiles
    // * alow duplicates between headerFiles and footerFiles

    if (this._headerFooterFilesIndex[relativePath] === true) {
      headerFooterFileOverlap = true;
      return false;
    }

    return !isDirectory(file);
  }, this);

  // raise IFF:
  //   * headerFiles or footerFiles overlapped with inputFiles
  //   * nothing matched inputFiles
  if (headerFooterFileOverlap === false &&
      files.length === 0 &&
      !this.allowNone) {
    throw new Error('ConcatWithMaps: nothing matched [' + this.inputFiles + ']');
  }

  files.forEach(function(file) {
    beginSection();
    this.concat.addFile(file.replace(posixInputPath + '/', ''));
  }, this);
};

function ensurePosix(filepath) {
  if (path.sep !== '/') {
    return filepath.split(path.sep).join('/');
  }
  return filepath;
}
<|endoftext|>


<commit_before>/**
 *
 * input:
 *
 * {% multicodeblock %}
 * ---js esnext
 * const greeting = `hello ${name}`;
 * ---js es5
 * var greeting = 'hello ' + name;
 * ---php php
 * $greeting = 'hello ' . $name;
 * {% endmulticodeblock %}
 *
 * pseudo-output:
 *
 * {% raw %}
 *

 * {% endraw %}
 *
 * ```js
 * const greeting = `hello ${name}`;
 * ```
 *
 * ```js
 * var greeting = 'hello ' + name;
 * ```
 *
 * ```php
 * $greeting = 'hello ' . $name;
 * {% raw %}
 * </div>
 * {% endraw %}
 *
 *
 * You can also use a default language:
 *
 * {% multicodeblock js %}
 * --- esnext
 * const greeting = `hello ${name}`;
 * --- es5
 * var greeting = 'hello ' + name;
 * {% endmulticodeblock %}
 *
 */

const { highlight } = require('hexo-util');

const parse = ([defaultLanguage], content) => {
  const [_, ...textParts] = content.split('---');

  const objectParts = textParts.map((textPart) => {
    const [configText, ...content] = textPart.split('\n');
    const [language, slot] = configText.split(' ');

    return {
      config: {
        language,
        slot
      },
      content: content.join('\n')
    };
  });

  const htmlParts = objectParts.map((objectPart) => {
    const codeblock = highlight(objectPart.content, {
      lang: objectPart.config.language || defaultLanguage || 'js',
      wrap: false,
      gutter: false
    });

    console.log(objectPart);

    const [codeblockTag, ...content] = codeblock.split('\n');
    const [codeblockTagName, ...codeblockTagParts] = codeblockTag.split('>');
    return`${codeblockTagName} slot=${objectPart.config.slot || defaultLanguage || 'js'}>${codeblockTagParts.join('>')}\n${content.join('\n')}`
  });

  return `
<div class="hexo-multi-codeblock">
\t${htmlParts.join('\n\t')}
</div>
`
}

hexo.extend.tag.register('multicodeblock', parse, {ends: true})
<commit_msg>testing<commit_after>/**
 *
 * input:
 *
 * {% multicodeblock %}
 * ---js esnext
 * const greeting = `hello ${name}`;
 * ---js es5
 * var greeting = 'hello ' + name;
 * ---php php
 * $greeting = 'hello ' . $name;
 * {% endmulticodeblock %}
 *
 * pseudo-output:
 *
 * {% raw %}
 * <div class="hexo-multi-codeblock">
 * {% endraw %}
 *   <!-- this will be <figure slot="esnext" ...>...</figure> -->
 * ```js
 * const greeting = `hello ${name}`;
 * ```
 *   <!-- <figure slot="es5" ...>...</figure> -->
 * ```js
 * var greeting = 'hello ' + name;
 * ```
 *   <!-- <figure slot="php" ...>...</figure> -->
 * ```php
 * $greeting = 'hello ' . $name;
 * {% raw %}
 *

 * {% endraw %}
 *
 *
 * You can also use a default language:
 *
 * {% multicodeblock js %}
 * --- esnext
 * const greeting = `hello ${name}`;
 * --- es5
 * var greeting = 'hello ' + name;
 * {% endmulticodeblock %}
 *
 */

const { highlight } = require('hexo-util');

const parse = ([defaultLanguage], content) => {
  const [_, ...textParts] = content.split('---');

  const objectParts = textParts.map((textPart) => {
    const [configText, ...content] = textPart.split('\n');
    const [language, slot] = configText.split(' ');

    return {
      config: {
        language: language || defaultLanguage || 'js',
        slot
      },
      content: content.join('\n')
    };
  });

  const htmlParts = objectParts.map((objectPart) => {
    const codeblock = highlight(objectPart.content, {
      lang: objectPart.config.language,
      wrap: false,
      gutter: false
    });
    console.log(codeblock, objectPart);

    const [codeblockTag, ...content] = codeblock.split('\n');
    const [codeblockTagName, ...codeblockTagParts] = codeblockTag.split('>');
    return`${codeblockTagName} slot=${objectPart.config.slot || defaultLanguage || 'js'}>${codeblockTagParts.join('>')}\n${content.join('\n')}`
  });

  return `

\t${htmlParts.join('\n\t')}

`
}

hexo.extend.tag.register('multicodeblock', parse, {ends: true})
<|endoftext|>


<commit_before>/* global ux, utils */
angular.module('ux').service('focusKeyboard', function (focusManager) {

    var tabKeysEnabled = false,
        arrowKeysEnabled = false;

    function enableTabKeys() {
        if (!tabKeysEnabled) {
            tabKeysEnabled = true;
        }
    }

    function disableTabKeys() {
        if (tabKeysEnabled) {
            tabKeysEnabled = false;
        }
    }

    function enableArrowKeys() {
        if (!arrowKeysEnabled) {
            arrowKeysEnabled = true;
        }
    }

    function disableArrowKeys() {
        if (arrowKeysEnabled) {
            arrowKeysEnabled = false;
        }
    }

    function toggleTabArrowKeys() {
        if (tabKeysEnabled) {
            disableTabKeys();
            enableArrowKeys();
        } else {
            enableTabKeys();
            disableArrowKeys();
        }
    }

    function triggerClick(evt) {
        evt.preventDefault();
        evt.stopPropagation();

        fireEvent(evt.target, 'mousedown');
        fireEvent(evt.target, 'mouseup');
        fireEvent(evt.target, 'click');
    }

    function onFocusNext(evt) {

        if (focusManager.enabled) {
            focusManager.next();
        }

        if (!focusManager.enabled) {
            return;
        }

        evt.preventDefault();
        evt.stopPropagation();

        return false;
    }

    function onFocusPrev(evt) {

        if (focusManager.enabled) {
            focusManager.prev();
        }

        if (!focusManager.enabled) {
            return;
        }

        evt.preventDefault();
        evt.stopPropagation();

        return false;
    }

    function fireEvent(node, eventName) {
        // Make sure we use the ownerDocument from the provided node to avoid cross-window problems
        var doc, event;
        if (node.ownerDocument) {
            doc = node.ownerDocument;
        } else if (node.nodeType === 9) {
            // the node may be the document itself, nodeType 9 = DOCUMENT_NODE
            doc = node;
        }
//        else {
//            throw new Error("Invalid node passed to fireEvent: " + node.id);
//        }

        if (node.dispatchEvent) {
            // Gecko-style approach (now the standard) takes more work
            var eventClass = "";

            // Different events have different event classes.
            // If this switch statement can't map an eventName to an eventClass,
            // the event firing is going to fail.
            switch (eventName) {
                case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
                case "mousedown":
                case "mouseup":
                    eventClass = "MouseEvents";
                    break;

//                case "focus":
//                case "change":
//                case "blur":
//                case "select":
//                    eventClass = "HTMLEvents";
//                    break;

//                default:
//                    throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
//                    break;
            }
            event = doc.createEvent(eventClass);

            var bubbles = eventName === "change" ? false : true;
            event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable.

            event.synthetic = true; // allow detection of synthetic events
            // The second parameter says go ahead with the default action
            node.dispatchEvent(event, true);
        } else if (node.fireEvent) {
            // IE-old school style
            event = doc.createEventObject();
            event.synthetic = true; // allow detection of synthetic events
            node.fireEvent("on" + eventName, event);
        }
    }

    function enable() {
        utils.addEvent(document, 'keydown', onKeyDown);
    }

    function disable() {
        utils.removeEvent(document, 'keydown', onKeyDown);
    }

    function onKeyDown(evt) {
        if (tabKeysEnabled) {
            if (evt.keyCode === 9) { // tab
                if (evt.shiftKey) {
                    onFocusPrev(evt);
                } else {
                    onFocusNext(evt);
                }
            }
        }

        if (arrowKeysEnabled) {
            if (!(evt.shiftKey || evt.altKey || evt.ctrlKey)) {
                if (evt.keyCode === 37) { // left arrow
                    onFocusPrev(evt);
                } else if (evt.keyCode === 38) { // up arrow
                    onFocusPrev(evt);
                } else if (evt.keyCode === 39) { //right arrow
                    onFocusNext(evt);
                } else if (evt.keyCode === 40) { // down arrow
                    onFocusNext(evt);
                }
            }
        }
        if (!(evt.shiftKey || evt.altKey || evt.ctrlKey)) {
            if (evt.keyCode === 13) {
                triggerClick(evt);
            }
        }
    }

    this.enable = enable;
    this.disable = disable;
    this.enableTabKeys = enableTabKeys;
    this.disableTabKeys = disableTabKeys;
    this.enableArrowKeys = enableArrowKeys;
    this.disableArrowKeys = disableArrowKeys;
    this.toggleTabArrowKeys = toggleTabArrowKeys;
    this.triggerClick = triggerClick;
})
    .run(function (focusKeyboard) {
        focusKeyboard.enable();
        focusKeyboard.enableTabKeys();
    });

<commit_msg>fix in keyboard to check for activeElement in focus manager before using event target<commit_after>/* global ux, utils */
angular.module('ux').service('focusKeyboard', function (focusManager) {

    var tabKeysEnabled = false,
        arrowKeysEnabled = false;

    function enableTabKeys() {
        if (!tabKeysEnabled) {
            tabKeysEnabled = true;
        }
    }

    function disableTabKeys() {
        if (tabKeysEnabled) {
            tabKeysEnabled = false;
        }
    }

    function enableArrowKeys() {
        if (!arrowKeysEnabled) {
            arrowKeysEnabled = true;
        }
    }

    function disableArrowKeys() {
        if (arrowKeysEnabled) {
            arrowKeysEnabled = false;
        }
    }

    function toggleTabArrowKeys() {
        if (tabKeysEnabled) {
            disableTabKeys();
            enableArrowKeys();
        } else {
            enableTabKeys();
            disableArrowKeys();
        }
    }

    function triggerClick(evt) {
        evt.preventDefault();
        evt.stopPropagation();

        var activeElement = focusManager.activeElement || evt.target;

        fireEvent(activeElement, "mousedown");
        fireEvent(activeElement, "mouseup");
        fireEvent(activeElement, "click");
    }

    function onFocusNext(evt) {

        if (focusManager.enabled) {
            focusManager.next();
        }

        if (!focusManager.enabled) {
            return;
        }

        evt.preventDefault();
        evt.stopPropagation();

        return false;
    }

    function onFocusPrev(evt) {

        if (focusManager.enabled) {
            focusManager.prev();
        }

        if (!focusManager.enabled) {
            return;
        }

        evt.preventDefault();
        evt.stopPropagation();

        return false;
    }

    function fireEvent(node, eventName) {
        // Make sure we use the ownerDocument from the provided node to avoid cross-window problems
        var doc, event;
        if (node.ownerDocument) {
            doc = node.ownerDocument;
        } else if (node.nodeType === 9) {
            // the node may be the document itself, nodeType 9 = DOCUMENT_NODE
            doc = node;
        }
//        else {
//            throw new Error("Invalid node passed to fireEvent: " + node.id);
//        }

        if (node.dispatchEvent) {
            // Gecko-style approach (now the standard) takes more work
            var eventClass = "";

            // Different events have different event classes.
            // If this switch statement can't map an eventName to an eventClass,
            // the event firing is going to fail.
            switch (eventName) {
                case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
                case "mousedown":
                case "mouseup":
                    eventClass = "MouseEvents";
                    break;

//                case "focus":
//                case "change":
//                case "blur":
//                case "select":
//                    eventClass = "HTMLEvents";
//                    break;

//                default:
//                    throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
//                    break;
            }
            event = doc.createEvent(eventClass);

            var bubbles = eventName === "change" ? false : true;
            event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable.

            event.synthetic = true; // allow detection of synthetic events
            // The second parameter says go ahead with the default action
            node.dispatchEvent(event, true);
        } else if (node.fireEvent) {
            // IE-old school style
            event = doc.createEventObject();
            event.synthetic = true; // allow detection of synthetic events
            node.fireEvent("on" + eventName, event);
        }
    }

    function enable() {
        utils.addEvent(document, 'keydown', onKeyDown);
    }

    function disable() {
        utils.removeEvent(document, 'keydown', onKeyDown);
    }

    function onKeyDown(evt) {
        if (tabKeysEnabled) {
            if (evt.keyCode === 9) { // tab
                if (evt.shiftKey) {
                    onFocusPrev(evt);
                } else {
                    onFocusNext(evt);
                }
            }
        }

        if (arrowKeysEnabled) {
            if (!(evt.shiftKey || evt.altKey || evt.ctrlKey)) {
                if (evt.keyCode === 37) { // left arrow
                    onFocusPrev(evt);
                } else if (evt.keyCode === 38) { // up arrow
                    onFocusPrev(evt);
                } else if (evt.keyCode === 39) { //right arrow
                    onFocusNext(evt);
                } else if (evt.keyCode === 40) { // down arrow
                    onFocusNext(evt);
                }
            }
        }
        if (!(evt.shiftKey || evt.altKey || evt.ctrlKey)) {
            if (evt.keyCode === 13) {
                triggerClick(evt);
            }
        }
    }

    this.enable = enable;
    this.disable = disable;
    this.enableTabKeys = enableTabKeys;
    this.disableTabKeys = disableTabKeys;
    this.enableArrowKeys = enableArrowKeys;
    this.disableArrowKeys = disableArrowKeys;
    this.toggleTabArrowKeys = toggleTabArrowKeys;
    this.triggerClick = triggerClick;
})
    .run(function (focusKeyboard) {
        focusKeyboard.enable();
        focusKeyboard.enableTabKeys();
    });

<|endoftext|>


<commit_before>'use strict';
var fs = require('fs'),
	es = require('event-stream'),
	File = require('gulp-util').File,
	gutil = require('gulp-util'),
	through = require('through2');

/**
 * gulp-license-check plugin, support buffer and stream.
 *
 * @param {string} path - The license header template file path.
 * @param {boolean} [true] blocking - Enable the plugin to block the build in case of error .
 * @param {boolean} [true] logInfo - Enable info log .
 * @param {boolean} [true] logError - Enable errors log.

 * @returns {object} Gulp extension in the pipline.
 */
module.exports = function (opts) {

	opts = opts || {};

	var HEADER_NOT_PRESENT = 'Header not present';
	var HEADER_PRESENT = 'Header present';

	var isInfoLogActive = opts.logInfo === undefined ? true : opts.logInfo,
		isErrorLogActive = opts.logError === undefined ? true : opts.logError,
		isErrorBlocking = opts.blocking === undefined ? true : opts.blocking,
		licenseFilePath = opts.path;

	return through.obj(function (file, encoding, callback) {
		if (file.isNull()) {
			return callback(null, file);
		}

		try {
			if (file.isStream()) {
				checkHeaderFromStream(file, this);
			} else {
				checkHeaderFromBuffer(file, this);
			}
		} catch (error) {
			callback(error, null);
			return;
		}

		callback(null, file);
	});

	/**
	 * Check header from stream.
	 *
	 * @param {object} file - current file from stream.
	 * @param {object} ctx - context.
	 *
	 * @returns {string[]} file in string[] format.
	 */
	function checkHeaderFromStream(file, ctx) {
		file.contents.pipe(es.wait(function (err, data) {
			if (err) {
				throw err;
			}

			var bufferFile = new File({
				path: file.path,
				contents: data
			});

			checkHeaderFromBuffer(bufferFile, ctx);
		}));
	}

	/**
	 * Check header from buffer.
	 *
	 * @param {object} file - current file from buffer.
	 * @param {object} ctx - context.
	 */
	function checkHeaderFromBuffer(file, ctx) {
		if (isLicenseHeaderPresent(file)) {
			log(file.path, ctx);
		} else {
			error(file.path, ctx);
		}
	}

	/**
	 * Read current file.
	 *
	 * @param {object} file - current file.
	 *
	 * @returns {string[]} file in string[] format.
	 */
	function readCurrentFile(file) {
		return file.contents.toString('utf8').split(/\r?\n/);
	}

	/**
	 * Read the file header path.
	 *
	 * @returns {string[]} The license header template in sting[] format.
	 */
	function readLicenseHeaderFile() {
		if (fs.existsSync(licenseFilePath)) {
			return fs.readFileSync(licenseFilePath, 'utf8').split(/\r?\n/);
		}

		throw new gutil.PluginError('gulp-license-check', new Error('The license header file doesn`t exist ' + licenseFilePath));
	}

	/**
	 * Log util.
	 *
	 * @param {string} filePath - file Path.
	 * @param {object} ctx - context.
	 */
	function log(filePath, ctx) {
		if (isInfoLogActive) {
			ctx.emit('log', {
				msg: HEADER_PRESENT,
				path: filePath
			});
			gutil.log(gutil.colors.green(HEADER_PRESENT), filePath);
		}
	}

	/**
	 * Manage error in case the header is not present.
	 *
	 * @param {string} filePath - file Path.
	 * @param {object} ctx - context.
	 */
	function error(filePath, ctx) {
		if (isErrorBlocking) {
			throw new gutil.PluginError('gulp-license-check', new Error('The following file doesn`t contain the license header ' + filePath));
		} else {
			logError(filePath, ctx);
		}
	}

	/**
	 * Log error.
	 *
	 * @param {string} filePath - file Path.
	 * @param {object} ctx - context.
	 */
	function logError(filePath, ctx) {
		if (isErrorLogActive) {
			ctx.emit('log', {
				msg: HEADER_NOT_PRESENT,
				path: filePath
			});
			gutil.log(gutil.colors.red(HEADER_NOT_PRESENT), filePath);
		}
	}

	/**
	 * Check if header is present.
	 *
	 * @param {object} currentFile - file in string[] format.
	 *
	 * @returns {boolean} dose match.
	 */
	function isLicenseHeaderPresent(currentFile) {
		if (!isFileEmpty(currentFile.contents)) {
			var currentFileUtf8 = readCurrentFile(currentFile),
				licenseFileUtf8 = readLicenseHeaderFile();

			for (var i = 0; i < licenseFileUtf8.length; i++) {
				if (currentFileUtf8[i] !== licenseFileUtf8[i]) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * Check if a file is empty.
	 *
	 * @param {string} file - file contents in string format.
	 *
	 * @returns {boolean}.
	 */
	function isFileEmpty(fileContents) {
		return fileContents.toString('utf8').trim() === '';
	}
};
<commit_msg>Fix test for licenses with trailing newlines<commit_after>'use strict';
var fs = require('fs'),
	es = require('event-stream'),
	File = require('gulp-util').File,
	gutil = require('gulp-util'),
	through = require('through2');

/**
 * gulp-license-check plugin, support buffer and stream.
 *
 * @param {string} path - The license header template file path.
 * @param {boolean} [true] blocking - Enable the plugin to block the build in case of error .
 * @param {boolean} [true] logInfo - Enable info log .
 * @param {boolean} [true] logError - Enable errors log.

 * @returns {object} Gulp extension in the pipline.
 */
module.exports = function (opts) {

	opts = opts || {};

	var HEADER_NOT_PRESENT = 'Header not present';
	var HEADER_PRESENT = 'Header present';

	var isInfoLogActive = opts.logInfo === undefined ? true : opts.logInfo,
		isErrorLogActive = opts.logError === undefined ? true : opts.logError,
		isErrorBlocking = opts.blocking === undefined ? true : opts.blocking,
		licenseFilePath = opts.path;

	return through.obj(function (file, encoding, callback) {
		if (file.isNull()) {
			return callback(null, file);
		}

		try {
			if (file.isStream()) {
				checkHeaderFromStream(file, this);
			} else {
				checkHeaderFromBuffer(file, this);
			}
		} catch (error) {
			callback(error, null);
			return;
		}

		callback(null, file);
	});

	/**
	 * Check header from stream.
	 *
	 * @param {object} file - current file from stream.
	 * @param {object} ctx - context.
	 *
	 * @returns {string[]} file in string[] format.
	 */
	function checkHeaderFromStream(file, ctx) {
		file.contents.pipe(es.wait(function (err, data) {
			if (err) {
				throw err;
			}

			var bufferFile = new File({
				path: file.path,
				contents: data
			});

			checkHeaderFromBuffer(bufferFile, ctx);
		}));
	}

	/**
	 * Check header from buffer.
	 *
	 * @param {object} file - current file from buffer.
	 * @param {object} ctx - context.
	 */
	function checkHeaderFromBuffer(file, ctx) {
		if (isLicenseHeaderPresent(file)) {
			log(file.path, ctx);
		} else {
			error(file.path, ctx);
		}
	}

	/**
	 * Read current file.
	 *
	 * @param {object} file - current file.
	 *
	 * @returns {string[]} file in string[] format.
	 */
	function readCurrentFile(file) {
		return file.contents.toString('utf8');
	}

	/**
	 * Read the file header path.
	 *
	 * @returns {string[]} The license header template in sting[] format.
	 */
	function readLicenseHeaderFile() {
		if (fs.existsSync(licenseFilePath)) {
			return fs.readFileSync(licenseFilePath, 'utf8');
		}

		throw new gutil.PluginError('gulp-license-check', new Error('The license header file doesn`t exist ' + licenseFilePath));
	}

	/**
	 * Log util.
	 *
	 * @param {string} filePath - file Path.
	 * @param {object} ctx - context.
	 */
	function log(filePath, ctx) {
		if (isInfoLogActive) {
			ctx.emit('log', {
				msg: HEADER_PRESENT,
				path: filePath
			});
			gutil.log(gutil.colors.green(HEADER_PRESENT), filePath);
		}
	}

	/**
	 * Manage error in case the header is not present.
	 *
	 * @param {string} filePath - file Path.
	 * @param {object} ctx - context.
	 */
	function error(filePath, ctx) {
		if (isErrorBlocking) {
			throw new gutil.PluginError('gulp-license-check', new Error('The following file doesn`t contain the license header ' + filePath));
		} else {
			logError(filePath, ctx);
		}
	}

	/**
	 * Log error.
	 *
	 * @param {string} filePath - file Path.
	 * @param {object} ctx - context.
	 */
	function logError(filePath, ctx) {
		if (isErrorLogActive) {
			ctx.emit('log', {
				msg: HEADER_NOT_PRESENT,
				path: filePath
			});
			gutil.log(gutil.colors.red(HEADER_NOT_PRESENT), filePath);
		}
	}

	/**
	 * Check if header is present.
	 *
	 * @param {object} currentFile - file in string[] format.
	 *
	 * @returns {boolean} dose match.
	 */
	function isLicenseHeaderPresent(currentFile) {
		if (!isFileEmpty(currentFile.contents)) {
			var currentFileUtf8 = readCurrentFile(currentFile),
				licenseFileUtf8 = readLicenseHeaderFile();

			for (var i = 0; i < licenseFileUtf8.length; i++) {
				if (currentFileUtf8[i] !== licenseFileUtf8[i]) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * Check if a file is empty.
	 *
	 * @param {string} file - file contents in string format.
	 *
	 * @returns {boolean}.
	 */
	function isFileEmpty(fileContents) {
		return fileContents.toString('utf8').trim() === '';
	}
};
<|endoftext|>