UNPKG

@decaf-ts/fabric-weaver

Version:
442 lines 67.1 kB
import { Logging } from "@decaf-ts/logging"; import { FabricBinaries } from "../constants/fabric-binaries"; import { FabricCAServerCommand } from "../constants/fabric-ca-server"; import { COMMA_SEPARATOR } from "../../core/constants/constants"; import { mapParser } from "../../utils"; import { runCommand } from "../../utils/child-process"; export class FabricCAServerCommandBuilder { constructor(logger) { this.binName = FabricBinaries.SERVER; this.command = FabricCAServerCommand.HELP; this.args = new Map(); if (!logger) this.log = Logging.for(FabricCAServerCommandBuilder); else this.log = logger.for(FabricCAServerCommandBuilder.name); } /** * @description Sets the command for the Fabric CA Server. * @summary Configures the primary action for the Fabric CA Server, such as starting the server or generating certificates. * @param {FabricCAServerCommand} [command] - The command to be executed by the Fabric CA Server. * @return {this} The current instance of the builder for method chaining. */ setCommand(command) { if (command !== undefined) { this.log.debug(`Setting command: ${command}`); this.command = command; } return this; } /** * @description Sets the port for the Fabric CA Server. * @summary Configures the network port on which the Fabric CA Server will listen for incoming connections. * @param {number} [port] - The port number for the Fabric CA Server to listen on. * @return {this} The current instance of the builder for method chaining. */ setPort(port) { if (port !== undefined) { this.log.debug(`Setting port: ${port}`); this.args.set("port", port); } return this; } /** * @description Enables or disables debug mode for the Fabric CA Server. * @summary Configures whether the Fabric CA Server should run in debug mode, providing more detailed logging and output. * @param {boolean} [enable] - Whether to enable debug mode. * @return {this} The current instance of the builder for method chaining. */ enableDebug(enable) { if (enable !== undefined) { this.log.debug(`Setting debug: ${enable}`); this.args.set("debug", enable); } return this; } setServerTLS(tlsConfig) { if (!tlsConfig) return this; if (tlsConfig.enabled !== undefined) { this.log.debug("Setting TLS enabled"); this.args.set("tls.enabled", tlsConfig.enabled); } if (tlsConfig.certfile !== undefined) { this.log.debug(`Setting TLS cert file: ${tlsConfig.certfile}`); this.args.set("tls.certfile", tlsConfig.certfile); } if (tlsConfig.keyfile !== undefined) { this.log.debug(`Setting TLS key file: ${tlsConfig.keyfile}`); this.args.set("tls.keyfile", tlsConfig.keyfile); } if (tlsConfig.clientauth === undefined) return this; if (tlsConfig.clientauth.certfiles !== undefined) { this.log.debug(`Setting TLS client certfiles: ${tlsConfig.clientauth.certfiles}`); this.args.set("tls.clientauth.certfiles", tlsConfig.clientauth.certfiles.join(COMMA_SEPARATOR)); } if (tlsConfig.clientauth.type !== undefined) { this.log.debug(`Setting TLS client auth type: ${tlsConfig.clientauth.type}`); this.args.set("tls.clientauth.type", tlsConfig.clientauth.type); } return this; } setCA(config) { if (!config) return this; if (config.name !== undefined) { this.log.debug(`Setting CA name: ${config.name}`); this.args.set("ca.name", config.name); } if (config.keyfile !== undefined) { this.log.debug(`Setting CA key file: ${config.keyfile}`); this.args.set("ca.keyfile", config.keyfile); } if (config.certfile !== undefined) { this.log.debug(`Setting CA cert file: ${config.certfile}`); this.args.set("ca.certfile", config.certfile); } if (config.chainfile !== undefined) { this.log.debug(`Setting CA chain file: ${config.chainfile}`); this.args.set("ca.chainfile", config.chainfile); } if (config.reenrollIgnoreCertExpiry !== undefined) { this.log.debug(`Setting reenrollIgnoreCertExpiry: ${config.reenrollIgnoreCertExpiry}`); this.args.set("ca.reenrollignorecertexpiry", config.reenrollIgnoreCertExpiry); } return this; } /** * @description Sets the address for the Fabric CA Server. * @summary Configures the network address on which the Fabric CA Server will listen for incoming connections. * @param {string} [address] - The network address for the Fabric CA Server to listen on. * @return {this} The current instance of the builder for method chaining. */ setAddress(address) { if (address !== undefined) { this.log.debug(`Setting address: ${address}`); this.args.set("address", address); } return this; } /** * @description Sets the bootstrap admin user for the Fabric CA Server. * @summary Configures the initial admin user with full privileges for the Fabric CA Server. * @param {string} [bootUser] - The bootstrap admin user in the format "username:password". * @return {this} The current instance of the builder for method chaining. */ setBootstrapAdmin(bootUser) { if (bootUser !== undefined) { const [user, password] = bootUser.split(":"); this.log.debug(`Setting bootstrap admin: ${user}:${password}`); this.args.set("boot", bootUser); } return this; } /** * @description Sets the number of CAs to run on the Fabric CA Server. * @summary Configures the Fabric CA Server to run multiple CA instances. * @param {number} [count] - The number of CA instances to run. * @return {this} The current instance of the builder for method chaining. */ setCACount(count) { if (count !== undefined) { this.log.debug(`Setting CA count: ${count}`); this.args.set("cacount", count); } return this; } /** * @description Sets the configuration files for multiple CAs. * @summary Configures the Fabric CA Server with multiple CA configurations using separate files. * @param {string[]} [files] - An array of paths to CA configuration files. * @return {this} The current instance of the builder for method chaining. */ setCAFiles(files) { if (files !== undefined && files.length > 0) { this.log.debug(`Setting CA configuration files: ${files.join(", ")}`); this.args.set("cafiles", files.join(COMMA_SEPARATOR)); } return this; } setCors(config) { if (!config) return this; if (config.enabled !== undefined) { this.log.debug(`Setting CORS enabled: ${config.enabled}`); this.args.set("cors.enabled", config.enabled); } if (config.origins !== undefined) { this.log.debug(`Setting CORS origins: ${config.origins.join(", ")}`); this.args.set("cors.origins", config.origins.join(COMMA_SEPARATOR)); } return this; } setCrlExpiry(crlExpiry) { if (crlExpiry !== undefined) { this.log.debug(`Setting CRL expiry: ${crlExpiry}`); this.args.set("crl.expiry", crlExpiry); } return this; } /** * @description Sets the size limit for the Certificate Revocation List (CRL). * @summary Configures the maximum number of revoked certificates that can be included in a single CRL. * @param {number} [limit] - The maximum number of revoked certificates in the CRL. * @return {this} The current instance of the builder for method chaining. */ setCRLSizeLimit(limit) { if (limit !== undefined) { this.log.debug(`Setting CRL size limit: ${limit}`); this.args.set("crlsizelimit", limit); } return this; } setCSR(csr) { if (csr === undefined) return this; if (csr.cn !== undefined) { this.log.debug(`Setting CSR CN: ${csr.cn}`); this.args.set("csr.cn", csr.cn); } if (csr.hosts !== undefined) { this.log.debug(`Setting CSR hosts: ${csr.hosts}`); this.args.set("csr.hosts", [...new Set(csr.hosts)].join(COMMA_SEPARATOR)); } if (csr.keyrequest !== undefined) { if (csr.keyrequest.algo !== undefined) { this.log.debug(`Setting CSR key request algorithm: ${csr.keyrequest.algo}`); this.args.set("csr.keyrequest.algo", csr.keyrequest.algo); } if (csr.keyrequest.size !== undefined) { this.log.debug(`Setting CSR key request size: ${csr.keyrequest.size}`); this.args.set("csr.keyrequest.size", csr.keyrequest.size); } if (csr.keyrequest.reusekey !== undefined) { this.log.debug(`Setting CSR key request reuse key: ${csr.keyrequest.reusekey}`); this.args.set("csr.keyrequest.reusekey", csr.keyrequest.reusekey); } } if (csr.serialnumber !== undefined) { this.log.debug(`Setting CSR serial number: ${csr.serialnumber}`); this.args.set("csr.serialnumber", csr.serialnumber); } return this; } setHelp(show) { if (show !== undefined) { this.log.debug(`Setting help flag: ${show}`); this.args.set("help", show); } return this; } setHome(home) { if (home !== undefined) { this.log.debug(`Setting home directory: ${home}`); this.args.set("home", home); } return this; } setDatabase(cfg) { if (cfg === undefined) return this; if (cfg.type !== undefined) { this.log.debug(`Setting database type: ${cfg.type}`); this.args.set("db.type", cfg.type); } if (cfg.datasource !== undefined) { this.log.debug(`Setting database datasource: ${cfg.datasource}`); this.args.set("db.datasource", cfg.datasource); } if (cfg.tls !== undefined) { if (cfg.tls.certfiles !== undefined) { this.log.debug(`Setting TLS certfiles: ${cfg.tls.certfiles}`); this.args.set("db.tls.certfiles", cfg.tls.certfiles.join(COMMA_SEPARATOR)); } if (cfg.tls.client !== undefined) { if (cfg.tls.client.certfile !== undefined) { this.log.debug(`Setting TLS client certfile: ${cfg.tls.client.certfile}`); this.args.set("db.tls.client.certfile", cfg.tls.client.certfile); } if (cfg.tls.client.keyfile !== undefined) { this.log.debug(`Setting TLS client keyfile: ${cfg.tls.client.keyfile}`); this.args.set("db.tls.client.keyfile", cfg.tls.client.keyfile); } } } return this; } setIdemix(idemix) { if (idemix === undefined) return this; if (idemix.nonceexpiration !== undefined) { this.log.debug(`Setting Idemix nonce expiration: ${idemix.nonceexpiration}`); this.args.set("idemix.nonceexpiration", idemix.nonceexpiration); } if (idemix.curve !== undefined) { this.log.debug(`Setting Idemix curve: ${idemix.curve}`); this.args.set("idemix.curve", idemix.curve); } if (idemix.noncesweepinterval !== undefined) { this.log.debug(`Setting Idemix noncesweep interval: ${idemix.noncesweepinterval}`); this.args.set("idemix.noncesweepinterval", idemix.noncesweepinterval); } if (idemix.rhpoolsize !== undefined) { this.log.debug(`Setting Idemix rhpoolsize: ${idemix.rhpoolsize}`); this.args.set("idemix.rhpoolsize", idemix.rhpoolsize); } return this; } setIntermediate(int) { if (int === undefined) return this; if (int.parentserver !== undefined) { if (int.parentserver.url !== undefined) { this.log.debug(`Setting intermediate CA parent server URL: ${int.parentserver.url}`); this.args.set("intermediate.parentserver.url", int.parentserver.url); } if (int.parentserver.caname !== undefined) { this.log.debug(`Setting intermediate CA parent server caname: ${int.parentserver.caname}`); this.args.set("intermediate.parentserver.caname", int.parentserver.caname); } } if (int.enrollment !== undefined) { if (int.enrollment.type !== undefined) { this.log.debug(`Setting intermediate CA enrollment type: ${int.enrollment.type}`); this.args.set("intermediate.enrollment.type", int.enrollment.type); } if (int.enrollment.profile !== undefined) { this.log.debug(`Setting intermediate CA enrollment profile: ${int.enrollment.profile}`); this.args.set("intermediate.enrollment.profile", int.enrollment.profile); } if (int.enrollment.label !== undefined) { this.log.debug(`Setting intermediate CA enrollment label: ${int.enrollment.label}`); this.args.set("intermediate.enrollment.label", int.enrollment.label); } } if (int.tls !== undefined) { if (int.tls.certfiles !== undefined) { this.log.debug(`Setting intermediate CA TLS certfiles: ${int.tls.certfiles.join(", ")}`); this.args.set("intermediate.tls.certfiles", int.tls.certfiles.join(COMMA_SEPARATOR)); } if (int.tls.client !== undefined) { if (int.tls.client.certfile !== undefined) { this.log.debug(`Setting intermediate CA TLS client certfile: ${int.tls.client.certfile}`); this.args.set("intermediate.tls.client.certfile", int.tls.client.certfile); } if (int.tls.client.keyfile !== undefined) { this.log.debug(`Setting intermediate CA TLS client keyfile: ${int.tls.client.keyfile}`); this.args.set("intermediate.tls.client.keyfile", int.tls.client.keyfile); } } } return this; } setLDAP(ldap) { if (ldap === undefined) return this; if (ldap.enabled !== undefined) { this.log.debug(`Setting LDAP enabled: ${ldap.enabled}`); this.args.set("ldap.enabled", ldap.enabled); } if (ldap.url !== undefined) { this.log.debug(`Setting LDAP URL: ${ldap.url}`); this.args.set("ldap.url", ldap.url); } if (ldap.tls !== undefined) { if (ldap.tls.certfiles !== undefined) { this.log.debug(`Setting TLS certfiles: ${ldap.tls.certfiles.join(", ")}`); this.args.set("ldap.tls.certfiles", ldap.tls.certfiles.join(COMMA_SEPARATOR)); } if (ldap.tls.client !== undefined) { if (ldap.tls.client.certfile !== undefined) { this.log.debug(`Setting TLS client certfile: ${ldap.tls.client.certfile}`); this.args.set("ldap.tls.client.certfile", ldap.tls.client.certfile); } if (ldap.tls.client.keyfile !== undefined) { this.log.debug(`Setting TLS client keyfile: ${ldap.tls.client.keyfile}`); this.args.set("ldap.tls.client.keyfile", ldap.tls.client.keyfile); } } } if (ldap.attribute !== undefined) { if (ldap.attribute.names !== undefined) { this.log.debug(`Setting LDAP attribute names: ${ldap.attribute.names.join(", ")}`); this.args.set("ldap.attribute.names", ldap.attribute.names.join(COMMA_SEPARATOR)); } } if (ldap.groupfilter !== undefined) { this.log.debug(`Setting LDAP groupfiler: ${ldap.groupfilter}`); this.args.set("ldap.groupfilter", ldap.groupfilter); } if (ldap.userfilter !== undefined) { this.log.debug(`Setting LDAP userfilter: ${ldap.userfilter}`); this.args.set("ldap.userfilter", ldap.userfilter); } return this; } setLogLevel(level) { this.log.debug(`Setting log level: ${level}`); this.args.set("loglevel", level); return this; } setMaxEnrollments(maxEnrollments) { if (maxEnrollments !== undefined) { this.log.debug(`Setting max enrollments: ${maxEnrollments}`); this.args.set("registry.maxenrollments", maxEnrollments); } return this; } setAllowAffiliationsRemove(allow) { if (allow !== undefined) { this.log.debug(`Setting affiliations allow remove: ${allow}`); this.args.set("cfg.affiliations.allowremove", allow); } return this; } setAllowIdentitiesRemove(allow) { if (allow !== undefined) { this.log.debug(`Setting identities allow remove: ${allow}`); this.args.set("cfg.identities.allowremove", allow); } return this; } setPasswordAttempts(attempts) { if (attempts !== undefined) { this.log.debug(`Setting password attempts: ${attempts}`); this.args.set("cfg.identities.passwordattempts", attempts); } return this; } build() { const command = [ this.getBinary(), this.getCommand(), ...mapParser(this.args), ].join(" "); this.log.debug(`Built command: ${command}`); return command; } getCommand() { return this.command; } getBinary() { return this.binName; } getArgs() { return mapParser(this.args); } async execute() { const bin = this.getBinary(); const argz = [this.getCommand(), ...this.getArgs()]; try { // const regex = /\[\s*INFO\s*\] Listening on http/; // can be used as a promise but to lock the logs running as execsync await runCommand(bin, argz); } catch (error) { this.log.error(`Error: Failed to execute the command: ${error}`); process.exit(1); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFicmljLWNhLXNlcnZlci1jb21tYW5kLWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZmFicmljL2ZhYnJpYy1jYS1zZXJ2ZXIvZmFicmljLWNhLXNlcnZlci1jb21tYW5kLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFVLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQVd0RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDakUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHdkQsTUFBTSxPQUFPLDRCQUE0QjtJQVF2QyxZQUFZLE1BQWU7UUFMbkIsWUFBTyxHQUFtQixjQUFjLENBQUMsTUFBTSxDQUFDO1FBQ2hELFlBQU8sR0FBMEIscUJBQXFCLENBQUMsSUFBSSxDQUFDO1FBRTVELFNBQUksR0FBc0QsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUcxRSxJQUFJLENBQUMsTUFBTTtZQUFFLElBQUksQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDOztZQUM3RCxJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVSxDQUFDLE9BQStCO1FBQ3hDLElBQUksT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLG9CQUFvQixPQUFPLEVBQUUsQ0FBQyxDQUFDO1lB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V0FBVyxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztRQUM1RSxDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHNDQUFzQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUM1RCxDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHFCQUFxQixFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUQsQ0FBQztZQUNELElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ3ZFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHFCQUFxQixFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUQsQ0FBQztZQUNELElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHNDQUFzQyxHQUFHLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUNoRSxDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHlCQUF5QixFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEUsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsOEJBQThCLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ2pFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsT0FBTyxDQUFDLElBQWM7UUFDcEIsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLElBQUksRUFBRSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLENBQUMsSUFBYTtRQUNuQixJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELFdBQVcsQ0FBQyxHQUFjO1FBQ3hCLElBQUksR0FBRyxLQUFLLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVuQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUNELElBQUksR0FBRyxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDakUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzFCLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDBCQUEwQixHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7Z0JBQzlELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNYLGtCQUFrQixFQUNsQixHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQ3hDLENBQUM7WUFDSixDQUFDO1lBRUQsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLGdDQUFnQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FDMUQsQ0FBQztvQkFDRixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDbkUsQ0FBQztnQkFFRCxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDekMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osK0JBQStCLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUN4RCxDQUFDO29CQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHVCQUF1QixFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNqRSxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxTQUFTLENBQUMsTUFBcUI7UUFDN0IsSUFBSSxNQUFNLEtBQUssU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRXRDLElBQUksTUFBTSxDQUFDLGVBQWUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN6QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixvQ0FBb0MsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUM3RCxDQUFDO1lBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsd0JBQXdCLEVBQUUsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMseUJBQXlCLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLGtCQUFrQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHVDQUF1QyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FDbkUsQ0FBQztZQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDJCQUEyQixFQUFFLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsOEJBQThCLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsZUFBZSxDQUFDLEdBQWdDO1FBQzlDLElBQUksR0FBRyxLQUFLLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVuQyxJQUFJLEdBQUcsQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkMsSUFBSSxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osOENBQThDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQ3JFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsK0JBQStCLEVBQUUsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN2RSxDQUFDO1lBQ0QsSUFBSSxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osaURBQWlELEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQzNFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsa0NBQWtDLEVBQ2xDLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUN4QixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakMsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osNENBQTRDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQ2xFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsOEJBQThCLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyRSxDQUFDO1lBRUQsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDekMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osK0NBQStDLEdBQUcsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQ3hFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsaUNBQWlDLEVBQ2pDLEdBQUcsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUN2QixDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLDZDQUE2QyxHQUFHLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUNwRSxDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLCtCQUErQixFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkUsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDMUIsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osMENBQTBDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FDOUQsSUFBSSxDQUNMLEVBQUUsQ0FDSixDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNYLDRCQUE0QixFQUM1QixHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQ3hDLENBQUM7WUFDSixDQUFDO1lBQ0QsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLGdEQUFnRCxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FDMUUsQ0FBQztvQkFDRixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FDWCxrQ0FBa0MsRUFDbEMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUN4QixDQUFDO2dCQUNKLENBQUM7Z0JBQ0QsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQ3pDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLCtDQUErQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FDeEUsQ0FBQztvQkFDRixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FDWCxpQ0FBaUMsRUFDakMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUN2QixDQUFDO2dCQUNKLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sQ0FBQyxJQUF3QjtRQUM5QixJQUFJLElBQUksS0FBSyxTQUFTO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFcEMsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHlCQUF5QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMscUJBQXFCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ2hELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWiwwQkFBMEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQzFELENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsb0JBQW9CLEVBQ3BCLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FDekMsQ0FBQztZQUNKLENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNsQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDM0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osZ0NBQWdDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUMzRCxDQUFDO29CQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDBCQUEwQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN0RSxDQUFDO2dCQUVELElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUMxQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWiwrQkFBK0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQ3pELENBQUM7b0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMseUJBQXlCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3BFLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN2QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixpQ0FBaUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQ25FLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsc0JBQXNCLEVBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FDM0MsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDRCQUE0QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDOUQsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxXQUFXLENBQUMsS0FBcUI7UUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGlCQUFpQixDQUFDLGNBQXVCO1FBQ3ZDLElBQUksY0FBYyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDRCQUE0QixjQUFjLEVBQUUsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHlCQUF5QixFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCwwQkFBMEIsQ0FBQyxLQUFlO1FBQ3hDLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHNDQUFzQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzlELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDhCQUE4QixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCx3QkFBd0IsQ0FBQyxLQUFlO1FBQ3RDLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzVELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDRCQUE0QixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxRQUFpQjtRQUNuQyxJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsS0FBSztRQUNILE1BQU0sT0FBTyxHQUFXO1lBQ3RCLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEIsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNqQixHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1NBQ3hCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRVosSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDNUMsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELFVBQVU7UUFDUixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVELFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVELE9BQU87UUFDTCxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVELEtBQUssQ0FBQyxPQUFPO1FBQ1gsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzdCLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFcEQsSUFBSSxDQUFDO1lBQ0gsb0RBQW9EO1lBQ3BELG9FQUFvRTtZQUNwRSxNQUFNLFVBQVUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUFDLE9BQU8sS0FBYyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMseUNBQXlDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDakUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBGYWJyaWNCaW5hcmllcyB9IGZyb20gXCIuLi9jb25zdGFudHMvZmFicmljLWJpbmFyaWVzXCI7XG5pbXBvcnQgeyBGYWJyaWNDQVNlcnZlckNvbW1hbmQgfSBmcm9tIFwiLi4vY29uc3RhbnRzL2ZhYnJpYy1jYS1zZXJ2ZXJcIjtcbmltcG9ydCB7XG4gIENBQ29uZmlnLFxuICBDb21tYWRDU1JDb25maWcsXG4gIENvbW1hbmRJbnRlcm1lZGlhdGVDQUNvbmZpZyxcbiAgQ29tbWFuZExEQVBDb25maWcsXG4gIENvcnNDb25maWcsXG4gIERCQ29uZmlnLFxuICBJZGVtaXhDb25maWcsXG4gIFNlcnZlclRMU0NvbmZpZyxcbn0gZnJvbSBcIi4uL2ludGVyZmFjZXMvZmFicmljL2ZhYnJpYy1jYS1zZXJ2ZXItY29uZmlnXCI7XG5pbXBvcnQgeyBDT01NQV9TRVBBUkFUT1IgfSBmcm9tIFwiLi4vLi4vY29yZS9jb25zdGFudHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBtYXBQYXJzZXIgfSBmcm9tIFwiLi4vLi4vdXRpbHNcIjtcbmltcG9ydCB7IHJ1bkNvbW1hbmQgfSBmcm9tIFwiLi4vLi4vdXRpbHMvY2hpbGQtcHJvY2Vzc1wiO1xuaW1wb3J0IHsgRmFicmljTG9nTGV2ZWwgfSBmcm9tIFwiLi4vY29uc3RhbnRzL2ZhYnJpYy1nZW5lcmFsXCI7XG5cbmV4cG9ydCBjbGFzcyBGYWJyaWNDQVNlcnZlckNvbW1hbmRCdWlsZGVyIHtcbiAgcHJpdmF0ZSBsb2c6IExvZ2dlcjtcblxuICBwcml2YXRlIGJpbk5hbWU6IEZhYnJpY0JpbmFyaWVzID0gRmFicmljQmluYXJpZXMuU0VSVkVSO1xuICBwcml2YXRlIGNvbW1hbmQ6IEZhYnJpY0NBU2VydmVyQ29tbWFuZCA9IEZhYnJpY0NBU2VydmVyQ29tbWFuZC5IRUxQO1xuXG4gIHByaXZhdGUgYXJnczogTWFwPHN0cmluZywgc3RyaW5nIHwgYm9vbGVhbiB8IG51bWJlciB8IHN0cmluZ1tdPiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3Rvcihsb2dnZXI/OiBMb2dnZXIpIHtcbiAgICBpZiAoIWxvZ2dlcikgdGhpcy5sb2cgPSBMb2dnaW5nLmZvcihGYWJyaWNDQVNlcnZlckNvbW1hbmRCdWlsZGVyKTtcbiAgICBlbHNlIHRoaXMubG9nID0gbG9nZ2VyLmZvcihGYWJyaWNDQVNlcnZlckNvbW1hbmRCdWlsZGVyLm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBjb21tYW5kIGZvciB0aGUgRmFicmljIENBIFNlcnZlci5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgcHJpbWFyeSBhY3Rpb24gZm9yIHRoZSBGYWJyaWMgQ0EgU2VydmVyLCBzdWNoIGFzIHN0YXJ0aW5nIHRoZSBzZXJ2ZXIgb3IgZ2VuZXJhdGluZyBjZXJ0aWZpY2F0ZXMuXG4gICAqIEBwYXJhbSB7RmFicmljQ0FTZXJ2ZXJDb21tYW5kfSBbY29tbWFuZF0gLSBUaGUgY29tbWFuZCB0byBiZSBleGVjdXRlZCBieSB0aGUgRmFicmljIENBIFNlcnZlci5cbiAgICogQHJldHVybiB7dGhpc30gVGhlIGN1cnJlbnQgaW5zdGFuY2Ugb2YgdGhlIGJ1aWxkZXIgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldENvbW1hbmQoY29tbWFuZD86IEZhYnJpY0NBU2VydmVyQ29tbWFuZCk6IHRoaXMge1xuICAgIGlmIChjb21tYW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBTZXR0aW5nIGNvbW1hbmQ6ICR7Y29tbWFuZH1gKTtcbiAgICAgIHRoaXMuY29tbWFuZCA9IGNvbW1hbmQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBwb3J0IGZvciB0aGUgRmFicmljIENBIFNlcnZlci5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgbmV0d29yayBwb3J0IG9uIHdoaWNoIHRoZSBGYWJyaWMgQ0EgU2VydmVyIHdpbGwgbGlzdGVuIGZvciBpbmNvbWluZyBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtwb3J0XSAtIFRoZSBwb3J0IG51bWJlciBmb3IgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgdG8gbGlzdGVuIG9uLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBUaGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGUgYnVpbGRlciBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0UG9ydChwb3J0PzogbnVtYmVyKTogdGhpcyB7XG4gICAgaWYgKHBvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgcG9ydDogJHtwb3J0fWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcInBvcnRcIiwgcG9ydCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFbmFibGVzIG9yIGRpc2FibGVzIGRlYnVnIG1vZGUgZm9yIHRoZSBGYWJyaWMgQ0EgU2VydmVyLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHdoZXRoZXIgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgc2hvdWxkIHJ1biBpbiBkZWJ1ZyBtb2RlLCBwcm92aWRpbmcgbW9yZSBkZXRhaWxlZCBsb2dnaW5nIGFuZCBvdXRwdXQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2VuYWJsZV0gLSBXaGV0aGVyIHRvIGVuYWJsZSBkZWJ1ZyBtb2RlLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBUaGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGUgYnVpbGRlciBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgZW5hYmxlRGVidWcoZW5hYmxlPzogYm9vbGVhbik6IHRoaXMge1xuICAgIGlmIChlbmFibGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgZGVidWc6ICR7ZW5hYmxlfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImRlYnVnXCIsIGVuYWJsZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc2V0U2VydmVyVExTKHRsc0NvbmZpZz86IFNlcnZlclRMU0NvbmZpZyk6IHRoaXMge1xuICAgIGlmICghdGxzQ29uZmlnKSByZXR1cm4gdGhpcztcblxuICAgIGlmICh0bHNDb25maWcuZW5hYmxlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhcIlNldHRpbmcgVExTIGVuYWJsZWRcIik7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFwidGxzLmVuYWJsZWRcIiwgdGxzQ29uZmlnLmVuYWJsZWQpO1xuICAgIH1cblxuICAgIGlmICh0bHNDb25maWcuY2VydGZpbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgVExTIGNlcnQgZmlsZTogJHt0bHNDb25maWcuY2VydGZpbGV9YCk7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFwidGxzLmNlcnRmaWxlXCIsIHRsc0NvbmZpZy5jZXJ0ZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKHRsc0NvbmZpZy5rZXlmaWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBTZXR0aW5nIFRMUyBrZXkgZmlsZTogJHt0bHNDb25maWcua2V5ZmlsZX1gKTtcbiAgICAgIHRoaXMuYXJncy5zZXQoXCJ0bHMua2V5ZmlsZVwiLCB0bHNDb25maWcua2V5ZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKHRsc0NvbmZpZy5jbGllbnRhdXRoID09PSB1bmRlZmluZWQpIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKHRsc0NvbmZpZy5jbGllbnRhdXRoLmNlcnRmaWxlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhcbiAgICAgICAgYFNldHRpbmcgVExTIGNsaWVudCBjZXJ0ZmlsZXM6ICR7dGxzQ29uZmlnLmNsaWVudGF1dGguY2VydGZpbGVzfWBcbiAgICAgICk7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFxuICAgICAgICBcInRscy5jbGllbnRhdXRoLmNlcnRmaWxlc1wiLFxuICAgICAgICB0bHNDb25maWcuY2xpZW50YXV0aC5jZXJ0ZmlsZXMuam9pbihDT01NQV9TRVBBUkFUT1IpXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0bHNDb25maWcuY2xpZW50YXV0aC50eXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKFxuICAgICAgICBgU2V0dGluZyBUTFMgY2xpZW50IGF1dGggdHlwZTogJHt0bHNDb25maWcuY2xpZW50YXV0aC50eXBlfWBcbiAgICAgICk7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFwidGxzLmNsaWVudGF1dGgudHlwZVwiLCB0bHNDb25maWcuY2xpZW50YXV0aC50eXBlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHNldENBKGNvbmZpZzogQ0FDb25maWcpOiB0aGlzIHtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoY29uZmlnLm5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgQ0EgbmFtZTogJHtjb25maWcubmFtZX1gKTtcbiAgICAgIHRoaXMuYXJncy5zZXQoXCJjYS5uYW1lXCIsIGNvbmZpZy5uYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLmtleWZpbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgQ0Ega2V5IGZpbGU6ICR7Y29uZmlnLmtleWZpbGV9YCk7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFwiY2Eua2V5ZmlsZVwiLCBjb25maWcua2V5ZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jZXJ0ZmlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgU2V0dGluZyBDQSBjZXJ0IGZpbGU6ICR7Y29uZmlnLmNlcnRmaWxlfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImNhLmNlcnRmaWxlXCIsIGNvbmZpZy5jZXJ0ZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jaGFpbmZpbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgQ0EgY2hhaW4gZmlsZTogJHtjb25maWcuY2hhaW5maWxlfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImNhLmNoYWluZmlsZVwiLCBjb25maWcuY2hhaW5maWxlKTtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLnJlZW5yb2xsSWdub3JlQ2VydEV4cGlyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhcbiAgICAgICAgYFNldHRpbmcgcmVlbnJvbGxJZ25vcmVDZXJ0RXhwaXJ5OiAke2NvbmZpZy5yZWVucm9sbElnbm9yZUNlcnRFeHBpcnl9YFxuICAgICAgKTtcbiAgICAgIHRoaXMuYXJncy5zZXQoXG4gICAgICAgIFwiY2EucmVlbnJvbGxpZ25vcmVjZXJ0ZXhwaXJ5XCIsXG4gICAgICAgIGNvbmZpZy5yZWVucm9sbElnbm9yZUNlcnRFeHBpcnlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGFkZHJlc3MgZm9yIHRoZSBGYWJyaWMgQ0EgU2VydmVyLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBuZXR3b3JrIGFkZHJlc3Mgb24gd2hpY2ggdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgd2lsbCBsaXN0ZW4gZm9yIGluY29taW5nIGNvbm5lY3Rpb25zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FkZHJlc3NdIC0gVGhlIG5ldHdvcmsgYWRkcmVzcyBmb3IgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgdG8gbGlzdGVuIG9uLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBUaGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGUgYnVpbGRlciBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0QWRkcmVzcyhhZGRyZXNzPzogc3RyaW5nKTogdGhpcyB7XG4gICAgaWYgKGFkZHJlc3MgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgYWRkcmVzczogJHthZGRyZXNzfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImFkZHJlc3NcIiwgYWRkcmVzcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBib290c3RyYXAgYWRtaW4gdXNlciBmb3IgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIGluaXRpYWwgYWRtaW4gdXNlciB3aXRoIGZ1bGwgcHJpdmlsZWdlcyBmb3IgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYm9vdFVzZXJdIC0gVGhlIGJvb3RzdHJhcCBhZG1pbiB1c2VyIGluIHRoZSBmb3JtYXQgXCJ1c2VybmFtZTpwYXNzd29yZFwiLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBUaGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGUgYnVpbGRlciBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0Qm9vdHN0cmFwQWRtaW4oYm9vdFVzZXI/OiBzdHJpbmcpOiB0aGlzIHtcbiAgICBpZiAoYm9vdFVzZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgW3VzZXIsIHBhc3N3b3JkXSA9IGJvb3RVc2VyLnNwbGl0KFwiOlwiKTtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBTZXR0aW5nIGJvb3RzdHJhcCBhZG1pbjogJHt1c2VyfToke3Bhc3N3b3JkfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImJvb3RcIiwgYm9vdFVzZXIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgbnVtYmVyIG9mIENBcyB0byBydW4gb24gdGhlIEZhYnJpYyBDQSBTZXJ2ZXIuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgdG8gcnVuIG11bHRpcGxlIENBIGluc3RhbmNlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtjb3VudF0gLSBUaGUgbnVtYmVyIG9mIENBIGluc3RhbmNlcyB0byBydW4uXG4gICAqIEByZXR1cm4ge3RoaXN9IFRoZSBjdXJyZW50IGluc3RhbmNlIG9mIHRoZSBidWlsZGVyIGZvciBtZXRob2QgY2hha