<commit_before>/*
Copyright (c) 2016, Tomohito Nakayama. All rights reserved.
Copyrights licensed under the New BSD License.
See the accompanying LICENSE file for terms.
*/

'use strict';

const fs = require('fs');
const path = require('path');

const bson = require('bson');
const BSON = new bson.BSONPure.BSON();

const EventEmitter = require('events');
const util = require('util');

const initialValue = {};

const JB_JSON = 'j';
const JB_BSON = 'b';

module.exports = {};

module.exports.initialValue =
  function() { return initialValue; };

module.exports.filed =
  function (file, errListener) {
     return addErrorListener( new filedExecuter (file), errListener );
   }

function executer( root ){
 this.executeChild = function( p1,p2 ){};

 this.io = addChildExecuterFunction(createExecuterFactory(ioExecuter,root),this);
 this.copy = addChildExecuterFunction(createExecuterFactory(copyExecuter,root),this);
 this.link = addChildExecuterFunction(createExecuterFactory(linkExecuter,root),this);
 this.pass = addChildExecuterFunction(createExecuterFactory(passExecuter,root),this);
 this.filter = addChildExecuterFunction(createExecuterFactory(filterExecuter,root),this);

}

function filedExecuter( file ){

  executer.call( this, this)
  let thisExecuter = this;
  this.exec = function(){ filedExecute( file, thisExecuter.executeChild, thisExecuter); };

};

function childExecuter( userProcess, root){

  executer.call( this, root );

  this.generalInternalExec = function ( filePath, jb , executerFunction) {
    executerFunction ( filePath, userProcess, jb, this.executeChild );
  }

  this.exec = function(){
    root.exec()
  };

}

function ioExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function(filePath, jb){
    this.generalInternalExec( filePath, jb, io);
  }

};

function copyExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function( filePath, jb){
    this.generalInternalExec( filePath, jb, copy);
  }

};

function linkExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function( filePath, jb){
    this.generalInternalExec( filePath, jb, link);
  }

};

function passExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function( filePath, jb){
    this.generalInternalExec( filePath, jb, pass);
  }

};

function filterExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function( filePath, jb){
    this.generalInternalExec( filePath, jb, filter);
  }

};

util.inherits( executer, EventEmitter);

util.inherits( filedExecuter, executer);

util.inherits( childExecuter, executer);
util.inherits( ioExecuter, childExecuter);
util.inherits( copyExecuter, childExecuter);
util.inherits( linkExecuter, childExecuter);
util.inherits( passExecuter, childExecuter);
util.inherits( filterExecuter, childExecuter);

function createExecuterFactory(classFunction,root){
  return function(userProcess){ return new classFunction( userProcess, root) };
}

function addChildExecuterFunction( executerFactory, parent ){

  var f = function( userProcess, errListener ){ //function to create child executer.

    let executer = executerFactory( userProcess );
    userProcess._plannedExecuter = executer; //hack to emit error from userProcess by executer.

    parent.executeChild = function( filePath ){ //switch state of parent also.
      try{
        executer.internalExec(
          filePath,
          calcJb( filePath )
        );

      }catch(err){
        raiseError(executer,err.toString(),err);
      }
    }

    if( errListener != null ){
      addErrorListener( executer, errListener);
    }

    return executer;

  }

  return f;//return function added to parent.

}

function filedExecute( file, execute, filedExecuter){
  let itr = pathIterator( file, filedExecuter);
  for( let filePath of itr ){
    execute(filePath, calcJb(filePath) );
  }
}

function pathIterator( file, filedExecuter){
  try{
    if ( typeof file == 'string' ){
      return singlePath(file);
    } else if ( file[ Symbol.iterator ] ) {
      return file;
    } else {
      throw new Error();
    }
  } catch ( error ) {
    raiseError( filedExecuter, 'Failed to create path Iterator' );
  }

  return [];

}

function * singlePath( file ){
  yield file;
}

function io( filePath, userProcess, jb, chainedProcess){

  process(
    filePath,
    userProcess,
    jb,
    chainedProcess,
    saveAfterApply,
    function(){
      //file to read does not exists.
      //create file with initial value and process json.
      fs.open(
        filePath,
        'w+',
        (err,fd) => {

          if(err) raiseError( userProcess._plannedExecuter, 'IOError Failed to create file.') ;

          //save to file and apply process.
          save(
            initialValue,
            fd,
            function(){
                //apply process
                apply(
                  userProcess,
                  initialValue,
                  fd,
                  function(afterCloseProcess){// close descriptor.
                    fs.close(
                      fd,
                      function(err){
                        if(err) raiseError( userProcess._plannedExecuter, "io:failsed to close file");
                        afterCloseProcess();
                      }
                    );
                  },
                  jb,
                  filePath,
                  saveAfterApply,
                  chainedProcess
                );
            },
            jb
          );

        }
      );
    }
  );

}

function link( filePath, userProcess, jb, chainedProcess ){
  process(filePath, userProcess, jb, chainedProcess, fsLink,
    raiseUnknownErrorFunction( userProcess._plannedExecuter ) // link does not create new file when not existed
  );
}

function copy( filePath, userProcess, jb, chainedProcess ){
  process(filePath, userProcess, jb, chainedProcess, fsCopy,
    raiseUnknownErrorFunction( userProcess._plannedExecuter ) //copy does not create new file when not existed
  );
}

function pass( filePath, userProcess, jb, chainedProcess){
  process(filePath, userProcess, jb, chainedProcess, passPostProcess,
    raiseUnknownErrorFunction( userProcess._plannedExecuter ) //pass dows not create new file when not existed
  );
}

function filter( filePath, userProcess, jb, chainedProcess){
  process(filePath,
    filternize(userProcess),
    jb,
    chainedProcess,
    filterPostProcess,
    raiseUnknownErrorFunction( userProcess._plannedExecuter) //pass does not create new file when not existed
  );
}

function process(
  filePath,
  userProcess,
  jb,
  chainedProcess,
  jfProcess,
  fileCreationProcess // process to create file when not existed
){

  fs.open(
    filePath,
    'r+',
    (err,fd) => {

      if( ! err ){
        //file exists.

        //read from file and process
        fs.readFile(
          fd,
          encoding(jb),
          (err, data) => {

            if (err) raiseError( userProcess._plannedExecuter, 'IOError Failed to read file.',err);
            fs.close(
              fd,
              function(err){
                if(err) raiseError( userProcess._plannedExecuter, 'IOError Failed to close file',err);

                var json = decode( data, jb);
                apply(
                  userProcess,
                  json,
                  filePath,
                  function( afterCloseProcess ){ afterCloseProcess() }, // closed already and no need to close, but need to call chained process
                  jb,
                  filePath,
                  jfProcess,
                  chainedProcess
                );

              }
            );
          }
        );
      }else{
        //file not exists.
        fileCreationProcess();

      }
    }
  );
}

//(*->*) -> (*->boolean) and a littile bit more.
function filternize( userProcess ){
  // return true/false according to result of user process.
  let result =
    wrapUserProcess(
      userProcess,
      function( process ){
        return function(obj,filePath){
            if( process ( obj, filePath) ) return true;
            else return false;
        };
      }
    );
  return result;

}

function guardProcess( userProcess ){

  let guarded =
    wrapUserProcess(
      userProcess,
      function( userProcess ){
        return function( json, filePath, errListener){
          try{
            return userProcess( json, filePath, errListener);

          }catch(err){

            //walkaround for unclear this/caller problem in javascript.
            //I just wanted to use something like "this".
            raiseError(
              userProcess._plannedExecuter.listenerCount('error') > 0 ?
              userProcess._plannedExecuter :
              defaultEmitter ,
              'User process error',
              err
            );

          }
        };
      }
    );

  return guarded;

}

function wrapUserProcess( userProcess, functionWrapper ){

  //To keep _plannedExecuter hack working, this function is needed to use when wrapping userProcess.
  let wrapped = functionWrapper( userProcess );
  wrapped._plannedExecuter = userProcess._plannedExecuter;//hack to emit error from userProcess by executer.

  return wrapped;

}

//apply process function to json.
function apply( process, json, file, closeFile, jb, filePath, postProcess, chainedProcess){

  let guardedProcess = guardProcess(process);

  if( chainedProcess == undefined ) chainedProcess = function(p1,p2){};

  var result = guardedProcess(json, filePath, guardedProcess._plannedExecuter);

  if(result != undefined && result != null){
    //if result returned, executePostProcess
    postProcess(
      result,
      file,
      closeFile, //executed after saved.
      jb,
      filePath,
      chainedProcess,
      guardedProcess._plannedExecuter
    );

  }else{
    closeFile( function(){ chainedProcess( filePath )} );
  }

}

//file can be either of file path and descriptor

function save( data, file, closeFile, jb, executer){
  saveCore( data,file, closeFile, jb, null, null, executer);
}

function saveAfterApply( data, file, closeFile, jb, filePath, chainedProcess, executer){
  saveCore(data,file,closeFile,jb,filePath,chainedProcess);
}

function saveCore( data, file, closeFile, jb,
                    filePath, chainedProcess, //only passsed in saveAfterApplly
                    executer
                  ){

  try{
    fs.writeFile(
      file,
      encode(data,jb),
      encoding(jb),
      (err)=>{
        closeFile(
          function() {
            if( chainedProcess ) chainedProcess(filePath);
          }
        );//file is closed in afterSaved, if needed.
        if (err) raiseError( executer, 'IOError failed to save json');
      }
    );
  }catch(error){
    closeFile(
      function() {
        if( chainedProcess ) chainedProcess(filePath);
      }
    );
    raiseError( executer, "failed in save", error);
  }
}

function fsCopy( copied2Path, file, closeFile, jb, originalFilePath, chainedProcess, executer ){ //"fs" is to avoid name conflict.

  let itr = pathIterator( copied2Path );
  for(let newFilePath of itr ){

    fsPipe(originalFilePath,newFilePath)
    .then(
      function() {
        if( chainedProcess ) chainedProcess( newFilePath );})
    .catch(
      function(err) {
        raiseError(
          executer,
          "Failed to copy from " + originalFilePath + " to " + newFilePath,
          err
        )
        if( chainedProcess ) chainedProcess( newFilePath );
      }
    );

  }
}

function fsPipe( fromPath, toPath, callback){

  return new Promise( //Use Promise as experiment.
    function(resolver, rejecter){

      let readStream = fs.createReadStream(fromPath);
      let writeStream = fs.createWriteStream(toPath,{flags: 'wx'}); //to escape copy between same files.

      //readStream.on('end',()=>{} ); // rely on end feature
      writeStream.on('finish',() => { resolver();} );

      readStream.on('error',(err) => { rejecter(err) } );
      writeStream.on('error',(err) => { rejecter(err) } );

      readStream.pipe(writeStream);

    }
  );

}

function fsLink( linkPath, file, closeFile, jb, originalFilePath, chainedProcess, executer){ //"fs" is to avoid name conflict.

  //link runs only after file was closed. closeFile is passed as compatibility of postProcess interface
  //closeFile();
  let itr = pathIterator( linkPath );
  for(let newFilePath of itr ){
    fs.link(
      originalFilePath,
      newFilePath,
      function(err){
        if(err) raiseError( executer, "Failed to link from " + originalFilePath + " to " + newFilePath,err);
        if( chainedProcess ) chainedProcess( newFilePath );
      }
    );
  }
}

function passPostProcess( result, file, closeFile, jb, originalFilePath, chainedProcess ){
  if( chainedProcess ) chainedProcess( originalFilePath );
}

function filterPostProcess( result, file, closeFile, jb, originalFilePath, chainedProcess ){
  if( result && chainedProcess ) chainedProcess( originalFilePath );
}

function encoding( jb ){
  if( jb == JB_BSON ) return null;
  else if( jb == JB_JSON ) return 'utf8';
  else raiseError(null, 'encoding: jb must be JSON or BSON');
}

function decode( obj, jb ){
  if( jb == JB_BSON ){
    return BSON.deserialize(
      obj,
      {
        evalFunctions: true,
        cacheFunctions: true
      }//experimental
    );
  }
  else if ( jb == JB_JSON ) return JSON.parse(obj);
  else raiseError( null, 'decode: jb must be JSON or BSON');
}

function encode( obj, jb ){
  if( jb == JB_BSON ) {
    return BSON.serialize(
      obj,
      false,
      true,
      true //experimental
    );
  }
  else if( jb == JB_JSON ) return JSON.stringify( obj );
  else raiseError( null, 'encode: jb must be JSON or BSON');
}

function calcJb( filePath ){

  switch( path.extname( filePath ).toLowerCase() ){

    case ".bson":
      return JB_BSON;

    case ".json":
    default:
      return JB_JSON;

  }
}

function JsonFiledError(msg,innerError){
  this.msg = msg;
  this.innerError = innerError;
};

util.inherits(JsonFiledError,Error);

function raiseError(emitter, msg, innerError){
  if( emitter == null || emitter == undefined){
    emitter = defaultEmitter;
  }
  emitter.emit( 'error', new JsonFiledError( msg, innerError));
}

function raiseUnknownErrorFunction(emitter){
  return function(){
    raiseError( emitter, "Unknown error.", null);
  }
}

var defaultErrorListener = function ( error ){
  console.error( error );
  throw error; //defaut Listener does not adohere keep running.
}

function addErrorListener(emitter, errListener){

  emitter.on(
    'error',
    errListener == undefined || errListener == null ?
    defaultErrorListener :
    errListener
  );
  return emitter;

}

function DefaultEmitter () {};
util.inherits( DefaultEmitter, EventEmitter);
let defaultEmitter = new DefaultEmitter();

defaultEmitter.on( 'error', defaultErrorListener);

module.exports.defaultEmitter = defaultEmitter;

module.exports.JsonFiledError = JsonFiledError;
<commit_msg>Rollback experimant of Promise<commit_after>/*
Copyright (c) 2016, Tomohito Nakayama. All rights reserved.
Copyrights licensed under the New BSD License.
See the accompanying LICENSE file for terms.
*/

'use strict';

const fs = require('fs');
const path = require('path');

const bson = require('bson');
const BSON = new bson.BSONPure.BSON();

const EventEmitter = require('events');
const util = require('util');

const initialValue = {};

const JB_JSON = 'j';
const JB_BSON = 'b';

module.exports = {};

module.exports.initialValue =
  function() { return initialValue; };

module.exports.filed =
  function (file, errListener) {
     return addErrorListener( new filedExecuter (file), errListener );
   }

function executer( root ){
 this.executeChild = function( p1,p2 ){};

 this.io = addChildExecuterFunction(createExecuterFactory(ioExecuter,root),this);
 this.copy = addChildExecuterFunction(createExecuterFactory(copyExecuter,root),this);
 this.link = addChildExecuterFunction(createExecuterFactory(linkExecuter,root),this);
 this.pass = addChildExecuterFunction(createExecuterFactory(passExecuter,root),this);
 this.filter = addChildExecuterFunction(createExecuterFactory(filterExecuter,root),this);

}

function filedExecuter( file ){

  executer.call( this, this)
  let thisExecuter = this;
  this.exec = function(){ filedExecute( file, thisExecuter.executeChild, thisExecuter); };

};

function childExecuter( userProcess, root){

  executer.call( this, root );

  this.generalInternalExec = function ( filePath, jb , executerFunction) {
    executerFunction ( filePath, userProcess, jb, this.executeChild );
  }

  this.exec = function(){
    root.exec()
  };

}

function ioExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function(filePath, jb){
    this.generalInternalExec( filePath, jb, io);
  }

};

function copyExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function( filePath, jb){
    this.generalInternalExec( filePath, jb, copy);
  }

};

function linkExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function( filePath, jb){
    this.generalInternalExec( filePath, jb, link);
  }

};

function passExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function( filePath, jb){
    this.generalInternalExec( filePath, jb, pass);
  }

};

function filterExecuter( userProcess, root) {
  childExecuter.call( this, userProcess, root);

  this.internalExec = function( filePath, jb){
    this.generalInternalExec( filePath, jb, filter);
  }

};

util.inherits( executer, EventEmitter);

util.inherits( filedExecuter, executer);

util.inherits( childExecuter, executer);
util.inherits( ioExecuter, childExecuter);
util.inherits( copyExecuter, childExecuter);
util.inherits( linkExecuter, childExecuter);
util.inherits( passExecuter, childExecuter);
util.inherits( filterExecuter, childExecuter);

function createExecuterFactory(classFunction,root){
  return function(userProcess){ return new classFunction( userProcess, root) };
}

function addChildExecuterFunction( executerFactory, parent ){

  var f = function( userProcess, errListener ){ //function to create child executer.

    let executer = executerFactory( userProcess );
    userProcess._plannedExecuter = executer; //hack to emit error from userProcess by executer.

    parent.executeChild = function( filePath ){ //switch state of parent also.
      try{
        executer.internalExec(
          filePath,
          calcJb( filePath )
        );

      }catch(err){
        raiseError(executer,err.toString(),err);
      }
    }

    if( errListener != null ){
      addErrorListener( executer, errListener);
    }

    return executer;

  }

  return f;//return function added to parent.

}

function filedExecute( file, execute, filedExecuter){
  let itr = pathIterator( file, filedExecuter);
  for( let filePath of itr ){
    execute(filePath, calcJb(filePath) );
  }
}

function pathIterator( file, filedExecuter){
  try{
    if ( typeof file == 'string' ){
      return singlePath(file);
    } else if ( file[ Symbol.iterator ] ) {
      return file;
    } else {
      throw new Error();
    }
  } catch ( error ) {
    raiseError( filedExecuter, 'Failed to create path Iterator' );
  }

  return [];

}

function * singlePath( file ){
  yield file;
}

function io( filePath, userProcess, jb, chainedProcess){

  process(
    filePath,
    userProcess,
    jb,
    chainedProcess,
    saveAfterApply,
    function(){
      //file to read does not exists.
      //create file with initial value and process json.
      fs.open(
        filePath,
        'w+',
        (err,fd) => {

          if(err) raiseError( userProcess._plannedExecuter, 'IOError Failed to create file.') ;

          //save to file and apply process.
          save(
            initialValue,
            fd,
            function(){
                //apply process
                apply(
                  userProcess,
                  initialValue,
                  fd,
                  function(afterCloseProcess){// close descriptor.
                    fs.close(
                      fd,
                      function(err){
                        if(err) raiseError( userProcess._plannedExecuter, "io:failsed to close file");
                        afterCloseProcess();
                      }
                    );
                  },
                  jb,
                  filePath,
                  saveAfterApply,
                  chainedProcess
                );
            },
            jb
          );

        }
      );
    }
  );

}

function link( filePath, userProcess, jb, chainedProcess ){
  process(filePath, userProcess, jb, chainedProcess, fsLink,
    raiseUnknownErrorFunction( userProcess._plannedExecuter ) // link does not create new file when not existed
  );
}

function copy( filePath, userProcess, jb, chainedProcess ){
  process(filePath, userProcess, jb, chainedProcess, fsCopy,
    raiseUnknownErrorFunction( userProcess._plannedExecuter ) //copy does not create new file when not existed
  );
}

function pass( filePath, userProcess, jb, chainedProcess){
  process(filePath, userProcess, jb, chainedProcess, passPostProcess,
    raiseUnknownErrorFunction( userProcess._plannedExecuter ) //pass dows not create new file when not existed
  );
}

function filter( filePath, userProcess, jb, chainedProcess){
  process(filePath,
    filternize(userProcess),
    jb,
    chainedProcess,
    filterPostProcess,
    raiseUnknownErrorFunction( userProcess._plannedExecuter) //pass does not create new file when not existed
  );
}

function process(
  filePath,
  userProcess,
  jb,
  chainedProcess,
  jfProcess,
  fileCreationProcess // process to create file when not existed
){

  fs.open(
    filePath,
    'r+',
    (err,fd) => {

      if( ! err ){
        //file exists.

        //read from file and process
        fs.readFile(
          fd,
          encoding(jb),
          (err, data) => {

            if (err) raiseError( userProcess._plannedExecuter, 'IOError Failed to read file.',err);
            fs.close(
              fd,
              function(err){
                if(err) raiseError( userProcess._plannedExecuter, 'IOError Failed to close file',err);

                var json = decode( data, jb);
                apply(
                  userProcess,
                  json,
                  filePath,
                  function( afterCloseProcess ){ afterCloseProcess() }, // closed already and no need to close, but need to call chained process
                  jb,
                  filePath,
                  jfProcess,
                  chainedProcess
                );

              }
            );
          }
        );
      }else{
        //file not exists.
        fileCreationProcess();

      }
    }
  );
}

//(*->*) -> (*->boolean) and a littile bit more.
function filternize( userProcess ){
  // return true/false according to result of user process.
  let result =
    wrapUserProcess(
      userProcess,
      function( process ){
        return function(obj,filePath){
            if( process ( obj, filePath) ) return true;
            else return false;
        };
      }
    );
  return result;

}

function guardProcess( userProcess ){

  let guarded =
    wrapUserProcess(
      userProcess,
      function( userProcess ){
        return function( json, filePath, errListener){
          try{
            return userProcess( json, filePath, errListener);

          }catch(err){

            //walkaround for unclear this/caller problem in javascript.
            //I just wanted to use something like "this".
            raiseError(
              userProcess._plannedExecuter.listenerCount('error') > 0 ?
              userProcess._plannedExecuter :
              defaultEmitter ,
              'User process error',
              err
            );

          }
        };
      }
    );

  return guarded;

}

function wrapUserProcess( userProcess, functionWrapper ){

  //To keep _plannedExecuter hack working, this function is needed to use when wrapping userProcess.
  let wrapped = functionWrapper( userProcess );
  wrapped._plannedExecuter = userProcess._plannedExecuter;//hack to emit error from userProcess by executer.

  return wrapped;

}

//apply process function to json.
function apply( process, json, file, closeFile, jb, filePath, postProcess, chainedProcess){

  let guardedProcess = guardProcess(process);

  if( chainedProcess == undefined ) chainedProcess = function(p1,p2){};

  var result = guardedProcess(json, filePath, guardedProcess._plannedExecuter);

  if(result != undefined && result != null){
    //if result returned, executePostProcess
    postProcess(
      result,
      file,
      closeFile, //executed after saved.
      jb,
      filePath,
      chainedProcess,
      guardedProcess._plannedExecuter
    );

  }else{
    closeFile( function(){ chainedProcess( filePath )} );
  }

}

//file can be either of file path and descriptor

function save( data, file, closeFile, jb, executer){
  saveCore( data,file, closeFile, jb, null, null, executer);
}

function saveAfterApply( data, file, closeFile, jb, filePath, chainedProcess, executer){
  saveCore(data,file,closeFile,jb,filePath,chainedProcess);
}

function saveCore( data, file, closeFile, jb,
                    filePath, chainedProcess, //only passsed in saveAfterApplly
                    executer
                  ){

  try{
    fs.writeFile(
      file,
      encode(data,jb),
      encoding(jb),
      (err)=>{
        closeFile(
          function() {
            if( chainedProcess ) chainedProcess(filePath);
          }
        );//file is closed in afterSaved, if needed.
        if (err) raiseError( executer, 'IOError failed to save json');
      }
    );
  }catch(error){
    closeFile(
      function() {
        if( chainedProcess ) chainedProcess(filePath);
      }
    );
    raiseError( executer, "failed in save", error);
  }
}

function fsCopy( copied2Path, file, closeFile, jb, originalFilePath, chainedProcess, executer ){ //"fs" is to avoid name conflict.

  let itr = pathIterator( copied2Path );
  for(let newFilePath of itr ){
    fsPipe(
      originalFilePath,
      newFilePath,
      function(err){
        if(err) raiseError( executer, "Failed to copy from " + originalFilePath + " to " + newFilePath,err);
        if( chainedProcess ) chainedProcess( newFilePath );
      }
    );
  }
}

function fsPipe( fromPath, toPath, callback){

  let readStream = fs.createReadStream(fromPath);
  let writeStream = fs.createWriteStream(toPath,{flags: 'wx'}); //to escape copy between same files.

  //readStream.on('end',()=>{} ); // rely on end feature
  writeStream.on('finish',() => { callback( false );} );

  readStream.on('error',(err) => { callback(err) } );
  writeStream.on('error',(err) => { callback(err) } );

  readStream.pipe(writeStream);

}

function fsLink( linkPath, file, closeFile, jb, originalFilePath, chainedProcess, executer){ //"fs" is to avoid name conflict.

  //link runs only after file was closed. closeFile is passed as compatibility of postProcess interface
  //closeFile();
  let itr = pathIterator( linkPath );
  for(let newFilePath of itr ){
    fs.link(
      originalFilePath,
      newFilePath,
      function(err){
        if(err) raiseError( executer, "Failed to link from " + originalFilePath + " to " + newFilePath,err);
        if( chainedProcess ) chainedProcess( newFilePath );
      }
    );
  }
}

function passPostProcess( result, file, closeFile, jb, originalFilePath, chainedProcess ){
  if( chainedProcess ) chainedProcess( originalFilePath );
}

function filterPostProcess( result, file, closeFile, jb, originalFilePath, chainedProcess ){
  if( result && chainedProcess ) chainedProcess( originalFilePath );
}

function encoding( jb ){
  if( jb == JB_BSON ) return null;
  else if( jb == JB_JSON ) return 'utf8';
  else raiseError(null, 'encoding: jb must be JSON or BSON');
}

function decode( obj, jb ){
  if( jb == JB_BSON ){
    return BSON.deserialize(
      obj,
      {
        evalFunctions: true,
        cacheFunctions: true
      }//experimental
    );
  }
  else if ( jb == JB_JSON ) return JSON.parse(obj);
  else raiseError( null, 'decode: jb must be JSON or BSON');
}

function encode( obj, jb ){
  if( jb == JB_BSON ) {
    return BSON.serialize(
      obj,
      false,
      true,
      true //experimental
    );
  }
  else if( jb == JB_JSON ) return JSON.stringify( obj );
  else raiseError( null, 'encode: jb must be JSON or BSON');
}

function calcJb( filePath ){

  switch( path.extname( filePath ).toLowerCase() ){

    case ".bson":
      return JB_BSON;

    case ".json":
    default:
      return JB_JSON;

  }
}

function JsonFiledError(msg,innerError){
  this.msg = msg;
  this.innerError = innerError;
};

util.inherits(JsonFiledError,Error);

function raiseError(emitter, msg, innerError){
  if( emitter == null || emitter == undefined){
    emitter = defaultEmitter;
  }
  emitter.emit( 'error', new JsonFiledError( msg, innerError));
}

function raiseUnknownErrorFunction(emitter){
  return function(){
    raiseError( emitter, "Unknown error.", null);
  }
}

var defaultErrorListener = function ( error ){
  console.error( error );
  throw error; //defaut Listener does not adohere keep running.
}

function addErrorListener(emitter, errListener){

  emitter.on(
    'error',
    errListener == undefined || errListener == null ?
    defaultErrorListener :
    errListener
  );
  return emitter;

}

function DefaultEmitter () {};
util.inherits( DefaultEmitter, EventEmitter);
let defaultEmitter = new DefaultEmitter();

defaultEmitter.on( 'error', defaultErrorListener);

module.exports.defaultEmitter = defaultEmitter;

module.exports.JsonFiledError = JsonFiledError;
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

var lib = {
  fs: require('fs'),
  path: require('path')
};
var _ = require('lodash');

exports.initConfig = function (grunt, config, options) {
  config = config || {};
  options = options || {};

  if (options.noMocha === undefined) {
    options.noMocha = !lib.fs.existsSync('test');
  }

  if (options.noMocha) {
    options.noIntegration = true;
  } else if (options.noIntegration === undefined) {
    options.noIntegration = !lib.fs.existsSync('test/integration');
  }

  var defaults = {
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      files: _.union([
        '*.js',
        'lib/**/*.js',
        'test/**/*.js',
        'bin/**/*.js',
        'cli/**/*.js',
        'tasks/**/*.js',
      ], options.jsFiles || []),
      options: { jshintrc: '.jshintrc' }
    },
    lintspaces: {
      files: _.union(['<%= jshint.files %>'], options.spaceFiles || []),
      options: {
        editorconfig: '.editorconfig',
        ignores: ['js-comments'],
      }
    },
    watch: {
      basic : {
        files: _.union([
          '<%= lintspaces.files %>',
          'test/**/*'
        ], options.watchFiles || []),
        tasks: [!options.noMocha && options.integrationWatch ? 'test-all' : 'test']
      }
    }
  };

  defaults['dependency-check'] = {
    files: _.union(['<%= jshint.files %>'], options.dependencyFiles || []),
    options: {
      excludeMissingDev: true,
    }
  };

  if (!options.noMocha) {
    defaults.mocha_istanbul = {
      options: {
        ui: 'tdd'
      },
      basic: {
        src: ['test/**/*.js', '!test/integration/**/*.js']
      },
      integration: {
        src: ['test/integration/**/*.js']
      }
    };
  }

  _.defaults(config, defaults);
  grunt.initConfig(config);

  var plugins = [
    'grunt-notify',
    'grunt-lintspaces',
    'grunt-contrib-jshint',
    'grunt-contrib-watch'
  ];

  var testTasks = ['lintspaces', 'jshint', 'dependency-check', 'setTestEnv'];
  var integrationTestTasks = options.noIntegration ? ['test'] : ['test', 'mocha_istanbul:integration'];

  if (!options.noMocha) {
    plugins.push('grunt-mocha-istanbul');
    testTasks.push('mocha_istanbul:basic');
  }

  testTasks = testTasks.concat(options.extraTestTasks || []);
  integrationTestTasks = integrationTestTasks.concat(options.extraTestAllTasks || []);

  // Uhm, HACK! But WTF Grunt!
  var cwd = process.cwd();
  process.chdir(__dirname);
  // Manually load the plugins so that we don't pollute the parent module
  // with loads of peer dependencies.
  plugins.forEach(function loadTasks(name) {
    grunt.loadNpmTasks(name);
  });
  process.chdir(cwd);

  grunt.loadTasks('tasks');

  grunt.registerTask('setTestEnv', 'Ensure that environment (database etc) is set up for testing', function () {
    process.env.NODE_ENV = 'test';
  });

  grunt.registerTask('test', testTasks);
  grunt.registerTask('test-all', integrationTestTasks);
  grunt.registerTask('default', 'test');
};
<commit_msg>fix(main): pass an absolute path to loadTasks so that grunt finds bundled tasks<commit_after>/*jslint node: true */
'use strict';

var lib = {
  fs: require('fs'),
  path: require('path')
};
var _ = require('lodash');

exports.initConfig = function (grunt, config, options) {
  config = config || {};
  options = options || {};

  if (options.noMocha === undefined) {
    options.noMocha = !lib.fs.existsSync('test');
  }

  if (options.noMocha) {
    options.noIntegration = true;
  } else if (options.noIntegration === undefined) {
    options.noIntegration = !lib.fs.existsSync('test/integration');
  }

  var defaults = {
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      files: _.union([
        '*.js',
        'lib/**/*.js',
        'test/**/*.js',
        'bin/**/*.js',
        'cli/**/*.js',
        'tasks/**/*.js',
      ], options.jsFiles || []),
      options: { jshintrc: '.jshintrc' }
    },
    lintspaces: {
      files: _.union(['<%= jshint.files %>'], options.spaceFiles || []),
      options: {
        editorconfig: '.editorconfig',
        ignores: ['js-comments'],
      }
    },
    watch: {
      basic : {
        files: _.union([
          '<%= lintspaces.files %>',
          'test/**/*'
        ], options.watchFiles || []),
        tasks: [!options.noMocha && options.integrationWatch ? 'test-all' : 'test']
      }
    }
  };

  defaults['dependency-check'] = {
    files: _.union(['<%= jshint.files %>'], options.dependencyFiles || []),
    options: {
      excludeMissingDev: true,
    }
  };

  if (!options.noMocha) {
    defaults.mocha_istanbul = {
      options: {
        ui: 'tdd'
      },
      basic: {
        src: ['test/**/*.js', '!test/integration/**/*.js']
      },
      integration: {
        src: ['test/integration/**/*.js']
      }
    };
  }

  _.defaults(config, defaults);
  grunt.initConfig(config);

  var plugins = [
    'grunt-notify',
    'grunt-lintspaces',
    'grunt-contrib-jshint',
    'grunt-contrib-watch'
  ];

  var testTasks = ['lintspaces', 'jshint', 'dependency-check', 'setTestEnv'];
  var integrationTestTasks = options.noIntegration ? ['test'] : ['test', 'mocha_istanbul:integration'];

  if (!options.noMocha) {
    plugins.push('grunt-mocha-istanbul');
    testTasks.push('mocha_istanbul:basic');
  }

  testTasks = testTasks.concat(options.extraTestTasks || []);
  integrationTestTasks = integrationTestTasks.concat(options.extraTestAllTasks || []);

  // Uhm, HACK! But WTF Grunt!
  var cwd = process.cwd();
  process.chdir(__dirname);
  // Manually load the plugins so that we don't pollute the parent module
  // with loads of peer dependencies.
  plugins.forEach(function loadTasks(name) {
    grunt.loadNpmTasks(name);
  });
  process.chdir(cwd);

  grunt.loadTasks(lib.path.join(__dirname, 'tasks'));

  grunt.registerTask('setTestEnv', 'Ensure that environment (database etc) is set up for testing', function () {
    process.env.NODE_ENV = 'test';
  });

  grunt.registerTask('test', testTasks);
  grunt.registerTask('test-all', integrationTestTasks);
  grunt.registerTask('default', 'test');
};
<|endoftext|>


<commit_before>/*!
 * snakeskin-loader
 * https://github.com/SnakeskinTpl/snakeskin-loader
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/snakeskin-loader/blob/master/LICENSE
 */

var
	$C = require('collection.js').$C,
	parent = module.parent;

