<commit_before>/**
 * Created with JetBrains WebStorm.
 * User:	zenboss
 * GitHub:	zenboss
 * Date:	13-8-13
 * Time:	下午10:21
 * Email:	zenyes@gmail.com
 */
"use strict";

(function(){
    var undefined = (function(){})();
    var _window = null;
    var _module = null;
    var isNode = false;
    //判断是否NODEJS环境
    if(typeof module !== typeof undefined && typeof process !== typeof undefined && !!process.version){
        _module = module;
        isNode = true;
    }else{
        _window = window;
        isNode = false;
    }

    var __innerNextTick = null;

    var __syncInnerExec = function(funcs,count,fnSum,argv,self,nextArgs){

        if(count == fnSum){
            return;
        }else{
            funcs[count].call(
                self,
                function(){//is next function
                    count++;
    //                __syncInnerExec(funcs,count,fnSum,argv,self,arguments);
                    __innerNextTick(__syncInnerExec,funcs,count,fnSum,argv,self,arguments);
                },
                argv,
                nextArgs
            );

        }
    };

    var boss = function(){ //构造函数
        this.__events = {};
        this.__models = {};
        this.__configs = {};
        this.__actions = {};
        this.CONST = {};//常量
        this.data = {};
        this.model = {};
        this.action = {};
        this.ext = {};
        this.ext.middles = [];
        this.checkLevel = {0:true};
        this.debug=1;
        this._loadFn = null;

    };
    //单例实例
    boss.__bossInstance = null;
    boss.prototype.VER_NAME = 'ZB_FRAMEWORK_2.2';
    boss.prototype.VER_STRING = 'ZB/2.2';
    boss.prototype.VER_NUMBER = '2.2';
    boss.prototype.extendEvent = function(obj){
        obj.__events = obj.__events || {};
        obj.on = boss.prototype.on;
        obj.once = boss.prototype.once;
        obj.emit = boss.prototype.emit;
        obj.emitApply = boss.prototype.emitApply;
        obj.removeLister = boss.prototype.removeLister;
        obj.removeAllListeners = boss.prototype.removeAllListeners;
        return obj;
    };
    boss.prototype.isNode = isNode;
    boss.prototype.sync = function(funcQ,argv){
        var self = this;
        var fLen = funcQ.length;
        argv = argv||{};
        if(!Array.isArray(argv)){
            argv=[argv];
        }

        return __syncInnerExec(funcQ,0,fLen,argv,self);

    };

    //异步循环
    var syncLoop = boss.prototype.syncLoop = function(func,args){
        args = args||{};
        __innerNextTick(func,function(){
            syncLoop(func,args);
        },args)
    };

    //对某个函数超时调用的默认调用
    boss.prototype.funcTimeout = function(func,timeout){
        var self = this;
        if((timeout|0)>0){
            var funcTimeoutTHD = 0;
            var called = false;
            var funcPack = function(arg1,arg2,argN){
                clearTimeout(funcTimeoutTHD);
                var retVal;
                if(!called){ //如果超时函数没有被执行过就执行他
                    retVal = func.apply(self,arguments);
                }
                called = true;
                return retVal;
            };
            funcTimeoutTHD = setTimeout(funcPack,timeout,'timeout_call');
            return funcPack;
        }else{
            return func;
        }

    };

	//UUID
	var UUID = 1;
	boss.prototype.uuid = function(){
		return UUID++;
	}

    //委派事件
    var eventPoolUUID = 1;
    boss.prototype.on = function(event_name,func,func_name){

        func_name = func_name || "__default__"+eventPoolUUID;
        eventPoolUUID++;
        this.__events[event_name] = this.__events[event_name] || {};
        this.__events[event_name][func_name] = func.bind(this);
        this.debug && console.log('-[boss.on]:['+event_name+']:',func_name);
    };

    //委派一次性事件
    boss.prototype.once = function(eventName,func,func_name){
        var self = this;
        func_name = func_name || "__default__"+eventPoolUUID;
        eventPoolUUID++;
        self.on(eventName,function(){
            func.apply(self,arguments);
            self.removeLister(eventName,func_name)
        },func_name);
    };

    //激发事件
    boss.prototype.emit = function(event_name,arg1){
        var self = this;
    //    self.debug && console.log('-[boss.emit]-:',event_name);
        var tmp_event_all = this.__events[event_name] || {};
        var args = [];
        for(var i=1;i<arguments.length;i++){
            args.push(arguments[i]);
        }
        var eventFnCount = 0;
        for(var key in tmp_event_all){
            var theFunc = tmp_event_all[key];
            __innerNextTick.apply(self,[theFunc].concat(args));
            self.debug && console.log('-[boss.emit]:['+event_name+']:',key);
            eventFnCount++;
    //        process.nextTick((function(_theFunc){
    //            return function(){
    //                _theFunc.apply(self,args);
    //            };
    //
    //        })(theFunc));

        }
        return eventFnCount;
    };

    //激发事件，第二位参数是数组
    boss.prototype.emitApply = function(event_name,argArray){
        var self = this;
        var args = [event_name];
        for(var i=0;i<argArray.length;i++){
            args.push(argArray[i]);
        }
        console.log(args);
        return self.emit.apply(self,args);
    };

    //移除监听
    boss.prototype.removeLister = function(event_name,func_name){

        var tmp_event_all = this.__events[event_name] || {};
        if(func_name){ //如果输入了函数名，就只删除这一个函数
            delete tmp_event_all[func_name];
        }else{//如果没有输入函数名，就把整个事件删除
            delete this.__events[event_name];
        }
    };

    //移除所有监听
    boss.prototype.removeAllListeners = function(event_name){
        delete this.__events[event_name];
    };

    //检查函数
    boss.prototype.check = function(level,args){ //用来收集数据的函数

        var self = this;
    //    var arg = [];
    //    for(var i in arguments){
    //        arg[arg.length] = arguments[i];
    //    }
    //    arg.unshift("boss.check."+level);
    //    console.log("check...");
        self.emit("boss.check",arguments);

    };

    boss.prototype.load = function(loadFn){
        this._loadFn = loadFn;
        this._loadFn();

    };
    boss.prototype.reload = function(){
        if('function' == typeof this._loadFn){
            this._loadFn();
        }
    };

    boss.prototype.help = {};
    boss.prototype.help.fs = {};
    boss.prototype.help.fs.createMenuSync = function(path,cb){
        cb = cb||function(file){return file;};
        var self = this;
        var retVal = {};

        var fs = require('fs');
        var fileStat = fs.lstatSync(path); //获得文件信息，包括大小

        if (fileStat === undefined) return false;

        if(fileStat.isDirectory()){//如果不是文件夹

            var dirInfo = fs.readdirSync(path);

            for(var key in dirInfo){
                var item = dirInfo[key];
                var bias = '';
                if(path[path.length-1]!='/'){
                    bias = '/';
                }
                var filePath = path+bias+item;

                var _retVal = self.createMenuSync.call(self,filePath,cb);
                for(var _key in _retVal){
                    retVal[_key] = _retVal[_key];
                }

            }
            return retVal;

        }else{

            var file = fs.statSync(path);

            file['/real_path/'] = fs.realpathSync(path);
            file['/file_name/'] = file['/real_path/'].substring(file['/real_path/'].lastIndexOf('/')+1);
            var extIndex = file['/file_name/'].lastIndexOf('.');
            file['/ext/'] = file['/file_name/'].substring(extIndex+1);
            file['/name/'] = file['/file_name/'].substring(0,extIndex);
            file['/path/'] = path;
            var dirIndex = file['/real_path/'].lastIndexOf('/');
            file['/dir/'] = file['/real_path/'].substring(0,dirIndex);
            file['/isDir/'] = false;
            file['/type/'] = 'file';

            var fileType = null;
            if(file.isFile()){
                fileType = 'file';
            }else if(file.isDirectory()){
                fileType = 'directory';
            }else if(file.isBlockDevice()){
                fileType = 'block_device';
            }else if(file.isCharacterDevice()){
                fileType = 'character_device';
            }else if(file.isSymbolicLink()){
                fileType = 'symbolic_link';
            }else if(file.isFIFO()){
                fileType = 'FIFO';
            }else if(file.isSocket()){
                fileType = 'socket';
            }
            file['/type/'] = fileType;

            retVal[file['/real_path/']] = cb(file);
            return retVal;

        }

    };
    //按行读取文件
    boss.prototype.help.fs.readFileLine = function(path,cb,endCB){
        var fs = require('fs');

        cb = cb||function(){};
        endCB = endCB||function(){};

        fs.stat(path,function(err,stats){
    //        console.log(err,stats);
            if(err){
                endCB(err);
                return;
            }
            var fl = fs.createReadStream(path,{bufferSize:512});
    //    var nullFl = fs.createReadStream('/dev/null',{bufferSize:512});

            var readline = require('readline');
            var rl = readline.createInterface({
                input:fl,
                output:fl

            });
            var lineNum = 0;
            rl.on('line',function(line){
                lineNum++;
                cb.call(rl,line,lineNum);
            })
            fl.on('end',endCB);
        });

    };
    boss.prototype.help.fs.mkdirs = function(dir,mode,cb){
        if('function' == typeof mode){
            cb = mode;
            mode = '0777';
        }
        cb = cb || function(){};
        var self = this;
        var fs = require('fs');
        var path = require('path');
        fs.exists(dir,function(exists){
            if(exists){
                cb(null,dir);

            }else{
                self.mkdirs(path.dirname(dir),mode,function(){
                    fs.mkdir(dir,mode,cb);
                });

            }

        })

    };
    boss.prototype.addModel = function(pathOrObj,modelName){
        var self = this;
        if('string' == typeof pathOrObj){
            try{
                pathOrObj = require(pathOrObj);
            }catch(ex){
                console.error('addModel - model path not found file');
                pathOrObj=null;
            }

        }

        if(!!pathOrObj){
            if(!modelName){
                console.error("model name cannot is empty");
                return null;
            }
            for(var funcName in pathOrObj){
                var theFunc = pathOrObj[funcName];
                if('function' == typeof theFunc && pathOrObj.hasOwnProperty(funcName)){
                    pathOrObj[funcName] = pathOrObj[funcName].bind(self);
                }
            }

            self.__models[modelName] = pathOrObj;
        }
        return self;

    };
    boss.prototype.getModel = function(modelName){
        if(modelName){
            return this.__models[modelName];
        }else{
            return this.__models;
        }

    };
    boss.prototype.config = function(configname,val){
        if('object' == typeof configname){
            for(var _k in configname){
                this.__configs[_k] = configname[_k];
            }
            return this.__configs;
        }
        if(arguments.length>=2){
            this.__configs[configname] = val;
        }

        if(configname){
            return this.__configs[configname];
        }else{
            return this.__configs;
        }
    };
    boss.prototype.loadConfig = function(path,cb){
        var paths = this.help.fs.createMenuSync(path);
        for(var _path in paths){
            var conf = require(_path);
            this.config(conf);
        }

    };

    boss.prototype.emitCronjob = function(){
        var self = this;
        var now = new Date();
        var nowTimeStamp = now.valueOf();

        var h = ('0'+now.getHours()).substr(-2); //使用原生的更快一些
        var i = ('0'+now.getMinutes()).substr(-2);
        var hi = h+':'+i;
        self.emit("boss.time.xx:xx",nowTimeStamp,now);
        self.emit("boss.time."+hi,nowTimeStamp,now);
        self.emit("boss.time.xx:"+i,nowTimeStamp,now);
    };

    var defaultTimeEventsIHD = null;//默认时间事件句柄
    boss.prototype.runDefaultTimeEvents = function(){
        var self = this;
		if(!!defaultTimeEventsIHD){
			return defaultTimeEventsIHD;
		}

        defaultTimeEventsIHD = setInterval(self.emitCronjob,1000*60);
        return defaultTimeEventsIHD;
    };

    boss.prototype.stopDefaultTimeEvents = function(){
        if(defaultTimeEventsIHD!==null){
            clearInterval(defaultTimeEventsIHD);
        }
		defaultTimeEventsIHD = null;
    };

    //空函数
    boss.prototype.noneFunc = function(){};

    //获得NODEJS 系统参数
    if(isNode && process && process.argv){
        boss.prototype.argv = {};
        var argv = process.argv.slice(2);
        for(var i in argv){
            var _temp = argv[i].split('=');
            var k = _temp[0];
            var v = _temp[1];
            if(0==k.indexOf('--')){
                k = k.substr(2);
                boss.prototype.argv[k] = v;
            }

        }
    }

    boss.instanceName = 'boss';
    if(isNode){
        __innerNextTick = boss.prototype.nextTick = setImmediate;

        _module.exports = function(opt){
            opt = opt||{};
            if(!boss.__bossInstance){
                boss.__bossInstance = new boss();
                if(opt.runDefaultTimeEvents!==false){
                    boss.__bossInstance.runDefaultTimeEvents();
                }

            }
            return boss.__bossInstance;
        };

    }else{

        __innerNextTick = boss.prototype.nextTick = function(fn){
            var args = Array.prototype.slice.call(arguments,1);
            return setTimeout(function(){
                fn.apply(null,args);
            },0);
        }

        //退位函数
        boss.prototype.abdicate = function(){
            var inst = _window[boss.instanceName];
            _window[boss.instanceName] = boss._preInstanceNameObj;
            return inst;
        };
        //原始的值
        boss._preInstanceNameObj = _window[boss.instanceName];
        var instance = _window[boss.instanceName] = new boss();
        instance.runDefaultTimeEvents();

    }

})();<commit_msg>Add a function's remarks<commit_after>/**
 * Created with JetBrains WebStorm.
 * User:	zenboss
 * GitHub:	zenboss
 * Date:	13-8-13
 * Time:	下午10:21
 * Email:	zenyes@gmail.com
 */
