<commit_before>function Upload(options) {
    var fs     = require('fs');
    var tools  = require(__dirname + '/../tools.js');

    var that = this;

    options = options || {};

    if (!options.states)      throw 'Invalid arguments: states is missing';
    if (!options.objects)     throw 'Invalid arguments: objects is missing';
    if (!options.processExit) throw 'Invalid arguments: processExit is missing';

    var states      = options.states;
    var objects     = options.objects;
    var processExit = options.processExit;
    var mime;

    // get all instances of one adapter
    function getInstances(adapter, callback) {
        objects.getObjectList({startkey: 'system.adapter.' + adapter + '.', endkey: 'system.adapter.' + adapter + '.\u9999'}, function (err, arr) {
            var instances = [];
            if (!err && arr && arr.rows) {
                var files = [];
                var count = 0;
                for (var i = 0; i < arr.rows.length; i++) {
                    if (arr.rows[i].value.type != 'instance') continue;
                    instances.push(arr.rows[i].value._id);
                }
            }
            callback(instances);
        });
    }

    // get all instances of all adapters in the list
    function getAllInstances(adapters, callback) {
        var instances = [];
        var count = adapters.length;
        for (var i = 0; i < adapters.length; i++) {
            if (!adapters[i]) continue;
            if (adapters[i].indexOf('.') == -1) {
                getInstances(adapters[i], function (inst) {
                    for (var j = 0; j < inst.length; j++) {
                        if (instances.indexOf(inst[j]) == -1) instances.push(inst[j]);
                    }
                    if (!--count) callback(instances);
                });
            } else {
                if (instances.indexOf(adapters[i]) == -1) instances.push(adapters[i]);
            }
        }
        if (!count) callback(instances);
    }

    // Check if some adapters must be restarted and restart them
    function checkRestartOther(adapter, callback) {
        var adapterDir = tools.getAdapterDir(adapter);
        var isRestarting = false;
        try {
            var adapterConf = JSON.parse(fs.readFileSync(adapterDir + '/io-package.json').toString());
            if (adapterConf.common.restartAdapters) {
                if (typeof adapterConf.common.restartAdapters !== 'object') adapterConf.common.restartAdapters = [adapterConf.common.restartAdapters];

                if (adapterConf.common.restartAdapters.length && adapterConf.common.restartAdapters[0]) {
                    isRestarting = true;
                    getAllInstances(adapterConf.common.restartAdapters, function (instances) {
                        isRestarting = false;
                        for (var r = 0; r < instances.length; r++) {
                            isRestarting = true;

                            objects.getObject(instances[r], function (err, obj) {
                                // if instance is enabled
                                if (!err && obj && obj.common.enabled) {

                                    obj.common.enabled = false; // disable instance

                                    objects.setObject(obj._id, obj, function (err) {
                                        if (!err) {

                                            obj.common.enabled = true; // enable instance

                                            objects.setObject(obj._id, obj, function (err) {
                                                console.log('Adapter "' + obj._id + '" restarted.');
                                                callback();
                                            });
                                        } else {
                                            if (err) {
                                                console.error('Cannot restart adapter "' + obj._id + '": ' + err);
                                            } else {
                                                console.warn('Adapter "' + obj._id + '" is disabled and cannot be restarted.');
                                            }
                                            callback();
                                        }
                                    });
                                } else {
                                    callback();
                                }
                            });
                        }
                        if (!isRestarting) {
                            callback();
                        }
                    });

                }
             }
        } catch (e) {
            console.error('Cannot parse ' + adapterDir + '/io-package.json:' + e);
            if (isRestarting) callback();
        }
        if (!isRestarting) callback();
    }

    this.uploadAdapterFull = function (adapters, callback) {
        if (!adapters || !adapters.length) {
            if (callback) callback();
            return;
        }
        var adapter = adapters.pop();
        that.uploadAdapter(adapter, true, true, function () {
            that.upgradeAdapterObjects(adapter, function () {
                that.uploadAdapter(adapter, false, true, function () {
                    setTimeout(function () {
                        that.uploadAdapterFull(adapters, callback);
                    }, 0);
                });
            });
        });
    };

    this.uploadFile = function (source, target, callback) {
        var request = require('request');
        target = target.replace(/\\/g, '/');
        source = source.replace(/\\/g, '/');
        if (target[0] === '/') target = target.substring(1);
        if (target[target.length - 1] == '/') {
            var name = source.split('/').pop();
            name = name.split('?')[0];
            if (name.indexOf('.') === -1) name = 'index.html';
            target += name;
        }
        var parts = target.split('/');
        var adapter = parts[0];
        parts.splice(0, 1);
        target = parts.join('/');

        if (source.match(/^http:\/\/|^https:\/\//)) {
            request(source, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    objects.writeFile(adapter, target, body, function (err) {
                        if (err) console.error(err);
                        if (typeof callback === 'function') callback(err, adapter + '/' + target);
                    });
                } else {
                    console.error('Cannot get URL: ' + error || response.statusCode);
                    if (typeof callback === 'function') callback(error || response.statusCode, adapter + '/' + target);
                }
            });
        } else {
            try {
                objects.writeFile(adapter, target, fs.readFileSync(source), function (err) {
                    if (err) console.error(err);
                    if (typeof callback === 'function') callback(err, adapter + '/' + target);
                });
            } catch (err) {
                console.error('Cannot read file "' + source + '": ' + err);
                if (typeof callback === 'function') callback(err, adapter + '/' + target);
            }
        }
    };

    // Upload www folder of adapter into ObjectsDB
    this.uploadAdapter = function (adapter, isAdmin, forceUpload, subTree, callback) {
        var rev;
        var id = adapter + (isAdmin ? '.admin' : '');
        var adapterDir = tools.getAdapterDir(adapter);
        var dir = adapterDir + (isAdmin ? '/admin' : '/www');
        var files = [];
        if (typeof subTree == 'function') {
            callback = subTree;
            subTree = null;
        }
        if (subTree) {
            dir += '/' + subTree;
        }

        if (!isAdmin) {
            var cfg;
            // check for common.wwwDontUpload (required for legacy adapter)
            if (fs.existsSync(adapterDir + '/io-package.json')) {
                cfg = require(adapterDir + '/io-package.json');
            }
            if (cfg && cfg.common && cfg.common.wwwDontUpload) {
                if (typeof callback === 'function') callback(adapter);
                return;
            }
        }
        // do not upload www dir of admin adapter
        if (adapter === 'admin' && !isAdmin) {
            // To DO remove after a while
            console.log('This should never happens!');
            if (typeof callback === 'function') callback(adapter);
            return;
        }

        // Create "upload progress" object if not exists
        if (!isAdmin) {
            objects.getObject('system.adapter.' + adapter + '.upload', function (err, obj) {
                if (err || !obj) {
                    objects.setObject('system.adapter.' + adapter + '.upload',
                        {
                            _id:   'system.adapter.' + adapter + '.upload',
                            type:   'state',
                            common: {
                                name: adapter + '.upload',
                                type: 'number',
                                role: 'indicator.state',
                                unit: '%',
                                def:  0,
                                desc: 'Upload process indicator'
                            },
                            native: {}
                        }
                    );
                }
            });
            // Set indicator to 0
            states.setState('system.adapter.' + adapter + '.upload', 0, true);
        }

        if (!mime) mime = require('mime');

        function done(err, res) {
            if (err) {
                callback();
            } else {
                console.log('got ' + dir);
                files = res;
                setTimeout(function (_adapter) {
                    maxFiles = files.length || 1;
                    upload(_adapter);
                }, 25, adapter);
            }
        }

        var maxFiles = 0;
        var lastProgressUpdate = (new Date()).getTime();

        function upload(adapter) {
            var file;
            if (!files.length) {
                if (!isAdmin) {
                    states.setState('system.adapter.' + adapter + '.upload', {val: 0, ack: true}, function () {
                        if (typeof callback === 'function') callback(adapter);
                    });
                } else {
                    if (typeof callback === 'function') callback(adapter);
                }
            } else {
                file = files.pop();
                if (file == '.gitignore') {
                    upload(adapter);
                    return;
                }

                var mimeType = mime.lookup(file);
                var attName;
                attName = file.split('/' + tools.appName + '.');
                if (attName.length === 1) {
                    // try to find anyway if adapter is not lower case
                    var pos = file.toLowerCase().indexOf(tools.appName.toLowerCase());
                    if (pos !== -1) attName = ['', file.substring(tools.appName.length + 2)];
                }

                attName = attName.pop();
                attName = attName.split('/').slice(2).join('/');
                console.log('upload [' + files.length + ']', id, file, attName, mimeType);

                // Update upload indicator
                if (!isAdmin) {
                    var now = (new Date()).getTime();
                    if (now - lastProgressUpdate > 1000) {
                        lastProgressUpdate = now;
                        states.setState('system.adapter.' + adapter + '.upload', {val: parseInt(1000 * (maxFiles - files.length) / maxFiles) / 10, ack: true});
                    }
                }

                fs.createReadStream(file).pipe(
                    objects.insert(id, attName, null, mimeType, {
                        rev: rev
                    }, function (err, res) {
                        if (err) {
                            console.log(err);
                            if (typeof callback === 'function') callback(adapter);
                        }
                        if (res) rev = res.rev;
                        setTimeout(function () {
                            upload(adapter);
                        }, 50);
                    })
                );
            }
        }

        function walk(dir, done) {
            var results = [];
            fs.readdir(dir, function (err, list) {
                if (err) return done(err);
                var i = 0;
                (function next() {
                    var file = list[i++];
                    if (!file) return done(null, results);
                    file = dir + '/' + file;
                    fs.stat(file, function (err, stat) {
                        if (stat && stat.isDirectory()) {
                            walk(file, function (err, res) {
                                results = results.concat(res);
                                next();
                            });
                        } else {
                            if (!file.match(/\.npmignore$/) && !file.match(/\.gitignore$/)) results.push(file);
                            next();
                        }
                    });
                })();
            });
        }

        objects.getObject(id, function (err, res) {
            if (err || !res) {
                objects.setObject(id, {
                    type: 'meta',
                    common: {
                        name: id.split('.').pop(),
                        type: isAdmin ? 'admin' : 'www'
                    },
                    native: {}
                }, function (err, res) {
                    if (res) rev = res.rev;
                    if (!isAdmin) {
                        checkRestartOther(adapter, function () {
                            walk(dir, done);
                        });
                    } else {
                        walk(dir, done);
                    }
                });
            } else {
                if (!forceUpload) {
                    if (typeof callback === 'function') callback(adapter);
                } else {
                    rev = res.rev;
                    if (!isAdmin) {
                        checkRestartOther(adapter, function () {
                            walk(dir, done);
                        });
                    } else {
                        walk(dir, done);
                    }
                }
            }
        });
    };

    function extendNative(target, additional) {
        for (var attr in additional) {
            if (target[attr] === undefined) {
                target[attr] = additional[attr];
            } else if (typeof additional[attr] === 'object' && !(additional[attr] instanceof Array)) {
                target[attr] = target[attr] || {};
                extendNative(target[attr], additional[attr]);
            }
        }
        return target;
    }

    function extendCommon(target, additional) {
        for (var attr in additional) {
            if (attr === 'title' || attr === 'schedule' || attr === 'mode' || attr === 'loglevel' || attr === 'enabled') {
                if (target[attr] === undefined) target[attr] = additional[attr];
            } else
            if (typeof additional[attr] !== 'object' || (additional[attr] instanceof Array)) {
                target[attr] = additional[attr];
            } else {
                target[attr] = target[attr] || {};
                extendCommon(target[attr], additional[attr]);
            }
        }
        return target;
    }

    this.upgradeAdapterObjects = function (name, iopack, callback) {
        if (typeof iopack == 'function') {
            callback = iopack;
            iopack = null;
        }
        if (!iopack) {
            var adapterDir = tools.getAdapterDir(name);
            try {
                iopack = JSON.parse(fs.readFileSync(adapterDir + '/io-package.json'));
            } catch (e) {
                console.error('Cannot find io-package.json in ' + adapterDir);
                iopack = null;
            }
        }

        if (!iopack) {
            callback(name);
        } else {
            objects.getObject('system.adapter.' + name, function (err, obj) {
                if (err || !obj) {
                    console.error('system.adapter.' + name + ' does not exist');
                    callback(name);
                } else {
                    obj.common = iopack.common || {};
                    obj.native = iopack.native || {};

                    obj.common.installedVersion = iopack.common.version;

                    var hostname = tools.getHostName();

                    objects.setObject('system.adapter.' + name, obj, function () {
                        // Update all instances of this host
                        objects.getObjectView('system', 'instance', {startkey: 'system.adapter.' + name + '.', endkey: 'system.adapter.' + name + '.\u9999'}, null, function (err, res) {
                            var cntr = 0;

                            if (res) {
                                for (var i = 0; i < res.rows.length; i++) {
                                    if (res.rows[i].value.common.host === hostname) {
                                        cntr++;
                                        objects.getObject(res.rows[i].id, function (err, _obj) {
                                            var newObject = JSON.parse(JSON.stringify(_obj));

                                            // all common settings should be taken from new one
                                            newObject.common = extendCommon(newObject.common, iopack.common);
                                            newObject.native = extendNative(newObject.native, iopack.native);

                                            newObject.common.installedVersion = iopack.common.version;
                                            newObject.common.version          = iopack.common.version;

                                            // Compare objects to reduce restarts of instances
                                            if (JSON.stringify(newObject) !== JSON.stringify(_obj)) {
                                                console.log('Update "' + newObject._id + '"');
                                                objects.setObject(newObject._id, newObject, function () {
                                                    if (!--cntr && callback) callback(name);
                                                });
                                            } else {
                                                if (!--cntr && callback) callback(name);
                                            }
                                        });
                                    }
                                }
                            }

                            // updates "_design/system" and co
                            if (iopack.objects && typeof iopack.objects === 'object') {
                                for (var _id in iopack.objects) {
                                    if (!iopack.objects.hasOwnProperty(_id)) continue;
                                    cntr++;
                                    objects.setObject(iopack.objects[_id]._id, iopack.objects[_id], function (err) {
                                        if (err) console.error('Cannot update object: ' + err);
                                        if (!--cntr && callback) callback(name);
                                    });
                                }
                            }

                            if (!cntr && callback) callback(name);
                        });
                    });
                }
            });
        }
    };
}