var
	path = require('path'),
	loaderUtils = require('loader-utils'),
	snakeskin = require('snakeskin'),
	beautify = require('js-beautify');

module.exports = function (source) {
	if (this.cacheable) {
		this.cacheable();
	}

	var
		opts = loaderUtils.parseQuery(this.query),
		tpls = {};

	opts = $C(opts).reduce(function (map, val, key) {
		map[key] = parse(val);
		return map;
	}, {});

	var prettyPrint;
	if (opts.exec) {
		if (opts.prettyPrint) {
			opts.prettyPrint = false;
			prettyPrint = true;
		}

		opts.context = tpls;
	}

	opts.cache = false;
	opts.exports = 'none';
	opts.throws = true;
	opts.debug = opts.debug || {};

	var
		file = this.resourcePath,
		res = snakeskin.compile(source, opts, {file: file}),
		_this = this;

	$C(opts.debug.files).forEach(function (bool, filePath) {
		_this.addDependency(filePath);
	});

	if (opts.exec) {
		res = snakeskin.returnMainTpl(tpls, file, opts.tpl) || '';

		if (res) {
			res = res(opts.data);

			if (prettyPrint) {
				res = beautify['html'](res);
				res = res.replace(/\r?\n|\r/g, opts.lineSeparator);
			}

			res += opts.lineSeparator;
		}
	}

	return res;
};

function toJS(str) {
	return new Function(
		'module',
		'exports',
		'require',
		'__filename',
		'__dirname',
		'return ' + str

	)(parent, parent.exports, parent.require, parent.filename, path.dirname(parent.filename));
}

function parse(val) {
	try {
		if (typeof val === 'object') {
			$C(val).forEach(function (el, key) {
				val[key] = toJS(el);
			});

			return val;
		}

		return toJS(val);

	} catch (ignore) {
		return val;
	}
}
<commit_msg>:wrench:<commit_after>/*!
 * snakeskin-loader
 * https://github.com/SnakeskinTpl/snakeskin-loader
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/snakeskin-loader/blob/master/LICENSE
 */

var
	$C = require('collection.js').$C,
	parent = module.parent;

var
	path = require('path'),
	loaderUtils = require('loader-utils'),
	snakeskin = require('snakeskin'),
	beautify = require('js-beautify');

module.exports = function (source) {
	if (this.cacheable) {
		this.cacheable();
	}

	var
		opts = loaderUtils.parseQuery(this.query),
		tpls = {};

	opts = $C(opts).reduce(function (map, val, key) {
		map[key] = parse(val);
		return map;
	}, {});

	var prettyPrint;
	if (opts.exec) {
		if (opts.prettyPrint) {
			opts.prettyPrint = false;
			prettyPrint = true;
		}

		opts.context = tpls;
	}

	opts.cache = false;
	opts.exports = 'none';
	opts.throws = true;
	opts.debug = opts.debug || {};

	var
		file = this.resourcePath,
		res = snakeskin.compile(source, opts, {file: file}),
		_this = this;

	$C(opts.debug.files).forEach(function (bool, filePath) {
		_this.addDependency(filePath);
	});

	if (opts.exec) {
		res = snakeskin.getMainTpl(tpls, file, opts.tpl) || '';

		if (res) {
			res = res(opts.data);

			if (prettyPrint) {
				res = beautify['html'](res);
				res = res.replace(/\r?\n|\r/g, opts.lineSeparator);
			}

			res += opts.lineSeparator;
		}
	}

	return res;
};

function toJS(str) {
	return new Function(
		'module',
		'exports',
		'require',
		'__filename',
		'__dirname',
		'return ' + str

	)(parent, parent.exports, parent.require, parent.filename, path.dirname(parent.filename));
}

function parse(val) {
	try {
		if (typeof val === 'object') {
			$C(val).forEach(function (el, key) {
				val[key] = toJS(el);
			});

			return val;
		}

		return toJS(val);

	} catch (ignore) {
		return val;
	}
}
<|endoftext|>


<commit_before>var through = require('through2');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var fs = require('fs');
var exec = require('child_process').exec;

var PLUGIN_NAME = 'gulp-tfs';

var gulpTfs = function (opts) {
	opts = setDefaultOptions(opts);
	return through.obj(function (file, enc, cb) {
		var that = this;
		checkForTFS(function (result) {

			if (result) {
				if (!fs.existsSync(file.path)) {
					throw new PluginError(PLUGIN_NAME, "File does not exist");
				}

				if (process.platform !== 'win32') {
					throw new PluginError(PLUGIN_NAME, "This plugin can only be used on a Windows system with Visual Studio installed");
				}

				var command = 'tf ' + opts.command + " " + file.path;
				exec(command, function (err, stdout, stderr) {
					"use strict";
					processExecResults(err, stdout, stderr);
					gutil.log('TF result: command ' + opts.command + " on file " + gutil.colors.cyan(stdout));
					that.push(file);
					cb();
				});
			}
			else {
				gutil.log('TF command is not found.');
				that.push(file);
				cb();
			}
		});
	});
};

var setDefaultOptions = function (opts) {
	var validCommands = ['edit', 'lock'];
	opts = opts || {};
	opts.command = opts.command || 'edit';
	if (validCommands.indexOf(opts.command) < 0) {
		throw new PluginError(PLUGIN_NAME, "The only commands currently implemented are 'edit' and 'lock'");
	}
	return opts;
};

var processExecResults = function (err, stdout, stderr) {
	var returnVal;
	if (stderr) {
		returnVal = stderr;
		throw new PluginError(PLUGIN_NAME, returnVal);
	}
	if (err) {
		returnVal = err;
		throw new PluginError(PLUGIN_NAME, returnVal);
	}
	else {
		returnVal = stdout;
	}
	return returnVal;
};

var checkForTFS = function (done) {
	exec('tf bob', function (err, stdout, stderr) {
		//not a tf command, but validates that tf throws the right error
		//this ensures that the tf command is available
		if (stderr === 'Unrecognized command: bob.\r\n') {
			done(true);
		}
		else {
			throw new PluginError(PLUGIN_NAME, 'TF command is not available. Make sure Visual Studio is installed and its install directory is in your %PATH%');
		}
	});
};

module.exports = gulpTfs;
module.exports.checkForTFS = checkForTFS;
module.exports.processExecResults = processExecResults;
module.exports.setDefaultOptions = setDefaultOptions;

<commit_msg>Exporting all of the functions for gulp-tfs<commit_after>var through = require('through2');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var fs = require('fs');
var exec = require('child_process').exec;

var PLUGIN_NAME = 'gulp-tfs';

var gulpTfs = function (opts) {
	opts = setDefaultOptions(opts);
	return through.obj(function (file, enc, cb) {
		var that = this;
		checkForTFS(function (result) {

			if (result) {
				if (!fs.existsSync(file.path)) {
					throw new PluginError(PLUGIN_NAME, "File does not exist");
				}

				if (process.platform !== 'win32') {
					throw new PluginError(PLUGIN_NAME, "This plugin can only be used on a Windows system with Visual Studio installed");
				}

				var command = 'tf ' + opts.command + " " + file.path;
				exec(command, function (err, stdout, stderr) {
					"use strict";
					processExecResults(err, stdout, stderr);
					gutil.log('TF result: command ' + opts.command + " on file " + gutil.colors.cyan(stdout));
					that.push(file);
					cb();
				});
			}
			else {
				gutil.log('TF command is not found.');
				that.push(file);
				cb();
			}
		});
	});
};

var setDefaultOptions = function (opts) {
	var validCommands = ['edit', 'lock'];
	opts = opts || {};
	opts.command = opts.command || 'edit';
	if (validCommands.indexOf(opts.command) < 0) {
		throw new PluginError(PLUGIN_NAME, "The only commands currently implemented are 'edit' and 'lock'");
	}
	return opts;
};

var processExecResults = function (err, stdout, stderr) {
	var returnVal;
	if (stderr) {
		returnVal = stderr;
		throw new PluginError(PLUGIN_NAME, returnVal);
	}
	if (err) {
		returnVal = err;
		gutil.log('TF command caution: ' + opts.command + " on file " + gutil.colors.cyan(stdout) + " -- " + gutil.colors.yello(returnVal));
		throw new PluginError(PLUGIN_NAME, returnVal);
	}
	else {
		returnVal = stdout;
	}
	return returnVal;
};

var checkForTFS = function (done) {
	exec('tf bob', function (err, stdout, stderr) {
		//not a tf command, but validates that tf throws the right error
		//this ensures that the tf command is available
		if (stderr === 'Unrecognized command: bob.\r\n') {
			done(true);
		}
		else {
			throw new PluginError(PLUGIN_NAME, 'TF command is not available. Make sure Visual Studio is installed and its install directory is in your %PATH%');
		}
	});
};

module.exports = gulpTfs;
module.exports.checkForTFS = checkForTFS;
module.exports.processExecResults = processExecResults;
module.exports.setDefaultOptions = setDefaultOptions;

<|endoftext|>


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

module.exports = postcss.plugin('postcss-grid', function (opts) {
	opts = opts || {};

	function unitParse(str){
		var returnValue = {};
		var match = str.match(/\d./);

		if(str.length) {
			var value = match[0];
			var unit = (str.replace(value, '')).trim();
			returnValue.unit = unit;
			returnValue.value = parseInt(value, 10);
		}
		return returnValue;
	}

	return function(css, result){

		css.walkDecls(function (decl){
			if(decl.prop === 'create-row'){
				var selectorName = decl.parent.selector;
				var rowValue = decl.value;

				decl.parent.append({prop: 'display', value: 'block'});
				decl.parent.append({prop: 'margin', value: '0 auto'});
				decl.parent.append({prop: 'max-width', value: rowValue});
				decl.parent.append({prop: 'position', value: 'relative'});
				decl.parent.append({prop: 'width', value: '100%'});

				css.insertAfter(decl.parent ,(selectorName + ':before,' + selectorName + ':after { content: " "; display: table; }' + selectorName + ':after { clear: both;}'));

				decl.removeSelf();
			}

			if(decl.prop === 'create-column'){
				var selectorName = decl.parent.selector;
				var colGut = unitParse(decl.value);

				decl.parent.append({prop: 'float', value: 'left'});
				decl.parent.append({prop: 'padding', value: '0 ' + (colGut.value/2) + colGut.unit});
				decl.parent.append({prop: 'position', value: 'relative'});
				decl.parent.append({prop: 'width', value: '100%'});

				decl.removeSelf();
			}

			if(decl.prop === 'create-grid'){
				var totalColumns = decl.value;
				var selectorName = decl.parent.selector + '_';
				for (i = 1; i <= totalColumns; i++){
					var width = ((i / totalColumns) * 100).toFixed(5) * 1;
					decl.parent.parent.append(selectorName + i + '{width: '+ width + '%; }');
				}
				decl.parent.remove();
			}

			if(decl.prop === 'create-offset'){
				var totalColumns = decl.value;
				var offsetColumns = totalColumns - 1;
				var selectorName = decl.parent.selector + '_';
				for (i = 1; i <= offsetColumns; i++){
					var offsetWidth = ((i / totalColumns) * 100).toFixed(5) * 1;
					decl.parent.parent.append(selectorName + i + '{margin-left: '+ offsetWidth + '%; }');
				}
				decl.parent.remove();
			}

			if(decl.prop === 'create-push'){
				var totalColumns = decl.value;
				var pushColumns = totalColumns - 1;
				var selectorName = decl.parent.selector + '_';
				for (i = 1; i <= pushColumns; i++){
					var pushWidth = ((i / totalColumns) * 100).toFixed(5) * 1;
					decl.parent.parent.append(selectorName + i + '{left: '+ pushWidth + '%; right: auto;}');
				}
				decl.parent.remove();
			}

			if(decl.prop === 'create-pull'){
				var totalColumns = decl.value;
				var pullColumns = totalColumns - 1;
				var selectorName = decl.parent.selector + '_';
				for (i = 1; i <= pullColumns; i++){
					var pullWidth = ((i / totalColumns) * 100).toFixed(5) * 1;
					decl.parent.parent.append(selectorName + i + '{left: auto; right: '+ pullWidth + '%; }');
				}
				decl.parent.remove();
			}
		});

	};
});
<commit_msg>small fixes<commit_after>var postcss = require('postcss');