"use strict";

(function(){
    var undefined = (function(){})();
    var _window = null;
    var _module = null;
    var isNode = false;
    //判断是否NODEJS环境
    if(typeof module !== typeof undefined && typeof process !== typeof undefined && !!process.version){
        _module = module;
        isNode = true;
    }else{
        _window = window;
        isNode = false;
    }

    var __innerNextTick = null;

    var __syncInnerExec = function(funcs,count,fnSum,argv,self,nextArgs){

        if(count == fnSum){
            return;
        }else{
            funcs[count].call(
                self,
                function(){//is next function
                    count++;
    //                __syncInnerExec(funcs,count,fnSum,argv,self,arguments);
                    __innerNextTick(__syncInnerExec,funcs,count,fnSum,argv,self,arguments);
                },
                argv,
                nextArgs
            );

        }
    };

    var boss = function(){ //构造函数
        this.__events = {};
        this.__models = {};
        this.__configs = {};
        this.__actions = {};
        this.CONST = {};//常量
        this.data = {};
        this.model = {};
        this.action = {};
        this.ext = {};
        this.ext.middles = [];
        this.checkLevel = {0:true};
        this.debug=1;
        this._loadFn = null;

    };
    //单例实例
    boss.__bossInstance = null;
    boss.prototype.VER_NAME = 'ZB_FRAMEWORK_2.2';
    boss.prototype.VER_STRING = 'ZB/2.2';
    boss.prototype.VER_NUMBER = '2.2';
    boss.prototype.extendEvent = function(obj){
        obj.__events = obj.__events || {};
        obj.on = boss.prototype.on;
        obj.once = boss.prototype.once;
        obj.emit = boss.prototype.emit;
        obj.emitApply = boss.prototype.emitApply;
        obj.removeLister = boss.prototype.removeLister;
        obj.removeAllListeners = boss.prototype.removeAllListeners;
        return obj;
    };
    boss.prototype.isNode = isNode;
    boss.prototype.sync = function(funcQ,argv){
        var self = this;
        var fLen = funcQ.length;
        argv = argv||{};
        if(!Array.isArray(argv)){
            argv=[argv];
        }

        return __syncInnerExec(funcQ,0,fLen,argv,self);

    };

    //异步循环
    var syncLoop = boss.prototype.syncLoop = function(func,args){
        args = args||{};
        __innerNextTick(func,function(){
            syncLoop(func,args);
        },args)
    };

    //对某个函数超时调用的默认调用
    boss.prototype.funcTimeout = function(func,timeout){
        var self = this;
        if((timeout|0)>0){
            var funcTimeoutTHD = 0;
            var called = false;
            var funcPack = function(arg1,arg2,argN){
                clearTimeout(funcTimeoutTHD);
                var retVal;
                if(!called){ //如果超时函数没有被执行过就执行他
                    retVal = func.apply(self,arguments);
                }
                called = true;
                return retVal;
            };
            funcTimeoutTHD = setTimeout(funcPack,timeout,'timeout_call');
            return funcPack;
        }else{
            return func;
        }

    };

	//UUID
	var UUID = 1;
	boss.prototype.uuid = function(){
		return UUID++;
	}

    //委派事件
    var eventPoolUUID = 1;
    boss.prototype.on = function(event_name,func,func_name){

        func_name = func_name || "__default__"+eventPoolUUID;
        eventPoolUUID++;
        this.__events[event_name] = this.__events[event_name] || {};
        this.__events[event_name][func_name] = func.bind(this);
        this.debug && console.log('-[boss.on]:['+event_name+']:',func_name);
    };

    //委派一次性事件
    boss.prototype.once = function(eventName,func,func_name){
        var self = this;
        func_name = func_name || "__default__"+eventPoolUUID;
        eventPoolUUID++;
        self.on(eventName,function(){
            func.apply(self,arguments);
            self.removeLister(eventName,func_name)
        },func_name);
    };

    //激发事件
    boss.prototype.emit = function(event_name,arg1){
        var self = this;
    //    self.debug && console.log('-[boss.emit]-:',event_name);
        var tmp_event_all = this.__events[event_name] || {};
        var args = [];
        for(var i=1;i<arguments.length;i++){
            args.push(arguments[i]);
        }
        var eventFnCount = 0;
        for(var key in tmp_event_all){
            var theFunc = tmp_event_all[key];
            __innerNextTick.apply(self,[theFunc].concat(args));
            self.debug && console.log('-[boss.emit]:['+event_name+']:',key);
            eventFnCount++;
    //        process.nextTick((function(_theFunc){
    //            return function(){
    //                _theFunc.apply(self,args);
    //            };
    //
    //        })(theFunc));

        }
        return eventFnCount;
    };

    //激发事件，第二位参数是数组
    boss.prototype.emitApply = function(event_name,argArray){
        var self = this;
        var args = [event_name];
        for(var i=0;i<argArray.length;i++){
            args.push(argArray[i]);
        }
        console.log(args);
        return self.emit.apply(self,args);
    };

    //移除监听
    boss.prototype.removeLister = function(event_name,func_name){

        var tmp_event_all = this.__events[event_name] || {};
        if(func_name){ //如果输入了函数名，就只删除这一个函数
            delete tmp_event_all[func_name];
        }else{//如果没有输入函数名，就把整个事件删除
            delete this.__events[event_name];
        }
    };

    //移除所有监听
    boss.prototype.removeAllListeners = function(event_name){
        delete this.__events[event_name];
    };

    //检查函数
    boss.prototype.check = function(level,args){ //用来收集数据的函数

        var self = this;
    //    var arg = [];
    //    for(var i in arguments){
    //        arg[arg.length] = arguments[i];
    //    }
    //    arg.unshift("boss.check."+level);
    //    console.log("check...");
        self.emit("boss.check",arguments);

    };

    boss.prototype.load = function(loadFn){
        this._loadFn = loadFn;
        this._loadFn();

    };
    boss.prototype.reload = function(){
        if('function' == typeof this._loadFn){
            this._loadFn();
        }
    };

    boss.prototype.help = {};
    boss.prototype.help.fs = {};
    boss.prototype.help.fs.createMenuSync = function(path,cb){
        cb = cb||function(file){return file;};
        var self = this;
        var retVal = {};

        var fs = require('fs');
        var fileStat = fs.lstatSync(path); //获得文件信息，包括大小

        if (fileStat === undefined) return false;

        if(fileStat.isDirectory()){//如果不是文件夹

            var dirInfo = fs.readdirSync(path);

            for(var key in dirInfo){
                var item = dirInfo[key];
                var bias = '';
                if(path[path.length-1]!='/'){
                    bias = '/';
                }
                var filePath = path+bias+item;

                var _retVal = self.createMenuSync.call(self,filePath,cb);
                for(var _key in _retVal){
                    retVal[_key] = _retVal[_key];
                }

            }
            return retVal;

        }else{

            var file = fs.statSync(path);

            file['/real_path/'] = fs.realpathSync(path);
            file['/file_name/'] = file['/real_path/'].substring(file['/real_path/'].lastIndexOf('/')+1);
            var extIndex = file['/file_name/'].lastIndexOf('.');
            file['/ext/'] = file['/file_name/'].substring(extIndex+1);
            file['/name/'] = file['/file_name/'].substring(0,extIndex);
            file['/path/'] = path;
            var dirIndex = file['/real_path/'].lastIndexOf('/');
            file['/dir/'] = file['/real_path/'].substring(0,dirIndex);
            file['/isDir/'] = false;
            file['/type/'] = 'file';

            var fileType = null;
            if(file.isFile()){
                fileType = 'file';
            }else if(file.isDirectory()){
                fileType = 'directory';
            }else if(file.isBlockDevice()){
                fileType = 'block_device';
            }else if(file.isCharacterDevice()){
                fileType = 'character_device';
            }else if(file.isSymbolicLink()){
                fileType = 'symbolic_link';
            }else if(file.isFIFO()){
                fileType = 'FIFO';
            }else if(file.isSocket()){
                fileType = 'socket';
            }
            file['/type/'] = fileType;

            retVal[file['/real_path/']] = cb(file);
            return retVal;

        }

    };
    //按行读取文件
    boss.prototype.help.fs.readFileLine = function(path,cb,endCB){
        var fs = require('fs');

        cb = cb||function(){};
        endCB = endCB||function(){};

        fs.stat(path,function(err,stats){
    //        console.log(err,stats);
            if(err){
                endCB(err);
                return;
            }
            var fl = fs.createReadStream(path,{bufferSize:512});
    //    var nullFl = fs.createReadStream('/dev/null',{bufferSize:512});

            var readline = require('readline');
            var rl = readline.createInterface({
                input:fl,
                output:fl

            });
            var lineNum = 0;
            rl.on('line',function(line){
                lineNum++;
                cb.call(rl,line,lineNum);
            })
            fl.on('end',endCB);
        });

    };
    boss.prototype.help.fs.mkdirs = function(dir,mode,cb){
        if('function' == typeof mode){
            cb = mode;
            mode = '0777';
        }
        cb = cb || function(){};
        var self = this;
        var fs = require('fs');
        var path = require('path');
        fs.exists(dir,function(exists){
            if(exists){
                cb(null,dir);

            }else{
                self.mkdirs(path.dirname(dir),mode,function(){
                    fs.mkdir(dir,mode,cb);
                });

            }

        })

    };
    boss.prototype.addModel = function(pathOrObj,modelName){
        var self = this;
        if('string' == typeof pathOrObj){
            try{
                pathOrObj = require(pathOrObj);
            }catch(ex){
                console.error('addModel - model path not found file');
                pathOrObj=null;
            }

        }

        if(!!pathOrObj){
            if(!modelName){
                console.error("model name cannot is empty");
                return null;
            }
            for(var funcName in pathOrObj){
                var theFunc = pathOrObj[funcName];
                if('function' == typeof theFunc && pathOrObj.hasOwnProperty(funcName)){
                    pathOrObj[funcName] = pathOrObj[funcName].bind(self);
                }
            }

            self.__models[modelName] = pathOrObj;
        }
        return self;

    };
    boss.prototype.getModel = function(modelName){
        if(modelName){
            return this.__models[modelName];
        }else{
            return this.__models;
        }

    };
    boss.prototype.config = function(configname,val){
        if('object' == typeof configname){
            for(var _k in configname){
                this.__configs[_k] = configname[_k];
            }
            return this.__configs;
        }
        if(arguments.length>=2){
            this.__configs[configname] = val;
        }

        if(configname){
            return this.__configs[configname];
        }else{
            return this.__configs;
        }
    };
    boss.prototype.loadConfig = function(path,cb){
        var paths = this.help.fs.createMenuSync(path);
        for(var _path in paths){
            var conf = require(_path);
            this.config(conf);
        }

    };

    //工作程式主函数
    boss.prototype.emitCronjob = function(){
        var self = this;
        var now = new Date();
        var nowTimeStamp = now.valueOf();

        var h = ('0'+now.getHours()).substr(-2); //使用原生的更快一些
        var i = ('0'+now.getMinutes()).substr(-2);
        var hi = h+':'+i;
        self.emit("boss.time.xx:xx",nowTimeStamp,now);
        self.emit("boss.time."+hi,nowTimeStamp,now);
        self.emit("boss.time.xx:"+i,nowTimeStamp,now);
    };

    var defaultTimeEventsIHD = null;//默认时间事件句柄
    boss.prototype.runDefaultTimeEvents = function(){
        var self = this;
		if(!!defaultTimeEventsIHD){
			return defaultTimeEventsIHD;
		}
        defaultTimeEventsIHD = setInterval(self.emitCronjob,1000*60);
        return defaultTimeEventsIHD;
    };

    boss.prototype.stopDefaultTimeEvents = function(){
        if(defaultTimeEventsIHD!==null){
            clearInterval(defaultTimeEventsIHD);
        }
		defaultTimeEventsIHD = null;
    };

    //空函数
    boss.prototype.noneFunc = function(){};

    //获得NODEJS 系统参数
    if(isNode && process && process.argv){
        boss.prototype.argv = {};
        var argv = process.argv.slice(2);
        for(var i in argv){
            var _temp = argv[i].split('=');
            var k = _temp[0];
            var v = _temp[1];
            if(0==k.indexOf('--')){
                k = k.substr(2);
                boss.prototype.argv[k] = v;
            }

        }
    }

    boss.instanceName = 'boss';
    if(isNode){
        __innerNextTick = boss.prototype.nextTick = setImmediate;

        _module.exports = function(opt){
            opt = opt||{};
            if(!boss.__bossInstance){
                boss.__bossInstance = new boss();
                if(opt.runDefaultTimeEvents!==false){
                    boss.__bossInstance.runDefaultTimeEvents();
                }

            }
            return boss.__bossInstance;
        };

    }else{

        __innerNextTick = boss.prototype.nextTick = function(fn){
            var args = Array.prototype.slice.call(arguments,1);
            return setTimeout(function(){
                fn.apply(null,args);
            },0);
        }

        //退位函数
        boss.prototype.abdicate = function(){
            var inst = _window[boss.instanceName];
            _window[boss.instanceName] = boss._preInstanceNameObj;
            return inst;
        };
        //原始的值
        boss._preInstanceNameObj = _window[boss.instanceName];
        var instance = _window[boss.instanceName] = new boss();
        instance.runDefaultTimeEvents();

    }

})();<|endoftext|>


