@witnet/ethers
Version:
Wit/Oracle Ethers Framework package for EVM-compatible projects
250 lines • 44.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WitOracleRadonRequestTemplate = exports.WitOracleRadonRequestModal = exports.WitOracleRadonRequestFactory = void 0;
const sdk_1 = require("@witnet/sdk");
const utils_1 = require("../utils");
const WitAppliance_1 = require("./WitAppliance");
class WitOracleRadonRequestFactory extends WitAppliance_1.WitAppliance {
constructor(witOracle, registry, at) {
super(witOracle, "WitOracleRadonRequestFactory", at);
this.registry = registry;
}
static async deployed(witOracle, registry) {
const deployer = new WitOracleRadonRequestFactory(witOracle, registry);
const witOracleRegistryAddress = await witOracle.contract.registry.staticCall();
if (registry.address !== witOracleRegistryAddress) {
throw new Error(`${this.constructor.name} at ${deployer.address}: uncompliant WitOracleRadonRegistry at ${registry.address})`);
}
return deployer;
}
async deployRadonRequestTemplate(template, options) {
const hashes = [];
for (const index in template.sources) {
const retrieval = template.sources[index];
const hash = `0x${await this.registry.determineRadonRetrievalHash(retrieval)}`;
await this.registry.verifyRadonRetrieval(retrieval, options);
hashes.push(hash);
}
const aggregator = (0, utils_1.abiEncodeRadonAsset)(template.sourcesReducer);
const tally = (0, utils_1.abiEncodeRadonAsset)(template.witnessReducer);
const target = await this.contract
.getFunction("buildRadonRequestTemplate(bytes32[],(uint8,(uint8,bytes)[]),(uint8,(uint8,bytes)[]))")
.staticCall(hashes, aggregator, tally);
if (options?.onDeployRadonRequestTemplate)
options.onDeployRadonRequestTemplate(target);
await this.contract
.getFunction("buildRadonRequestTemplate(bytes32[],(uint8,(uint8,bytes)[]),(uint8,(uint8,bytes)[]))")
.send(hashes, aggregator, tally)
.then(async (tx) => {
const receipt = await tx.wait(options?.confirmations || 1);
if (options?.onDeployRadonRequestTemplateReceipt) {
options.onDeployRadonRequestTemplateReceipt(receipt);
}
});
return await WitOracleRadonRequestTemplate.at(this.witOracle, target);
}
async deployRadonRequestModal(modal, options) {
const retrieval = [
modal.sources[0].method,
modal.sources[0].body || "",
modal.sources[0]?.headers ? Object.entries(modal.sources[0].headers) : [],
modal.sources[0].script?.toBytecode() || "0x",
];
const tally = (0, utils_1.abiEncodeRadonAsset)(modal.witnessReducer);
const target = await this.contract
.buildRadonRequestModal //getFunction("buildRadonRequestModal((uint8,string,string[2][],bytes),(uint8,(uint8,bytes)[]))")
.staticCall(retrieval, tally);
if (options?.onDeployRadonRequestModal)
options.onDeployRadonRequestModal(target);
await this.contract
.buildRadonRequestModal
// .getFunction("buildRadonRequestModal((uint8,string,string[2][],bytes),(uint8,(uint8,bytes)[]))")
.send(retrieval, tally)
.then(async (tx) => {
const receipt = await tx.wait(options?.confirmations || 1);
if (options?.onDeployRadonRequestModalReceipt) {
options.onDeployRadonRequestModalReceipt(receipt);
}
});
return await WitOracleRadonRequestModal.at(this.witOracle, target);
}
async verifyRadonRequest(request, _options) {
// TODO:
//
return request.radHash;
}
}
exports.WitOracleRadonRequestFactory = WitOracleRadonRequestFactory;
class WitOracleRadonRequestModal extends WitAppliance_1.WitAppliance {
constructor(witOracle, at) {
super(witOracle, "WitOracleRadonRequestModal", at);
}
static async at(witOracle, target) {
const template = new WitOracleRadonRequestModal(witOracle, target);
const templateWitOracleAddr = await template.contract.witOracle.staticCall();
if (templateWitOracleAddr !== witOracle.address) {
throw new Error(`${this.constructor.name} at ${target}: mismatching Wit/Oracle address (${templateWitOracleAddr})`);
}
return template;
}
async getDataResultType() {
return this.contract
.getFunction("getDataResultType()")
.staticCall()
.then((result) => {
switch (Number(result)) {
case 1: return "array";
case 2: return "boolean";
case 3: return "bytes";
case 4: return "integer";
case 5: return "float";
case 6: return "map";
case 7: return "string";
default:
return "any";
}
});
}
async getDataSourcesArgsCount() {
return this.contract
.getFunction("getDataSourcesArgsCount()")
.staticCall()
.then((argsCount) => Number(argsCount));
}
async getRadonModalRetrieval() {
return this.contract
.getFunction("getRadonModalRetrieval()")
.staticCall()
.then((result) => {
return new sdk_1.Witnet.Radon.RadonRetrieval({
method: result[1],
url: result[3],
body: result[4],
headers: Object.fromEntries(result[5]),
script: (0, utils_1.parseRadonScript)(result[6]),
});
});
}
async verifyRadonRequest(dataProviders, commonRetrievalArgs, options) {
const argsCount = await this.getDataSourcesArgsCount();
if (argsCount != 1 + (commonRetrievalArgs?.length || 0)) {
throw TypeError(`${this.constructor.name}@${this.address}: unmatching args count != ${argsCount - 1}.`);
}
const method = this.contract.getFunction("verifyRadonRequest(string[],string[])");
const radHash = (await method.staticCall(commonRetrievalArgs || [], dataProviders)).slice(2);
try {
await (await this.witOracle.getWitOracleRadonRegistry()).lookupRadonRequestBytecode(radHash);
}
catch {
if (options?.onVerifyRadonRequest)
options.onVerifyRadonRequest(radHash);
await method
.send(commonRetrievalArgs || [], dataProviders)
.then(tx => tx.wait(options?.confirmations || 1))
.then(receipt => {
if (options?.onVerifyRadonRequestReceipt) {
options.onVerifyRadonRequestReceipt(receipt);
}
return radHash;
});
}
return radHash;
}
}
exports.WitOracleRadonRequestModal = WitOracleRadonRequestModal;
class WitOracleRadonRequestTemplate extends WitAppliance_1.WitAppliance {
constructor(witOracle, at) {
super(witOracle, "WitOracleRadonRequestTemplate", at);
}
static async at(witOracle, target) {
const template = new WitOracleRadonRequestTemplate(witOracle, target);
const templateWitOracleAddr = await template.contract.witOracle.staticCall();
if (templateWitOracleAddr !== witOracle.address) {
throw new Error(`${this.constructor.name} at ${target}: mismatching Wit/Oracle address (${templateWitOracleAddr})`);
}
return template;
}
async getDataResultType() {
return this.contract
.getFunction("getDataResultType()")
.staticCall()
.then((result) => {
switch (Number(result)) {
case 1: return "array";
case 2: return "boolean";
case 3: return "bytes";
case 4: return "integer";
case 5: return "float";
case 6: return "map";
case 7: return "string";
default:
return "any";
}
});
}
async getDataSources() {
return this.contract
.getFunction("getDataSources()")
.staticCall()
.then((results) => {
return results.map(result => new sdk_1.Witnet.Radon.RadonRetrieval({
method: result[1],
url: result[3],
body: result[4],
headers: Object.fromEntries(result[5]),
script: (0, utils_1.parseRadonScript)(result[6]),
}));
});
}
async getDataSourcesArgsCount() {
return this.contract
.getFunction("getDataSourcesArgsCount()")
.staticCall()
.then((dims) => dims.map(dim => Number(dim)));
}
async verifyRadonRequest(args, options) {
const argsCount = await this.getDataSourcesArgsCount();
let encodedArgs = [];
if (typeof args === 'string') {
if (argsCount.length === 1 && argsCount[0] === 1) {
encodedArgs = [[args]];
}
}
else if (Array.isArray(args)) {
if (Array.isArray(args[0])) {
if (argsCount.length === args.length
&& !args.find((subargs, index) => subargs.length !== argsCount[index])) {
encodedArgs = args;
}
}
else if (args.length === argsCount[0]
&& !args.find(arg => typeof arg !== 'string')) {
encodedArgs = [args];
}
}
if (encodedArgs.length === 0) {
throw TypeError(`${this.constructor.name}@${this.address}: unmatching args count != [${argsCount}, ].`);
}
const method = this.contract.getFunction("verifyRadonRequest(string[][])");
const radHash = (await method.staticCall(encodedArgs)).slice(2);
try {
await (await this.witOracle.getWitOracleRadonRegistry()).lookupRadonRequestBytecode(radHash);
}
catch {
if (options?.onVerifyRadonRequest)
options.onVerifyRadonRequest(radHash);
await method
.send(encodedArgs)
.then(tx => tx.wait(options?.confirmations || 1))
.then(receipt => {
if (options?.onVerifyRadonRequestReceipt) {
options.onVerifyRadonRequestReceipt(receipt);
}
return radHash;
});
}
return radHash;
}
}
exports.WitOracleRadonRequestTemplate = WitOracleRadonRequestTemplate;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvd3JhcHBlcnMvV2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxQ0FBb0M7QUFDcEMsb0NBQWdFO0FBRWhFLGlEQUE2QztBQUk3QyxNQUFhLDRCQUE2QixTQUFRLDJCQUFZO0lBSTFELFlBQXVCLFNBQW9CLEVBQUUsUUFBZ0MsRUFBRSxFQUFXO1FBQ3RGLEtBQUssQ0FBQyxTQUFTLEVBQUUsOEJBQThCLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFDcEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7SUFDNUIsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFNBQW9CLEVBQUUsUUFBZ0M7UUFDeEUsTUFBTSxRQUFRLEdBQUcsSUFBSSw0QkFBNEIsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFDdEUsTUFBTSx3QkFBd0IsR0FBRyxNQUFNLFNBQVMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFBO1FBQy9FLElBQUksUUFBUSxDQUFDLE9BQU8sS0FBSyx3QkFBd0IsRUFBRSxDQUFDO1lBQ2hELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksT0FBTyxRQUFRLENBQUMsT0FBTywyQ0FBMkMsUUFBUSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUE7UUFDbEksQ0FBQztRQUNELE9BQU8sUUFBUSxDQUFBO0lBQ25CLENBQUM7SUFFTSxLQUFLLENBQUMsMEJBQTBCLENBQ25DLFFBQW9DLEVBQ3BDLE9BY0M7UUFHRCxNQUFNLE1BQU0sR0FBa0IsRUFBRSxDQUFBO1FBQ2hDLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ25D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aUJBQ2hELElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDWixJQUFJLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxDQUFDO29CQUN2QyxPQUFPLENBQUMsMkJBQTJCLENBQUMsT0FBTyxDQUFDLENBQUE7Z0JBQ2hELENBQUM7Z0JBQ0QsT0FBTyxPQUFPLENBQUE7WUFDbEIsQ0FBQyxDQUFDLENBQUE7UUFDVixDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUE7SUFDbEIsQ0FBQztDQUNKO0FBMUdELHNFQTBHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0LCBSZXN1bHQgfSBmcm9tIFwiZXRoZXJzXCJcclxuaW1wb3J0IHsgV2l0bmV0IH0gZnJvbSBcIkB3aXRuZXQvc2RrXCJcclxuaW1wb3J0IHsgYWJpRW5jb2RlUmFkb25Bc3NldCwgcGFyc2VSYWRvblNjcmlwdCB9IGZyb20gXCIuLi91dGlsc1wiXHJcbmltcG9ydCB7IFdpdE9yYWNsZVJlc3VsdERhdGFUeXBlcyB9IGZyb20gXCIuLi90eXBlc1wiXHJcbmltcG9ydCB7IFdpdEFwcGxpYW5jZSB9IGZyb20gXCIuL1dpdEFwcGxpYW5jZVwiXHJcbmltcG9ydCB7IFdpdE9yYWNsZSB9IGZyb20gXCIuL1dpdE9yYWNsZVwiXHJcbmltcG9ydCB7IFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkgfSBmcm9tIFwiLi9XaXRPcmFjbGVSYWRvblJlZ2lzdHJ5XCJcclxuXHJcbmV4cG9ydCBjbGFzcyBXaXRPcmFjbGVSYWRvblJlcXVlc3RGYWN0b3J5IGV4dGVuZHMgV2l0QXBwbGlhbmNlIHsgIFxyXG5cclxuICAgIHB1YmxpYyByZWFkb25seSByZWdpc3RyeTogV2l0T3JhY2xlUmFkb25SZWdpc3RyeVxyXG4gICAgXHJcbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IgKHdpdE9yYWNsZTogV2l0T3JhY2xlLCByZWdpc3RyeTogV2l0T3JhY2xlUmFkb25SZWdpc3RyeSwgYXQ/OiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcih3aXRPcmFjbGUsIFwiV2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeVwiLCBhdClcclxuICAgICAgICB0aGlzLnJlZ2lzdHJ5ID0gcmVnaXN0cnlcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgYXN5bmMgZGVwbG95ZWQod2l0T3JhY2xlOiBXaXRPcmFjbGUsIHJlZ2lzdHJ5OiBXaXRPcmFjbGVSYWRvblJlZ2lzdHJ5KTogUHJvbWlzZTxXaXRPcmFjbGVSYWRvblJlcXVlc3RGYWN0b3J5PiB7XHJcbiAgICAgICAgY29uc3QgZGVwbG95ZXIgPSBuZXcgV2l0T3JhY2xlUmFkb25SZXF1ZXN0RmFjdG9yeSh3aXRPcmFjbGUsIHJlZ2lzdHJ5KVxyXG4gICAgICAgIGNvbnN0IHdpdE9yYWNsZVJlZ2lzdHJ5QWRkcmVzcyA9IGF3YWl0IHdpdE9yYWNsZS5jb250cmFjdC5yZWdpc3RyeS5zdGF0aWNDYWxsKClcclxuICAgICAgICBpZiAocmVnaXN0cnkuYWRkcmVzcyAhPT0gd2l0T3JhY2xlUmVnaXN0cnlBZGRyZXNzKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IGF0ICR7ZGVwbG95ZXIuYWRkcmVzc306IHVuY29tcGxpYW50IFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkgYXQgJHtyZWdpc3RyeS5hZGRyZXNzfSlgKVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZGVwbG95ZXJcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGUoXHJcbiAgICAgICAgdGVtcGxhdGU6IFdpdG5ldC5SYWRvbi5SYWRvblRlbXBsYXRlLFxyXG4gICAgICAgIG9wdGlvbnM/OiB7XHJcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM/OiBudW1iZXIsXHJcbiAgICAgICAgICAgIG9uRGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGU/OiAoYWRkcmVzczogc3RyaW5nKSA9PiBhbnksXHJcbiAgICAgICAgICAgIG9uRGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGVSZWNlaXB0PzogKHJlY2VpcHQ6IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0IHwgbnVsbCkgPT4gYW55LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ2FsbGJhY2sgaGFuZGxlciBjYWxsZWQganVzdCBpbiBjYXNlIGEgYHZlcmlmeVJhZG9uUmV0cmlldmFsYCB0cmFuc2FjdGlvbiBpcyB1bHRpbWF0ZWx5IHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25WZXJpZnlSYWRvblJldHJpZXZhbD86IChoYXNoOiBzdHJpbmcpID0+IGFueSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIENhbGxiYWNrIGhhbmRsZXIgY2FsbGVkIG9uY2UgdGhlIGB2ZXJpZnlSYWRvblJldHJpZXZhbGAgdHJhbnNhY3Rpb24gZ2V0cyBjb25maXJtZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSByZWNlaXB0IFRoZSBgdmVyaWZ5UmFkb25SZXRyaWV2YWxgIHRyYW5zYWN0aW9uIHJlY2VpcHQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBoYXNoIFRoZSB1bmlxdWUgaGFzaCBvZiB0aGUgUmFkb24gUmV0cmlldmFsLCBhcyB2ZXJpZmllZCBvbiB0aGUgY29ubmVjdGVkIG5ldHdvcmsuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmV0cmlldmFsUmVjZWlwdD86IChyZWNlaXB0OiBDb250cmFjdFRyYW5zYWN0aW9uUmVjZWlwdCB8IG51bGwpID0+IGFueSxcclxuICAgICAgICB9LFxyXG4gICAgKTogUHJvbWlzZTxXaXRPcmFjbGVSYWRvblJlcXVlc3RUZW1wbGF0ZT4ge1xyXG4gICAgICAgIFxyXG4gICAgICAgIGNvbnN0IGhhc2hlczogQXJyYXk8c3RyaW5nPiA9IFtdXHJcbiAgICAgICAgZm9yIChjb25zdCBpbmRleCBpbiB0ZW1wbGF0ZS5zb3VyY2VzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJldHJpZXZhbCA9IHRlbXBsYXRlLnNvdXJjZXNbaW5kZXhdXHJcbiAgICAgICAgICAgIGNvbnN0IGhhc2ggPSBgMHgke2F3YWl0IHRoaXMucmVnaXN0cnkuZGV0ZXJtaW5lUmFkb25SZXRyaWV2YWxIYXNoKHJldHJpZXZhbCl9YFxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdHJ5LnZlcmlmeVJhZG9uUmV0cmlldmFsKHJldHJpZXZhbCwgb3B0aW9ucylcclxuICAgICAgICAgICAgaGFzaGVzLnB1c2goaGFzaClcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgY29uc3QgYWdncmVnYXRvciA9IGFiaUVuY29kZVJhZG9uQXNzZXQodGVtcGxhdGUuc291cmNlc1JlZHVjZXIpXHJcbiAgICAgICAgY29uc3QgdGFsbHkgPSBhYmlFbmNvZGVSYWRvbkFzc2V0KHRlbXBsYXRlLndpdG5lc3NSZWR1Y2VyKVxyXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGF3YWl0IHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiYnVpbGRSYWRvblJlcXVlc3RUZW1wbGF0ZShieXRlczMyW10sKHVpbnQ4LCh1aW50OCxieXRlcylbXSksKHVpbnQ4LCh1aW50OCxieXRlcylbXSkpXCIpXHJcbiAgICAgICAgICAgIC5zdGF0aWNDYWxsKGhhc2hlcywgYWdncmVnYXRvciwgdGFsbHkpXHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKG9wdGlvbnM/Lm9uRGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGUpIG9wdGlvbnMub25EZXBsb3lSYWRvblJlcXVlc3RUZW1wbGF0ZSh0YXJnZXQpO1xyXG4gICAgICAgIGF3YWl0IHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiYnVpbGRSYWRvblJlcXVlc3RUZW1wbGF0ZShieXRlczMyW10sKHVpbnQ4LCh1aW50OCxieXRlcylbXSksKHVpbnQ4LCh1aW50OCxieXRlcylbXSkpXCIpXHJcbiAgICAgICAgICAgIC5zZW5kKGhhc2hlcywgYWdncmVnYXRvciwgdGFsbHkpXHJcbiAgICAgICAgICAgIC50aGVuKGFzeW5jICh0eCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVjZWlwdCA9IGF3YWl0IHR4LndhaXQob3B0aW9ucz8uY29uZmlybWF0aW9ucyB8fCAxKVxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnM/Lm9uRGVwbG95UmFkb25SZXF1ZXN0VGVtcGxhdGVSZWNlaXB0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5vbkRlcGxveVJhZG9uUmVxdWVzdFRlbXBsYXRlUmVjZWlwdChyZWNlaXB0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IFdpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlLmF0KFxyXG4gICAgICAgICAgICB0aGlzLndpdE9yYWNsZSwgXHJcbiAgICAgICAgICAgIHRhcmdldFxyXG4gICAgICAgIClcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZGVwbG95UmFkb25SZXF1ZXN0TW9kYWwoXHJcbiAgICAgICAgbW9kYWw6IFdpdG5ldC5SYWRvbi5SYWRvbk1vZGFsLFxyXG4gICAgICAgIG9wdGlvbnM/OiB7XHJcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM/OiBudW1iZXIsXHJcbiAgICAgICAgICAgIG9uRGVwbG95UmFkb25SZXF1ZXN0TW9kYWw/OiAoYWRkcmVzczogc3RyaW5nKSA9PiBhbnksXHJcbiAgICAgICAgICAgIG9uRGVwbG95UmFkb25SZXF1ZXN0TW9kYWxSZWNlaXB0PzogKHJlY2VpcHQ6IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0IHwgbnVsbCkgPT4gYW55LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ2FsbGJhY2sgaGFuZGxlciBjYWxsZWQganVzdCBpbiBjYXNlIGEgYHZlcmlmeVJhZG9uUmV0cmlldmFsYCB0cmFuc2FjdGlvbiBpcyB1bHRpbWF0ZWx5IHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25WZXJpZnlSYWRvblJldHJpZXZhbD86IChoYXNoOiBzdHJpbmcpID0+IGFueSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIENhbGxiYWNrIGhhbmRsZXIgY2FsbGVkIG9uY2UgdGhlIGB2ZXJpZnlSYWRvblJldHJpZXZhbGAgdHJhbnNhY3Rpb24gZ2V0cyBjb25maXJtZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSByZWNlaXB0IFRoZSBgdmVyaWZ5UmFkb25SZXRyaWV2YWxgIHRyYW5zYWN0aW9uIHJlY2VpcHQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBoYXNoIFRoZSB1bmlxdWUgaGFzaCBvZiB0aGUgUmFkb24gUmV0cmlldmFsLCBhcyB2ZXJpZmllZCBvbiB0aGUgY29ubmVjdGVkIG5ldHdvcmsuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmV0cmlldmFsUmVjZWlwdD86IChyZWNlaXB0OiBDb250cmFjdFRyYW5zYWN0aW9uUmVjZWlwdCB8IG51bGwpID0+IGFueSxcclxuICAgICAgICB9LFxyXG4gICAgKTogUHJvbWlzZTxXaXRPcmFjbGVSYWRvblJlcXVlc3RNb2RhbD4ge1xyXG5cclxuICAgICAgICBjb25zdCByZXRyaWV2YWwgPSBbXHJcbiAgICAgICAgICAgIG1vZGFsLnNvdXJjZXNbMF0ubWV0aG9kLFxyXG4gICAgICAgICAgICAgICAgbW9kYWwuc291cmNlc1swXS5ib2R5IHx8IFwiXCIsXHJcbiAgICAgICAgICAgICAgICBtb2RhbC5zb3VyY2VzWzBdPy5oZWFkZXJzID8gT2JqZWN0LmVudHJpZXMobW9kYWwuc291cmNlc1swXS5oZWFkZXJzKSA6IFtdLFxyXG4gICAgICAgICAgICAgICAgbW9kYWwuc291cmNlc1swXS5zY3JpcHQ/LnRvQnl0ZWNvZGUoKSB8fCBcIjB4XCIsXHJcbiAgICAgICAgXTtcclxuICAgICAgICBjb25zdCB0YWxseSA9IGFiaUVuY29kZVJhZG9uQXNzZXQobW9kYWwud2l0bmVzc1JlZHVjZXIpXHJcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gYXdhaXQgdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuYnVpbGRSYWRvblJlcXVlc3RNb2RhbCAvL2dldEZ1bmN0aW9uKFwiYnVpbGRSYWRvblJlcXVlc3RNb2RhbCgodWludDgsc3RyaW5nLHN0cmluZ1syXVtdLGJ5dGVzKSwodWludDgsKHVpbnQ4LGJ5dGVzKVtdKSlcIilcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwocmV0cmlldmFsLCB0YWxseSlcclxuICAgICAgICBcclxuICAgICAgICBpZiAob3B0aW9ucz8ub25EZXBsb3lSYWRvblJlcXVlc3RNb2RhbCkgb3B0aW9ucy5vbkRlcGxveVJhZG9uUmVxdWVzdE1vZGFsKHRhcmdldCk7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuYnVpbGRSYWRvblJlcXVlc3RNb2RhbFxyXG4gICAgICAgICAgICAvLyAuZ2V0RnVuY3Rpb24oXCJidWlsZFJhZG9uUmVxdWVzdE1vZGFsKCh1aW50OCxzdHJpbmcsc3RyaW5nWzJdW10sYnl0ZXMpLCh1aW50OCwodWludDgsYnl0ZXMpW10pKVwiKVxyXG4gICAgICAgICAgICAuc2VuZChyZXRyaWV2YWwsIHRhbGx5KVxyXG4gICAgICAgICAgICAudGhlbihhc3luYyAodHgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlY2VpcHQgPSBhd2FpdCB0eC53YWl0KG9wdGlvbnM/LmNvbmZpcm1hdGlvbnMgfHwgMSlcclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zPy5vbkRlcGxveVJhZG9uUmVxdWVzdE1vZGFsUmVjZWlwdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMub25EZXBsb3lSYWRvblJlcXVlc3RNb2RhbFJlY2VpcHQocmVjZWlwdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiBhd2FpdCBXaXRPcmFjbGVSYWRvblJlcXVlc3RNb2RhbC5hdChcclxuICAgICAgICAgICAgdGhpcy53aXRPcmFjbGUsIFxyXG4gICAgICAgICAgICB0YXJnZXRcclxuICAgICAgICApXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIHZlcmlmeVJhZG9uUmVxdWVzdChcclxuICAgICAgICByZXF1ZXN0OiBXaXRuZXQuUmFkb24uUmFkb25SZXF1ZXN0LFxyXG4gICAgICAgIF9vcHRpb25zPzoge1xyXG4gICAgICAgICAgICBjb25maXJtYXRpb25zPzogbnVtYmVyLFxyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmVxdWVzdD86IChhZGRyZXNzOiBzdHJpbmcpID0+IGFueSxcclxuICAgICAgICAgICAgb25WZXJpZnlSYWRvblJlcXVlc3RSZWNlaXB0PzogKHJlY2VpcHQ6IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0IHwgbnVsbCkgPT4gYW55LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ2FsbGJhY2sgaGFuZGxlciBjYWxsZWQganVzdCBpbiBjYXNlIGEgYHZlcmlmeVJhZG9uUmV0cmlldmFsYCB0cmFuc2FjdGlvbiBpcyB1bHRpbWF0ZWx5IHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25WZXJpZnlSYWRvblJldHJpZXZhbD86IChoYXNoOiBzdHJpbmcpID0+IGFueSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIENhbGxiYWNrIGhhbmRsZXIgY2FsbGVkIG9uY2UgdGhlIGB2ZXJpZnlSYWRvblJldHJpZXZhbGAgdHJhbnNhY3Rpb24gZ2V0cyBjb25maXJtZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSByZWNlaXB0IFRoZSBgdmVyaWZ5UmFkb25SZXRyaWV2YWxgIHRyYW5zYWN0aW9uIHJlY2VpcHQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBoYXNoIFRoZSB1bmlxdWUgaGFzaCBvZiB0aGUgUmFkb24gUmV0cmlldmFsLCBhcyB2ZXJpZmllZCBvbiB0aGUgY29ubmVjdGVkIG5ldHdvcmsuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmV0cmlldmFsUmVjZWlwdD86IChyZWNlaXB0OiBDb250cmFjdFRyYW5zYWN0aW9uUmVjZWlwdCB8IG51bGwpID0+IGFueSxcclxuICAgICAgICB9XHJcbiAgICApOiBQcm9taXNlPFdpdG5ldC5IYXNoPiB7XHJcbiAgICAgICAgLy8gVE9ETzpcclxuICAgICAgICAvL1xyXG4gICAgICAgIHJldHVybiByZXF1ZXN0LnJhZEhhc2hcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFdpdE9yYWNsZVJhZG9uUmVxdWVzdE1vZGFsIGV4dGVuZHMgV2l0QXBwbGlhbmNlIHtcclxuXHJcbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IgKHdpdE9yYWNsZTogV2l0T3JhY2xlLCBhdDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIod2l0T3JhY2xlLCBcIldpdE9yYWNsZVJhZG9uUmVxdWVzdE1vZGFsXCIsIGF0KVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBhc3luYyBhdCh3aXRPcmFjbGU6IFdpdE9yYWNsZSwgdGFyZ2V0OiBzdHJpbmcpOiBQcm9taXNlPFdpdE9yYWNsZVJhZG9uUmVxdWVzdE1vZGFsPiB7XHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBuZXcgV2l0T3JhY2xlUmFkb25SZXF1ZXN0TW9kYWwod2l0T3JhY2xlLCB0YXJnZXQpXHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGVXaXRPcmFjbGVBZGRyID0gYXdhaXQgdGVtcGxhdGUuY29udHJhY3Qud2l0T3JhY2xlLnN0YXRpY0NhbGwoKVxyXG4gICAgICAgIGlmICh0ZW1wbGF0ZVdpdE9yYWNsZUFkZHIgIT09IHdpdE9yYWNsZS5hZGRyZXNzKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IGF0ICR7dGFyZ2V0fTogbWlzbWF0Y2hpbmcgV2l0L09yYWNsZSBhZGRyZXNzICgke3RlbXBsYXRlV2l0T3JhY2xlQWRkcn0pYClcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldERhdGFSZXN1bHRUeXBlKCk6IFByb21pc2U8V2l0T3JhY2xlUmVzdWx0RGF0YVR5cGVzPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiZ2V0RGF0YVJlc3VsdFR5cGUoKVwiKVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbCgpXHJcbiAgICAgICAgICAgIC50aGVuKChyZXN1bHQ6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChOdW1iZXIocmVzdWx0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTogcmV0dXJuIFwiYXJyYXlcIjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IHJldHVybiBcImJvb2xlYW5cIjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHJldHVybiBcImJ5dGVzXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiByZXR1cm4gXCJpbnRlZ2VyXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OiByZXR1cm4gXCJmbG9hdFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjogcmV0dXJuIFwibWFwXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiByZXR1cm4gXCJzdHJpbmdcIjtcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYW55XCI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldERhdGFTb3VyY2VzQXJnc0NvdW50KCk6IFByb21pc2U8bnVtYmVyPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiZ2V0RGF0YVNvdXJjZXNBcmdzQ291bnQoKVwiKVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbCgpXHJcbiAgICAgICAgICAgIC50aGVuKChhcmdzQ291bnQ6IGJpZ2ludCkgPT4gTnVtYmVyKGFyZ3NDb3VudCkpXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldFJhZG9uTW9kYWxSZXRyaWV2YWwoKTogUHJvbWlzZTxXaXRuZXQuUmFkb24uUmFkb25SZXRyaWV2YWw+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250cmFjdFxyXG4gICAgICAgICAgICAuZ2V0RnVuY3Rpb24oXCJnZXRSYWRvbk1vZGFsUmV0cmlldmFsKClcIilcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwoKVxyXG4gICAgICAgICAgICAudGhlbigocmVzdWx0OiBSZXN1bHQpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgV2l0bmV0LlJhZG9uLlJhZG9uUmV0cmlldmFsKHtcclxuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IHJlc3VsdFsxXSxcclxuICAgICAgICAgICAgICAgICAgICB1cmw6IHJlc3VsdFszXSxcclxuICAgICAgICAgICAgICAgICAgICBib2R5OiByZXN1bHRbNF0sXHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogT2JqZWN0LmZyb21FbnRyaWVzKHJlc3VsdFs1XSksXHJcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0OiBwYXJzZVJhZG9uU2NyaXB0KHJlc3VsdFs2XSksXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyB2ZXJpZnlSYWRvblJlcXVlc3QoXHJcbiAgICAgICAgZGF0YVByb3ZpZGVyczogc3RyaW5nW10sXHJcbiAgICAgICAgY29tbW9uUmV0cmlldmFsQXJncz86IHN0cmluZ1tdLFxyXG4gICAgICAgIG9wdGlvbnM/OiB7XHJcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM/OiBudW1iZXIsIFxyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmVxdWVzdDogKHJhZEhhc2g6IHN0cmluZykgPT4gYW55LFxyXG4gICAgICAgICAgICBvblZlcmlmeVJhZG9uUmVxdWVzdFJlY2VpcHQ6IChyZWNlaXB0OiBDb250cmFjdFRyYW5zYWN0aW9uUmVjZWlwdCB8IG51bGwpID0+IGFueSxcclxuICAgICAgICB9LFxyXG4gICAgKTogUHJvbWlzZTxXaXRuZXQuSGFzaD4ge1xyXG4gICAgICAgIGNvbnN0IGFyZ3NDb3VudCA9IGF3YWl0IHRoaXMuZ2V0RGF0YVNvdXJjZXNBcmdzQ291bnQoKVxyXG4gICAgICAgIGlmIChhcmdzQ291bnQgIT0gMSArIChjb21tb25SZXRyaWV2YWxBcmdzPy5sZW5ndGggfHwgMCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX1AJHt0aGlzLmFkZHJlc3N9OiB1bm1hdGNoaW5nIGFyZ3MgY291bnQgIT0gJHthcmdzQ291bnQgLTEgfS5gKVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtZXRob2QgPSB0aGlzLmNvbnRyYWN0LmdldEZ1bmN0aW9uKFwidmVyaWZ5UmFkb25SZXF1ZXN0KHN0cmluZ1tdLHN0cmluZ1tdKVwiKVxyXG4gICAgICAgIGNvbnN0IHJhZEhhc2ggPSAoYXdhaXQgbWV0aG9kLnN0YXRpY0NhbGwoY29tbW9uUmV0cmlldmFsQXJncyB8fCBbXSwgZGF0YVByb3ZpZGVycykpLnNsaWNlKDIpXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgKGF3YWl0IHRoaXMud2l0T3JhY2xlLmdldFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkoKSkubG9va3VwUmFkb25SZXF1ZXN0Qnl0ZWNvZGUocmFkSGFzaClcclxuICAgICAgICB9IGNhdGNoIHtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnM/Lm9uVmVyaWZ5UmFkb25SZXF1ZXN0KSBvcHRpb25zLm9uVmVyaWZ5UmFkb25SZXF1ZXN0KHJhZEhhc2gpO1xyXG4gICAgICAgICAgICBhd2FpdCBtZXRob2RcclxuICAgICAgICAgICAgICAgIC5zZW5kKGNvbW1vblJldHJpZXZhbEFyZ3MgfHwgW10sIGRhdGFQcm92aWRlcnMpXHJcbiAgICAgICAgICAgICAgICAudGhlbih0eCA9PiB0eC53YWl0KG9wdGlvbnM/LmNvbmZpcm1hdGlvbnMgfHwgMSkpXHJcbiAgICAgICAgICAgICAgICAudGhlbihyZWNlaXB0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucz8ub25WZXJpZnlSYWRvblJlcXVlc3RSZWNlaXB0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMub25WZXJpZnlSYWRvblJlcXVlc3RSZWNlaXB0KHJlY2VpcHQpXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByYWRIYXNoXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmFkSGFzaFxyXG4gICAgfVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFdpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlIGV4dGVuZHMgV2l0QXBwbGlhbmNlIHtcclxuXHJcbiAgICBwcm90ZWN0ZWQgY29uc3RydWN0b3IgKHdpdE9yYWNsZTogV2l0T3JhY2xlLCBhdDogc3RyaW5nKSB7XHJcbiAgICAgICAgc3VwZXIod2l0T3JhY2xlLCBcIldpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlXCIsIGF0KVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBhc3luYyBhdCh3aXRPcmFjbGU6IFdpdE9yYWNsZSwgdGFyZ2V0OiBzdHJpbmcpOiBQcm9taXNlPFdpdE9yYWNsZVJhZG9uUmVxdWVzdFRlbXBsYXRlPiB7XHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBuZXcgV2l0T3JhY2xlUmFkb25SZXF1ZXN0VGVtcGxhdGUod2l0T3JhY2xlLCB0YXJnZXQpXHJcbiAgICAgICAgY29uc3QgdGVtcGxhdGVXaXRPcmFjbGVBZGRyID0gYXdhaXQgdGVtcGxhdGUuY29udHJhY3Qud2l0T3JhY2xlLnN0YXRpY0NhbGwoKVxyXG4gICAgICAgIGlmICh0ZW1wbGF0ZVdpdE9yYWNsZUFkZHIgIT09IHdpdE9yYWNsZS5hZGRyZXNzKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IGF0ICR7dGFyZ2V0fTogbWlzbWF0Y2hpbmcgV2l0L09yYWNsZSBhZGRyZXNzICgke3RlbXBsYXRlV2l0T3JhY2xlQWRkcn0pYClcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldERhdGFSZXN1bHRUeXBlKCk6IFByb21pc2U8V2l0T3JhY2xlUmVzdWx0RGF0YVR5cGVzPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiZ2V0RGF0YVJlc3VsdFR5cGUoKVwiKVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbCgpXHJcbiAgICAgICAgICAgIC50aGVuKChyZXN1bHQ6IG51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChOdW1iZXIocmVzdWx0KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTogcmV0dXJuIFwiYXJyYXlcIjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IHJldHVybiBcImJvb2xlYW5cIjtcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHJldHVybiBcImJ5dGVzXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiByZXR1cm4gXCJpbnRlZ2VyXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA1OiByZXR1cm4gXCJmbG9hdFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgNjogcmV0dXJuIFwibWFwXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiByZXR1cm4gXCJzdHJpbmdcIjtcclxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYW55XCI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldERhdGFTb3VyY2VzKCk6IFByb21pc2U8QXJyYXk8V2l0bmV0LlJhZG9uLlJhZG9uUmV0cmlldmFsPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRyYWN0XHJcbiAgICAgICAgICAgIC5nZXRGdW5jdGlvbihcImdldERhdGFTb3VyY2VzKClcIilcclxuICAgICAgICAgICAgLnN0YXRpY0NhbGwoKVxyXG4gICAgICAgICAgICAudGhlbigocmVzdWx0czogQXJyYXk8UmVzdWx0PikgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHMubWFwKHJlc3VsdCA9PiBuZXcgV2l0bmV0LlJhZG9uLlJhZG9uUmV0cmlldmFsKHtcclxuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IHJlc3VsdFsxXSxcclxuICAgICAgICAgICAgICAgICAgICB1cmw6IHJlc3VsdFszXSxcclxuICAgICAgICAgICAgICAgICAgICBib2R5OiByZXN1bHRbNF0sXHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogT2JqZWN0LmZyb21FbnRyaWVzKHJlc3VsdFs1XSksXHJcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0OiBwYXJzZVJhZG9uU2NyaXB0KHJlc3VsdFs2XSksXHJcbiAgICAgICAgICAgICAgICB9KSlcclxuICAgICAgICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0RGF0YVNvdXJjZXNBcmdzQ291bnQoKTogUHJvbWlzZTxBcnJheTxudW1iZXI+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udHJhY3RcclxuICAgICAgICAgICAgLmdldEZ1bmN0aW9uKFwiZ2V0RGF0YVNvdXJjZXNBcmdzQ291bnQoKVwiKVxyXG4gICAgICAgICAgICAuc3RhdGljQ2FsbCgpXHJcbiAgICAgICAgICAgIC50aGVuKChkaW1zOiBBcnJheTxiaWdpbnQ+KSA9PiBkaW1zLm1hcChkaW0gPT4gTnVtYmVyKGRpbSkpKVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyB2ZXJpZnlSYWRvblJlcXVlc3QoXHJcbiAgICAgICAgYXJnczogc3RyaW5nIHwgc3RyaW5nW10gfCBBcnJheTxzdHJpbmdbXT4sXHJcbiAgICAgICAgb3B0aW9ucz86IHtcclxuICAgICAgICAgICAgY29uZmlybWF0aW9ucz86IG51bWJlciwgXHJcbiAgICAgICAgICAgIG9uVmVyaWZ5UmFkb25SZXF1ZXN0OiAocmFkSGFzaDogc3RyaW5nKSA9PiBhbnksXHJcbiAgICAgICAgICAgIG9uVmVyaWZ5UmFkb25SZXF1ZXN0UmVjZWlwdDogKHJlY2VpcHQ6IENvbnRyYWN0VHJhbnNhY3Rpb25SZWNlaXB0IHwgbnVsbCkgPT4gYW55LFxyXG4gICAgICAgIH0sXHJcbiAgICApOiBQcm9taXNlPFdpdG5ldC5IZXhTdHJpbmc+IHtcclxuICAgICAgICBjb25zdCBhcmdzQ291bnQgPSBhd2FpdCB0aGlzLmdldERhdGFTb3VyY2VzQXJnc0NvdW50KClcclxuICAgICAgICBsZXQgZW5jb2RlZEFyZ3M6IEFycmF5PHN0cmluZ1tdPiA9IFtdXHJcbiAgICAgICAgaWYgKHR5cGVvZiBhcmdzID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBpZiAoYXJnc0NvdW50Lmxlbmd0aCA9PT0gMSAmJiBhcmdzQ291bnRbMF0gPT09IDEpIHtcclxuICAgICAgICAgICAgICAgIGVuY29kZWRBcmdzID0gWyBbIGFyZ3MgYXMgc3RyaW5nIF1dXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoYXJncykpIHtcclxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICBhcmdzQ291bnQubGVuZ3RoID09PSBhcmdzLmxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiAhYXJncy5maW5kKChzdWJhcmdzLCBpbmRleCkgPT4gc3ViYXJncy5sZW5ndGggIT09IGFyZ3NDb3VudFtpbmRleF0pXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICBlbmNvZGVkQXJncyA9IGFyZ3MgYXMgQXJyYXk8c3RyaW5nW10+XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgICAgICAgICBhcmdzLmxlbmd0aCA9PT0gYXJnc0NvdW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgJiYgIWFyZ3MuZmluZChhcmcgPT4gdHlwZW9mIGFyZyAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgZW5jb2RlZEFyZ3MgPSBbIGFyZ3MgYXMgc3RyaW5nW10gXVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlbmNvZGVkQXJncy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX1AJHt0aGlzLmFkZHJlc3N9OiB1bm1hdGNoaW5nIGFyZ3MgY291bnQgIT0gWyR7YXJnc0NvdW50fSwgXS5gKVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtZXRob2QgPSB0aGlzLmNvbnRyYWN0LmdldEZ1bmN0aW9uKFwidmVyaWZ5UmFkb25SZXF1ZXN0KHN0cmluZ1tdW10pXCIpXHJcbiAgICAgICAgY29uc3QgcmFkSGFzaCA9IChhd2FpdCBtZXRob2Quc3RhdGljQ2FsbChlbmNvZGVkQXJncykpLnNsaWNlKDIpXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgKGF3YWl0IHRoaXMud2l0T3JhY2xlLmdldFdpdE9yYWNsZVJhZG9uUmVnaXN0cnkoKSkubG9va3VwUmFkb25SZXF1ZXN0Qnl0ZWNvZGUocmFkSGFzaClcclxuICAgICAgICB9IGNhdGNoIHtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnM/Lm9uVmVyaWZ5UmFkb25SZXF1ZXN0KSBvcHRpb25zLm9uVmVyaWZ5UmFkb25SZXF1ZXN0KHJhZEhhc2gpO1xyXG4gICAgICAgICAgICBhd2FpdCBtZXRob2RcclxuICAgICAgICAgICAgICAgIC5zZW5kKGVuY29kZWRBcmdzKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4odHggPT4gdHgud2FpdChvcHRpb25zPy5jb25maXJtYXRpb25zIHx8IDEpKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVjZWlwdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnM/Lm9uVmVyaWZ5UmFkb25SZXF1ZXN0UmVjZWlwdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm9uVmVyaWZ5UmFkb25SZXF1ZXN0UmVjZWlwdChyZWNlaXB0KVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmFkSGFzaFxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJhZEhhc2hcclxuICAgIH1cclxufVxyXG5cclxuIl19