<commit_before>const lodash = require('lodash');

macro delegate {
    rule { $property:ident $method:ident } => {
        function () {
            this . $property . $method . apply (this . $property , arguments);
            return this;
        }
    }
}

const defaultFactoryConfiguration = {
    'NetSocket' : require('net').Socket,
    'IrcSocket' : require('irc-socket'),
    'IrcOutputSocket' : require('./output-socket.js'),
    'MessageHandler' : require('./message-handler.js'),
    'CommandHandler' : require('./command-handler.js'),
    'Plugins' : require('tennu-plugins'),
    'BiSubscriber' : require('./bisubscriber.js'),
    'Logger': require('./null-logger.js'),
    'NicknameTracker': require('./nickname-tracker.js')
};

const defaultClientConfiguration = {
    // IrcSocket Config
    'server': undefined,
    'port': 6667,
    'ipv6': undefined,
    'localAddress': undefined,
    'secure': false,
    'password': <PASSWORD>,
    'capab': false,
    'nickname': 'tennubot',
    'username': 'tennu',
    'realname': 'tennu 0.9.x',

    // Tennu Config
    'channels': [],
    'nickserv': 'nickserv',
    'auth-password': <PASSWORD>,
    'plugins': [],
    'command-trigger': '!',
    'disable-help': false
};

/** Fields
 * _config
 * _socket
 * _logger
 * out      (_outputSocket)
 * events   (_subscriber)
 * plugins  (_plugins)
 * nickname (_nickname)
 */
 const Client = function (config, dependencies) {
    if (config.nick || config.user) {
        throw new Error('Please use \'nickname\' and \'username\' instead of \'nick\' and \'user\' in your configuration.');
    }

    const client = Object.create(Client.prototype);

    // Parse the configuration object. Make it immutable.
    client._config = config = Object.freeze(lodash.defaults({}, config, defaultClientConfiguration));
    di = lodash.defaults({}, dependencies || {}, defaultFactoryConfiguration);

    // Create a logger.
    // Default logger is a bunch of NOOPs.
    client._logger = new di.Logger();

    // The socket reads and sends messages from/to the IRC server.
    client._socket = new di.IrcSocket(config, di.NetSocket);

    // Create the listener to the socket.
    // This listener will parse the raw messages of the socket, and
    // emits specific events to listen to.
    client._messageHandler = new di.MessageHandler(client, client._logger, client._socket);

    // Create the object that tracks the nickname of the client.
    // Because this object is a function, it is expected that
    // the factory function does not use `this`.
    client._nickname = di.NicknameTracker(config.nickname, client._messageHandler);

    // The output socket wraps the `raw` method of the client._socket.
    client._outputSocket = new di.IrcOutputSocket(client._socket, client._messageHandler, client._nickname, client._logger);

    // Create the listener to private messages from the IRCMessageEmitter
    // The commander will parse these private messages for commands, and
    // emit those commands, also parsed.
    const commandHandler = new di.CommandHandler(config, client, client._nickname, client._logger);

    // The subscriber handles event subscriptions to the Client object,
    // determining whether they should be handled by the IrcMessageEmitter
    // or the Command Handler.
    client._subscriber = new di.BiSubscriber(client._messageHandler, commandHandler);
    client._subscriber.on('privmsg', function (privmsg) { commandHandler.parse(privmsg); });

    // And finally, the module system.
    client._plugins = new di.Plugins('tennu', client);
    client._plugins.addHook('handlers', function (module, handlers) {
        client._subscriber.on(handlers);
    });
    client.note('Tennu', 'Loading default plugins');
    client._plugins.use(['server', 'help', 'user', 'channel', 'startup'], __dirname);
    client.note('Tennu', 'Loading your plugins');
    client._plugins.use(config.plugins || [], process.cwd());


    client.out = client._outputSocket;
    client.events = client._subscriber;
    client.plugins = client._plugins;
    client.nickname = client._nickname;

    client.connected = false;

    client.note('Tennu', 'Client created.');
    return client;
};

// implements ConfigurationStorage

Client.prototype.config = function (param) {
    return this._config[param];
};

// implements Runnable ;)

const connect = function () {
    this.debug('Tennu', 'Trying to connect.');

    if (this.connected) {
        this.warn('Tennu', 'Attempted to start Tennu Client that already is connected.');
        return;
    }

    this._socket.connect();
    this.connected = true;
    this.debug('Tennu', 'Connected');
    return this;
}

Client.prototype.connect = connect;
Client.prototype.start = connect;

const disconnect = function () {
    this.debug('Tennu', 'Trying to disconnect.');

    if (!this.connected) {
        this.warn('Tennu', 'Attempted to end Tennu Client that already is not connected.');
        return this;
    }

    this._socket.end();
    this.connected = false;
    this.debug('Tennu', 'Disconnected');
    return this;
};

Client.prototype.disconnect = disconnect;
Client.prototype.end = disconnect;

// implements IRC Output Socket

Client.prototype.say                    = delegate _outputSocket say;<commit_msg>Grab version from package.json, single quotes to double quotes in client.js<commit_after>const lodash = require("lodash");
const packagejson = require("../package.json")[""]

macro delegate {
    rule { $property:ident $method:ident } => {
        function () {
            this . $property . $method . apply (this . $property , arguments);
            return this;
        }
    }
}

const defaultFactoryConfiguration = {
    "NetSocket" : require("net").Socket,
    "IrcSocket" : require("irc-socket"),
    "IrcOutputSocket" : require("./output-socket.js"),
    "MessageHandler" : require("./message-handler.js"),
    "CommandHandler" : require("./command-handler.js"),
    "Plugins" : require("tennu-plugins"),
    "BiSubscriber" : require("./bisubscriber.js"),
    "Logger": require("./null-logger.js"),
    "NicknameTracker": require("./nickname-tracker.js")
};

const defaultClientConfiguration = {
    // IrcSocket Config
    "server": undefined,
    "port": 6667,
    "ipv6": undefined,
    "localAddress": undefined,
    "secure": false,
    "password": <PASSWORD>,
    "capab": false,
    "nickname": "tennubot",
    "username": "tennu",
    "realname": "tennu " + require("../package.json")["version"],

    // Tennu Config
    "channels": [],
    "nickserv": "nickserv",
    "auth-password": undefined,
    "plugins": [],
    "command-trigger": "!",
    "disable-help": false
};

/** Fields
 * _config
 * _socket
 * _logger
 * out      (_outputSocket)
 * events   (_subscriber)
 * plugins  (_plugins)
 * nickname (_nickname)
 */
 const Client = function (config, dependencies) {
    if (config.nick || config.user) {
        throw new Error("Please use \"nickname\" and \"username\" instead of \"nick\" and \"user\" in your configuration.");
    }

    const client = Object.create(Client.prototype);

    // Parse the configuration object. Make it immutable.
    client._config = config = Object.freeze(lodash.defaults({}, config, defaultClientConfiguration));
    di = lodash.defaults({}, dependencies || {}, defaultFactoryConfiguration);

    // Create a logger.
    // Default logger is a bunch of NOOPs.
    client._logger = new di.Logger();

    // The socket reads and sends messages from/to the IRC server.
    client._socket = new di.IrcSocket(config, di.NetSocket);

    // Create the listener to the socket.
    // This listener will parse the raw messages of the socket, and
    // emits specific events to listen to.
    client._messageHandler = new di.MessageHandler(client, client._logger, client._socket);

    // Create the object that tracks the nickname of the client.
    // Because this object is a function, it is expected that
    // the factory function does not use `this`.
    client._nickname = di.NicknameTracker(config.nickname, client._messageHandler);

    // The output socket wraps the `raw` method of the client._socket.
    client._outputSocket = new di.IrcOutputSocket(client._socket, client._messageHandler, client._nickname, client._logger);

    // Create the listener to private messages from the IRCMessageEmitter
    // The commander will parse these private messages for commands, and
    // emit those commands, also parsed.
    const commandHandler = new di.CommandHandler(config, client, client._nickname, client._logger);

    // The subscriber handles event subscriptions to the Client object,
    // determining whether they should be handled by the IrcMessageEmitter
    // or the Command Handler.
    client._subscriber = new di.BiSubscriber(client._messageHandler, commandHandler);
    client._subscriber.on("privmsg", function (privmsg) { commandHandler.parse(privmsg); });

    // And finally, the module system.
    client._plugins = new di.Plugins("tennu", client);
    client._plugins.addHook("handlers", function (module, handlers) {
        client._subscriber.on(handlers);
    });
    client.note("Tennu", "Loading default plugins");
    client._plugins.use(["server", "help", "user", "channel", "startup"], __dirname);
    client.note("Tennu", "Loading your plugins");
    client._plugins.use(config.plugins || [], process.cwd());


    client.out = client._outputSocket;
    client.events = client._subscriber;
    client.plugins = client._plugins;
    client.nickname = client._nickname;

    client.connected = false;

    client.note("Tennu", "Client created.");
    return client;
};

// implements ConfigurationStorage

Client.prototype.config = function (param) {
    return this._config[param];
};

// implements Runnable ;)

const connect = function () {
    this.debug("Tennu", "Trying to connect.");

    if (this.connected) {
        this.warn("Tennu", "Attempted to start Tennu Client that already is connected.");
        return;
    }

    this._socket.connect();
    this.connected = true;
    this.debug("Tennu", "Connected");
    return this;
}

Client.prototype.connect = connect;
Client.prototype.start = connect;

const disconnect = function () {
    this.debug("Tennu", "Trying to disconnect.");

    if (!this.connected) {
        this.warn("Tennu", "Attempted to end Tennu Client that already is not connected.");
        return this;
    }

    this._socket.end();
    this.connected = false;
    this.debug("Tennu", "Disconnected");
    return this;
};

Client.prototype.disconnect = disconnect;
Client.prototype.end = disconnect;

// implements IRC Output Socket

Client.prototype.say                    = delegate _outputSocket say;
{'fraction_non_alphanumeric': 0.1357402742793171, 'fraction_numerical': 0.001119507416736636, 'mean_word_length': 3.265817747711898, 'pattern_counts': {'":': 18, '<': 6, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7274646', 'n_tokens_mistral': 3053, 'n_tokens_neox': 2946, 'n_words': 844}