<commit_before>"use strict";

var p2r = require('path-to-regexp'),
    funcDeps = require('func-deps'),
    q = require('q'),
    _ = require('lodash'),
    http = require('http'),
    util = require('util');

var coreProviderNames = [
    'send-json', 'send',
    'accepts', 'accepts-encodings', 'accepts-charsets', 'accepts-languages',
    'range', 'type-is'];
var coreProviders = [];

function dashToCamel(string) {
    return string.replace(/\W+(.)/g, function (x, chr) {
        return chr.toUpperCase();
    });
};

coreProviderNames.forEach(function(providerName) {
    var injectionName = dashToCamel(providerName);
    var provider = require('./providers/' + providerName);
    coreProviders.push(
        getProviderDefinition('ALL', /.*/, injectionName, provider()));
});

function Molded() {
    if (typeof this === 'undefined') {
        return new Molded();
    }
    this.providers = coreProviders;
    this.singletons = [];
    this.values = [];
    this.handlers = [];
    this.errorHandlers = [];
}

function initialDep(name, value) {
    return {
        method: 'ALL',
        route: /.*/,
        name: name,
        value: value
    }
};

function initialDeps(req, res, next, err) {
    var deps = [
        initialDep('req', req),
        initialDep('res', res),
    ];
    if (next) {
        deps.push(initialDep('next', next));
    }
    if (err) {
        deps.push(initialDep('err', err));
    }
    return deps;
}

Molded.prototype.resolveDeps = function resolveDeps(method, url, initialDeps, depNames) {
    var self = this;
    var possibleDeps = []
        .concat(initialDeps)
        .concat(this.values)
        .concat(this.singletons)
        .concat(this.providers);

    var nextlessDeps = initialDeps.filter(function(dep) {
        return dep.name !== 'next';
    });
    var resolvedDeps = [];
    _.forEach(depNames, function(dep, index) {
        var found = _.find(possibleDeps, function(possibleDep) {
            if (!methodMatches(method, possibleDep.method)) {
                return false;
            }
            return possibleDep.name == dep
                && null !== possibleDep.route.exec(url);
        });
        if (found) {
            if (found.value) {
                resolvedDeps.push(found.value);
            } else {
                resolvedDeps.push(self.resolveAndCall(method, url, nextlessDeps, found));
            }
        } else {
            resolvedDeps.push(q.fcall(function() {
                throw Error('Unresolved dependency: ' + dep);
            }));
            return false;
        }
    });
    return q.all(resolvedDeps);
};

Molded.prototype.resolveAndCall = function resolveAndCall(method, url, initialDeps, callback) {
    var depsPromise = this.resolveDeps(method, url, initialDeps, callback.deps);
    return depsPromise.then(function(resolvedDeps) {
        return callback.resolve.apply(null, resolvedDeps)
    });
};

function routeParams(route, url, keys) {
    var keys = _.map(keys || [], function(key) {
        if ('string' === typeof key) {
            return key;
        } else {
            return key.name;
        }
    });
    var params = params = route.exec(url);
    if (null === params) {
        return null;
    }
    params = Array.prototype.slice.call(params, 1);
    if (keys.length > 0) {
        return _.zipObject(keys, params);
    } else {
        return params;
    }
}

function methodMatches(expected, actual) {
    return 'ALL' === actual || expected === actual;
}

Molded.prototype.handleRequest = function handleRequest(req, res) {
    var self = this;
    var handlers = _.clone(this.handlers);
    function next(err) {
        if (err) {
            self.handleError(req, res, err);
        } else {
            if (handlers.length > 0) {
                var handler = handlers.shift();
                if (!methodMatches(req.method, handler.method)) {
                    return next();
                }
                var params = handler.route.exec(req.url);
                if (null === params) {
                    return next();
                }
                req.params = routeParams(handler.route, req.url, handler.keys);
                var deps = initialDeps(req, res, next);
                self.resolveAndCall(req.method, req.url, deps, handler)
                    .catch(function(err) {
                        self.handleError(req, res, err)
                    });
            } else {
                res.statusCode = 404;
                res.write(util.format("Can't %s %s", req.method, req.url));
                res.end();
            }
        }
    }
    next();
};

Molded.prototype.handleError = function handleError(req, res, err) {
    var self = this;
    var errorHandlers = _.clone(this.errorHandlers);
    function next(err) {
        if (errorHandlers.length > 0) {
            var handler = errorHandlers.shift();
            if (!methodMatches(req.method, handler.method)) {
                return next(err);
            }
            var params = handler.route.exec(req.url);
            if (null === params) {
                return next(err);
            }
            req.params = routeParams(handler.route, req.url, handler.keys);
            self.resolveAndCall(req.method, req.url, initialDeps(req, res, next, err), handler).catch(function(err) {
                next(err);
            });
        } else {
            console.log(err);
            res.statusCode = 500;
            var message = 'An error has occurred. ' +
                'Either there are no error handlers, ' +
                'or the associated error handler(s) also threw error(s).'
            res.end(message);
        }
    }
    next(err);
};

function addHandler(method, route, handler) {
    if (_.isFunction(route) || _.isArray(route)) {
        handler = route;
        route = /.*/;
    }
    var keys = [];
    var route = p2r(route, keys);
    var deps = funcDeps(handler);
    this.handlers.push({
        method: method,
        keys: keys,
        route: route,
        resolve: deps.func,
        deps: deps.deps
    });
}

function getProviderDefinition(method, route, name, func) {
    var deps = funcDeps(func);
    return {
        method: 'ALL',
        route: /.*/,
        name: name,
        deps: deps.deps,
        resolve: deps.func
    };
};

Molded.prototype.provide = function provide(depName, provider) {
    this.providers.push(
        getProviderDefinition('ALL', /.*/, depName, provider));
};

Molded.prototype.singleton = function singleton(depName, func) {
    var deps = funcDeps(func);
    var single = {
        method: 'ALL',
        route: /.*/,
        name: depName,
        deps: deps.deps,
        resolve: deps.func
    };
    single.value = this.resolveAndCall('ALL', '/', [], single);
    this.singletons.push(single);
};

Molded.prototype.value = function value(depName, val) {
    if (val) {
        this.values.push({
            method: 'ALL',
            route: /.*/,
            name: depName,
            value: val
        });
    } else {
        var found = _.find(this.values, function(value) {
            return value.name === depName
        });
        return undefined === found ? undefined : found.value;
    }
};

