UNPKG

@decaf-ts/fabric-weaver

Version:
201 lines 37.3 kB
"use strict"; 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=