UNPKG

eulith-web3js-core

Version:

Eulith core web3js SDK (code to access Eulith services via web3js)

308 lines 40.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Tokens = void 0; const web3_1 = __importDefault(require("web3")); const Eulith = __importStar(require("../src/index")); /** * Module for code relating to (mostly ERC20) tokens. */ var Tokens; (function (Tokens) { /** * The Symbols enumeration lists the ERC20 symbol (property of the contract) values associated with * some common ERC20 token contracts. * * Historical Note: Cloned from erc20.py TokenSymbol */ let Symbols; (function (Symbols) { Symbols["USDT"] = "USDT"; Symbols["BNB"] = "BNB"; Symbols["USDC"] = "USDC"; Symbols["BUSD"] = "BUSD"; Symbols["MATIC"] = "MATIC"; Symbols["STETH"] = "stETH"; Symbols["WETH"] = "WETH"; Symbols["LDO"] = "LDO"; Symbols["CRV"] = "CRV"; Symbols["CVX"] = "CVX"; Symbols["BAL"] = "BAL"; Symbols["BADGER"] = "BADGER"; Symbols["ONEINCH"] = "1INCH"; Symbols["UNI"] = "UNI"; Symbols["LINK"] = "LINK"; Symbols["APE"] = "APE"; Symbols["GMT"] = "GMT"; Symbols["WBTC"] = "WBTC"; Symbols["LUSD"] = "LUSD"; Symbols["FRAX"] = "FRAX"; Symbols["CBETH"] = "cbETH"; Symbols["GALA"] = "GALA"; Symbols["HEX"] = "HEX"; Symbols["RPL"] = "RPL"; Symbols["DYDX"] = "DYDX"; Symbols["BONE"] = "BONE"; Symbols["LOOKS"] = "LOOKS"; Symbols["AGEUR"] = "agEUR"; Symbols["OSQTH"] = "oSQTH"; Symbols["WSTETH"] = "wstETH"; Symbols["ALBT"] = "ALBT"; })(Symbols = Tokens.Symbols || (Tokens.Symbols = {})); /** * Eulith.Token.getTokenContract - erc20-token-based smart contract factory * * Return the ERC20based token contract object, for the given symbol. * * This function always returns a valid ERC20 contract, or raises an exception. * * This function requires a valid 'provider' (which is bound to the returned contract), * and EITHER an valid symbol, or contract address (from which the symbol can be retrieved). * * See also Eulith.Contracts.ERC20TokenContract - if you don't have a 'symbol' - but an address/etc for the contract. * * \note - this replaces Eulith.Web3.getERCToken() */ function getTokenContract({ provider, symbol, address }) { return __awaiter(this, void 0, void 0, function* () { try { let contractAddr; let decimals; if (symbol != undefined) { const result = (yield provider.request({ method: "eulith_erc_lookup", params: [{ symbol }] }))[0]; contractAddr = result === null || result === void 0 ? void 0 : result.contract_address; decimals = result === null || result === void 0 ? void 0 : result.decimals; } else { contractAddr = address; } if (contractAddr === undefined) { throw new Error("Unrecognized token contract"); } if (symbol == Eulith.Tokens.Symbols.WETH) { if (decimals != 18) { throw new Error("unexpected decimal count in getTokenContract"); } return Eulith.Contracts.WethTokenContract.mk({ provider, contractAddress: contractAddr }); } else { return Eulith.Contracts.ERC20TokenContract.mk({ provider, contractAddress: contractAddr, decimals, symbol }); } } catch (e) { // check if is 'Error' type and prepend 'while' ... stuff to message // LogErr_(this.logger_, "calling getERCToken", e); throw e; } }); } Tokens.getTokenContract = getTokenContract; /** * The API for web3js is somewhat confusing/flexible about units. These utility classes * make easier converting a particular value to/from its web/wire format, and to/from a * sensible numeric value in that tokens 'base' units. * * \note It would be nice to support operator overloading, and conversion operators and such * but this appears to be a weakness in typescript, that it doesn't support this (making a utility like this * far less useful) */ let Value; (function (Value) { /** * An ETH token value is NOT an ERC20 compatible token value, but rather a value from the native blockchain. */ class ETH { /** * if v is a number, its interpretted in ether units * if v is a string or bigint, its interpretted as being in fundamental units (wei). */ constructor(v) { if (typeof v === "number") { this.fundementalValue_ = BigInt(v * Math.pow(10, 18)); } else if (typeof v === "bigint") { this.fundementalValue_ = v; } else { this.fundementalValue_ = BigInt(web3_1.default.utils.toWei(v, "wei")); } } /** * Return the value as a native javascript number, in the units of this currency (ETH) */ get asFloat() { return Number(this.fundementalValue_) / Math.pow(10, 18); } /* * wire format is the 'Fundamental' format, as Hex string */ get asWire() { return this.asWeiHex; } get asFundamentalFloat() { return Number(this.fundementalValue_); } get asFundamentalBN() { return web3_1.default.utils.toBN(this.asFundamentalFloat); } get asFundamentalHex() { return web3_1.default.utils.fromWei(this.asFundamentalBN, "wei"); } get asFundamentalBigInt() { return this.fundementalValue_; } /* * 'Wei' is the 'Fundamental' currency for ETH */ get asWeiBN() { return this.asFundamentalBN; } get asWeiHex() { return this.asFundamentalHex; } get asWeiBigInt() { return this.asFundamentalBigInt; } get symbol() { return "ETH"; } get asDisplayString() { return `${this.asFloat} ${this.symbol}`; } cloneWithNewValue(newV) { return new ETH(newV); } } Value.ETH = ETH; /** * Eulith.Tokens.Value.ERC20 is an object that refers to a value of a token from an ERC20 * contract (see https://eips.ethereum.org/EIPS/eip-20). * * This contains a number, and a level of precision, used when converting to the native form. */ class ERC20 { /** * if v is a number, its interpretted in ERC20 token units * if v is a string | BigInt, its interpretted as being in fundamental units. */ constructor({ v, decimals, contract, symbol }) { if (contract && !decimals) { decimals = contract.decimals; } if (!decimals) { throw new Error("Expected either decimals or contract as argument to Eulith.Tokens.Value.ERC20"); } if (contract && !symbol) { symbol = contract.symbol; } if (!symbol) { throw new Error("Expected either symbol or contract as argument to Eulith.Tokens.Value.ERC20"); } this.symbol_ = symbol; this.decimals_ = decimals; this.toWireFactor_ = Math.pow(10, decimals); if (typeof v === "number") { this.fundementalValue_ = BigInt(Math.round(v * this.toWireFactor_)); } else if (typeof v === "bigint") { this.fundementalValue_ = v; } else if (typeof v === "string") { this.fundementalValue_ = BigInt(v); } else { this.fundementalValue_ = v.asFundamentalBigInt; } } get asFloat() { // @todo this isn't necesarily the best way to convert - probably better to shift decimals first and then convert. return Number(this.fundementalValue_) / this.toWireFactor_; } get asWire() { return this.asFundamentalHex; } get asFundamentalHex() { return "0x" + this.fundementalValue_.toString(16); } get asFundamentalBN() { return web3_1.default.utils.toBN(this.asFundamentalHex); } get asFundamentalBigInt() { return this.fundementalValue_; } get asFundamentalFloat() { return Number(this.fundementalValue_); } get symbol() { return this.symbol_; } get asDisplayString() { return `${this.asFloat} ${this.symbol}`; } cloneWithNewValue(newV) { return new ERC20({ v: newV, symbol: this.symbol_, decimals: this.decimals_ }); } } Value.ERC20 = ERC20; /** * @todo DISCUSS IF THIS SHOULD BE DEPRECATED? IMHO NO, but Kristian at one point I think thought it should... */ class USDC extends ERC20 { constructor(v) { super({ v: v, decimals: 6 }); } } Value.USDC = USDC; /** * Really BEST word here would be Atomic, but too risky of confusion with atomic in "Atomic Transactions" * * This is the smallest indivisible unit of money for a given ERC20 token. */ class Fundamental extends ERC20 { constructor(v) { super({ v: v, decimals: 1 }); } } Value.Fundamental = Fundamental; })(Value = Tokens.Value || (Tokens.Value = {})); })(Tokens = exports.Tokens || (exports.Tokens = {})); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rva2Vucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLGdEQUF3QjtBQUV4QixxREFBdUM7QUFFdkM7O0dBRUc7QUFDSCxJQUFjLE1BQU0sQ0F3WG5CO0FBeFhELFdBQWMsTUFBTTtJQUNoQjs7Ozs7T0FLRztJQUNILElBQVksT0FnQ1g7SUFoQ0QsV0FBWSxPQUFPO1FBQ2Ysd0JBQWEsQ0FBQTtRQUNiLHNCQUFXLENBQUE7UUFDWCx3QkFBYSxDQUFBO1FBQ2Isd0JBQWEsQ0FBQTtRQUNiLDBCQUFlLENBQUE7UUFDZiwwQkFBZSxDQUFBO1FBQ2Ysd0JBQWEsQ0FBQTtRQUNiLHNCQUFXLENBQUE7UUFDWCxzQkFBVyxDQUFBO1FBQ1gsc0JBQVcsQ0FBQTtRQUNYLHNCQUFXLENBQUE7UUFDWCw0QkFBaUIsQ0FBQTtRQUNqQiw0QkFBaUIsQ0FBQTtRQUNqQixzQkFBVyxDQUFBO1FBQ1gsd0JBQWEsQ0FBQTtRQUNiLHNCQUFXLENBQUE7UUFDWCxzQkFBVyxDQUFBO1FBQ1gsd0JBQWEsQ0FBQTtRQUNiLHdCQUFhLENBQUE7UUFDYix3QkFBYSxDQUFBO1FBQ2IsMEJBQWUsQ0FBQTtRQUNmLHdCQUFhLENBQUE7UUFDYixzQkFBVyxDQUFBO1FBQ1gsc0JBQVcsQ0FBQTtRQUNYLHdCQUFhLENBQUE7UUFDYix3QkFBYSxDQUFBO1FBQ2IsMEJBQWUsQ0FBQTtRQUNmLDBCQUFlLENBQUE7UUFDZiwwQkFBZSxDQUFBO1FBQ2YsNEJBQWlCLENBQUE7UUFDakIsd0JBQWEsQ0FBQTtJQUNqQixDQUFDLEVBaENXLE9BQU8sR0FBUCxjQUFPLEtBQVAsY0FBTyxRQWdDbEI7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsU0FBc0IsZ0JBQWdCLENBQUMsRUFDbkMsUUFBUSxFQUNSLE1BQU0sRUFDTixPQUFPLEVBS1Y7O1lBQ0csSUFBSTtnQkFDQSxJQUFJLFlBQW9CLENBQUM7Z0JBQ3pCLElBQUksUUFBZ0IsQ0FBQztnQkFDckIsSUFBSSxNQUFNLElBQUksU0FBUyxFQUFFO29CQUNyQixNQUFNLE1BQU0sR0FBRyxDQUFDLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ2xHLFlBQVksR0FBRyxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsZ0JBQWdCLENBQUM7b0JBQ3hDLFFBQVEsR0FBRyxNQUFNLGFBQU4sTUFBTSx1QkFBTixNQUFNLENBQUUsUUFBa0IsQ0FBQztpQkFDekM7cUJBQU07b0JBQ0gsWUFBWSxHQUFHLE9BQU8sQ0FBQztpQkFDMUI7Z0JBQ0QsSUFBSSxZQUFZLEtBQUssU0FBUyxFQUFFO29CQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7aUJBQ2xEO2dCQUNELElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtvQkFDdEMsSUFBSSxRQUFRLElBQUksRUFBRSxFQUFFO3dCQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7cUJBQ25FO29CQUNELE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7aUJBQzdGO3FCQUFNO29CQUNILE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7d0JBQzFDLFFBQVE7d0JBQ1IsZUFBZSxFQUFFLFlBQVk7d0JBQzdCLFFBQVE7d0JBQ1IsTUFBTTtxQkFDVCxDQUFDLENBQUM7aUJBQ047YUFDSjtZQUFDLE9BQU8sQ0FBTSxFQUFFO2dCQUNiLG9FQUFvRTtnQkFDcEUsbURBQW1EO2dCQUNuRCxNQUFNLENBQUMsQ0FBQzthQUNYO1FBQ0wsQ0FBQztLQUFBO0lBeENxQix1QkFBZ0IsbUJBd0NyQyxDQUFBO0lBRUQ7Ozs7Ozs7O09BUUc7SUFFSCxJQUFjLEtBQUssQ0E0UWxCO0lBNVFELFdBQWMsS0FBSztRQXlGZjs7V0FFRztRQUNILE1BQWEsR0FBRztZQUdaOzs7ZUFHRztZQUNILFlBQW1CLENBQTJCO2dCQUMxQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsRUFBRTtvQkFDdkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBRSxDQUFZLEdBQUcsU0FBQSxFQUFFLEVBQUksRUFBRSxDQUFBLENBQUMsQ0FBQztpQkFDN0Q7cUJBQU0sSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLEVBQUU7b0JBQzlCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxDQUFXLENBQUM7aUJBQ3hDO3FCQUFNO29CQUNILElBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsY0FBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7aUJBQ3pFO1lBQ0wsQ0FBQztZQUVEOztlQUVHO1lBQ0gsSUFBVyxPQUFPO2dCQUNkLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLFNBQUEsRUFBRSxFQUFJLEVBQUUsQ0FBQSxDQUFDO1lBQ3JELENBQUM7WUFFRDs7ZUFFRztZQUNILElBQVcsTUFBTTtnQkFDYixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDekIsQ0FBQztZQUVELElBQVcsa0JBQWtCO2dCQUN6QixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUMxQyxDQUFDO1lBQ0QsSUFBVyxlQUFlO2dCQUN0QixPQUFPLGNBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ3BELENBQUM7WUFDRCxJQUFXLGdCQUFnQjtnQkFDdkIsT0FBTyxjQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNELENBQUM7WUFDRCxJQUFXLG1CQUFtQjtnQkFDMUIsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUM7WUFDbEMsQ0FBQztZQUVEOztlQUVHO1lBQ0gsSUFBVyxPQUFPO2dCQUNkLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUNoQyxDQUFDO1lBQ0QsSUFBVyxRQUFRO2dCQUNmLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDO1lBQ2pDLENBQUM7WUFDRCxJQUFXLFdBQVc7Z0JBQ2xCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDO1lBQ3BDLENBQUM7WUFFRCxJQUFXLE1BQU07Z0JBQ2IsT0FBTyxLQUFLLENBQUM7WUFDakIsQ0FBQztZQUVELElBQVcsZUFBZTtnQkFDdEIsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzVDLENBQUM7WUFFTSxpQkFBaUIsQ0FBQyxJQUE4QjtnQkFDbkQsT0FBTyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixDQUFDO1NBQ0o7UUFwRVksU0FBRyxNQW9FZixDQUFBO1FBRUQ7Ozs7O1dBS0c7UUFDSCxNQUFhLEtBQUs7WUFNZDs7O2VBR0c7WUFDSCxZQUFtQixFQUNmLENBQUMsRUFDRCxRQUFRLEVBQ1IsUUFBUSxFQUNSLE1BQU0sRUFNVDtnQkFDRyxJQUFJLFFBQVEsSUFBSSxDQUFDLFFBQVEsRUFBRTtvQkFDdkIsUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUM7aUJBQ2hDO2dCQUNELElBQUksQ0FBQyxRQUFRLEVBQUU7b0JBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQywrRUFBK0UsQ0FBQyxDQUFDO2lCQUNwRztnQkFDRCxJQUFJLFFBQVEsSUFBSSxDQUFDLE1BQU0sRUFBRTtvQkFDckIsTUFBTSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7aUJBQzVCO2dCQUNELElBQUksQ0FBQyxNQUFNLEVBQUU7b0JBQ1QsTUFBTSxJQUFJLEtBQUssQ0FBQyw2RUFBNkUsQ0FBQyxDQUFDO2lCQUNsRztnQkFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztnQkFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQzVDLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxFQUFFO29CQUN2QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUUsQ0FBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO2lCQUNuRjtxQkFBTSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsRUFBRTtvQkFDOUIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQVcsQ0FBQztpQkFDeEM7cUJBQU0sSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLEVBQUU7b0JBQzlCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsQ0FBVyxDQUFDLENBQUM7aUJBQ2hEO3FCQUFNO29CQUNILElBQUksQ0FBQyxpQkFBaUIsR0FBSSxDQUFpQixDQUFDLG1CQUFtQixDQUFDO2lCQUNuRTtZQUNMLENBQUM7WUFFRCxJQUFXLE9BQU87Z0JBQ2Qsa0hBQWtIO2dCQUNsSCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQy9ELENBQUM7WUFFRCxJQUFXLE1BQU07Z0JBQ2IsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7WUFDakMsQ0FBQztZQUVELElBQVcsZ0JBQWdCO2dCQUN2QixPQUFPLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3RELENBQUM7WUFDRCxJQUFXLGVBQWU7Z0JBQ3RCLE9BQU8sY0FBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDbEQsQ0FBQztZQUNELElBQVcsbUJBQW1CO2dCQUMxQixPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztZQUNsQyxDQUFDO1lBQ0QsSUFBVyxrQkFBa0I7Z0JBQ3pCLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQzFDLENBQUM7WUFFRCxJQUFXLE1BQU07Z0JBQ2IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQ3hCLENBQUM7WUFDRCxJQUFXLGVBQWU7Z0JBQ3RCLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM1QyxDQUFDO1lBRU0saUJBQWlCLENBQUMsSUFBOEI7Z0JBQ25ELE9BQU8sSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztZQUNsRixDQUFDO1NBQ0o7UUEvRVksV0FBSyxRQStFakIsQ0FBQTtRQUVEOztXQUVHO1FBQ0gsTUFBYSxJQUFLLFNBQVEsS0FBSztZQUMzQixZQUFtQixDQUFrQjtnQkFDakMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqQyxDQUFDO1NBQ0o7UUFKWSxVQUFJLE9BSWhCLENBQUE7UUFFRDs7OztXQUlHO1FBQ0gsTUFBYSxXQUFZLFNBQVEsS0FBSztZQUNsQyxZQUFtQixDQUFrQjtnQkFDakMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqQyxDQUFDO1NBQ0o7UUFKWSxpQkFBVyxjQUl2QixDQUFBO0lBQ0wsQ0FBQyxFQTVRYSxLQUFLLEdBQUwsWUFBSyxLQUFMLFlBQUssUUE0UWxCO0FBQ0wsQ0FBQyxFQXhYYSxNQUFNLEdBQU4sY0FBTSxLQUFOLGNBQU0sUUF3WG5CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJOIGZyb20gXCJiblwiO1xuaW1wb3J0IFdlYjMgZnJvbSBcIndlYjNcIjtcblxuaW1wb3J0ICogYXMgRXVsaXRoIGZyb20gXCIuLi9zcmMvaW5kZXhcIjtcblxuLyoqXG4gKiAgTW9kdWxlIGZvciBjb2RlIHJlbGF0aW5nIHRvIChtb3N0bHkgRVJDMjApIHRva2Vucy5cbiAqL1xuZXhwb3J0IG1vZHVsZSBUb2tlbnMge1xuICAgIC8qKlxuICAgICAqICBUaGUgU3ltYm9scyBlbnVtZXJhdGlvbiBsaXN0cyB0aGUgRVJDMjAgc3ltYm9sIChwcm9wZXJ0eSBvZiB0aGUgY29udHJhY3QpIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGhcbiAgICAgKiAgc29tZSBjb21tb24gRVJDMjAgdG9rZW4gY29udHJhY3RzLlxuICAgICAqXG4gICAgICogIEhpc3RvcmljYWwgTm90ZTogQ2xvbmVkIGZyb20gZXJjMjAucHkgVG9rZW5TeW1ib2xcbiAgICAgKi9cbiAgICBleHBvcnQgZW51bSBTeW1ib2xzIHtcbiAgICAgICAgVVNEVCA9IFwiVVNEVFwiLFxuICAgICAgICBCTkIgPSBcIkJOQlwiLFxuICAgICAgICBVU0RDID0gXCJVU0RDXCIsXG4gICAgICAgIEJVU0QgPSBcIkJVU0RcIixcbiAgICAgICAgTUFUSUMgPSBcIk1BVElDXCIsXG4gICAgICAgIFNURVRIID0gXCJzdEVUSFwiLFxuICAgICAgICBXRVRIID0gXCJXRVRIXCIsXG4gICAgICAgIExETyA9IFwiTERPXCIsXG4gICAgICAgIENSViA9IFwiQ1JWXCIsXG4gICAgICAgIENWWCA9IFwiQ1ZYXCIsXG4gICAgICAgIEJBTCA9IFwiQkFMXCIsXG4gICAgICAgIEJBREdFUiA9IFwiQkFER0VSXCIsXG4gICAgICAgIE9ORUlOQ0ggPSBcIjFJTkNIXCIsXG4gICAgICAgIFVOSSA9IFwiVU5JXCIsXG4gICAgICAgIExJTksgPSBcIkxJTktcIixcbiAgICAgICAgQVBFID0gXCJBUEVcIixcbiAgICAgICAgR01UID0gXCJHTVRcIixcbiAgICAgICAgV0JUQyA9IFwiV0JUQ1wiLFxuICAgICAgICBMVVNEID0gXCJMVVNEXCIsXG4gICAgICAgIEZSQVggPSBcIkZSQVhcIixcbiAgICAgICAgQ0JFVEggPSBcImNiRVRIXCIsXG4gICAgICAgIEdBTEEgPSBcIkdBTEFcIixcbiAgICAgICAgSEVYID0gXCJIRVhcIixcbiAgICAgICAgUlBMID0gXCJSUExcIixcbiAgICAgICAgRFlEWCA9IFwiRFlEWFwiLFxuICAgICAgICBCT05FID0gXCJCT05FXCIsXG4gICAgICAgIExPT0tTID0gXCJMT09LU1wiLFxuICAgICAgICBBR0VVUiA9IFwiYWdFVVJcIixcbiAgICAgICAgT1NRVEggPSBcIm9TUVRIXCIsXG4gICAgICAgIFdTVEVUSCA9IFwid3N0RVRIXCIsXG4gICAgICAgIEFMQlQgPSBcIkFMQlRcIlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV1bGl0aC5Ub2tlbi5nZXRUb2tlbkNvbnRyYWN0IC0gZXJjMjAtdG9rZW4tYmFzZWQgc21hcnQgY29udHJhY3QgZmFjdG9yeVxuICAgICAqXG4gICAgICogIFJldHVybiB0aGUgRVJDMjBiYXNlZCB0b2tlbiBjb250cmFjdCBvYmplY3QsIGZvciB0aGUgZ2l2ZW4gc3ltYm9sLlxuICAgICAqXG4gICAgICogIFRoaXMgZnVuY3Rpb24gYWx3YXlzIHJldHVybnMgYSB2YWxpZCBFUkMyMCBjb250cmFjdCwgb3IgcmFpc2VzIGFuIGV4Y2VwdGlvbi5cbiAgICAgKlxuICAgICAqICBUaGlzIGZ1bmN0aW9uIHJlcXVpcmVzIGEgdmFsaWQgJ3Byb3ZpZGVyJyAod2hpY2ggaXMgYm91bmQgdG8gdGhlIHJldHVybmVkIGNvbnRyYWN0KSxcbiAgICAgKiAgYW5kIEVJVEhFUiBhbiB2YWxpZCBzeW1ib2wsIG9yIGNvbnRyYWN0IGFkZHJlc3MgKGZyb20gd2hpY2ggdGhlIHN5bWJvbCBjYW4gYmUgcmV0cmlldmVkKS5cbiAgICAgKlxuICAgICAqICBTZWUgYWxzbyBFdWxpdGguQ29udHJhY3RzLkVSQzIwVG9rZW5Db250cmFjdCAtIGlmIHlvdSBkb24ndCBoYXZlIGEgJ3N5bWJvbCcgLSBidXQgYW4gYWRkcmVzcy9ldGMgZm9yIHRoZSBjb250cmFjdC5cbiAgICAgKlxuICAgICAqICBcXG5vdGUgLSB0aGlzIHJlcGxhY2VzIEV1bGl0aC5XZWIzLmdldEVSQ1Rva2VuKClcbiAgICAgKi9cbiAgICBleHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0VG9rZW5Db250cmFjdCh7XG4gICAgICAgIHByb3ZpZGVyLFxuICAgICAgICBzeW1ib2wsXG4gICAgICAgIGFkZHJlc3NcbiAgICB9OiB7XG4gICAgICAgIHByb3ZpZGVyOiBFdWxpdGguUHJvdmlkZXI7XG4gICAgICAgIHN5bWJvbD86IFN5bWJvbHM7XG4gICAgICAgIGFkZHJlc3M/OiBzdHJpbmc7XG4gICAgfSk6IFByb21pc2U8RXVsaXRoLkNvbnRyYWN0cy5FUkMyMFRva2VuQ29udHJhY3QgfCBFdWxpdGguQ29udHJhY3RzLldldGhUb2tlbkNvbnRyYWN0PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgY29udHJhY3RBZGRyOiBzdHJpbmc7XG4gICAgICAgICAgICBsZXQgZGVjaW1hbHM6IG51bWJlcjtcbiAgICAgICAgICAgIGlmIChzeW1ib2wgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gKGF3YWl0IHByb3ZpZGVyLnJlcXVlc3QoeyBtZXRob2Q6IFwiZXVsaXRoX2VyY19sb29rdXBcIiwgcGFyYW1zOiBbeyBzeW1ib2wgfV0gfSkpWzBdO1xuICAgICAgICAgICAgICAgIGNvbnRyYWN0QWRkciA9IHJlc3VsdD8uY29udHJhY3RfYWRkcmVzcztcbiAgICAgICAgICAgICAgICBkZWNpbWFscyA9IHJlc3VsdD8uZGVjaW1hbHMgYXMgbnVtYmVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250cmFjdEFkZHIgPSBhZGRyZXNzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbnRyYWN0QWRkciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5yZWNvZ25pemVkIHRva2VuIGNvbnRyYWN0XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN5bWJvbCA9PSBFdWxpdGguVG9rZW5zLlN5bWJvbHMuV0VUSCkge1xuICAgICAgICAgICAgICAgIGlmIChkZWNpbWFscyAhPSAxOCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bmV4cGVjdGVkIGRlY2ltYWwgY291bnQgaW4gZ2V0VG9rZW5Db250cmFjdFwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIEV1bGl0aC5Db250cmFjdHMuV2V0aFRva2VuQ29udHJhY3QubWsoeyBwcm92aWRlciwgY29udHJhY3RBZGRyZXNzOiBjb250cmFjdEFkZHIgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBFdWxpdGguQ29udHJhY3RzLkVSQzIwVG9rZW5Db250cmFjdC5tayh7XG4gICAgICAgICAgICAgICAgICAgIHByb3ZpZGVyLFxuICAgICAgICAgICAgICAgICAgICBjb250cmFjdEFkZHJlc3M6IGNvbnRyYWN0QWRkcixcbiAgICAgICAgICAgICAgICAgICAgZGVjaW1hbHMsXG4gICAgICAgICAgICAgICAgICAgIHN5bWJvbFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGlzICdFcnJvcicgdHlwZSBhbmQgcHJlcGVuZCAnd2hpbGUnIC4uLiBzdHVmZiB0byBtZXNzYWdlXG4gICAgICAgICAgICAvLyBMb2dFcnJfKHRoaXMubG9nZ2VyXywgXCJjYWxsaW5nIGdldEVSQ1Rva2VuXCIsIGUpO1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqICBUaGUgQVBJIGZvciB3ZWIzanMgaXMgc29tZXdoYXQgY29uZnVzaW5nL2ZsZXhpYmxlIGFib3V0IHVuaXRzLiBUaGVzZSB1dGlsaXR5IGNsYXNzZXNcbiAgICAgKiAgbWFrZSBlYXNpZXIgY29udmVydGluZyBhIHBhcnRpY3VsYXIgdmFsdWUgdG8vZnJvbSBpdHMgd2ViL3dpcmUgZm9ybWF0LCBhbmQgdG8vZnJvbSBhXG4gICAgICogIHNlbnNpYmxlIG51bWVyaWMgdmFsdWUgaW4gdGhhdCB0b2tlbnMgJ2Jhc2UnIHVuaXRzLlxuICAgICAqXG4gICAgICogIFxcbm90ZSBJdCB3b3VsZCBiZSBuaWNlIHRvIHN1cHBvcnQgb3BlcmF0b3Igb3ZlcmxvYWRpbmcsIGFuZCBjb252ZXJzaW9uIG9wZXJhdG9ycyBhbmQgc3VjaFxuICAgICAqICAgICAgICBidXQgdGhpcyBhcHBlYXJzIHRvIGJlIGEgd2Vha25lc3MgaW4gdHlwZXNjcmlwdCwgdGhhdCBpdCBkb2Vzbid0IHN1cHBvcnQgdGhpcyAobWFraW5nIGEgdXRpbGl0eSBsaWtlIHRoaXNcbiAgICAgKiAgICAgICAgZmFyIGxlc3MgdXNlZnVsKVxuICAgICAqL1xuXG4gICAgZXhwb3J0IG1vZHVsZSBWYWx1ZSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiAgQWJzdHJhY3QgQVBJIHRvIGNhcHR1cmUgYmFzaWMgaW50ZXJvcGVyYXRpb24gb2YgdG9rZW4gdmFsdWVzIGFzIGV4Y2hhbmdlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogIE9uZSBrZXkgaWRlYSBoZXJlIC0gaXMgdGhhdCBmb3IgSVRva2VuVmFsdWUsIHRoZXJlIGFyZSB0d28gQkFTSUMgTlVNQkVSUyB5b3UgY2FuIGdldC5cbiAgICAgICAgICogICAgICBvICAgdGhlIHZhbHVlIGluIGl0cyBiYXNpYyBhdG9taWMgKGZ1bmRlbWVudGFsKSB1bml0c1xuICAgICAgICAgKiAgICAgIG8gICBhbmQgdGhlIHZhbHVlIGluIGl0cyBuYXRpdmUgKGUuZy4gV0VUSCBvciBVRFNDIGV0YykgRVJDMjAgdW5pdHMuXG4gICAgICAgICAqXG4gICAgICAgICAqICBUaGVuIHRoZXJlIGlzIHRoZSBPUlRIT0dBTkFMIGlzc3VlIG9mIGhvdyB5b3UgcmVwcmVzZW50IHRoYXQgbnVtYmVyIChmbG9hdCwgb3IgaGV4IHN0cmluZykuXG4gICAgICAgICAqXG4gICAgICAgICAqICBJdCB0dXJucyBvdXQgLSB0aGUgT05MWSB1c2UgZm9yIHRoZSBoZXggc3RyaW5ncywgYXJlIGluIGZ1bmRlbWVudGFsIHVuaXRzLCAod2lyZSBmb3JtYXQpIC1cbiAgICAgICAgICogIHNvIHRoYXRzIHRoZSBvbmx5IGNhc2Ugd2hlcmUgd2Ugb2ZmZXIgdGhhdCByZXByZXNlbnRhdGlvbiB0eXBlLiBTaW1pbGFybHksIEJpZ051bSdzIGFyZSB1c2VkXG4gICAgICAgICAqICBlc3NlbnRpYWxseSBhbHdheXMgZm9yIHRoZSBmdW5kZW1lbnRhbCByZXByZXNlbnRhdGlvbiAoYXRvbWljIHVuaXRzKSAtIHNvIHRoaXMgaXMgdGhlIHByZWZlcmVkXG4gICAgICAgICAqICBkYXRhIGZvcm1hdCBmb3IgdGhlIGZ1bmRlbWVudGFsIHJlcHJlc2VudGF0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiAgQHRvZG8gRElTQ1VTUyBpZiBJVG9rZW5WYWx1ZSBzaG91bGQgaGF2ZSBhIHJlYWRvbmx5ICd1bml0cycgc3RyaW5nIHByb3BlcnR5LCBvcHRpb25hbCxcbiAgICAgICAgICogICAgICAgIGZvciBkb2N1bWVudGF0aW9uIHB1cnBvc2VzIChhc0Rpc3BsYXlTdHJpbmcgbWV0aG9kKS4gTUlHSFQgQkUgVVNFRlVMIHRvIHRyYWNrXG4gICAgICAgICAqICAgICAgICBkaWZmZXJlbmNlIGJldHdlZW4gRVRIIGFuZCBVU0RDIHRva2VuIHZhbHVlcy4gSW50ZXJvcGVyYWJsZSwgYnV0IHRoYXRzIHByb2JhYmx5IHVuZm9ydHVuYXRlLlxuICAgICAgICAgKlxuICAgICAgICAgKiAgQHRvZG8gRElTQ1VTUyBpZiBJVG9rZW5WYWx1ZSBzaG91bGQgaGF2ZSBhIHJlYWRvbmx5ICdkZWNpbWFscycgdmFsdWUuIEl0IGhhcyB0aGlzIElNUExJQ0lUTFkgYmVjYXVzZVxuICAgICAgICAgKiAgICAgICAgb2YgdGhlIGNvdm5lcnNpb24gYmV0d2VlbiBhc0Zsb2F0IGFuZCBhc0Z1bmRhbWVudGFsRmxvYXQgKGRlY2ltYWxzPT1sb2coYXNGdW5kYW1lbnRhbEZsb2F0L2FzRmxvYXQpKVxuICAgICAgICAgKi9cbiAgICAgICAgZXhwb3J0IGludGVyZmFjZSBJVG9rZW5WYWx1ZSB7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqICBSZXR1cm4gdGhlIHZhbHVlIGFzIGEgbmF0aXZlIGphdmFzY3JpcHQgbnVtYmVyLCBpbiB0aGUgdW5pdHMgb2YgdGhpcyBjdXJyZW5jeVxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqICBOT1RFIC0gdGhpcyBjb252ZXJzaW9uIHRvIGEgamF2YXNjcmlwdCBudW1iZXIgY2FuIGJlIGxvc3N5LlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqICBcXG5vdGUgLSB3ZSBjYW5ub3QgcmV0dXJuIHRoZSBFUkMyMCB0b2tlbiByZXByZXNlbnRhdGlvbiBhcyBCTiwgb3IgQmlnSW50LCAgYmVjYXVzZVxuICAgICAgICAgICAgICogICAgICAgICAgdGhpcyB3aWxsIGZyZXF1ZW50bHkgYmUgYSBmcmFjdGlvbmFsIChkZWNpbWFsKSBxdWFudGl0eSBpbiB0aGUgbmF0aXZlIHRva2VuIHVuaXRzIChsaWtlIFVTREMsIG9yIFdFVEgpLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIEB0b2RvIElNSE8sIG91ciB1c2Ugb2YgdGhlIHRlcm0gJ0Zsb2F0JyBpbiB0aGlzIEFQSSBjb3VsZCByZWFzb25hYmx5IGJlIHJlcGxhY2VkIHdpdGggJ051bWJlcicsIGFuZCB3b3VsZCBmaXQgYmV0dGVyXG4gICAgICAgICAgICAgKiAgICAgICB3aXRoIEpTIC0gQEtyaXN0aWFuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGdldCBhc0Zsb2F0KCk6IG51bWJlcjtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJucyB0aGUgdG9rZW4gdmFsdWUgaW4gdGhlIG5hdGl2ZSBmb3JtIGFzIGl0IGdvZXMgb3ZlciB0aGUgd2lyZSB0by9mcm9tIHRoZSBldGhlcmV1bSBuZXR3b3JrL2NvbnRyYWN0LlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqICBUaGlzIGlzIGVxdWl2aWxlbnQgdG8gYXNGdW5kYW1lbnRhbEhleFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgYXNXaXJlKCk6IHN0cmluZztcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJucyB0aGUgdG9rZW4gdmFsdWUgYXMgYW4gaW50ZWdyYWwgIyBmbG9hdCBpbiB0aGUgRnVuZGFtZW50YWwgKGF0b21pYykgdW5pdHNcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgZ2V0IGFzRnVuZGFtZW50YWxGbG9hdCgpOiBudW1iZXI7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogIFJldHVybnMgdGhlIHRva2VuIHZhbHVlIGFzIGFuIGludGVncmFsICMgQk4gKG9sZCBCaWdOdW1iZXIgQVBJKSBpbiB0aGUgRnVuZGFtZW50YWwgKGF0b21pYykgdW5pdHNcbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKiAgXFxub3RlIC0gQk4gdXNlZCBpbnRlcm5hbGx5IGJ5IHdlYjNqcyBhcyBvZiAxLjgueFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgYXNGdW5kYW1lbnRhbEJOKCk6IEJOO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqICBSZXR1cm5zIHRoZSB0b2tlbiB2YWx1ZSBhcyBhbiBpbnRlZ3JhbCAjIEJpZ0ludCAoTkVXIEJpZ051bWJlciBBUEkpIGluIHRoZSBGdW5kYW1lbnRhbCAoYXRvbWljKSB1bml0c1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgYXNGdW5kYW1lbnRhbEJpZ0ludCgpOiBiaWdpbnQ7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogIFJldHVybnMgdGhlIHRva2VuIHZhbHVlIGFzIGEgaGV4IHN0cmluZyBpbiB0aGUgZnVuZGFtZW50YWwgKGF0b21pYykgdW5pdHNcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgZ2V0IGFzRnVuZGFtZW50YWxIZXgoKTogc3RyaW5nO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqICBSZXR1cm4gdGhlIHN5bWJvbCBhc3NvY2lhdGVkIHdpdGggdGhpcyB0b2tlbiB2YWx1ZSAoZnJvbSBFUkMyMCBzeW1ib2wgQVBJKVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgc3ltYm9sKCk6IHN0cmluZztcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJucyB0aGUgbnVtYmVyIGluIG5hdHVyYWwgKG5vdCBhdG9taWMvZnVuZGVtZW50YWwpIHVuaXRzLCB3aXRoIHRoZSBsYWJlbCBvZiB0aGUgc3ltYm9sLlxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqICBFeGFtcGxlOlxuICAgICAgICAgICAgICogICAgICAyMy40IFdFVEhcbiAgICAgICAgICAgICAqICAgICAgMTguNDUgVVNEQ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBnZXQgYXNEaXNwbGF5U3RyaW5nKCk6IHN0cmluZztcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJucyBhIGNsb25lZCB2YWx1ZSwgYnV0IHdpdGggdGhlIG5ldyB2YWx1ZS4gbmV3ViB0eXBlIGludGVycHJldGF0aW9uIHNhbWUgYXMgdGhlXG4gICAgICAgICAgICAgKiAgdmFsdWUgY29uc3RydWN0b3IgKG51bWJlciBpbnRyaW5zaWMgdmFsdWUsIEJpZ0ludCBmdW5kZW1lbnRhbCwgYW5kIHN0cmluZyBmdW5kZW1lbnRhbClcbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKiAgVXNlZnVsIGZvciBhcml0aG1hdGljIChsaWtlIC8gMilcbiAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNsb25lV2l0aE5ld1ZhbHVlKG5ld1Y6IG51bWJlciB8IHN0cmluZyB8IGJpZ2ludCk6IElUb2tlblZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqICBBbiBFVEggdG9rZW4gdmFsdWUgaXMgTk9UIGFuIEVSQzIwIGNvbXBhdGlibGUgdG9rZW4gdmFsdWUsIGJ1dCByYXRoZXIgYSB2YWx1ZSBmcm9tIHRoZSBuYXRpdmUgYmxvY2tjaGFpbi5cbiAgICAgICAgICovXG4gICAgICAgIGV4cG9ydCBjbGFzcyBFVEggaW1wbGVtZW50cyBJVG9rZW5WYWx1ZSB7XG4gICAgICAgICAgICBwcml2YXRlIGZ1bmRlbWVudGFsVmFsdWVfOiBiaWdpbnQ7IC8vIHZhbHVlIGluICd3ZWknIChmdW5kZW1lbnRhbCB1bml0KSwgdXNpbmcgdGhlIEJpZ0ludCBwYWNrYWdlXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogaWYgdiBpcyBhIG51bWJlciwgaXRzIGludGVycHJldHRlZCBpbiBldGhlciB1bml0c1xuICAgICAgICAgICAgICogaWYgdiBpcyBhIHN0cmluZyBvciBiaWdpbnQsIGl0cyBpbnRlcnByZXR0ZWQgYXMgYmVpbmcgaW4gZnVuZGFtZW50YWwgdW5pdHMgKHdlaSkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcih2OiBudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHYgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9IEJpZ0ludCgodiBhcyBudW1iZXIpICogMTAgKiogMTgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwiYmlnaW50XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9IHYgYXMgYmlnaW50O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZnVuZGVtZW50YWxWYWx1ZV8gPSBCaWdJbnQoV2ViMy51dGlscy50b1dlaSh2IGFzIHN0cmluZywgXCJ3ZWlcIikpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiAgUmV0dXJuIHRoZSB2YWx1ZSBhcyBhIG5hdGl2ZSBqYXZhc2NyaXB0IG51bWJlciwgaW4gdGhlIHVuaXRzIG9mIHRoaXMgY3VycmVuY3kgKEVUSClcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcHVibGljIGdldCBhc0Zsb2F0KCk6IG51bWJlciB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlcih0aGlzLmZ1bmRlbWVudGFsVmFsdWVfKSAvIDEwICoqIDE4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogIHdpcmUgZm9ybWF0IGlzIHRoZSAnRnVuZGFtZW50YWwnIGZvcm1hdCwgYXMgSGV4IHN0cmluZ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzV2lyZSgpOiBzdHJpbmcge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFzV2VpSGV4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxGbG9hdCgpOiBudW1iZXIge1xuICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIodGhpcy5mdW5kZW1lbnRhbFZhbHVlXyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxCTigpOiBCTiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFdlYjMudXRpbHMudG9CTih0aGlzLmFzRnVuZGFtZW50YWxGbG9hdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxIZXgoKTogc3RyaW5nIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gV2ViMy51dGlscy5mcm9tV2VpKHRoaXMuYXNGdW5kYW1lbnRhbEJOLCBcIndlaVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHB1YmxpYyBnZXQgYXNGdW5kYW1lbnRhbEJpZ0ludCgpOiBiaWdpbnQge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZ1bmRlbWVudGFsVmFsdWVfO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogICdXZWknIGlzIHRoZSAnRnVuZGFtZW50YWwnIGN1cnJlbmN5IGZvciBFVEhcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcHVibGljIGdldCBhc1dlaUJOKCk6IEJOIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hc0Z1bmRhbWVudGFsQk47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzV2VpSGV4KCk6IHN0cmluZyB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXNGdW5kYW1lbnRhbEhleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHB1YmxpYyBnZXQgYXNXZWlCaWdJbnQoKTogYmlnaW50IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hc0Z1bmRhbWVudGFsQmlnSW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IHN5bWJvbCgpOiBzdHJpbmcge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIkVUSFwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRGlzcGxheVN0cmluZygpOiBzdHJpbmcge1xuICAgICAgICAgICAgICAgIHJldHVybiBgJHt0aGlzLmFzRmxvYXR9ICR7dGhpcy5zeW1ib2x9YDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHVibGljIGNsb25lV2l0aE5ld1ZhbHVlKG5ld1Y6IG51bWJlciB8IHN0cmluZyB8IGJpZ2ludCk6IElUb2tlblZhbHVlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEVUSChuZXdWKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiAgRXVsaXRoLlRva2Vucy5WYWx1ZS5FUkMyMCBpcyBhbiBvYmplY3QgdGhhdCByZWZlcnMgdG8gYSB2YWx1ZSBvZiBhIHRva2VuIGZyb20gYW4gRVJDMjBcbiAgICAgICAgICogIGNvbnRyYWN0IChzZWUgaHR0cHM6Ly9laXBzLmV0aGVyZXVtLm9yZy9FSVBTL2VpcC0yMCkuXG4gICAgICAgICAqXG4gICAgICAgICAqICBUaGlzIGNvbnRhaW5zIGEgbnVtYmVyLCBhbmQgYSBsZXZlbCBvZiBwcmVjaXNpb24sIHVzZWQgd2hlbiBjb252ZXJ0aW5nIHRvIHRoZSBuYXRpdmUgZm9ybS5cbiAgICAgICAgICovXG4gICAgICAgIGV4cG9ydCBjbGFzcyBFUkMyMCBpbXBsZW1lbnRzIElUb2tlblZhbHVlIHtcbiAgICAgICAgICAgIHByaXZhdGUgZnVuZGVtZW50YWxWYWx1ZV86IGJpZ2ludDtcbiAgICAgICAgICAgIHByaXZhdGUgdG9XaXJlRmFjdG9yXzogbnVtYmVyO1xuICAgICAgICAgICAgcHJpdmF0ZSBzeW1ib2xfOiBzdHJpbmc7XG4gICAgICAgICAgICBwcml2YXRlIGRlY2ltYWxzXzogbnVtYmVyO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIGlmIHYgaXMgYSBudW1iZXIsIGl0cyBpbnRlcnByZXR0ZWQgaW4gRVJDMjAgdG9rZW4gdW5pdHNcbiAgICAgICAgICAgICAqIGlmIHYgaXMgYSBzdHJpbmcgfCBCaWdJbnQsIGl0cyBpbnRlcnByZXR0ZWQgYXMgYmVpbmcgaW4gZnVuZGFtZW50YWwgdW5pdHMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcih7XG4gICAgICAgICAgICAgICAgdixcbiAgICAgICAgICAgICAgICBkZWNpbWFscyxcbiAgICAgICAgICAgICAgICBjb250cmFjdCxcbiAgICAgICAgICAgICAgICBzeW1ib2xcbiAgICAgICAgICAgIH06IHtcbiAgICAgICAgICAgICAgICB2OiBudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQgfCBJVG9rZW5WYWx1ZTtcbiAgICAgICAgICAgICAgICBkZWNpbWFscz86IG51bWJlcjtcbiAgICAgICAgICAgICAgICBzeW1ib2w/OiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgY29udHJhY3Q/OiBFdWxpdGguQ29udHJhY3RzLkVSQzIwVG9rZW5Db250cmFjdDtcbiAgICAgICAgICAgIH0pIHtcbiAgICAgICAgICAgICAgICBpZiAoY29udHJhY3QgJiYgIWRlY2ltYWxzKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlY2ltYWxzID0gY29udHJhY3QuZGVjaW1hbHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghZGVjaW1hbHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgZWl0aGVyIGRlY2ltYWxzIG9yIGNvbnRyYWN0IGFzIGFyZ3VtZW50IHRvIEV1bGl0aC5Ub2tlbnMuVmFsdWUuRVJDMjBcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjb250cmFjdCAmJiAhc3ltYm9sKSB7XG4gICAgICAgICAgICAgICAgICAgIHN5bWJvbCA9IGNvbnRyYWN0LnN5bWJvbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFzeW1ib2wpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgZWl0aGVyIHN5bWJvbCBvciBjb250cmFjdCBhcyBhcmd1bWVudCB0byBFdWxpdGguVG9rZW5zLlZhbHVlLkVSQzIwXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnN5bWJvbF8gPSBzeW1ib2w7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWNpbWFsc18gPSBkZWNpbWFscztcbiAgICAgICAgICAgICAgICB0aGlzLnRvV2lyZUZhY3Rvcl8gPSBNYXRoLnBvdygxMCwgZGVjaW1hbHMpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdiA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZ1bmRlbWVudGFsVmFsdWVfID0gQmlnSW50KE1hdGgucm91bmQoKHYgYXMgbnVtYmVyKSAqIHRoaXMudG9XaXJlRmFjdG9yXykpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwiYmlnaW50XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9IHYgYXMgYmlnaW50O1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHYgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9IEJpZ0ludCh2IGFzIHN0cmluZyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXyA9ICh2IGFzIElUb2tlblZhbHVlKS5hc0Z1bmRhbWVudGFsQmlnSW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHVibGljIGdldCBhc0Zsb2F0KCk6IG51bWJlciB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gdGhpcyBpc24ndCBuZWNlc2FyaWx5IHRoZSBiZXN0IHdheSB0byBjb252ZXJ0IC0gcHJvYmFibHkgYmV0dGVyIHRvIHNoaWZ0IGRlY2ltYWxzIGZpcnN0IGFuZCB0aGVuIGNvbnZlcnQuXG4gICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlcih0aGlzLmZ1bmRlbWVudGFsVmFsdWVfKSAvIHRoaXMudG9XaXJlRmFjdG9yXztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHVibGljIGdldCBhc1dpcmUoKTogc3RyaW5nIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hc0Z1bmRhbWVudGFsSGV4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxIZXgoKTogc3RyaW5nIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCIweFwiICsgdGhpcy5mdW5kZW1lbnRhbFZhbHVlXy50b1N0cmluZygxNik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxCTigpOiBCTiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFdlYjMudXRpbHMudG9CTih0aGlzLmFzRnVuZGFtZW50YWxIZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHVibGljIGdldCBhc0Z1bmRhbWVudGFsQmlnSW50KCk6IGJpZ2ludCB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZnVuZGVtZW50YWxWYWx1ZV87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaWMgZ2V0IGFzRnVuZGFtZW50YWxGbG9hdCgpOiBudW1iZXIge1xuICAgICAgICAgICAgICAgIHJldHVybiBOdW1iZXIodGhpcy5mdW5kZW1lbnRhbFZhbHVlXyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHB1YmxpYyBnZXQgc3ltYm9sKCk6IHN0cmluZyB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3ltYm9sXztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHB1YmxpYyBnZXQgYXNEaXNwbGF5U3RyaW5nKCk6IHN0cmluZyB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3RoaXMuYXNGbG9hdH0gJHt0aGlzLnN5bWJvbH1gO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaWMgY2xvbmVXaXRoTmV3VmFsdWUobmV3VjogbnVtYmVyIHwgc3RyaW5nIHwgYmlnaW50KTogSVRva2VuVmFsdWUge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRVJDMjAoeyB2OiBuZXdWLCBzeW1ib2w6IHRoaXMuc3ltYm9sXywgZGVjaW1hbHM6IHRoaXMuZGVjaW1hbHNfIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqICBAdG9kbyBESVNDVVNTIElGIFRISVMgU0hPVUxEIEJFIERFUFJFQ0FURUQ/IElNSE8gTk8sIGJ1dCBLcmlzdGlhbiBhdCBvbmUgcG9pbnQgSSB0aGluayB0aG91Z2h0IGl0IHNob3VsZC4uLlxuICAgICAgICAgKi9cbiAgICAgICAgZXhwb3J0IGNsYXNzIFVTREMgZXh0ZW5kcyBFUkMyMCB7XG4gICAgICAgICAgICBwdWJsaWMgY29uc3RydWN0b3IodjogbnVtYmVyIHwgc3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIoeyB2OiB2LCBkZWNpbWFsczogNiB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiAgUmVhbGx5IEJFU1Qgd29yZCBoZXJlIHdvdWxkIGJlIEF0b21pYywgYnV0IHRvbyByaXNreSBvZiBjb25mdXNpb24gd2l0aCBhdG9taWMgaW4gXCJBdG9taWMgVHJhbnNhY3Rpb25zXCJcbiAgICAgICAgICpcbiAgICAgICAgICogIFRoaXMgaXMgdGhlIHNtYWxsZXN0IGluZGl2aXNpYmxlIHVuaXQgb2YgbW9uZXkgZm9yIGEgZ2l2ZW4gRVJDMjAgdG9rZW4uXG4gICAgICAgICAqL1xuICAgICAgICBleHBvcnQgY2xhc3MgRnVuZGFtZW50YWwgZXh0ZW5kcyBFUkMyMCB7XG4gICAgICAgICAgICBwdWJsaWMgY29uc3RydWN0b3IodjogbnVtYmVyIHwgc3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgc3VwZXIoeyB2OiB2LCBkZWNpbWFsczogMSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==