Molded.prototype.error = function error(route, handler) {
    if (_.isFunction(route) || _.isArray(route)) {
        handler = route;
        route = /.*/;
    }
    var keys = [];
    var route = p2r(route, keys);
    var deps = funcDeps(handler);
    this.errorHandlers.push({
        method: 'ALL',
        keys: keys,
        route: route,
        resolve: deps.func,
        deps: deps.deps
    });
};

Molded.prototype.use = function() {
    var args = ['ALL'].concat(Array.prototype.slice.apply(arguments));
    addHandler.apply(this, args);
};

var methods = ['get', 'post', 'put', 'patch', 'delete', 'copy',
               'head', 'options', 'link', 'unlink', 'purge', 'all'];

_.forEach(methods, function(method) {
    var methodUpper = method.toUpperCase();
    Molded.prototype[method] = function() {
        var args = [methodUpper].concat(Array.prototype.slice.apply(arguments));
        addHandler.apply(this, args);
    };
});

Molded.prototype.listen = function listen(port, cb) {
    http.createServer(this.handleRequest.bind(this)).listen(port);
};

module.exports = Molded;
<commit_msg>Add close method to app<commit_after>"use strict";

var p2r = require('path-to-regexp'),
    funcDeps = require('func-deps'),
    q = require('q'),
    _ = require('lodash'),
    http = require('http'),
    util = require('util');

var coreProviderNames = [
    'send-json', 'send',
    'accepts', 'accepts-encodings', 'accepts-charsets', 'accepts-languages',
    'range', 'type-is'];
var coreProviders = [];

function dashToCamel(string) {
    return string.replace(/\W+(.)/g, function (x, chr) {
        return chr.toUpperCase();
    });
};

coreProviderNames.forEach(function(providerName) {
    var injectionName = dashToCamel(providerName);
    var provider = require('./providers/' + providerName);
    coreProviders.push(
        getProviderDefinition('ALL', /.*/, injectionName, provider()));
});

function Molded() {
    if (typeof this === 'undefined') {
        return new Molded();
    }
    this.providers = coreProviders;
    this.singletons = [];
    this.values = [];
    this.handlers = [];
    this.errorHandlers = [];
}

function initialDep(name, value) {
    return {
        method: 'ALL',
        route: /.*/,
        name: name,
        value: value
    }
};

function initialDeps(req, res, next, err) {
    var deps = [
        initialDep('req', req),
        initialDep('res', res),
    ];
    if (next) {
        deps.push(initialDep('next', next));
    }
    if (err) {
        deps.push(initialDep('err', err));
    }
    return deps;
}

Molded.prototype.resolveDeps = function resolveDeps(method, url, initialDeps, depNames) {
    var self = this;
    var possibleDeps = []
        .concat(initialDeps)
        .concat(this.values)
        .concat(this.singletons)
        .concat(this.providers);

    var nextlessDeps = initialDeps.filter(function(dep) {
        return dep.name !== 'next';
    });
    var resolvedDeps = [];
    _.forEach(depNames, function(dep, index) {
        var found = _.find(possibleDeps, function(possibleDep) {
            if (!methodMatches(method, possibleDep.method)) {
                return false;
            }
            return possibleDep.name == dep
                && null !== possibleDep.route.exec(url);
        });
        if (found) {
            if (found.value) {
                resolvedDeps.push(found.value);
            } else {
                resolvedDeps.push(self.resolveAndCall(method, url, nextlessDeps, found));
            }
        } else {
            resolvedDeps.push(q.fcall(function() {
                throw Error('Unresolved dependency: ' + dep);
            }));
            return false;
        }
    });
    return q.all(resolvedDeps);
};

Molded.prototype.resolveAndCall = function resolveAndCall(method, url, initialDeps, callback) {
    var depsPromise = this.resolveDeps(method, url, initialDeps, callback.deps);
    return depsPromise.then(function(resolvedDeps) {
        return callback.resolve.apply(null, resolvedDeps)
    });
};

function routeParams(route, url, keys) {
    var keys = _.map(keys || [], function(key) {
        if ('string' === typeof key) {
            return key;
        } else {
            return key.name;
        }
    });
    var params = params = route.exec(url);
    if (null === params) {
        return null;
    }
    params = Array.prototype.slice.call(params, 1);
    if (keys.length > 0) {
        return _.zipObject(keys, params);
    } else {
        return params;
    }
}

function methodMatches(expected, actual) {
    return 'ALL' === actual || expected === actual;
}

Molded.prototype.handleRequest = function handleRequest(req, res) {
    var self = this;
    var handlers = _.clone(this.handlers);
    function next(err) {
        if (err) {
            self.handleError(req, res, err);
        } else {
            if (handlers.length > 0) {
                var handler = handlers.shift();
                if (!methodMatches(req.method, handler.method)) {
                    return next();
                }
                var params = handler.route.exec(req.url);
                if (null === params) {
                    return next();
                }
                req.params = routeParams(handler.route, req.url, handler.keys);
                var deps = initialDeps(req, res, next);
                self.resolveAndCall(req.method, req.url, deps, handler)
                    .catch(function(err) {
                        self.handleError(req, res, err)
                    });
            } else {
                res.statusCode = 404;
                res.write(util.format("Can't %s %s", req.method, req.url));
                res.end();
            }
        }
    }
    next();
};

Molded.prototype.handleError = function handleError(req, res, err) {
    var self = this;
    var errorHandlers = _.clone(this.errorHandlers);
    function next(err) {
        if (errorHandlers.length > 0) {
            var handler = errorHandlers.shift();
            if (!methodMatches(req.method, handler.method)) {
                return next(err);
            }
            var params = handler.route.exec(req.url);
            if (null === params) {
                return next(err);
            }
            req.params = routeParams(handler.route, req.url, handler.keys);
            self.resolveAndCall(req.method, req.url, initialDeps(req, res, next, err), handler).catch(function(err) {
                next(err);
            });
        } else {
            console.log(err);
            res.statusCode = 500;
            var message = 'An error has occurred. ' +
                'Either there are no error handlers, ' +
                'or the associated error handler(s) also threw error(s).'
            res.end(message);
        }
    }
    next(err);
};

function addHandler(method, route, handler) {
    if (_.isFunction(route) || _.isArray(route)) {
        handler = route;
        route = /.*/;
    }
    var keys = [];
    var route = p2r(route, keys);
    var deps = funcDeps(handler);
    this.handlers.push({
        method: method,
        keys: keys,
        route: route,
        resolve: deps.func,
        deps: deps.deps
    });
}

function getProviderDefinition(method, route, name, func) {
    var deps = funcDeps(func);
    return {
        method: 'ALL',
        route: /.*/,
        name: name,
        deps: deps.deps,
        resolve: deps.func
    };
};

Molded.prototype.provide = function provide(depName, provider) {
    this.providers.push(
        getProviderDefinition('ALL', /.*/, depName, provider));
};

Molded.prototype.singleton = function singleton(depName, func) {
    var deps = funcDeps(func);
    var single = {
        method: 'ALL',
        route: /.*/,
        name: depName,
        deps: deps.deps,
        resolve: deps.func
    };
    single.value = this.resolveAndCall('ALL', '/', [], single);
    this.singletons.push(single);
};

Molded.prototype.value = function value(depName, val) {
    if (val) {
        this.values.push({
            method: 'ALL',
            route: /.*/,
            name: depName,
            value: val
        });
    } else {
        var found = _.find(this.values, function(value) {
            return value.name === depName
        });
        return undefined === found ? undefined : found.value;
    }
};

Molded.prototype.error = function error(route, handler) {
    if (_.isFunction(route) || _.isArray(route)) {
        handler = route;
        route = /.*/;
    }
    var keys = [];
    var route = p2r(route, keys);
    var deps = funcDeps(handler);
    this.errorHandlers.push({
        method: 'ALL',
        keys: keys,
        route: route,
        resolve: deps.func,
        deps: deps.deps
    });
};

Molded.prototype.use = function() {
    var args = ['ALL'].concat(Array.prototype.slice.apply(arguments));
    addHandler.apply(this, args);
};

var methods = ['get', 'post', 'put', 'patch', 'delete', 'copy',
               'head', 'options', 'link', 'unlink', 'purge', 'all'];

_.forEach(methods, function(method) {
    var methodUpper = method.toUpperCase();
    Molded.prototype[method] = function() {
        var args = [methodUpper].concat(Array.prototype.slice.apply(arguments));
        addHandler.apply(this, args);
    };
});

Molded.prototype.listen = function listen(port, cb) {
    this.server = http.createServer(this.handleRequest.bind(this)).listen(port);
};

Molded.prototype.close = function close(cb) {
    if (this.server) {
        this.server.close(cb);
        this.server = null;
    }
};

module.exports = Molded;
<|endoftext|>


<commit_before>module.exports = SteamTradeOffers;

var request = require('request');
var cheerio = require('cheerio');
var Long = require('long');
var url = require('url');
var vm = require('vm');
var querystring = require('querystring');

var communityURL = 'https://steamcommunity.com';
var defaultTimeout = 30000;

function SteamTradeOffers() {}

SteamTradeOffers.prototype.setup = function(options) {
  var timeout = options.timeout || defaultTimeout;

  this._j = request.jar();
  this._requestCommunity = request.defaults({
    jar: this._j,
    timeout: timeout
  });

  this._requestAPI = request.defaults({
    timeout: timeout
  });

  this.APIKey = options.APIKey;

  this.sessionID = options.sessionID;

  options.webCookie.forEach(function(name) {
    setCookie.bind(this)(name);
  }.bind(this));
};

SteamTradeOffers.prototype.getOfferToken = function(callback) {
  this.getOfferUrl(function(error, offerUrl) {
    if (error) {
      return callback(error);
    }

    var offerToken = url.parse(offerUrl, true).query.token;
    callback(null, offerToken);
  });
};

SteamTradeOffers.prototype.getOfferUrl = function(callback) {
  this._requestCommunity.get({
    uri: communityURL + '/my/tradeoffers/privacy'
  }, function(error, response, body) {
    if (error || response.statusCode !== 200) {
      return callback(error || new Error(response.statusCode));
    }
    if (!body) {
      return callback(new Error('Invalid Response'));
    }

    var $ = cheerio.load(body);
    var offerUrl = $('input#trade_offer_access_url').val();

    callback(null, offerUrl);
  }.bind(this));
};

SteamTradeOffers.prototype.getTradeHoldDuration = function(options, callback) {
  var url = communityURL + '/tradeoffer/' + options.tradeOfferId + '/';

  getHoldDuration.bind(this)(url, callback);
};

SteamTradeOffers.prototype.getHoldDuration = function(options, callback) {
  var query = {
    partner: options.partnerAccountId || toAccountId(options.partnerSteamId)
  };

  if (options.accessToken) {
    query.token = options.accessToken;
  }

  var url = communityURL + '/tradeoffer/new/?' + querystring.stringify(query);

  getHoldDuration.bind(this)(url, callback);
};

SteamTradeOffers.prototype.loadMyInventory = function(options, callback) {
  var query = {};

  if (options.language) {
    query.l = options.language;
  }

  if (options.tradableOnly !== false) {
    query.trading = 1;
  }

  var uri = communityURL + '/my/inventory/json/' + options.appId +
    '/' + options.contextId + '/?' + querystring.stringify(query);

  loadInventory.bind(this)({
    uri: uri,
    contextId: options.contextId
  }, callback);
};