module.exports = Upload;
<commit_msg>tests<commit_after>function Upload(options) {
    var fs     = require('fs');
    var tools  = require(__dirname + '/../tools.js');

    var that = this;

    options = options || {};

    if (!options.states)      throw 'Invalid arguments: states is missing';
    if (!options.objects)     throw 'Invalid arguments: objects is missing';
    if (!options.processExit) throw 'Invalid arguments: processExit is missing';

    var states      = options.states;
    var objects     = options.objects;
    var processExit = options.processExit;
    var mime;

    // get all instances of one adapter
    function getInstances(adapter, callback) {
        objects.getObjectList({startkey: 'system.adapter.' + adapter + '.', endkey: 'system.adapter.' + adapter + '.\u9999'}, function (err, arr) {
            var instances = [];
            if (!err && arr && arr.rows) {
                var files = [];
                var count = 0;
                for (var i = 0; i < arr.rows.length; i++) {
                    if (arr.rows[i].value.type != 'instance') continue;
                    instances.push(arr.rows[i].value._id);
                }
            }
            callback(instances);
        });
    }

    // get all instances of all adapters in the list
    function getAllInstances(adapters, callback) {
        var instances = [];
        var count = adapters.length;
        for (var i = 0; i < adapters.length; i++) {
            if (!adapters[i]) continue;
            if (adapters[i].indexOf('.') == -1) {
                getInstances(adapters[i], function (inst) {
                    for (var j = 0; j < inst.length; j++) {
                        if (instances.indexOf(inst[j]) == -1) instances.push(inst[j]);
                    }
                    if (!--count) callback(instances);
                });
            } else {
                if (instances.indexOf(adapters[i]) == -1) instances.push(adapters[i]);
            }
        }
        if (!count) callback(instances);
    }

    // Check if some adapters must be restarted and restart them
    function checkRestartOther(adapter, callback) {
        var adapterDir = tools.getAdapterDir(adapter);
        var isRestarting = false;
        try {
            var adapterConf = JSON.parse(fs.readFileSync(adapterDir + '/io-package.json').toString());
            if (adapterConf.common.restartAdapters) {
                if (typeof adapterConf.common.restartAdapters !== 'object') adapterConf.common.restartAdapters = [adapterConf.common.restartAdapters];

                if (adapterConf.common.restartAdapters.length && adapterConf.common.restartAdapters[0]) {
                    isRestarting = true;
                    getAllInstances(adapterConf.common.restartAdapters, function (instances) {
                        isRestarting = false;
                        for (var r = 0; r < instances.length; r++) {
                            isRestarting = true;

                            objects.getObject(instances[r], function (err, obj) {
                                // if instance is enabled
                                if (!err && obj && obj.common.enabled) {

                                    obj.common.enabled = false; // disable instance

                                    objects.setObject(obj._id, obj, function (err) {
                                        if (!err) {

                                            obj.common.enabled = true; // enable instance

                                            objects.setObject(obj._id, obj, function (err) {
                                                console.log('Adapter "' + obj._id + '" restarted.');
                                                callback();
                                            });
                                        } else {
                                            if (err) {
                                                console.error('Cannot restart adapter "' + obj._id + '": ' + err);
                                            } else {
                                                console.warn('Adapter "' + obj._id + '" is disabled and cannot be restarted.');
                                            }
                                            callback();
                                        }
                                    });
                                } else {
                                    callback();
                                }
                            });
                        }
                        if (!isRestarting) {
                            callback();
                        }
                    });

                }
             }
        } catch (e) {
            console.error('Cannot parse ' + adapterDir + '/io-package.json:' + e);
            if (isRestarting) callback();
        }
        if (!isRestarting) callback();
    }

    this.uploadAdapterFull = function (adapters, callback) {
        if (!adapters || !adapters.length) {
            if (callback) callback();
            return;
        }
        var adapter = adapters.pop();
        that.uploadAdapter(adapter, true, true, function () {
            that.upgradeAdapterObjects(adapter, function () {
                that.uploadAdapter(adapter, false, true, function () {
                    setTimeout(function () {
                        that.uploadAdapterFull(adapters, callback);
                    }, 0);
                });
            });
        });
    };

    this.uploadFile = function (source, target, callback) {
        var request = require('request');
        target = target.replace(/\\/g, '/');
        source = source.replace(/\\/g, '/');
        if (target[0] === '/') target = target.substring(1);
        if (target[target.length - 1] == '/') {
            var name = source.split('/').pop();
            name = name.split('?')[0];
            if (name.indexOf('.') === -1) name = 'index.html';
            target += name;
        }
        var parts = target.split('/');
        var adapter = parts[0];
        parts.splice(0, 1);
        target = parts.join('/');

        if (source.match(/^http:\/\/|^https:\/\//)) {
            request(source, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    objects.writeFile(adapter, target, body, function (err) {
                        if (err) console.error(err);
                        if (typeof callback === 'function') callback(err, adapter + '/' + target);
                    });
                } else {
                    console.error('Cannot get URL: ' + error || response.statusCode);
                    if (typeof callback === 'function') callback(error || response.statusCode, adapter + '/' + target);
                }
            });
        } else {
            try {
                objects.writeFile(adapter, target, fs.readFileSync(source), function (err) {
                    if (err) console.error(err);
                    if (typeof callback === 'function') callback(err, adapter + '/' + target);
                });
            } catch (err) {
                console.error('Cannot read file "' + source + '": ' + err);
                if (typeof callback === 'function') callback(err, adapter + '/' + target);
            }
        }
    };

    // Upload www folder of adapter into ObjectsDB
    this.uploadAdapter = function (adapter, isAdmin, forceUpload, subTree, callback) {
        var rev;
        var id = adapter + (isAdmin ? '.admin' : '');
        var adapterDir = tools.getAdapterDir(adapter);
        var dir = adapterDir + (isAdmin ? '/admin' : '/www');
        var files = [];
        if (typeof subTree == 'function') {
            callback = subTree;
            subTree = null;
        }
        if (subTree) {
            dir += '/' + subTree;
        }

        if (!isAdmin) {
            var cfg;
            // check for common.wwwDontUpload (required for legacy adapter)
            if (fs.existsSync(adapterDir + '/io-package.json')) {
                cfg = require(adapterDir + '/io-package.json');
            }
            if (cfg && cfg.common && cfg.common.wwwDontUpload) {
                if (typeof callback === 'function') callback(adapter);
                return;
            }
        }
        // do not upload www dir of admin adapter
        if (adapter === 'admin' && !isAdmin) {
            // To DO remove after a while
            console.log('This should never happens!');
            if (typeof callback === 'function') callback(adapter);
            return;
        }

        // Create "upload progress" object if not exists
        if (!isAdmin) {
            objects.getObject('system.adapter.' + adapter + '.upload', function (err, obj) {
                if (err || !obj) {
                    objects.setObject('system.adapter.' + adapter + '.upload',
                        {
                            _id:   'system.adapter.' + adapter + '.upload',
                            type:   'state',
                            common: {
                                name: adapter + '.upload',
                                type: 'number',
                                role: 'indicator.state',
                                unit: '%',
                                def:  0,
                                desc: 'Upload process indicator'
                            },
                            native: {}
                        }
                    );
                }
            });
            // Set indicator to 0
            states.setState('system.adapter.' + adapter + '.upload', 0, true);
        }

        if (!mime) mime = require('mime');

        function done(err, res) {
            if (err) {
                console.log('error in upload: ' + err);
                callback();
            } else {
                console.log('got ' + dir);
                files = res;
                setTimeout(function (_adapter) {
                    maxFiles = files.length || 1;
                    upload(_adapter);
                }, 25, adapter);
            }
        }

        var maxFiles = 0;
        var lastProgressUpdate = (new Date()).getTime();

        function upload(adapter) {
            var file;
            if (!files.length) {
                console.log('call callback after finished upload');
                if (!isAdmin) {
                    states.setState('system.adapter.' + adapter + '.upload', {val: 0, ack: true}, function () {
                        if (typeof callback === 'function') callback(adapter);
                    });
                } else {
                    if (typeof callback === 'function') callback(adapter);
                }
            } else {
                file = files.pop();
                if (file == '.gitignore') {
                    upload(adapter);
                    return;
                }

                var mimeType = mime.lookup(file);
                var attName;
                attName = file.split('/' + tools.appName + '.');
                if (attName.length === 1) {
                    // try to find anyway if adapter is not lower case
                    var pos = file.toLowerCase().indexOf(tools.appName.toLowerCase());
                    if (pos !== -1) attName = ['', file.substring(tools.appName.length + 2)];
                }

                attName = attName.pop();
                attName = attName.split('/').slice(2).join('/');
                console.log('upload [' + files.length + ']', id, file, attName, mimeType);

                // Update upload indicator
                if (!isAdmin) {
                    var now = (new Date()).getTime();
                    if (now - lastProgressUpdate > 1000) {
                        lastProgressUpdate = now;
                        states.setState('system.adapter.' + adapter + '.upload', {val: parseInt(1000 * (maxFiles - files.length) / maxFiles) / 10, ack: true});
                    }
                }

                fs.createReadStream(file).pipe(
                    objects.insert(id, attName, null, mimeType, {
                        rev: rev
                    }, function (err, res) {
                        if (err) {
                            console.log(err);
                            if (typeof callback === 'function') callback(adapter);
                        }
                        if (res) rev = res.rev;
                        setTimeout(function () {
                            upload(adapter);
                        }, 50);
                    })
                );
            }
        }

        function walk(dir, done) {
            var results = [];
            fs.readdir(dir, function (err, list) {
                if (err) return done(err);
                var i = 0;
                (function next() {
                    var file = list[i++];
                    if (!file) return done(null, results);
                    file = dir + '/' + file;
                    fs.stat(file, function (err, stat) {
                        if (stat && stat.isDirectory()) {
                            walk(file, function (err, res) {
                                results = results.concat(res);
                                next();
                            });
                        } else {
                            if (!file.match(/\.npmignore$/) && !file.match(/\.gitignore$/)) results.push(file);
                            next();
                        }
                    });
                })();
            });
        }

        objects.getObject(id, function (err, res) {
            if (err || !res) {
                objects.setObject(id, {
                    type: 'meta',
                    common: {
                        name: id.split('.').pop(),
                        type: isAdmin ? 'admin' : 'www'
                    },
                    native: {}
                }, function (err, res) {
                    if (res) rev = res.rev;
                    if (!isAdmin) {
                        checkRestartOther(adapter, function () {
                            walk(dir, done);
                        });
                    } else {
                        walk(dir, done);
                    }
                });
            } else {
                if (!forceUpload) {
                    if (typeof callback === 'function') callback(adapter);
                } else {
                    rev = res.rev;
                    if (!isAdmin) {
                        checkRestartOther(adapter, function () {
                            walk(dir, done);
                        });
                    } else {
                        walk(dir, done);
                    }
                }
            }
        });
    };

    function extendNative(target, additional) {
        for (var attr in additional) {
            if (target[attr] === undefined) {
                target[attr] = additional[attr];
            } else if (typeof additional[attr] === 'object' && !(additional[attr] instanceof Array)) {
                target[attr] = target[attr] || {};
                extendNative(target[attr], additional[attr]);
            }
        }
        return target;
    }

    function extendCommon(target, additional) {
        for (var attr in additional) {
            if (attr === 'title' || attr === 'schedule' || attr === 'mode' || attr === 'loglevel' || attr === 'enabled') {
                if (target[attr] === undefined) target[attr] = additional[attr];
            } else
            if (typeof additional[attr] !== 'object' || (additional[attr] instanceof Array)) {
                target[attr] = additional[attr];
            } else {
                target[attr] = target[attr] || {};
                extendCommon(target[attr], additional[attr]);
            }
        }
        return target;
    }

    this.upgradeAdapterObjects = function (name, iopack, callback) {
        if (typeof iopack == 'function') {
            callback = iopack;
            iopack = null;
        }
        if (!iopack) {
            var adapterDir = tools.getAdapterDir(name);
            try {
                iopack = JSON.parse(fs.readFileSync(adapterDir + '/io-package.json'));
            } catch (e) {
                console.error('Cannot find io-package.json in ' + adapterDir);
                iopack = null;
            }
        }

        if (!iopack) {
            callback(name);
        } else {
            objects.getObject('system.adapter.' + name, function (err, obj) {
                if (err || !obj) {
                    console.error('system.adapter.' + name + ' does not exist');
                    callback(name);
                } else {
                    obj.common = iopack.common || {};
                    obj.native = iopack.native || {};

                    obj.common.installedVersion = iopack.common.version;

                    var hostname = tools.getHostName();

                    objects.setObject('system.adapter.' + name, obj, function () {
                        // Update all instances of this host
                        objects.getObjectView('system', 'instance', {startkey: 'system.adapter.' + name + '.', endkey: 'system.adapter.' + name + '.\u9999'}, null, function (err, res) {
                            var cntr = 0;

                            if (res) {
                                for (var i = 0; i < res.rows.length; i++) {
                                    if (res.rows[i].value.common.host === hostname) {
                                        cntr++;
                                        objects.getObject(res.rows[i].id, function (err, _obj) {
                                            var newObject = JSON.parse(JSON.stringify(_obj));

                                            // all common settings should be taken from new one
                                            newObject.common = extendCommon(newObject.common, iopack.common);
                                            newObject.native = extendNative(newObject.native, iopack.native);

                                            newObject.common.installedVersion = iopack.common.version;
                                            newObject.common.version          = iopack.common.version;

                                            // Compare objects to reduce restarts of instances
                                            if (JSON.stringify(newObject) !== JSON.stringify(_obj)) {
                                                console.log('Update "' + newObject._id + '"');
                                                objects.setObject(newObject._id, newObject, function () {
                                                    if (!--cntr && callback) callback(name);
                                                });
                                            } else {
                                                if (!--cntr && callback) callback(name);
                                            }
                                        });
                                    }
                                }
                            }

                            // updates "_design/system" and co
                            if (iopack.objects && typeof iopack.objects === 'object') {
                                for (var _id in iopack.objects) {
                                    if (!iopack.objects.hasOwnProperty(_id)) continue;
                                    cntr++;
                                    objects.setObject(iopack.objects[_id]._id, iopack.objects[_id], function (err) {
                                        if (err) console.error('Cannot update object: ' + err);
                                        if (!--cntr && callback) callback(name);
                                    });
                                }
                            }

                            if (!cntr && callback) callback(name);
                        });
                    });
                }
            });
        }
    };
}

module.exports = Upload;
<|endoftext|>


<commit_before>var Extends = require('./DisplayObject.class.js');
var Class = {
    "_model": null,
    "bind": function bind(model) {
        if (this._model) {
            this.unbind();
        }
        this._model = model;
        model.on('change', this.onModelChange);
        if (this.Super.getNode()) {
            this.onModelChange();
        }
    },
    "unbind": function unbind() {
        var model = this._model;

        if (model) {
            model.removeListener('change', this.onModelChange);
            this._model = null;
        }
    },
    "create": function create(parentNode) {
        this.Super.create(parentNode);
        if (this._model) {
            this.onModelChange();
        }
    },
    "draw": function draw(data) {
        var nodeMap = this.Super.getNodeMap(),
            node,
            nodeName,
            property;

        if (!data && this._model) {
            data = this._model.escape();
        }
        for (nodeName in nodeMap) {
            property = data[nodeName];
            if (property === null || property === undefined) {
                property = "";  // If there is no value set, we display an empty string
            }
            node = nodeMap[nodeName];
            if (node.tagName === 'INPUT') {
                nodeMap[nodeName].value = property;
            } else {
                nodeMap[nodeName].innerHTML = property;
            }
        }
    },
    "destroy": function destroy() {
        this.unbind();
        this.Super.destroy();
    },
    "?onModelChange": Function,
    "?onCreate": Function,
    "?onDisplay": Function,
    "?onDestroy": Function
};<commit_msg>added if-has-own-property-clause to for-in loop within the draw()-method<commit_after>var Extends = require('./DisplayObject.class.js');
var Class = {
    "_model": null,
    "bind": function bind(model) {
        if (this._model) {
            this.unbind();
        }
        this._model = model;
        model.on('change', this.onModelChange);
        if (this.Super.getNode()) {
            this.onModelChange();
        }
    },
    "unbind": function unbind() {
        var model = this._model;

        if (model) {
            model.removeListener('change', this.onModelChange);
            this._model = null;
        }
    },
    "create": function create(parentNode) {
        this.Super.create(parentNode);
        if (this._model) {
            this.onModelChange();
        }
    },
    "draw": function draw(data) {
        var nodeMap = this.Super.getNodeMap(),
            node,
            nodeName,
            property;

        if (!data && this._model) {
            data = this._model.escape();
        }
        for (nodeName in nodeMap) {
            if (nodeMap.hasOwnProperty(nodeName)) {
                property = data[nodeName];
                if (property === null || property === undefined) {
                    property = "";  // If there is no value set, we display an empty string
                }
                node = nodeMap[nodeName];
                if (node.tagName === 'INPUT') {
                    nodeMap[nodeName].value = property;
                } else {
                    nodeMap[nodeName].innerHTML = property;
                }
            }
        }
    },
    "destroy": function destroy() {
        this.unbind();
        this.Super.destroy();
    },
    "?onModelChange": Function,
    "?onCreate": Function,
    "?onDisplay": Function,
    "?onDestroy": Function
};<|endoftext|>


