'use strict';// hgetall converts its replies to an Object. If the reply is empty, null is returned.// These function are only called with internal data and have therefore always the same instanceof Xfunction replyToObject (reply) {    // The reply might be a string or a buffer if this is called in a transaction (multi)    if (reply.length === 0 || !(reply instanceof Array)) {        return null;    }    var obj = {};    for (var i = 0; i < reply.length; i += 2) {        obj[reply[i].toString('binary')] = reply[i + 1];    }    return obj;}function replyToStrings (reply) {    if (reply instanceof Buffer) {        return reply.toString();    }    if (reply instanceof Array) {        var res = new Array(reply.length);        for (var i = 0; i < reply.length; i++) {            // Recusivly call the function as slowlog returns deep nested replies            res[i] = replyToStrings(reply[i]);        }        return res;    }    return reply;}function print (err, reply) {    if (err) {        // A error always begins with Error:        console.log(err.toString());    } else {        console.log('Reply: ' + reply);    }}var camelCase;// Deep clone arbitrary objects with arrays. Can't handle cyclic structures (results in a range error)// Any attribute with a non primitive value besides object and array will be passed by reference (e.g. Buffers, Maps, Functions)// All capital letters are going to be replaced with a lower case letter and a underscore infront of itfunction clone (obj) {    var copy;    if (Array.isArray(obj)) {        copy = new Array(obj.length);        for (var i = 0; i < obj.length; i++) {            copy[i] = clone(obj[i]);        }        return copy;    }    if (Object.prototype.toString.call(obj) === '[object Object]') {        copy = {};        var elems = Object.keys(obj);        var elem;        while (elem = elems.pop()) {            if (elem === 'tls') { // special handle tls                copy[elem] = obj[elem];                continue;            }            // Accept camelCase options and convert them to snake_case            var snake_case = elem.replace(/[A-Z][^A-Z]/g, '_$&').toLowerCase();            // If camelCase is detected, pass it to the client, so all variables are going to be camelCased            // There are no deep nested options objects yet, but let's handle this future proof            if (snake_case !== elem.toLowerCase()) {                camelCase = true;            }            copy[snake_case] = clone(obj[elem]);        }        return copy;    }    return obj;}function convenienceClone (obj) {    camelCase = false;    obj = clone(obj) || {};    if (camelCase) {        obj.camel_case = true;    }    return obj;}function callbackOrEmit (self, callback, err, res) {    if (callback) {        callback(err, res);    } else if (err) {        self.emit('error', err);    }}function replyInOrder (self, callback, err, res, queue) {    // If the queue is explicitly passed, use that, otherwise fall back to the offline queue first,    // as there might be commands in both queues at the same time    var command_obj;    /* istanbul ignore if: TODO: Remove this as soon as we test Redis 3.2 on travis */    if (queue) {        command_obj = queue.peekBack();    } else {        command_obj = self.offline_queue.peekBack() || self.command_queue.peekBack();    }    if (!command_obj) {        process.nextTick(function () {            callbackOrEmit(self, callback, err, res);        });    } else {        var tmp = command_obj.callback;        command_obj.callback = tmp ?            function (e, r) {                tmp(e, r);                callbackOrEmit(self, callback, err, res);            } :            function (e, r) {                if (e) {                    self.emit('error', e);                }                callbackOrEmit(self, callback, err, res);            };    }}module.exports = {    reply_to_strings: replyToStrings,    reply_to_object: replyToObject,    print: print,    err_code: /^([A-Z]+)\s+(.+)$/,    // BUG: NVD-CWE-Other Other    // monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]+ .+\]( ".+?")+$/,    // FIXED:    monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]+ .+\].*"$/,    clone: convenienceClone,    callback_or_emit: callbackOrEmit,    reply_in_order: replyInOrder};