SteamTradeOffers.prototype.loadPartnerInventory = function(options, callback) {
  var form = {
    sessionid: this.sessionID,
    partner: options.partnerSteamId || toSteamId(options.partnerAccountId),
    appid: options.appId,
    contextid: options.contextId
  };

  if (options.language) {
    form.l = options.language;
  }

  var offer = 'new';
  if (options.tradeOfferId) {
    offer = options.tradeOfferId;
  }

  var uri = communityURL + '/tradeoffer/' + offer +
    '/partnerinventory/?' + querystring.stringify(form);

  loadInventory.bind(this)({
    uri: uri,
    headers: {
      referer: communityURL + '/tradeoffer/' + offer +
        '/?partner=' + toAccountId(form.partner)
    },
    contextId: options.contextId
  }, callback);
};

SteamTradeOffers.prototype.getOffers = function(options, callback) {
  doAPICall.bind(this)({
    method: 'GetTradeOffers/v1',
    params: options,
    callback: function(error, res) {
      if (error) {
        return callback(error);
      }

      if (res.response.trade_offers_received !== undefined) {
        res.response.trade_offers_received = res.response.trade_offers_received.map(function(offer) {
          offer.steamid_other = toSteamId(offer.accountid_other);
          return offer;
        });
      }

      if (res.response.trade_offers_sent !== undefined) {
        res.response.trade_offers_sent = res.response.trade_offers_sent.map(function(offer) {
          offer.steamid_other = toSteamId(offer.accountid_other);
          return offer;
        });
      }

      callback(null, res);
    }
  });
};

SteamTradeOffers.prototype.getOffer = function(options, callback) {
  doAPICall.bind(this)({
    method: 'GetTradeOffer/v1',
    params: options,
    callback: function(error, res) {
      if (error) {
        return callback(error);
      }

      if (res.response.offer !== undefined) {
        res.response.offer.steamid_other = toSteamId(res.response.offer.accountid_other);
      }

      callback(null, res);
    }
  });
};

SteamTradeOffers.prototype.getSummary = function(options, callback) {
  doAPICall.bind(this)({
    method: 'GetTradeOffersSummary/v1',
    params: options,
    callback: callback
  });
};

SteamTradeOffers.prototype.declineOffer = function(options, callback) {
  doAPICall.bind(this)({
    method: 'DeclineTradeOffer/v1',
    params: {
      tradeofferid: options.tradeOfferId
    },
    post: true,
    callback: callback
  });
};

SteamTradeOffers.prototype.cancelOffer = function(options, callback) {
  doAPICall.bind(this)({
    method: 'CancelTradeOffer/v1',
    params: {
      tradeofferid: options.tradeOfferId
    },
    post: true,
    callback: callback
  });
};

SteamTradeOffers.prototype.acceptOffer = function(options, callback) {
  this._requestCommunity.post({
    uri: communityURL + '/tradeoffer/' + options.tradeOfferId + '/accept',
    headers: {
      referer: communityURL + '/tradeoffer/' + options.tradeOfferId + '/'
    },
    json: true,
    form: {
      sessionid: this.sessionID,
      serverid: 1,
      tradeofferid: options.tradeOfferId
    }
  }, function(error, response, body) {
    if (error) {
      if (typeof callback === 'function') {
        callback(error);
      }
      return;
    }
    if (body && body.strError) {
      if (typeof callback === 'function') {
        callback(new Error(body.strError));
      }
      return;
    }
    if (response.statusCode !== 200) {
      if (typeof callback === 'function') {
        callback(new Error(response.statusCode));
      }
      return;
    }

    if (typeof callback === 'function') {
      callback(null, body);
    }
  }.bind(this));
};

SteamTradeOffers.prototype.makeOffer = function(options, callback) {
  var tradeoffer = {
    newversion: true,
    version: 2,
    me: { assets: options.itemsFromMe, currency: [], ready: false },
    them: { assets: options.itemsFromThem, currency: [], ready: false }
  };

  var formFields = {
    serverid: 1,
    sessionid: this.sessionID,
    partner: options.partnerSteamId || toSteamId(options.partnerAccountId),
    tradeoffermessage: options.message || '',
    json_tradeoffer: JSON.stringify(tradeoffer)
  };

  var query = {
    partner: options.partnerAccountId || toAccountId(options.partnerSteamId)
  };

  if (options.accessToken !== undefined) {
    formFields.trade_offer_create_params = JSON.stringify({
      trade_offer_access_token: options.accessToken
    });
    query.token = options.accessToken;
  }

  var referer;
  if (options.counteredTradeOffer !== undefined) {
    formFields.tradeofferid_countered = options.counteredTradeOffer;
    referer = communityURL + '/tradeoffer/' + options.counteredTradeOffer + '/';
  } else {
    referer = communityURL + '/tradeoffer/new/?' + querystring.stringify(query);
  }

  this._requestCommunity.post({
    uri: communityURL + '/tradeoffer/new/send',
    headers: {
      referer: referer
    },
    json: true,
    form: formFields
  }, function(error, response, body) {
    if (error) {
      if (typeof callback === 'function') {
        callback(error);
      }
      return;
    }
    if (body && body.strError) {
      if (typeof callback === 'function') {
        callback(new Error(body.strError));
      }
      return;
    }
    if (response.statusCode !== 200) {
      if (typeof callback === 'function') {
        callback(new Error(response.statusCode));
      }
      return;
    }

    if (typeof callback === 'function') {
      callback(null, body);
    }
  }.bind(this));
};

SteamTradeOffers.prototype.getItems = function(options, callback) {
  // Derived from node-steam-trade
  // https://github.com/seishun/node-steam-trade/blob/master/index.js#L86-L119
  this._requestCommunity.get({
    uri: communityURL + '/trade/' + options.tradeId + '/receipt/'
  }, function(err, response, body) {
    if (err || response.statusCode !== 200) {
      return callback(err || new Error(response.statusCode));
    }

    var script = body.match(/(var oItem;[\s\S]*)<\/script>/);
    if (!script) {
      return callback(new Error('No session'));
    }

    var sandbox = {
      items: []
    };

    // prepare to execute the script in new context
    var code = 'var UserYou;' +
      'function BuildHover(str, item) {' +
        'items.push(item);' +
      '}' +
      'function $() {' +
        'return {' +
          'show: function() {}' +
        '};' +
      '}' +
      script[1];

    vm.runInNewContext(code, sandbox);

    callback(null, sandbox.items);
  });
};

function setCookie(cookie) {
  this._j.setCookie(request.cookie(cookie), communityURL);
}

function toSteamId(accountId) {
  return new Long(parseInt(accountId, 10), 0x1100001).toString();
}

function toAccountId(steamId) {
  return Long.fromString(steamId).toInt().toString();
}

function mergeRawInventory (raw, rawBody) {
  var body = JSON.parse(JSON.stringify(rawBody));
  var rgInventory = raw.rgInventory || {};
  var rgCurrency = raw.rgCurrency || {};
  var rgDescriptions = raw.rgDescriptions || {};

  return {
    rgInventory: mergeObjects(rgInventory, body.rgInventory),
    rgCurrency: mergeObjects(rgCurrency, body.rgCurrency),
    rgDescriptions: mergeObjects(rgDescriptions, body.rgDescriptions)
  };
}

function mergeInventory(inventory, body, contextId) {
  return inventory.concat(
    mergeWithDescriptions(body.rgInventory, body.rgDescriptions, contextId)
      .concat(
        mergeWithDescriptions(body.rgCurrency, body.rgDescriptions, contextId)
      )
  );
}

function mergeWithDescriptions(items, descriptions, contextid) {
  return Object.keys(items).map(function(id) {
    var item = items[id];
    var description = descriptions[item.classid + '_' + (item.instanceid || '0')];
    for (var key in description) {
      if (description.hasOwnProperty(key)) {
        item[key] = description[key];
      }
    }
    // add contextid because Steam is retarded
    item.contextid = contextid;
    return item;
  });
}

function mergeObjects() {
  var result = {};
  for (var i = 0; i < arguments.length; i++) {
    for (var index in arguments[i]) {
      if (arguments[i].hasOwnProperty(index)) {
        result[index] = arguments[i][index];
      }
    }
  }
  return result;
}

function loadInventory(options, callback) {
  options.inventory = options.inventory || [];
  options.raw = options.raw || {};

  var requestParams = {
    uri: options.uri,
    json: true
  };

  if (options.start) {
    requestParams.uri += '&start=' + options.start;
  }

  if (options.headers) {
    requestParams.headers = options.headers;
  }

  this._requestCommunity.get(requestParams, function(error, response, body) {
    if (error) {
      return callback(error);
    }
    if (body && body.error) {
      return callback(new Error(body.error));
    }
    if (response.statusCode !== 200) {
      return callback(new Error(response.statusCode));
    }
    if (!body || !body.rgInventory || !body.rgDescriptions || !body.rgCurrency) {
      return callback(new Error('Invalid Response'));
    }

    options.raw = mergeRawInventory(options.raw, body);
    options.inventory = mergeInventory(options.inventory, body, options.contextId);

    if (body.more) {
      options.start = body.more_start;
      loadInventory.bind(this)(options, callback);
    } else {
      callback(null, options.inventory, options.raw);
    }
  }.bind(this));
}

function doAPICall(options) {
  var httpMethod = options.post ? 'post' : 'get';

  var params = {
    uri: 'https://api.steampowered.com/IEconService/' + options.method +
      '/?key=' + this.APIKey +
      ((options.post) ? '' : '&' + querystring.stringify(options.params)),
    json: true
  };

  if (options.post) {
    params.form = options.params;
  }

  this._requestAPI[httpMethod](params, function(error, response, body) {
    if (error || response.statusCode !== 200) {
      if (typeof options.callback === 'function') {
        options.callback(error || new Error(response.statusCode));
      }
      return;
    }
    if (!body || typeof body !== 'object') {
      if (typeof options.callback === 'function') {
        options.callback(new Error('Invalid Response'));
      }
      return;
    }
    if (typeof options.callback === 'function') {
      options.callback(null, body);
    }
  }.bind(this));
}

function getHoldDuration (url, callback) {
  this._requestCommunity.get({
    uri: url
  }, function(error, response, body) {
    if (error || response.statusCode !== 200) {
      return callback(error || new Error(response.statusCode));
    }
    if (!body) {
      return callback(new Error('Invalid Response'));
    }

    var $ = cheerio.load(body);
    var scriptToExec = '';
    var status = $('script').get().some(function (script) {
      if (!script.children[0]) {
        return false;
      }
      var text = script.children[0].data;
      if (/var g_daysMyEscrow/.test(text)) {
        scriptToExec = text;
        return true;
      }
      return false;
    });

    if (!status) {
      var errorMsg;

      if ($('#error_msg').length > 0) {
        errorMsg = $('#error_msg').text().trim();
      }

      var message = errorMsg || 'Can\'t get hold duration';

      return callback(new Error(message));
    }

    var sandbox = {
      data: {}
    };

    // prepare to execute the script in new context
    var code = scriptToExec +
      'data.my = g_daysMyEscrow;' +
      'data.their = g_daysTheirEscrow;';

    vm.runInNewContext(code, sandbox);

    callback(null, sandbox.data);
  }.bind(this));
}
<commit_msg>Check that `offerUrl` exists<commit_after>module.exports = SteamTradeOffers;