<commit_before>/*
 *  Copyright 2015 Adobe Systems Incorporated. All rights reserved.
 *  This file is licensed to you under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License. You may obtain a copy
 *  of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under
 *  the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
 *  OF ANY KIND, either express or implied. See the License for the specific language
 *  governing permissions and limitations under the License.
 */

'use strict';

var put = require('put');
var binary = require('binary');
var Long = require('long');
var logger = require('winston').loggers.get('smb');

var ntstatus = require('../../ntstatus');
var SMB = require('../constants');
var utils = require('../../utils');
var smb2 = require('../../smb2/handler');
var smb2Message = require('../../smb2/message');
var SMB2 = require('../../smb2/constants');

var ZERO = new Buffer([ 0 ]);

// Max multiplex count.
var MAX_MPX_COUNT = 50;
// Max number of virtual circuits.
var MAX_NUMBER_VCS = 1;
// Max buffer size.
var MAX_BUFFER_SIZE = 33028;
// Max raw size.
var MAX_RAW_SIZE = 65536;

/**
 * SMB_COM_NEGOTIATE (0x72): Negotiate protocol dialect.
 *
 * @param {Object} msg - an SMB message object
 * @param {Number} commandId - the command id
 * @param {Buffer} commandParams - the command parameters
 * @param {Buffer} commandData - the command data
 * @param {Number} commandParamsOffset - the command parameters offset within the SMB
 * @param {Number} commandDataOffset - the command data offset within the SMB
 * @param {Object} connection - an SMBConnection instance
 * @param {Object} server - an SMBServer instance
 * @param {Function} cb callback called with the command's result
 * @param {Object} cb.result - an object with the command's result params and data
 *                             or null if the handler already sent the response and
 *                             no further processing is required by the caller
 * @param {Number} cb.result.status
 * @param {Buffer} cb.result.params
 * @param {Buffer} cb.result.data
 */
function handle(msg, commandId, commandParams, commandData, commandParamsOffset, commandDataOffset, connection, server, cb) {
  // decode dialects
  msg.dialects = [];

  var read = 0;
  binary.parse(commandData).loop(function (end, vars) {
    // buffer format (0x2: dialect)
    this.skip(1);
    read += 1;

    // extract dialect name (nul terminated)
    this.scan('dialect', ZERO);
    var dialect = vars['dialect'].toString();
    msg.dialects.push(dialect);
    read += dialect.length + 1;

    if (read >= commandData.length) {
      end();
    }
  });

  logger.debug('[%s] dialects: %s', SMB.COMMAND_TO_STRING[commandId].toUpperCase(), msg.dialects.toString());

  var result;

  // SMB2 handshake?
  if (!!server.config['smb2Support'] && msg.dialects.indexOf(SMB.DIALECT_SMB_2_X) > -1) {
    // handcraft an smb2 negotiate response
    // todo refactor into reusable separate function
    var buf = new Buffer(SMB2.HEADER_LENGTH);
    buf.fill(0);
    var smb2Msg = smb2Message.decode(buf);
    smb2Msg.protocolId = SMB2.PROTOCOL_ID;
    smb2Msg.header.flags.reply = true;
    smb2Msg.header.commandId = SMB2.STRING_TO_COMMAND['negotiate'];
    smb2Msg.header.creditReqRes = 1;

    var systemTime = utils.systemToSMBTime(Date.now());
    var startTime = utils.systemToSMBTime(server.getStartTime());
    var securityBuffer = utils.EMPTY_BUFFER;
    var out = put();
    out.word16le(0x0041)  // StructureSize (fixed according to spec)
      .word16le(0) // SecurityMode
      .word16le(SMB2.SMB_2_X_X) // DialectRevision
      .word16le(0)  // NegotiateContextCount/Reserved
      .put(server.getGuid())  // ServerGuid
      .word32le(0) // Capabilities
      .word32le(0x00100000) // MaxTransactSize
      .word32le(0x00100000) // MaxReadSize
      .word32le(0x00100000) // MaxWriteSize
      .word32le(systemTime.getLowBitsUnsigned())  // SystemTime
      .word32le(systemTime.getHighBitsUnsigned())
      .word32le(startTime.getLowBitsUnsigned())  // ServerStartTime
      .word32le(startTime.getHighBitsUnsigned())
      .word16le(SMB2.HEADER_LENGTH + 64)  // SecurityBufferOffset
      .word16le(securityBuffer.length)  // SecurityBufferLength
      .word32le(0)  // NegotiateContextOffset/Reserved2
      .put(securityBuffer); // SecurityBuffer
    smb2Msg.body = out.buffer();
    smb2.sendResponse(smb2Msg, ntstatus.STATUS_SUCCESS, connection, server, function (err) {
      if (err) {
        logger.error('failed to send SMB2 negotiate response', err);
      }
      // we've already handled sending the response ourselves, no further processing required by the caller
      cb(null);
    });
    return;
  }

  var idx = msg.dialects.indexOf(SMB.DIALECT_NT_LM_0_12);

  // send response

  if (idx === -1) {
    // couldn't agree on a dialect
    result = {
      status: ntstatus.STATUS_SUCCESS,
      params: new Buffer(2).writeUint16LE(0xffff),
      data: commandData
    };
    process.nextTick(function () { cb(result); });
    return;
  }

  var capabilities = SMB.CAP_STATUS32 | SMB.CAP_LEVEL2_OPLOCKS |
    SMB.CAP_NT_SMBS | SMB.CAP_NT_FIND |
    SMB.CAP_LARGE_FILES | SMB.CAP_UNICODE |
    SMB.CAP_INFOLEVEL_PASSTHRU | SMB.CAP_RPC_REMOTE_APIS |
    SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX |
    //SMB.CAP_LWIO |
    SMB.CAP_LOCK_AND_READ;

  var extendedSecurity = false;
  if (server.config.extendedSecurity) {
    if (msg.header.flags.security.extended) {
      capabilities |= SMB.CAP_EXTENDED_SECURITY;
      extendedSecurity = true;
    }
  }

  var login = server.createLogin();

  var params = new Buffer(2 * 17);
  var offset = 0;
  // DialectIndex
  params.writeUInt16LE(idx, offset);
  offset += 2;
  // SecurityMode
  params.writeUInt8(SMB.NEGOTIATE_USER_SECURITY | SMB.NEGOTIATE_ENCRYPT_PASSWORDS, offset);
  offset += 1;
  // MaxMpxCount
  params.writeUInt16LE(MAX_MPX_COUNT, offset);
  offset += 2;
  // MaxNumberVcs
  params.writeUInt16LE(MAX_NUMBER_VCS, offset);
  offset += 2;
  // MaxBufferSize
  //params.writeUInt32LE(consts.SMB_MAX_LENGTH, offset);
  params.writeUInt32LE(MAX_BUFFER_SIZE, offset);
  offset += 4;
  // MaxRawSize
  params.writeUInt32LE(MAX_RAW_SIZE, offset);
  offset += 4;
  // SessionKey
  params.writeUInt32LE(login.key, offset);
  offset += 4;
  // Capabilities
  params.writeInt32LE(capabilities, offset);
  offset += 4;
  // SystemTime
  var long = utils.systemToSMBTime(Date.now());
  params.writeUInt32LE(long.getLowBitsUnsigned(), offset);
  offset += 4;
  params.writeUInt32LE(long.getHighBitsUnsigned(), offset);
  offset += 4;
  // ServerTimeZone
  params.writeInt16LE(new Date().getTimezoneOffset(), offset);
  offset += 2;
  // ChallengeLength
  params.writeUInt8(extendedSecurity ? 0 : login.challenge.length, offset);

  var data;
  offset = 0;
  if (extendedSecurity) {
    // todo securityBlob: raw NTLMSSP (empty) or SPNEGO (NegotiateToken)?
    var securityBlob = utils.EMPTY_BUFFER;
    data = new Buffer(server.getGuid().length + securityBlob.length);
    // ServerGUID
    server.getGuid().copy(data, offset);
    offset += server.getGuid().length;
    // SecurityBlob
    securityBlob.copy(data, offset);
    offset += securityBlob.length;
  } else {
    var encDomain = new Buffer(server.domainName, 'utf16le');
    data = new Buffer(login.challenge.length + encDomain.length + 2);
    // Challenge
    login.challenge.copy(data, offset);
    offset += login.challenge.length;
    // DomainName
    encDomain.copy(data, offset);
    offset += encDomain.length;
    data.writeUInt16LE(0, offset);  // sting delimiter (0x0000)
  }

  // return result
  result = {
    status: ntstatus.STATUS_SUCCESS,
    params: params,
    data: data
  };
  process.nextTick(function () { cb(result); });
}

module.exports = handle;<commit_msg>negotiate: add serverName to repsonse, remember returned sessionKey in connection (#43)<commit_after>/*
 *  Copyright 2015 Adobe Systems Incorporated. All rights reserved.
 *  This file is licensed to you under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License. You may obtain a copy
 *  of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under
 *  the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
 *  OF ANY KIND, either express or implied. See the License for the specific language
 *  governing permissions and limitations under the License.
 */

'use strict';

var put = require('put');
var binary = require('binary');
var Long = require('long');
var logger = require('winston').loggers.get('smb');

var ntstatus = require('../../ntstatus');
var SMB = require('../constants');
var utils = require('../../utils');
var smb2 = require('../../smb2/handler');
var smb2Message = require('../../smb2/message');
var SMB2 = require('../../smb2/constants');

var ZERO = new Buffer([ 0 ]);

// Max multiplex count.
var MAX_MPX_COUNT = 50;
// Max number of virtual circuits.
var MAX_NUMBER_VCS = 1;
// Max buffer size.
var MAX_BUFFER_SIZE = 33028;
// Max raw size.
var MAX_RAW_SIZE = 65536;

/**
 * SMB_COM_NEGOTIATE (0x72): Negotiate protocol dialect.
 *
 * @param {Object} msg - an SMB message object
 * @param {Number} commandId - the command id
 * @param {Buffer} commandParams - the command parameters
 * @param {Buffer} commandData - the command data
 * @param {Number} commandParamsOffset - the command parameters offset within the SMB
 * @param {Number} commandDataOffset - the command data offset within the SMB
 * @param {Object} connection - an SMBConnection instance
 * @param {Object} server - an SMBServer instance
 * @param {Function} cb callback called with the command's result
 * @param {Object} cb.result - an object with the command's result params and data
 *                             or null if the handler already sent the response and
 *                             no further processing is required by the caller
 * @param {Number} cb.result.status
 * @param {Buffer} cb.result.params
 * @param {Buffer} cb.result.data
 */
function handle(msg, commandId, commandParams, commandData, commandParamsOffset, commandDataOffset, connection, server, cb) {
  // decode dialects
  msg.dialects = [];

  var read = 0;
  binary.parse(commandData).loop(function (end, vars) {
    // buffer format (0x2: dialect)
    this.skip(1);
    read += 1;

    // extract dialect name (nul terminated)
    this.scan('dialect', ZERO);
    var dialect = vars['dialect'].toString();
    msg.dialects.push(dialect);
    read += dialect.length + 1;

    if (read >= commandData.length) {
      end();
    }
  });

  logger.debug('[%s] dialects: %s', SMB.COMMAND_TO_STRING[commandId].toUpperCase(), msg.dialects.toString());

  var result;

  // SMB2 handshake?
  if (!!server.config['smb2Support'] && msg.dialects.indexOf(SMB.DIALECT_SMB_2_X) > -1) {
    // handcraft an smb2 negotiate response
    // todo refactor into reusable separate function
    var buf = new Buffer(SMB2.HEADER_LENGTH);
    buf.fill(0);
    var smb2Msg = smb2Message.decode(buf);
    smb2Msg.protocolId = SMB2.PROTOCOL_ID;
    smb2Msg.header.flags.reply = true;
    smb2Msg.header.commandId = SMB2.STRING_TO_COMMAND['negotiate'];
    smb2Msg.header.creditReqRes = 1;

    var systemTime = utils.systemToSMBTime(Date.now());
    var startTime = utils.systemToSMBTime(server.getStartTime());
    var securityBuffer = utils.EMPTY_BUFFER;
    var out = put();
    out.word16le(0x0041)  // StructureSize (fixed according to spec)
      .word16le(0) // SecurityMode
      .word16le(SMB2.SMB_2_X_X) // DialectRevision
      .word16le(0)  // NegotiateContextCount/Reserved
      .put(server.getGuid())  // ServerGuid
      .word32le(0) // Capabilities
      .word32le(0x00100000) // MaxTransactSize
      .word32le(0x00100000) // MaxReadSize
      .word32le(0x00100000) // MaxWriteSize
      .word32le(systemTime.getLowBitsUnsigned())  // SystemTime
      .word32le(systemTime.getHighBitsUnsigned())
      .word32le(startTime.getLowBitsUnsigned())  // ServerStartTime
      .word32le(startTime.getHighBitsUnsigned())
      .word16le(SMB2.HEADER_LENGTH + 64)  // SecurityBufferOffset
      .word16le(securityBuffer.length)  // SecurityBufferLength
      .word32le(0)  // NegotiateContextOffset/Reserved2
      .put(securityBuffer); // SecurityBuffer
    smb2Msg.body = out.buffer();
    smb2.sendResponse(smb2Msg, ntstatus.STATUS_SUCCESS, connection, server, function (err) {
      if (err) {
        logger.error('failed to send SMB2 negotiate response', err);
      }
      // we've already handled sending the response ourselves, no further processing required by the caller
      cb(null);
    });
    return;
  }

  var idx = msg.dialects.indexOf(SMB.DIALECT_NT_LM_0_12);

  // send response

  if (idx === -1) {
    // couldn't agree on a dialect
    result = {
      status: ntstatus.STATUS_SUCCESS,
      params: new Buffer(2).writeUint16LE(0xffff),
      data: commandData
    };
    process.nextTick(function () { cb(result); });
    return;
  }

  var capabilities = SMB.CAP_STATUS32 | SMB.CAP_LEVEL2_OPLOCKS |
    SMB.CAP_NT_SMBS | SMB.CAP_NT_FIND |
    SMB.CAP_LARGE_FILES | SMB.CAP_UNICODE |
    SMB.CAP_INFOLEVEL_PASSTHRU | SMB.CAP_RPC_REMOTE_APIS |
    SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX |
    //SMB.CAP_LWIO |
    SMB.CAP_LOCK_AND_READ;

  var extendedSecurity = false;
  if (server.config.extendedSecurity) {
    if (msg.header.flags.security.extended) {
      capabilities |= SMB.CAP_EXTENDED_SECURITY;
      extendedSecurity = true;
    }
  }

  var login = server.createLogin();
  // fallback solution (if sessionKey is not transmitted in SMB header)
  connection.sessionKey = login.key;

  var params = new Buffer(2 * 17);
  var offset = 0;
  // DialectIndex
  params.writeUInt16LE(idx, offset);
  offset += 2;
  // SecurityMode
  params.writeUInt8(SMB.NEGOTIATE_USER_SECURITY | SMB.NEGOTIATE_ENCRYPT_PASSWORDS, offset);
  offset += 1;
  // MaxMpxCount
  params.writeUInt16LE(MAX_MPX_COUNT, offset);
  offset += 2;
  // MaxNumberVcs
  params.writeUInt16LE(MAX_NUMBER_VCS, offset);
  offset += 2;
  // MaxBufferSize
  //params.writeUInt32LE(consts.SMB_MAX_LENGTH, offset);
  params.writeUInt32LE(MAX_BUFFER_SIZE, offset);
  offset += 4;
  // MaxRawSize
  params.writeUInt32LE(MAX_RAW_SIZE, offset);
  offset += 4;
  // SessionKey
  params.writeUInt32LE(login.key, offset);
  offset += 4;
  // Capabilities
  params.writeInt32LE(capabilities, offset);
  offset += 4;
  // SystemTime
  var long = utils.systemToSMBTime(Date.now());
  params.writeUInt32LE(long.getLowBitsUnsigned(), offset);
  offset += 4;
  params.writeUInt32LE(long.getHighBitsUnsigned(), offset);
  offset += 4;
  // ServerTimeZone
  params.writeInt16LE(new Date().getTimezoneOffset(), offset);
  offset += 2;
  // ChallengeLength
  params.writeUInt8(extendedSecurity ? 0 : login.challenge.length, offset);

  var data;
  offset = 0;
  if (extendedSecurity) {
    // todo securityBlob: raw NTLMSSP (empty) or SPNEGO (NegotiateToken)?
    var securityBlob = utils.EMPTY_BUFFER;
    data = new Buffer(server.getGuid().length + securityBlob.length);
    // ServerGUID
    server.getGuid().copy(data, offset);
    offset += server.getGuid().length;
    // SecurityBlob
    securityBlob.copy(data, offset);
    offset += securityBlob.length;
  } else {
    var encDomain = new Buffer(server.domainName, 'utf16le');
    var encServer = new Buffer(server.hostName, 'utf16le');
    data = new Buffer(login.challenge.length + encDomain.length + 2 + encServer.length + 2);
    // Challenge
    login.challenge.copy(data, offset);
    offset += login.challenge.length;
    // DomainName
    encDomain.copy(data, offset);
    offset += encDomain.length;
    data.writeUInt16LE(0, offset);  // sting delimiter (0x0000)
    // ServerName
    encServer.copy(data, offset);
    offset += encServer.length;
    data.writeUInt16LE(0, offset);  // sting delimiter (0x0000)
  }

  // return result
  result = {
    status: ntstatus.STATUS_SUCCESS,
    params: params,
    data: data
  };
  process.nextTick(function () { cb(result); });
}

module.exports = handle;<|endoftext|>


<commit_before>var uuidModule = require('uuid');
var uuid = uuidModule.v4.bind(uuidModule);
var amqp = require('amqp'),
	_ = require('lodash'),
	q = require('q');

var DEFAULTS = {
	exclusive: false,
	autoDelete: false,
	durable: true
};

var Exchange = require('./exchange');
var badMessageExchange = new Exchange({
	name: 'bad_message'
});

function Queue(params){
	params = _.extend(Object.create(null), DEFAULTS, params);

	var name = params.name || uuid(),
		exchangeName = params.exchangeName,
		ctag;

	delete params.name;
	delete params.exchangeName;

	var queuePromise = _getConnection().then(_getQueue);

	function _getConnection(){
		var deferred = q.defer();
		var connection = amqp.createConnection({ host: '127.0.0.1' });
		connection.addListener('ready', deferred.resolve.bind(deferred, connection));

		return deferred.promise;
	}

	function _getQueue(connection){
		var d = q.defer();

		connection.queue(name, params, function(queue){
			d.resolve(queue);
		});

		return d.promise;
	}

	function doBind(fn, theQueue){
		theQueue.bind(exchangeName, '#');

		theQueue.subscribe({ack:true}, function (message) {
			var metadata = message.wabbittzzz;
			var doneCalled = false;

			delete message.wabbittzzz;

			var done = function(error){
				doneCalled = true;

				if (!error){
					return theQueue.shift();
				}

				global.logger.error(error);

				if (metadata){
					message.wabbittzzz = metadata;
					metadata.attempts += 1;

					if (metadata.attempts > 2){
						// if this is the 3rd failure
						// then remove the message from the queue
						// and push to the bad message exchange.

						theQueue.shift();
						badMessageExchange.publish(message, {persistent:true});
						return;
					}
				}
				else {
					message.wabbittzzz = { attempts: 1 };
				}

				// put the message back on the queue
				theQueue.shift(true, true);
			};

			try {
				fn(message, done);
			} catch (e){
				if (!doneCalled){
					done(e.toString());
				}
			}
		}).addCallback(function(res){
			ctag = res.consumerTag;
		});
	}

	var receieveFunc = function(fn){
		queuePromise
			.then(function(queue){
				doBind(fn, queue);
			});
	};

	receieveFunc.stop = function(){
		queuePromise
			.then(function(queue){
				if (!ctag) return;

				queue.unsubscribe(ctag);
			});
	};
	return receieveFunc;
}

module.exports = Queue;

<commit_msg>allow binding to happen before we are subscribed<commit_after>var uuidModule = require('uuid');
var uuid = uuidModule.v4.bind(uuidModule);
var amqp = require('amqp'),
	_ = require('lodash'),
	q = require('q');

var DEFAULTS = {
	exclusive: false,
	autoDelete: false,
	durable: true
};

var Exchange = require('./exchange');
var badMessageExchange = new Exchange({
	name: 'bad_message'
});

function Queue(params){
	params = _.extend(Object.create(null), DEFAULTS, params);

	var name = params.name || uuid(),
		exchangeName = params.exchangeName,
		ctag;

	delete params.name;
	delete params.exchangeName;

	var queuePromise = _getConnection().then(_getQueue);

	function _getConnection(){
		var deferred = q.defer();
		var connection = amqp.createConnection({ host: '127.0.0.1' });
		connection.addListener('ready', deferred.resolve.bind(deferred, connection));

		return deferred.promise;
	}

	function _getQueue(connection){
		var d = q.defer();

		connection.queue(name, params, function(queue){
			d.resolve(queue);
		});

		return d.promise;
	}

	queuePromise
		.then(function(queue){
			queue.bind(exchangeName, '#');
		});

	var receieveFunc = function(fn){
		queuePromise
			.then(function(queue){
				queue.subscribe({ack:true}, function (message) {
					var doneCalled = false;

					var done = function(error){
						doneCalled = true;

						if (!error){
							return queue.shift();
						}

						global.logger.error(error);

						// put the message back on the queue
						queue.shift(true, true);
					};

					try {
						fn(message, done);
					} catch (e){
						if (!doneCalled){
							done(e.toString());
						}
					}
				}).addCallback(function(res){
					ctag = res.consumerTag;
				});
			});
	};

	receieveFunc.stop = function(){
		queuePromise
			.then(function(queue){
				if (!ctag) return;

				queue.unsubscribe(ctag);
			});
	};

	return receieveFunc;
}

module.exports = Queue;

<|endoftext|>


<commit_before>var gameCount=0;
//count number of times when user click start button
function startGame(){

      gameCount++;
      document.getElementById("keytoRace").style.visibility="visible";
      var playerStrip = document.querySelectorAll('tr')

         if(gameCount<=1) {
            //creating track length
            trackLength = prompt("How many km required for you to escape from the city?")

               for (var i = 0; i < playerStrip.length; i++) {
                    for ( var j = 0; j < trackLength; j++){
                        var trackColoumn = document.createElement('td')
                        playerStrip[i].appendChild(trackColoumn)
                     }
                  }
               }
       //when user want new game while progressing the current
         else if(gameCount>1) {

               location.reload();
               alert("Oops!! you want to start a new game");
               alert("Click again on Start button for new game");
                }
           }

  document.addEventListener('DOMContentLoaded', function() {

          document.getElementById("keytoRace").style.visibility="hidden";
          var playerStrip = document.querySelectorAll('tr')
          player1Strip = document.querySelectorAll('#player1_strip td')
          document.addEventListener('keyup', udatePlayerPosition);

          var pCount=0;
          var qCount=0

          function udatePlayerPosition(e) {

               //when user release 'p' key
               if (event.which ===80) {
               pCount++;

                     if(pCount<=trackLength){

                            var j=pCount;
                            player1Strip = document.querySelectorAll('#player1_strip td')
                            player1Strip[j].className="active";
                            player1Strip[j-1].className="";
                            trackSpeed()
                      }
                     //when 'p' reaches finish point
                    if(pCount>trackLength && pCount>qCount) {

                            player2Strip = document.querySelectorAll('#player2_strip td');
                            document.getElementById("trackEsc").innerHTML="HURRAY! P ESCAPED FROM CITY";
                            document.getElementById("pChaseTrack").style.visibility="hidden";
                            document.getElementById("qChaseTrack").style.visibility="hidden";
                            document.getElementById("trackEsc").style.visibility="visible";
                            alert("BRAVE! P ESCAPED!");
                            pageReload();
                   }
             }
           //when user release 'q' key
               else if (event.which ===81) {
               qCount++;

                       if(qCount<=trackLength) {

                             var j=qCount;
                             player2Strip = document.querySelectorAll('#player2_strip td')
                             player2Strip[j].className="active";
                             player2Strip[j-1].className="";
                             trackSpeed()
                     }
                   //when 'q' reaches finish point
                    if(qCount>trackLength && qCount>pCount) {

                             player1Strip = document.querySelectorAll('#player1_strip td')
                             var win2=document.getElementById("trackEsc").innerHTML="HURRAY! Q ESCAPED FROM CITY";
                             document.getElementById("trackEsc").innerHTML="HURRAY! Q ESCAPED FROM CITY";
                             document.getElementById("pChaseTrack").style.visibility="hidden";
                             document.getElementById("qChaseTrack").style.visibility="hidden";
                             document.getElementById("trackEsc").style.visibility="visible";
                             alert("BRAVE! Q ESCAPED!");
                             pageReload();
                    }
              }
          trackSpeed()
      }
         function trackSpeed() {

               var x=document.getElementsByClassName("active");
               //when p chase faster than q
                    if(pCount>qCount) {

                             document.getElementById("pChaseTrack").innerHTML="P IS CHASING";
                             document.getElementById("qChaseTrack").innerHTML="";
                             document.getElementById("trackEsc").style.visibility="hidden";
                    }
                //when q chase faster than p
                     if(qCount>pCount) {

                             document.getElementById("qChaseTrack").innerHTML="Q IS CHASING";
                             document.getElementById("pChaseTrack").innerHTML="";
                             document.getElementById("trackEsc").style.visibility="hidden";
                   }
                 }
             //when user finish game and starts new game
          function pageReload() {

                             document.getElementById("trackEsc").style.visibility="visible";
                             document.getElementById("pChaseTrack").style.visibility="hidden";
                             document.getElementById("qChaseTrack").style.visibility="hidden";

                             alert("Click on start new game button to start a new game");
                             location.reload();

                             document.getElementById("player1_strip").style.visibility="hidden";
                             document.getElementById("player2_strip").style.visibility="hidden";
                             document.getElementById("pChaseTrack").style.visibility="hidden";
                             document.getElementById("qChaseTrack").style.visibility="hidden";
                             document.getElementById("startBtn").style.visibility="visible";
                             document.getElementById("car3").style.visibility="visible";
                             document.getElementById("car4").style.visibility="visible";

                             player1Strip[0].className="active";
                             player2Strip[0].className="active";
                }
          })
<commit_msg>tidy up indentation remove extra space<commit_after>var gameCount=0;
//count number of times when user click start button
function startGame(){

      gameCount++;
      document.getElementById("keytoRace").style.visibility="visible";
      var playerStrip = document.querySelectorAll('tr')

         if(gameCount<=1) {
            //creating track length
            trackLength = prompt("How many km required for you to escape from the city?")

               for (var i = 0; i < playerStrip.length; i++) {
                    for ( var j = 0; j < trackLength; j++){
                        var trackColoumn = document.createElement('td')
                        playerStrip[i].appendChild(trackColoumn)
                     }
                  }
               }
       //when user want new game while progressing the current
         else if(gameCount>1) {

               location.reload();
               alert("Oops!! you want to start a new game");
               alert("Click again on Start button for new game");
                }
           }

  document.addEventListener('DOMContentLoaded', function() {

          document.getElementById("keytoRace").style.visibility="hidden";
          var playerStrip = document.querySelectorAll('tr')
          player1Strip = document.querySelectorAll('#player1_strip td')
          document.addEventListener('keyup', udatePlayerPosition);

          var pCount=0;
          var qCount=0

          function udatePlayerPosition(e) {

               //when user release 'p' key
               if (event.which ===80) {
               pCount++;

                     if(pCount<=trackLength){

                            var j=pCount;
                            player1Strip = document.querySelectorAll('#player1_strip td')
                            player1Strip[j].className="active";
                            player1Strip[j-1].className="";
                            trackSpeed()
                      }
                     //when 'p' reaches finish point
                    if(pCount>trackLength && pCount>qCount) {

                            player2Strip = document.querySelectorAll('#player2_strip td');
                            document.getElementById("trackEsc").innerHTML="HURRAY! P ESCAPED FROM CITY";
                            document.getElementById("pChaseTrack").style.visibility="hidden";
                            document.getElementById("qChaseTrack").style.visibility="hidden";
                            document.getElementById("trackEsc").style.visibility="visible";
                            alert("BRAVE! P ESCAPED!");
                            pageReload();
                   }
             }
               //when user release 'q' key
               else if (event.which ===81) {
               qCount++;

                       if(qCount<=trackLength) {

                             var j=qCount;
                             player2Strip = document.querySelectorAll('#player2_strip td')
                             player2Strip[j].className="active";
                             player2Strip[j-1].className="";
                             trackSpeed()
                     }
                     //when 'q' reaches finish point
                    if(qCount>trackLength && qCount>pCount) {

                             player1Strip = document.querySelectorAll('#player1_strip td')
                             var win2=document.getElementById("trackEsc").innerHTML="HURRAY! Q ESCAPED FROM CITY";
                             document.getElementById("trackEsc").innerHTML="HURRAY! Q ESCAPED FROM CITY";
                             document.getElementById("pChaseTrack").style.visibility="hidden";
                             document.getElementById("qChaseTrack").style.visibility="hidden";
                             document.getElementById("trackEsc").style.visibility="visible";
                             alert("BRAVE! Q ESCAPED!");
                             pageReload();
                    }
              }
          trackSpeed()
      }
         function trackSpeed() {

               var x=document.getElementsByClassName("active");
               //when p chase faster than q
                    if(pCount>qCount) {

                             document.getElementById("pChaseTrack").innerHTML="P IS CHASING";
                             document.getElementById("qChaseTrack").innerHTML="";
                             document.getElementById("trackEsc").style.visibility="hidden";
                    }
                //when q chase faster than p
                     if(qCount>pCount) {

                             document.getElementById("qChaseTrack").innerHTML="Q IS CHASING";
                             document.getElementById("pChaseTrack").innerHTML="";
                             document.getElementById("trackEsc").style.visibility="hidden";
                   }
                 }
             //when user finish game and starts new game
          function pageReload() {

                             document.getElementById("trackEsc").style.visibility="visible";
                             document.getElementById("pChaseTrack").style.visibility="hidden";
                             document.getElementById("qChaseTrack").style.visibility="hidden";

                             alert("Click on start new game button to start a new game");
                             location.reload();

                             document.getElementById("player1_strip").style.visibility="hidden";
                             document.getElementById("player2_strip").style.visibility="hidden";
                             document.getElementById("pChaseTrack").style.visibility="hidden";
                             document.getElementById("qChaseTrack").style.visibility="hidden";
                             document.getElementById("startBtn").style.visibility="visible";
                             document.getElementById("car3").style.visibility="visible";
                             document.getElementById("car4").style.visibility="visible";

                             player1Strip[0].className="active";
                             player2Strip[0].className="active";
                }
          })
<|endoftext|>


<commit_before>var sizeof = require('object-sizeof');
var weatherDB = require("./data/weatherDB");
var cppMsg = require('./node_modules/cppmsg/cppMsg.js');
var reverse = require("buffer-reverse");

//Test code, remove when complete
var response = {
        SleepTime: 10,
        LightningIndoors: false,
        LightningTune: 0,
        LightningNoiseFloor: 4,
        RadioPower: 2,
        SystemReset: 0
};

var weatherdatamsg = new cppMsg.msg(
	[
		['MessageType', 'int8'],
		['Temperature', 'int16'],
		['Humidty', 'int16'],
		['BaroPressure', 'int16'],
		['BaroTemperature', 'int16'],
		['Lux', 'uint16']
	]
);

var lightningMsg = new cppMsg.msg(
	[
		['MessageType', 'int8'],
		['EventType', 'int16'],
		['Distance', 'int16'],
		['Intensity', 'int16']
	]
);

var weathercontrolmsg = new cppMsg.msg(
	[
		['SleepTime', 'int16'],
		['LightningIndoors', 'bool'],
		['LightningTune', 'int16'],
		['LightningNoiseFloor', 'int16'],
		['RadioPower', 'int16'],
		['SystemReset', 'bool']
	]
);

var socket = require('socket.io-client')('http://localhost:3000');

var NRF24 = require('nrf'),
	spiDev = "/dev/spidev0.0",
	cePin = 24,
	irqPin = 25, //var ce = require("./gpio").connect(cePin)
	pipes = [0xF0F0F0F0E1, 0xF0F0F0F0D2];
var nrf = NRF24.connect(spiDev, cePin, irqPin);
//nrf._debug = true;
nrf.channel(0x4c); // Set channel to 76
nrf.transmitPower('PA_MAX');
nrf.dataRate('1Mbps') // Set data rate to 1Mbps
nrf.crcBytes(2) // Set the CRC to 2
nrf.autoRetransmit({
	count: 500,
	delay: 15
});
nrf.begin(function() {
	console.log("Radio recevier listening.");
	var rx = nrf.openPipe('rx', pipes[1]),
		tx = nrf.openPipe('tx', pipes[0]);

	rx.on('data', function(d) {

                var responseBuf = reverse(weathercontrolmsg.encodeMsg(response));
	        console.log(sizeof(responseBuf));
		tx.write(responseBuf,12);

		var typeCode = reverse(d).readUIntBE(0, 1);;
		console.log(typeCode);

		if (typeCode === 1) {
			var data = weatherdatamsg.decodeMsg(reverse(d));
			console.log(data);
			data.SampleDate = new Date();
			weatherDB.insertWeather(data, function(currentDate) {
				socket.emit('weather message', data);
			});

		}
		else if(typeCode === 2) {
			var data = lightningMsg.decodeMsg(reverse(d));
			console.log(data);
			weatherDB.insertLightning(data, () => {
                                        socket.emit('lightning message', data);
				});
		}
		else{
				console.warn("No suitable struct found for decode.");
		}

	});
	tx.on('error', function(e) {
		console.warn("Error sending reply.", e);
		process.exit();
	});
	tx.on('error', function(e) {
		console.warn("Error sending reply.", e);
		process.exit();
	});
});
<commit_msg>removed some consolelogs<commit_after>var sizeof = require('object-sizeof');
var weatherDB = require("./data/weatherDB");
var cppMsg = require('./node_modules/cppmsg/cppMsg.js');
var reverse = require("buffer-reverse");

//Test code, remove when complete
var response = {
        SleepTime: 10,
        LightningIndoors: false,
        LightningTune: 0,
        LightningNoiseFloor: 4,
        RadioPower: 2,
        SystemReset: 0
};

var weatherdatamsg = new cppMsg.msg(
	[
		['MessageType', 'int8'],
		['Temperature', 'int16'],
		['Humidty', 'int16'],
		['BaroPressure', 'int16'],
		['BaroTemperature', 'int16'],
		['Lux', 'uint16']
	]
);

var lightningMsg = new cppMsg.msg(
	[
		['MessageType', 'int8'],
		['EventType', 'int16'],
		['Distance', 'int16'],
		['Intensity', 'int16']
	]
);

var weathercontrolmsg = new cppMsg.msg(
	[
		['SleepTime', 'int16'],
		['LightningIndoors', 'bool'],
		['LightningTune', 'int16'],
		['LightningNoiseFloor', 'int16'],
		['RadioPower', 'int16'],
		['SystemReset', 'bool']
	]
);

var socket = require('socket.io-client')('http://localhost:3000');

var NRF24 = require('nrf'),
	spiDev = "/dev/spidev0.0",
	cePin = 24,
	irqPin = 25, //var ce = require("./gpio").connect(cePin)
	pipes = [0xF0F0F0F0E1, 0xF0F0F0F0D2];
var nrf = NRF24.connect(spiDev, cePin, irqPin);
//nrf._debug = true;
nrf.channel(0x4c); // Set channel to 76
nrf.transmitPower('PA_MAX');
nrf.dataRate('1Mbps') // Set data rate to 1Mbps
nrf.crcBytes(2) // Set the CRC to 2
nrf.autoRetransmit({
	count: 500,
	delay: 15
});
nrf.begin(function() {
	console.log("Radio recevier listening.");
	var rx = nrf.openPipe('rx', pipes[1]),
		tx = nrf.openPipe('tx', pipes[0]);

	rx.on('data', function(d) {

                var responseBuf = reverse(weathercontrolmsg.encodeMsg(response));
//	        console.log(sizeof(responseBuf));
		tx.write(responseBuf,12);

		var typeCode = reverse(d).readUIntBE(0, 1);;
//		console.log(typeCode);

		if (typeCode === 1) {
			var data = weatherdatamsg.decodeMsg(reverse(d));
			console.log(data);
			data.SampleDate = new Date();
			weatherDB.insertWeather(data, function(currentDate) {
				socket.emit('weather message', data);
			});

		}
		else if(typeCode === 2) {
			var data = lightningMsg.decodeMsg(reverse(d));
			console.log(data);
			weatherDB.insertLightning(data, () => {
                                        socket.emit('lightning message', data);
				});
		}
		else{
				console.warn("No suitable struct found for decode.");
		}

	});
	tx.on('error', function(e) {
		console.warn("Error sending reply.", e);
		process.exit();
	});
	tx.on('error', function(e) {
		console.warn("Error sending reply.", e);
		process.exit();
	});
});
<|endoftext|>


<commit_before>var compiler = require('vue-template-compiler')
var transpile = require('vue-template-es2015-compiler')
var loaderUtils = require('loader-utils')
var beautify = require('js-beautify').js_beautify
var normalize = require('./normalize')
var hotReloadAPIPath = normalize.dep('vue-hot-reload-api')

// vue compiler module for using transforming `<tag>:<attribute>` to `require`
var defaultTransformToRequire = {
  img: 'src',
  image: 'xlink:href'
}
var transformToRequire = defaultTransformToRequire
var defaultCompileOptions = {
  modules: [{
    postTransformNode (el) {
      for (var tag in transformToRequire) {
        if (el.tag === tag && el.attrs) {
          var attributes = transformToRequire[tag]
          if (typeof attributes === 'string') {
            el.attrs.some(attr => rewrite(attr, attributes))
          } else if (Array.isArray(attributes)) {
            attributes.forEach(item => el.attrs.some(attr => rewrite(attr, item)))
          }
        }
      }
    }
  }]
}

function rewrite (attr, name) {
  if (attr.name === name) {
    var value = attr.value
    var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"'
    if (!isStatic) {
      return
    }
    var firstChar = value.charAt(1)
    if (firstChar === '.' || firstChar === '~') {
      if (firstChar === '~') {
        value = '"' + value.slice(2)
      }
      attr.value = `require(${value})`
    }
    return true
  }
}

module.exports = function (html) {
  this.cacheable()
  var isProduction = this.minimize || process.env.NODE_ENV === 'production'
  var query = loaderUtils.parseQuery(this.query)
  var isServer = this.options.target === 'node'
  var vueOptions = this.options.__vueOptions__
  if (vueOptions.transformToRequire) {
    transformToRequire = Object.assign(
      {},
      defaultTransformToRequire,
      vueOptions.transformToRequire
    )
  }
  var compiled = compiler.compile(html, Object.assign({
    preserveWhitespace: vueOptions.preserveWhitespace
  }, defaultCompileOptions))
  var code
  if (compiled.errors.length) {
    var self = this
    compiled.errors.forEach(function (err) {
      self.emitError('\n  Vue template syntax error:\n\n  ' + err + '\n')
    })
    code = 'module.exports={render:function(){},staticRenderFns:[]}'
  } else {
    var bubleOptions = vueOptions.buble
    code = transpile('module.exports={' +
      'render:' + toFunction(compiled.render) + ',' +
      'staticRenderFns: [' + compiled.staticRenderFns.map(toFunction).join(',') + ']' +
    '}', bubleOptions)
    // mark with stripped (this enables Vue to use correct runtime proxy detection)
    if (!isProduction && (
      !bubleOptions ||
      !bubleOptions.transforms ||
      bubleOptions.transforms.stripWith !== false
    )) {
      code += `\nmodule.exports.render._withStripped = true`
    }
  }
  // hot-reload
  if (!isServer &&
      !this.minimize &&
      process.env.NODE_ENV !== 'production') {
    code +=
      '\nif (module.hot) {\n' +
      '  module.hot.accept()\n' +
      '  if (module.hot.data) {\n' +
      '     require("' + hotReloadAPIPath + '").rerender("' + query.id + '", module.exports)\n' +
      '  }\n' +
      '}'
  }
  return code
}

function toFunction (code) {
  return 'function (){' + beautify(code, {
    indent_size: 2 // eslint-disable-line camelcase
  }) + '}'
}
<commit_msg>tweak parser warning output<commit_after>var compiler = require('vue-template-compiler')
var transpile = require('vue-template-es2015-compiler')
var loaderUtils = require('loader-utils')
var beautify = require('js-beautify').js_beautify
var normalize = require('./normalize')
var hotReloadAPIPath = normalize.dep('vue-hot-reload-api')

// vue compiler module for using transforming `<tag>:<attribute>` to `require`
var defaultTransformToRequire = {
  img: 'src',
  image: 'xlink:href'
}
var transformToRequire = defaultTransformToRequire
var defaultCompileOptions = {
  modules: [{
    postTransformNode (el) {
      for (var tag in transformToRequire) {
        if (el.tag === tag && el.attrs) {
          var attributes = transformToRequire[tag]
          if (typeof attributes === 'string') {
            el.attrs.some(attr => rewrite(attr, attributes))
          } else if (Array.isArray(attributes)) {
            attributes.forEach(item => el.attrs.some(attr => rewrite(attr, item)))
          }
        }
      }
    }
  }]
}

function rewrite (attr, name) {
  if (attr.name === name) {
    var value = attr.value
    var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"'
    if (!isStatic) {
      return
    }
    var firstChar = value.charAt(1)
    if (firstChar === '.' || firstChar === '~') {
      if (firstChar === '~') {
        value = '"' + value.slice(2)
      }
      attr.value = `require(${value})`
    }
    return true
  }
}

module.exports = function (html) {
  this.cacheable()
  var isProduction = this.minimize || process.env.NODE_ENV === 'production'
  var query = loaderUtils.parseQuery(this.query)
  var isServer = this.options.target === 'node'
  var vueOptions = this.options.__vueOptions__
  if (vueOptions.transformToRequire) {
    transformToRequire = Object.assign(
      {},
      defaultTransformToRequire,
      vueOptions.transformToRequire
    )
  }
  var compiled = compiler.compile(html, Object.assign({
    preserveWhitespace: vueOptions.preserveWhitespace
  }, defaultCompileOptions))
  var code
  if (compiled.errors.length) {
    this.emitError(
      `\n  Error compiling template:\n${pad(html)}\n` +
      compiled.errors.map(e => `  - ${e}`).join('\n') + '\n'
    )
    code = 'module.exports={render:function(){},staticRenderFns:[]}'
  } else {
    var bubleOptions = vueOptions.buble
    code = transpile('module.exports={' +
      'render:' + toFunction(compiled.render) + ',' +
      'staticRenderFns: [' + compiled.staticRenderFns.map(toFunction).join(',') + ']' +
    '}', bubleOptions)
    // mark with stripped (this enables Vue to use correct runtime proxy detection)
    if (!isProduction && (
      !bubleOptions ||
      !bubleOptions.transforms ||
      bubleOptions.transforms.stripWith !== false
    )) {
      code += `\nmodule.exports.render._withStripped = true`
    }
  }
  // hot-reload
  if (!isServer &&
      !this.minimize &&
      process.env.NODE_ENV !== 'production') {
    code +=
      '\nif (module.hot) {\n' +
      '  module.hot.accept()\n' +
      '  if (module.hot.data) {\n' +
      '     require("' + hotReloadAPIPath + '").rerender("' + query.id + '", module.exports)\n' +
      '  }\n' +
      '}'
  }
  return code
}

function toFunction (code) {
  return 'function (){' + beautify(code, {
    indent_size: 2 // eslint-disable-line camelcase
  }) + '}'
}

function pad (html) {
  return html.split(/\r?\n/).map(line => `  ${line}`).join('\n')
}
<|endoftext|>