module.exports = postcss.plugin('postcss-grid', function (opts) {
	opts = opts || {};

	function unitParse(str){
		var returnValue = {};
		var match = str.match(/\d./);

		if(str.length) {
			var value = match[0];
			var unit = (str.replace(value, '')).trim();
			returnValue.unit = unit;
			returnValue.value = parseInt(value, 10);
		}
		return returnValue;
	}

	return function(css, result){

		css.walkDecls(function (decl){
			if(decl.prop === 'create-row'){
				var selectorName = decl.parent.selector;
				var rowValue = decl.value;

				decl.parent.append({prop: 'display', value: 'block'});
				decl.parent.append({prop: 'margin', value: '0 auto'});
				decl.parent.append({prop: 'max-width', value: rowValue});
				decl.parent.append({prop: 'position', value: 'relative'});
				decl.parent.append({prop: 'width', value: '100%'});

				css.insertAfter(decl.parent ,(selectorName + ':before,' + selectorName + ':after { content: " "; display: table; }' + selectorName + ':after { clear: both;}'));

				decl.remove();
			}

			if(decl.prop === 'create-column'){
				var selectorName = decl.parent.selector;
				var colGut = unitParse(decl.value);

				decl.parent.append({prop: 'float', value: 'left'});
				decl.parent.append({prop: 'padding', value: '0 ' + (colGut.value/2) + colGut.unit});
				decl.parent.append({prop: 'position', value: 'relative'});
				decl.parent.append({prop: 'width', value: '100%'});

				decl.remove();
			}

			if(decl.prop === 'create-grid'){
				var totalColumns = decl.value;
				var selectorName = decl.parent.selector + '_';
				for (i = 1; i <= totalColumns; i++){
					var width = ((i / totalColumns) * 100).toFixed(5) * 1;
					decl.parent.parent.append(selectorName + i + '{width: '+ width + '%; }');
				}
				decl.parent.remove();
			}

			if(decl.prop === 'create-offset'){
				var totalColumns = decl.value;
				var offsetColumns = totalColumns - 1;
				var selectorName = decl.parent.selector + '_';
				for (i = 0; i <= offsetColumns; i++){
					var offsetWidth = ((i / totalColumns) * 100).toFixed(5) * 1;
					decl.parent.parent.append(selectorName + i + '{margin-left: '+ offsetWidth + '%; }');
				}
				decl.parent.remove();
			}

			if(decl.prop === 'create-push'){
				var totalColumns = decl.value;
				var pushColumns = totalColumns - 1;
				var selectorName = decl.parent.selector + '_';
				for (i = 0; i <= pushColumns; i++){
					var pushWidth = ((i / totalColumns) * 100).toFixed(5) * 1;
					decl.parent.parent.append(selectorName + i + '{left: '+ pushWidth + '%; right: auto;}');
				}
				decl.parent.remove();
			}

			if(decl.prop === 'create-pull'){
				var totalColumns = decl.value;
				var pullColumns = totalColumns - 1;
				var selectorName = decl.parent.selector + '_';
				for (i = 0; i <= pullColumns; i++){
					var pullWidth = ((i / totalColumns) * 100).toFixed(5) * 1;
					decl.parent.parent.append(selectorName + i + '{left: auto; right: '+ pullWidth + '%; }');
				}
				decl.parent.remove();
			}
		});

	};
});
<|endoftext|>


<commit_before>var grunt = require('grunt');
var log = require('grunt-legacy-log');
var stream = require('readable-stream');
var inherits = require('inherits');
var rimraf = require('rimraf');
var multiTasks = [];

function BufferStream(done, options) {
  stream.Writable.call(this, options);

  var data = [];

  this._write = function (chunk, encoding, callback) {
    data.push(chunk);
    callback();
  };
  this.on('finish', function () {
    done(null, Buffer.concat(data));
  });
  this.on('error', function (err) {
    done(err);
  });
}
inherits(BufferStream, stream.Writable);

grunt.registerMultiTask = (function (obj, method) {
  return function (name) {
    multiTasks.push(name);
    method.apply(obj, arguments);
  };
})(grunt.task, grunt.task.registerMultiTask);

function Task(name, config) {
  if (!(this instanceof Task)) {
    return new Task(name, config);
  }

  var args = name.split(':');

  this.grunt = grunt;
  this.grunt.log = new log.Log({muted: true});
  this.grunt.verbose = this.grunt.log.verbose;
  this.name = args.shift();
  this.multi = multiTasks.indexOf(this.name) >= 0;
  this.target = this.multi ? args.shift() : null;
  this.args = args;
  this.data = {};
  this.files = [];
  this.stdout = null;

  this.grunt.config.set(this.name, config || {});
}

Task.prototype.run = function (/* [arguments...], done */) {
  var args = this.args.concat([].slice.apply(arguments));
  var task = this;

  if (task.target) {
    args.unshift(task.target);
  } else if (task.multi) {
    args.unshift('');
  }
  args.unshift(task.name);

  function run(done) {
    var warn = task.grunt.fail.warn;
    var fatal = task.grunt.fail.fatal;
    var outStream = task.grunt.log.options.outStream;
    var config = task.grunt.config.get(task.name);
    var finished = false;

    function end() {
      if (!finished) {
        finished = true;

        task.grunt.log.options.outStream.end();
        task.grunt.log.options.outStream = outStream;
        task.grunt.fail.warn = warn;
        task.grunt.fail.fatal = fatal;

        done.apply(this, arguments);
      }
    }

    task.target = task.multi ? (task.target || Object.keys(config)[0] || 'default') : null;
    task.data = task.multi ? config[task.target] : config;
    task.files = task.grunt.task.normalizeMultiTaskFiles(task.data, task.target);

    task.grunt.log.options.outStream = new BufferStream(function (err, data) {
      task.stdout = data;
    });

    task.grunt.fail.warn = end;
    task.grunt.fail.fatal = end;

    task.grunt.task.options({
      error: end,
      done: end
    });

    task.grunt.task.run(args.join(':'));
    task.grunt.task.start({asyncDone: true});
  }

  if (typeof args[args.length-1] === 'function') {
    run(args.pop());
    return this;
  } else {
    return run;
  }
};

Task.prototype.fail = function() {
  var args = [].slice.apply(arguments);
  var task = this;

  function expectError(done) {
    return function (err) {
      if (!err) {
        done(new Error('Expected ' + task.name + ' task to fail'));
      } else {
        done(null, err);
      }
    };
  }

  if (typeof args[args.length-1] === 'function') {
    args.push(expectError(args.pop()));
    return task.run.apply(task, args);
  } else {
    return function(done) {
      args.push(expectError(done));
      task.run.apply(task, args);
    };
  }
};

Task.prototype.clean = function(/* [files...], [done] */) {
  var args = [].slice.apply(arguments);
  var task = this;

  function clean(done) {
    var remain = task.files.length;

    function one(err) {
      if (err && remain > 0) {
        remain = 0;
        return done(err);
      }

      remain -= 1;
      if (remain === 0) {
        done();
      }
    }

    task.files.forEach(function (file) {
      rimraf(file.dest, one);
    });
  }

  if (typeof args[args.length-1] === 'function') {
    clean(args.pop());
    return this;
  } else {
    return clean;
  }
};

function runTask(name, config /* [arguments...], [done] */) {
  var task = new Task(name, config);

  return task.run.apply(task, [].slice.call(arguments, 2));
}

runTask.task = function create(name, config) {
  return new Task(name, config);
};

[ 'initConfig',
  'registerTask',
  'registerMultiTask',
  'renameTask',
  'loadTasks',
  'loadNpmTasks' ].forEach(function (fn) {
  runTask[fn] = grunt[fn].bind(grunt);
});

module.exports = runTask;
<commit_msg>If no files to rmeove: do nothing<commit_after>var grunt = require('grunt');
var log = require('grunt-legacy-log');
var stream = require('readable-stream');
var inherits = require('inherits');
var rimraf = require('rimraf');
var multiTasks = [];

function BufferStream(done, options) {
  stream.Writable.call(this, options);

  var data = [];

  this._write = function (chunk, encoding, callback) {
    data.push(chunk);
    callback();
  };
  this.on('finish', function () {
    done(null, Buffer.concat(data));
  });
  this.on('error', function (err) {
    done(err);
  });
}
inherits(BufferStream, stream.Writable);

grunt.registerMultiTask = (function (obj, method) {
  return function (name) {
    multiTasks.push(name);
    method.apply(obj, arguments);
  };
})(grunt.task, grunt.task.registerMultiTask);

function Task(name, config) {
  if (!(this instanceof Task)) {
    return new Task(name, config);
  }

  var args = name.split(':');

  this.grunt = grunt;
  this.grunt.log = new log.Log({muted: true});
  this.grunt.verbose = this.grunt.log.verbose;
  this.name = args.shift();
  this.multi = multiTasks.indexOf(this.name) >= 0;
  this.target = this.multi ? args.shift() : null;
  this.args = args;
  this.data = {};
  this.files = [];
  this.stdout = null;

  this.grunt.config.set(this.name, config || {});
}

Task.prototype.run = function (/* [arguments...], done */) {
  var args = this.args.concat([].slice.apply(arguments));
  var task = this;

  if (task.target) {
    args.unshift(task.target);
  } else if (task.multi) {
    args.unshift('');
  }
  args.unshift(task.name);

  function run(done) {
    var warn = task.grunt.fail.warn;
    var fatal = task.grunt.fail.fatal;
    var outStream = task.grunt.log.options.outStream;
    var config = task.grunt.config.get(task.name);
    var finished = false;

    function end() {
      if (!finished) {
        finished = true;

        task.grunt.log.options.outStream.end();
        task.grunt.log.options.outStream = outStream;
        task.grunt.fail.warn = warn;
        task.grunt.fail.fatal = fatal;

        done.apply(this, arguments);
      }
    }

    task.target = task.multi ? (task.target || Object.keys(config)[0] || 'default') : null;
    task.data = task.multi ? config[task.target] : config;
    task.files = task.grunt.task.normalizeMultiTaskFiles(task.data, task.target);

    task.grunt.log.options.outStream = new BufferStream(function (err, data) {
      task.stdout = data;
    });

    task.grunt.fail.warn = end;
    task.grunt.fail.fatal = end;

    task.grunt.task.options({
      error: end,
      done: end
    });

    task.grunt.task.run(args.join(':'));
    task.grunt.task.start({asyncDone: true});
  }

  if (typeof args[args.length-1] === 'function') {
    run(args.pop());
    return this;
  } else {
    return run;
  }
};

