diff --git a/src/context-helpers/internal-context.ts b/src/context-helpers/internal-context.ts index e7b6e1d..36e37ad 100644 --- a/src/context-helpers/internal-context.ts +++ b/src/context-helpers/internal-context.ts @@ -2,6 +2,7 @@ import { Account, BaseContract, internal } from '@algorandfoundation/algorand-ty import { AccountData } from '../impl/account' import { ApplicationData } from '../impl/application' import { AssetData } from '../impl/asset' +import { VoterData } from '../impl/voter-params' import { TransactionGroup } from '../subcontexts/transaction-context' import { TestExecutionContext } from '../test-execution-context' @@ -69,6 +70,14 @@ class InternalContext { } return data } + + getVoterData(account: Account): VoterData { + const data = this.ledger.voterDataMap.get(account) + if (!data) { + throw internal.errors.internalError('Unknown voter, check correct testing context is active') + } + return data + } } export const lazyContext = new InternalContext() diff --git a/src/impl/account.ts b/src/impl/account.ts index 614d8a8..977e5b1 100644 --- a/src/impl/account.ts +++ b/src/impl/account.ts @@ -20,6 +20,9 @@ export class AssetHolding { export class AccountData { optedAssets = new Uint64Map() optedApplications = new Uint64Map() + incentiveEligible = false + lastProposed?: uint64 + lastHeartbeat?: uint64 account: Mutable> constructor() { diff --git a/src/impl/acct-params.ts b/src/impl/acct-params.ts index 9042446..685fac5 100644 --- a/src/impl/acct-params.ts +++ b/src/impl/acct-params.ts @@ -2,6 +2,7 @@ import { Account, Application, gtxn, internal, uint64 } from '@algorandfoundatio import { lazyContext } from '../context-helpers/internal-context' import { asMaybeUint64Cls } from '../util' import { getApp } from './app-params' +import { Global } from './global' export const getAccount = (acct: Account | internal.primitives.StubUint64Compat): Account => { const acctId = asMaybeUint64Cls(acct) @@ -84,14 +85,19 @@ export const AcctParams: internal.opTypes.AcctParamsType = { const acct = getAccount(a) return [acct.totalBoxBytes, acct.balance !== 0] }, - // TODO: implement v11 methods - acctIncentiveEligible: function (_a: Account | uint64): readonly [boolean, boolean] { - throw new Error('Function not implemented.') + acctIncentiveEligible: function (a: Account | internal.primitives.StubUint64Compat): readonly [boolean, boolean] { + const acct = getAccount(a) + const accountData = lazyContext.ledger.accountDataMap.get(acct) + return [accountData?.incentiveEligible ?? false, acct.balance !== 0] }, - acctLastProposed: function (_a: Account | uint64): readonly [uint64, boolean] { - throw new Error('Function not implemented.') + acctLastProposed: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + const accountData = lazyContext.ledger.accountDataMap.get(acct) + return [accountData?.lastProposed ?? Global.round, acct.balance !== 0] }, - acctLastHeartbeat: function (_a: Account | uint64): readonly [uint64, boolean] { - throw new Error('Function not implemented.') + acctLastHeartbeat: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const acct = getAccount(a) + const accountData = lazyContext.ledger.accountDataMap.get(acct) + return [accountData?.lastHeartbeat ?? Global.round, acct.balance !== 0] }, } diff --git a/src/impl/block.ts b/src/impl/block.ts index 79e9069..0a2f7a3 100644 --- a/src/impl/block.ts +++ b/src/impl/block.ts @@ -1,38 +1,62 @@ -import { Account, bytes, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, bytes, internal, Uint64, uint64 } from '@algorandfoundation/algorand-typescript' import { lazyContext } from '../context-helpers/internal-context' -import { asUint64 } from '../util' -import { itob } from './pure' +import { asUint64, getRandomBytes } from '../util' + +export class BlockData { + seed: bytes + timestamp: uint64 + proposer: Account + feesCollected: uint64 + bonus: uint64 + branch: bytes + feeSink: Account + protocol: bytes + txnCounter: uint64 + proposerPayout: uint64 + + constructor() { + this.seed = getRandomBytes(32).asAlgoTs() + this.timestamp = asUint64(Date.now()) + this.proposer = Account() + this.feesCollected = Uint64(0) + this.bonus = Uint64(0) + this.branch = getRandomBytes(32).asAlgoTs() + this.feeSink = Account() + this.protocol = getRandomBytes(32).asAlgoTs() + this.txnCounter = Uint64(0) + this.proposerPayout = Uint64(0) + } +} export const Block: internal.opTypes.BlockType = { blkSeed: function (a: internal.primitives.StubUint64Compat): bytes { - return itob(lazyContext.ledger.getBlockContent(a).seed) + return lazyContext.ledger.getBlockData(a).seed }, blkTimestamp: function (a: internal.primitives.StubUint64Compat): uint64 { - return asUint64(lazyContext.ledger.getBlockContent(a).timestamp) + return lazyContext.ledger.getBlockData(a).timestamp }, - // TODO: implement v11 methods - blkProposer: function (_a: uint64): Account { - throw new Error('Function not implemented.') + blkProposer: function (a: uint64): Account { + return lazyContext.ledger.getBlockData(a).proposer }, - blkFeesCollected: function (_a: uint64): uint64 { - throw new Error('Function not implemented.') + blkFeesCollected: function (a: uint64): uint64 { + return lazyContext.ledger.getBlockData(a).feesCollected }, - blkBonus: function (_a: uint64): uint64 { - throw new Error('Function not implemented.') + blkBonus: function (a: uint64): uint64 { + return lazyContext.ledger.getBlockData(a).bonus }, - blkBranch: function (_a: uint64): bytes { - throw new Error('Function not implemented.') + blkBranch: function (a: uint64): bytes { + return lazyContext.ledger.getBlockData(a).branch }, - blkFeeSink: function (_a: uint64): Account { - throw new Error('Function not implemented.') + blkFeeSink: function (a: uint64): Account { + return lazyContext.ledger.getBlockData(a).feeSink }, - blkProtocol: function (_a: uint64): bytes { - throw new Error('Function not implemented.') + blkProtocol: function (a: uint64): bytes { + return lazyContext.ledger.getBlockData(a).protocol }, - blkTxnCounter: function (_a: uint64): uint64 { - throw new Error('Function not implemented.') + blkTxnCounter: function (a: uint64): uint64 { + return lazyContext.ledger.getBlockData(a).txnCounter }, - blkProposerPayout: function (_a: uint64): uint64 { - throw new Error('Function not implemented.') + blkProposerPayout: function (a: uint64): uint64 { + return lazyContext.ledger.getBlockData(a).proposerPayout }, } diff --git a/src/impl/global.ts b/src/impl/global.ts index 393cc88..48600fd 100644 --- a/src/impl/global.ts +++ b/src/impl/global.ts @@ -25,6 +25,10 @@ export class GlobalData { assetOptInMinBalance: uint64 genesisHash: bytes opcodeBudget?: uint64 + payoutsEnabled: boolean + payoutsGoOnlineFee: uint64 + payoutsPercent: uint64 + payoutsMinBalance: uint64 constructor() { this.minTxnFee = Uint64(MIN_TXN_FEE) @@ -35,6 +39,10 @@ export class GlobalData { this.assetCreateMinBalance = Uint64(DEFAULT_ASSET_CREATE_MIN_BALANCE) this.assetOptInMinBalance = Uint64(DEFAULT_ASSET_OPT_IN_MIN_BALANCE) this.genesisHash = DEFAULT_GLOBAL_GENESIS_HASH + this.payoutsEnabled = false + this.payoutsGoOnlineFee = Uint64(0) + this.payoutsPercent = Uint64(0) + this.payoutsMinBalance = Uint64(0) } } const getGlobalData = (): GlobalData => { @@ -184,10 +192,44 @@ export const Global: internal.opTypes.GlobalType = { get genesisHash(): bytes { return getGlobalData().genesisHash }, - payoutsEnabled: false, - // TODO: implement v11 fields - payoutsGoOnlineFee: 0, - payoutsPercent: 0, - payoutsMinBalance: 0, - payoutsMaxBalance: 0, + + /** + * Whether block proposal payouts are enabled. + * Min AVM version: 11 + */ + get payoutsEnabled(): boolean { + return getGlobalData().payoutsEnabled + }, + + /** + * The fee required in a keyreg transaction to make an account incentive eligible. + * Min AVM version: 11 + */ + get payoutsGoOnlineFee(): uint64 { + return getGlobalData().payoutsGoOnlineFee + }, + + /** + * The percentage of transaction fees in a block that can be paid to the block proposer. + * Min AVM version: 11 + */ + get payoutsPercent(): uint64 { + return getGlobalData().payoutsPercent + }, + + /** + * The minimum algo balance an account must have in the agreement round to receive block payouts in the proposal round. + * Min AVM version: 11 + */ + get payoutsMinBalance(): uint64 { + return getGlobalData().payoutsMinBalance + }, + + /** + * The maximum algo balance an account can have in the agreement round to receive block payouts in the proposal round. + * Min AVM version: 11 + */ + get payoutsMaxBalance(): uint64 { + return getGlobalData().payoutsMinBalance + }, } diff --git a/src/impl/index.ts b/src/impl/index.ts index 42bd62b..a90600c 100644 --- a/src/impl/index.ts +++ b/src/impl/index.ts @@ -11,6 +11,8 @@ export { Global } from './global' export { GTxn } from './gtxn' export { GITxn, ITxn, ITxnCreate } from './itxn' export { arg } from './logicSigArg' +export { onlineStake } from './online-stake' export * from './pure' export { gloadBytes, gloadUint64, Scratch } from './scratch' export { gaid, Txn } from './txn' +export { VoterParams } from './voter-params' diff --git a/src/impl/online-stake.ts b/src/impl/online-stake.ts new file mode 100644 index 0000000..c9fa68b --- /dev/null +++ b/src/impl/online-stake.ts @@ -0,0 +1,6 @@ +import { internal } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' + +export const onlineStake: internal.opTypes.OnlineStakeType = () => { + return lazyContext.ledger.onlineStake +} diff --git a/src/impl/transactions.ts b/src/impl/transactions.ts index d2d7573..fdda1d4 100644 --- a/src/impl/transactions.ts +++ b/src/impl/transactions.ts @@ -117,6 +117,12 @@ export class KeyRegistrationTransaction extends TransactionBase implements gtxn. this.voteKeyDilution = fields.voteKeyDilution ?? Uint64(0) this.nonparticipation = fields.nonparticipation ?? false this.stateProofKey = fields.stateProofKey ?? Bytes() + const globalData = lazyContext.ledger.globalData + if (this.fee >= globalData.payoutsGoOnlineFee && globalData.payoutsEnabled) { + lazyContext.ledger.patchAccountData(this.sender, { + incentiveEligible: true, + }) + } } readonly voteKey: bytes diff --git a/src/impl/voter-params.ts b/src/impl/voter-params.ts new file mode 100644 index 0000000..b0722d2 --- /dev/null +++ b/src/impl/voter-params.ts @@ -0,0 +1,29 @@ +import { Account, internal, uint64 } from '@algorandfoundation/algorand-typescript' +import { lazyContext } from '../context-helpers/internal-context' +import { getAccount } from './acct-params' + +export class VoterData { + balance: uint64 + incentiveEligible: boolean + + constructor() { + this.balance = 0 + this.incentiveEligible = false + } +} + +const getVoterData = (a: Account | internal.primitives.StubUint64Compat): VoterData => { + const acct = getAccount(a) + return lazyContext.getVoterData(acct) +} + +export const VoterParams: internal.opTypes.VoterParamsType = { + voterBalance: function (a: Account | internal.primitives.StubUint64Compat): readonly [uint64, boolean] { + const data = getVoterData(a) + return [data.balance, data.balance !== 0] + }, + voterIncentiveEligible: function (a: Account | internal.primitives.StubUint64Compat): readonly [boolean, boolean] { + const data = getVoterData(a) + return [data.incentiveEligible, data.balance !== 0] + }, +} diff --git a/src/subcontexts/ledger-context.ts b/src/subcontexts/ledger-context.ts index 1a1b0e0..55b3d7e 100644 --- a/src/subcontexts/ledger-context.ts +++ b/src/subcontexts/ledger-context.ts @@ -4,15 +4,12 @@ import { MAX_UINT64 } from '../constants' import { AccountData, AssetHolding } from '../impl/account' import { ApplicationData } from '../impl/application' import { AssetData } from '../impl/asset' +import { BlockData } from '../impl/block' import { GlobalData } from '../impl/global' import { GlobalStateCls } from '../impl/state' +import { VoterData } from '../impl/voter-params' import { asBigInt, asMaybeBytesCls, asMaybeUint64Cls, asUint64, asUint64Cls, iterBigInt } from '../util' -interface BlockData { - seed: bigint - timestamp: bigint -} - export class LedgerContext { appIdIter = iterBigInt(1001n, MAX_UINT64) assetIdIter = iterBigInt(1001n, MAX_UINT64) @@ -20,8 +17,10 @@ export class LedgerContext { appIdContractMap = new Uint64Map() accountDataMap = new AccountMap() assetDataMap = new Uint64Map() + voterDataMap = new AccountMap() blocks = new Uint64Map() globalData = new GlobalData() + onlineStake = 0 /* @internal */ addAppIdContractMap(appId: internal.primitives.StubUint64Compat, contract: BaseContract): void { @@ -112,19 +111,36 @@ export class LedgerContext { } } - setBlock( - index: internal.primitives.StubUint64Compat, - seed: internal.primitives.StubUint64Compat, - timestamp: internal.primitives.StubUint64Compat, - ): void { - const i = asBigInt(index) - const s = asBigInt(seed) - const t = asBigInt(timestamp) + patchAccountData(account: Account, data: Partial) { + const accountData = this.accountDataMap.get(account) ?? new AccountData() + this.accountDataMap.set(account, { + ...accountData, + ...data, + account: { + ...accountData?.account, + ...data.account, + }, + }) + } - this.blocks.set(i, { seed: s, timestamp: t }) + patchVoterData(account: Account, data: Partial) { + const voterData = this.voterDataMap.get(account) ?? new VoterData() + this.voterDataMap.set(account, { + ...voterData, + ...data, + }) + } + + patchBlockData(index: internal.primitives.StubUint64Compat, data: Partial): void { + const i = asUint64(index) + const blockData = this.blocks.get(i) ?? new BlockData() + this.blocks.set(i, { + ...blockData, + ...data, + }) } - getBlockContent(index: internal.primitives.StubUint64Compat): BlockData { + getBlockData(index: internal.primitives.StubUint64Compat): BlockData { const i = asBigInt(index) if (this.blocks.has(i)) { return this.blocks.get(i)! diff --git a/src/value-generators/avm.ts b/src/value-generators/avm.ts index a3cca0f..a8ad43c 100644 --- a/src/value-generators/avm.ts +++ b/src/value-generators/avm.ts @@ -9,6 +9,7 @@ import { asBigInt, asUint64Cls, getRandomBigInt, getRandomBytes } from '../util' type AccountContextData = Partial & { address?: Account + incentiveEligible?: boolean optedAssetBalances?: Map optedApplications?: Application[] } @@ -56,7 +57,8 @@ export class AvmValueGenerator { } const data = new AccountData() - const { address, optedAssetBalances, optedApplications, ...accountData } = input ?? {} + const { address, optedAssetBalances, optedApplications, incentiveEligible, ...accountData } = input ?? {} + data.incentiveEligible = incentiveEligible ?? false data.account = { ...data.account, ...accountData, diff --git a/tests/artifacts/state-ops/contract.algo.ts b/tests/artifacts/state-ops/contract.algo.ts index ac97863..0e2e9eb 100644 --- a/tests/artifacts/state-ops/contract.algo.ts +++ b/tests/artifacts/state-ops/contract.algo.ts @@ -23,122 +23,6 @@ function get_1st_ref_index(): uint64 { return op.btoi(Txn.applicationArgs(1)) } -export class StateAcctParamsGetContract extends arc4.Contract { - @arc4.abimethod() - public verify_acct_balance(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctBalance(a) - const [value_index, funded_index] = op.AcctParams.acctBalance(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - assert(value === a.balance, 'expected Account balance to match') - assert(value === op.balance(a), 'expected op.balance to match') - assert(value === op.balance(get_1st_ref_index()), 'expected op.balance by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_min_balance(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctMinBalance(a) - const [value_index, funded_index] = op.AcctParams.acctMinBalance(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - assert(value === a.minBalance, 'expected Account min_balance to match') - assert(value === op.minBalance(a), 'expected op.min_balance to match') - assert(value === op.minBalance(get_1st_ref_index()), 'expected op.min_balance by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_auth_addr(a: Account): Address { - const [value, funded] = op.AcctParams.acctAuthAddr(a) - const [value_index, funded_index] = op.AcctParams.acctAuthAddr(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return new Address(value) - } - - @arc4.abimethod() - public verify_acct_total_num_uint(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalNumUint(a) - const [value_index, funded_index] = op.AcctParams.acctTotalNumUint(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_total_num_byte_slice(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalNumByteSlice(a) - const [value_index, funded_index] = op.AcctParams.acctTotalNumByteSlice(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_total_extra_app_pages(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalExtraAppPages(a) - const [value_index, funded_index] = op.AcctParams.acctTotalExtraAppPages(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_total_apps_created(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalAppsCreated(a) - const [value_index, funded_index] = op.AcctParams.acctTotalAppsCreated(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_total_apps_opted_in(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalAppsOptedIn(a) - const [value_index, funded_index] = op.AcctParams.acctTotalAppsOptedIn(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_total_assets_created(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalAssetsCreated(a) - const [value_index, funded_index] = op.AcctParams.acctTotalAssetsCreated(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_total_assets(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalAssets(a) - const [value_index, funded_index] = op.AcctParams.acctTotalAssets(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_total_boxes(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalBoxes(a) - const [value_index, funded_index] = op.AcctParams.acctTotalBoxes(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } - - @arc4.abimethod() - public verify_acct_total_box_bytes(a: Account): uint64 { - const [value, funded] = op.AcctParams.acctTotalBoxBytes(a) - const [value_index, funded_index] = op.AcctParams.acctTotalBoxBytes(get_1st_ref_index()) - assert(value === value_index, 'expected value by index to match') - assert(funded === funded_index, 'expected funded by index to match') - return value - } -} - export class StateAssetHoldingContract extends arc4.Contract { @arc4.abimethod() public verify_asset_holding_get(a: Account, b: Asset): uint64 { diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal index dceec00..d7a94a4 100644 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.approval.teal @@ -1,182 +1,185 @@ -#pragma version 10 +#pragma version 11 +#pragma typetrack false -tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.approvalProgram: +// @algorandfoundation/algorand-typescript/arc4/index.d.ts::Contract.approvalProgram() -> uint64: +main: intcblock 1 0 bytecblock 0x151f7c75 - callsub __puya_arc4_router__ - return - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.__puya_arc4_router__() -> uint64: -__puya_arc4_router__: - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { - proto 0 1 txn NumAppArgs - bz __puya_arc4_router___bare_routing@16 - pushbytess 0x5f5b43e4 0x73dc93c7 0x5626dfeb 0xdc8a25bf 0x198ebd8c 0x2301ab26 0x9f68fca6 0xa975c2d1 0xd1e04801 0xb6966be5 0x195d5418 0x6adae3f1 // method "verify_acct_balance(account)uint64", method "verify_acct_min_balance(account)uint64", method "verify_acct_auth_addr(account)address", method "verify_acct_total_num_uint(account)uint64", method "verify_acct_total_num_byte_slice(account)uint64", method "verify_acct_total_extra_app_pages(account)uint64", method "verify_acct_total_apps_created(account)uint64", method "verify_acct_total_apps_opted_in(account)uint64", method "verify_acct_total_assets_created(account)uint64", method "verify_acct_total_assets(account)uint64", method "verify_acct_total_boxes(account)uint64", method "verify_acct_total_box_bytes(account)uint64" + bz main_bare_routing@18 + pushbytess 0x5f5b43e4 0x73dc93c7 0x5626dfeb 0xdc8a25bf 0x198ebd8c 0x2301ab26 0x9f68fca6 0xa975c2d1 0xd1e04801 0xb6966be5 0x195d5418 0x6adae3f1 0xdf8cfee5 // method "verify_acct_balance(account)uint64", method "verify_acct_min_balance(account)uint64", method "verify_acct_auth_addr(account)address", method "verify_acct_total_num_uint(account)uint64", method "verify_acct_total_num_byte_slice(account)uint64", method "verify_acct_total_extra_app_pages(account)uint64", method "verify_acct_total_apps_created(account)uint64", method "verify_acct_total_apps_opted_in(account)uint64", method "verify_acct_total_assets_created(account)uint64", method "verify_acct_total_assets(account)uint64", method "verify_acct_total_boxes(account)uint64", method "verify_acct_total_box_bytes(account)uint64", method "verify_acct_incentive_eligible(account)bool" txna ApplicationArgs 0 - match __puya_arc4_router___verify_acct_balance_route@2 __puya_arc4_router___verify_acct_min_balance_route@3 __puya_arc4_router___verify_acct_auth_addr_route@4 __puya_arc4_router___verify_acct_total_num_uint_route@5 __puya_arc4_router___verify_acct_total_num_byte_slice_route@6 __puya_arc4_router___verify_acct_total_extra_app_pages_route@7 __puya_arc4_router___verify_acct_total_apps_created_route@8 __puya_arc4_router___verify_acct_total_apps_opted_in_route@9 __puya_arc4_router___verify_acct_total_assets_created_route@10 __puya_arc4_router___verify_acct_total_assets_route@11 __puya_arc4_router___verify_acct_total_boxes_route@12 __puya_arc4_router___verify_acct_total_box_bytes_route@13 + match main_verify_acct_balance_route@3 main_verify_acct_min_balance_route@4 main_verify_acct_auth_addr_route@5 main_verify_acct_total_num_uint_route@6 main_verify_acct_total_num_byte_slice_route@7 main_verify_acct_total_extra_app_pages_route@8 main_verify_acct_total_apps_created_route@9 main_verify_acct_total_apps_opted_in_route@10 main_verify_acct_total_assets_created_route@11 main_verify_acct_total_assets_route@12 main_verify_acct_total_boxes_route@13 main_verify_acct_total_box_bytes_route@14 main_verify_acct_incentive_eligible_route@15 + +main_after_if_else@22: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 + // export class StateAcctParamsGetContract extends arc4.Contract { intc_1 // 0 - retsub + return -__puya_arc4_router___verify_acct_balance_route@2: - // tests/artifacts/state-ops/contract.algo.ts:27 +main_verify_acct_incentive_eligible_route@15: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:123 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:27 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:123 // @arc4.abimethod() - callsub verify_acct_balance - itob + callsub verify_acct_incentive_eligible + pushbytes 0x00 + intc_1 // 0 + uncover 2 + setbit bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_min_balance_route@3: - // tests/artifacts/state-ops/contract.algo.ts:39 +main_verify_acct_total_box_bytes_route@14: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:114 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:39 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:114 // @arc4.abimethod() - callsub verify_acct_min_balance + callsub verify_acct_total_box_bytes itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_auth_addr_route@4: - // tests/artifacts/state-ops/contract.algo.ts:51 +main_verify_acct_total_boxes_route@13: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:105 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:51 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:105 // @arc4.abimethod() - callsub verify_acct_auth_addr + callsub verify_acct_total_boxes + itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_num_uint_route@5: - // tests/artifacts/state-ops/contract.algo.ts:60 +main_verify_acct_total_assets_route@12: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:96 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:60 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:96 // @arc4.abimethod() - callsub verify_acct_total_num_uint + callsub verify_acct_total_assets itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_num_byte_slice_route@6: - // tests/artifacts/state-ops/contract.algo.ts:69 +main_verify_acct_total_assets_created_route@11: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:87 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:69 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:87 // @arc4.abimethod() - callsub verify_acct_total_num_byte_slice + callsub verify_acct_total_assets_created itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_extra_app_pages_route@7: - // tests/artifacts/state-ops/contract.algo.ts:78 +main_verify_acct_total_apps_opted_in_route@10: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:78 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:78 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:78 // @arc4.abimethod() - callsub verify_acct_total_extra_app_pages + callsub verify_acct_total_apps_opted_in itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_apps_created_route@8: - // tests/artifacts/state-ops/contract.algo.ts:87 +main_verify_acct_total_apps_created_route@9: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:69 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:87 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:69 // @arc4.abimethod() callsub verify_acct_total_apps_created itob @@ -185,546 +188,633 @@ __puya_arc4_router___verify_acct_total_apps_created_route@8: concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_apps_opted_in_route@9: - // tests/artifacts/state-ops/contract.algo.ts:96 +main_verify_acct_total_extra_app_pages_route@8: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:60 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:96 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:60 // @arc4.abimethod() - callsub verify_acct_total_apps_opted_in + callsub verify_acct_total_extra_app_pages itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_assets_created_route@10: - // tests/artifacts/state-ops/contract.algo.ts:105 +main_verify_acct_total_num_byte_slice_route@7: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:51 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:105 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:51 // @arc4.abimethod() - callsub verify_acct_total_assets_created + callsub verify_acct_total_num_byte_slice itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_assets_route@11: - // tests/artifacts/state-ops/contract.algo.ts:114 +main_verify_acct_total_num_uint_route@6: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:42 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:114 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:42 // @arc4.abimethod() - callsub verify_acct_total_assets + callsub verify_acct_total_num_uint itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_boxes_route@12: - // tests/artifacts/state-ops/contract.algo.ts:123 +main_verify_acct_auth_addr_route@5: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:33 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:123 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:33 // @arc4.abimethod() - callsub verify_acct_total_boxes + callsub verify_acct_auth_addr + bytec_0 // 0x151f7c75 + swap + concat + log + intc_0 // 1 + return + +main_verify_acct_min_balance_route@4: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:21 + // @arc4.abimethod() + txn OnCompletion + ! + assert // OnCompletion is not NoOp + txn ApplicationID + assert // can only call when not creating + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 + // export class StateAcctParamsGetContract extends arc4.Contract { + txna ApplicationArgs 1 + btoi + txnas Accounts + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:21 + // @arc4.abimethod() + callsub verify_acct_min_balance itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___verify_acct_total_box_bytes_route@13: - // tests/artifacts/state-ops/contract.algo.ts:132 +main_verify_acct_balance_route@3: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:9 // @arc4.abimethod() txn OnCompletion ! assert // OnCompletion is not NoOp txn ApplicationID assert // can only call when not creating - // tests/artifacts/state-ops/contract.algo.ts:26 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txna ApplicationArgs 1 btoi txnas Accounts - // tests/artifacts/state-ops/contract.algo.ts:132 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:9 // @arc4.abimethod() - callsub verify_acct_total_box_bytes + callsub verify_acct_balance itob bytec_0 // 0x151f7c75 swap concat log intc_0 // 1 - retsub + return -__puya_arc4_router___bare_routing@16: - // tests/artifacts/state-ops/contract.algo.ts:26 +main_bare_routing@18: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:8 // export class StateAcctParamsGetContract extends arc4.Contract { txn OnCompletion - bnz __puya_arc4_router___after_if_else@20 + bnz main_after_if_else@22 txn ApplicationID ! assert // can only call when creating intc_0 // 1 - retsub - -__puya_arc4_router___after_if_else@20: - // tests/artifacts/state-ops/contract.algo.ts:26 - // export class StateAcctParamsGetContract extends arc4.Contract { - intc_1 // 0 - retsub + return -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_balance(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_balance(a: bytes) -> uint64: verify_acct_balance: - // tests/artifacts/state-ops/contract.algo.ts:27-28 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:9-10 // @arc4.abimethod() // public verify_acct_balance(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:29 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:11 // const [value, funded] = op.AcctParams.acctBalance(a) frame_dig -1 acct_params_get AcctBalance - // tests/artifacts/state-ops/contract.algo.ts:30 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:12 // const [value_index, funded_index] = op.AcctParams.acctBalance(get_1st_ref_index()) - callsub get_1st_ref_index + dup acct_params_get AcctBalance - // tests/artifacts/state-ops/contract.algo.ts:31 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:13 // assert(value === value_index, 'expected value by index to match') - dig 3 + dig 4 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:32 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:14 // assert(funded === funded_index, 'expected funded by index to match') + uncover 2 == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:33 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:15 // assert(value === a.balance, 'expected Account balance to match') frame_dig -1 acct_params_get AcctBalance assert // account funded - dig 1 + dig 2 == assert // expected Account balance to match - // tests/artifacts/state-ops/contract.algo.ts:34 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:16 // assert(value === op.balance(a), 'expected op.balance to match') frame_dig -1 balance - dig 1 + dig 2 == assert // expected op.balance to match - // tests/artifacts/state-ops/contract.algo.ts:35 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:17 // assert(value === op.balance(get_1st_ref_index()), 'expected op.balance by index to match') - callsub get_1st_ref_index balance dig 1 == assert // expected op.balance by index to match - // tests/artifacts/state-ops/contract.algo.ts:36 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:18 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::get_1st_ref_index() -> uint64: -get_1st_ref_index: - // tests/artifacts/state-ops/contract.algo.ts:22 - // function get_1st_ref_index(): uint64 { - proto 0 1 - // tests/artifacts/state-ops/contract.algo.ts:23 - // return op.btoi(Txn.applicationArgs(1)) - intc_0 // 1 - txnas ApplicationArgs - btoi - retsub - - -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_min_balance(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_min_balance(a: bytes) -> uint64: verify_acct_min_balance: - // tests/artifacts/state-ops/contract.algo.ts:39-40 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:21-22 // @arc4.abimethod() // public verify_acct_min_balance(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:41 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:23 // const [value, funded] = op.AcctParams.acctMinBalance(a) frame_dig -1 acct_params_get AcctMinBalance - // tests/artifacts/state-ops/contract.algo.ts:42 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:24 // const [value_index, funded_index] = op.AcctParams.acctMinBalance(get_1st_ref_index()) - callsub get_1st_ref_index + dup acct_params_get AcctMinBalance - // tests/artifacts/state-ops/contract.algo.ts:43 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:25 // assert(value === value_index, 'expected value by index to match') - dig 3 + dig 4 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:44 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:26 // assert(funded === funded_index, 'expected funded by index to match') + uncover 2 == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:45 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:27 // assert(value === a.minBalance, 'expected Account min_balance to match') frame_dig -1 acct_params_get AcctMinBalance assert // account funded - dig 1 + dig 2 == assert // expected Account min_balance to match - // tests/artifacts/state-ops/contract.algo.ts:46 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:28 // assert(value === op.minBalance(a), 'expected op.min_balance to match') frame_dig -1 min_balance - dig 1 + dig 2 == assert // expected op.min_balance to match - // tests/artifacts/state-ops/contract.algo.ts:47 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:29 // assert(value === op.minBalance(get_1st_ref_index()), 'expected op.min_balance by index to match') - callsub get_1st_ref_index min_balance dig 1 == assert // expected op.min_balance by index to match - // tests/artifacts/state-ops/contract.algo.ts:48 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:30 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_auth_addr(a: bytes) -> bytes: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_auth_addr(a: bytes) -> bytes: verify_acct_auth_addr: - // tests/artifacts/state-ops/contract.algo.ts:51-52 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:33-34 // @arc4.abimethod() // public verify_acct_auth_addr(a: Account): Address { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:53 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:35 // const [value, funded] = op.AcctParams.acctAuthAddr(a) frame_dig -1 acct_params_get AcctAuthAddr - // tests/artifacts/state-ops/contract.algo.ts:54 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:36 // const [value_index, funded_index] = op.AcctParams.acctAuthAddr(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctAuthAddr - // tests/artifacts/state-ops/contract.algo.ts:55 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:37 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:56 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:38 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:57 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:39 // return new Address(value) retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_num_uint(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_num_uint(a: bytes) -> uint64: verify_acct_total_num_uint: - // tests/artifacts/state-ops/contract.algo.ts:60-61 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:42-43 // @arc4.abimethod() // public verify_acct_total_num_uint(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:62 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:44 // const [value, funded] = op.AcctParams.acctTotalNumUint(a) frame_dig -1 acct_params_get AcctTotalNumUint - // tests/artifacts/state-ops/contract.algo.ts:63 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:45 // const [value_index, funded_index] = op.AcctParams.acctTotalNumUint(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalNumUint - // tests/artifacts/state-ops/contract.algo.ts:64 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:46 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:65 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:47 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:66 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:48 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_num_byte_slice(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_num_byte_slice(a: bytes) -> uint64: verify_acct_total_num_byte_slice: - // tests/artifacts/state-ops/contract.algo.ts:69-70 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:51-52 // @arc4.abimethod() // public verify_acct_total_num_byte_slice(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:71 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:53 // const [value, funded] = op.AcctParams.acctTotalNumByteSlice(a) frame_dig -1 acct_params_get AcctTotalNumByteSlice - // tests/artifacts/state-ops/contract.algo.ts:72 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:54 // const [value_index, funded_index] = op.AcctParams.acctTotalNumByteSlice(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalNumByteSlice - // tests/artifacts/state-ops/contract.algo.ts:73 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:55 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:74 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:56 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:75 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:57 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_extra_app_pages(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_extra_app_pages(a: bytes) -> uint64: verify_acct_total_extra_app_pages: - // tests/artifacts/state-ops/contract.algo.ts:78-79 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:60-61 // @arc4.abimethod() // public verify_acct_total_extra_app_pages(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:80 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:62 // const [value, funded] = op.AcctParams.acctTotalExtraAppPages(a) frame_dig -1 acct_params_get AcctTotalExtraAppPages - // tests/artifacts/state-ops/contract.algo.ts:81 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:63 // const [value_index, funded_index] = op.AcctParams.acctTotalExtraAppPages(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalExtraAppPages - // tests/artifacts/state-ops/contract.algo.ts:82 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:64 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:83 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:65 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:84 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:66 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_apps_created(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_apps_created(a: bytes) -> uint64: verify_acct_total_apps_created: - // tests/artifacts/state-ops/contract.algo.ts:87-88 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:69-70 // @arc4.abimethod() // public verify_acct_total_apps_created(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:89 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:71 // const [value, funded] = op.AcctParams.acctTotalAppsCreated(a) frame_dig -1 acct_params_get AcctTotalAppsCreated - // tests/artifacts/state-ops/contract.algo.ts:90 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:72 // const [value_index, funded_index] = op.AcctParams.acctTotalAppsCreated(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalAppsCreated - // tests/artifacts/state-ops/contract.algo.ts:91 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:73 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:92 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:74 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:93 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:75 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_apps_opted_in(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_apps_opted_in(a: bytes) -> uint64: verify_acct_total_apps_opted_in: - // tests/artifacts/state-ops/contract.algo.ts:96-97 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:78-79 // @arc4.abimethod() // public verify_acct_total_apps_opted_in(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:98 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:80 // const [value, funded] = op.AcctParams.acctTotalAppsOptedIn(a) frame_dig -1 acct_params_get AcctTotalAppsOptedIn - // tests/artifacts/state-ops/contract.algo.ts:99 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:81 // const [value_index, funded_index] = op.AcctParams.acctTotalAppsOptedIn(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalAppsOptedIn - // tests/artifacts/state-ops/contract.algo.ts:100 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:82 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:101 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:83 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:102 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:84 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_assets_created(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_assets_created(a: bytes) -> uint64: verify_acct_total_assets_created: - // tests/artifacts/state-ops/contract.algo.ts:105-106 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:87-88 // @arc4.abimethod() // public verify_acct_total_assets_created(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:107 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:89 // const [value, funded] = op.AcctParams.acctTotalAssetsCreated(a) frame_dig -1 acct_params_get AcctTotalAssetsCreated - // tests/artifacts/state-ops/contract.algo.ts:108 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:90 // const [value_index, funded_index] = op.AcctParams.acctTotalAssetsCreated(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalAssetsCreated - // tests/artifacts/state-ops/contract.algo.ts:109 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:91 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:110 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:92 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:111 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:93 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_assets(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_assets(a: bytes) -> uint64: verify_acct_total_assets: - // tests/artifacts/state-ops/contract.algo.ts:114-115 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:96-97 // @arc4.abimethod() // public verify_acct_total_assets(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:116 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:98 // const [value, funded] = op.AcctParams.acctTotalAssets(a) frame_dig -1 acct_params_get AcctTotalAssets - // tests/artifacts/state-ops/contract.algo.ts:117 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:99 // const [value_index, funded_index] = op.AcctParams.acctTotalAssets(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalAssets - // tests/artifacts/state-ops/contract.algo.ts:118 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:100 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:119 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:101 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:120 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:102 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_boxes(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_boxes(a: bytes) -> uint64: verify_acct_total_boxes: - // tests/artifacts/state-ops/contract.algo.ts:123-124 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:105-106 // @arc4.abimethod() // public verify_acct_total_boxes(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:125 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:107 // const [value, funded] = op.AcctParams.acctTotalBoxes(a) frame_dig -1 acct_params_get AcctTotalBoxes - // tests/artifacts/state-ops/contract.algo.ts:126 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:108 // const [value_index, funded_index] = op.AcctParams.acctTotalBoxes(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalBoxes - // tests/artifacts/state-ops/contract.algo.ts:127 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:109 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:128 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:110 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:129 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:111 // return value retsub -// tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_box_bytes(a: bytes) -> uint64: +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_total_box_bytes(a: bytes) -> uint64: verify_acct_total_box_bytes: - // tests/artifacts/state-ops/contract.algo.ts:132-133 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:114-115 // @arc4.abimethod() // public verify_acct_total_box_bytes(a: Account): uint64 { proto 1 1 - // tests/artifacts/state-ops/contract.algo.ts:134 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:116 // const [value, funded] = op.AcctParams.acctTotalBoxBytes(a) frame_dig -1 acct_params_get AcctTotalBoxBytes - // tests/artifacts/state-ops/contract.algo.ts:135 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:117 // const [value_index, funded_index] = op.AcctParams.acctTotalBoxBytes(get_1st_ref_index()) - callsub get_1st_ref_index acct_params_get AcctTotalBoxBytes - // tests/artifacts/state-ops/contract.algo.ts:136 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:118 + // assert(value === value_index, 'expected value by index to match') + dig 3 + uncover 2 + == + assert // expected value by index to match + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:119 + // assert(funded === funded_index, 'expected funded by index to match') + == + assert // expected funded by index to match + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:120 + // return value + retsub + + +// tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts::StateAcctParamsGetContract.verify_acct_incentive_eligible(a: bytes) -> uint64: +verify_acct_incentive_eligible: + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:123-124 + // @arc4.abimethod() + // public verify_acct_incentive_eligible(a: Account): boolean { + proto 1 1 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:125 + // const [value, funded] = op.AcctParams.acctIncentiveEligible(a) + frame_dig -1 + acct_params_get AcctIncentiveEligible + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:5 + // return op.btoi(Txn.applicationArgs(1)) + intc_0 // 1 + txnas ApplicationArgs + btoi + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:126 + // const [value_index, funded_index] = op.AcctParams.acctIncentiveEligible(get_1st_ref_index()) + acct_params_get AcctIncentiveEligible + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:127 // assert(value === value_index, 'expected value by index to match') dig 3 uncover 2 == assert // expected value by index to match - // tests/artifacts/state-ops/contract.algo.ts:137 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:128 // assert(funded === funded_index, 'expected funded by index to match') == assert // expected funded by index to match - // tests/artifacts/state-ops/contract.algo.ts:138 + // tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts:129 // return value retsub diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json index 4fbd3f2..42ebdd0 100644 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc32.json @@ -59,11 +59,16 @@ "call_config": { "no_op": "CALL" } + }, + "verify_acct_incentive_eligible(account)bool": { + "call_config": { + "no_op": "CALL" + } } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE2CiAgICBwdXNoYnl0ZXNzIDB4NWY1YjQzZTQgMHg3M2RjOTNjNyAweDU2MjZkZmViIDB4ZGM4YTI1YmYgMHgxOThlYmQ4YyAweDIzMDFhYjI2IDB4OWY2OGZjYTYgMHhhOTc1YzJkMSAweGQxZTA0ODAxIDB4YjY5NjZiZTUgMHgxOTVkNTQxOCAweDZhZGFlM2YxIC8vIG1ldGhvZCAidmVyaWZ5X2FjY3RfYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X2F1dGhfYWRkcihhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYWNjb3VudCl1aW50NjQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbl9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTMKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X2JhbGFuY2Vfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2JhbGFuY2UKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfYXV0aF9hZGRyX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50X3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXNfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9iYWxhbmNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3LTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEuYmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBBY2NvdW50IGJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGEpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhbGFuY2UKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLmJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGdldF8xc3RfcmVmX2luZGV4KCkpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBiYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzktNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MgogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEubWluQmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gnKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgQWNjb3VudCBtaW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoYSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIG1pbl9iYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0OAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2F1dGhfYWRkcihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9hY2N0X2F1dGhfYWRkcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1MS01MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogQWNjb3VudCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEF1dGhBZGRyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QXV0aEFkZHIoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAtNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MgogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxOdW1VaW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxOdW1VaW50CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtQnl0ZVNsaWNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OC03OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MAogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxFeHRyYUFwcFBhZ2VzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxFeHRyYUFwcFBhZ2VzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODEKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsRXh0cmFBcHBQYWdlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEV4dHJhQXBwUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MgogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3LTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzQ3JlYXRlZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYtOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk5CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc09wdGVkSW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDAKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUtMTA2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQXNzZXRzQ3JlYXRlZChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEwCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNC0xMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE2CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMy0xMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveGVzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94ZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMi0xMzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveEJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hCeXRlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxCb3hCeXRlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYXJjNC9pbmRleC5kLnRzOjpDb250cmFjdC5hcHByb3ZhbFByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdAMTgKICAgIHB1c2hieXRlc3MgMHg1ZjViNDNlNCAweDczZGM5M2M3IDB4NTYyNmRmZWIgMHhkYzhhMjViZiAweDE5OGViZDhjIDB4MjMwMWFiMjYgMHg5ZjY4ZmNhNiAweGE5NzVjMmQxIDB4ZDFlMDQ4MDEgMHhiNjk2NmJlNSAweDE5NWQ1NDE4IDB4NmFkYWUzZjEgMHhkZjhjZmVlNSAvLyBtZXRob2QgInZlcmlmeV9hY2N0X2JhbGFuY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X21pbl9iYWxhbmNlKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYWNjb3VudClhZGRyZXNzIiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludChhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcyhhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcyhhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF9pbmNlbnRpdmVfZWxpZ2libGUoYWNjb3VudClib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDMgbWFpbl92ZXJpZnlfYWNjdF9taW5fYmFsYW5jZV9yb3V0ZUA0IG1haW5fdmVyaWZ5X2FjY3RfYXV0aF9hZGRyX3JvdXRlQDUgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA2IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANyBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlc19yb3V0ZUA4IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDkgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luX3JvdXRlQDEwIG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTEgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfcm91dGVAMTIgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMyBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlc19yb3V0ZUAxNCBtYWluX3ZlcmlmeV9hY2N0X2luY2VudGl2ZV9lbGlnaWJsZV9yb3V0ZUAxNQoKbWFpbl9hZnRlcl9pZl9lbHNlQDIyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfaW5jZW50aXZlX2VsaWdpYmxlX3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2luY2VudGl2ZV9lbGlnaWJsZQogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2JveGVzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjgKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfYXV0aF9hZGRyCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjgKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X21pbl9iYWxhbmNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X2JhbGFuY2Vfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2JhbGFuY2UKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBtYWluX2FmdGVyX2lmX2Vsc2VAMjIKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9iYWxhbmNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5LTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTEKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEJhbGFuY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEyCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RCYWxhbmNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBkdXAKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMwogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyA0CiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjE1CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEuYmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBkaWcgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBBY2NvdW50IGJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTYKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gb3AuYmFsYW5jZShhKSwgJ2V4cGVjdGVkIG9wLmJhbGFuY2UgdG8gbWF0Y2gnKQogICAgZnJhbWVfZGlnIC0xCiAgICBiYWxhbmNlCiAgICBkaWcgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjE3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLmJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGJhbGFuY2UKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLmJhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjIxLTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X21pbl9iYWxhbmNlKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjIzCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RNaW5CYWxhbmNlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0TWluQmFsYW5jZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoyNAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgZHVwCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgNAogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoyNwogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBhLm1pbkJhbGFuY2UsICdleHBlY3RlZCBBY2NvdW50IG1pbl9iYWxhbmNlIHRvIG1hdGNoJykKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGRpZyAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MjgKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gb3AubWluQmFsYW5jZShhKSwgJ2V4cGVjdGVkIG9wLm1pbl9iYWxhbmNlIHRvIG1hdGNoJykKICAgIGZyYW1lX2RpZyAtMQogICAgbWluX2JhbGFuY2UKICAgIGRpZyAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLm1pbl9iYWxhbmNlIHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MzAKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYXV0aF9hZGRyKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2FjY3RfYXV0aF9hZGRyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czozMy0zNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogQWNjb3VudCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjM1CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RBdXRoQWRkcihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEF1dGhBZGRyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjM2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RBdXRoQWRkcihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RBdXRoQWRkcgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czozNwogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MzgKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czozOQogICAgLy8gcmV0dXJuIG5ldyBBZGRyZXNzKHZhbHVlKQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjQyLTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bVVpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NQogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NDUKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NDYKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NDgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUxLTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUzCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjU0CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1NQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NTYKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1NwogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2MC02MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NjIKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsRXh0cmFBcHBQYWdlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsRXh0cmFBcHBQYWdlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2MwogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxFeHRyYUFwcFBhZ2VzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsRXh0cmFBcHBQYWdlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2NAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2NgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NzEKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQXBwc0NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNDcmVhdGVkCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjcyCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjc0CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NzUKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo3OC03OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjgwCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxBcHBzT3B0ZWRJbihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNPcHRlZEluCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4MwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjg0CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4Ny04OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4OQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxBc3NldHNDcmVhdGVkKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHNDcmVhdGVkCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjkwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHNDcmVhdGVkCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5MgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjk2LTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5OAogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxBc3NldHMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5OQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxBc3NldHMoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTAwCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDEKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEwNS0xMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94ZXMoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExMAogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExMQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMTQtMTE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcyhhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMTYKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94Qnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxCb3hCeXRlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExOAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTE5CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTIwCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2luY2VudGl2ZV9lbGlnaWJsZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9pbmNlbnRpdmVfZWxpZ2libGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEyMy0xMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfaW5jZW50aXZlX2VsaWdpYmxlKGE6IEFjY291bnQpOiBib29sZWFuIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEluY2VudGl2ZUVsaWdpYmxlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0SW5jZW50aXZlRWxpZ2libGUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NQogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RJbmNlbnRpdmVFbGlnaWJsZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RJbmNlbnRpdmVFbGlnaWJsZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEyOAogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYmFzZS1jb250cmFjdC5kLnRzOjpCYXNlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" }, "state": { "global": { @@ -243,6 +248,19 @@ "returns": { "type": "uint64" } + }, + { + "name": "verify_acct_incentive_eligible", + "args": [ + { + "type": "account", + "name": "a" + } + ], + "readonly": false, + "returns": { + "type": "bool" + } } ], "networks": {} diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json index 0ad82cf..766444e 100644 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.arc56.json @@ -253,6 +253,27 @@ "readonly": false, "events": [], "recommendations": {} + }, + { + "name": "verify_acct_incentive_eligible", + "args": [ + { + "type": "account", + "name": "a" + } + ], + "returns": { + "type": "bool" + }, + "actions": { + "create": [], + "call": [ + "NoOp" + ] + }, + "readonly": false, + "events": [], + "recommendations": {} } ], "arcs": [ @@ -294,117 +315,121 @@ { "pc": [ 120, - 143, - 166, - 188, - 211, - 234, - 257, - 280, - 303, - 326, - 349, - 372 + 149, + 172, + 195, + 218, + 241, + 264, + 287, + 310, + 333, + 356, + 378, + 401 ], "errorMessage": "OnCompletion is not NoOp" }, { "pc": [ - 429, - 482 + 460, + 506 ], "errorMessage": "account funded" }, { "pc": [ - 400 + 429 ], "errorMessage": "can only call when creating" }, { "pc": [ 123, - 146, - 169, - 191, - 214, - 237, - 260, - 283, - 306, - 329, - 352, - 375 + 152, + 175, + 198, + 221, + 244, + 267, + 290, + 313, + 336, + 359, + 381, + 404 ], "errorMessage": "can only call when not creating" }, { "pc": [ - 433 + 464 ], "errorMessage": "expected Account balance to match" }, { "pc": [ - 486 + 510 ], "errorMessage": "expected Account min_balance to match" }, { "pc": [ - 424, - 477, - 522, - 543, - 564, - 585, - 606, - 627, - 648, - 669, - 690, - 711 + 455, + 501, + 544, + 566, + 588, + 610, + 632, + 654, + 676, + 698, + 720, + 742, + 764 ], "errorMessage": "expected funded by index to match" }, { "pc": [ - 448 + 476 ], "errorMessage": "expected op.balance by index to match" }, { "pc": [ - 440 + 471 ], "errorMessage": "expected op.balance to match" }, { "pc": [ - 501 + 522 ], "errorMessage": "expected op.min_balance by index to match" }, { "pc": [ - 493 + 517 ], "errorMessage": "expected op.min_balance to match" }, { "pc": [ - 422, - 475, - 520, - 541, - 562, - 583, - 604, - 625, - 646, - 667, - 688, - 709 + 451, + 497, + 542, + 564, + 586, + 608, + 630, + 652, + 674, + 696, + 718, + 740, + 762 ], "errorMessage": "expected value by index to match" } @@ -417,8 +442,20 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmFwcHJvdmFsUHJvZ3JhbToKICAgIGludGNibG9jayAxIDAKICAgIGJ5dGVjYmxvY2sgMHgxNTFmN2M3NQogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE2CiAgICBwdXNoYnl0ZXNzIDB4NWY1YjQzZTQgMHg3M2RjOTNjNyAweDU2MjZkZmViIDB4ZGM4YTI1YmYgMHgxOThlYmQ4YyAweDIzMDFhYjI2IDB4OWY2OGZjYTYgMHhhOTc1YzJkMSAweGQxZTA0ODAxIDB4YjY5NjZiZTUgMHgxOTVkNTQxOCAweDZhZGFlM2YxIC8vIG1ldGhvZCAidmVyaWZ5X2FjY3RfYmFsYW5jZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X2F1dGhfYWRkcihhY2NvdW50KWFkZHJlc3MiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4oYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYWNjb3VudCl1aW50NjQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2Vfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzX3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbl9yb3V0ZUA5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTMKICAgIGludGNfMSAvLyAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X2JhbGFuY2Vfcm91dGVAMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2JhbGFuY2UKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjM5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9taW5fYmFsYW5jZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfYXV0aF9hZGRyX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50X3JvdXRlQDU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXNfcm91dGVANzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW5fcm91dGVAOToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW4KICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEwNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTIzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTMyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyNgogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gY3JlYXRpbmcKICAgIGludGNfMCAvLyAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjA6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjYKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgaW50Y18xIC8vIDAKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9iYWxhbmNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjI3LTI4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyOQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozMAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzEKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzIKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjMzCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEuYmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBBY2NvdW50IGJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGEpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGJhbGFuY2UKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLmJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czozNQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBvcC5iYWxhbmNlKGdldF8xc3RfcmVmX2luZGV4KCkpLCAnZXhwZWN0ZWQgb3AuYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBiYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpnZXRfMXN0X3JlZl9pbmRleCgpIC0+IHVpbnQ2NDoKZ2V0XzFzdF9yZWZfaW5kZXg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MjIKICAgIC8vIGZ1bmN0aW9uIGdldF8xc3RfcmVmX2luZGV4KCk6IHVpbnQ2NCB7CiAgICBwcm90byAwIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoyMwogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MzktNDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0MgogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NDQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ1CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEubWluQmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gnKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IGZ1bmRlZAogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgQWNjb3VudCBtaW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoYSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIG1pbl9iYWxhbmNlCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5taW5fYmFsYW5jZSB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo0OAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2F1dGhfYWRkcihhOiBieXRlcykgLT4gYnl0ZXM6CnZlcmlmeV9hY2N0X2F1dGhfYWRkcjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1MS01MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogQWNjb3VudCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTMKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEF1dGhBZGRyKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0QXV0aEFkZHIoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGNhbGxzdWIgZ2V0XzFzdF9yZWZfaW5kZXgKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QXV0aEFkZHIKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo1NgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NTcKICAgIC8vIHJldHVybiBuZXcgQWRkcmVzcyh2YWx1ZSkKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjAtNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2MgogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxOdW1VaW50KGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxOdW1VaW50CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjMKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2NQogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NjYKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZShhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjcxCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzIKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtQnl0ZVNsaWNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6NzQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjc1CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlczoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo3OC03OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MAogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxFeHRyYUFwcFBhZ2VzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxFeHRyYUFwcFBhZ2VzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODEKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsRXh0cmFBcHBQYWdlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEV4dHJhQXBwUGFnZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MgogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo4MwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6ODQKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg3LTg4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZChhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjg5CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzQ3JlYXRlZAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjkwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czo5MgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTMKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfb3B0ZWRfaW46CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OTYtOTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk4CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjk5CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc09wdGVkSW4KICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDAKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTAxCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZDoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDUtMTA2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQXNzZXRzQ3JlYXRlZChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTEwCiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTEKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hc3NldHMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExNC0xMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE2CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXNzZXRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTE3CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0cyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjExOAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMTkKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMAogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2JveGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEyMy0xMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveGVzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBjYWxsc3ViIGdldF8xc3RfcmVmX2luZGV4CiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQm94ZXMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTI4CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvY29udHJhY3QuYWxnby50czoxMjkKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzMi0xMzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM0CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveEJ5dGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hCeXRlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxCb3hCeXRlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgY2FsbHN1YiBnZXRfMXN0X3JlZl9pbmRleAogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM2CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9jb250cmFjdC5hbGdvLnRzOjEzNwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6MTM4CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL2NvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LmNsZWFyU3RhdGVQcm9ncmFtOgogICAgcHVzaGludCAxIC8vIDEKICAgIHJldHVybgo=" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYXJjNC9pbmRleC5kLnRzOjpDb250cmFjdC5hcHByb3ZhbFByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBpbnRjYmxvY2sgMSAwCiAgICBieXRlY2Jsb2NrIDB4MTUxZjdjNzUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogbWFpbl9iYXJlX3JvdXRpbmdAMTgKICAgIHB1c2hieXRlc3MgMHg1ZjViNDNlNCAweDczZGM5M2M3IDB4NTYyNmRmZWIgMHhkYzhhMjViZiAweDE5OGViZDhjIDB4MjMwMWFiMjYgMHg5ZjY4ZmNhNiAweGE5NzVjMmQxIDB4ZDFlMDQ4MDEgMHhiNjk2NmJlNSAweDE5NWQ1NDE4IDB4NmFkYWUzZjEgMHhkZjhjZmVlNSAvLyBtZXRob2QgInZlcmlmeV9hY2N0X2JhbGFuY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X21pbl9iYWxhbmNlKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYWNjb3VudClhZGRyZXNzIiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludChhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYWNjb3VudCl1aW50NjQiLCBtZXRob2QgInZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcyhhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF90b3RhbF9ib3hlcyhhY2NvdW50KXVpbnQ2NCIsIG1ldGhvZCAidmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzKGFjY291bnQpdWludDY0IiwgbWV0aG9kICJ2ZXJpZnlfYWNjdF9pbmNlbnRpdmVfZWxpZ2libGUoYWNjb3VudClib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggbWFpbl92ZXJpZnlfYWNjdF9iYWxhbmNlX3JvdXRlQDMgbWFpbl92ZXJpZnlfYWNjdF9taW5fYmFsYW5jZV9yb3V0ZUA0IG1haW5fdmVyaWZ5X2FjY3RfYXV0aF9hZGRyX3JvdXRlQDUgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA2IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2Vfcm91dGVANyBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlc19yb3V0ZUA4IG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkX3JvdXRlQDkgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luX3JvdXRlQDEwIG1haW5fdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzX2NyZWF0ZWRfcm91dGVAMTEgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfcm91dGVAMTIgbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hlc19yb3V0ZUAxMyBtYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlc19yb3V0ZUAxNCBtYWluX3ZlcmlmeV9hY2N0X2luY2VudGl2ZV9lbGlnaWJsZV9yb3V0ZUAxNQoKbWFpbl9hZnRlcl9pZl9lbHNlQDIyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIGludGNfMSAvLyAwCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfaW5jZW50aXZlX2VsaWdpYmxlX3JvdXRlQDE1OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMjMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2luY2VudGl2ZV9lbGlnaWJsZQogICAgcHVzaGJ5dGVzIDB4MDAKICAgIGludGNfMSAvLyAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXNfcm91dGVAMTQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2JveGVzX3JvdXRlQDEzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2JveGVzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19yb3V0ZUAxMjoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OTYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfdG90YWxfYXNzZXRzCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkX3JvdXRlQDExOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjg3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luX3JvdXRlQDEwOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo3OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjc4CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X3RvdGFsX2FwcHNfY3JlYXRlZF9yb3V0ZUA5OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzX3JvdXRlQDg6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjgKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X3RvdGFsX2V4dHJhX2FwcF9wYWdlcwogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZV9yb3V0ZUA3OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fYnl0ZV9zbGljZQogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludF9yb3V0ZUA2OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo0MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiB2ZXJpZnlfYWNjdF90b3RhbF9udW1fdWludAogICAgaXRvYgogICAgYnl0ZWNfMCAvLyAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50Y18wIC8vIDEKICAgIHJldHVybgoKbWFpbl92ZXJpZnlfYWNjdF9hdXRoX2FkZHJfcm91dGVANToKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIG5vdCBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGNhbiBvbmx5IGNhbGwgd2hlbiBub3QgY3JlYXRpbmcKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OAogICAgLy8gZXhwb3J0IGNsYXNzIFN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0IGV4dGVuZHMgYXJjNC5Db250cmFjdCB7CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgdmVyaWZ5X2FjY3RfYXV0aF9hZGRyCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X21pbl9iYWxhbmNlX3JvdXRlQDQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBub3QgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBjYW4gb25seSBjYWxsIHdoZW4gbm90IGNyZWF0aW5nCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjgKICAgIC8vIGV4cG9ydCBjbGFzcyBTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdCBleHRlbmRzIGFyYzQuQ29udHJhY3QgewogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQWNjb3VudHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X21pbl9iYWxhbmNlCiAgICBpdG9iCiAgICBieXRlY18wIC8vIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgptYWluX3ZlcmlmeV9hY2N0X2JhbGFuY2Vfcm91dGVAMzoKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgbm90IE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIG5vdCBjcmVhdGluZwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHZlcmlmeV9hY2N0X2JhbGFuY2UKICAgIGl0b2IKICAgIGJ5dGVjXzAgLy8gMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludGNfMCAvLyAxCiAgICByZXR1cm4KCm1haW5fYmFyZV9yb3V0aW5nQDE4OgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4CiAgICAvLyBleHBvcnQgY2xhc3MgU3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QgZXh0ZW5kcyBhcmM0LkNvbnRyYWN0IHsKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBtYWluX2FmdGVyX2lmX2Vsc2VAMjIKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gY2FuIG9ubHkgY2FsbCB3aGVuIGNyZWF0aW5nCiAgICBpbnRjXzAgLy8gMQogICAgcmV0dXJuCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYmFsYW5jZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9iYWxhbmNlOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5LTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X2JhbGFuY2UoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTEKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEJhbGFuY2UoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RCYWxhbmNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEyCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RCYWxhbmNlKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBkdXAKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMwogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyA0CiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTQKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjE1CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IGEuYmFsYW5jZSwgJ2V4cGVjdGVkIEFjY291bnQgYmFsYW5jZSB0byBtYXRjaCcpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgZnVuZGVkCiAgICBkaWcgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBBY2NvdW50IGJhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTYKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gb3AuYmFsYW5jZShhKSwgJ2V4cGVjdGVkIG9wLmJhbGFuY2UgdG8gbWF0Y2gnKQogICAgZnJhbWVfZGlnIC0xCiAgICBiYWxhbmNlCiAgICBkaWcgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBvcC5iYWxhbmNlIHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjE3CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLmJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5iYWxhbmNlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGJhbGFuY2UKICAgIGRpZyAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLmJhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfbWluX2JhbGFuY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfbWluX2JhbGFuY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjIxLTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X21pbl9iYWxhbmNlKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjIzCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RNaW5CYWxhbmNlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0TWluQmFsYW5jZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoyNAogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0TWluQmFsYW5jZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgZHVwCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MjUKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgNAogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjI2CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoyNwogICAgLy8gYXNzZXJ0KHZhbHVlID09PSBhLm1pbkJhbGFuY2UsICdleHBlY3RlZCBBY2NvdW50IG1pbl9iYWxhbmNlIHRvIG1hdGNoJykKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RNaW5CYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBmdW5kZWQKICAgIGRpZyAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIEFjY291bnQgbWluX2JhbGFuY2UgdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MjgKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gb3AubWluQmFsYW5jZShhKSwgJ2V4cGVjdGVkIG9wLm1pbl9iYWxhbmNlIHRvIG1hdGNoJykKICAgIGZyYW1lX2RpZyAtMQogICAgbWluX2JhbGFuY2UKICAgIGRpZyAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIG9wLm1pbl9iYWxhbmNlIHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjI5CiAgICAvLyBhc3NlcnQodmFsdWUgPT09IG9wLm1pbkJhbGFuY2UoZ2V0XzFzdF9yZWZfaW5kZXgoKSksICdleHBlY3RlZCBvcC5taW5fYmFsYW5jZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBtaW5fYmFsYW5jZQogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgb3AubWluX2JhbGFuY2UgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MzAKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfYXV0aF9hZGRyKGE6IGJ5dGVzKSAtPiBieXRlczoKdmVyaWZ5X2FjY3RfYXV0aF9hZGRyOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czozMy0zNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF9hdXRoX2FkZHIoYTogQWNjb3VudCk6IEFkZHJlc3MgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjM1CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RBdXRoQWRkcihhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdEF1dGhBZGRyCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjM2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RBdXRoQWRkcihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RBdXRoQWRkcgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czozNwogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MzgKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czozOQogICAgLy8gcmV0dXJuIG5ldyBBZGRyZXNzKHZhbHVlKQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX3VpbnQ6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjQyLTQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX251bV91aW50KGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjQ0CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bVVpbnQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NQogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NDUKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsTnVtVWludChnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bVVpbnQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NDYKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjQ3CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NDgKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2UoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfbnVtX2J5dGVfc2xpY2U6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUxLTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX251bV9ieXRlX3NsaWNlKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUzCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsTnVtQnl0ZVNsaWNlCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjU0CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbE51bUJ5dGVTbGljZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbE51bUJ5dGVTbGljZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1NQogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NTYKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1NwogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfZXh0cmFfYXBwX3BhZ2VzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2MC02MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9leHRyYV9hcHBfcGFnZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NjIKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsRXh0cmFBcHBQYWdlcyhhKQogICAgZnJhbWVfZGlnIC0xCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsRXh0cmFBcHBQYWdlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2MwogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxFeHRyYUFwcFBhZ2VzKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsRXh0cmFBcHBQYWdlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2NAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NjUKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2NgogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYXBwc19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo2OS03MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX2NyZWF0ZWQoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NzEKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQXBwc0NyZWF0ZWQoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNDcmVhdGVkCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjcyCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNDcmVhdGVkKGdldF8xc3RfcmVmX2luZGV4KCkpCiAgICBhY2N0X3BhcmFtc19nZXQgQWNjdFRvdGFsQXBwc0NyZWF0ZWQKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NzMKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjc0CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NzUKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYXBwc19vcHRlZF9pbihhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo3OC03OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9hcHBzX29wdGVkX2luKGE6IEFjY291bnQpOiB1aW50NjQgewogICAgcHJvdG8gMSAxCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjgwCiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFwcHNPcHRlZEluKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBcHBzT3B0ZWRJbgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4MQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxBcHBzT3B0ZWRJbihnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFwcHNPcHRlZEluCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjgyCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4MwogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjg0CiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkKGE6IGJ5dGVzKSAtPiB1aW50NjQ6CnZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0c19jcmVhdGVkOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4Ny04OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIHB1YmxpYyB2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHNfY3JlYXRlZChhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo4OQogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxBc3NldHNDcmVhdGVkKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHNDcmVhdGVkCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjkwCiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEFzc2V0c0NyZWF0ZWQoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHNDcmVhdGVkCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjkxCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5MgogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjkzCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF90b3RhbF9hc3NldHM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjk2LTk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2Fzc2V0cyhhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5OAogICAgLy8gY29uc3QgW3ZhbHVlLCBmdW5kZWRdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxBc3NldHMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEFzc2V0cwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo5OQogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxBc3NldHMoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxBc3NldHMKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTAwCiAgICAvLyBhc3NlcnQodmFsdWUgPT09IHZhbHVlX2luZGV4LCAnZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDEKICAgIC8vIGFzc2VydChmdW5kZWQgPT09IGZ1bmRlZF9pbmRleCwgJ2V4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaCcpCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGZ1bmRlZCBieSBpbmRleCB0byBtYXRjaAogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDIKICAgIC8vIHJldHVybiB2YWx1ZQogICAgcmV0c3ViCgoKLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo6U3RhdGVBY2N0UGFyYW1zR2V0Q29udHJhY3QudmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXM6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEwNS0xMDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfdG90YWxfYm94ZXMoYTogQWNjb3VudCk6IHVpbnQ2NCB7CiAgICBwcm90byAxIDEKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTA3CiAgICAvLyBjb25zdCBbdmFsdWUsIGZ1bmRlZF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RUb3RhbEJveGVzKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czo1CiAgICAvLyByZXR1cm4gb3AuYnRvaShUeG4uYXBwbGljYXRpb25BcmdzKDEpKQogICAgaW50Y18wIC8vIDEKICAgIHR4bmFzIEFwcGxpY2F0aW9uQXJncwogICAgYnRvaQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDgKICAgIC8vIGNvbnN0IFt2YWx1ZV9pbmRleCwgZnVuZGVkX2luZGV4XSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94ZXMoZ2V0XzFzdF9yZWZfaW5kZXgoKSkKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0VG90YWxCb3hlcwogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMDkKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExMAogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExMQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIKCgovLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjpTdGF0ZUFjY3RQYXJhbXNHZXRDb250cmFjdC52ZXJpZnlfYWNjdF90b3RhbF9ib3hfYnl0ZXMoYTogYnl0ZXMpIC0+IHVpbnQ2NDoKdmVyaWZ5X2FjY3RfdG90YWxfYm94X2J5dGVzOgogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMTQtMTE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gcHVibGljIHZlcmlmeV9hY2N0X3RvdGFsX2JveF9ieXRlcyhhOiBBY2NvdW50KTogdWludDY0IHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMTYKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdFRvdGFsQm94Qnl0ZXMoYSkKICAgIGZyYW1lX2RpZyAtMQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjUKICAgIC8vIHJldHVybiBvcC5idG9pKFR4bi5hcHBsaWNhdGlvbkFyZ3MoMSkpCiAgICBpbnRjXzAgLy8gMQogICAgdHhuYXMgQXBwbGljYXRpb25BcmdzCiAgICBidG9pCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExNwogICAgLy8gY29uc3QgW3ZhbHVlX2luZGV4LCBmdW5kZWRfaW5kZXhdID0gb3AuQWNjdFBhcmFtcy5hY2N0VG90YWxCb3hCeXRlcyhnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RUb3RhbEJveEJ5dGVzCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjExOAogICAgLy8gYXNzZXJ0KHZhbHVlID09PSB2YWx1ZV9pbmRleCwgJ2V4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgdmFsdWUgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTE5CiAgICAvLyBhc3NlcnQoZnVuZGVkID09PSBmdW5kZWRfaW5kZXgsICdleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gnKQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBmdW5kZWQgYnkgaW5kZXggdG8gbWF0Y2gKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTIwCiAgICAvLyByZXR1cm4gdmFsdWUKICAgIHJldHN1YgoKCi8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6OlN0YXRlQWNjdFBhcmFtc0dldENvbnRyYWN0LnZlcmlmeV9hY2N0X2luY2VudGl2ZV9lbGlnaWJsZShhOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnlfYWNjdF9pbmNlbnRpdmVfZWxpZ2libGU6CiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEyMy0xMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBwdWJsaWMgdmVyaWZ5X2FjY3RfaW5jZW50aXZlX2VsaWdpYmxlKGE6IEFjY291bnQpOiBib29sZWFuIHsKICAgIHByb3RvIDEgMQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMjUKICAgIC8vIGNvbnN0IFt2YWx1ZSwgZnVuZGVkXSA9IG9wLkFjY3RQYXJhbXMuYWNjdEluY2VudGl2ZUVsaWdpYmxlKGEpCiAgICBmcmFtZV9kaWcgLTEKICAgIGFjY3RfcGFyYW1zX2dldCBBY2N0SW5jZW50aXZlRWxpZ2libGUKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6NQogICAgLy8gcmV0dXJuIG9wLmJ0b2koVHhuLmFwcGxpY2F0aW9uQXJncygxKSkKICAgIGludGNfMCAvLyAxCiAgICB0eG5hcyBBcHBsaWNhdGlvbkFyZ3MKICAgIGJ0b2kKICAgIC8vIHRlc3RzL2FydGlmYWN0cy9zdGF0ZS1vcHMvc3RhdGUtYWNjdC1wYXJhbXMtZ2V0LWNvbnRyYWN0LmFsZ28udHM6MTI2CiAgICAvLyBjb25zdCBbdmFsdWVfaW5kZXgsIGZ1bmRlZF9pbmRleF0gPSBvcC5BY2N0UGFyYW1zLmFjY3RJbmNlbnRpdmVFbGlnaWJsZShnZXRfMXN0X3JlZl9pbmRleCgpKQogICAgYWNjdF9wYXJhbXNfZ2V0IEFjY3RJbmNlbnRpdmVFbGlnaWJsZQogICAgLy8gdGVzdHMvYXJ0aWZhY3RzL3N0YXRlLW9wcy9zdGF0ZS1hY2N0LXBhcmFtcy1nZXQtY29udHJhY3QuYWxnby50czoxMjcKICAgIC8vIGFzc2VydCh2YWx1ZSA9PT0gdmFsdWVfaW5kZXgsICdleHBlY3RlZCB2YWx1ZSBieSBpbmRleCB0byBtYXRjaCcpCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIHZhbHVlIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEyOAogICAgLy8gYXNzZXJ0KGZ1bmRlZCA9PT0gZnVuZGVkX2luZGV4LCAnZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoJykKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgZnVuZGVkIGJ5IGluZGV4IHRvIG1hdGNoCiAgICAvLyB0ZXN0cy9hcnRpZmFjdHMvc3RhdGUtb3BzL3N0YXRlLWFjY3QtcGFyYW1zLWdldC1jb250cmFjdC5hbGdvLnRzOjEyOQogICAgLy8gcmV0dXJuIHZhbHVlCiAgICByZXRzdWIK", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDExCiNwcmFnbWEgdHlwZXRyYWNrIGZhbHNlCgovLyBAYWxnb3JhbmRmb3VuZGF0aW9uL2FsZ29yYW5kLXR5cGVzY3JpcHQvYmFzZS1jb250cmFjdC5kLnRzOjpCYXNlQ29udHJhY3QuY2xlYXJTdGF0ZVByb2dyYW0oKSAtPiB1aW50NjQ6Cm1haW46CiAgICBwdXNoaW50IDEgLy8gMQogICAgcmV0dXJuCg==" + }, + "byteCode": { + "approval": "CyACAQAmAQQVH3x1MRtBAZSCDQRfW0PkBHPck8cEVibf6wTciiW/BBmOvYwEIwGrJgSfaPymBKl1wtEE0eBIAQS2lmvlBBldVBgEatrj8QTfjP7lNhoAjg0BGwEEAO4A1wDAAKkAkgB7AGQATQA2AB8AAiNDMRkURDEYRDYaARfAHIgCY4ABACNPAlQoTFCwIkMxGRREMRhENhoBF8AciAIwFihMULAiQzEZFEQxGEQ2GgEXwByIAgMWKExQsCJDMRkURDEYRDYaARfAHIgB1hYoTFCwIkMxGRREMRhENhoBF8AciAGpFihMULAiQzEZFEQxGEQ2GgEXwByIAXwWKExQsCJDMRkURDEYRDYaARfAHIgBTxYoTFCwIkMxGRREMRhENhoBF8AciAEiFihMULAiQzEZFEQxGEQ2GgEXwByIAPUWKExQsCJDMRkURDEYRDYaARfAHIgAyBYoTFCwIkMxGRREMRhENhoBF8AciACbKExQsCJDMRkURDEYRDYaARfAHIgAVxYoTFCwIkMxGRREMRhENhoBF8AciAASFihMULAiQzEZQP7JMRgURCJDigEBi/9zACLAGhdJcwBLBE8CEkRPAhJEi/9zAERLAhJEi/9gSwISRGBLARJEiYoBAYv/cwEiwBoXSXMBSwRPAhJETwISRIv/cwFESwISRIv/eEsCEkR4SwESRImKAQGL/3MCIsAaF3MCSwNPAhJEEkSJigEBi/9zAyLAGhdzA0sDTwISRBJEiYoBAYv/cwQiwBoXcwRLA08CEkQSRImKAQGL/3MFIsAaF3MFSwNPAhJEEkSJigEBi/9zBiLAGhdzBksDTwISRBJEiYoBAYv/cwciwBoXcwdLA08CEkQSRImKAQGL/3MIIsAaF3MISwNPAhJEEkSJigEBi/9zCSLAGhdzCUsDTwISRBJEiYoBAYv/cwoiwBoXcwpLA08CEkQSRImKAQGL/3MLIsAaF3MLSwNPAhJEEkSJigEBi/9zDCLAGhdzDEsDTwISRBJEiQ==", + "clear": "C4EBQw==" + }, + "compilerInfo": { + "compiler": "puya", + "compilerVersion": { + "major": 4, + "minor": 1, + "patch": 1 + } }, "events": [], "templateVariables": {} diff --git a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal index c48a376..42f81b0 100644 --- a/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal +++ b/tests/artifacts/state-ops/data/StateAcctParamsGetContract.clear.teal @@ -1,5 +1,7 @@ -#pragma version 10 +#pragma version 11 +#pragma typetrack false -tests/artifacts/state-ops/contract.algo.ts::StateAcctParamsGetContract.clearStateProgram: +// @algorandfoundation/algorand-typescript/base-contract.d.ts::BaseContract.clearStateProgram() -> uint64: +main: pushint 1 // 1 return diff --git a/tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts b/tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts new file mode 100644 index 0000000..fd7514c --- /dev/null +++ b/tests/artifacts/state-ops/state-acct-params-get-contract.algo.ts @@ -0,0 +1,131 @@ +import { Account, arc4, assert, op, Txn, uint64 } from '@algorandfoundation/algorand-typescript' +import { Address } from '@algorandfoundation/algorand-typescript/arc4' + +function get_1st_ref_index(): uint64 { + return op.btoi(Txn.applicationArgs(1)) +} + +export class StateAcctParamsGetContract extends arc4.Contract { + @arc4.abimethod() + public verify_acct_balance(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctBalance(a) + const [value_index, funded_index] = op.AcctParams.acctBalance(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + assert(value === a.balance, 'expected Account balance to match') + assert(value === op.balance(a), 'expected op.balance to match') + assert(value === op.balance(get_1st_ref_index()), 'expected op.balance by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_min_balance(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctMinBalance(a) + const [value_index, funded_index] = op.AcctParams.acctMinBalance(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + assert(value === a.minBalance, 'expected Account min_balance to match') + assert(value === op.minBalance(a), 'expected op.min_balance to match') + assert(value === op.minBalance(get_1st_ref_index()), 'expected op.min_balance by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_auth_addr(a: Account): Address { + const [value, funded] = op.AcctParams.acctAuthAddr(a) + const [value_index, funded_index] = op.AcctParams.acctAuthAddr(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return new Address(value) + } + + @arc4.abimethod() + public verify_acct_total_num_uint(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalNumUint(a) + const [value_index, funded_index] = op.AcctParams.acctTotalNumUint(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_num_byte_slice(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalNumByteSlice(a) + const [value_index, funded_index] = op.AcctParams.acctTotalNumByteSlice(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_extra_app_pages(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalExtraAppPages(a) + const [value_index, funded_index] = op.AcctParams.acctTotalExtraAppPages(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_apps_created(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalAppsCreated(a) + const [value_index, funded_index] = op.AcctParams.acctTotalAppsCreated(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_apps_opted_in(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalAppsOptedIn(a) + const [value_index, funded_index] = op.AcctParams.acctTotalAppsOptedIn(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_assets_created(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalAssetsCreated(a) + const [value_index, funded_index] = op.AcctParams.acctTotalAssetsCreated(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_assets(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalAssets(a) + const [value_index, funded_index] = op.AcctParams.acctTotalAssets(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_boxes(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalBoxes(a) + const [value_index, funded_index] = op.AcctParams.acctTotalBoxes(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_total_box_bytes(a: Account): uint64 { + const [value, funded] = op.AcctParams.acctTotalBoxBytes(a) + const [value_index, funded_index] = op.AcctParams.acctTotalBoxBytes(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } + + @arc4.abimethod() + public verify_acct_incentive_eligible(a: Account): boolean { + const [value, funded] = op.AcctParams.acctIncentiveEligible(a) + const [value_index, funded_index] = op.AcctParams.acctIncentiveEligible(get_1st_ref_index()) + assert(value === value_index, 'expected value by index to match') + assert(funded === funded_index, 'expected funded by index to match') + return value + } +} diff --git a/tests/avm-invoker.ts b/tests/avm-invoker.ts index 844ff7c..cc8de30 100644 --- a/tests/avm-invoker.ts +++ b/tests/avm-invoker.ts @@ -14,15 +14,33 @@ export type ABIValue = boolean | number | bigint | string | Uint8Array | ABIValu algokit.Config.configure({ logger: nullLogger }) -const algorandClient = Lazy(() => algokit.AlgorandClient.defaultLocalNet()) +const algorandClient = Lazy(() => { + const client = algokit.AlgorandClient.defaultLocalNet() + client.setDefaultValidityWindow(1000) + return client +}) export const INITIAL_BALANCE_MICRO_ALGOS = Number(20e6) +export const getAlgorandAppClientV11 = async (appSpec: AppSpec) => { + if ((await getAlgodMajorVersion()) < 4) { + return undefined + } + const [appClient, _] = await getAlgorandAppClientWithApp(appSpec) + return appClient +} + export const getAlgorandAppClient = async (appSpec: AppSpec) => { const [appClient, _] = await getAlgorandAppClientWithApp(appSpec) return appClient } +export const getAlgodMajorVersion = async () => { + const algorand = algorandClient() + const version = await algorand.client.algod.versionsCheck().do() + return version.build.major +} + export const getAlgorandAppClientWithApp = async (appSpec: AppSpec) => { const algorand = algorandClient() const defaultSigner = await algorand.account.kmd.getLocalNetDispenserAccount() diff --git a/tests/state-op-codes.spec.ts b/tests/state-op-codes.spec.ts index 84326de..b8a8bd8 100644 --- a/tests/state-op-codes.spec.ts +++ b/tests/state-op-codes.spec.ts @@ -1,23 +1,23 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' import { AppClient } from '@algorandfoundation/algokit-utils/types/app-client' import { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' -import { Account, arc4, bytes, Bytes, internal, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, arc4, bytes, Bytes, Global, internal, op, TransactionType, uint64, Uint64 } from '@algorandfoundation/algorand-typescript' import { DynamicBytes, UintN64 } from '@algorandfoundation/algorand-typescript/arc4' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../src' import { ABI_RETURN_VALUE_LOG_PREFIX, MIN_TXN_FEE, OnApplicationComplete, ZERO_ADDRESS } from '../src/constants' +import { lazyContext } from '../src/context-helpers/internal-context' import { testInvariant } from '../src/errors' import { Block, gloadBytes, gloadUint64 } from '../src/impl' import { AccountCls } from '../src/impl/account' import { InnerTxn } from '../src/impl/itxn' import { ApplicationTransaction } from '../src/impl/transactions' import { DeliberateAny } from '../src/typescript-helpers' -import { asBigInt, asNumber, asUint64Cls, asUint8Array } from '../src/util' +import { asBigInt, asBigUintCls, asNumber, asUint64Cls, asUint8Array, encodeAddress, getRandomBytes } from '../src/util' import { AppExpectingEffects } from './artifacts/created-app-asset/contract.algo' import { ItxnDemoContract, ITxnOpsContract, - StateAcctParamsGetContract, StateAppGlobalContract, StateAppGlobalExContract, StateAppLocalContract, @@ -34,10 +34,13 @@ import appLocalExAppSpecJson from './artifacts/state-ops/data/StateAppLocalExCon import appParamsAppSpecJson from './artifacts/state-ops/data/StateAppParamsContract.arc32.json' import assetHoldingAppSpecJson from './artifacts/state-ops/data/StateAssetHoldingContract.arc32.json' import assetParamsAppSpecJson from './artifacts/state-ops/data/StateAssetParamsContract.arc32.json' +import { StateAcctParamsGetContract } from './artifacts/state-ops/state-acct-params-get-contract.algo' import { generateTestAccount, generateTestAsset, + getAlgodMajorVersion, getAlgorandAppClient, + getAlgorandAppClientV11, getAlgorandAppClientWithApp, getAvmResult, getLocalNetDefaultAccount, @@ -46,13 +49,15 @@ import { describe('State op codes', async () => { const ctx = new TestExecutionContext() + const algodVersion = await getAlgodMajorVersion() + const isV11Supported = algodVersion > 4 afterEach(async () => { ctx.reset() }) - describe('AcctParams', async () => { - const [appClient, dummyAccount] = await Promise.all([getAlgorandAppClient(acctParamsAppSpecJson as AppSpec), generateTestAccount()]) + describe.skipIf(!isV11Supported)('AcctParams', async () => { + const [appClient, dummyAccount] = await Promise.all([getAlgorandAppClientV11(acctParamsAppSpecJson as AppSpec), generateTestAccount()]) test.each([ ['verify_acct_balance', INITIAL_BALANCE_MICRO_ALGOS + 100_000], @@ -85,7 +90,7 @@ describe('State op codes', async () => { }) const avmResult = await getAvmResult( - { appClient, sendParams: { staticFee: AlgoAmount.Algos(1000) } }, + { appClient: appClient!, sendParams: { staticFee: AlgoAmount.Algos(1000) } }, methodName, asUint8Array(dummyAccount.bytes), ) @@ -96,6 +101,58 @@ describe('State op codes', async () => { expect(mockResult).toEqual(avmResult) expect(mockResult).toEqual(expectedValue) }) + + it('should return true when account is eligible for incentive', async () => { + const mockAccount = ctx.any.account({ + address: dummyAccount, + balance: Uint64(INITIAL_BALANCE_MICRO_ALGOS + 100000), + minBalance: Uint64(100000), + }) + ctx.ledger.patchGlobalData({ payoutsEnabled: true, payoutsGoOnlineFee: 10 }) + ctx.txn.createScope([ctx.any.txn.keyRegistration({ sender: mockAccount, fee: 10 })]).execute(() => { + expect(op.AcctParams.acctIncentiveEligible(mockAccount)).toEqual([true, true]) + }) + + await appClient!.algorand.send.onlineKeyRegistration({ + sender: encodeAddress(asUint8Array(dummyAccount.bytes)), + voteKey: getRandomBytes(32).asUint8Array(), + selectionKey: getRandomBytes(32).asUint8Array(), + voteFirst: 1n, + voteLast: 1000000n, + voteKeyDilution: 1000000n, + stateProofKey: getRandomBytes(64).asUint8Array(), + staticFee: AlgoAmount.Algos(10), + }) + const avmResult = await getAvmResult( + { appClient: appClient!, sendParams: { staticFee: AlgoAmount.Algos(10) } }, + 'verify_acct_incentive_eligible', + asUint8Array(dummyAccount.bytes), + ) + expect(avmResult).toEqual(true) + }) + + it('should return last round as last proposed and last hearbeat by default', () => { + const mockAccount = ctx.any.account({ + address: dummyAccount, + balance: Uint64(INITIAL_BALANCE_MICRO_ALGOS + 100000), + }) + const lastProposed = op.AcctParams.acctLastProposed(mockAccount) + const lastHeartbeat = op.AcctParams.acctLastHeartbeat(mockAccount) + expect(lastProposed).toEqual([Global.round, true]) + expect(lastHeartbeat).toEqual([Global.round, true]) + }) + + it('should return configured round as last proposed and last hearbeat', () => { + const mockAccount = ctx.any.account({ + address: dummyAccount, + balance: Uint64(INITIAL_BALANCE_MICRO_ALGOS + 100000), + }) + ctx.ledger.patchAccountData(mockAccount, { lastProposed: 100, lastHeartbeat: 200 }) + const lastProposed = op.AcctParams.acctLastProposed(mockAccount) + const lastHeartbeat = op.AcctParams.acctLastHeartbeat(mockAccount) + expect(lastProposed).toEqual([100, true]) + expect(lastHeartbeat).toEqual([200, true]) + }) }) describe('AppParams', async () => { @@ -235,6 +292,25 @@ describe('State op codes', async () => { }) }) + describe('VoterParams', async () => { + it('should return the configured balance and incentive eligibility', async () => { + const mockAccount = ctx.any.account() + ctx.ledger.patchVoterData(mockAccount, { balance: 100, incentiveEligible: true }) + const balance = op.VoterParams.voterBalance(mockAccount) + const incentiveEligible = op.VoterParams.voterIncentiveEligible(mockAccount) + expect(balance).toEqual([100, true]) + expect(incentiveEligible).toEqual([true, true]) + }) + }) + + describe('onlineStake', async () => { + it('should return the configured online stake', async () => { + lazyContext.ledger.onlineStake = Uint64(42) + const result = op.onlineStake() + expect(result).toEqual(42) + }) + }) + describe('Global', async () => { it('should return the correct global field value', async () => { const creator = ctx.any.account() @@ -272,6 +348,18 @@ describe('State op codes', async () => { }) expect([...asUint8Array(firstGroupId)]).not.toEqual([...asUint8Array(secondGroupId)]) expect(firstTimestamp.valueOf()).not.toEqual(secondTimestamp.valueOf()) + + ctx.ledger.patchGlobalData({ + payoutsEnabled: true, + payoutsGoOnlineFee: 12, + payoutsPercent: 2, + payoutsMinBalance: 42, + }) + + expect(op.Global.payoutsEnabled).toEqual(true) + expect(op.Global.payoutsGoOnlineFee).toEqual(12) + expect(op.Global.payoutsPercent).toEqual(2) + expect(op.Global.payoutsMinBalance).toEqual(42) }) }) @@ -427,14 +515,40 @@ describe('State op codes', async () => { describe('Block', async () => { it('should return the correct field value of the block', async () => { const index = 42 - const seed = 123 + const seed = asBigUintCls(123n).toBytes().asAlgoTs() const timestamp = 1234567890 - ctx.ledger.setBlock(index, seed, timestamp) - const seedResult = op.btoi(Block.blkSeed(Uint64(index))) - const timestampResult = Block.blkTimestamp(Uint64(index)) + const proposer = ctx.any.account() + const feesCollected = 1000 + const bonus = 12 + const branch = getRandomBytes(32).asAlgoTs() + const feeSink = ctx.any.account() + const protocol = getRandomBytes(32).asAlgoTs() + const txnCounter = 32 + const proposerPayout = 42 + + ctx.ledger.patchBlockData(index, { + seed, + timestamp, + proposer, + feesCollected, + bonus, + branch, + feeSink, + protocol, + txnCounter, + proposerPayout, + }) - expect(seedResult).toEqual(Uint64(seed)) - expect(timestampResult).toEqual(Uint64(timestamp)) + expect(Block.blkSeed(index)).toEqual(seed) + expect(Block.blkTimestamp(index)).toEqual(timestamp) + expect(Block.blkProposer(index)).toEqual(proposer) + expect(Block.blkFeesCollected(index)).toEqual(feesCollected) + expect(Block.blkBonus(index)).toEqual(bonus) + expect(Block.blkBranch(index)).toEqual(branch) + expect(Block.blkFeeSink(index)).toEqual(feeSink) + expect(Block.blkProtocol(index)).toEqual(protocol) + expect(Block.blkTxnCounter(index)).toEqual(txnCounter) + expect(Block.blkProposerPayout(index)).toEqual(proposerPayout) }) it('should throw error if the block is not set', async () => { const index = 42