var request = require('request');
var cheerio = require('cheerio');
var Long = require('long');
var url = require('url');
var vm = require('vm');
var querystring = require('querystring');

var communityURL = 'https://steamcommunity.com';
var defaultTimeout = 30000;

function SteamTradeOffers() {}

SteamTradeOffers.prototype.setup = function(options) {
  var timeout = options.timeout || defaultTimeout;

  this._j = request.jar();
  this._requestCommunity = request.defaults({
    jar: this._j,
    timeout: timeout
  });

  this._requestAPI = request.defaults({
    timeout: timeout
  });

  this.APIKey = options.APIKey;

  this.sessionID = options.sessionID;

  options.webCookie.forEach(function(name) {
    setCookie.bind(this)(name);
  }.bind(this));
};

SteamTradeOffers.prototype.getOfferToken = function(callback) {
  this.getOfferUrl(function(error, offerUrl) {
    if (error) {
      return callback(error);
    }

    var offerToken = url.parse(offerUrl, true).query.token;
    callback(null, offerToken);
  });
};

SteamTradeOffers.prototype.getOfferUrl = function(callback) {
  this._requestCommunity.get({
    uri: communityURL + '/my/tradeoffers/privacy'
  }, function(error, response, body) {
    if (error || response.statusCode !== 200) {
      return callback(error || new Error(response.statusCode));
    }
    if (!body) {
      return callback(new Error('Invalid Response'));
    }

    var $ = cheerio.load(body);
    var offerUrl = $('input#trade_offer_access_url').val();

    if (!offerUrl) {
      return callback(new Error('Invalid Response'));
    }

    callback(null, offerUrl);
  }.bind(this));
};

SteamTradeOffers.prototype.getTradeHoldDuration = function(options, callback) {
  var url = communityURL + '/tradeoffer/' + options.tradeOfferId + '/';

  getHoldDuration.bind(this)(url, callback);
};

SteamTradeOffers.prototype.getHoldDuration = function(options, callback) {
  var query = {
    partner: options.partnerAccountId || toAccountId(options.partnerSteamId)
  };

  if (options.accessToken) {
    query.token = options.accessToken;
  }

  var url = communityURL + '/tradeoffer/new/?' + querystring.stringify(query);

  getHoldDuration.bind(this)(url, callback);
};

SteamTradeOffers.prototype.loadMyInventory = function(options, callback) {
  var query = {};

  if (options.language) {
    query.l = options.language;
  }

  if (options.tradableOnly !== false) {
    query.trading = 1;
  }

  var uri = communityURL + '/my/inventory/json/' + options.appId +
    '/' + options.contextId + '/?' + querystring.stringify(query);

  loadInventory.bind(this)({
    uri: uri,
    contextId: options.contextId
  }, callback);
};

SteamTradeOffers.prototype.loadPartnerInventory = function(options, callback) {
  var form = {
    sessionid: this.sessionID,
    partner: options.partnerSteamId || toSteamId(options.partnerAccountId),
    appid: options.appId,
    contextid: options.contextId
  };

  if (options.language) {
    form.l = options.language;
  }

  var offer = 'new';
  if (options.tradeOfferId) {
    offer = options.tradeOfferId;
  }

  var uri = communityURL + '/tradeoffer/' + offer +
    '/partnerinventory/?' + querystring.stringify(form);

  loadInventory.bind(this)({
    uri: uri,
    headers: {
      referer: communityURL + '/tradeoffer/' + offer +
        '/?partner=' + toAccountId(form.partner)
    },
    contextId: options.contextId
  }, callback);
};

SteamTradeOffers.prototype.getOffers = function(options, callback) {
  doAPICall.bind(this)({
    method: 'GetTradeOffers/v1',
    params: options,
    callback: function(error, res) {
      if (error) {
        return callback(error);
      }

      if (res.response.trade_offers_received !== undefined) {
        res.response.trade_offers_received = res.response.trade_offers_received.map(function(offer) {
          offer.steamid_other = toSteamId(offer.accountid_other);
          return offer;
        });
      }

      if (res.response.trade_offers_sent !== undefined) {
        res.response.trade_offers_sent = res.response.trade_offers_sent.map(function(offer) {
          offer.steamid_other = toSteamId(offer.accountid_other);
          return offer;
        });
      }

      callback(null, res);
    }
  });
};

SteamTradeOffers.prototype.getOffer = function(options, callback) {
  doAPICall.bind(this)({
    method: 'GetTradeOffer/v1',
    params: options,
    callback: function(error, res) {
      if (error) {
        return callback(error);
      }

      if (res.response.offer !== undefined) {
        res.response.offer.steamid_other = toSteamId(res.response.offer.accountid_other);
      }

      callback(null, res);
    }
  });
};

SteamTradeOffers.prototype.getSummary = function(options, callback) {
  doAPICall.bind(this)({
    method: 'GetTradeOffersSummary/v1',
    params: options,
    callback: callback
  });
};

SteamTradeOffers.prototype.declineOffer = function(options, callback) {
  doAPICall.bind(this)({
    method: 'DeclineTradeOffer/v1',
    params: {
      tradeofferid: options.tradeOfferId
    },
    post: true,
    callback: callback
  });
};

SteamTradeOffers.prototype.cancelOffer = function(options, callback) {
  doAPICall.bind(this)({
    method: 'CancelTradeOffer/v1',
    params: {
      tradeofferid: options.tradeOfferId
    },
    post: true,
    callback: callback
  });
};

SteamTradeOffers.prototype.acceptOffer = function(options, callback) {
  this._requestCommunity.post({
    uri: communityURL + '/tradeoffer/' + options.tradeOfferId + '/accept',
    headers: {
      referer: communityURL + '/tradeoffer/' + options.tradeOfferId + '/'
    },
    json: true,
    form: {
      sessionid: this.sessionID,
      serverid: 1,
      tradeofferid: options.tradeOfferId
    }
  }, function(error, response, body) {
    if (error) {
      if (typeof callback === 'function') {
        callback(error);
      }
      return;
    }
    if (body && body.strError) {
      if (typeof callback === 'function') {
        callback(new Error(body.strError));
      }
      return;
    }
    if (response.statusCode !== 200) {
      if (typeof callback === 'function') {
        callback(new Error(response.statusCode));
      }
      return;
    }

    if (typeof callback === 'function') {
      callback(null, body);
    }
  }.bind(this));
};

SteamTradeOffers.prototype.makeOffer = function(options, callback) {
  var tradeoffer = {
    newversion: true,
    version: 2,
    me: { assets: options.itemsFromMe, currency: [], ready: false },
    them: { assets: options.itemsFromThem, currency: [], ready: false }
  };

  var formFields = {
    serverid: 1,
    sessionid: this.sessionID,
    partner: options.partnerSteamId || toSteamId(options.partnerAccountId),
    tradeoffermessage: options.message || '',
    json_tradeoffer: JSON.stringify(tradeoffer)
  };

  var query = {
    partner: options.partnerAccountId || toAccountId(options.partnerSteamId)
  };

  if (options.accessToken !== undefined) {
    formFields.trade_offer_create_params = JSON.stringify({
      trade_offer_access_token: options.accessToken
    });
    query.token = options.accessToken;
  }

  var referer;
  if (options.counteredTradeOffer !== undefined) {
    formFields.tradeofferid_countered = options.counteredTradeOffer;
    referer = communityURL + '/tradeoffer/' + options.counteredTradeOffer + '/';
  } else {
    referer = communityURL + '/tradeoffer/new/?' + querystring.stringify(query);
  }

  this._requestCommunity.post({
    uri: communityURL + '/tradeoffer/new/send',
    headers: {
      referer: referer
    },
    json: true,
    form: formFields
  }, function(error, response, body) {
    if (error) {
      if (typeof callback === 'function') {
        callback(error);
      }
      return;
    }
    if (body && body.strError) {
      if (typeof callback === 'function') {
        callback(new Error(body.strError));
      }
      return;
    }
    if (response.statusCode !== 200) {
      if (typeof callback === 'function') {
        callback(new Error(response.statusCode));
      }
      return;
    }

    if (typeof callback === 'function') {
      callback(null, body);
    }
  }.bind(this));
};

SteamTradeOffers.prototype.getItems = function(options, callback) {
  // Derived from node-steam-trade
  // https://github.com/seishun/node-steam-trade/blob/master/index.js#L86-L119
  this._requestCommunity.get({
    uri: communityURL + '/trade/' + options.tradeId + '/receipt/'
  }, function(err, response, body) {
    if (err || response.statusCode !== 200) {
      return callback(err || new Error(response.statusCode));
    }

    var script = body.match(/(var oItem;[\s\S]*)<\/script>/);
    if (!script) {
      return callback(new Error('No session'));
    }

    var sandbox = {
      items: []
    };

    // prepare to execute the script in new context
    var code = 'var UserYou;' +
      'function BuildHover(str, item) {' +
        'items.push(item);' +
      '}' +
      'function $() {' +
        'return {' +
          'show: function() {}' +
        '};' +
      '}' +
      script[1];

    vm.runInNewContext(code, sandbox);

    callback(null, sandbox.items);
  });
};

function setCookie(cookie) {
  this._j.setCookie(request.cookie(cookie), communityURL);
}

function toSteamId(accountId) {
  return new Long(parseInt(accountId, 10), 0x1100001).toString();
}

function toAccountId(steamId) {
  return Long.fromString(steamId).toInt().toString();
}

function mergeRawInventory (raw, rawBody) {
  var body = JSON.parse(JSON.stringify(rawBody));
  var rgInventory = raw.rgInventory || {};
  var rgCurrency = raw.rgCurrency || {};
  var rgDescriptions = raw.rgDescriptions || {};

  return {
    rgInventory: mergeObjects(rgInventory, body.rgInventory),
    rgCurrency: mergeObjects(rgCurrency, body.rgCurrency),
    rgDescriptions: mergeObjects(rgDescriptions, body.rgDescriptions)
  };
}

function mergeInventory(inventory, body, contextId) {
  return inventory.concat(
    mergeWithDescriptions(body.rgInventory, body.rgDescriptions, contextId)
      .concat(
        mergeWithDescriptions(body.rgCurrency, body.rgDescriptions, contextId)
      )
  );
}

function mergeWithDescriptions(items, descriptions, contextid) {
  return Object.keys(items).map(function(id) {
    var item = items[id];
    var description = descriptions[item.classid + '_' + (item.instanceid || '0')];
    for (var key in description) {
      if (description.hasOwnProperty(key)) {
        item[key] = description[key];
      }
    }
    // add contextid because Steam is retarded
    item.contextid = contextid;
    return item;
  });
}

function mergeObjects() {
  var result = {};
  for (var i = 0; i < arguments.length; i++) {
    for (var index in arguments[i]) {
      if (arguments[i].hasOwnProperty(index)) {
        result[index] = arguments[i][index];
      }
    }
  }
  return result;
}