Task.prototype.fail = function() {
  var args = [].slice.apply(arguments);
  var task = this;

  function expectError(done) {
    return function (err) {
      if (!err) {
        done(new Error('Expected ' + task.name + ' task to fail'));
      } else {
        done(null, err);
      }
    };
  }

  if (typeof args[args.length-1] === 'function') {
    args.push(expectError(args.pop()));
    return task.run.apply(task, args);
  } else {
    return function(done) {
      args.push(expectError(done));
      task.run.apply(task, args);
    };
  }
};

Task.prototype.clean = function(/* [files...], [done] */) {
  var args = [].slice.apply(arguments);
  var task = this;

  function clean(done) {
    var remain = task.files.length;

    function one(err) {
      if (err && remain > 0) {
        remain = 0;
        return done(err);
      }

      remain -= 1;
      if (remain === 0) {
        done();
      }
    }

    if (remain) {
      task.files.forEach(function (file) {
        rimraf(file.dest, one);
      });
    } else {
      done();
    }
  }

  if (typeof args[args.length-1] === 'function') {
    clean(args.pop());
    return this;
  } else {
    return clean;
  }
};

function runTask(name, config /* [arguments...], [done] */) {
  var task = new Task(name, config);

  return task.run.apply(task, [].slice.call(arguments, 2));
}

runTask.task = function create(name, config) {
  return new Task(name, config);
};

[ 'initConfig',
  'registerTask',
  'registerMultiTask',
  'renameTask',
  'loadTasks',
  'loadNpmTasks' ].forEach(function (fn) {
  runTask[fn] = grunt[fn].bind(grunt);
});

module.exports = runTask;
<|endoftext|>


<commit_before>var through = require( 'through2' );
var watchify = require( 'watchify' );
var trim = require( 'jq-trim' );

var parseAsRegex = function parseAsRegex( regex ) {
  if ( typeof regex === 'string' ) {
    return new RegExp( regex );
  }
  return regex;
};

