@decaf-ts/fabric-weaver
Version:
template for ts projects
201 lines • 37.3 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.issuePeer = issuePeer;
exports.startPeer = startPeer;
exports.bootPeer = bootPeer;
exports.hasPeerInitialized = hasPeerInitialized;
exports.peerFetchGenesisBlock = peerFetchGenesisBlock;
exports.peerJoinChannel = peerJoinChannel;
exports.packageChaincode = packageChaincode;
exports.installChaincode = installChaincode;
exports.approveChaincode = approveChaincode;
exports.commitChainCode = commitChainCode;
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const logging_1 = require("@decaf-ts/logging");
const fabric_peer_config_builder_1 = require("../../fabric/peer/fabric-peer-config-builder.cjs");
const fabric_peer_node_command_builder_1 = require("../../fabric/peer/fabric-peer-node-command-builder.cjs");
const fabric_peer_1 = require("../../fabric/constants/fabric-peer.cjs");
const fabric_peer_channel_command_builder_1 = require("../../fabric/peer/fabric-peer-channel-command-builder.cjs");
const fabric_peer_lifecycle_chaincode_command_builder_1 = require("../../fabric/peer/fabric-peer-lifecycle-chaincode-command-builder.cjs");
const child_process_1 = require("child_process");
function issuePeer(log, cpath, gossip, tls, authTimeWindow, keepAlive, gateway, general, bccsp, msp, clientConnectionTimeout, delivery, profile, handlers, discovery, limits, msgSize, chaincode, state, blockchain, enableLedgerHistoryDatabase, pvtData, ledgerSnapshosRootDir, operation, metrics, vm) {
const logger = logging_1.Logging.for(issuePeer);
log.debug(`Issuing Peer...`);
log.debug(`Writing configuration to ${cpath}`);
const builder = new fabric_peer_config_builder_1.FabricPeerConfigBuilder(logger);
builder
.setGossip(gossip)
.setTLS(tls)
.setLedgerSnapshotsRootDir(ledgerSnapshosRootDir)
.setOperations(operation)
.setMetrics(metrics)
.enableLedgerHistoryDatabase(enableLedgerHistoryDatabase)
.setLedgerPvtDataStore(pvtData)
.setHandlers(handlers)
.setDiscovery(discovery)
.setLimits(limits)
.setMessageSize(msgSize)
.setChaincode(chaincode)
.setLedgerState(state)
.setLegerBlockchain(blockchain)
.setAuthentication(authTimeWindow)
.setKeepAlice(keepAlive)
.setGateway(gateway)
.setGeneral(general)
.setBCCSP(bccsp)
.setMspConfig(msp)
.setConnTimeoutClient(clientConnectionTimeout)
.setDeliveryClient(delivery)
.setProfile(profile)
.setVMOptions(vm)
.save(cpath);
}
async function startPeer(logger) {
const log = logger.for(startPeer);
log.debug(`Starting Peer`);
const builder = new fabric_peer_node_command_builder_1.FabricPeerNodeCommandBuilder(log);
builder.setCommand(fabric_peer_1.PeerNodeCommands.START).execute();
}
async function bootPeer(log, cpath, gossip, tls, authTimeWindow, keepAlive, gateway, general, bccsp, msp, clientConnectionTimeout, delivery, profile, handlers, discovery, limits, msgSize, chaincode, state, blockchain, enableLedgerHistoryDatabase, pvtData, ledgerSnapshosRootDir, operation, metrics, vm) {
const logger = logging_1.Logging.for(bootPeer);
log.debug(`Booting Peer...`);
if (!hasPeerInitialized(cpath))
issuePeer(logger, cpath, gossip, tls, authTimeWindow, keepAlive, gateway, general, bccsp, msp, clientConnectionTimeout, delivery, profile, handlers, discovery, limits, msgSize, chaincode, state, blockchain, enableLedgerHistoryDatabase, pvtData, ledgerSnapshosRootDir, operation, metrics, vm);
startPeer(logger);
}
function hasPeerInitialized(fileLocation) {
const log = logging_1.Logging.for(hasPeerInitialized);
const defaultFileLocation = path_1.default.join(__dirname, "../../../peer/core.yaml");
if (!fileLocation) {
log.debug(`No file location provided, using default file location: ${defaultFileLocation}`);
fileLocation = defaultFileLocation;
}
else {
if (!fileLocation.endsWith(".yaml"))
fileLocation = path_1.default.join(fileLocation, "core.yaml");
log.debug(`Using provided file location: ${fileLocation}`);
}
const booted = fs_1.default.existsSync(fileLocation);
log.debug(`Peer has been booted: ${booted}`);
return booted;
}
function peerFetchGenesisBlock(logger, channelID, ordererAddress, blockNumber, outputFile, tlsEnabled, tlsCACertFile) {
const log = logging_1.Logging.for(peerFetchGenesisBlock);
log.debug(`Fetching Genesis Block`);
const builder = new fabric_peer_channel_command_builder_1.FabricPeerChannelCommandBuilder(logger);
builder
.enableTLS(tlsEnabled)
.setCommand(fabric_peer_1.PeerChannelCommands.FETCH)
.setBlockReference(blockNumber)
.setDestination(outputFile)
.setOrderer(ordererAddress)
.setChannelID(channelID)
.setTLSCAFile(tlsCACertFile)
.execute();
}
async function peerJoinChannel(logger, blockPath) {
const log = logging_1.Logging.for(peerJoinChannel);
log.debug(`Joining Channel`);
const builder = new fabric_peer_channel_command_builder_1.FabricPeerChannelCommandBuilder(logger);
builder
.setCommand(fabric_peer_1.PeerChannelCommands.JOIN)
.setBlockPath(blockPath)
.execute();
}
function packageChaincode(logger, outputFile, contractPath, lang, contractName, contractVersion) {
const log = logging_1.Logging.for(packageChaincode);
log.debug(`Packaging Chaincode`);
const builder = new fabric_peer_lifecycle_chaincode_command_builder_1.FabricPeerLifecycleChaincodeCommandBuilder(logger);
builder
.setCommand(fabric_peer_1.PeerLifecycleChaincodeCommands.PACKAGE)
.setDestination(outputFile)
.setContractPath(contractPath)
.setLang(lang)
.setLabel(`${contractName}_${contractVersion}`)
.execute();
}
function installChaincode(logger, contractLocation) {
const log = logging_1.Logging.for(installChaincode);
log.debug(`Installing Chaincode`);
const builder = new fabric_peer_lifecycle_chaincode_command_builder_1.FabricPeerLifecycleChaincodeCommandBuilder(logger);
builder
.setCommand(fabric_peer_1.PeerLifecycleChaincodeCommands.INSTALL)
.setDestination(contractLocation)
.execute();
}
function approveChaincode(logger, ordererAddress, channelID, chaincodeName, version, sequence, enableTLS, tlsCACertFile, collectionConfigPath, ordererTLSHostnameOverride) {
const log = logging_1.Logging.for(installChaincode);
log.debug(`Approve Chaincode`);
const builder = new fabric_peer_lifecycle_chaincode_command_builder_1.FabricPeerLifecycleChaincodeCommandBuilder(logger);
const id = (0, child_process_1.execSync)(builder.setCommand(fabric_peer_1.PeerLifecycleChaincodeCommands.QUERYINSTALLED).build());
log.debug(`Using id: ${id}`);
builder
.setCommand(fabric_peer_1.PeerLifecycleChaincodeCommands.APPROVEFORMYORG)
.setOrdererAddress(ordererAddress)
.setChannelID(channelID)
.setContractName(chaincodeName)
.setVersion(version)
.setSequence(sequence)
.enableTLS(enableTLS)
.setTLSCAFile(tlsCACertFile)
.setOrdererTLSHostnameOverride(ordererTLSHostnameOverride)
.setCollectionsConfigPath(collectionConfigPath)
.setPackageID(id
.toString()
.split(",")[0]
.split("\n")[1]
.split(":")
.slice(1)
.map((s) => s.trim())
.join(":"))
.execute();
}
async function commitChainCode(logger, ordererAddress, channelID, chaincodeName, version, sequence, enableTLS, tlsCACertFile, collectionConfigPath, ordererTLSHostnameOverride, peerAddresses, peerTLSRoots) {
const log = logging_1.Logging.for(commitChainCode);
log.info(`Commiting chaincode`);
const checkChaincodeReadiness = function (logger, channelID, chaincodeName, version, sequence, enableTLS, tlsCACertFile) {
const verificationBuilder = new fabric_peer_lifecycle_chaincode_command_builder_1.FabricPeerLifecycleChaincodeCommandBuilder(logger);
const approvalData = (0, child_process_1.execSync)(verificationBuilder
.setCommand(fabric_peer_1.PeerLifecycleChaincodeCommands.CHECKCOMMITREADINESS)
.setChannelID(channelID)
.setContractName(chaincodeName)
.setVersion(version)
.setSequence(sequence)
.enableTLS(enableTLS)
.setTLSCAFile(tlsCACertFile)
.setOutput("json")
.build()).toString();
const approvalJSON = JSON.parse(approvalData);
log.info(JSON.stringify(approvalJSON, null, 2));
return (Object.keys(approvalJSON.approvals).filter((key) => approvalJSON.approvals[key] == true).length >
Object.keys(approvalJSON.approvals).length / 2);
};
const commitWhenReady = function (logger, ordererAddress, channelID, chaincodeName, version, sequence, enableTLS, tlsCACertFile, collectionConfigPath, ordererTLSHostnameOverride, peerAddresses, peerTLSRoots) {
if (!checkChaincodeReadiness(logger, channelID, chaincodeName, version, sequence, enableTLS, tlsCACertFile)) {
log.info("Chaincode not ready, waiting...");
return setTimeout(() => {
commitWhenReady(logger, ordererAddress, channelID, chaincodeName, version, sequence, enableTLS, tlsCACertFile, collectionConfigPath, ordererTLSHostnameOverride, peerAddresses, peerTLSRoots);
}, 30000);
}
new fabric_peer_lifecycle_chaincode_command_builder_1.FabricPeerLifecycleChaincodeCommandBuilder(logger)
.setCommand(fabric_peer_1.PeerLifecycleChaincodeCommands.COMMIT)
.setOrdererAddress(ordererAddress)
.setChannelID(channelID)
.setContractName(chaincodeName)
.setVersion(version)
.setSequence(sequence)
.enableTLS(enableTLS)
.setTLSCAFile(tlsCACertFile)
.setCollectionsConfigPath(collectionConfigPath)
.setOrdererTLSHostnameOverride(ordererTLSHostnameOverride)
.setPeerAddresses(peerAddresses)
.setPeerTLSRoots(peerTLSRoots)
.execute();
};
commitWhenReady(logger, ordererAddress, channelID, chaincodeName, version, sequence, enableTLS, tlsCACertFile, collectionConfigPath, ordererTLSHostnameOverride, peerAddresses, peerTLSRoots);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb3JlL3NjcmlwdHMvcGVlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQXFDQSw4QkE0REM7QUFFRCw4QkFPQztBQUVELDRCQThEQztBQUVELGdEQXFCQztBQUVELHNEQXVCQztBQUVELDBDQVVDO0FBRUQsNENBb0JDO0FBRUQsNENBVUM7QUFFRCw0Q0E2Q0M7QUFFRCwwQ0FpSUM7QUExYkQsZ0RBQXdCO0FBQ3hCLDRDQUFvQjtBQUNwQiwrQ0FBb0Q7QUFDcEQsNkZBQXVGO0FBd0J2Rix5R0FBa0c7QUFDbEcsb0VBSTRDO0FBQzVDLCtHQUF3RztBQUN4Ryx1SUFBK0g7QUFDL0gsaURBQXlDO0FBRXpDLFNBQWdCLFNBQVMsQ0FDdkIsR0FBVyxFQUNYLEtBQWEsRUFDYixNQUFxQixFQUNyQixHQUFlLEVBQ2YsY0FBdUIsRUFDdkIsU0FBMkIsRUFDM0IsT0FBdUIsRUFDdkIsT0FBdUIsRUFDdkIsS0FBbUIsRUFDbkIsR0FBZSxFQUNmLHVCQUFnQyxFQUNoQyxRQUErQixFQUMvQixPQUF1QixFQUN2QixRQUF5QixFQUN6QixTQUEyQixFQUMzQixNQUFxQixFQUNyQixPQUF1QixFQUN2QixTQUEyQixFQUMzQixLQUF5QixFQUN6QixVQUFnQixFQUNoQiwyQkFBcUMsRUFDckMsT0FBZ0MsRUFDaEMscUJBQThCLEVBQzlCLFNBQTRCLEVBQzVCLE9BQXVCLEVBQ3ZCLEVBQWE7SUFFYixNQUFNLE1BQU0sR0FBRyxpQkFBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0QyxHQUFHLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDN0IsR0FBRyxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUUvQyxNQUFNLE9BQU8sR0FBRyxJQUFJLG9EQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRXBELE9BQU87U0FD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R0FBRyxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBQzVDLE9BQU8sVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDckIsZUFBZSxDQUNiLE1BQU0sRUFDTixjQUFjLEVBQ2QsU0FBUyxFQUNULGFBQWEsRUFDYixPQUFPLEVBQ1AsUUFBUSxFQUNSLFNBQVMsRUFDVCxhQUFhLEVBQ2Isb0JBQW9CLEVBQ3BCLDBCQUEwQixFQUMxQixhQUFhLEVBQ2IsWUFBWSxDQUNiLENBQUM7WUFDSixDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDWixDQUFDO1FBRUQsSUFBSSw0RkFBMEMsQ0FBQyxNQUFNLENBQUM7YUFDbkQsVUFBVSxDQUFDLDRDQUE4QixDQUFDLE1BQU0sQ0FBQzthQUNqRCxpQkFBaUIsQ0FBQyxjQUFjLENBQUM7YUFDakMsWUFBWSxDQUFDLFNBQVMsQ0FBQzthQUN2QixlQUFlLENBQUMsYUFBYSxDQUFDO2FBQzlCLFVBQVUsQ0FBQyxPQUFPLENBQUM7YUFDbkIsV0FBVyxDQUFDLFFBQVEsQ0FBQzthQUNyQixTQUFTLENBQUMsU0FBUyxDQUFDO2FBQ3BCLFlBQVksQ0FBQyxhQUFhLENBQUM7YUFDM0Isd0JBQXdCLENBQUMsb0JBQW9CLENBQUM7YUFDOUMsNkJBQTZCLENBQUMsMEJBQTBCLENBQUM7YUFDekQsZ0JBQWdCLENBQUMsYUFBYSxDQUFDO2FBQy9CLGVBQWUsQ0FBQyxZQUFZLENBQUM7YUFDN0IsT0FBTyxFQUFFLENBQUM7SUFDZixDQUFDLENBQUM7SUFFRixlQUFlLENBQ2IsTUFBTSxFQUNOLGNBQWMsRUFDZCxTQUFTLEVBQ1QsYUFBYSxFQUNiLE9BQU8sRUFDUCxRQUFRLEVBQ1IsU0FBUyxFQUNULGFBQWEsRUFDYixvQkFBb0IsRUFDcEIsMEJBQTBCLEVBQzFCLGFBQWEsRUFDYixZQUFZLENBQ2IsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBGYWJyaWNQZWVyQ29uZmlnQnVpbGRlciB9IGZyb20gXCIuLi8uLi9mYWJyaWMvcGVlci9mYWJyaWMtcGVlci1jb25maWctYnVpbGRlclwiO1xuaW1wb3J0IHtcbiAgQkNDU1BDb25maWcsXG4gIENoYWluY29kZUNvbmZpZyxcbiAgRGVsaXZlcnlDbGllbnRDb25maWcsXG4gIERpc2NvdmVyeUNvbmZpZyxcbiAgR2F0ZXdheUNvbmZpZyxcbiAgR2VuZXJhbENvbmZpZyxcbiAgR29zc2lwQ29uZmlnLFxuICBIYW5kbGVyc0NvbmZpZyxcbiAgS2VlcEFsaXZlQ29uZmlnLFxuICBMZWRnZXJTdGF0ZUNvbmZpZyxcbiAgTGltaXRzQ29uZmlnLFxuICBNU0dTaXplQ29uZmlnLFxuICBNU1BDb25maWcsXG4gIFByaXZhdGVEYXRhU3RvcmVDb25maWcsXG4gIFByb2ZpbGVDb25maWcsXG4gIFRMU0NvbmZpZyxcbiAgVk1Db25maWcsXG59IGZyb20gXCIuLi8uLi9mYWJyaWMvaW50ZXJmYWNlcy9mYWJyaWMvcGVlci1jb25maWdcIjtcbmltcG9ydCB7XG4gIE1ldHJpY3NDb25maWcsXG4gIE9wZXJhdGlvbnNDb25maWcsXG59IGZyb20gXCIuLi8uLi9mYWJyaWMvaW50ZXJmYWNlcy9mYWJyaWMvZ2VuZXJhbC1jb25maWdzXCI7XG5pbXBvcnQgeyBGYWJyaWNQZWVyTm9kZUNvbW1hbmRCdWlsZGVyIH0gZnJvbSBcIi4uLy4uL2ZhYnJpYy9wZWVyL2ZhYnJpYy1wZWVyLW5vZGUtY29tbWFuZC1idWlsZGVyXCI7XG5pbXBvcnQge1xuICBQZWVyQ2hhbm5lbENvbW1hbmRzLFxuICBQZWVyTGlmZWN5Y2xlQ2hhaW5jb2RlQ29tbWFuZHMsXG4gIFBlZXJOb2RlQ29tbWFuZHMsXG59IGZyb20gXCIuLi8uLi9mYWJyaWMvY29uc3RhbnRzL2ZhYnJpYy1wZWVyXCI7XG5pbXBvcnQgeyBGYWJyaWNQZWVyQ2hhbm5lbENvbW1hbmRCdWlsZGVyIH0gZnJvbSBcIi4uLy4uL2ZhYnJpYy9wZWVyL2ZhYnJpYy1wZWVyLWNoYW5uZWwtY29tbWFuZC1idWlsZGVyXCI7XG5pbXBvcnQgeyBGYWJyaWNQZWVyTGlmZWN5Y2xlQ2hhaW5jb2RlQ29tbWFuZEJ1aWxkZXIgfSBmcm9tIFwiLi4vLi4vZmFicmljL3BlZXIvZmFicmljLXBlZXItbGlmZWN5Y2xlLWNoYWluY29kZS1jb21tYW5kLWJ1aWxkZXJcIjtcbmltcG9ydCB7IGV4ZWNTeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzc3VlUGVlcihcbiAgbG9nOiBMb2dnZXIsXG4gIGNwYXRoOiBzdHJpbmcsXG4gIGdvc3NpcD86IEdvc3NpcENvbmZpZyxcbiAgdGxzPzogVExTQ29uZmlnLFxuICBhdXRoVGltZVdpbmRvdz86IHN0cmluZyxcbiAga2VlcEFsaXZlPzogS2VlcEFsaXZlQ29uZmlnLFxuICBnYXRld2F5PzogR2F0ZXdheUNvbmZpZyxcbiAgZ2VuZXJhbD86IEdlbmVyYWxDb25maWcsXG4gIGJjY3NwPzogQkNDU1BDb25maWcsXG4gIG1zcD86IE1TUENvbmZpZyxcbiAgY2xpZW50Q29ubmVjdGlvblRpbWVvdXQ/OiBzdHJpbmcsXG4gIGRlbGl2ZXJ5PzogRGVsaXZlcnlDbGllbnRDb25maWcsXG4gIHByb2ZpbGU/OiBQcm9maWxlQ29uZmlnLFxuICBoYW5kbGVycz86IEhhbmRsZXJzQ29uZmlnLFxuICBkaXNjb3Zlcnk/OiBEaXNjb3ZlcnlDb25maWcsXG4gIGxpbWl0cz86IExpbWl0c0NvbmZpZyxcbiAgbXNnU2l6ZT86IE1TR1NpemVDb25maWcsXG4gIGNoYWluY29kZT86IENoYWluY29kZUNvbmZpZyxcbiAgc3RhdGU/OiBMZWRnZXJTdGF0ZUNvbmZpZyxcbiAgYmxvY2tjaGFpbj86IGFueSxcbiAgZW5hYmxlTGVkZ2VySGlzdG9yeURhdGFiYXNlPzogYm9vbGVhbixcbiAgcHZ0RGF0YT86IFByaXZhdGVEYXRhU3RvcmVDb25maWcsXG4gIGxlZGdlclNuYXBzaG9zUm9vdERpcj86IHN0cmluZyxcbiAgb3BlcmF0aW9uPzogT3BlcmF0aW9uc0NvbmZpZyxcbiAgbWV0cmljcz86IE1ldHJpY3NDb25maWcsXG4gIHZtPzogVk1Db25maWdcbikge1xuICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmZvcihpc3N1ZVBlZXIpO1xuICBsb2cuZGVidWcoYElzc3VpbmcgUGVlci4uLmApO1xuICBsb2cuZGVidWcoYFdyaXRpbmcgY29uZmlndXJhdGlvbiB0byAke2NwYXRofWApO1xuXG4gIGNvbnN0IGJ1aWxkZXIgPSBuZXcgRmFicmljUGVlckNvbmZpZ0J1aWxkZXIobG9nZ2VyKTtcblxuICBidWlsZGVyXG4gICAgLnNldEdvc3NpcChnb3NzaXApXG4gICAgLnNldFRMUyh0bHMpXG4gICAgLnNldExlZGdlclNuYXBzaG90c1Jvb3REaXIobGVkZ2VyU25hcHNob3NSb290RGlyKVxuICAgIC5zZXRPcGVyYXRpb25zKG9wZXJhdGlvbilcbiAgICAuc2V0TWV0cmljcyhtZXRyaWNzKVxuICAgIC5lbmFibGVMZWRnZXJIaXN0b3J5RGF0YWJhc2UoZW5hYmxlTGVkZ2VySGlzdG9yeURhdGFiYXNlKVxuICAgIC5zZXRMZWRnZXJQdnREYXRhU3RvcmUocHZ0RGF0YSlcbiAgICAuc2V0SGFuZGxlcnMoaGFuZGxlcnMpXG4gICAgLnNldERpc2NvdmVyeShkaXNjb3ZlcnkpXG4gICAgLnNldExpbWl0cyhsaW1pdHMpXG4gICAgLnNldE1lc3NhZ2VTaXplKG1zZ1NpemUpXG4gICAgLnNldENoYWluY29kZShjaGFpbmNvZGUpXG4gICAgLnNldExlZGdlclN0YXRlKHN0YXRlKVxuICAgIC5zZXRMZWdlckJsb2NrY2hhaW4oYmxvY2tjaGFpbilcbiAgICAuc2V0QXV0aGVudGljYXRpb24oYXV0aFRpbWVXaW5kb3cpXG4gICAgLnNldEtlZXBBbGljZShrZWVwQWxpdmUpXG4gICAgLnNldEdhdGV3YXkoZ2F0ZXdheSlcbiAgICAuc2V0R2VuZXJhbChnZW5lcmFsKVxuICAgIC5zZXRCQ0NTUChiY2NzcClcbiAgICAuc2V0TXNwQ29uZmlnKG1zcClcbiAgICAuc2V0Q29ublRpbWVvdXRDbGllbnQoY2xpZW50Q29ubmVjdGlvblRpbWVvdXQpXG4gICAgLnNldERlbGl2ZXJ5Q2xpZW50KGRlbGl2ZXJ5KVxuICAgIC5zZXRQcm9maWxlKHByb2ZpbGUpXG4gICAgLnNldFZNT3B0aW9ucyh2bSlcbiAgICAuc2F2ZShjcGF0aCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydFBlZXIobG9nZ2VyOiBMb2dnZXIpIHtcbiAgY29uc3QgbG9nOiBMb2dnZXIgPSBsb2dnZXIuZm9yKHN0YXJ0UGVlcik7XG4gIGxvZy5kZWJ1ZyhgU3RhcnRpbmcgUGVlcmApO1xuXG4gIGNvbnN0IGJ1aWxkZXIgPSBuZXcgRmFicmljUGVlck5vZGVDb21tYW5kQnVpbGRlcihsb2cpO1xuXG4gIGJ1aWxkZXIuc2V0Q29tbWFuZChQZWVyTm9kZUNvbW1hbmRzLlNUQVJUKS5leGVjdXRlKCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBib290UGVlcihcbiAgbG9nOiBMb2dnZXIsXG4gIGNwYXRoOiBzdHJpbmcsXG4gIGdvc3NpcD86IEdvc3NpcENvbmZpZyxcbiAgdGxzPzogVExTQ29uZmlnLFxuICBhdXRoVGltZVdpbmRvdz86IHN0cmluZyxcbiAga2VlcEFsaXZlPzogS2VlcEFsaXZlQ29uZmlnLFxuICBnYXRld2F5PzogR2F0ZXdheUNvbmZpZyxcbiAgZ2VuZXJhbD86IEdlbmVyYWxDb25maWcsXG4gIGJjY3NwPzogQkNDU1BDb25maWcsXG4gIG1zcD86IE1TUENvbmZpZyxcbiAgY2xpZW50Q29ubmVjdGlvblRpbWVvdXQ/OiBzdHJpbmcsXG4gIGRlbGl2ZXJ5PzogRGVsaXZlcnlDbGllbnRDb25maWcsXG4gIHByb2ZpbGU/OiBQcm9maWxlQ29uZmlnLFxuICBoYW5kbGVycz86IEhhbmRsZXJzQ29uZmlnLFxuICBkaXNjb3Zlcnk/OiBEaXNjb3ZlcnlDb25maWcsXG4gIGxpbWl0cz86IExpbWl0c0NvbmZpZyxcbiAgbXNnU2l6ZT86IE1TR1NpemVDb25maWcsXG4gIGNoYWluY29kZT86IENoYWluY29kZUNvbmZpZyxcbiAgc3RhdGU/OiBMZWRnZXJTdGF0ZUNvbmZpZyxcbiAgYmxvY2tjaGFpbj86IGFueSxcbiAgZW5hYmxlTGVkZ2VySGlzdG9yeURhdGFiYXNlPzogYm9vbGVhbixcbiAgcHZ0RGF0YT86IFByaXZhdGVEYXRhU3RvcmVDb25maWcsXG4gIGxlZGdlclNuYXBzaG9zUm9vdERpcj86IHN0cmluZyxcbiAgb3BlcmF0aW9uPzogT3BlcmF0aW9uc0NvbmZpZyxcbiAgbWV0cmljcz86IE1ldHJpY3NDb25maWcsXG4gIHZtPzogVk1Db25maWdcbikge1xuICBjb25zdCBsb2dnZXIgPSBMb2dnaW5nLmZvcihib290UGVlcik7XG4gIGxvZy5kZWJ1ZyhgQm9vdGluZyBQZWVyLi4uYCk7XG5cbiAgaWYgKCFoYXNQZWVySW5pdGlhbGl6ZWQoY3BhdGgpKVxuICAgIGlzc3VlUGVlcihcbiAgICAgIGxvZ2dlcixcbiAgICAgIGNwYXRoLFxuICAgICAgZ29zc2lwLFxuICAgICAgdGxzLFxuICAgICAgYXV0aFRpbWVXaW5kb3csXG4gICAgICBrZWVwQWxpdmUsXG4gICAgICBnYXRld2F5LFxuICAgICAgZ2VuZXJhbCxcbiAgICAgIGJjY3NwLFxuICAgICAgbXNwLFxuICAgICAgY2xpZW50Q29ubmVjdGlvblRpbWVvdXQsXG4gICAgICBkZWxpdmVyeSxcbiAgICAgIHByb2ZpbGUsXG4gICAgICBoYW5kbGVycyxcbiAgICAgIGRpc2NvdmVyeSxcbiAgICAgIGxpbWl0cyxcbiAgICAgIG1zZ1NpemUsXG4gICAgICBjaGFpbmNvZGUsXG4gICAgICBzdGF0ZSxcbiAgICAgIGJsb2NrY2hhaW4sXG4gICAgICBlbmFibGVMZWRnZXJIaXN0b3J5RGF0YWJhc2UsXG4gICAgICBwdnREYXRhLFxuICAgICAgbGVkZ2VyU25hcHNob3NSb290RGlyLFxuICAgICAgb3BlcmF0aW9uLFxuICAgICAgbWV0cmljcyxcbiAgICAgIHZtXG4gICAgKTtcblxuICBzdGFydFBlZXIobG9nZ2VyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1BlZXJJbml0aWFsaXplZChmaWxlTG9jYXRpb24/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgbG9nOiBMb2dnZXIgPSBMb2dnaW5nLmZvcihoYXNQZWVySW5pdGlhbGl6ZWQpO1xuXG4gIGNvbnN0IGRlZmF1bHRGaWxlTG9jYXRpb24gPSBwYXRoLmpvaW4oX19kaXJuYW1lLCBcIi4uLy4uLy4uL3BlZXIvY29yZS55YW1sXCIpO1xuXG4gIGlmICghZmlsZUxvY2F0aW9uKSB7XG4gICAgbG9nLmRlYnVnKFxuICAgICAgYE5vIGZpbGUgbG9jYXRpb24gcHJvdmlkZWQsIHVzaW5nIGRlZmF1bHQgZmlsZSBsb2NhdGlvbjogJHtkZWZhdWx0RmlsZUxvY2F0aW9ufWBcbiAgICApO1xuICAgIGZpbGVMb2NhdGlvbiA9IGRlZmF1bHRGaWxlTG9jYXRpb247XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFmaWxlTG9jYXRpb24uZW5kc1dpdGgoXCIueWFtbFwiKSlcbiAgICAgIGZpbGVMb2NhdGlvbiA9IHBhdGguam9pbihmaWxlTG9jYXRpb24sIFwiY29yZS55YW1sXCIpO1xuICAgIGxvZy5kZWJ1ZyhgVXNpbmcgcHJvdmlkZWQgZmlsZSBsb2NhdGlvbjogJHtmaWxlTG9jYXRpb259YCk7XG4gIH1cblxuICBjb25zdCBib290ZWQgPSBmcy5leGlzdHNTeW5jKGZpbGVMb2NhdGlvbik7XG5cbiAgbG9nLmRlYnVnKGBQZWVyIGhhcyBiZWVuIGJvb3RlZDogJHtib290ZWR9YCk7XG5cbiAgcmV0dXJuIGJvb3RlZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBlZXJGZXRjaEdlbmVzaXNCbG9jayhcbiAgbG9nZ2VyPzogTG9nZ2VyLFxuICBjaGFubmVsSUQ/OiBzdHJpbmcsXG4gIG9yZGVyZXJBZGRyZXNzPzogc3RyaW5nLFxuICBibG9ja051bWJlcj86IHN0cmluZyxcbiAgb3V0cHV0RmlsZT86IHN0cmluZyxcbiAgdGxzRW5hYmxlZD86IGJvb2xlYW4sXG4gIHRsc0NBQ2VydEZpbGU/OiBzdHJpbmdcbikge1xuICBjb25zdCBsb2c6IExvZ2dlciA9IExvZ2dpbmcuZm9yKHBlZXJGZXRjaEdlbmVzaXNCbG9jayk7XG4gIGxvZy5kZWJ1ZyhgRmV0Y2hpbmcgR2VuZXNpcyBCbG9ja2ApO1xuXG4gIGNvbnN0IGJ1aWxkZXIgPSBuZXcgRmFicmljUGVlckNoYW5uZWxDb21tYW5kQnVpbGRlcihsb2dnZXIpO1xuXG4gIGJ1aWxkZXJcbiAgICAuZW5hYmxlVExTKHRsc0VuYWJsZWQpXG4gICAgLnNldENvbW1hbmQoUGVlckNoYW5uZWxDb21tYW5kcy5GRVRDSClcbiAgICAuc2V0QmxvY2tSZWZlcmVuY2UoYmxvY2tOdW1iZXIpXG4gICAgLnNldERlc3RpbmF0aW9uKG91dHB1dEZpbGUpXG4gICAgLnNldE9yZGVyZXIob3JkZXJlckFkZHJlc3MpXG4gICAgLnNldENoYW5uZWxJRChjaGFubmVsSUQpXG4gICAgLnNldFRMU0NBRmlsZSh0bHNDQUNlcnRGaWxlKVxuICAgIC5leGVjdXRlKCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwZWVySm9pbkNoYW5uZWwobG9nZ2VyPzogTG9nZ2VyLCBibG9ja1BhdGg/OiBzdHJpbmcpIHtcbiAgY29uc3QgbG9nOiBMb2dnZXIgPSBMb2dnaW5nLmZvcihwZWVySm9pbkNoYW5uZWwpO1xuICBsb2cuZGVidWcoYEpvaW5pbmcgQ2hhbm5lbGApO1xuXG4gIGNvbnN0IGJ1aWxkZXIgPSBuZXcgRmFicmljUGVlckNoYW5uZWxDb21tYW5kQnVpbGRlcihsb2dnZXIpO1xuXG4gIGJ1aWxkZXJcbiAgICAuc2V0Q29tbWFuZChQZWVyQ2hhbm5lbENvbW1hbmRzLkpPSU4pXG4gICAgLnNldEJsb2NrUGF0aChibG9ja1BhdGgpXG4gICAgLmV4ZWN1dGUoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhY2thZ2VDaGFpbmNvZGUoXG4gIGxvZ2dlcj86IExvZ2dlcixcbiAgb3V0cHV0RmlsZT86IHN0cmluZyxcbiAgY29udHJhY3RQYXRoPzogc3RyaW5nLFxuICBsYW5nPzogc3RyaW5nLFxuICBjb250cmFjdE5hbWU/OiBzdHJpbmcsXG4gIGNvbnRyYWN0VmVyc2lvbj86IHN0cmluZ1xuKSB7XG4gIGNvbnN0IGxvZzogTG9nZ2VyID0gTG9nZ2luZy5mb3IocGFja2FnZUNoYWluY29kZSk7XG4gIGxvZy5kZWJ1ZyhgUGFja2FnaW5nIENoYWluY29kZWApO1xuXG4gIGNvbnN0IGJ1aWxkZXIgPSBuZXcgRmFicmljUGVlckxpZmVjeWNsZUNoYWluY29kZUNvbW1hbmRCdWlsZGVyKGxvZ2dlcik7XG5cbiAgYnVpbGRlclxuICAgIC5zZXRDb21tYW5kKFBlZXJMaWZlY3ljbGVDaGFpbmNvZGVDb21tYW5kcy5QQUNLQUdFKVxuICAgIC5zZXREZXN0aW5hdGlvbihvdXRwdXRGaWxlKVxuICAgIC5zZXRDb250cmFjdFBhdGgoY29udHJhY3RQYXRoKVxuICAgIC5zZXRMYW5nKGxhbmcpXG4gICAgLnNldExhYmVsKGAke2NvbnRyYWN0TmFtZX1fJHtjb250cmFjdFZlcnNpb259YClcbiAgICAuZXhlY3V0ZSgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5zdGFsbENoYWluY29kZShsb2dnZXI6IExvZ2dlciwgY29udHJhY3RMb2NhdGlvbj86IHN0cmluZykge1xuICBjb25zdCBsb2c6IExvZ2dlciA9IExvZ2dpbmcuZm9yKGluc3RhbGxDaGFpbmNvZGUpO1xuICBsb2cuZGVidWcoYEluc3RhbGxpbmcgQ2hhaW5jb2RlYCk7XG5cbiAgY29uc3QgYnVpbGRlciA9IG5ldyBGYWJyaWNQZWVyTGlmZWN5Y2xlQ2hhaW5jb2RlQ29tbWFuZEJ1aWxkZXIobG9nZ2VyKTtcblxuICBidWlsZGVyXG4gICAgLnNldENvbW1hbmQoUGVlckxpZmVjeWNsZUNoYWluY29kZUNvbW1hbmRzLklOU1RBTEwpXG4gICAgLnNldERlc3RpbmF0aW9uKGNvbnRyYWN0TG9jYXRpb24pXG4gICAgLmV4ZWN1dGUoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcHJvdmVDaGFpbmNvZGUoXG4gIGxvZ2dlcjogTG9nZ2VyLFxuICBvcmRlcmVyQWRkcmVzcz86IHN0cmluZyxcbiAgY2hhbm5lbElEPzogc3RyaW5nLFxuICBjaGFpbmNvZGVOYW1lPzogc3RyaW5nLFxuICB2ZXJzaW9uPzogc3RyaW5nLFxuICBzZXF1ZW5jZT86IHN0cmluZyxcbiAgZW5hYmxlVExTPzogYm9vbGVhbixcbiAgdGxzQ0FDZXJ0RmlsZT86IHN0cmluZyxcbiAgY29sbGVjdGlvbkNvbmZpZ1BhdGg/OiBzdHJpbmcsXG4gIG9yZGVyZXJUTFNIb3N0bmFtZU92ZXJyaWRlPzogc3RyaW5nXG4pIHtcbiAgY29uc3QgbG9nOiBMb2dnZXIgPSBMb2dnaW5nLmZvcihpbnN0YWxsQ2hhaW5jb2RlKTtcbiAgbG9nLmRlYnVnKGBBcHByb3ZlIENoYWluY29kZWApO1xuXG4gIGNvbnN0IGJ1aWxkZXIgPSBuZXcgRmFicmljUGVlckxpZmVjeWNsZUNoYWluY29kZUNvbW1hbmRCdWlsZGVyKGxvZ2dlcik7XG5cbiAgY29uc3QgaWQgPSBleGVjU3luYyhcbiAgICBidWlsZGVyLnNldENvbW1hbmQoUGVlckxpZmVjeWNsZUNoYWluY29kZUNvbW1hbmRzLlFVRVJZSU5TVEFMTEVEKS5idWlsZCgpXG4gICk7XG5cbiAgbG9nLmRlYnVnKGBVc2luZyBpZDogJHtpZH1gKTtcblxuICBidWlsZGVyXG4gICAgLnNldENvbW1hbmQoUGVlckxpZmVjeWNsZUNoYWluY29kZUNvbW1hbmRzLkFQUFJPVkVGT1JNWU9SRylcbiAgICAuc2V0T3JkZXJlckFkZHJlc3Mob3JkZXJlckFkZHJlc3MpXG4gICAgLnNldENoYW5uZWxJRChjaGFubmVsSUQpXG4gICAgLnNldENvbnRyYWN0TmFtZShjaGFpbmNvZGVOYW1lKVxuICAgIC5zZXRWZXJzaW9uKHZlcnNpb24pXG4gICAgLnNldFNlcXVlbmNlKHNlcXVlbmNlKVxuICAgIC5lbmFibGVUTFMoZW5hYmxlVExTKVxuICAgIC5zZXRUTFNDQUZpbGUodGxzQ0FDZXJ0RmlsZSlcbiAgICAuc2V0T3JkZXJlclRMU0hvc3RuYW1lT3ZlcnJpZGUob3JkZXJlclRMU0hvc3RuYW1lT3ZlcnJpZGUpXG4gICAgLnNldENvbGxlY3Rpb25zQ29uZmlnUGF0aChjb2xsZWN0aW9uQ29uZmlnUGF0aClcbiAgICAuc2V0UGFja2FnZUlEKFxuICAgICAgaWRcbiAgICAgICAgLnRvU3RyaW5nKClcbiAgICAgICAgLnNwbGl0KFwiLFwiKVswXVxuICAgICAgICAuc3BsaXQoXCJcXG5cIilbMV1cbiAgICAgICAgLnNwbGl0KFwiOlwiKVxuICAgICAgICAuc2xpY2UoMSlcbiAgICAgICAgLm1hcCgocykgPT4gcy50cmltKCkpXG4gICAgICAgIC5qb2luKFwiOlwiKVxuICAgIClcbiAgICAuZXhlY3V0ZSgpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29tbWl0Q2hhaW5Db2RlKFxuICBsb2dnZXI6IExvZ2dlcixcbiAgb3JkZXJlckFkZHJlc3M/OiBzdHJpbmcsXG4gIGNoYW5uZWxJRD86IHN0cmluZyxcbiAgY2hhaW5jb2RlTmFtZT86IHN0cmluZyxcbiAgdmVyc2lvbj86IHN0cmluZyxcbiAgc2VxdWVuY2U/OiBzdHJpbmcsXG4gIGVuYWJsZVRMUz86IGJvb2xlYW4sXG4gIHRsc0NBQ2VydEZpbGU/OiBzdHJpbmcsXG4gIGNvbGxlY3Rpb25Db25maWdQYXRoPzogc3RyaW5nLFxuICBvcmRlcmVyVExTSG9zdG5hbWVPdmVycmlkZT86IHN0cmluZyxcbiAgcGVlckFkZHJlc3Nlcz86IHN0cmluZ1tdLFxuICBwZWVyVExTUm9vdHM/OiBzdHJpbmdbXVxuKSB7XG4gIGNvbnN0IGxvZzogTG9nZ2VyID0gTG9nZ2luZy5mb3IoY29tbWl0Q2hhaW5Db2RlKTtcbiAgbG9nLmluZm8oYENvbW1pdGluZyBjaGFpbmNvZGVgKTtcblxuICBjb25zdCBjaGVja0NoYWluY29kZVJlYWRpbmVzcyA9IGZ1bmN0aW9uIChcbiAgICBsb2dnZXI6IExvZ2dlcixcbiAgICBjaGFubmVsSUQ/OiBzdHJpbmcsXG4gICAgY2hhaW5jb2RlTmFtZT86IHN0cmluZyxcbiAgICB2ZXJzaW9uPzogc3RyaW5nLFxuICAgIHNlcXVlbmNlPzogc3RyaW5nLFxuICAgIGVuYWJsZVRMUz86IGJvb2xlYW4sXG4gICAgdGxzQ0FDZXJ0RmlsZT86IHN0cmluZ1xuICApIHtcbiAgICBjb25zdCB2ZXJpZmljYXRpb25CdWlsZGVyID0gbmV3IEZhYnJpY1BlZXJMaWZlY3ljbGVDaGFpbmNvZGVDb21tYW5kQnVpbGRlcihcbiAgICAgIGxvZ2dlclxuICAgICk7XG5cbiAgICBjb25zdCBhcHByb3ZhbERhdGEgPSBleGVjU3luYyhcbiAgICAgIHZlcmlmaWNhdGlvbkJ1aWxkZXJcbiAgICAgICAgLnNldENvbW1hbmQoUGVlckxpZmVjeWNsZUNoYWluY29kZUNvbW1hbmRzLkNIRUNLQ09NTUlUUkVBRElORVNTKVxuICAgICAgICAuc2V0Q2hhbm5lbElEKGNoYW5uZWxJRClcbiAgICAgICAgLnNldENvbnRyYWN0TmFtZShjaGFpbmNvZGVOYW1lKVxuICAgICAgICAuc2V0VmVyc2lvbih2ZXJzaW9uKVxuICAgICAgICAuc2V0U2VxdWVuY2Uoc2VxdWVuY2UpXG4gICAgICAgIC5lbmFibGVUTFMoZW5hYmxlVExTKVxuICAgICAgICAuc2V0VExTQ0FGaWxlKHRsc0NBQ2VydEZpbGUpXG4gICAgICAgIC5zZXRPdXRwdXQoXCJqc29uXCIpXG4gICAgICAgIC5idWlsZCgpXG4gICAgKS50b1N0cmluZygpO1xuXG4gICAgY29uc3QgYXBwcm92YWxKU09OID0gSlNPTi5wYXJzZShhcHByb3ZhbERhdGEpO1xuXG4gICAgbG9nLmluZm8oSlNPTi5zdHJpbmdpZnkoYXBwcm92YWxKU09OLCBudWxsLCAyKSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgT2JqZWN0LmtleXMoYXBwcm92YWxKU09OLmFwcHJvdmFscykuZmlsdGVyKFxuICAgICAgICAoa2V5KSA9PiBhcHByb3ZhbEpTT04uYXBwcm92YWxzW2tleV0gPT0gdHJ1ZVxuICAgICAgKS5sZW5ndGggPlxuICAgICAgT2JqZWN0LmtleXMoYXBwcm92YWxKU09OLmFwcHJvdmFscykubGVuZ3RoIC8gMlxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgY29tbWl0V2hlblJlYWR5ID0gZnVuY3Rpb24gKFxuICAgIGxvZ2dlcjogTG9nZ2VyLFxuICAgIG9yZGVyZXJBZGRyZXNzPzogc3RyaW5nLFxuICAgIGNoYW5uZWxJRD86IHN0cmluZyxcbiAgICBjaGFpbmNvZGVOYW1lPzogc3RyaW5nLFxuICAgIHZlcnNpb24/OiBzdHJpbmcsXG4gICAgc2VxdWVuY2U/OiBzdHJpbmcsXG4gICAgZW5hYmxlVExTPzogYm9vbGVhbixcbiAgICB0bHNDQUNlcnRGaWxlPzogc3RyaW5nLFxuICAgIGNvbGxlY3Rpb25Db25maWdQYXRoPzogc3RyaW5nLFxuICAgIG9yZGVyZXJUTFNIb3N0bmFtZU92ZXJyaWRlPzogc3RyaW5nLFxuICAgIHBlZXJBZGRyZXNzZXM/OiBzdHJpbmdbXSxcbiAgICBwZWVyVExTUm9vdHM/OiBzdHJpbmdbXVxuICApIHtcbiAgICBpZiAoXG4gICAgICAhY2hlY2tDaGFpbmNvZGVSZWFkaW5lc3MoXG4gICAgICAgIGxvZ2dlcixcbiAgICAgICAgY2hhbm5lbElELFxuICAgICAgICBjaGFpbmNvZGVOYW1lLFxuICAgICAgICB2ZXJzaW9uLFxuICAgICAgICBzZXF1ZW5jZSxcbiAgICAgICAgZW5hYmxlVExTLFxuICAgICAgICB0bHNDQUNlcnRGaWxlXG4gICAgICApXG4gICAgKSB7XG4gICAgICBsb2cuaW5mbyhcIkNoYWluY29kZSBub3QgcmVhZHksIHdhaXRpbmcuLi5cIik7XG4gICAgICByZXR1cm4gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbW1pdFdoZW5SZWFkeShcbiAgICAgICAgICBsb2dnZXIsXG4gICAgICAgICAgb3JkZXJlckFkZHJlc3MsXG4gICAgICAgICAgY2hhbm5lbElELFxuICAgICAgICAgIGNoYWluY29kZU5hbWUsXG4gICAgICAgICAgdmVyc2lvbixcbiAgICAgICAgICBzZXF1ZW5jZSxcbiAgICAgICAgICBlbmFibGVUTFMsXG4gICAgICAgICAgdGxzQ0FDZXJ0RmlsZSxcbiAgICAgICAgICBjb2xsZWN0aW9uQ29uZmlnUGF0aCxcbiAgICAgICAgICBvcmRlcmVyVExTSG9zdG5hbWVPdmVycmlkZSxcbiAgICAgICAgICBwZWVyQWRkcmVzc2VzLFxuICAgICAgICAgIHBlZXJUTFNSb290c1xuICAgICAgICApO1xuICAgICAgfSwgMzAwMDApO1xuICAgIH1cblxuICAgIG5ldyBGYWJyaWNQZWVyTGlmZWN5Y2xlQ2hhaW5jb2RlQ29tbWFuZEJ1aWxkZXIobG9nZ2VyKVxuICAgICAgLnNldENvbW1hbmQoUGVlckxpZmVjeWNsZUNoYWluY29kZUNvbW1hbmRzLkNPTU1JVClcbiAgICAgIC5zZXRPcmRlcmVyQWRkcmVzcyhvcmRlcmVyQWRkcmVzcylcbiAgICAgIC5zZXRDaGFubmVsSUQoY2hhbm5lbElEKVxuICAgICAgLnNldENvbnRyYWN0TmFtZShjaGFpbmNvZGVOYW1lKVxuICAgICAgLnNldFZlcnNpb24odmVyc2lvbilcbiAgICAgIC5zZXRTZXF1ZW5jZShzZXF1ZW5jZSlcbiAgICAgIC5lbmFibGVUTFMoZW5hYmxlVExTKVxuICAgICAgLnNldFRMU0NBRmlsZSh0bHNDQUNlcnRGaWxlKVxuICAgICAgLnNldENvbGxlY3Rpb25zQ29uZmlnUGF0aChjb2xsZWN0aW9uQ29uZmlnUGF0aClcbiAgICAgIC5zZXRPcmRlcmVyVExTSG9zdG5hbWVPdmVycmlkZShvcmRlcmVyVExTSG9zdG5hbWVPdmVycmlkZSlcbiAgICAgIC5zZXRQZWVyQWRkcmVzc2VzKHBlZXJBZGRyZXNzZXMpXG4gICAgICAuc2V0UGVlclRMU1Jvb3RzKHBlZXJUTFNSb290cylcbiAgICAgIC5leGVjdXRlKCk7XG4gIH07XG5cbiAgY29tbWl0V2hlblJlYWR5KFxuICAgIGxvZ2dlcixcbiAgICBvcmRlcmVyQWRkcmVzcyxcbiAgICBjaGFubmVsSUQsXG4gICAgY2hhaW5jb2RlTmFtZSxcbiAgICB2ZXJzaW9uLFxuICAgIHNlcXVlbmNlLFxuICAgIGVuYWJsZVRMUyxcbiAgICB0bHNDQUNlcnRGaWxlLFxuICAgIGNvbGxlY3Rpb25Db25maWdQYXRoLFxuICAgIG9yZGVyZXJUTFNIb3N0bmFtZU92ZXJyaWRlLFxuICAgIHBlZXJBZGRyZXNzZXMsXG4gICAgcGVlclRMU1Jvb3RzXG4gICk7XG59XG4iXX0=