UNPKG

@decaf-ts/fabric-weaver

Version:
591 lines 92.9 kB
import { Logging } from "@decaf-ts/logging"; import { readFileYaml, writeFileYaml } from "../../utils/yaml"; import path from "path"; import { overrideNonUndefined } from "../../utils-old/object"; import fs from "fs"; export class FabricCAServerConfigBuilder { constructor(logger) { this.config = readFileYaml(path.join(__dirname, "../../../config/fabric-ca-server-config.yaml")); if (!logger) this.log = Logging.for(FabricCAServerConfigBuilder); else this.log = logger.for(FabricCAServerConfigBuilder.name); } setVersion(version) { if (version !== undefined) { this.log.debug(`Setting version: ${version}`); this.config.version = version; } 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.config.port = port; } return this; } setCors(cors) { if (cors === undefined) return this; if (cors.enabled !== undefined) { this.log.debug("Setting CORS enabled"); this.config.cors.enabled = cors.enabled; } if (cors.origins !== undefined) { this.log.debug(`Setting CORS origins: ${cors.origins}`); this.config.cors.origins = cors.origins; } 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.config.debug = enable; } return this; } setCrlSizeLimit(crlSizeLimit) { if (crlSizeLimit !== undefined) { this.log.debug(`Setting CRL size limit: ${crlSizeLimit}`); this.config.crlsizelimit = crlSizeLimit; } return this; } setServerTLS(tlsConfig) { if (!tlsConfig) return this; if (tlsConfig.enabled !== undefined) { this.log.debug("Setting TLS enabled"); this.config.tls.enabled = tlsConfig.enabled; } if (tlsConfig.certfile !== undefined) { this.log.debug(`Setting TLS cert file: ${tlsConfig.certfile}`); this.config.tls.certfile = tlsConfig.certfile; } if (tlsConfig.keyfile !== undefined) { this.log.debug(`Setting TLS key file: ${tlsConfig.keyfile}`); this.config.tls.keyfile = tlsConfig.keyfile; } if (tlsConfig.clientauth !== undefined) { if (tlsConfig.clientauth.certfiles !== undefined) { this.log.debug(`Setting TLS client certfiles: ${tlsConfig.clientauth.certfiles}`); this.config.tls.clientauth.certfiles = tlsConfig.clientauth.certfiles; } if (tlsConfig.clientauth.type !== undefined) { this.log.debug(`Setting TLS client auth type: ${tlsConfig.clientauth.type}`); this.config.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.config.ca.name = config.name; } if (config.keyfile !== undefined) { this.log.debug(`Setting CA key file: ${config.keyfile}`); this.config.ca.keyfile = config.keyfile; } if (config.certfile !== undefined) { this.log.debug(`Setting CA cert file: ${config.certfile}`); this.config.ca.certfile = config.certfile; } if (config.chainfile !== undefined) { this.log.debug(`Setting CA chain file: ${config.chainfile}`); this.config.ca.chainfile = config.chainfile; } if (config.reenrollIgnoreCertExpiry !== undefined) { this.log.debug(`Setting reenrollIgnoreCertExpiry: ${config.reenrollIgnoreCertExpiry}`); this.config.ca.reenrollIgnoreCertExpiry = config.reenrollIgnoreCertExpiry; } return this; } setCrlExpiry(crlExpiry) { if (crlExpiry !== undefined) { this.log.debug(`Setting CRL expiry: ${crlExpiry}`); this.config.crl.expiry = crlExpiry; } return this; } setIdentities(ids) { if (ids !== undefined) { if (!Array.isArray(ids)) ids = [ids]; this.log.debug(`Setting identities: ${JSON.stringify(ids)}`); const baseIdentity = this.config.registry.identities[0]; const identities = ids.map((el) => { const identity = { ...baseIdentity }; if (el.name !== undefined) identity.name = el.name; if (el.pass !== undefined) identity.pass = el.pass; if (el.type !== undefined) identity.type = el.type; if (el.affiliation !== undefined) identity.affiliation = el.affiliation; if (el.attrs !== undefined) identity.attrs = overrideNonUndefined(identity.attrs, el.attrs); return identity; }); this.config.registry.identities = identities; } return this; } setMaxEnrollments(maxEnrollments) { if (maxEnrollments !== undefined) { this.log.debug(`Setting max enrollments: ${maxEnrollments}`); this.config.registry.maxenrollments = maxEnrollments; } return this; } setDatabase(cfg) { if (cfg === undefined) return this; if (cfg.type !== undefined) { this.log.debug(`Setting database type: ${cfg.type}`); this.config.db.type = cfg.type; } if (cfg.datasource !== undefined) { this.log.debug(`Setting database datasource: ${cfg.datasource}`); this.config.db.datasource = cfg.datasource; } if (cfg.tls !== undefined) { if (cfg.tls.enabled !== undefined) { this.log.debug(`Setting TLS enabled: ${cfg.tls.enabled}`); this.config.db.tls.enabled = cfg.tls.enabled; } if (cfg.tls.certfiles !== undefined) { this.log.debug(`Setting TLS certfiles: ${cfg.tls.certfiles}`); this.config.db.tls.certfiles = cfg.tls.certfiles; } if (cfg.tls.client !== undefined) { if (cfg.tls.client.certfile !== undefined) { this.log.debug(`Setting TLS client certfile: ${cfg.tls.client.certfile}`); this.config.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.config.db.tls.client.keyfile = cfg.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.config.ldap.enabled = ldap.enabled; } if (ldap.url !== undefined) { this.log.debug(`Setting LDAP URL: ${ldap.url}`); this.config.ldap.url = ldap.url; } if (ldap.tls !== undefined) { if (ldap.tls.certfiles !== undefined) { this.log.debug(`Setting TLS certfiles: ${ldap.tls.certfiles}`); this.config.ldap.tls.certfiles = ldap.tls.certfiles; } if (ldap.tls.client !== undefined) { if (ldap.tls.client.certfile !== undefined) { this.log.debug(`Setting TLS client certfile: ${ldap.tls.client.certfile}`); this.config.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.config.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}`); this.config.ldap.attribute.names = ldap.attribute.names; } if (ldap.attribute.converters !== undefined) { this.log.debug(`Setting LDAP attribute converters: ${JSON.stringify(ldap.attribute.converters)}`); this.config.ldap.attribute.converters = ldap.attribute.converters; } if (ldap.attribute.maps !== undefined) { this.log.debug(`Setting LDAP attribute maps: ${JSON.stringify(ldap.attribute.maps)}`); this.config.ldap.attribute.maps = ldap.attribute.maps; } } return this; } setAffiliations(affiliations) { if (affiliations !== undefined) { this.log.debug(`Setting affiliations: ${JSON.stringify(affiliations)}`); this.config.affiliations = affiliations; } return this; } /** * @description Removes unused profiles from the Fabric CA Server configuration. * @summary This method allows you to remove the TLS and/or CA profiles from the configuration if they are not needed. * Removing unused profiles can help streamline the configuration and potentially improve performance. * @param {boolean} [removeTLSProfile=false] - Whether to remove the TLS profile. * @param {boolean} [removeCAProfile=false] - Whether to remove the CA profile. * @return {this} The current instance of the builder for method chaining. * @example * const builder = new FabricCAServerCommandBuilder(); * builder.removeUnusedProfiles(true, false); // Removes TLS profile, keeps CA profile * * @mermaid * sequenceDiagram * participant Client * participant Builder as FabricCAServerCommandBuilder * participant Config as FabricCAServerConfig * Client->>Builder: removeUnusedProfiles(true, false) * Builder->>Builder: Check removeTLSProfile * alt removeTLSProfile is true * Builder->>Config: Remove TLS profile * end * Builder->>Builder: Check removeCAProfile * alt removeCAProfile is true * Builder->>Config: Remove CA profile * end * Builder-->>Client: Return this */ removeUnusedProfiles(removeTLSProfile = false, removeCAProfile = false) { if (removeTLSProfile) { this.log.debug("Removing TLS profile"); delete this.config.signing?.profiles?.tls; } if (removeCAProfile) { this.log.debug("Removing CA profile"); delete this.config.signing?.profiles?.ca; } return this; } setSigning(cfg) { if (cfg === undefined) return this; if (cfg.default !== undefined) { if (cfg.default.usage !== undefined) { this.log.debug(`Setting default usage: ${cfg.default.usage}`); this.config.signing.default.usage = [...new Set(cfg.default.usage)]; } if (cfg.default.expiry !== undefined) { this.log.debug(`Setting default expiry: ${cfg.default.expiry}`); this.config.signing.default.expiry = cfg.default.expiry; } } if (cfg.profiles !== undefined) { if (cfg.profiles.ca !== undefined) { if (cfg.profiles.ca.usage !== undefined) { this.log.debug(`Setting CA usage: ${cfg.profiles.ca.usage}`); this.config.signing.profiles.ca.usage = [ ...new Set(cfg.profiles.ca.usage), ]; } if (cfg.profiles.ca.expiry !== undefined) { this.log.debug(`Setting CA expiry: ${cfg.profiles.ca.expiry}`); this.config.signing.profiles.ca.expiry = cfg.profiles.ca.expiry; } if (cfg.profiles.ca.caconstraint !== undefined) { if (cfg.profiles.ca.caconstraint.isca !== undefined) { this.log.debug(`Setting CA isCA: ${cfg.profiles.ca.caconstraint.isca}`); this.config.signing.profiles.ca.caconstraint.isca = cfg.profiles.ca.caconstraint.isca; } if (cfg.profiles.ca.caconstraint.maxpathlen !== undefined) { this.log.debug(`Setting CA max pathlength: ${cfg.profiles.ca.caconstraint.maxpathlen}`); this.config.signing.profiles.ca.caconstraint.maxpathlen = cfg.profiles.ca.caconstraint.maxpathlen; } } } if (cfg.profiles.tls !== undefined) { if (cfg.profiles.tls.usage !== undefined) { this.log.debug(`Setting TLS usage: ${cfg.profiles.tls.usage}`); this.config.signing.profiles.tls.usage = [ ...new Set(cfg.profiles.tls.usage), ]; } if (cfg.profiles.tls.expiry !== undefined) { this.log.debug(`Setting TLS expiry: ${cfg.profiles.tls.expiry}`); this.config.signing.profiles.tls.expiry = cfg.profiles.tls.expiry; } } } return this; } setCSR(csr) { if (csr === undefined) return this; if (csr.cn !== undefined) { this.log.debug(`Setting CSR CN: ${csr.cn}`); this.config.csr.cn = csr.cn; } if (csr.hosts !== undefined) { this.log.debug(`Setting CSR hosts: ${csr.hosts}`); this.config.csr.hosts = [...new Set(csr.hosts)]; } if (csr.keyrequest !== undefined) { if (csr.keyrequest.algo !== undefined) { this.log.debug(`Setting CSR key request algorithm: ${csr.keyrequest.algo}`); this.config.csr.keyrequest.algo = csr.keyrequest.algo; } if (csr.keyrequest.size !== undefined) { this.log.debug(`Setting CSR key request size: ${csr.keyrequest.size}`); this.config.csr.keyrequest.size = csr.keyrequest.size; } } if (csr.names !== undefined) { this.log.debug(`Setting CSR names: ${JSON.stringify(csr.names)}`); this.config.csr.names = csr.names; } if (csr.ca !== undefined) { if (csr.ca.expiry !== undefined) { this.log.debug(`Setting CSR CA expiry: ${csr.ca.expiry}`); this.config.csr.ca.expiry = csr.ca.expiry; } if (csr.ca.pathlength !== undefined) { this.log.debug(`Setting CSR CA pathlength: ${csr.ca.pathlength}`); this.config.csr.ca.pathlength = csr.ca.pathlength; } } return this; } setIdemix(idemix) { if (idemix === undefined) return this; if (idemix.nonceexpiration !== undefined) { this.log.debug(`Setting Idemix nonce expiration: ${idemix.nonceexpiration}`); this.config.idemix.nonceexpiration = idemix.nonceexpiration; } if (idemix.curve !== undefined) { this.log.debug(`Setting Idemix curve: ${idemix.curve}`); this.config.idemix.curve = idemix.curve; } if (idemix.noncesweepinterval !== undefined) { this.log.debug(`Setting Idemix noncesweep interval: ${idemix.noncesweepinterval}`); this.config.idemix.noncesweepinterval = idemix.noncesweepinterval; } if (idemix.rhpoolsize !== undefined) { this.log.debug(`Setting Idemix rhpoolsize: ${idemix.rhpoolsize}`); this.config.idemix.rhpoolsize = idemix.rhpoolsize; } return this; } setBCCSP(bccsp) { if (bccsp === undefined) return this; if (bccsp.default !== undefined) { this.log.debug(`Setting default BCCSP: ${bccsp.default}`); this.config.bccsp.default = bccsp.default; } if (bccsp.sw !== undefined) { if (bccsp.sw.hash !== undefined) { this.log.debug(`Setting BCCSP hash: ${bccsp.sw.hash}`); this.config.bccsp.sw.hash = bccsp.sw.hash; } if (bccsp.sw.security !== undefined) { this.log.debug(`Setting BCCSP security: ${bccsp.sw.security}`); this.config.bccsp.sw.security = bccsp.sw.security; } if (bccsp.sw.filekeystore !== undefined) { if (bccsp.sw.filekeystore.keystore !== undefined) { this.log.debug(`Setting BCCSP filekeystore keystore: ${bccsp.sw.filekeystore.keystore}`); this.config.bccsp.sw.filekeystore.keystore = bccsp.sw.filekeystore.keystore; } } } return this; } setCACount(count) { if (count !== undefined) { this.log.debug(`Setting CA count: ${count}`); this.config.cacount = count; } return this; } setCAFiles(files) { if (files !== undefined) { this.log.debug(`Setting CA files: ${files.join(", ")}`); this.config.cafiles = files; } 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.config.intermediate.parentserver.url = int.parentserver.url; } if (int.parentserver.caname !== undefined) { this.log.debug(`Setting intermediate CA parent server caname: ${int.parentserver.caname}`); this.config.intermediate.parentserver.caname = int.parentserver.caname; } } if (int.enrollment !== undefined) { if (int.enrollment.hosts !== undefined) { this.log.debug(`Setting intermediate CA enrollment hosts: ${int.enrollment.hosts.join(", ")}`); this.config.intermediate.enrollment.hosts = int.enrollment.hosts; } if (int.enrollment.profile !== undefined) { this.log.debug(`Setting intermediate CA enrollment profile: ${int.enrollment.profile}`); this.config.intermediate.enrollment.profile = int.enrollment.profile; } if (int.enrollment.label !== undefined) { this.log.debug(`Setting intermediate CA enrollment label: ${int.enrollment.label}`); this.config.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.config.intermediate.tls.certfiles = int.tls.certfiles; } 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.config.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.config.intermediate.tls.client.keyfile = int.tls.client.keyfile; } } } return this; } setPasswordAttempts(attempts) { if (attempts !== undefined) { this.log.debug(`Setting password attempts: ${attempts}`); this.config.cfg.identities.passwordattempts = attempts; } return this; } setOperations(operations) { if (operations === undefined) return this; if (operations.listenAddress !== undefined) { this.log.debug(`Setting operations listen address: ${operations.listenAddress}`); this.config.operations.listenAddress = operations.listenAddress; } if (operations.tls !== undefined) { if (operations.tls.enabled !== undefined) { this.log.debug(`Setting operations TLS enabled: ${operations.tls.enabled}`); this.config.operations.tls.enabled = operations.tls.enabled; } if (operations.tls.cert !== undefined) { if (operations.tls.cert.file !== undefined) { this.log.debug(`Setting operations TLS cert file: ${operations.tls.cert.file}`); this.config.operations.tls.cert.file = operations.tls.cert.file; } } if (operations.tls.key !== undefined) { if (operations.tls.key.file !== undefined) { this.log.debug(`Setting operations TLS key file: ${operations.tls.key.file}`); this.config.operations.tls.key.file = operations.tls.key.file; } } if (operations.tls.clientAuthRequired !== undefined) { this.log.debug(`Setting operations TLS client authentication required: ${operations.tls.clientAuthRequired}`); this.config.operations.tls.clientAuthRequired = operations.tls.clientAuthRequired; } if (operations.tls.clientRootCAs !== undefined) { if (operations.tls.clientRootCAs.files !== undefined) { this.log.debug(`Setting operations TLS client root CAs files: ${operations.tls.clientRootCAs.files.join(", ")}`); this.config.operations.tls.clientRootCAs.files = operations.tls.clientRootCAs.files; } } } return this; } setMetrics(metrics) { if (metrics === undefined) return this; if (metrics.provider !== undefined) { this.log.debug(`Setting metrics provider: ${metrics.provider}`); this.config.metrics.provider = metrics.provider; } if (metrics.statsd !== undefined) { if (metrics.statsd.network !== undefined) { this.log.debug(`Setting metrics statsd network: ${metrics.statsd.network}`); this.config.metrics.statsd.network = metrics.statsd.network; } if (metrics.statsd.address !== undefined) { this.log.debug(`Setting metrics statsd address: ${metrics.statsd.address}`); this.config.metrics.statsd.address = metrics.statsd.address; } if (metrics.statsd.writeInterval !== undefined) { this.log.debug(`Setting metrics statsd write interval: ${metrics.statsd.writeInterval}`); this.config.metrics.statsd.writeInterval = metrics.statsd.writeInterval; } if (metrics.statsd.prefix !== undefined) { this.log.debug(`Setting metrics statsd prefix: ${metrics.statsd.prefix}`); this.config.metrics.statsd.prefix = metrics.statsd.prefix; } } return this; } /** * @description Saves the current configuration to a file. * @summary Writes the current Fabric CA Server configuration to a YAML file at the specified path. If the directory doesn't exist, it will be created. * @param {string} cpath - The path where the configuration file should be saved. * @return {this} The current instance of the builder for method chaining. * @example * const builder = new FabricCAServerCommandBuilder(); * builder.save('/path/to/config/fabric-ca-server.yaml'); * * @mermaid * sequenceDiagram * participant Client * participant Builder as FabricCAServerCommandBuilder * participant FileSystem as File System * Client->>Builder: saveConfig('/path/to/config/fabric-ca-server.yaml') * Builder->>Builder: Check if cpath is defined * alt cpath is defined * Builder->>FileSystem: Check if directory exists * alt Directory doesn't exist * Builder->>FileSystem: Create directory * end * Builder->>Builder: Log debug message * Builder->>FileSystem: Write YAML configuration to file * end * Builder-->>Client: Return this */ save(cpath) { if (cpath === undefined) return this; if (!fs.existsSync(path.join(cpath))) fs.mkdirSync(path.join(cpath), { recursive: true }); if (!cpath.endsWith(".yaml")) cpath = path.join(cpath, "fabric-ca-server-config.yaml"); this.log.debug(`Writing configuration to ${cpath}`); this.log.debug(`Config file: ${JSON.stringify(this.config, null, 2)}`); writeFileYaml(cpath, this.config); return this; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFicmljLWNhLXNlcnZlci1jb25maWctYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9mYWJyaWMvZmFicmljLWNhLXNlcnZlci9mYWJyaWMtY2Etc2VydmVyLWNvbmZpZy1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBVSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBZS9ELE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFNcEIsTUFBTSxPQUFPLDJCQUEyQjtJQU90QyxZQUFZLE1BQWU7UUFKbkIsV0FBTSxHQUF5QixZQUFZLENBQ2pELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLDhDQUE4QyxDQUFDLENBQzdDLENBQUM7UUFHeEIsSUFBSSxDQUFDLE1BQU07WUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLENBQUMsQ0FBQzs7WUFDNUQsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRCxVQUFVLENBQUMsT0FBZ0I7UUFDekIsSUFBSSxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDOUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ2hDLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE9BQU8sQ0FBQyxJQUFhO1FBQ25CLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGlCQUFpQixJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUMxQixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsT0FBTyxDQUFDLElBQWlCO1FBQ3ZCLElBQUksSUFBSSxLQUFLLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVwQyxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztZQUN2QyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUMzQyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHlCQUF5QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUMzQyxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxXQUFXLENBQUMsTUFBZ0I7UUFDMUIsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO1FBQzdCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxlQUFlLENBQUMsWUFBcUI7UUFDbkMsSUFBSSxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsMkJBQTJCLFlBQVksRUFBRSxDQUFDLENBQUM7WUFDMUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQzFDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxZQUFZLENBQUMsU0FBMkI7UUFDdEMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUU1QixJQUFJLFNBQVMsQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQztRQUMvQyxDQUFDO1FBRUQsSUFBSSxTQUFTLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDBCQUEwQixTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQztRQUNqRCxDQUFDO1FBRUQsSUFBSSxTQUFTLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHlCQUF5QixTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM3RCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQztRQUMvQyxDQUFDO1FBRUQsSUFBSSxTQUFTLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3ZDLElBQUksU0FBUyxDQUFDLFVBQVUsQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2pELElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLGlDQUFpQyxTQUFTLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUNsRSxDQUFDO2dCQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBSSxDQUFDLFVBQVcsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUM7WUFDMUUsQ0FBQztZQUVELElBQUksU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzVDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLGlDQUFpQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUM3RCxDQUFDO2dCQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBSSxDQUFDLFVBQVcsQ0FBQyxJQUFJLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7WUFDaEUsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBaUI7UUFDckIsSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPLElBQUksQ0FBQztRQUV6QixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO1FBQ3JDLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsd0JBQXdCLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQzNDLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMseUJBQXlCLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQzNELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO1FBQzdDLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRyxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO1FBQy9DLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyx3QkFBd0IsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNsRCxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixxQ0FBcUMsTUFBTSxDQUFDLHdCQUF3QixFQUFFLENBQ3ZFLENBQUM7WUFDRixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUcsQ0FBQyx3QkFBd0I7Z0JBQ3RDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQztRQUNwQyxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsWUFBWSxDQUFDLFNBQWtCO1FBQzdCLElBQUksU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHVCQUF1QixTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7UUFDdEMsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGFBQWEsQ0FBQyxHQUEyQjtRQUN2QyxJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7Z0JBQUUsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFckMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsdUJBQXVCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzdELE1BQU0sWUFBWSxHQUFhLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUyxDQUFDLFVBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwRSxNQUFNLFVBQVUsR0FBZSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBWSxFQUFFLEVBQUU7Z0JBQ3RELE1BQU0sUUFBUSxHQUFHLEVBQUUsR0FBRyxZQUFZLEVBQUUsQ0FBQztnQkFDckMsSUFBSSxFQUFFLENBQUMsSUFBSSxLQUFLLFNBQVM7b0JBQUUsUUFBUSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO2dCQUNuRCxJQUFJLEVBQUUsQ0FBQyxJQUFJLEtBQUssU0FBUztvQkFBRSxRQUFRLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7Z0JBQ25ELElBQUksRUFBRSxDQUFDLElBQUksS0FBSyxTQUFTO29CQUFFLFFBQVEsQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztnQkFDbkQsSUFBSSxFQUFFLENBQUMsV0FBVyxLQUFLLFNBQVM7b0JBQUUsUUFBUSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDO2dCQUN4RSxJQUFJLEVBQUUsQ0FBQyxLQUFLLEtBQUssU0FBUztvQkFDeEIsUUFBUSxDQUFDLEtBQUssR0FBRyxvQkFBb0IsQ0FDbkMsUUFBUSxDQUFDLEtBRVIsRUFDRCxFQUFFLENBQUMsS0FBSyxDQUNULENBQUM7Z0JBRUosT0FBTyxRQUFRLENBQUM7WUFDbEIsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVMsQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQ2hELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxjQUF1QjtRQUN2QyxJQUFJLGNBQWMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsY0FBYyxFQUFFLENBQUMsQ0FBQztZQUM3RCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVMsQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1FBQ3hELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxXQUFXLENBQUMsR0FBYztRQUN4QixJQUFJLEdBQUcsS0FBSyxTQUFTO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFbkMsSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzNCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDBCQUEwQixHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQztRQUNsQyxDQUFDO1FBQ0QsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNqRSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUcsQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQztRQUM5QyxDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzFCLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHdCQUF3QixHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQzFELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRyxDQUFDLEdBQUksQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7WUFDakQsQ0FBQztZQUVELElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDBCQUEwQixHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7Z0JBQzlELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRyxDQUFDLEdBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7WUFDckQsQ0FBQztZQUVELElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2pDLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUMxQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixnQ0FBZ0MsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQzFELENBQUM7b0JBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFHLENBQUMsR0FBSSxDQUFDLE1BQU8sQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO2dCQUNsRSxDQUFDO2dCQUVELElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUN6QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWiwrQkFBK0IsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQ3hELENBQUM7b0JBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFHLENBQUMsR0FBSSxDQUFDLE1BQU8sQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO2dCQUNoRSxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLENBQUMsSUFBaUI7UUFDdkIsSUFBSSxJQUFJLEtBQUssU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRXBDLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDM0MsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFLLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDbkMsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQywwQkFBMEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO2dCQUMvRCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUssQ0FBQyxHQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDO1lBQ3hELENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNsQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDM0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osZ0NBQWdDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUMzRCxDQUFDO29CQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSyxDQUFDLEdBQUksQ0FBQyxNQUFPLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztnQkFDckUsQ0FBQztnQkFFRCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDMUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osK0JBQStCLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUN6RCxDQUFDO29CQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSyxDQUFDLEdBQUksQ0FBQyxNQUFPLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztnQkFDbkUsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7Z0JBQ3hFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSyxDQUFDLFNBQVUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7WUFDNUQsQ0FBQztZQUVELElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzVDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHNDQUFzQyxJQUFJLENBQUMsU0FBUyxDQUNsRCxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FDMUIsRUFBRSxDQUNKLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFLLENBQUMsU0FBVSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQztZQUN0RSxDQUFDO1lBRUQsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osZ0NBQWdDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUN0RSxDQUFDO2dCQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSyxDQUFDLFNBQVUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7WUFDMUQsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxlQUFlLENBQUMsWUFBMEM7UUFDeEQsSUFBSSxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMseUJBQXlCLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3hFLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUMxQyxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BMEJHO0lBQ0gsb0JBQW9CLENBQ2xCLG1CQUE0QixLQUFLLEVBQ2pDLGtCQUEyQixLQUFLO1FBRWhDLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQ3ZDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEdBQUcsQ0FBQztRQUM1QyxDQUFDO1FBQ0QsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBQ3RDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQztRQUMzQyxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsVUFBVSxDQUFDLEdBQW1CO1FBQzVCLElBQUksR0FBRyxLQUFLLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVuQyxJQUFJLEdBQUcsQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDOUIsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztnQkFDOUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFRLENBQUMsT0FBUSxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ3hFLENBQUM7WUFFRCxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQVEsQ0FBQyxPQUFRLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQzVELENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUN4QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztvQkFDN0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFRLENBQUMsUUFBUyxDQUFDLEVBQUcsQ0FBQyxLQUFLLEdBQUc7d0JBQ3pDLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO3FCQUNsQyxDQUFDO2dCQUNKLENBQUM7Z0JBRUQsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQ3pDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHNCQUFzQixHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO29CQUMvRCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQVEsQ0FBQyxRQUFTLENBQUMsRUFBRyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUM7Z0JBQ3JFLENBQUM7Z0JBRUQsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQy9DLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQzt3QkFDcEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osb0JBQW9CLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FDeEQsQ0FBQzt3QkFDRixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQVEsQ0FBQyxRQUFTLENBQUMsRUFBRyxDQUFDLFlBQWEsQ0FBQyxJQUFJOzRCQUNuRCxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO29CQUN0QyxDQUFDO29CQUVELElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQzt3QkFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osOEJBQThCLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsQ0FDeEUsQ0FBQzt3QkFDRixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQVEsQ0FBQyxRQUFTLENBQUMsRUFBRyxDQUFDLFlBQWEsQ0FBQyxVQUFVOzRCQUN6RCxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDO29CQUM1QyxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDbkMsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQ3pDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHNCQUFzQixHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO29CQUMvRCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQVEsQ0FBQyxRQUFTLENBQUMsR0FBSSxDQUFDLEtBQUssR0FBRzt3QkFDMUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUM7cUJBQ25DLENBQUM7Z0JBQ0osQ0FBQztnQkFFRCxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDMUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7b0JBQ2pFLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBUSxDQUFDLFFBQVMsQ0FBQyxHQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztnQkFDdkUsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxDQUFDLEdBQWU7UUFDcEIsSUFBSSxHQUFHLEtBQUssU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRW5DLElBQUksR0FBRyxDQUFDLEVBQUUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDL0IsQ0FBQztRQUVELElBQUksR0FBRyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHNDQUFzQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUM1RCxDQUFDO2dCQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBSSxDQUFDLFVBQVcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7WUFDMUQsQ0FBQztZQUNELElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ3ZFLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBSSxDQUFDLFVBQVcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7WUFDMUQsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztRQUNyQyxDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsRUFBRSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3pCLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2hDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDBCQUEwQixHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7Z0JBQzFELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBSSxDQUFDLEVBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUM7WUFDOUMsQ0FBQztZQUNELElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDhCQUE4QixHQUFHLENBQUMsRUFBRSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7Z0JBQ2xFLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBSSxDQUFDLEVBQUcsQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUM7WUFDdEQsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxTQUFTLENBQUMsTUFBcUI7UUFDN0IsSUFBSSxNQUFNLEtBQUssU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRXRDLElBQUksTUFBTSxDQUFDLGVBQWUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN6QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixvQ0FBb0MsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUM3RCxDQUFDO1lBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFPLENBQUMsZUFBZSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUM7UUFDL0QsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFPLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDM0MsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLGtCQUFrQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHVDQUF1QyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FDbkUsQ0FBQztZQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTyxDQUFDLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQztRQUNyRSxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDhCQUE4QixNQUFNLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU8sQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQztRQUNyRCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQW1CO1FBQzFCLElBQUksS0FBSyxLQUFLLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVyQyxJQUFJLEtBQUssQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQzFELElBQUksQ0FBQyxNQUFNLENBQUMsS0FBTSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQzdDLENBQUM7UUFFRCxJQUFJLEtBQUssQ0FBQyxFQUFFLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDM0IsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDaEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDdkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFNLENBQUMsRUFBRyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQztZQUM5QyxDQUFDO1lBRUQsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEtBQUssQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztnQkFDL0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFNLENBQUMsRUFBRyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQztZQUN0RCxDQUFDO1lBQ0QsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQ2pELElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHdDQUF3QyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FDekUsQ0FBQztvQkFDRixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQU0sQ0FBQyxFQUFHLENBQUMsWUFBYSxDQUFDLFFBQVE7d0JBQzNDLEtBQUssQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztnQkFDbkMsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsVUFBVSxDQUFDLEtBQWM7UUFDdkIsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMscUJBQXFCLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQzlCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxVQUFVLENBQUMsS0FBZ0I7UUFDekIsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMscUJBQXFCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUM5QixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsZUFBZSxDQUFDLEdBQXlCO1FBQ3ZDLElBQUksR0FBRyxLQUFLLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVuQyxJQUFJLEdBQUcsQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkMsSUFBSSxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osOENBQThDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQ3JFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFhLENBQUMsWUFBYSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcs