I have a C++ library for generating passwords. The library is implemented using the Abstract Factory and Command patterns. Please write a main() function that will define a console user interface and allow this library to be used to generate passwords for the user. After generating a password or several passwords, the user returns to the menu (that is, the program is cyclical). Write all comments and lines in Russian. Check the entered values. Handle any anomalous situations and input errors using a try, catch and throw block. Avoid mistakes in C++ code. Library code:

#include <string>
#include <vector>
#include <random>
#include <stdexcept>

class PasswordOptions {
public:
    virtual bool useLowercase() const = 0;
    virtual bool useUppercase() const = 0;
    virtual bool useDigits() const = 0;
    virtual bool useSpecialChars() const = 0;
    virtual size_t getPasswordLength() const = 0;
};

class PasswordFactory {
public:
    virtual std::string generatePassword() const = 0;
};

class BasePasswordOptions : public PasswordOptions {
private:
    bool includeLowercase;
    bool includeUppercase;
    bool includeDigits;
    bool includeSpecialChars;
    size_t length;

public:
    BasePasswordOptions(bool lower, bool upper, bool digits, bool special, size_t len)
        : includeLowercase(lower),
          includeUppercase(upper),
          includeDigits(digits),
          includeSpecialChars(special),
          length(len) {}

    bool useLowercase() const override { return includeLowercase; }
    bool useUppercase() const override { return includeUppercase; }
    bool useDigits() const override { return includeDigits; }
    bool useSpecialChars() const override { return includeSpecialChars; }
    size_t getPasswordLength() const override { return length; }
};

class ConcretePasswordFactory : public PasswordFactory {
private:
    PasswordOptions const &options;

    char randomChar(const std::string &category) const {
        static std::mt19937 rng(std::random_device{}());
        std::uniform_int_distribution<> dist(0, category.length() - 1);
        return category[dist(rng)];
    }

public:
    ConcretePasswordFactory(const PasswordOptions &opts) : options(opts) {}

    std::string generatePassword() const override {
        std::string allowedChars;
        if (options.useLowercase()) allowedChars += "abcdefghijklmnopqrstuvwxyz";
        if (options.useUppercase()) allowedChars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        if (options.useDigits()) allowedChars += "0123456789";
        if (options.useSpecialChars()) allowedChars += "!@#$%^&*()_-+=<>?";

        if (allowedChars.empty()) throw std::runtime_error("No characters are allowed for password generation");
        
        std::string password;
        for (size_t i = 0; i < options.getPasswordLength(); ++i) {
            password += randomChar(allowedChars);
        }
        return password;
    }
};

class ICommand {
public:
    virtual void execute() = 0;
};

class PasswordGeneratorCommand : public ICommand {
private:
    const PasswordFactory &factory;
    size_t numberOfPasswords;
    std::vector<std::string> &passwords;

public:
    PasswordGeneratorCommand(const PasswordFactory &f, size_t numPasswords, std::vector<std::string> &p)
        : factory(f), numberOfPasswords(numPasswords), passwords(p) {}

    void execute() override {
        try {
            for (size_t i = 0; i < numberOfPasswords; ++i) {
                passwords.push_back(factory.generatePassword());
            }
        } catch (const std::exception &e) {
            throw;
        }
    }
};

class PasswordStrengthChecker {
public:
    static bool isPasswordStrong(const std::string &password) {
        size_t score = 0;
        for (char ch : password) {
            if (std::islower(ch)) score += 1;
            else if (std::isupper(ch)) score += 2;
            else if (std::isdigit(ch)) score += 3;
            else score += 5;
        }
        return score > 10;
    }
};