function loadInventory(options, callback) {
  options.inventory = options.inventory || [];
  options.raw = options.raw || {};

  var requestParams = {
    uri: options.uri,
    json: true
  };

  if (options.start) {
    requestParams.uri += '&start=' + options.start;
  }

  if (options.headers) {
    requestParams.headers = options.headers;
  }

  this._requestCommunity.get(requestParams, function(error, response, body) {
    if (error) {
      return callback(error);
    }
    if (body && body.error) {
      return callback(new Error(body.error));
    }
    if (response.statusCode !== 200) {
      return callback(new Error(response.statusCode));
    }
    if (!body || !body.rgInventory || !body.rgDescriptions || !body.rgCurrency) {
      return callback(new Error('Invalid Response'));
    }

    options.raw = mergeRawInventory(options.raw, body);
    options.inventory = mergeInventory(options.inventory, body, options.contextId);

    if (body.more) {
      options.start = body.more_start;
      loadInventory.bind(this)(options, callback);
    } else {
      callback(null, options.inventory, options.raw);
    }
  }.bind(this));
}

function doAPICall(options) {
  var httpMethod = options.post ? 'post' : 'get';

  var params = {
    uri: 'https://api.steampowered.com/IEconService/' + options.method +
      '/?key=' + this.APIKey +
      ((options.post) ? '' : '&' + querystring.stringify(options.params)),
    json: true
  };

  if (options.post) {
    params.form = options.params;
  }

  this._requestAPI[httpMethod](params, function(error, response, body) {
    if (error || response.statusCode !== 200) {
      if (typeof options.callback === 'function') {
        options.callback(error || new Error(response.statusCode));
      }
      return;
    }
    if (!body || typeof body !== 'object') {
      if (typeof options.callback === 'function') {
        options.callback(new Error('Invalid Response'));
      }
      return;
    }
    if (typeof options.callback === 'function') {
      options.callback(null, body);
    }
  }.bind(this));
}

function getHoldDuration (url, callback) {
  this._requestCommunity.get({
    uri: url
  }, function(error, response, body) {
    if (error || response.statusCode !== 200) {
      return callback(error || new Error(response.statusCode));
    }
    if (!body) {
      return callback(new Error('Invalid Response'));
    }

    var $ = cheerio.load(body);
    var scriptToExec = '';
    var status = $('script').get().some(function (script) {
      if (!script.children[0]) {
        return false;
      }
      var text = script.children[0].data;
      if (/var g_daysMyEscrow/.test(text)) {
        scriptToExec = text;
        return true;
      }
      return false;
    });

    if (!status) {
      var errorMsg;

      if ($('#error_msg').length > 0) {
        errorMsg = $('#error_msg').text().trim();
      }

      var message = errorMsg || 'Can\'t get hold duration';

      return callback(new Error(message));
    }

    var sandbox = {
      data: {}
    };

    // prepare to execute the script in new context
    var code = scriptToExec +
      'data.my = g_daysMyEscrow;' +
      'data.their = g_daysTheirEscrow;';

    vm.runInNewContext(code, sandbox);

    callback(null, sandbox.data);
  }.bind(this));
}
<|endoftext|>


<commit_before>'use strict';

var transformTools = require('browserify-transform-tools');
var fs = require('fs');
var pp = require('preprocess');

module.exports = transformTools.makeStringTransform('preprocessify', {},
    function (content, transformOptions, done) {
        var config = transformOptions.config;

        var context;

        if (config.context) {
            context = config.context;
        } else if (config.contextFile) {
            context = JSON.parse(fs.readFileSync(config.contextFile, 'utf8'));
        } else {
            done(new Error('A context object or file must be specified (e.g. "browserify -t [preprocessify --contextFile ./path/to/file.json] app.js" or "b.transform(preprocessify, {context: {FOO:BAR}})"'));
        }

        done(null, pp.preprocess(content, context, {type: 'js'}));
    });

<commit_msg>Allowed for no context file to be specified<commit_after>'use strict';

var transformTools = require('browserify-transform-tools');
var fs = require('fs');
var pp = require('preprocess');

module.exports = transformTools.makeStringTransform('preprocessify', {},
    function (content, transformOptions, done) {
        var config = transformOptions.config;

        var context;

        if (config.context) {
            context = config.context;
        } else if (config.contextFile) {
            context = JSON.parse(fs.readFileSync(config.contextFile, 'utf8'));
        } else {
            context = {};
        }

        done(null, pp.preprocess(content, context, {type: 'js'}));
    });
<|endoftext|>


<commit_before>// Used to toggle the menu on small screens when clicking on the menu button
function toggleNavMenu() {
    var x = document.getElementById("navDemo");
    if (x.className.indexOf("w3-show") == -1) {
        x.className += " w3-show";
    } else {
        x.className = x.className.replace(" w3-show", "");
    }
}

// Create all Google maps and add associated markers
function initMaps()
{
	// Define coordinates
	centerMont = new google.maps.LatLng(48.636017,-1.511114);
	centerJapan = new google.maps.LatLng(37.902552,139.023095);
	centerRoquebillière = new google.maps.LatLng(44.012749,7.307727);

	// Define map options
	var optionsMont = {
		center: centerMont,
		zoom:12, scrollwheel: false, draggable: false,
		mapTypeId:google.maps.MapTypeId.ROADMAP
	};
	var optionsJapan = {
		center: centerJapan,
		zoom:12, scrollwheel: false, draggable: false,
		mapTypeId:google.maps.MapTypeId.ROADMAP
	};
	var optionsRoquebillière = {
		center: centerRoquebillière,
		zoom:12, scrollwheel: false, draggable: false,
		mapTypeId:google.maps.MapTypeId.ROADMAP
	};

	// Create maps
	var mapMont = new google.maps.Map(document.getElementById("mapMont"), optionsMont);
	var mapJapan = new google.maps.Map(document.getElementById("mapJapan"), optionsJapan);
	var mapRoquebillière = new google.maps.Map(document.getElementById("mapRoquebillière"), optionsRoquebillière);

	// Add markers
	var markerMont = new google.maps.Marker({
		position: centerMont,
	});
	markerMont.setMap(mapMont);

	var markerJapan = new google.maps.Marker({
		position: centerJapan,
	});
	markerJapan.setMap(mapJapan);

	var markerRoquebillière = new google.maps.Marker({
		position: centerRoquebillière,
	});
	markerRoquebillière.setMap(mapRoquebillière);
}<commit_msg>Add js examples<commit_after>// Used to toggle the menu on small screens when clicking on the menu button
function toggleNavMenu() {
    var x = document.getElementById("navDemo");
    if (x.className.indexOf("w3-show") == -1) {
        x.className += " w3-show";
    } else {
        x.className = x.className.replace(" w3-show", "");
    }
}

// Create all Google maps and add associated markers
function initMaps() {
	// Define coordinates
	centerMont = new google.maps.LatLng(48.636017,-1.511114);
	centerJapan = new google.maps.LatLng(37.902552,139.023095);
	centerRoquebillière = new google.maps.LatLng(44.012749,7.307727);

	// Define map options
	var optionsMont = {
		center: centerMont,
		zoom:12, scrollwheel: false, draggable: false,
		mapTypeId:google.maps.MapTypeId.ROADMAP
	};
	var optionsJapan = {
		center: centerJapan,
		zoom:12, scrollwheel: false, draggable: false,
		mapTypeId:google.maps.MapTypeId.ROADMAP
	};
	var optionsRoquebillière = {
		center: centerRoquebillière,
		zoom:12, scrollwheel: false, draggable: false,
		mapTypeId:google.maps.MapTypeId.ROADMAP
	};

	// Create maps
	var mapMont = new google.maps.Map(document.getElementById("mapMont"), optionsMont);
	var mapJapan = new google.maps.Map(document.getElementById("mapJapan"), optionsJapan);
	var mapRoquebillière = new google.maps.Map(document.getElementById("mapRoquebillière"), optionsRoquebillière);

	// Add markers
	var markerMont = new google.maps.Marker({
		position: centerMont,
	});
	markerMont.setMap(mapMont);

	var markerJapan = new google.maps.Marker({
		position: centerJapan,
	});
	markerJapan.setMap(mapJapan);

	var markerRoquebillière = new google.maps.Marker({
		position: centerRoquebillière,
	});
	markerRoquebillière.setMap(mapRoquebillière);
}

// --------------- Exemples de fonctions

// Object (qui est défini par une classe, implicite ici)
let erin = {
	// Attribut (Champ)
	nom: "Erin",
	age: 16,

	// Methode (fonction de classe)
	sayHello: function() {
		console.log("Hello! Je m'appelle " + this.nom + " et j'ai " + this.age + " ans.")
	}
}

// On appelle la méthode sayHello
erin.sayHello();

// Une fonction (une moulinette qui fait des trucs)
function add2or3(nombre) {
	var result = 0;
	// Une condition: Si nombre est divisible par 2 (pair)
	if(nombre % 2 == 0) {
		result = nombre + 2;
	// Sinon si c'est impair
	} else {
		result = nombre + 3;
	}
	return result;
}

// Une boucle for
for(var i = 0; i <= 10; i++) {
	console.log(i);
}

// Une variable (qui n'est pas un objet)
var i = 10;

// Une boucle while
while(i > 0) {
	console.log(i);
	i-=2;
}

// Des tests...
var test = add2or3(7);
console.log("test = ", test);
var test2 = add2or3(test);
console.log("test2 = ", test2);
<|endoftext|>


<commit_before>// Routing
var request = require('request');
var express = require('express');
var path = require('path');
var app = express()
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
app.listen(process.env.PORT || 3000, function() {});

// Firebase
var firebase = require('firebase');
firebase.initializeApp({
  apiKey: process.env.FIREBASE_API_KEY,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID
});

// Botkit
var Botkit = require('botkit');
var controller = Botkit.slackbot();
controller.configureSlackApp({
  clientId: process.env.SLACK_CLIENT_ID,
  clientSecret: process.env.SLACK_CLIENT_SECRET,
  redirectUri: 'http://localhost:3000/slack/callback',
  scopes: ['commands']
});

// Genius
var Genius = require('node-genius')
var genius = new Genius(process.env.GENIUS_ACCESS_TOKEN)

// Mixpanel
var Mixpanel = require('mixpanel');
var mixpanel = Mixpanel.init(process.env.MIXPANEL_KEY);

// Routes
app.get('/', function(req, res) {
  res.sendFile(__dirname + '/public/index.html')
})

app.get('/?ref=*', function(req, res) {
  res.sendFile(__dirname + '/public/index.html')
})

app.get('/success', function (req, res) {
    res.sendFile(__dirname + '/public/success.html')
});

app.get('/fail', function (req, res) {
    res.sendFile(__dirname + '/public/fail.html')
});

app.get('/privacy', function (req, res) {
    res.sendFile(__dirname + '/public/privacy.html')
});