module.exports = function ( browserifyOpts, opts, argv ) {
  browserifyOpts = browserifyOpts || { };
  opts = opts || { };
  var hash = require( 'hash-string' );

  var xtend = require( 'xtend' );

  var id = 'persistify_' + hash( process.cwd() + trim( opts.cacheId ) );
  var depsCacheId = 'deps-cx-' + id;
  var cacheDir = opts.cacheDir;

  var flatCache = require( 'flat-cache' );
  var fileEntryCache = require( 'file-entry-cache' );

  if ( opts.recreate ) {
    flatCache.clearCacheById( id, cacheDir );
    flatCache.clearCacheById( depsCacheId, cacheDir );
  }
  // load the cache with id
  var cache = flatCache.load( id, cacheDir );

  // load the file entry cache with id, or create a new
  // one if the previous one doesn't exist
  var depsCacheFile = fileEntryCache.create( depsCacheId, cacheDir );

  var ignoreCache = false;

  // if the command was specified this can be used
  // as the cache buster
  if ( opts.command ) {
    var configHashPersisted = cache.getKey( 'configHash' );
    var hashOfConfig = hash( opts.command );

    ignoreCache = configHashPersisted !== hashOfConfig;

    if ( ignoreCache ) {
      cache.setKey( 'configHash', hashOfConfig );
    }
  }

  var defaultCache = {
    cache: {},
    packageCache: {}
  };

  var persistifyCache = ignoreCache ? defaultCache : (cache.getKey( 'persistifyArgs' ) || defaultCache);

  browserifyOpts.cache = persistifyCache.cache;
  browserifyOpts.packageCache = persistifyCache.packageCache;

  var fromArgs = require( 'browserify/bin/args' );

  var b = argv ? fromArgs( argv, browserifyOpts ) : require( 'browserify' )( browserifyOpts );

  function normalizeCache( removeDeletedOnly ) {
    var cachedFiles = Object.keys( browserifyOpts.cache );

    var neverCache = opts.neverCache;
    if ( neverCache ) {
      if ( !Array.isArray( neverCache ) ) {
        neverCache = [ neverCache ];
      }
      cachedFiles.forEach( function ( file ) {
        for (var i = 0; i < neverCache.length; i++) {
          var regex = parseAsRegex( neverCache[ i ] );

          if ( file.match( regex ) ) {
            b.emit( 'skip:cache', file );
            delete browserifyOpts.cache[ file ]; //esfmt-ignore-line
            break;
          }
        }
      } );
    }

    var res = depsCacheFile.analyzeFiles( cachedFiles );

    var changedFiles = res.changedFiles;
    var notFoundFiles = res.notFoundFiles;

    var changedOrNotFound = removeDeletedOnly ? notFoundFiles : changedFiles.concat( notFoundFiles );

    if ( changedOrNotFound.length > 0 ) {
      changedOrNotFound.forEach( function ( file ) {
        delete browserifyOpts.cache[ file ]; //esfmt-ignore-line
      } );
    }

    cache.setKey( 'persistifyArgs', { cache: browserifyOpts.cache, packageCache: browserifyOpts.packageCache } );
  }

  normalizeCache();

  function collect() {
    b.pipeline.get( 'deps' ).push( through.obj( function ( row, enc, next ) {
      var file = row.expose ? b._expose[ row.id ] : row.file;
      persistifyCache.cache[ file ] = {
        source: row.source,
        deps: xtend( { }, row.deps )
      };
      b.emit( 'file', file ); // attempt to make latest watchify to work with persistify
      this.push( row );
      next();
    } ) );
  }

  if ( opts.watch ) {
    b = watchify( b );
  }

  collect();
  b.on( 'reset', collect );

  var oldBundle = b.bundle;
  b.bundle = function () {
    var start = Date.now();
    var stream;
    try {
      stream = oldBundle.apply( b, arguments );
      stream.on( 'error', function ( err ) {
        console.error( err ); // eslint-disable-line
      } );
      stream.on( 'end', function () {
        setTimeout( function () {
          normalizeCache( true /* remove deleted only*/ );
          depsCacheFile.reconcile();
          cache.save();
        }, 0 );

        var end = Date.now() - start;
        b.emit( 'bundle:done', end );
      } );
    } catch (ex) {
      console.error( ex ); // eslint-disable-line
    }

    return stream;
  };

  return b;
};
<commit_msg>ignore watch passed to watchify (#15)<commit_after>var through = require( 'through2' );
var watchify = require( 'watchify' );
var trim = require( 'jq-trim' );

var parseAsRegex = function parseAsRegex( regex ) {
  if ( typeof regex === 'string' ) {
    return new RegExp( regex );
  }
  return regex;
};

module.exports = function ( browserifyOpts, opts, argv ) {
  browserifyOpts = browserifyOpts || { };
  opts = opts || { };
  var hash = require( 'hash-string' );

  var xtend = require( 'xtend' );

  var id = 'persistify_' + hash( process.cwd() + trim( opts.cacheId ) );
  var depsCacheId = 'deps-cx-' + id;
  var cacheDir = opts.cacheDir;

  var flatCache = require( 'flat-cache' );
  var fileEntryCache = require( 'file-entry-cache' );

  if ( opts.recreate ) {
    flatCache.clearCacheById( id, cacheDir );
    flatCache.clearCacheById( depsCacheId, cacheDir );
  }
  // load the cache with id
  var cache = flatCache.load( id, cacheDir );

  // load the file entry cache with id, or create a new
  // one if the previous one doesn't exist
  var depsCacheFile = fileEntryCache.create( depsCacheId, cacheDir );

  var ignoreCache = false;

  // if the command was specified this can be used
  // as the cache buster
  if ( opts.command ) {
    var configHashPersisted = cache.getKey( 'configHash' );
    var hashOfConfig = hash( opts.command );

    ignoreCache = configHashPersisted !== hashOfConfig;

    if ( ignoreCache ) {
      cache.setKey( 'configHash', hashOfConfig );
    }
  }

  var defaultCache = {
    cache: {},
    packageCache: {}
  };

  var persistifyCache = ignoreCache ? defaultCache : (cache.getKey( 'persistifyArgs' ) || defaultCache);

  browserifyOpts.cache = persistifyCache.cache;
  browserifyOpts.packageCache = persistifyCache.packageCache;

  var fromArgs = require( 'browserify/bin/args' );

  var b = argv ? fromArgs( argv, browserifyOpts ) : require( 'browserify' )( browserifyOpts );

  function normalizeCache( removeDeletedOnly ) {
    var cachedFiles = Object.keys( browserifyOpts.cache );

    var neverCache = opts.neverCache;
    if ( neverCache ) {
      if ( !Array.isArray( neverCache ) ) {
        neverCache = [ neverCache ];
      }
      cachedFiles.forEach( function ( file ) {
        for (var i = 0; i < neverCache.length; i++) {
          var regex = parseAsRegex( neverCache[ i ] );

          if ( file.match( regex ) ) {
            b.emit( 'skip:cache', file );
            delete browserifyOpts.cache[ file ]; //esfmt-ignore-line
            break;
          }
        }
      } );
    }

    var res = depsCacheFile.analyzeFiles( cachedFiles );

    var changedFiles = res.changedFiles;
    var notFoundFiles = res.notFoundFiles;

    var changedOrNotFound = removeDeletedOnly ? notFoundFiles : changedFiles.concat( notFoundFiles );

    if ( changedOrNotFound.length > 0 ) {
      changedOrNotFound.forEach( function ( file ) {
        delete browserifyOpts.cache[ file ]; //esfmt-ignore-line
      } );
    }

    cache.setKey( 'persistifyArgs', { cache: browserifyOpts.cache, packageCache: browserifyOpts.packageCache } );
  }

  normalizeCache();

  function collect() {
    b.pipeline.get( 'deps' ).push( through.obj( function ( row, enc, next ) {
      var file = row.expose ? b._expose[ row.id ] : row.file;
      persistifyCache.cache[ file ] = {
        source: row.source,
        deps: xtend( { }, row.deps )
      };
      b.emit( 'file', file ); // attempt to make latest watchify to work with persistify
      this.push( row );
      next();
    } ) );
  }

  if ( opts.watch ) {
    b = watchify( b, {
      ignoreWatch: b.argv[ "ignore-watch" ] || b.argv.iw
    } );
  }

  collect();
  b.on( 'reset', collect );

  var oldBundle = b.bundle;
  b.bundle = function () {
    var start = Date.now();
    var stream;
    try {
      stream = oldBundle.apply( b, arguments );
      stream.on( 'error', function ( err ) {
        console.error( err ); // eslint-disable-line
      } );
      stream.on( 'end', function () {
        setTimeout( function () {
          normalizeCache( true /* remove deleted only*/ );
          depsCacheFile.reconcile();
          cache.save();
        }, 0 );

        var end = Date.now() - start;
        b.emit( 'bundle:done', end );
      } );
    } catch (ex) {
      console.error( ex ); // eslint-disable-line
    }

    return stream;
  };

  return b;
};
<|endoftext|>


<commit_before>var method = GeoGrid.prototype;

function GeoGrid(n) {
    if(n<1) this._n = 1; //div by zero err
    this._n = n;
    this._RADIUS = 6371;
    this._GRID_WIDTH_EQUATOR = this._RADIUS/this._n;
    this._GRID_TO_LON = this._n/360;
    this._GRID_TO_LAT = this._n/(180*2);
    //this._KM_TO_GRID_UNIT = 2*this._RADIUS*MATH.PI/this._n;
    this._GRID_UNIT_TO_KM = this._n/(2*this._RADIUS*Math.PI);
    console.log('grid unit to km'+this._GRID_UNIT_TO_KM);

};

method.hash = function(lat, lon) {
   //this._cellWidth;
   return Math.floor( (lat +90) * this._GRID_TO_LAT ) * this._n + Math.floor( (lon +180) *this._GRID_TO_LON) ;

};

method.geoHash=function(lat,lon){
    if(lon<0)
        lat++;
    if(lon>this._n)
        lat--;
    return Math.floor(lat)*this._n + Math.floor(lon);
};

method.neighbours9 = function (lat, lon, cb) {
     var centerHash=this.hash(lat,lon);
    console.log('centerHash:'+centerHash);
     var hashes = [
          centerHash - this._n,
          centerHash,
          centerHash + this._n,
                  ];
    if(centerHash % this._n == 1){
        //left boundary
        hashes.push(centerHash -1 + this._n*2);
        hashes.push(centerHash -1 + this._n);
        hashes.push(centerHash -1);
    }else{
        hashes.push(centerHash - this._n -1 );
        hashes.push(centerHash - 1);
        hashes.push(centerHash + this._n -1 )
    }

    if(centerHash % this._n == 0){
        //right boundary
        hashes.push(centerHash+1);
        hashes.push(centerHash - this._n +1);
        hashes.push(centerHash - this._n*2 +1);
    }else{
        hashes.push(centerHash - this._n +1 );
        hashes.push(centerHash + 1);
        hashes.push(centerHash + this._n +1 )
    }
    return cb(hashes);

};

//possibleHashes returns the hashes you should search
method.possibleHashes = function(lat, lon, r, cb) {
   var hashes = [];
    var err = null;
   //find the hashes inside or on the circle
    var centerHash = this.hash(lat,lon);
    console.log('----centerHash: '+centerHash);
    var gridLat = this.transLat(lat);
    var gridLon = this.transLon(lon);

    //boundary too close to one of the poles
    //console.log('south pole dist:'+this.distGrid(gridLat, 0,0,0));
    //console.log('north pole dist:'+this.distGrid(gridLat, 0,this._n/2, 0 ));
    if( (this.distGrid(gridLat, 0,0,0) <=r) || (this.distGrid(gridLat, 0,this._n/2, 0 ) <=r) ){
        console.log('too close to pole');
        return cb(err, hashes);
    }

    //find top hash for the circle
     //find the top point of the circle
     //var topHash = Math.ceil(this.trans(lat) - r * this._GRID_UNIT_TO_KM)*this._n + Math.ceil(this.trans(lon));
     var endGridLat = gridLat + r* this._GRID_UNIT_TO_KM;
    // console.log('endGridLat:'+endGridLat);

     var endHash = this.geoHash(endGridLat, gridLon); //
     console.log('Top hash:'+endHash); //

   //  var endWithinCenterCell = false;
     if(Math.floor(endGridLat) > gridLat){
        var vt = Math.floor(endGridLat)-Math.floor(gridLat);
         console.log('vt      : .... '+vt);
        do{
           var hl = 0;
           var hr = 0;
           do{
             var brk = false;
             //check the left to end cell intersects with the circle
             if( this.distGrid( Math.floor(gridLat)+vt, Math.floor(gridLon)+hl, gridLat, gridLon) <= r)
                hl--;
             else
                brk = true;

             //right of end cell
             if( this.distGrid( Math.floor(gridLat)+vt, Math.ceil(gridLon)+hr, gridLat, gridLon) <= r)
                hr++;
              else
                brk=true;

           } while(!brk);
            console.log('===gridLon + hl'+(gridLon + hl));
          /* if(gridLon + hl < 0){ //boundary left
               for(var b = Math.floor(gridLon)+hl; b<0; b++){
                   hashes.push( this.geoHash(gridLat+vt+1, b+1));
                   console.log('geoGrid left boundary top b:'+b+' hl'+hl);
               }
               hl= -Math.floor(gridLon);
           }
           if(gridLon + hr > this._n){ //boundary right
               for(var b = Math.floor(gridLon)+hr; b > this._n; b--){
                   hashes.push( this.geoHash(gridLat+vt-1, b));
                   console.log('geoGrid right boundary top');
               }
               hr = Math.floor(this._n -gridLon);
           }*/
           // console.log('hl'+hl+', hr:'+hr);
           for (var i = hl; i<=hr; i++){
             hashes.push(this.geoHash(gridLat+vt,gridLon+i));
           }
            vt--;
        } while (vt>0)

     } //else {
    //    endWithinCenterCell = true;
    // }
     //center line
     if(gridLat%1 != 0){

         endGridLon = gridLon-r*this._GRID_UNIT_TO_KM;

         hl = -Math.ceil(gridLon) + Math.ceil(endGridLon);
         console.log('gridLon: '+gridLon+' endGridLon:'+endGridLon +' hl:'+hl);

         endGridLon = gridLon + r*this._GRID_UNIT_TO_KM;
         hr = - Math.ceil(gridLon) + Math.ceil(endGridLon);
         console.log('gridLon: '+gridLon+' endGridLon:'+endGridLon +' hr:'+hr);

         console.log('center line hl:'+hl+ ' hr: '+hr);
         //left boundary
         if(gridLon + hl <0){
             for(var b = Math.floor(gridLon)+hl ; b<0;b++ ){
                 hashes.push(Math.ceil(gridLat+1)*this._n+b+1);
             }
             hl=-Math.floor(gridLon);
         }
         if(gridLon + hr > this._n){
             for(var b = Math.ceil(gridLon)+hr ; b>this._n;b-- ){
                 hashes.push(Math.ceil(gridLat-1)*this._n +b);
             }
             hr = Math.floor(this._n -gridLon);
         }
         for(var i = hl; i <=hr; i++){
             hashes.push(centerHash+i);
         }

         //hashes.push(0);
     }

     //bottom
     endGridLat = gridLat - r* this._GRID_UNIT_TO_KM;
    // console.log('topGridLat:'+topGridLat);
     endGridLon = gridLon;
     endHash = Math.floor(endGridLat)*this._n + Math.ceil(endGridLon);
     console.log('bottom hash:'+endHash+ ' endGridLat'+endGridLat);
   //  var topWithinCenterCell = false;
     if(endHash < centerHash){

        var vb = Math.floor(endGridLat)-Math.floor(gridLat);

        do{
           var hl = 0;
           var hr = 0;
           do{
             var brk = false;
             //check the left to top cell intersects with the circle
             //console.log('Math.floor(gridLon)+hl'+Math.floor(gridLon)+hl); console.log('dist top left:'+this.distGrid( Math.ceil(gridLat+vt)-1, Math.floor(gridLon)+hl, gridLat, gridLon));

             if( this.distGrid( Math.ceil(gridLat +vb)+1, Math.floor(gridLon)+hl, gridLat, gridLon) <= r)
                hl--;
             else
                brk = true;

             //right of top cell
            //   console.log('vt: '+vt); console.log('Math.ceil(gridLat+vt)-1:'+ Math.ceil(gridLat+vt-1));
              // console.log(' Math.ceil(gridLon)+hr:'+ Math.ceil(gridLon)+hr);
               //console.log('dist form top right:'+this.distGrid( Math.ceil(gridLat+vt)-1, Math.ceil(gridLon)+hr, gridLat, gridLon));
             if( this.distGrid( Math.ceil(gridLat+vb)+1, Math.ceil(gridLon)+hr, gridLat, gridLon) <= r)
                hr++;
              else
                brk=true;

           } while(!brk);
           if(gridLon + hl < 0){ //boundary left
               for(var b = Math.floor(gridLon)+hl; b<0; b++){
                   hashes.push(Math.ceil(gridLat+vb+1)*this._n + b +1);
                   console.log('geoGrid left boundary bottom');
               }
               hl=-Math.floor(gridLon);
           }
           if(gridLon + hr > this._n){ //boundary right
               for(var b = Math.ceil(gridLon+hr); b > this._n; b--){
                   hashes.push(Math.ceil(gridLat+vb+1)*this._n +b );
                   console.log('geoGrid right boundary bottom');
               }
               hr = Math.floor(this._n -gridLon);
           }
            console.log('hl'+hl+', hr:'+hr+ ', vb:'+vb);
           for (var i = hl; i<=hr; i++){
             hashes.push(centerHash + vb*this._n + i);
           }
            vb++;
        } while (vb<0)

     }

   //check for boundary condition

   //check for poles

   return cb(err, hashes);
};

method.transLon= function(Lon){
//translates lat or lon to your grid's lat lon
  return (Lon +180 ) *this._GRID_TO_LON;
};

method.transLat= function(Lat){
//translates lat or lon to your grid's lat lon
  return (Lat +90) *this._GRID_TO_LAT;
};

method.distGrid= function( lat1, lon1, lat2, lon2){
   // console.log('lat1, lon1 '+lat1+','+lon1);
    var lon1Unit = Math.sin(lat1/this._n *Math.PI *2);
    var lon2Unit = Math.sin(lat2/this._n *Math.PI *2);
    var factor = (lon1Unit+lon2Unit)/2;
//    console.log('lon2 ' + lon2 +'  lon1 '+lon1);
  //  console.log('lon1Unit :'+lon1Unit + '  lon2unit: '+ lon2Unit +'lon2-lon1:' +(lon2-lon1)+ '    lon2 * lon2Unit -lon1*lon1Unit:'+(lon2 * lon2Unit) +':::' +(lon1*lon1Unit));
  return Math.sqrt( Math.pow((lat2-lat1),2) + Math.pow((lon2  -lon1)*factor,2) ) / this._GRID_UNIT_TO_KM;
};

module.exports = GeoGrid;
<commit_msg>boundary now handled by geohash<commit_after>var method = GeoGrid.prototype;

function GeoGrid(n) {
    if(n<1) this._n = 1; //div by zero err
    this._n = n;
    this._RADIUS = 6371;
    this._GRID_WIDTH_EQUATOR = this._RADIUS/this._n;
    this._GRID_TO_LON = this._n/360;
    this._GRID_TO_LAT = this._n/(180*2);
    //this._KM_TO_GRID_UNIT = 2*this._RADIUS*MATH.PI/this._n;
    this._GRID_UNIT_TO_KM = this._n/(2*this._RADIUS*Math.PI);
    console.log('grid unit to km'+this._GRID_UNIT_TO_KM);

};

method.hash = function(lat, lon) {
   //this._cellWidth;
   return Math.floor( (lat +90) * this._GRID_TO_LAT ) * this._n + Math.floor( (lon +180) *this._GRID_TO_LON) ;

};

method.geoHash=function(lat,lon){
    if(lon<0) //left boundary
        lat++;
    if(lon>this._n) //rt boundary
        lat--;
    return Math.floor(lat)*this._n + Math.floor(lon);
};

method.neighbours9 = function (lat, lon, cb) {
     var centerHash=this.hash(lat,lon);
    console.log('centerHash:'+centerHash);
     var hashes = [
          centerHash - this._n,
          centerHash,
          centerHash + this._n,
                  ];
    if(centerHash % this._n == 1){
        //left boundary
        hashes.push(centerHash -1 + this._n*2);
        hashes.push(centerHash -1 + this._n);
        hashes.push(centerHash -1);
    }else{
        hashes.push(centerHash - this._n -1 );
        hashes.push(centerHash - 1);
        hashes.push(centerHash + this._n -1 )
    }

    if(centerHash % this._n == 0){
        //right boundary
        hashes.push(centerHash+1);
        hashes.push(centerHash - this._n +1);
        hashes.push(centerHash - this._n*2 +1);
    }else{
        hashes.push(centerHash - this._n +1 );
        hashes.push(centerHash + 1);
        hashes.push(centerHash + this._n +1 )
    }
    return cb(hashes);

};

//possibleHashes returns the hashes you should search
method.possibleHashes = function(lat, lon, r, cb) {
   var hashes = [];
    var err = null;
   //find the hashes inside or on the circle
    var centerHash = this.hash(lat,lon);
    console.log('----centerHash: '+centerHash);
    var gridLat = this.transLat(lat);
    var gridLon = this.transLon(lon);

    //boundary too close to one of the poles
    //console.log('south pole dist:'+this.distGrid(gridLat, 0,0,0));
    //console.log('north pole dist:'+this.distGrid(gridLat, 0,this._n/2, 0 ));
    if( (this.distGrid(gridLat, 0,0,0) <=r) || (this.distGrid(gridLat, 0,this._n/2, 0 ) <=r) ){
        console.log('too close to pole');
        return cb(err, hashes);
    }

    //find top hash for the circle
     //find the top point of the circle
     //var topHash = Math.ceil(this.trans(lat) - r * this._GRID_UNIT_TO_KM)*this._n + Math.ceil(this.trans(lon));
     var endGridLat = gridLat + r* this._GRID_UNIT_TO_KM;
    // console.log('endGridLat:'+endGridLat);

     var endHash = this.geoHash(endGridLat, gridLon); //
     console.log('Top hash:'+endHash); //

   //  var endWithinCenterCell = false;
     if(Math.floor(endGridLat) > gridLat){
        var vt = Math.floor(endGridLat)-Math.floor(gridLat);
         console.log('vt      : .... '+vt);
        do{
           var hl = 0;
           var hr = 0;
           do{
             var brk = false;
             //check the left to end cell intersects with the circle
             if( this.distGrid( Math.floor(gridLat)+vt, Math.floor(gridLon)+hl, gridLat, gridLon) <= r)
                hl--;
             else
                brk = true;

             //right of end cell
             if( this.distGrid( Math.floor(gridLat)+vt, Math.ceil(gridLon)+hr, gridLat, gridLon) <= r)
                hr++;
              else
                brk=true;

           } while(!brk);
            console.log('===gridLon + hl'+(gridLon + hl));
          /* if(gridLon + hl < 0){ //boundary left
               for(var b = Math.floor(gridLon)+hl; b<0; b++){
                   hashes.push( this.geoHash(gridLat+vt+1, b+1));
                   console.log('geoGrid left boundary top b:'+b+' hl'+hl);
               }
               hl= -Math.floor(gridLon);
           }
           if(gridLon + hr > this._n){ //boundary right
               for(var b = Math.floor(gridLon)+hr; b > this._n; b--){
                   hashes.push( this.geoHash(gridLat+vt-1, b));
                   console.log('geoGrid right boundary top');
               }
               hr = Math.floor(this._n -gridLon);
           }*/
           // console.log('hl'+hl+', hr:'+hr);
           for (var i = hl; i<=hr; i++){
             hashes.push(this.geoHash(gridLat+vt,gridLon+i));
           }
            vt--;
        } while (vt>0)

     } //else {
    //    endWithinCenterCell = true;
    // }
     //center line
     if(gridLat%1 != 0){

         endGridLon = gridLon-r*this._GRID_UNIT_TO_KM;

         hl = -Math.floor(gridLon) + Math.floor(endGridLon);
         console.log('gridLon: '+gridLon+' endGridLon:'+endGridLon +' hl:'+hl);

         endGridLon = gridLon + r*this._GRID_UNIT_TO_KM;
         hr = - Math.floor(gridLon) + Math.floor(endGridLon);
         console.log('gridLon: '+gridLon+' endGridLon:'+endGridLon +' hr:'+hr);

         console.log('center line hl:'+hl+ ' hr: '+hr);
         //left boundary
         /*
         if(gridLon + hl <0){
             for(var b = Math.floor(gridLon)+hl ; b<0;b++ ){
                 hashes.push(Math.ceil(gridLat+1)*this._n+b+1);
             }
             hl=-Math.floor(gridLon);
         }
         if(gridLon + hr > this._n){
             for(var b = Math.ceil(gridLon)+hr ; b>this._n;b-- ){
                 hashes.push(Math.ceil(gridLat-1)*this._n +b);
             }
             hr = Math.floor(this._n -gridLon);
         }*/
         for(var i = hl; i <=hr; i++){
             hashes.push(this.geoHash(gridLat,gridLon+i));
         }

     }

     //bottom
     endGridLat = gridLat - r* this._GRID_UNIT_TO_KM;
    // console.log('topGridLat:'+topGridLat);
     //endGridLon = gridLon;
     endHash =  this.geoHash(endGridLat, gridLon); //
     console.log('bottom hash:'+endHash+ ' endGridLat'+endGridLat); //
   //  var topWithinCenterCell = false;
     if(Math.floor(endGridLat) < gridLat){

        var vb = Math.floor(endGridLat)-Math.floor(gridLat);

        do{
           var hl = 0;
           var hr = 0;
           do{
             var brk = false;
             //check the left to top cell intersects with the circle
             //console.log('Math.floor(gridLon)+hl'+Math.floor(gridLon)+hl); console.log('dist top left:'+this.distGrid( Math.ceil(gridLat+vt)-1, Math.floor(gridLon)+hl, gridLat, gridLon));

             if( this.distGrid( Math.ceil(gridLat)+vb, Math.floor(gridLon)+hl, gridLat, gridLon) <= r)
                hl--;
             else
                brk = true;

             //right of top cell
            //   console.log('vt: '+vt); console.log('Math.ceil(gridLat+vt)-1:'+ Math.ceil(gridLat+vt-1));
              // console.log(' Math.ceil(gridLon)+hr:'+ Math.ceil(gridLon)+hr);
               //console.log('dist form top right:'+this.distGrid( Math.ceil(gridLat+vt)-1, Math.ceil(gridLon)+hr, gridLat, gridLon));
             if( this.distGrid( Math.ceil(gridLat)+vb, Math.ceil(gridLon)+hr, gridLat, gridLon) <= r)
                hr++;
              else
                brk=true;

           } while(!brk);
           /*
           if(gridLon + hl < 0){ //boundary left
               for(var b = Math.floor(gridLon)+hl; b<0; b++){
                   hashes.push(Math.ceil(gridLat+vb+1)*this._n + b +1);
                   console.log('geoGrid left boundary bottom');
               }
               hl=-Math.floor(gridLon);
           }
           if(gridLon + hr > this._n){ //boundary right
               for(var b = Math.ceil(gridLon+hr); b > this._n; b--){
                   hashes.push(Math.ceil(gridLat+vb+1)*this._n +b );
                   console.log('geoGrid right boundary bottom');
               }
               hr = Math.floor(this._n -gridLon);
           }*/
            console.log('hl'+hl+', hr:'+hr+ ', vb:'+vb);
           for (var i = hl; i<=hr; i++){
             hashes.push(this.geoHash(gridLat+vb, i));
           }
            vb++;
        } while (vb<0)

     }

   return cb(err, hashes);
};

method.transLon= function(Lon){
//translates lat or lon to your grid's lat lon
  return (Lon +180 ) *this._GRID_TO_LON;
};

method.transLat= function(Lat){
//translates lat or lon to your grid's lat lon
  return (Lat +90) *this._GRID_TO_LAT;
};

method.distGrid= function( lat1, lon1, lat2, lon2){
   // console.log('lat1, lon1 '+lat1+','+lon1);
    var factor = Math.sin((lat1+lat2)/this._n *Math.PI );
    //var lon2Unit = Math.sin(lat2/this._n *Math.PI *2);
    //var factor = (lon1Unit+lon2Unit)/2;
//    console.log('lon2 ' + lon2 +'  lon1 '+lon1);
  //  console.log('lon1Unit :'+lon1Unit + '  lon2unit: '+ lon2Unit +'lon2-lon1:' +(lon2-lon1)+ '    lon2 * lon2Unit -lon1*lon1Unit:'+(lon2 * lon2Unit) +':::' +(lon1*lon1Unit));
  return Math.sqrt( Math.pow((lat2-lat1),2) + Math.pow((lon2  -lon1)*factor,2) ) / this._GRID_UNIT_TO_KM;
};

module.exports = GeoGrid;
<|endoftext|>


<commit_before>#!/usr/bin/env node
"use strict";
const program = require("commander");
program
  .version("0.0.6")
  .parse(process.argv);

const fs = require("fs");
const request = require("request");
const wallpaper = require("wallpaper");
const Nightmare = require("nightmare");
let nightmare = Nightmare();

const search = process.argv[2];

let url = "https://www.google.fr/search?q="
        + encodeURI(search)
        + "&biw=1366&bih=658&tbm=isch&source=lnt&tbs=photo,isz:ex,iszw:1920,iszh:1080";

nightmare
  .goto(url)
  .wait("a.rg_l")
  .evaluate(() => {
    const arr = document.querySelectorAll("a.rg_l");
    arr[Math.floor(Math.random() * arr.length)].click();
  })
  .wait(".irc_fsl[tabindex=\"0\"]")
  .evaluate(() => {
    return document.querySelector(".irc_fsl[tabindex=\"0\"]").getAttribute("href");
  })
  .end()
  .then((img) => {
    if (img != "")
    {
      const ext = img.substring(img.lastIndexOf("."));
      const uniq = (new Date()).getTime();
      request.head(img, (err, res, body) => {
        request(img)
          .pipe(fs.createWriteStream(uniq + ext))
          .on("close", () => {
            wallpaper
              .set(uniq + ext, {
                scale: "fill"
              })
              .then(() => {
                fs.unlink(uniq + ext, () => {
                  console.log("done !");
                });
              });
          });
      });
    }
    else
      console.log("not found");
  });
<commit_msg>[-] don't remove bg cause on reboot we have the default bg<commit_after>#!/usr/bin/env node
"use strict";
const program = require("commander");
program
  .version("0.0.6")
  .parse(process.argv);

const fs = require("fs");
const request = require("request");
const wallpaper = require("wallpaper");
const Nightmare = require("nightmare");
let nightmare = Nightmare();

const search = process.argv[2];

let url = "https://www.google.fr/search?q="
        + encodeURI(search)
        + "&biw=1366&bih=658&tbm=isch&source=lnt&tbs=photo,isz:ex,iszw:1920,iszh:1080";

nightmare
  .goto(url)
  .wait("a.rg_l")
  .evaluate(() => {
    const arr = document.querySelectorAll("a.rg_l");
    arr[Math.floor(Math.random() * arr.length)].click();
  })
  .wait(".irc_fsl[tabindex=\"0\"]")
  .evaluate(() => {
    return document.querySelector(".irc_fsl[tabindex=\"0\"]").getAttribute("href");
  })
  .end()
  .then((img) => {
    if (img != "")
    {
      const ext = img.substring(img.lastIndexOf("."));
      const uniq = (new Date()).getTime();
      request.head(img, (err, res, body) => {
        request(img)
          .pipe(fs.createWriteStream(uniq + ext))
          .on("close", () => {
            wallpaper
              .set(uniq + ext, {
                scale: "fill"
              })
              .then(() => {
                //fs.unlink(uniq + ext, () => {
                  console.log("done !");
                //});
              });
          });
      });
    }
    else
      console.log("not found");
  });
<|endoftext|>