// Slack Authentication
app.get('/slack/callback', function(req, res) {
  var url = 'https://slack.com/api/oauth.access?';
  url += 'client_id=' + process.env.SLACK_CLIENT_ID;
  url += '&client_secret=' + process.env.SLACK_CLIENT_SECRET;
  url += '&code=' + req.query.code;

  request(url, function (error, response, body) {
    if (error || response.statusCode != 200) {
      console.log('Request Error: ' + error)
      res.sendFile(__dirname + '/public/failure.html')
    } else {
      var data = JSON.parse(body)
      if (!data.ok) {
        console.log('Slack OAuth Error: ' + data.error)
        res.sendFile(__dirname + '/public/failure.html')
      } else {
        var team = {}
        team[data.team_id] = {
          access_token: data.access_token,
          scope: data.scope,
          user_id: data.user_id,
          team_id: data.team_id,
          team_name: data.team_name
        }

        firebase.database().ref('/slack/').update(team, function(error) {
          if (error) {
            console.log('Firebase Error: ' + error)
            res.sendFile(__dirname + '/public/failure.html')
          } else {
            console.log(team[data.team_id].team_name + ' was added to Firebase')
            res.sendFile(__dirname + '/public/success.html')
          }
        });
      }
    }
  });
});

// Slack Firesong
app.post('/slack/firesong', function(req, res) {
  console.log('/slack/firesong find: ' + req.body.text)
  genius.search(req.body.text, function (error, results) {
    var dataJSON = JSON.parse(results);
    var hits = dataJSON.response.hits;
    console.log('Genius found ' + hits.length + ' hits')

    if (hits.length < 1) {
      console.log('No hits: ' + dataJSON)
      sendDefaultMessage(res);
    } else {
      // Get Random Genius Hit
      getRandomGeniusHit(res, hits, 0)
    }
  });
});

function getRandomGeniusHit(res, hits, attempt) {
  var i = (hits.length < 4 ? hits.length : 3);
  var random = Math.floor(Math.random() * i);

  // Get Genius song from random song id
  var geniusId = hits[random].result.id
  console.log('Got Genius song id: ' + geniusId)
  genius.getSong(geniusId, function (error, song) {
    if (error) {
      console.log('Get random Genius song error: ', error);
      tryToGetAnotherRandomHit(res, hits, attempt)
    } else {
      var songJSON = JSON.parse(song);

      // Find the Spotify Media
      if (!songJSON.response.song.media) {
        console.log('No media')
        tryToGetAnotherRandomHit(res, hits, attempt)
      } else {
        var media = songJSON.response.song.media
        var spotifyMedia = media.map(function(source) { if (source.provider == 'spotify') { return source } })
        if (spotifyMedia) {
          var spotifyURL = spotifyMedia.url
          if (spotifyURL.includes('local')) {
            console.log('Local Spotify song id')
            tryToGetAnotherRandomHit(res, hits, attempt)
          } else {
            // Send message to Slack
            res.send({
              'response_type': 'in_channel',
              'text': spotifyURL
            });

            // Record in Mixpanel
            recordMixpanelEvent(req, spotifyURL.substr(37));
          }
        } else {
          if (media.length == 0) {
            console.log('No media')
            tryToGetAnotherRandomHit(res, hits, attempt)
          } else {
            var mediaURL = spotifyMedia.url
            // Send message to Slack
            res.send({
              'response_type': 'in_channel',
              'text': mediaURL
            });

            // Record in Mixpanel
            recordMixpanelEvent(req, mediaURL);
          }
        }
      }
    }
  });
}

// Mixpanel Event
function recordMixpanelEvent(req, spotify_id) {
  mixpanel.track('/firesong', {
    distinct_id: req.body.response_url.substr(33),
    user_id: req.body.user_id,
    user_name: req.body.user_name,
    channel_id: req.body.channel_id,
    team_id: req.body.team_id,
    team_domain: req.body.team_domain,
    text: req.body.text,
    song: spotify_id
  });
}

// Try to get another random Genius Hit
function tryToGetAnotherRandomHit(res, hits, attempt) {
  if (attempt > 2) {
    sendDefaultMessage(res);
  } else {
    console.log('Grab another random hit, attempts: ' + (attempt + 1))
    getRandomGeniusHit(res, hits, attempt + 1);
  }
}

// Send default song in case anything goes wrong
function sendDefaultMessage(res) {
  console.log('Sending default message')
  res.send({
    'response_type': 'in_channel',
    'text': "Something went wrong 🤔 we're on it. In the meantime: " + 'https://open.spotify.com/track/2uljPrNySotVP1d42B30X2'
  });
}
<commit_msg>add array handle<commit_after>// Routing
var request = require('request');
var express = require('express');
var path = require('path');
var app = express()
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
app.listen(process.env.PORT || 3000, function() {});

// Firebase
var firebase = require('firebase');
firebase.initializeApp({
  apiKey: process.env.FIREBASE_API_KEY,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID
});

// Botkit
var Botkit = require('botkit');
var controller = Botkit.slackbot();
controller.configureSlackApp({
  clientId: process.env.SLACK_CLIENT_ID,
  clientSecret: process.env.SLACK_CLIENT_SECRET,
  redirectUri: 'http://localhost:3000/slack/callback',
  scopes: ['commands']
});

// Genius
var Genius = require('node-genius')
var genius = new Genius(process.env.GENIUS_ACCESS_TOKEN)

// Mixpanel
var Mixpanel = require('mixpanel');
var mixpanel = Mixpanel.init(process.env.MIXPANEL_KEY);

// Routes
app.get('/', function(req, res) {
  res.sendFile(__dirname + '/public/index.html')
})

app.get('/?ref=*', function(req, res) {
  res.sendFile(__dirname + '/public/index.html')
})

app.get('/success', function (req, res) {
    res.sendFile(__dirname + '/public/success.html')
});

app.get('/fail', function (req, res) {
    res.sendFile(__dirname + '/public/fail.html')
});

app.get('/privacy', function (req, res) {
    res.sendFile(__dirname + '/public/privacy.html')
});

// Slack Authentication
app.get('/slack/callback', function(req, res) {
  var url = 'https://slack.com/api/oauth.access?';
  url += 'client_id=' + process.env.SLACK_CLIENT_ID;
  url += '&client_secret=' + process.env.SLACK_CLIENT_SECRET;
  url += '&code=' + req.query.code;

  request(url, function (error, response, body) {
    if (error || response.statusCode != 200) {
      console.log('Request Error: ' + error)
      res.sendFile(__dirname + '/public/failure.html')
    } else {
      var data = JSON.parse(body)
      if (!data.ok) {
        console.log('Slack OAuth Error: ' + data.error)
        res.sendFile(__dirname + '/public/failure.html')
      } else {
        var team = {}
        team[data.team_id] = {
          access_token: data.access_token,
          scope: data.scope,
          user_id: data.user_id,
          team_id: data.team_id,
          team_name: data.team_name
        }

        firebase.database().ref('/slack/').update(team, function(error) {
          if (error) {
            console.log('Firebase Error: ' + error)
            res.sendFile(__dirname + '/public/failure.html')
          } else {
            console.log(team[data.team_id].team_name + ' was added to Firebase')
            res.sendFile(__dirname + '/public/success.html')
          }
        });
      }
    }
  });
});

// Slack Firesong
app.post('/slack/firesong', function(req, res) {
  console.log('/slack/firesong find: ' + req.body.text)
  genius.search(req.body.text, function (error, results) {
    var dataJSON = JSON.parse(results);
    var hits = dataJSON.response.hits;
    console.log('Genius found ' + hits.length + ' hits')

    if (hits.length < 1) {
      console.log('No hits: ' + dataJSON)
      sendDefaultMessage(res);
    } else {
      // Get Random Genius Hit
      getRandomGeniusHit(res, hits, 0)
    }
  });
});

function getRandomGeniusHit(res, hits, attempt) {
  var i = (hits.length < 4 ? hits.length : 3);
  var random = Math.floor(Math.random() * i);

  // Get Genius song from random song id
  var geniusId = hits[random].result.id
  console.log('Got Genius song id: ' + geniusId)
  genius.getSong(geniusId, function (error, song) {
    if (error) {
      console.log('Get random Genius song error: ', error);
      tryToGetAnotherRandomHit(res, hits, attempt)
    } else {
      var songJSON = JSON.parse(song);

      // Find the Spotify Media
      if (!songJSON.response.song.media) {
        console.log('No media')
        tryToGetAnotherRandomHit(res, hits, attempt)
      } else {
        var media = songJSON.response.song.media
        var spotifyMedia = media.map(function(source) { if (source.provider == 'spotify') { return source } })
        if (spotifyMedia) {
          var spotifyURL = spotifyMedia[0].url
          if (spotifyURL.includes('local')) {
            console.log('Local Spotify song id')
            tryToGetAnotherRandomHit(res, hits, attempt)
          } else {
            // Send message to Slack
            res.send({
              'response_type': 'in_channel',
              'text': spotifyURL
            });

            // Record in Mixpanel
            recordMixpanelEvent(req, spotifyURL.substr(37));
          }
        } else {
          if (media.length == 0) {
            console.log('No media')
            tryToGetAnotherRandomHit(res, hits, attempt)
          } else {
            var mediaURL = media[0].url
            // Send message to Slack
            res.send({
              'response_type': 'in_channel',
              'text': mediaURL
            });

            // Record in Mixpanel
            recordMixpanelEvent(req, mediaURL);
          }
        }
      }
    }
  });
}

// Mixpanel Event
function recordMixpanelEvent(req, spotify_id) {
  mixpanel.track('/firesong', {
    distinct_id: req.body.response_url.substr(33),
    user_id: req.body.user_id,
    user_name: req.body.user_name,
    channel_id: req.body.channel_id,
    team_id: req.body.team_id,
    team_domain: req.body.team_domain,
    text: req.body.text,
    song: spotify_id
  });
}

// Try to get another random Genius Hit
function tryToGetAnotherRandomHit(res, hits, attempt) {
  if (attempt > 2) {
    sendDefaultMessage(res);
  } else {
    console.log('Grab another random hit, attempts: ' + (attempt + 1))
    getRandomGeniusHit(res, hits, attempt + 1);
  }
}

// Send default song in case anything goes wrong
function sendDefaultMessage(res) {
  console.log('Sending default message')
  res.send({
    'response_type': 'in_channel',
    'text': "Something went wrong 🤔 we're on it. In the meantime: " + 'https://open.spotify.com/track/2uljPrNySotVP1d42B30X2'
  });
}
<|endoftext|>


<commit_before>var express = require('express');
var fs = require('fs');

module.exports = function(dirname) {
  var router = express.Router();
  fs.readdirSync(dirname).forEach(function(file) {
    if(file === 'index.js'
        || file.substr(file.lastIndexOf('.') + 1) !== 'js'
        || file.substr(0, 1) === '_')
      return;
    subRouter = require(dirname + '/' + file.substr(0, file.indexOf('.')));
    console.log(subRouter);
    router.use('/', subRouter, { mergeParams: true });
    return router;
  });
};

<commit_msg>Debugging subrouting<commit_after>var express = require('express');
var fs = require('fs');

module.exports = function(dirname) {
  var router = express.Router();
  fs.readdirSync(dirname).forEach(function(file) {
    if(file === 'index.js'
        || file.substr(file.lastIndexOf('.') + 1) !== 'js'
        || file.substr(0, 1) === '_')
      return;
    subRouter = require(dirname + '/' + file.substr(0, file.indexOf('.')));
    console.log(subRouter);
    router.use('/', subRouter);
    return router;
  });
};

<|endoftext|>