From 2f827aba3cc471f588609156f551130b47f9c5b8 Mon Sep 17 00:00:00 2001 From: Adam Chidlow Date: Fri, 6 Sep 2024 14:42:58 +0800 Subject: [PATCH] fix: when accessing a member of `self`, use the source location of the access --- .../amm/out/ConstantProductAMM.approval.mir | 68 +- .../amm/out/ConstantProductAMM.approval.teal | 174 +--- .../amm/out/ConstantProductAMM.arc32.json | 2 +- .../ConstantProductAMM.approval.teal | 174 +--- examples/auction/out/Auction.approval.mir | 38 +- examples/auction/out/Auction.approval.teal | 82 +- examples/auction/out/Auction.arc32.json | 2 +- .../out_unoptimized/Auction.approval.teal | 83 +- .../box_storage/out/BoxContract.approval.mir | 124 +-- .../box_storage/out/BoxContract.approval.teal | 517 +---------- .../box_storage/out/BoxContract.arc32.json | 2 +- .../out_unoptimized/BoxContract.approval.teal | 874 +----------------- .../out/AppStateContract.approval.mir | 46 +- .../out/AppStateContract.approval.teal | 94 +- .../AppStateContract.approval.teal | 94 +- .../out/LocalStateContract.approval.mir | 12 +- .../out/LocalStateContract.approval.teal | 25 - .../out/LocalStateWithOffsets.approval.mir | 10 +- .../out/LocalStateWithOffsets.approval.teal | 20 - .../LocalStateContract.approval.teal | 25 - .../LocalStateWithOffsets.approval.teal | 20 - examples/merkle/out/MerkleTree.approval.mir | 2 +- examples/merkle/out/MerkleTree.approval.teal | 4 - examples/merkle/out/MerkleTree.arc32.json | 2 +- .../out_unoptimized/MerkleTree.approval.teal | 4 - .../out/TicTacToeContract.approval.mir | 48 +- .../out/TicTacToeContract.approval.teal | 96 +- .../out/TicTacToeContract.arc32.json | 2 +- .../TicTacToeContract.approval.teal | 96 +- .../voting/out/VotingRoundApp.approval.mir | 58 +- .../voting/out/VotingRoundApp.approval.teal | 266 +----- examples/voting/out/VotingRoundApp.arc32.json | 2 +- .../VotingRoundApp.approval.teal | 272 +----- src/puyapy/awst_build/eb/contracts.py | 21 +- src/puyapy/awst_build/eb/interface.py | 2 +- .../abi_routing/out/Reference.approval.mir | 6 +- .../abi_routing/out/Reference.approval.teal | 13 +- .../abi_routing/out/Reference.arc32.json | 2 +- .../out_unoptimized/Reference.approval.teal | 13 +- test_cases/asset/out/Reference.approval.mir | 6 +- test_cases/asset/out/Reference.approval.teal | 13 +- .../out_unoptimized/Reference.approval.teal | 13 +- .../out/Augmented.approval.mir | 20 +- .../out/Augmented.approval.teal | 46 +- .../out_unoptimized/Augmented.approval.teal | 46 +- test_cases/compile/out/Hello.approval.mir | 4 +- test_cases/compile/out/Hello.approval.teal | 8 +- test_cases/compile/out/Hello.arc32.json | 2 +- test_cases/compile/out/HelloBase.approval.mir | 2 +- .../compile/out/HelloBase.approval.teal | 4 - test_cases/compile/out/HelloBase.arc32.json | 2 +- .../out/HelloOtherConstants.approval.mir | 10 +- .../out/HelloOtherConstants.approval.teal | 20 - .../out/HelloOtherConstants.arc32.json | 2 +- test_cases/compile/out/HelloPrfx.approval.mir | 4 +- .../compile/out/HelloPrfx.approval.teal | 8 +- test_cases/compile/out/HelloPrfx.arc32.json | 2 +- test_cases/compile/out/HelloTmpl.approval.mir | 4 +- .../compile/out/HelloTmpl.approval.teal | 8 +- test_cases/compile/out/HelloTmpl.arc32.json | 2 +- .../out_unoptimized/Hello.approval.teal | 8 +- .../out_unoptimized/HelloBase.approval.teal | 4 - .../HelloOtherConstants.approval.teal | 20 - .../out_unoptimized/HelloPrfx.approval.teal | 8 +- .../out_unoptimized/HelloTmpl.approval.teal | 8 +- .../ConditionalExecutionContract.approval.mir | 36 +- ...ConditionalExecutionContract.approval.teal | 72 +- ...ConditionalExecutionContract.approval.teal | 72 +- .../everything/out/MyContract.approval.mir | 14 +- .../everything/out/MyContract.approval.teal | 28 - .../everything/out/MyContract.arc32.json | 4 +- .../everything/out/MyContract.clear.mir | 4 +- .../everything/out/MyContract.clear.teal | 8 - .../out_unoptimized/MyContract.approval.teal | 28 - .../out_unoptimized/MyContract.clear.teal | 8 - .../out/Greeter.approval.mir | 8 +- .../out/Greeter.approval.teal | 16 +- .../inner_transactions/out/Greeter.arc32.json | 2 +- .../out/MyContract.approval.mir | 8 +- .../out/MyContract.approval.teal | 16 +- .../out_unoptimized/Greeter.approval.teal | 16 +- .../out_unoptimized/MyContract.approval.teal | 16 +- .../intrinsics/out/Overloaded.approval.mir | 4 +- .../intrinsics/out/Overloaded.approval.teal | 8 - .../out_unoptimized/Overloaded.approval.teal | 8 - test_cases/match/out/Counter.approval.mir | 4 +- test_cases/match/out/Counter.approval.teal | 8 - test_cases/match/out/MyContract.approval.mir | 4 +- test_cases/match/out/MyContract.approval.teal | 8 - .../out_unoptimized/Counter.approval.teal | 8 - .../out_unoptimized/MyContract.approval.teal | 8 - test_cases/simplish/out/Simplish.approval.mir | 8 +- .../simplish/out/Simplish.approval.teal | 16 - .../out_unoptimized/Simplish.approval.teal | 16 - .../state_mutations/out/Contract.approval.mir | 62 +- .../out/Contract.approval.teal | 124 +-- .../state_mutations/out/Contract.arc32.json | 2 +- .../out_unoptimized/Contract.approval.teal | 124 +-- .../out/StateProxyContract.approval.mir | 6 +- .../out/StateProxyContract.approval.teal | 12 +- .../out/StateProxyContract.arc32.json | 2 +- .../StateProxyContract.approval.teal | 12 +- .../out/NestedTuples.approval.mir | 8 +- .../out/NestedTuples.approval.teal | 16 +- .../tuple_support/out/NestedTuples.arc32.json | 2 +- .../out/TupleSupport.approval.mir | 2 +- .../out/TupleSupport.approval.teal | 4 - .../NestedTuples.approval.teal | 16 +- .../TupleSupport.approval.teal | 4 - 109 files changed, 494 insertions(+), 4027 deletions(-) diff --git a/examples/amm/out/ConstantProductAMM.approval.mir b/examples/amm/out/ConstantProductAMM.approval.mir index 8e67e4336b..a44356775d 100644 --- a/examples/amm/out/ConstantProductAMM.approval.mir +++ b/examples/amm/out/ConstantProductAMM.approval.mir @@ -343,7 +343,7 @@ set_governor: set_governor_block@0: callsub _check_is_governor // (𝕡) new_governor#0 | self._check_is_governor() amm/contract.py:46 - byte "governor" // (𝕡) new_governor#0 | "governor" # The current governor of this contract, allowed to do admin type actions\nself.governor amm/contract.py:36-37 + byte "governor" // (𝕡) new_governor#0 | "governor" self.governor amm/contract.py:47 frame_dig -1 // load new_governor#0 from parameters (𝕡) new_governor#0 | "governor",new_governor#0 self.governor = new_governor amm/contract.py:47 app_global_put // (𝕡) new_governor#0 | self.governor = new_governor amm/contract.py:47 retsub // @@ -357,7 +357,7 @@ _check_is_governor_block@0: txn Sender // {txn} Txn.sender amm/contract.py:265 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Txn.sender amm/contract.py:265 int 0 // tmp%0#0,0 self.governor amm/contract.py:265 - byte "governor" // tmp%0#0,0,"governor" # The current governor of this contract, allowed to do admin type actions\nself.governor amm/contract.py:36-37 + byte "governor" // tmp%0#0,0,"governor" self.governor amm/contract.py:265 app_global_get_ex // tmp%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.governor amm/contract.py:265 // virtual: store maybe_exists%0#0 to l-stack (no copy) tmp%0#0,maybe_exists%0#0,{app_global_get_ex}.0 self.governor amm/contract.py:265 // virtual: store maybe_value%0#0 to l-stack (no copy) tmp%0#0,maybe_value%0#0,maybe_exists%0#0 self.governor amm/contract.py:265 @@ -378,7 +378,7 @@ bootstrap: bootstrap_block@0: int 0 // (𝕡) seed#0,a_asset#0,b_asset#0 | 0 self.pool_token amm/contract.py:66 - byte "pool_token" // (𝕡) seed#0,a_asset#0,b_asset#0 | 0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // (𝕡) seed#0,a_asset#0,b_asset#0 | 0,"pool_token" self.pool_token amm/contract.py:66 app_global_get_ex // (𝕡) seed#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.pool_token amm/contract.py:66 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.pool_token amm/contract.py:66 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_value%0#0,maybe_exists%0#0 self.pool_token amm/contract.py:66 @@ -424,19 +424,19 @@ bootstrap_block@0: // virtual: store tmp%8#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | tmp%8#0 a_asset.id < b_asset.id, "asset a must be less than asset b" amm/contract.py:72 // virtual: load tmp%8#0 from l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | tmp%8#0 assert a_asset.id < b_asset.id, "asset a must be less than asset b" amm/contract.py:72 assert // asset a must be less than asset b // (𝕡) seed#0,a_asset#0,b_asset#0 | assert a_asset.id < b_asset.id, "asset a must be less than asset b" amm/contract.py:72 - byte "asset_a" // (𝕡) seed#0,a_asset#0,b_asset#0 | "asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) seed#0,a_asset#0,b_asset#0 | "asset_a" self.asset_a amm/contract.py:73 frame_dig -2 // load a_asset#0 from parameters (𝕡) seed#0,a_asset#0,b_asset#0 | "asset_a",a_asset#0 self.asset_a = a_asset amm/contract.py:73 app_global_put // (𝕡) seed#0,a_asset#0,b_asset#0 | self.asset_a = a_asset amm/contract.py:73 - byte "asset_b" // (𝕡) seed#0,a_asset#0,b_asset#0 | "asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) seed#0,a_asset#0,b_asset#0 | "asset_b" self.asset_b amm/contract.py:74 frame_dig -1 // load b_asset#0 from parameters (𝕡) seed#0,a_asset#0,b_asset#0 | "asset_b",b_asset#0 self.asset_b = b_asset amm/contract.py:74 app_global_put // (𝕡) seed#0,a_asset#0,b_asset#0 | self.asset_b = b_asset amm/contract.py:74 callsub _create_pool_token // (𝕡) seed#0,a_asset#0,b_asset#0 | {_create_pool_token} self._create_pool_token() amm/contract.py:75 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | new_state_value%0#0 self._create_pool_token() amm/contract.py:75 - byte "pool_token" // (𝕡) seed#0,a_asset#0,b_asset#0 | new_state_value%0#0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // (𝕡) seed#0,a_asset#0,b_asset#0 | new_state_value%0#0,"pool_token" self.pool_token amm/contract.py:75 uncover 1 // load new_state_value%0#0 from l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | "pool_token",new_state_value%0#0 self.pool_token = self._create_pool_token() amm/contract.py:75 app_global_put // (𝕡) seed#0,a_asset#0,b_asset#0 | self.pool_token = self._create_pool_token() amm/contract.py:75 int 0 // (𝕡) seed#0,a_asset#0,b_asset#0 | 0 self.asset_a amm/contract.py:77 - byte "asset_a" // (𝕡) seed#0,a_asset#0,b_asset#0 | 0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) seed#0,a_asset#0,b_asset#0 | 0,"asset_a" self.asset_a amm/contract.py:77 app_global_get_ex // (𝕡) seed#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:77 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:77 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_value%1#0,maybe_exists%1#0 self.asset_a amm/contract.py:77 @@ -445,7 +445,7 @@ bootstrap_block@0: // virtual: load maybe_value%1#0 from l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_value%1#0 self._do_opt_in(self.asset_a) amm/contract.py:77 callsub _do_opt_in // (𝕡) seed#0,a_asset#0,b_asset#0 | self._do_opt_in(self.asset_a) amm/contract.py:77 int 0 // (𝕡) seed#0,a_asset#0,b_asset#0 | 0 self.asset_b amm/contract.py:78 - byte "asset_b" // (𝕡) seed#0,a_asset#0,b_asset#0 | 0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) seed#0,a_asset#0,b_asset#0 | 0,"asset_b" self.asset_b amm/contract.py:78 app_global_get_ex // (𝕡) seed#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:78 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_exists%2#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:78 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_value%2#0,maybe_exists%2#0 self.asset_b amm/contract.py:78 @@ -454,7 +454,7 @@ bootstrap_block@0: // virtual: load maybe_value%2#0 from l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_value%2#0 self._do_opt_in(self.asset_b) amm/contract.py:78 callsub _do_opt_in // (𝕡) seed#0,a_asset#0,b_asset#0 | self._do_opt_in(self.asset_b) amm/contract.py:78 int 0 // (𝕡) seed#0,a_asset#0,b_asset#0 | 0 self.pool_token amm/contract.py:79 - byte "pool_token" // (𝕡) seed#0,a_asset#0,b_asset#0 | 0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // (𝕡) seed#0,a_asset#0,b_asset#0 | 0,"pool_token" self.pool_token amm/contract.py:79 app_global_get_ex // (𝕡) seed#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.pool_token amm/contract.py:79 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_exists%3#0,{app_global_get_ex}.0 self.pool_token amm/contract.py:79 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) seed#0,a_asset#0,b_asset#0 | maybe_value%3#0,maybe_exists%3#0 self.pool_token amm/contract.py:79 @@ -471,7 +471,7 @@ _create_pool_token: _create_pool_token_block@0: itxn_begin // itxn.AssetConfig(\nasset_name=b"DPT-" + self.asset_a.unit_name + b"-" + self.asset_b.unit_name,\n... amm/contract.py:271-279 int 0 // 0 self.asset_a amm/contract.py:272 - byte "asset_a" // 0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // 0,"asset_a" self.asset_a amm/contract.py:272 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:272 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:272 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.asset_a amm/contract.py:272 @@ -492,7 +492,7 @@ _create_pool_token_block@0: concat // {concat} b"DPT-" + self.asset_a.unit_name + b"-" amm/contract.py:272 // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 b"DPT-" + self.asset_a.unit_name + b"-" amm/contract.py:272 int 0 // tmp%1#0,0 self.asset_b amm/contract.py:272 - byte "asset_b" // tmp%1#0,0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // tmp%1#0,0,"asset_b" self.asset_b amm/contract.py:272 app_global_get_ex // tmp%1#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:272 // virtual: store maybe_exists%1#0 to l-stack (no copy) tmp%1#0,maybe_exists%1#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:272 // virtual: store maybe_value%1#0 to l-stack (no copy) tmp%1#0,maybe_value%1#0,maybe_exists%1#0 self.asset_b amm/contract.py:272 @@ -576,7 +576,7 @@ mint: mint_block@0: callsub _check_bootstrapped // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | self._check_bootstrapped() amm/contract.py:111 int 0 // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0 \nassert pool_asset == self.pool_token amm/contract.py:113-114 - byte "pool_token" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"pool_token" \nassert pool_asset == self.pool_token amm/contract.py:113-114 app_global_get_ex // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 \nassert pool_asset == self.pool_token amm/contract.py:113-114 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_exists%0#0,{app_global_get_ex}.0 \nassert pool_asset == self.pool_token amm/contract.py:113-114 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_value%0#0,maybe_exists%0#0 \nassert pool_asset == self.pool_token amm/contract.py:113-114 @@ -589,7 +589,7 @@ mint_block@0: // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%0#0 # well-formed mint\nassert pool_asset == self.pool_token, "asset pool incorrect" amm/contract.py:113-114 assert // asset pool incorrect // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | # well-formed mint\nassert pool_asset == self.pool_token, "asset pool incorrect" amm/contract.py:113-114 int 0 // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0 self.asset_a amm/contract.py:115 - byte "asset_a" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"asset_a" self.asset_a amm/contract.py:115 app_global_get_ex // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:115 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:115 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_value%1#0,maybe_exists%1#0 self.asset_a amm/contract.py:115 @@ -602,7 +602,7 @@ mint_block@0: // virtual: load tmp%1#0 from l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%1#0 assert a_asset == self.asset_a, "asset a incorrect" amm/contract.py:115 assert // asset a incorrect // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | assert a_asset == self.asset_a, "asset a incorrect" amm/contract.py:115 int 0 // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0 self.asset_b amm/contract.py:116 - byte "asset_b" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"asset_b" self.asset_b amm/contract.py:116 app_global_get_ex // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:116 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_exists%2#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:116 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_value%2#0,maybe_exists%2#0 self.asset_b amm/contract.py:116 @@ -651,7 +651,7 @@ mint_block@0: gtxns XferAsset // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | {gtxns} a_xfer.xfer_asset amm/contract.py:124 // virtual: store tmp%12#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%12#0 a_xfer.xfer_asset amm/contract.py:124 int 0 // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%12#0,0 self.asset_a amm/contract.py:124 - byte "asset_a" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%12#0,0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%12#0,0,"asset_a" self.asset_a amm/contract.py:124 app_global_get_ex // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%12#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:124 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%12#0,maybe_exists%3#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:124 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%12#0,maybe_value%3#0,maybe_exists%3#0 self.asset_a amm/contract.py:124 @@ -683,7 +683,7 @@ mint_block@0: gtxns XferAsset // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%14#0,{gtxns} b_xfer.xfer_asset amm/contract.py:131 // virtual: store tmp%19#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%14#0,tmp%19#0 b_xfer.xfer_asset amm/contract.py:131 int 0 // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%14#0,tmp%19#0,0 self.asset_b amm/contract.py:131 - byte "asset_b" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%14#0,tmp%19#0,0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%14#0,tmp%19#0,0,"asset_b" self.asset_b amm/contract.py:131 app_global_get_ex // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%14#0,tmp%19#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:131 // virtual: store maybe_exists%4#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%14#0,tmp%19#0,maybe_exists%4#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:131 // virtual: store maybe_value%4#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%14#0,tmp%19#0,maybe_value%4#0,maybe_exists%4#0 self.asset_b amm/contract.py:131 @@ -718,7 +718,7 @@ mint_block@0: txn Sender // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | to_mint#0,{txn} \ndo_asset_transfer(receiver=Txn.sender amm/contract.py:143-144 // virtual: store tmp%29#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | to_mint#0,tmp%29#0 \ndo_asset_transfer(receiver=Txn.sender amm/contract.py:143-144 int 0 // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | to_mint#0,tmp%29#0,0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.pool_token amm/contract.py:143-144 - byte "pool_token" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | to_mint#0,tmp%29#0,0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | to_mint#0,tmp%29#0,0,"pool_token" \ndo_asset_transfer(receiver=Txn.sender, asset=self.pool_token amm/contract.py:143-144 app_global_get_ex // (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | to_mint#0,tmp%29#0,{app_global_get_ex}.0,{app_global_get_ex}.1 \ndo_asset_transfer(receiver=Txn.sender, asset=self.pool_token amm/contract.py:143-144 // virtual: store maybe_exists%5#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | to_mint#0,tmp%29#0,maybe_exists%5#0,{app_global_get_ex}.0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.pool_token amm/contract.py:143-144 // virtual: store maybe_value%5#0 to l-stack (no copy) (𝕡) a_xfer#0,b_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | to_mint#0,tmp%29#0,maybe_value%5#0,maybe_exists%5#0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.pool_token amm/contract.py:143-144 @@ -738,7 +738,7 @@ _check_bootstrapped: _check_bootstrapped_block@0: int 0 // 0 self.pool_token amm/contract.py:253 - byte "pool_token" // 0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // 0,"pool_token" self.pool_token amm/contract.py:253 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.pool_token amm/contract.py:253 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.pool_token amm/contract.py:253 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.pool_token amm/contract.py:253 @@ -757,7 +757,7 @@ _current_pool_balance_block@0: global CurrentApplicationAddress // {global} Global.current_application_address amm/contract.py:293 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Global.current_application_address amm/contract.py:293 int 0 // tmp%0#0,0 self.pool_token amm/contract.py:293 - byte "pool_token" // tmp%0#0,0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // tmp%0#0,0,"pool_token" self.pool_token amm/contract.py:293 app_global_get_ex // tmp%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.pool_token amm/contract.py:293 // virtual: store maybe_exists%0#0 to l-stack (no copy) tmp%0#0,maybe_exists%0#0,{app_global_get_ex}.0 self.pool_token amm/contract.py:293 // virtual: store maybe_value%0#0 to l-stack (no copy) tmp%0#0,maybe_value%0#0,maybe_exists%0#0 self.pool_token amm/contract.py:293 @@ -782,7 +782,7 @@ _current_a_balance_block@0: global CurrentApplicationAddress // {global} Global.current_application_address amm/contract.py:297 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Global.current_application_address amm/contract.py:297 int 0 // tmp%0#0,0 self.asset_a amm/contract.py:297 - byte "asset_a" // tmp%0#0,0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // tmp%0#0,0,"asset_a" self.asset_a amm/contract.py:297 app_global_get_ex // tmp%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:297 // virtual: store maybe_exists%0#0 to l-stack (no copy) tmp%0#0,maybe_exists%0#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:297 // virtual: store maybe_value%0#0 to l-stack (no copy) tmp%0#0,maybe_value%0#0,maybe_exists%0#0 self.asset_a amm/contract.py:297 @@ -807,7 +807,7 @@ _current_b_balance_block@0: global CurrentApplicationAddress // {global} Global.current_application_address amm/contract.py:301 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Global.current_application_address amm/contract.py:301 int 0 // tmp%0#0,0 self.asset_b amm/contract.py:301 - byte "asset_b" // tmp%0#0,0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // tmp%0#0,0,"asset_b" self.asset_b amm/contract.py:301 app_global_get_ex // tmp%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:301 // virtual: store maybe_exists%0#0 to l-stack (no copy) tmp%0#0,maybe_exists%0#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:301 // virtual: store maybe_value%0#0 to l-stack (no copy) tmp%0#0,maybe_value%0#0,maybe_exists%0#0 self.asset_b amm/contract.py:301 @@ -966,7 +966,7 @@ _update_ratio_block@0: uncover 1 // load b_balance#0 from l-stack (no copy) tmp%0#0,b_balance#0 a_balance * SCALE // b_balance amm/contract.py:260 / // {/} a_balance * SCALE // b_balance amm/contract.py:260 // virtual: store new_state_value%0#0 to l-stack (no copy) new_state_value%0#0 a_balance * SCALE // b_balance amm/contract.py:260 - byte "ratio" // new_state_value%0#0,"ratio" # The ratio between assets (A*Scale/B)\nself.ratio amm/contract.py:40-41 + byte "ratio" // new_state_value%0#0,"ratio" self.ratio amm/contract.py:260 uncover 1 // load new_state_value%0#0 from l-stack (no copy) "ratio",new_state_value%0#0 self.ratio = a_balance * SCALE // b_balance amm/contract.py:260 app_global_put // self.ratio = a_balance * SCALE // b_balance amm/contract.py:260 retsub // @@ -979,7 +979,7 @@ burn: burn_block@0: callsub _check_bootstrapped // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | self._check_bootstrapped() amm/contract.py:170 int 0 // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0 self.pool_token amm/contract.py:172 - byte "pool_token" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"pool_token" self.pool_token amm/contract.py:172 app_global_get_ex // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.pool_token amm/contract.py:172 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.pool_token amm/contract.py:172 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_value%0#0,maybe_exists%0#0 self.pool_token amm/contract.py:172 @@ -992,7 +992,7 @@ burn_block@0: // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%0#0 assert pool_asset == self.pool_token, "asset pool incorrect" amm/contract.py:172 assert // asset pool incorrect // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | assert pool_asset == self.pool_token, "asset pool incorrect" amm/contract.py:172 int 0 // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0 self.asset_a amm/contract.py:173 - byte "asset_a" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"asset_a" self.asset_a amm/contract.py:173 app_global_get_ex // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:173 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:173 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_value%1#0,maybe_exists%1#0 self.asset_a amm/contract.py:173 @@ -1005,7 +1005,7 @@ burn_block@0: // virtual: load tmp%1#0 from l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%1#0 assert a_asset == self.asset_a, "asset a incorrect" amm/contract.py:173 assert // asset a incorrect // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | assert a_asset == self.asset_a, "asset a incorrect" amm/contract.py:173 int 0 // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0 self.asset_b amm/contract.py:174 - byte "asset_b" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | 0,"asset_b" self.asset_b amm/contract.py:174 app_global_get_ex // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:174 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_exists%2#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:174 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | maybe_value%2#0,maybe_exists%2#0 self.asset_b amm/contract.py:174 @@ -1037,7 +1037,7 @@ burn_block@0: gtxns XferAsset // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%6#0,{gtxns} pool_xfer.xfer_asset amm/contract.py:180 // virtual: store tmp%8#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%6#0,tmp%8#0 pool_xfer.xfer_asset amm/contract.py:180 int 0 // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%6#0,tmp%8#0,0 self.pool_token amm/contract.py:180 - byte "pool_token" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%6#0,tmp%8#0,0,"pool_token" # The asset id of the Pool Token, used to track share of pool the holder may recover\nself.pool_t... amm/contract.py:38-39 + byte "pool_token" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%6#0,tmp%8#0,0,"pool_token" self.pool_token amm/contract.py:180 app_global_get_ex // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%6#0,tmp%8#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.pool_token amm/contract.py:180 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%6#0,tmp%8#0,maybe_exists%3#0,{app_global_get_ex}.0 self.pool_token amm/contract.py:180 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | tmp%6#0,tmp%8#0,maybe_value%3#0,maybe_exists%3#0 self.pool_token amm/contract.py:180 @@ -1079,7 +1079,7 @@ burn_block@0: txn Sender // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,a_amt#0,{txn} t of a\ndo_asset_transfer(receiver=Txn.sender amm/contract.py:197-198 // virtual: store tmp%17#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,a_amt#0,tmp%17#0 t of a\ndo_asset_transfer(receiver=Txn.sender amm/contract.py:197-198 int 0 // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,a_amt#0,tmp%17#0,0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_a amm/contract.py:197-198 - byte "asset_a" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,a_amt#0,tmp%17#0,0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,a_amt#0,tmp%17#0,0,"asset_a" \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_a amm/contract.py:197-198 app_global_get_ex // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,a_amt#0,tmp%17#0,{app_global_get_ex}.0,{app_global_get_ex}.1 \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_a amm/contract.py:197-198 // virtual: store maybe_exists%4#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,a_amt#0,tmp%17#0,maybe_exists%4#0,{app_global_get_ex}.0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_a amm/contract.py:197-198 // virtual: store maybe_value%4#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,a_amt#0,tmp%17#0,maybe_value%4#0,maybe_exists%4#0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_a amm/contract.py:197-198 @@ -1092,7 +1092,7 @@ burn_block@0: txn Sender // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,{txn} t of b\ndo_asset_transfer(receiver=Txn.sender amm/contract.py:200-201 // virtual: store tmp%18#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,tmp%18#0 t of b\ndo_asset_transfer(receiver=Txn.sender amm/contract.py:200-201 int 0 // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,tmp%18#0,0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_b amm/contract.py:200-201 - byte "asset_b" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,tmp%18#0,0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,tmp%18#0,0,"asset_b" \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_b amm/contract.py:200-201 app_global_get_ex // (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,tmp%18#0,{app_global_get_ex}.0,{app_global_get_ex}.1 \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_b amm/contract.py:200-201 // virtual: store maybe_exists%5#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,tmp%18#0,maybe_exists%5#0,{app_global_get_ex}.0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_b amm/contract.py:200-201 // virtual: store maybe_value%5#0 to l-stack (no copy) (𝕡) pool_xfer#0,pool_asset#0,a_asset#0,b_asset#0 | b_amt#0,tmp%18#0,maybe_value%5#0,maybe_exists%5#0 \ndo_asset_transfer(receiver=Txn.sender, asset=self.asset_b amm/contract.py:200-201 @@ -1140,7 +1140,7 @@ swap: swap_block@0: callsub _check_bootstrapped // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | self._check_bootstrapped() amm/contract.py:223 int 0 // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | 0 self.asset_a amm/contract.py:225 - byte "asset_a" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | 0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | 0,"asset_a" self.asset_a amm/contract.py:225 app_global_get_ex // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:225 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:225 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | maybe_value%0#0,maybe_exists%0#0 self.asset_a amm/contract.py:225 @@ -1153,7 +1153,7 @@ swap_block@0: // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | tmp%0#0 assert a_asset == self.asset_a, "asset a incorrect" amm/contract.py:225 assert // asset a incorrect // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | assert a_asset == self.asset_a, "asset a incorrect" amm/contract.py:225 int 0 // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | 0 self.asset_b amm/contract.py:226 - byte "asset_b" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | 0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | 0,"asset_b" self.asset_b amm/contract.py:226 app_global_get_ex // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:226 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:226 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0 | maybe_value%1#0,maybe_exists%1#0 self.asset_b amm/contract.py:226 @@ -1183,14 +1183,14 @@ swap_block@0: // virtual: load tmp%6#0 from l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | tmp%6#0 assert swap_xfer.sender == Txn.sender, "sender invalid" amm/contract.py:229 assert // sender invalid // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | assert swap_xfer.sender == Txn.sender, "sender invalid" amm/contract.py:229 int 0 // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | 0 self.asset_a amm/contract.py:232 - byte "asset_a" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | 0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | 0,"asset_a" self.asset_a amm/contract.py:232 app_global_get_ex // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:232 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_exists%2#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:232 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0,maybe_exists%2#0 self.asset_a amm/contract.py:232 // virtual: load maybe_exists%2#0 from l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0,maybe_exists%2#0 self.asset_a amm/contract.py:232 assert // check self.asset_a exists // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0 self.asset_a amm/contract.py:232 int 0 // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0,0 self.asset_b amm/contract.py:236 - byte "asset_b" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0,0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0,0,"asset_b" self.asset_b amm/contract.py:236 app_global_get_ex // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:236 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0,maybe_exists%3#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:236 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | maybe_value%2#0,maybe_value%3#0,maybe_exists%3#0 self.asset_b amm/contract.py:236 @@ -1211,7 +1211,7 @@ swap_switch_case_0@1: callsub _current_a_balance // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | {_current_a_balance} self._current_a_balance() amm/contract.py:234 // virtual: store out_supply#0 to x-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | out_supply = self._current_a_balance() amm/contract.py:234 int 0 // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | 0 self.asset_a amm/contract.py:235 - byte "asset_a" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | 0,"asset_a" # The asset id of asset A\nself.asset_a amm/contract.py:32-33 + byte "asset_a" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | 0,"asset_a" self.asset_a amm/contract.py:235 app_global_get_ex // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_a amm/contract.py:235 cover 1 // store maybe_exists%4#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | maybe_exists%4#0,{app_global_get_ex}.0 self.asset_a amm/contract.py:235 frame_bury 1 // store out_asset#0 to f-stack (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | maybe_exists%4#0 self.asset_a amm/contract.py:235 @@ -1225,7 +1225,7 @@ swap_switch_case_1@2: callsub _current_b_balance // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | {_current_b_balance} self._current_b_balance() amm/contract.py:238 // virtual: store out_supply#0 to x-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | out_supply = self._current_b_balance() amm/contract.py:238 int 0 // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | 0 self.asset_b amm/contract.py:239 - byte "asset_b" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | 0,"asset_b" # The asset id of asset B\nself.asset_b amm/contract.py:34-35 + byte "asset_b" // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | 0,"asset_b" self.asset_b amm/contract.py:239 app_global_get_ex // (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asset_b amm/contract.py:239 cover 1 // store maybe_exists%5#0 to l-stack (no copy) (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | maybe_exists%5#0,{app_global_get_ex}.0 self.asset_b amm/contract.py:239 frame_bury 1 // store out_asset#0 to f-stack (𝕡) swap_xfer#0,a_asset#0,b_asset#0 | (𝕗) in_supply#0,out_asset#0,tmp%2#0 | (𝕏) out_supply#0 | maybe_exists%5#0 self.asset_b amm/contract.py:239 diff --git a/examples/amm/out/ConstantProductAMM.approval.teal b/examples/amm/out/ConstantProductAMM.approval.teal index 2914c381e4..7987721195 100644 --- a/examples/amm/out/ConstantProductAMM.approval.teal +++ b/examples/amm/out/ConstantProductAMM.approval.teal @@ -246,12 +246,9 @@ set_governor: // amm/contract.py:46 // self._check_is_governor() callsub _check_is_governor - // amm/contract.py:36-37 - // # The current governor of this contract, allowed to do admin type actions - // self.governor = Txn.sender - byte "governor" // amm/contract.py:47 // self.governor = new_governor + byte "governor" frame_dig -1 app_global_put retsub @@ -267,12 +264,7 @@ _check_is_governor: // Txn.sender == self.governor txn Sender int 0 - // amm/contract.py:36-37 - // # The current governor of this contract, allowed to do admin type actions - // self.governor = Txn.sender byte "governor" - // amm/contract.py:265 - // Txn.sender == self.governor app_global_get_ex assert // check self.governor exists == @@ -293,12 +285,7 @@ bootstrap: // amm/contract.py:66 // assert not self.pool_token, "application has already been bootstrapped" int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:66 - // assert not self.pool_token, "application has already been bootstrapped" app_global_get_ex assert // check self.pool_token exists ! @@ -332,66 +319,40 @@ bootstrap: frame_dig -1 < assert // asset a must be less than asset b - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() - byte "asset_a" // amm/contract.py:73 // self.asset_a = a_asset + byte "asset_a" frame_dig -2 app_global_put - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() - byte "asset_b" // amm/contract.py:74 // self.asset_b = b_asset + byte "asset_b" frame_dig -1 app_global_put // amm/contract.py:75 // self.pool_token = self._create_pool_token() callsub _create_pool_token - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:75 - // self.pool_token = self._create_pool_token() swap app_global_put // amm/contract.py:77 // self._do_opt_in(self.asset_a) int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:77 - // self._do_opt_in(self.asset_a) app_global_get_ex assert // check self.asset_a exists callsub _do_opt_in // amm/contract.py:78 // self._do_opt_in(self.asset_b) int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:78 - // self._do_opt_in(self.asset_b) app_global_get_ex assert // check self.asset_b exists callsub _do_opt_in // amm/contract.py:79 // return self.pool_token.id int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:79 - // return self.pool_token.id app_global_get_ex assert // check self.pool_token exists retsub @@ -417,12 +378,7 @@ _create_pool_token: // amm/contract.py:272 // asset_name=b"DPT-" + self.asset_a.unit_name + b"-" + self.asset_b.unit_name, int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:272 - // asset_name=b"DPT-" + self.asset_a.unit_name + b"-" + self.asset_b.unit_name, app_global_get_ex assert // check self.asset_a exists asset_params_get AssetUnitName @@ -433,12 +389,7 @@ _create_pool_token: byte 0x2d concat int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:272 - // asset_name=b"DPT-" + self.asset_a.unit_name + b"-" + self.asset_b.unit_name, app_global_get_ex assert // check self.asset_b exists asset_params_get AssetUnitName @@ -600,13 +551,7 @@ mint: // # well-formed mint // assert pool_asset == self.pool_token, "asset pool incorrect" int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:113-114 - // # well-formed mint - // assert pool_asset == self.pool_token, "asset pool incorrect" app_global_get_ex assert // check self.pool_token exists frame_dig -3 @@ -615,12 +560,7 @@ mint: // amm/contract.py:115 // assert a_asset == self.asset_a, "asset a incorrect" int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:115 - // assert a_asset == self.asset_a, "asset a incorrect" app_global_get_ex assert // check self.asset_a exists frame_dig -2 @@ -629,12 +569,7 @@ mint: // amm/contract.py:116 // assert b_asset == self.asset_b, "asset b incorrect" int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:116 - // assert b_asset == self.asset_b, "asset b incorrect" app_global_get_ex assert // check self.asset_b exists frame_dig -1 @@ -671,12 +606,7 @@ mint: frame_dig -5 gtxns XferAsset int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:124 - // assert a_xfer.xfer_asset == self.asset_a, "asset a incorrect" app_global_get_ex assert // check self.asset_a exists == @@ -704,12 +634,7 @@ mint: frame_dig -4 gtxns XferAsset int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:131 - // assert b_xfer.xfer_asset == self.asset_b, "asset b incorrect" app_global_get_ex assert // check self.asset_b exists == @@ -749,13 +674,7 @@ mint: // do_asset_transfer(receiver=Txn.sender, asset=self.pool_token, amount=to_mint) txn Sender int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:143-144 - // # mint tokens - // do_asset_transfer(receiver=Txn.sender, asset=self.pool_token, amount=to_mint) app_global_get_ex assert // check self.pool_token exists uncover 2 @@ -775,12 +694,7 @@ _check_bootstrapped: // amm/contract.py:253 // assert self.pool_token, "bootstrap method needs to be called first" int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:253 - // assert self.pool_token, "bootstrap method needs to be called first" app_global_get_ex assert // check self.pool_token exists assert // bootstrap method needs to be called first @@ -797,12 +711,7 @@ _current_pool_balance: // return self.pool_token.balance(Global.current_application_address) global CurrentApplicationAddress int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:293 - // return self.pool_token.balance(Global.current_application_address) app_global_get_ex assert // check self.pool_token exists asset_holding_get AssetBalance @@ -820,12 +729,7 @@ _current_a_balance: // return self.asset_a.balance(Global.current_application_address) global CurrentApplicationAddress int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:297 - // return self.asset_a.balance(Global.current_application_address) app_global_get_ex assert // check self.asset_a exists asset_holding_get AssetBalance @@ -843,12 +747,7 @@ _current_b_balance: // return self.asset_b.balance(Global.current_application_address) global CurrentApplicationAddress int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:301 - // return self.asset_b.balance(Global.current_application_address) app_global_get_ex assert // check self.asset_b exists asset_holding_get AssetBalance @@ -973,12 +872,7 @@ _update_ratio: * swap / - // amm/contract.py:40-41 - // # The ratio between assets (A*Scale/B) - // self.ratio = UInt64(0) byte "ratio" - // amm/contract.py:260 - // self.ratio = a_balance * SCALE // b_balance swap app_global_put retsub @@ -1008,12 +902,7 @@ burn: // amm/contract.py:172 // assert pool_asset == self.pool_token, "asset pool incorrect" int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:172 - // assert pool_asset == self.pool_token, "asset pool incorrect" app_global_get_ex assert // check self.pool_token exists frame_dig -3 @@ -1022,12 +911,7 @@ burn: // amm/contract.py:173 // assert a_asset == self.asset_a, "asset a incorrect" int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:173 - // assert a_asset == self.asset_a, "asset a incorrect" app_global_get_ex assert // check self.asset_a exists frame_dig -2 @@ -1036,12 +920,7 @@ burn: // amm/contract.py:174 // assert b_asset == self.asset_b, "asset b incorrect" int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:174 - // assert b_asset == self.asset_b, "asset b incorrect" app_global_get_ex assert // check self.asset_b exists frame_dig -1 @@ -1069,12 +948,7 @@ burn: frame_dig -4 gtxns XferAsset int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:180 - // assert pool_xfer.xfer_asset == self.pool_token, "asset pool incorrect" app_global_get_ex assert // check self.pool_token exists == @@ -1122,13 +996,7 @@ burn: // do_asset_transfer(receiver=Txn.sender, asset=self.asset_a, amount=a_amt) txn Sender int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:197-198 - // # Send back commensurate amt of a - // do_asset_transfer(receiver=Txn.sender, asset=self.asset_a, amount=a_amt) app_global_get_ex assert // check self.asset_a exists uncover 2 @@ -1138,13 +1006,7 @@ burn: // do_asset_transfer(receiver=Txn.sender, asset=self.asset_b, amount=b_amt) txn Sender int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:200-201 - // # Send back commensurate amt of b - // do_asset_transfer(receiver=Txn.sender, asset=self.asset_b, amount=b_amt) app_global_get_ex assert // check self.asset_b exists uncover 2 @@ -1202,12 +1064,7 @@ swap: // amm/contract.py:225 // assert a_asset == self.asset_a, "asset a incorrect" int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:225 - // assert a_asset == self.asset_a, "asset a incorrect" app_global_get_ex assert // check self.asset_a exists frame_dig -2 @@ -1216,12 +1073,7 @@ swap: // amm/contract.py:226 // assert b_asset == self.asset_b, "asset b incorrect" int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:226 - // assert b_asset == self.asset_b, "asset b incorrect" app_global_get_ex assert // check self.asset_b exists frame_dig -1 @@ -1243,23 +1095,13 @@ swap: // amm/contract.py:232 // case self.asset_a: int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:232 - // case self.asset_a: app_global_get_ex assert // check self.asset_a exists // amm/contract.py:236 // case self.asset_b: int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:236 - // case self.asset_b: app_global_get_ex assert // check self.asset_b exists // amm/contract.py:231 @@ -1294,12 +1136,7 @@ swap_switch_case_0@1: // amm/contract.py:235 // out_asset = self.asset_a int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:235 - // out_asset = self.asset_a app_global_get_ex swap frame_bury 1 @@ -1317,12 +1154,7 @@ swap_switch_case_1@2: // amm/contract.py:239 // out_asset = self.asset_b int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:239 - // out_asset = self.asset_b app_global_get_ex swap frame_bury 1 diff --git a/examples/amm/out/ConstantProductAMM.arc32.json b/examples/amm/out/ConstantProductAMM.arc32.json index e2eee327cf..784ae8571b 100644 --- a/examples/amm/out/ConstantProductAMM.arc32.json +++ b/examples/amm/out/ConstantProductAMM.arc32.json @@ -65,7 +65,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBjbGFzcyBDb25zdGFudFByb2R1Y3RBTU0oQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A5CiAgICBtZXRob2QgInNldF9nb3Zlcm5vcihhY2NvdW50KXZvaWQiCiAgICBtZXRob2QgImJvb3RzdHJhcChwYXksYXNzZXQsYXNzZXQpdWludDY0IgogICAgbWV0aG9kICJtaW50KGF4ZmVyLGF4ZmVyLGFzc2V0LGFzc2V0LGFzc2V0KXZvaWQiCiAgICBtZXRob2QgImJ1cm4oYXhmZXIsYXNzZXQsYXNzZXQsYXNzZXQpdm9pZCIKICAgIG1ldGhvZCAic3dhcChheGZlcixhc3NldCxhc3NldCl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2dvdmVybm9yX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fYm9vdHN0cmFwX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fbWludF9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2J1cm5fcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19zd2FwX3JvdXRlQDYKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9nb3Zlcm5vcl9yb3V0ZUAyOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBjbGFzcyBDb25zdGFudFByb2R1Y3RBTU0oQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyBhbW0vY29udHJhY3QucHk6NDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9nb3Zlcm5vcgogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYm9vdHN0cmFwX3JvdXRlQDM6CiAgICAvLyBhbW0vY29udHJhY3QucHk6NDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcKICAgIC8vIGNsYXNzIENvbnN0YW50UHJvZHVjdEFNTShBUkM0Q29udHJhY3QpOgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBib290c3RyYXAKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX21pbnRfcm91dGVANDoKICAgIC8vIGFtbS9jb250cmFjdC5weTo4MS04NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJwb29sX2Fzc2V0IjogInBvb2xfdG9rZW4iLAogICAgLy8gICAgICAgICAiYV9hc3NldCI6ICJhc3NldF9hIiwKICAgIC8vICAgICAgICAgImJfYXNzZXQiOiAiYXNzZXRfYiIsCiAgICAvLyAgICAgfSwKICAgIC8vICkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFtbS9jb250cmFjdC5weToyNwogICAgLy8gY2xhc3MgQ29uc3RhbnRQcm9kdWN0QU1NKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDIKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBheGZlcgogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIGF4ZmVyCiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBheGZlcgogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIGF4ZmVyCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhbW0vY29udHJhY3QucHk6ODEtODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgKICAgIC8vICAgICBkZWZhdWx0X2FyZ3M9ewogICAgLy8gICAgICAgICAicG9vbF9hc3NldCI6ICJwb29sX3Rva2VuIiwKICAgIC8vICAgICAgICAgImFfYXNzZXQiOiAiYXNzZXRfYSIsCiAgICAvLyAgICAgICAgICJiX2Fzc2V0IjogImFzc2V0X2IiLAogICAgLy8gICAgIH0sCiAgICAvLyApCiAgICBjYWxsc3ViIG1pbnQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2J1cm5fcm91dGVANToKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDctMTUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgInBvb2xfYXNzZXQiOiAicG9vbF90b2tlbiIsCiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBjbGFzcyBDb25zdGFudFByb2R1Y3RBTU0oQVJDNENvbnRyYWN0KToKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IGF4ZmVyCiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgYXhmZXIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDctMTUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgInBvb2xfYXNzZXQiOiAicG9vbF90b2tlbiIsCiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgY2FsbHN1YiBidXJuCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zd2FwX3JvdXRlQDY6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjA0LTIwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBjbGFzcyBDb25zdGFudFByb2R1Y3RBTU0oQVJDNENvbnRyYWN0KToKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IGF4ZmVyCiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgYXhmZXIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjA0LTIwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgY2FsbHN1YiBzd2FwCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOToKICAgIC8vIGFtbS9jb250cmFjdC5weToyNwogICAgLy8gY2xhc3MgQ29uc3RhbnRQcm9kdWN0QU1NKEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMzoKICAgIC8vIGFtbS9jb250cmFjdC5weToyNwogICAgLy8gY2xhc3MgQ29uc3RhbnRQcm9kdWN0QU1NKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYW1tLmNvbnRyYWN0LkNvbnN0YW50UHJvZHVjdEFNTS5zZXRfZ292ZXJub3IobmV3X2dvdmVybm9yOiBieXRlcykgLT4gdm9pZDoKc2V0X2dvdmVybm9yOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjQzLTQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9nb3Zlcm5vcihzZWxmLCBuZXdfZ292ZXJub3I6IEFjY291bnQpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIGFtbS9jb250cmFjdC5weTo0NgogICAgLy8gc2VsZi5fY2hlY2tfaXNfZ292ZXJub3IoKQogICAgY2FsbHN1YiBfY2hlY2tfaXNfZ292ZXJub3IKICAgIC8vIGFtbS9jb250cmFjdC5weTozNi0zNwogICAgLy8gIyBUaGUgY3VycmVudCBnb3Zlcm5vciBvZiB0aGlzIGNvbnRyYWN0LCBhbGxvd2VkIHRvIGRvIGFkbWluIHR5cGUgYWN0aW9ucwogICAgLy8gc2VsZi5nb3Zlcm5vciA9IFR4bi5zZW5kZXIKICAgIGJ5dGUgImdvdmVybm9yIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBzZWxmLmdvdmVybm9yID0gbmV3X2dvdmVybm9yCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9jaGVja19pc19nb3Zlcm5vcigpIC0+IHZvaWQ6Cl9jaGVja19pc19nb3Zlcm5vcjoKICAgIC8vIGFtbS9jb250cmFjdC5weToyNjItMjYzCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9jaGVja19pc19nb3Zlcm5vcihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjY1CiAgICAvLyBUeG4uc2VuZGVyID09IHNlbGYuZ292ZXJub3IKICAgIHR4biBTZW5kZXIKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzYtMzcKICAgIC8vICMgVGhlIGN1cnJlbnQgZ292ZXJub3Igb2YgdGhpcyBjb250cmFjdCwgYWxsb3dlZCB0byBkbyBhZG1pbiB0eXBlIGFjdGlvbnMKICAgIC8vIHNlbGYuZ292ZXJub3IgPSBUeG4uc2VuZGVyCiAgICBieXRlICJnb3Zlcm5vciIKICAgIC8vIGFtbS9jb250cmFjdC5weToyNjUKICAgIC8vIFR4bi5zZW5kZXIgPT0gc2VsZi5nb3Zlcm5vcgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdvdmVybm9yIGV4aXN0cwogICAgPT0KICAgIC8vIGFtbS9jb250cmFjdC5weToyNjQtMjY2CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIFR4bi5zZW5kZXIgPT0gc2VsZi5nb3Zlcm5vcgogICAgLy8gKSwgIk9ubHkgdGhlIGFjY291bnQgc2V0IGluIGdsb2JhbF9zdGF0ZS5nb3Zlcm5vciBtYXkgY2FsbCB0aGlzIG1ldGhvZCIKICAgIGFzc2VydCAvLyBPbmx5IHRoZSBhY2NvdW50IHNldCBpbiBnbG9iYWxfc3RhdGUuZ292ZXJub3IgbWF5IGNhbGwgdGhpcyBtZXRob2QKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uYm9vdHN0cmFwKHNlZWQ6IHVpbnQ2NCwgYV9hc3NldDogdWludDY0LCBiX2Fzc2V0OiB1aW50NjQpIC0+IHVpbnQ2NDoKYm9vdHN0cmFwOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjQ5LTUwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGJvb3RzdHJhcChzZWxmLCBzZWVkOiBndHhuLlBheW1lbnRUcmFuc2FjdGlvbiwgYV9hc3NldDogQXNzZXQsIGJfYXNzZXQ6IEFzc2V0KSAtPiBVSW50NjQ6CiAgICBwcm90byAzIDEKICAgIC8vIGFtbS9jb250cmFjdC5weTo2NgogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLnBvb2xfdG9rZW4sICJhcHBsaWNhdGlvbiBoYXMgYWxyZWFkeSBiZWVuIGJvb3RzdHJhcHBlZCIKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzgtMzkKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIHRoZSBQb29sIFRva2VuLCB1c2VkIHRvIHRyYWNrIHNoYXJlIG9mIHBvb2wgdGhlIGhvbGRlciBtYXkgcmVjb3ZlcgogICAgLy8gc2VsZi5wb29sX3Rva2VuID0gQXNzZXQoKQogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIC8vIGFtbS9jb250cmFjdC5weTo2NgogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLnBvb2xfdG9rZW4sICJhcHBsaWNhdGlvbiBoYXMgYWxyZWFkeSBiZWVuIGJvb3RzdHJhcHBlZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wb29sX3Rva2VuIGV4aXN0cwogICAgIQogICAgYXNzZXJ0IC8vIGFwcGxpY2F0aW9uIGhhcyBhbHJlYWR5IGJlZW4gYm9vdHN0cmFwcGVkCiAgICAvLyBhbW0vY29udHJhY3QucHk6NjcKICAgIC8vIHNlbGYuX2NoZWNrX2lzX2dvdmVybm9yKCkKICAgIGNhbGxzdWIgX2NoZWNrX2lzX2dvdmVybm9yCiAgICAvLyBhbW0vY29udHJhY3QucHk6NjgKICAgIC8vIGFzc2VydCBHbG9iYWwuZ3JvdXBfc2l6ZSA9PSAyLCAiZ3JvdXAgc2l6ZSBub3QgMiIKICAgIGdsb2JhbCBHcm91cFNpemUKICAgIGludCAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGdyb3VwIHNpemUgbm90IDIKICAgIC8vIGFtbS9jb250cmFjdC5weTo2OQogICAgLy8gYXNzZXJ0IHNlZWQucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywgInJlY2VpdmVyIG5vdCBhcHAgYWRkcmVzcyIKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgUmVjZWl2ZXIKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICA9PQogICAgYXNzZXJ0IC8vIHJlY2VpdmVyIG5vdCBhcHAgYWRkcmVzcwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjcxCiAgICAvLyBhc3NlcnQgc2VlZC5hbW91bnQgPj0gMzAwXzAwMCwgImFtb3VudCBtaW5pbXVtIG5vdCBtZXQiICAjIDAuMyBBbGdvcwogICAgZnJhbWVfZGlnIC0zCiAgICBndHhucyBBbW91bnQKICAgIGludCAzMDAwMDAKICAgID49CiAgICBhc3NlcnQgLy8gYW1vdW50IG1pbmltdW0gbm90IG1ldAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjcyCiAgICAvLyBhc3NlcnQgYV9hc3NldC5pZCA8IGJfYXNzZXQuaWQsICJhc3NldCBhIG11c3QgYmUgbGVzcyB0aGFuIGFzc2V0IGIiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPAogICAgYXNzZXJ0IC8vIGFzc2V0IGEgbXVzdCBiZSBsZXNzIHRoYW4gYXNzZXQgYgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMyLTMzCiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBBCiAgICAvLyBzZWxmLmFzc2V0X2EgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9hIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjczCiAgICAvLyBzZWxmLmFzc2V0X2EgPSBhX2Fzc2V0CiAgICBmcmFtZV9kaWcgLTIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzQtMzUKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIGFzc2V0IEIKICAgIC8vIHNlbGYuYXNzZXRfYiA9IEFzc2V0KCkKICAgIGJ5dGUgImFzc2V0X2IiCiAgICAvLyBhbW0vY29udHJhY3QucHk6NzQKICAgIC8vIHNlbGYuYXNzZXRfYiA9IGJfYXNzZXQKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFtbS9jb250cmFjdC5weTo3NQogICAgLy8gc2VsZi5wb29sX3Rva2VuID0gc2VsZi5fY3JlYXRlX3Bvb2xfdG9rZW4oKQogICAgY2FsbHN1YiBfY3JlYXRlX3Bvb2xfdG9rZW4KICAgIC8vIGFtbS9jb250cmFjdC5weTozOC0zOQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgdGhlIFBvb2wgVG9rZW4sIHVzZWQgdG8gdHJhY2sgc2hhcmUgb2YgcG9vbCB0aGUgaG9sZGVyIG1heSByZWNvdmVyCiAgICAvLyBzZWxmLnBvb2xfdG9rZW4gPSBBc3NldCgpCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyBzZWxmLnBvb2xfdG9rZW4gPSBzZWxmLl9jcmVhdGVfcG9vbF90b2tlbigpCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYW1tL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBzZWxmLl9kb19vcHRfaW4oc2VsZi5hc3NldF9hKQogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozMi0zMwogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQQogICAgLy8gc2VsZi5hc3NldF9hID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYSIKICAgIC8vIGFtbS9jb250cmFjdC5weTo3NwogICAgLy8gc2VsZi5fZG9fb3B0X2luKHNlbGYuYXNzZXRfYSkKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9hIGV4aXN0cwogICAgY2FsbHN1YiBfZG9fb3B0X2luCiAgICAvLyBhbW0vY29udHJhY3QucHk6NzgKICAgIC8vIHNlbGYuX2RvX29wdF9pbihzZWxmLmFzc2V0X2IpCiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM0LTM1CiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBCCiAgICAvLyBzZWxmLmFzc2V0X2IgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9iIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5Ojc4CiAgICAvLyBzZWxmLl9kb19vcHRfaW4oc2VsZi5hc3NldF9iKQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCiAgICBjYWxsc3ViIF9kb19vcHRfaW4KICAgIC8vIGFtbS9jb250cmFjdC5weTo3OQogICAgLy8gcmV0dXJuIHNlbGYucG9vbF90b2tlbi5pZAogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozOC0zOQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgdGhlIFBvb2wgVG9rZW4sIHVzZWQgdG8gdHJhY2sgc2hhcmUgb2YgcG9vbCB0aGUgaG9sZGVyIG1heSByZWNvdmVyCiAgICAvLyBzZWxmLnBvb2xfdG9rZW4gPSBBc3NldCgpCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyByZXR1cm4gc2VsZi5wb29sX3Rva2VuLmlkCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucG9vbF90b2tlbiBleGlzdHMKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uX2NyZWF0ZV9wb29sX3Rva2VuKCkgLT4gdWludDY0OgpfY3JlYXRlX3Bvb2xfdG9rZW46CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjY4LTI2OQogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBfY3JlYXRlX3Bvb2xfdG9rZW4oc2VsZikgLT4gQXNzZXQ6CiAgICBwcm90byAwIDEKICAgIC8vIGFtbS9jb250cmFjdC5weToyNzEtMjc5CiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgIGFzc2V0X25hbWU9YiJEUFQtIiArIHNlbGYuYXNzZXRfYS51bml0X25hbWUgKyBiIi0iICsgc2VsZi5hc3NldF9iLnVuaXRfbmFtZSwKICAgIC8vICAgICB1bml0X25hbWU9YiJkYnQiLAogICAgLy8gICAgIHRvdGFsPVRPVEFMX1NVUFBMWSwKICAgIC8vICAgICBkZWNpbWFscz0zLAogICAgLy8gICAgIG1hbmFnZXI9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIC8vICAgICByZXNlcnZlPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyApCiAgICAvLyAuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIC8vIGFtbS9jb250cmFjdC5weToyNzIKICAgIC8vIGFzc2V0X25hbWU9YiJEUFQtIiArIHNlbGYuYXNzZXRfYS51bml0X25hbWUgKyBiIi0iICsgc2VsZi5hc3NldF9iLnVuaXRfbmFtZSwKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzItMzMKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIGFzc2V0IEEKICAgIC8vIHNlbGYuYXNzZXRfYSA9IEFzc2V0KCkKICAgIGJ5dGUgImFzc2V0X2EiCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcyCiAgICAvLyBhc3NldF9uYW1lPWIiRFBULSIgKyBzZWxmLmFzc2V0X2EudW5pdF9uYW1lICsgYiItIiArIHNlbGYuYXNzZXRfYi51bml0X25hbWUsCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgIGFzc2V0X3BhcmFtc19nZXQgQXNzZXRVbml0TmFtZQogICAgYXNzZXJ0IC8vIGFzc2V0IGV4aXN0cwogICAgYnl0ZSAweDQ0NTA1NDJkCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgyZAogICAgY29uY2F0CiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM0LTM1CiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBCCiAgICAvLyBzZWxmLmFzc2V0X2IgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9iIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3MgogICAgLy8gYXNzZXRfbmFtZT1iIkRQVC0iICsgc2VsZi5hc3NldF9hLnVuaXRfbmFtZSArIGIiLSIgKyBzZWxmLmFzc2V0X2IudW5pdF9uYW1lLAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIGFzc2VydCAvLyBhc3NldCBleGlzdHMKICAgIGNvbmNhdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3NgogICAgLy8gbWFuYWdlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgIC8vIGFtbS9jb250cmFjdC5weToyNzcKICAgIC8vIHJlc2VydmU9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIGR1cAogICAgaXR4bl9maWVsZCBDb25maWdBc3NldFJlc2VydmUKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRNYW5hZ2VyCiAgICAvLyBhbW0vY29udHJhY3QucHk6Mjc1CiAgICAvLyBkZWNpbWFscz0zLAogICAgaW50IDMKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXREZWNpbWFscwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3NAogICAgLy8gdG90YWw9VE9UQUxfU1VQUExZLAogICAgaW50IDEwMDAwMDAwMDAwCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VG90YWwKICAgIC8vIGFtbS9jb250cmFjdC5weToyNzMKICAgIC8vIHVuaXRfbmFtZT1iImRidCIsCiAgICBieXRlIDB4NjQ2Mjc0CiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VW5pdE5hbWUKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXROYW1lCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcxCiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgaW50IGFjZmcKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3MS0yNzkKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICAvLyAgICAgYXNzZXRfbmFtZT1iIkRQVC0iICsgc2VsZi5hc3NldF9hLnVuaXRfbmFtZSArIGIiLSIgKyBzZWxmLmFzc2V0X2IudW5pdF9uYW1lLAogICAgLy8gICAgIHVuaXRfbmFtZT1iImRidCIsCiAgICAvLyAgICAgdG90YWw9VE9UQUxfU1VQUExZLAogICAgLy8gICAgIGRlY2ltYWxzPTMsCiAgICAvLyAgICAgbWFuYWdlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gICAgIHJlc2VydmU9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgaXR4bl9zdWJtaXQKICAgIC8vIGFtbS9jb250cmFjdC5weToyNzEtMjgwCiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgIGFzc2V0X25hbWU9YiJEUFQtIiArIHNlbGYuYXNzZXRfYS51bml0X25hbWUgKyBiIi0iICsgc2VsZi5hc3NldF9iLnVuaXRfbmFtZSwKICAgIC8vICAgICB1bml0X25hbWU9YiJkYnQiLAogICAgLy8gICAgIHRvdGFsPVRPVEFMX1NVUFBMWSwKICAgIC8vICAgICBkZWNpbWFscz0zLAogICAgLy8gICAgIG1hbmFnZXI9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIC8vICAgICByZXNlcnZlPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyApCiAgICAvLyAuc3VibWl0KCkKICAgIC8vIC5jcmVhdGVkX2Fzc2V0CiAgICBpdHhuIENyZWF0ZWRBc3NldElECiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcwLTI4MQogICAgLy8gcmV0dXJuICgKICAgIC8vICAgICBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgICAgICBhc3NldF9uYW1lPWIiRFBULSIgKyBzZWxmLmFzc2V0X2EudW5pdF9uYW1lICsgYiItIiArIHNlbGYuYXNzZXRfYi51bml0X25hbWUsCiAgICAvLyAgICAgICAgIHVuaXRfbmFtZT1iImRidCIsCiAgICAvLyAgICAgICAgIHRvdGFsPVRPVEFMX1NVUFBMWSwKICAgIC8vICAgICAgICAgZGVjaW1hbHM9MywKICAgIC8vICAgICAgICAgbWFuYWdlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gICAgICAgICByZXNlcnZlPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyAgICAgKQogICAgLy8gICAgIC5zdWJtaXQoKQogICAgLy8gICAgIC5jcmVhdGVkX2Fzc2V0CiAgICAvLyApCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9kb19vcHRfaW4oYXNzZXQ6IHVpbnQ2NCkgLT4gdm9pZDoKX2RvX29wdF9pbjoKICAgIC8vIGFtbS9jb250cmFjdC5weToyODMtMjg0CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9kb19vcHRfaW4oc2VsZiwgYXNzZXQ6IEFzc2V0KSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6Mjg2CiAgICAvLyByZWNlaXZlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgIC8vIGFtbS9jb250cmFjdC5weToyODUtMjg5CiAgICAvLyBkb19hc3NldF90cmFuc2ZlcigKICAgIC8vICAgICByZWNlaXZlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gICAgIGFzc2V0PWFzc2V0LAogICAgLy8gICAgIGFtb3VudD1VSW50NjQoMCksCiAgICAvLyApCiAgICBmcmFtZV9kaWcgLTEKICAgIC8vIGFtbS9jb250cmFjdC5weToyODgKICAgIC8vIGFtb3VudD1VSW50NjQoMCksCiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI4NS0yODkKICAgIC8vIGRvX2Fzc2V0X3RyYW5zZmVyKAogICAgLy8gICAgIHJlY2VpdmVyPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyAgICAgYXNzZXQ9YXNzZXQsCiAgICAvLyAgICAgYW1vdW50PVVJbnQ2NCgwKSwKICAgIC8vICkKICAgIGNhbGxzdWIgZG9fYXNzZXRfdHJhbnNmZXIKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5kb19hc3NldF90cmFuc2ZlcihyZWNlaXZlcjogYnl0ZXMsIGFzc2V0OiB1aW50NjQsIGFtb3VudDogdWludDY0KSAtPiB2b2lkOgpkb19hc3NldF90cmFuc2ZlcjoKICAgIC8vIGFtbS9jb250cmFjdC5weTozNTYtMzU3CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGRvX2Fzc2V0X3RyYW5zZmVyKCosIHJlY2VpdmVyOiBBY2NvdW50LCBhc3NldDogQXNzZXQsIGFtb3VudDogVUludDY0KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzU4LTM2MgogICAgLy8gaXR4bi5Bc3NldFRyYW5zZmVyKAogICAgLy8gICAgIHhmZXJfYXNzZXQ9YXNzZXQsCiAgICAvLyAgICAgYXNzZXRfYW1vdW50PWFtb3VudCwKICAgIC8vICAgICBhc3NldF9yZWNlaXZlcj1yZWNlaXZlciwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIGZyYW1lX2RpZyAtMwogICAgaXR4bl9maWVsZCBBc3NldFJlY2VpdmVyCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0eG5fZmllbGQgQXNzZXRBbW91bnQKICAgIGZyYW1lX2RpZyAtMgogICAgaXR4bl9maWVsZCBYZmVyQXNzZXQKICAgIC8vIGFtbS9jb250cmFjdC5weTozNTgKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIGludCBheGZlcgogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzU4LTM2MgogICAgLy8gaXR4bi5Bc3NldFRyYW5zZmVyKAogICAgLy8gICAgIHhmZXJfYXNzZXQ9YXNzZXQsCiAgICAvLyAgICAgYXNzZXRfYW1vdW50PWFtb3VudCwKICAgIC8vICAgICBhc3NldF9yZWNlaXZlcj1yZWNlaXZlciwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLm1pbnQoYV94ZmVyOiB1aW50NjQsIGJfeGZlcjogdWludDY0LCBwb29sX2Fzc2V0OiB1aW50NjQsIGFfYXNzZXQ6IHVpbnQ2NCwgYl9hc3NldDogdWludDY0KSAtPiB2b2lkOgptaW50OgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjgxLTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgInBvb2xfYXNzZXQiOiAicG9vbF90b2tlbiIsCiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgLy8gZGVmIG1pbnQoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBhX3hmZXI6IGd0eG4uQXNzZXRUcmFuc2ZlclRyYW5zYWN0aW9uLAogICAgLy8gICAgIGJfeGZlcjogZ3R4bi5Bc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24sCiAgICAvLyAgICAgcG9vbF9hc3NldDogQXNzZXQsCiAgICAvLyAgICAgYV9hc3NldDogQXNzZXQsCiAgICAvLyAgICAgYl9hc3NldDogQXNzZXQsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byA1IDAKICAgIC8vIGFtbS9jb250cmFjdC5weToxMTEKICAgIC8vIHNlbGYuX2NoZWNrX2Jvb3RzdHJhcHBlZCgpCiAgICBjYWxsc3ViIF9jaGVja19ib290c3RyYXBwZWQKICAgIC8vIGFtbS9jb250cmFjdC5weToxMTMtMTE0CiAgICAvLyAjIHdlbGwtZm9ybWVkIG1pbnQKICAgIC8vIGFzc2VydCBwb29sX2Fzc2V0ID09IHNlbGYucG9vbF90b2tlbiwgImFzc2V0IHBvb2wgaW5jb3JyZWN0IgogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozOC0zOQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgdGhlIFBvb2wgVG9rZW4sIHVzZWQgdG8gdHJhY2sgc2hhcmUgb2YgcG9vbCB0aGUgaG9sZGVyIG1heSByZWNvdmVyCiAgICAvLyBzZWxmLnBvb2xfdG9rZW4gPSBBc3NldCgpCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjExMy0xMTQKICAgIC8vICMgd2VsbC1mb3JtZWQgbWludAogICAgLy8gYXNzZXJ0IHBvb2xfYXNzZXQgPT0gc2VsZi5wb29sX3Rva2VuLCAiYXNzZXQgcG9vbCBpbmNvcnJlY3QiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucG9vbF90b2tlbiBleGlzdHMKICAgIGZyYW1lX2RpZyAtMwogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBwb29sIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjExNQogICAgLy8gYXNzZXJ0IGFfYXNzZXQgPT0gc2VsZi5hc3NldF9hLCAiYXNzZXQgYSBpbmNvcnJlY3QiCiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMyLTMzCiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBBCiAgICAvLyBzZWxmLmFzc2V0X2EgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9hIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjExNQogICAgLy8gYXNzZXJ0IGFfYXNzZXQgPT0gc2VsZi5hc3NldF9hLCAiYXNzZXQgYSBpbmNvcnJlY3QiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMgogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBhIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjExNgogICAgLy8gYXNzZXJ0IGJfYXNzZXQgPT0gc2VsZi5hc3NldF9iLCAiYXNzZXQgYiBpbmNvcnJlY3QiCiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM0LTM1CiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBCCiAgICAvLyBzZWxmLmFzc2V0X2IgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9iIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjExNgogICAgLy8gYXNzZXJ0IGJfYXNzZXQgPT0gc2VsZi5hc3NldF9iLCAiYXNzZXQgYiBpbmNvcnJlY3QiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYiBleGlzdHMKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBiIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjExNwogICAgLy8gYXNzZXJ0IGFfeGZlci5zZW5kZXIgPT0gVHhuLnNlbmRlciwgInNlbmRlciBpbnZhbGlkIgogICAgZnJhbWVfZGlnIC01CiAgICBndHhucyBTZW5kZXIKICAgIHR4biBTZW5kZXIKICAgID09CiAgICBhc3NlcnQgLy8gc2VuZGVyIGludmFsaWQKICAgIC8vIGFtbS9jb250cmFjdC5weToxMTgKICAgIC8vIGFzc2VydCBiX3hmZXIuc2VuZGVyID09IFR4bi5zZW5kZXIsICJzZW5kZXIgaW52YWxpZCIKICAgIGZyYW1lX2RpZyAtNAogICAgZ3R4bnMgU2VuZGVyCiAgICB0eG4gU2VuZGVyCiAgICA9PQogICAgYXNzZXJ0IC8vIHNlbmRlciBpbnZhbGlkCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTIyCiAgICAvLyBhX3hmZXIuYXNzZXRfcmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC01CiAgICBndHhucyBBc3NldFJlY2VpdmVyCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgPT0KICAgIC8vIGFtbS9jb250cmFjdC5weToxMjAtMTIzCiAgICAvLyAjIHZhbGlkIGFzc2V0IGEgeGZlcgogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBhX3hmZXIuYXNzZXRfcmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gKSwgInJlY2VpdmVyIG5vdCBhcHAgYWRkcmVzcyIKICAgIGFzc2VydCAvLyByZWNlaXZlciBub3QgYXBwIGFkZHJlc3MKICAgIC8vIGFtbS9jb250cmFjdC5weToxMjQKICAgIC8vIGFzc2VydCBhX3hmZXIueGZlcl9hc3NldCA9PSBzZWxmLmFzc2V0X2EsICJhc3NldCBhIGluY29ycmVjdCIKICAgIGZyYW1lX2RpZyAtNQogICAgZ3R4bnMgWGZlckFzc2V0CiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMyLTMzCiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBBCiAgICAvLyBzZWxmLmFzc2V0X2EgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9hIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjEyNAogICAgLy8gYXNzZXJ0IGFfeGZlci54ZmVyX2Fzc2V0ID09IHNlbGYuYXNzZXRfYSwgImFzc2V0IGEgaW5jb3JyZWN0IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2EgZXhpc3RzCiAgICA9PQogICAgYXNzZXJ0IC8vIGFzc2V0IGEgaW5jb3JyZWN0CiAgICAvLyBhbW0vY29udHJhY3QucHk6MTI1CiAgICAvLyBhc3NlcnQgYV94ZmVyLmFzc2V0X2Ftb3VudCA+IDAsICJhbW91bnQgbWluaW11bSBub3QgbWV0IgogICAgZnJhbWVfZGlnIC01CiAgICBndHhucyBBc3NldEFtb3VudAogICAgZHVwCiAgICBhc3NlcnQgLy8gYW1vdW50IG1pbmltdW0gbm90IG1ldAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjEyOQogICAgLy8gYl94ZmVyLmFzc2V0X3JlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIGZyYW1lX2RpZyAtNAogICAgZ3R4bnMgQXNzZXRSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyBhbW0vY29udHJhY3QucHk6MTI3LTEzMAogICAgLy8gIyB2YWxpZCBhc3NldCBiIHhmZXIKICAgIC8vIGFzc2VydCAoCiAgICAvLyAgICAgYl94ZmVyLmFzc2V0X3JlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICksICJyZWNlaXZlciBub3QgYXBwIGFkZHJlc3MiCiAgICBhc3NlcnQgLy8gcmVjZWl2ZXIgbm90IGFwcCBhZGRyZXNzCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTMxCiAgICAvLyBhc3NlcnQgYl94ZmVyLnhmZXJfYXNzZXQgPT0gc2VsZi5hc3NldF9iLCAiYXNzZXQgYiBpbmNvcnJlY3QiCiAgICBmcmFtZV9kaWcgLTQKICAgIGd0eG5zIFhmZXJBc3NldAogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozNC0zNQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQgogICAgLy8gc2VsZi5hc3NldF9iID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYiIKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzEKICAgIC8vIGFzc2VydCBiX3hmZXIueGZlcl9hc3NldCA9PSBzZWxmLmFzc2V0X2IsICJhc3NldCBiIGluY29ycmVjdCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9iIGV4aXN0cwogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBiIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjEzMgogICAgLy8gYXNzZXJ0IGJfeGZlci5hc3NldF9hbW91bnQgPiAwLCAiYW1vdW50IG1pbmltdW0gbm90IG1ldCIKICAgIGZyYW1lX2RpZyAtNAogICAgZ3R4bnMgQXNzZXRBbW91bnQKICAgIGR1cAogICAgYXNzZXJ0IC8vIGFtb3VudCBtaW5pbXVtIG5vdCBtZXQKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzUKICAgIC8vIHBvb2xfYmFsYW5jZT1zZWxmLl9jdXJyZW50X3Bvb2xfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9wb29sX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzYKICAgIC8vIGFfYmFsYW5jZT1zZWxmLl9jdXJyZW50X2FfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9hX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzcKICAgIC8vIGJfYmFsYW5jZT1zZWxmLl9jdXJyZW50X2JfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9iX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzQtMTQwCiAgICAvLyB0b19taW50ID0gdG9rZW5zX3RvX21pbnQoCiAgICAvLyAgICAgcG9vbF9iYWxhbmNlPXNlbGYuX2N1cnJlbnRfcG9vbF9iYWxhbmNlKCksCiAgICAvLyAgICAgYV9iYWxhbmNlPXNlbGYuX2N1cnJlbnRfYV9iYWxhbmNlKCksCiAgICAvLyAgICAgYl9iYWxhbmNlPXNlbGYuX2N1cnJlbnRfYl9iYWxhbmNlKCksCiAgICAvLyAgICAgYV9hbW91bnQ9YV94ZmVyLmFzc2V0X2Ftb3VudCwKICAgIC8vICAgICBiX2Ftb3VudD1iX3hmZXIuYXNzZXRfYW1vdW50LAogICAgLy8gKQogICAgdW5jb3ZlciA0CiAgICB1bmNvdmVyIDQKICAgIGNhbGxzdWIgdG9rZW5zX3RvX21pbnQKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDEKICAgIC8vIGFzc2VydCB0b19taW50ID4gMCwgInNlbmQgYW1vdW50IHRvbyBsb3ciCiAgICBkdXAKICAgIGFzc2VydCAvLyBzZW5kIGFtb3VudCB0b28gbG93CiAgICAvLyBhbW0vY29udHJhY3QucHk6MTQzLTE0NAogICAgLy8gIyBtaW50IHRva2VucwogICAgLy8gZG9fYXNzZXRfdHJhbnNmZXIocmVjZWl2ZXI9VHhuLnNlbmRlciwgYXNzZXQ9c2VsZi5wb29sX3Rva2VuLCBhbW91bnQ9dG9fbWludCkKICAgIHR4biBTZW5kZXIKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzgtMzkKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIHRoZSBQb29sIFRva2VuLCB1c2VkIHRvIHRyYWNrIHNoYXJlIG9mIHBvb2wgdGhlIGhvbGRlciBtYXkgcmVjb3ZlcgogICAgLy8gc2VsZi5wb29sX3Rva2VuID0gQXNzZXQoKQogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDMtMTQ0CiAgICAvLyAjIG1pbnQgdG9rZW5zCiAgICAvLyBkb19hc3NldF90cmFuc2ZlcihyZWNlaXZlcj1UeG4uc2VuZGVyLCBhc3NldD1zZWxmLnBvb2xfdG9rZW4sIGFtb3VudD10b19taW50KQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnBvb2xfdG9rZW4gZXhpc3RzCiAgICB1bmNvdmVyIDIKICAgIGNhbGxzdWIgZG9fYXNzZXRfdHJhbnNmZXIKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDUKICAgIC8vIHNlbGYuX3VwZGF0ZV9yYXRpbygpCiAgICBjYWxsc3ViIF91cGRhdGVfcmF0aW8KICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uX2NoZWNrX2Jvb3RzdHJhcHBlZCgpIC0+IHZvaWQ6Cl9jaGVja19ib290c3RyYXBwZWQ6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjUxLTI1MgogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBfY2hlY2tfYm9vdHN0cmFwcGVkKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGFtbS9jb250cmFjdC5weToyNTMKICAgIC8vIGFzc2VydCBzZWxmLnBvb2xfdG9rZW4sICJib290c3RyYXAgbWV0aG9kIG5lZWRzIHRvIGJlIGNhbGxlZCBmaXJzdCIKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzgtMzkKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIHRoZSBQb29sIFRva2VuLCB1c2VkIHRvIHRyYWNrIHNoYXJlIG9mIHBvb2wgdGhlIGhvbGRlciBtYXkgcmVjb3ZlcgogICAgLy8gc2VsZi5wb29sX3Rva2VuID0gQXNzZXQoKQogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIC8vIGFtbS9jb250cmFjdC5weToyNTMKICAgIC8vIGFzc2VydCBzZWxmLnBvb2xfdG9rZW4sICJib290c3RyYXAgbWV0aG9kIG5lZWRzIHRvIGJlIGNhbGxlZCBmaXJzdCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wb29sX3Rva2VuIGV4aXN0cwogICAgYXNzZXJ0IC8vIGJvb3RzdHJhcCBtZXRob2QgbmVlZHMgdG8gYmUgY2FsbGVkIGZpcnN0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9jdXJyZW50X3Bvb2xfYmFsYW5jZSgpIC0+IHVpbnQ2NDoKX2N1cnJlbnRfcG9vbF9iYWxhbmNlOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI5MS0yOTIKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgX2N1cnJlbnRfcG9vbF9iYWxhbmNlKHNlbGYpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDAgMQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI5MwogICAgLy8gcmV0dXJuIHNlbGYucG9vbF90b2tlbi5iYWxhbmNlKEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MpCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozOC0zOQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgdGhlIFBvb2wgVG9rZW4sIHVzZWQgdG8gdHJhY2sgc2hhcmUgb2YgcG9vbCB0aGUgaG9sZGVyIG1heSByZWNvdmVyCiAgICAvLyBzZWxmLnBvb2xfdG9rZW4gPSBBc3NldCgpCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI5MwogICAgLy8gcmV0dXJuIHNlbGYucG9vbF90b2tlbi5iYWxhbmNlKEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MpCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucG9vbF90b2tlbiBleGlzdHMKICAgIGFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgb3B0ZWQgaW50byBhc3NldAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYW1tLmNvbnRyYWN0LkNvbnN0YW50UHJvZHVjdEFNTS5fY3VycmVudF9hX2JhbGFuY2UoKSAtPiB1aW50NjQ6Cl9jdXJyZW50X2FfYmFsYW5jZToKICAgIC8vIGFtbS9jb250cmFjdC5weToyOTUtMjk2CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9jdXJyZW50X2FfYmFsYW5jZShzZWxmKSAtPiBVSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGFtbS9jb250cmFjdC5weToyOTcKICAgIC8vIHJldHVybiBzZWxmLmFzc2V0X2EuYmFsYW5jZShHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzKQogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzItMzMKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIGFzc2V0IEEKICAgIC8vIHNlbGYuYXNzZXRfYSA9IEFzc2V0KCkKICAgIGJ5dGUgImFzc2V0X2EiCiAgICAvLyBhbW0vY29udHJhY3QucHk6Mjk3CiAgICAvLyByZXR1cm4gc2VsZi5hc3NldF9hLmJhbGFuY2UoR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcykKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9hIGV4aXN0cwogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRCYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBvcHRlZCBpbnRvIGFzc2V0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9jdXJyZW50X2JfYmFsYW5jZSgpIC0+IHVpbnQ2NDoKX2N1cnJlbnRfYl9iYWxhbmNlOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI5OS0zMDAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgX2N1cnJlbnRfYl9iYWxhbmNlKHNlbGYpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDAgMQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMwMQogICAgLy8gcmV0dXJuIHNlbGYuYXNzZXRfYi5iYWxhbmNlKEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MpCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozNC0zNQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQgogICAgLy8gc2VsZi5hc3NldF9iID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYiIKICAgIC8vIGFtbS9jb250cmFjdC5weTozMDEKICAgIC8vIHJldHVybiBzZWxmLmFzc2V0X2IuYmFsYW5jZShHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzKQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCiAgICBhc3NldF9ob2xkaW5nX2dldCBBc3NldEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IG9wdGVkIGludG8gYXNzZXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC50b2tlbnNfdG9fbWludChwb29sX2JhbGFuY2U6IHVpbnQ2NCwgYV9iYWxhbmNlOiB1aW50NjQsIGJfYmFsYW5jZTogdWludDY0LCBhX2Ftb3VudDogdWludDY0LCBiX2Ftb3VudDogdWludDY0KSAtPiB1aW50NjQ6CnRva2Vuc190b19taW50OgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMyMi0zMzAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgdG9rZW5zX3RvX21pbnQoCiAgICAvLyAgICAgKiwKICAgIC8vICAgICBwb29sX2JhbGFuY2U6IFVJbnQ2NCwKICAgIC8vICAgICBhX2JhbGFuY2U6IFVJbnQ2NCwKICAgIC8vICAgICBiX2JhbGFuY2U6IFVJbnQ2NCwKICAgIC8vICAgICBhX2Ftb3VudDogVUludDY0LAogICAgLy8gICAgIGJfYW1vdW50OiBVSW50NjQsCiAgICAvLyApIC0+IFVJbnQ2NDoKICAgIHByb3RvIDUgMQogICAgYnl0ZSAiIgogICAgZHVwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzMxCiAgICAvLyBpc19pbml0aWFsX21pbnQgPSBhX2JhbGFuY2UgPT0gYV9hbW91bnQgYW5kIGJfYmFsYW5jZSA9PSBiX2Ftb3VudAogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTIKICAgID09CiAgICBieiB0b2tlbnNfdG9fbWludF9ib29sX2ZhbHNlQDMKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgYnogdG9rZW5zX3RvX21pbnRfYm9vbF9mYWxzZUAzCiAgICBpbnQgMQogICAgYiB0b2tlbnNfdG9fbWludF9ib29sX21lcmdlQDQKCnRva2Vuc190b19taW50X2Jvb2xfZmFsc2VAMzoKICAgIGludCAwCgp0b2tlbnNfdG9fbWludF9ib29sX21lcmdlQDQ6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzMyCiAgICAvLyBpZiBpc19pbml0aWFsX21pbnQ6CiAgICBieiB0b2tlbnNfdG9fbWludF9hZnRlcl9pZl9lbHNlQDYKICAgIC8vIGFtbS9jb250cmFjdC5weTozMzMKICAgIC8vIHJldHVybiBvcC5zcXJ0KGFfYW1vdW50ICogYl9hbW91bnQpIC0gU0NBTEUKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICBzcXJ0CiAgICBpbnQgMTAwMAogICAgLQogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCnRva2Vuc190b19taW50X2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIGFtbS9jb250cmFjdC5weTozMzQKICAgIC8vIGlzc3VlZCA9IFRPVEFMX1NVUFBMWSAtIHBvb2xfYmFsYW5jZQogICAgaW50IDEwMDAwMDAwMDAwCiAgICBmcmFtZV9kaWcgLTUKICAgIC0KICAgIC8vIGFtbS9jb250cmFjdC5weTozMzUKICAgIC8vIGFfcmF0aW8gPSBTQ0FMRSAqIGFfYW1vdW50IC8vIChhX2JhbGFuY2UgLSBhX2Ftb3VudCkKICAgIGludCAxMDAwCiAgICBmcmFtZV9kaWcgLTIKICAgICoKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0yCiAgICAtCiAgICAvCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMzNgogICAgLy8gYl9yYXRpbyA9IFNDQUxFICogYl9hbW91bnQgLy8gKGJfYmFsYW5jZSAtIGJfYW1vdW50KQogICAgaW50IDEwMDAKICAgIGZyYW1lX2RpZyAtMQogICAgKgogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTEKICAgIC0KICAgIC8KICAgIGR1cAogICAgZnJhbWVfYnVyeSAxCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzM3CiAgICAvLyBpZiBhX3JhdGlvIDwgYl9yYXRpbzoKICAgIDwKICAgIGJ6IHRva2Vuc190b19taW50X2Vsc2VfYm9keUA4CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzM4CiAgICAvLyByZXR1cm4gYV9yYXRpbyAqIGlzc3VlZCAvLyBTQ0FMRQogICAgZnJhbWVfZGlnIDAKICAgICoKICAgIGludCAxMDAwCiAgICAvCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKdG9rZW5zX3RvX21pbnRfZWxzZV9ib2R5QDg6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzQwCiAgICAvLyByZXR1cm4gYl9yYXRpbyAqIGlzc3VlZCAvLyBTQ0FMRQogICAgZnJhbWVfZGlnIDEKICAgICoKICAgIGludCAxMDAwCiAgICAvCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uX3VwZGF0ZV9yYXRpbygpIC0+IHZvaWQ6Cl91cGRhdGVfcmF0aW86CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjU1LTI1NgogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBfdXBkYXRlX3JhdGlvKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGFtbS9jb250cmFjdC5weToyNTcKICAgIC8vIGFfYmFsYW5jZSA9IHNlbGYuX2N1cnJlbnRfYV9iYWxhbmNlKCkKICAgIGNhbGxzdWIgX2N1cnJlbnRfYV9iYWxhbmNlCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjU4CiAgICAvLyBiX2JhbGFuY2UgPSBzZWxmLl9jdXJyZW50X2JfYmFsYW5jZSgpCiAgICBjYWxsc3ViIF9jdXJyZW50X2JfYmFsYW5jZQogICAgc3dhcAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI2MAogICAgLy8gc2VsZi5yYXRpbyA9IGFfYmFsYW5jZSAqIFNDQUxFIC8vIGJfYmFsYW5jZQogICAgaW50IDEwMDAKICAgICoKICAgIHN3YXAKICAgIC8KICAgIC8vIGFtbS9jb250cmFjdC5weTo0MC00MQogICAgLy8gIyBUaGUgcmF0aW8gYmV0d2VlbiBhc3NldHMgKEEqU2NhbGUvQikKICAgIC8vIHNlbGYucmF0aW8gPSBVSW50NjQoMCkKICAgIGJ5dGUgInJhdGlvIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI2MAogICAgLy8gc2VsZi5yYXRpbyA9IGFfYmFsYW5jZSAqIFNDQUxFIC8vIGJfYmFsYW5jZQogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uYnVybihwb29sX3hmZXI6IHVpbnQ2NCwgcG9vbF9hc3NldDogdWludDY0LCBhX2Fzc2V0OiB1aW50NjQsIGJfYXNzZXQ6IHVpbnQ2NCkgLT4gdm9pZDoKYnVybjoKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDctMTYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgInBvb2xfYXNzZXQiOiAicG9vbF90b2tlbiIsCiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgLy8gZGVmIGJ1cm4oCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBwb29sX3hmZXI6IGd0eG4uQXNzZXRUcmFuc2ZlclRyYW5zYWN0aW9uLAogICAgLy8gICAgIHBvb2xfYXNzZXQ6IEFzc2V0LAogICAgLy8gICAgIGFfYXNzZXQ6IEFzc2V0LAogICAgLy8gICAgIGJfYXNzZXQ6IEFzc2V0LAogICAgLy8gKSAtPiBOb25lOgogICAgcHJvdG8gNCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTcwCiAgICAvLyBzZWxmLl9jaGVja19ib290c3RyYXBwZWQoKQogICAgY2FsbHN1YiBfY2hlY2tfYm9vdHN0cmFwcGVkCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTcyCiAgICAvLyBhc3NlcnQgcG9vbF9hc3NldCA9PSBzZWxmLnBvb2xfdG9rZW4sICJhc3NldCBwb29sIGluY29ycmVjdCIKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzgtMzkKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIHRoZSBQb29sIFRva2VuLCB1c2VkIHRvIHRyYWNrIHNoYXJlIG9mIHBvb2wgdGhlIGhvbGRlciBtYXkgcmVjb3ZlcgogICAgLy8gc2VsZi5wb29sX3Rva2VuID0gQXNzZXQoKQogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIC8vIGFtbS9jb250cmFjdC5weToxNzIKICAgIC8vIGFzc2VydCBwb29sX2Fzc2V0ID09IHNlbGYucG9vbF90b2tlbiwgImFzc2V0IHBvb2wgaW5jb3JyZWN0IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnBvb2xfdG9rZW4gZXhpc3RzCiAgICBmcmFtZV9kaWcgLTMKICAgID09CiAgICBhc3NlcnQgLy8gYXNzZXQgcG9vbCBpbmNvcnJlY3QKICAgIC8vIGFtbS9jb250cmFjdC5weToxNzMKICAgIC8vIGFzc2VydCBhX2Fzc2V0ID09IHNlbGYuYXNzZXRfYSwgImFzc2V0IGEgaW5jb3JyZWN0IgogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozMi0zMwogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQQogICAgLy8gc2VsZi5hc3NldF9hID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYSIKICAgIC8vIGFtbS9jb250cmFjdC5weToxNzMKICAgIC8vIGFzc2VydCBhX2Fzc2V0ID09IHNlbGYuYXNzZXRfYSwgImFzc2V0IGEgaW5jb3JyZWN0IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2EgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTIKICAgID09CiAgICBhc3NlcnQgLy8gYXNzZXQgYSBpbmNvcnJlY3QKICAgIC8vIGFtbS9jb250cmFjdC5weToxNzQKICAgIC8vIGFzc2VydCBiX2Fzc2V0ID09IHNlbGYuYXNzZXRfYiwgImFzc2V0IGIgaW5jb3JyZWN0IgogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozNC0zNQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQgogICAgLy8gc2VsZi5hc3NldF9iID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYiIKICAgIC8vIGFtbS9jb250cmFjdC5weToxNzQKICAgIC8vIGFzc2VydCBiX2Fzc2V0ID09IHNlbGYuYXNzZXRfYiwgImFzc2V0IGIgaW5jb3JyZWN0IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTEKICAgID09CiAgICBhc3NlcnQgLy8gYXNzZXQgYiBpbmNvcnJlY3QKICAgIC8vIGFtbS9jb250cmFjdC5weToxNzcKICAgIC8vIHBvb2xfeGZlci5hc3NldF9yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzCiAgICBmcmFtZV9kaWcgLTQKICAgIGd0eG5zIEFzc2V0UmVjZWl2ZXIKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICA9PQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjE3Ni0xNzgKICAgIC8vIGFzc2VydCAoCiAgICAvLyAgICAgcG9vbF94ZmVyLmFzc2V0X3JlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICksICJyZWNlaXZlciBub3QgYXBwIGFkZHJlc3MiCiAgICBhc3NlcnQgLy8gcmVjZWl2ZXIgbm90IGFwcCBhZGRyZXNzCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTc5CiAgICAvLyBhc3NlcnQgcG9vbF94ZmVyLmFzc2V0X2Ftb3VudCA+IDAsICJhbW91bnQgbWluaW11bSBub3QgbWV0IgogICAgZnJhbWVfZGlnIC00CiAgICBndHhucyBBc3NldEFtb3VudAogICAgZHVwCiAgICBhc3NlcnQgLy8gYW1vdW50IG1pbmltdW0gbm90IG1ldAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjE4MAogICAgLy8gYXNzZXJ0IHBvb2xfeGZlci54ZmVyX2Fzc2V0ID09IHNlbGYucG9vbF90b2tlbiwgImFzc2V0IHBvb2wgaW5jb3JyZWN0IgogICAgZnJhbWVfZGlnIC00CiAgICBndHhucyBYZmVyQXNzZXQKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzgtMzkKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIHRoZSBQb29sIFRva2VuLCB1c2VkIHRvIHRyYWNrIHNoYXJlIG9mIHBvb2wgdGhlIGhvbGRlciBtYXkgcmVjb3ZlcgogICAgLy8gc2VsZi5wb29sX3Rva2VuID0gQXNzZXQoKQogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIC8vIGFtbS9jb250cmFjdC5weToxODAKICAgIC8vIGFzc2VydCBwb29sX3hmZXIueGZlcl9hc3NldCA9PSBzZWxmLnBvb2xfdG9rZW4sICJhc3NldCBwb29sIGluY29ycmVjdCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wb29sX3Rva2VuIGV4aXN0cwogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBwb29sIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjE4MQogICAgLy8gYXNzZXJ0IHBvb2xfeGZlci5zZW5kZXIgPT0gVHhuLnNlbmRlciwgInNlbmRlciBpbnZhbGlkIgogICAgZnJhbWVfZGlnIC00CiAgICBndHhucyBTZW5kZXIKICAgIHR4biBTZW5kZXIKICAgID09CiAgICBhc3NlcnQgLy8gc2VuZGVyIGludmFsaWQKICAgIC8vIGFtbS9jb250cmFjdC5weToxODMtMTg1CiAgICAvLyAjIEdldCB0aGUgdG90YWwgbnVtYmVyIG9mIHRva2VucyBpc3N1ZWQKICAgIC8vICMgIWltcG9ydGFudDogdGhpcyBoYXBwZW5zIHByaW9yIHRvIHJlY2VpdmluZyB0aGUgY3VycmVudCBheGZlciBvZiBwb29sIHRva2VucwogICAgLy8gcG9vbF9iYWxhbmNlID0gc2VsZi5fY3VycmVudF9wb29sX2JhbGFuY2UoKQogICAgY2FsbHN1YiBfY3VycmVudF9wb29sX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxODgKICAgIC8vIHN1cHBseT1zZWxmLl9jdXJyZW50X2FfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9hX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxODYtMTkwCiAgICAvLyBhX2FtdCA9IHRva2Vuc190b19idXJuKAogICAgLy8gICAgIHBvb2xfYmFsYW5jZT1wb29sX2JhbGFuY2UsCiAgICAvLyAgICAgc3VwcGx5PXNlbGYuX2N1cnJlbnRfYV9iYWxhbmNlKCksCiAgICAvLyAgICAgYW1vdW50PXBvb2xfeGZlci5hc3NldF9hbW91bnQsCiAgICAvLyApCiAgICBkaWcgMQogICAgc3dhcAogICAgZGlnIDMKICAgIGNhbGxzdWIgdG9rZW5zX3RvX2J1cm4KICAgIGNvdmVyIDIKICAgIC8vIGFtbS9jb250cmFjdC5weToxOTMKICAgIC8vIHN1cHBseT1zZWxmLl9jdXJyZW50X2JfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9iX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxOTEtMTk1CiAgICAvLyBiX2FtdCA9IHRva2Vuc190b19idXJuKAogICAgLy8gICAgIHBvb2xfYmFsYW5jZT1wb29sX2JhbGFuY2UsCiAgICAvLyAgICAgc3VwcGx5PXNlbGYuX2N1cnJlbnRfYl9iYWxhbmNlKCksCiAgICAvLyAgICAgYW1vdW50PXBvb2xfeGZlci5hc3NldF9hbW91bnQsCiAgICAvLyApCiAgICB1bmNvdmVyIDIKICAgIGNhbGxzdWIgdG9rZW5zX3RvX2J1cm4KICAgIHN3YXAKICAgIC8vIGFtbS9jb250cmFjdC5weToxOTctMTk4CiAgICAvLyAjIFNlbmQgYmFjayBjb21tZW5zdXJhdGUgYW10IG9mIGEKICAgIC8vIGRvX2Fzc2V0X3RyYW5zZmVyKHJlY2VpdmVyPVR4bi5zZW5kZXIsIGFzc2V0PXNlbGYuYXNzZXRfYSwgYW1vdW50PWFfYW10KQogICAgdHhuIFNlbmRlcgogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozMi0zMwogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQQogICAgLy8gc2VsZi5hc3NldF9hID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYSIKICAgIC8vIGFtbS9jb250cmFjdC5weToxOTctMTk4CiAgICAvLyAjIFNlbmQgYmFjayBjb21tZW5zdXJhdGUgYW10IG9mIGEKICAgIC8vIGRvX2Fzc2V0X3RyYW5zZmVyKHJlY2VpdmVyPVR4bi5zZW5kZXIsIGFzc2V0PXNlbGYuYXNzZXRfYSwgYW1vdW50PWFfYW10KQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2EgZXhpc3RzCiAgICB1bmNvdmVyIDIKICAgIGNhbGxzdWIgZG9fYXNzZXRfdHJhbnNmZXIKICAgIC8vIGFtbS9jb250cmFjdC5weToyMDAtMjAxCiAgICAvLyAjIFNlbmQgYmFjayBjb21tZW5zdXJhdGUgYW10IG9mIGIKICAgIC8vIGRvX2Fzc2V0X3RyYW5zZmVyKHJlY2VpdmVyPVR4bi5zZW5kZXIsIGFzc2V0PXNlbGYuYXNzZXRfYiwgYW1vdW50PWJfYW10KQogICAgdHhuIFNlbmRlcgogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozNC0zNQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQgogICAgLy8gc2VsZi5hc3NldF9iID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYiIKICAgIC8vIGFtbS9jb250cmFjdC5weToyMDAtMjAxCiAgICAvLyAjIFNlbmQgYmFjayBjb21tZW5zdXJhdGUgYW10IG9mIGIKICAgIC8vIGRvX2Fzc2V0X3RyYW5zZmVyKHJlY2VpdmVyPVR4bi5zZW5kZXIsIGFzc2V0PXNlbGYuYXNzZXRfYiwgYW1vdW50PWJfYW10KQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCiAgICB1bmNvdmVyIDIKICAgIGNhbGxzdWIgZG9fYXNzZXRfdHJhbnNmZXIKICAgIC8vIGFtbS9jb250cmFjdC5weToyMDIKICAgIC8vIHNlbGYuX3VwZGF0ZV9yYXRpbygpCiAgICBjYWxsc3ViIF91cGRhdGVfcmF0aW8KICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC50b2tlbnNfdG9fYnVybihwb29sX2JhbGFuY2U6IHVpbnQ2NCwgc3VwcGx5OiB1aW50NjQsIGFtb3VudDogdWludDY0KSAtPiB1aW50NjQ6CnRva2Vuc190b19idXJuOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM0My0zNDQKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgdG9rZW5zX3RvX2J1cm4oKiwgcG9vbF9iYWxhbmNlOiBVSW50NjQsIHN1cHBseTogVUludDY0LCBhbW91bnQ6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzQ1CiAgICAvLyBpc3N1ZWQgPSBUT1RBTF9TVVBQTFkgLSBwb29sX2JhbGFuY2UgLSBhbW91bnQKICAgIGludCAxMDAwMDAwMDAwMAogICAgZnJhbWVfZGlnIC0zCiAgICAtCiAgICBmcmFtZV9kaWcgLTEKICAgIC0KICAgIC8vIGFtbS9jb250cmFjdC5weTozNDYKICAgIC8vIHJldHVybiBzdXBwbHkgKiBhbW91bnQgLy8gaXNzdWVkCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgKgogICAgc3dhcAogICAgLwogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYW1tLmNvbnRyYWN0LkNvbnN0YW50UHJvZHVjdEFNTS5zd2FwKHN3YXBfeGZlcjogdWludDY0LCBhX2Fzc2V0OiB1aW50NjQsIGJfYXNzZXQ6IHVpbnQ2NCkgLT4gdm9pZDoKc3dhcDoKICAgIC8vIGFtbS9jb250cmFjdC5weToyMDQtMjE1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgImFfYXNzZXQiOiAiYXNzZXRfYSIsCiAgICAvLyAgICAgICAgICJiX2Fzc2V0IjogImFzc2V0X2IiLAogICAgLy8gICAgIH0sCiAgICAvLyApCiAgICAvLyBkZWYgc3dhcCgKICAgIC8vICAgICBzZWxmLAogICAgLy8gICAgIHN3YXBfeGZlcjogZ3R4bi5Bc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24sCiAgICAvLyAgICAgYV9hc3NldDogQXNzZXQsCiAgICAvLyAgICAgYl9hc3NldDogQXNzZXQsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIGJ5dGUgIiIKICAgIGR1cAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIyMwogICAgLy8gc2VsZi5fY2hlY2tfYm9vdHN0cmFwcGVkKCkKICAgIGNhbGxzdWIgX2NoZWNrX2Jvb3RzdHJhcHBlZAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIyNQogICAgLy8gYXNzZXJ0IGFfYXNzZXQgPT0gc2VsZi5hc3NldF9hLCAiYXNzZXQgYSBpbmNvcnJlY3QiCiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMyLTMzCiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBBCiAgICAvLyBzZWxmLmFzc2V0X2EgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9hIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIyNQogICAgLy8gYXNzZXJ0IGFfYXNzZXQgPT0gc2VsZi5hc3NldF9hLCAiYXNzZXQgYSBpbmNvcnJlY3QiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMgogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBhIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIyNgogICAgLy8gYXNzZXJ0IGJfYXNzZXQgPT0gc2VsZi5hc3NldF9iLCAiYXNzZXQgYiBpbmNvcnJlY3QiCiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM0LTM1CiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBCCiAgICAvLyBzZWxmLmFzc2V0X2IgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9iIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIyNgogICAgLy8gYXNzZXJ0IGJfYXNzZXQgPT0gc2VsZi5hc3NldF9iLCAiYXNzZXQgYiBpbmNvcnJlY3QiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYiBleGlzdHMKICAgIGZyYW1lX2RpZyAtMQogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBiIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIyOAogICAgLy8gYXNzZXJ0IHN3YXBfeGZlci5hc3NldF9hbW91bnQgPiAwLCAiYW1vdW50IG1pbmltdW0gbm90IG1ldCIKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgQXNzZXRBbW91bnQKICAgIGR1cAogICAgYXNzZXJ0IC8vIGFtb3VudCBtaW5pbXVtIG5vdCBtZXQKICAgIC8vIGFtbS9jb250cmFjdC5weToyMjkKICAgIC8vIGFzc2VydCBzd2FwX3hmZXIuc2VuZGVyID09IFR4bi5zZW5kZXIsICJzZW5kZXIgaW52YWxpZCIKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgU2VuZGVyCiAgICB0eG4gU2VuZGVyCiAgICA9PQogICAgYXNzZXJ0IC8vIHNlbmRlciBpbnZhbGlkCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjMyCiAgICAvLyBjYXNlIHNlbGYuYXNzZXRfYToKICAgIGludCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzItMzMKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIGFzc2V0IEEKICAgIC8vIHNlbGYuYXNzZXRfYSA9IEFzc2V0KCkKICAgIGJ5dGUgImFzc2V0X2EiCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjMyCiAgICAvLyBjYXNlIHNlbGYuYXNzZXRfYToKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9hIGV4aXN0cwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIzNgogICAgLy8gY2FzZSBzZWxmLmFzc2V0X2I6CiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM0LTM1CiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBCCiAgICAvLyBzZWxmLmFzc2V0X2IgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9iIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIzNgogICAgLy8gY2FzZSBzZWxmLmFzc2V0X2I6CiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYiBleGlzdHMKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzEKICAgIC8vIG1hdGNoIHN3YXBfeGZlci54ZmVyX2Fzc2V0OgogICAgZnJhbWVfZGlnIC0zCiAgICBndHhucyBYZmVyQXNzZXQKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzEtMjQxCiAgICAvLyBtYXRjaCBzd2FwX3hmZXIueGZlcl9hc3NldDoKICAgIC8vICAgICBjYXNlIHNlbGYuYXNzZXRfYToKICAgIC8vICAgICAgICAgaW5fc3VwcGx5ID0gc2VsZi5fY3VycmVudF9iX2JhbGFuY2UoKQogICAgLy8gICAgICAgICBvdXRfc3VwcGx5ID0gc2VsZi5fY3VycmVudF9hX2JhbGFuY2UoKQogICAgLy8gICAgICAgICBvdXRfYXNzZXQgPSBzZWxmLmFzc2V0X2EKICAgIC8vICAgICBjYXNlIHNlbGYuYXNzZXRfYjoKICAgIC8vICAgICAgICAgaW5fc3VwcGx5ID0gc2VsZi5fY3VycmVudF9hX2JhbGFuY2UoKQogICAgLy8gICAgICAgICBvdXRfc3VwcGx5ID0gc2VsZi5fY3VycmVudF9iX2JhbGFuY2UoKQogICAgLy8gICAgICAgICBvdXRfYXNzZXQgPSBzZWxmLmFzc2V0X2IKICAgIC8vICAgICBjYXNlIF86CiAgICAvLyAgICAgICAgIGFzc2VydCBGYWxzZSwgImFzc2V0IGlkIGluY29ycmVjdCIKICAgIG1hdGNoIHN3YXBfc3dpdGNoX2Nhc2VfMEAxIHN3YXBfc3dpdGNoX2Nhc2VfMUAyCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjQxCiAgICAvLyBhc3NlcnQgRmFsc2UsICJhc3NldCBpZCBpbmNvcnJlY3QiCiAgICBlcnIgLy8gYXNzZXQgaWQgaW5jb3JyZWN0Cgpzd2FwX3N3aXRjaF9jYXNlXzBAMToKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzMKICAgIC8vIGluX3N1cHBseSA9IHNlbGYuX2N1cnJlbnRfYl9iYWxhbmNlKCkKICAgIGNhbGxzdWIgX2N1cnJlbnRfYl9iYWxhbmNlCiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzQKICAgIC8vIG91dF9zdXBwbHkgPSBzZWxmLl9jdXJyZW50X2FfYmFsYW5jZSgpCiAgICBjYWxsc3ViIF9jdXJyZW50X2FfYmFsYW5jZQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIzNQogICAgLy8gb3V0X2Fzc2V0ID0gc2VsZi5hc3NldF9hCiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMyLTMzCiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBBCiAgICAvLyBzZWxmLmFzc2V0X2EgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9hIgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIzNQogICAgLy8gb3V0X2Fzc2V0ID0gc2VsZi5hc3NldF9hCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgc3dhcAogICAgZnJhbWVfYnVyeSAxCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9hIGV4aXN0cwogICAgYiBzd2FwX3N3aXRjaF9jYXNlX25leHRANAoKc3dhcF9zd2l0Y2hfY2FzZV8xQDI6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjM3CiAgICAvLyBpbl9zdXBwbHkgPSBzZWxmLl9jdXJyZW50X2FfYmFsYW5jZSgpCiAgICBjYWxsc3ViIF9jdXJyZW50X2FfYmFsYW5jZQogICAgZnJhbWVfYnVyeSAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjM4CiAgICAvLyBvdXRfc3VwcGx5ID0gc2VsZi5fY3VycmVudF9iX2JhbGFuY2UoKQogICAgY2FsbHN1YiBfY3VycmVudF9iX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzkKICAgIC8vIG91dF9hc3NldCA9IHNlbGYuYXNzZXRfYgogICAgaW50IDAKICAgIC8vIGFtbS9jb250cmFjdC5weTozNC0zNQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQgogICAgLy8gc2VsZi5hc3NldF9iID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYiIKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzkKICAgIC8vIG91dF9hc3NldCA9IHNlbGYuYXNzZXRfYgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHN3YXAKICAgIGZyYW1lX2J1cnkgMQogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYiBleGlzdHMKCnN3YXBfc3dpdGNoX2Nhc2VfbmV4dEA0OgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI0My0yNDUKICAgIC8vIHRvX3N3YXAgPSB0b2tlbnNfdG9fc3dhcCgKICAgIC8vICAgICBpbl9hbW91bnQ9c3dhcF94ZmVyLmFzc2V0X2Ftb3VudCwgaW5fc3VwcGx5PWluX3N1cHBseSwgb3V0X3N1cHBseT1vdXRfc3VwcGx5CiAgICAvLyApCiAgICBmcmFtZV9kaWcgMgogICAgZnJhbWVfZGlnIDAKICAgIHVuY292ZXIgMgogICAgY2FsbHN1YiB0b2tlbnNfdG9fc3dhcAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI0NgogICAgLy8gYXNzZXJ0IHRvX3N3YXAgPiAwLCAic2VuZCBhbW91bnQgdG9vIGxvdyIKICAgIGR1cAogICAgYXNzZXJ0IC8vIHNlbmQgYW1vdW50IHRvbyBsb3cKICAgIC8vIGFtbS9jb250cmFjdC5weToyNDgKICAgIC8vIGRvX2Fzc2V0X3RyYW5zZmVyKHJlY2VpdmVyPVR4bi5zZW5kZXIsIGFzc2V0PW91dF9hc3NldCwgYW1vdW50PXRvX3N3YXApCiAgICB0eG4gU2VuZGVyCiAgICBmcmFtZV9kaWcgMQogICAgdW5jb3ZlciAyCiAgICBjYWxsc3ViIGRvX2Fzc2V0X3RyYW5zZmVyCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjQ5CiAgICAvLyBzZWxmLl91cGRhdGVfcmF0aW8oKQogICAgY2FsbHN1YiBfdXBkYXRlX3JhdGlvCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QudG9rZW5zX3RvX3N3YXAoaW5fYW1vdW50OiB1aW50NjQsIGluX3N1cHBseTogdWludDY0LCBvdXRfc3VwcGx5OiB1aW50NjQpIC0+IHVpbnQ2NDoKdG9rZW5zX3RvX3N3YXA6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzQ5LTM1MAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiB0b2tlbnNfdG9fc3dhcCgqLCBpbl9hbW91bnQ6IFVJbnQ2NCwgaW5fc3VwcGx5OiBVSW50NjQsIG91dF9zdXBwbHk6IFVJbnQ2NCkgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzUxCiAgICAvLyBpbl90b3RhbCA9IFNDQUxFICogKGluX3N1cHBseSAtIGluX2Ftb3VudCkgKyAoaW5fYW1vdW50ICogRkFDVE9SKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTMKICAgIC0KICAgIGludCAxMDAwCiAgICAqCiAgICBmcmFtZV9kaWcgLTMKICAgIGludCA5OTUKICAgICoKICAgIGR1cAogICAgY292ZXIgMgogICAgKwogICAgc3dhcAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM1MgogICAgLy8gb3V0X3RvdGFsID0gaW5fYW1vdW50ICogRkFDVE9SICogb3V0X3N1cHBseQogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzUzCiAgICAvLyByZXR1cm4gb3V0X3RvdGFsIC8vIGluX3RvdGFsCiAgICBzd2FwCiAgICAvCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjgKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzItMzMKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIGFzc2V0IEEKICAgIC8vIHNlbGYuYXNzZXRfYSA9IEFzc2V0KCkKICAgIGJ5dGUgImFzc2V0X2EiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFtbS9jb250cmFjdC5weTozNC0zNQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgYXNzZXQgQgogICAgLy8gc2VsZi5hc3NldF9iID0gQXNzZXQoKQogICAgYnl0ZSAiYXNzZXRfYiIKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM2LTM3CiAgICAvLyAjIFRoZSBjdXJyZW50IGdvdmVybm9yIG9mIHRoaXMgY29udHJhY3QsIGFsbG93ZWQgdG8gZG8gYWRtaW4gdHlwZSBhY3Rpb25zCiAgICAvLyBzZWxmLmdvdmVybm9yID0gVHhuLnNlbmRlcgogICAgYnl0ZSAiZ292ZXJub3IiCiAgICB0eG4gU2VuZGVyCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM4LTM5CiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiB0aGUgUG9vbCBUb2tlbiwgdXNlZCB0byB0cmFjayBzaGFyZSBvZiBwb29sIHRoZSBob2xkZXIgbWF5IHJlY292ZXIKICAgIC8vIHNlbGYucG9vbF90b2tlbiA9IEFzc2V0KCkKICAgIGJ5dGUgInBvb2xfdG9rZW4iCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFtbS9jb250cmFjdC5weTo0MC00MQogICAgLy8gIyBUaGUgcmF0aW8gYmV0d2VlbiBhc3NldHMgKEEqU2NhbGUvQikKICAgIC8vIHNlbGYucmF0aW8gPSBVSW50NjQoMCkKICAgIGJ5dGUgInJhdGlvIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBjbGFzcyBDb25zdGFudFByb2R1Y3RBTU0oQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A5CiAgICBtZXRob2QgInNldF9nb3Zlcm5vcihhY2NvdW50KXZvaWQiCiAgICBtZXRob2QgImJvb3RzdHJhcChwYXksYXNzZXQsYXNzZXQpdWludDY0IgogICAgbWV0aG9kICJtaW50KGF4ZmVyLGF4ZmVyLGFzc2V0LGFzc2V0LGFzc2V0KXZvaWQiCiAgICBtZXRob2QgImJ1cm4oYXhmZXIsYXNzZXQsYXNzZXQsYXNzZXQpdm9pZCIKICAgIG1ldGhvZCAic3dhcChheGZlcixhc3NldCxhc3NldCl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fc2V0X2dvdmVybm9yX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fYm9vdHN0cmFwX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fbWludF9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2J1cm5fcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19zd2FwX3JvdXRlQDYKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9nb3Zlcm5vcl9yb3V0ZUAyOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBjbGFzcyBDb25zdGFudFByb2R1Y3RBTU0oQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICAvLyBhbW0vY29udHJhY3QucHk6NDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIHNldF9nb3Zlcm5vcgogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYm9vdHN0cmFwX3JvdXRlQDM6CiAgICAvLyBhbW0vY29udHJhY3QucHk6NDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcKICAgIC8vIGNsYXNzIENvbnN0YW50UHJvZHVjdEFNTShBUkM0Q29udHJhY3QpOgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBib290c3RyYXAKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX21pbnRfcm91dGVANDoKICAgIC8vIGFtbS9jb250cmFjdC5weTo4MS04NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJwb29sX2Fzc2V0IjogInBvb2xfdG9rZW4iLAogICAgLy8gICAgICAgICAiYV9hc3NldCI6ICJhc3NldF9hIiwKICAgIC8vICAgICAgICAgImJfYXNzZXQiOiAiYXNzZXRfYiIsCiAgICAvLyAgICAgfSwKICAgIC8vICkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFtbS9jb250cmFjdC5weToyNwogICAgLy8gY2xhc3MgQ29uc3RhbnRQcm9kdWN0QU1NKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDIKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBheGZlcgogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIGF4ZmVyCiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBheGZlcgogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIGF4ZmVyCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhbW0vY29udHJhY3QucHk6ODEtODcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgKICAgIC8vICAgICBkZWZhdWx0X2FyZ3M9ewogICAgLy8gICAgICAgICAicG9vbF9hc3NldCI6ICJwb29sX3Rva2VuIiwKICAgIC8vICAgICAgICAgImFfYXNzZXQiOiAiYXNzZXRfYSIsCiAgICAvLyAgICAgICAgICJiX2Fzc2V0IjogImFzc2V0X2IiLAogICAgLy8gICAgIH0sCiAgICAvLyApCiAgICBjYWxsc3ViIG1pbnQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2J1cm5fcm91dGVANToKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDctMTUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgInBvb2xfYXNzZXQiOiAicG9vbF90b2tlbiIsCiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBjbGFzcyBDb25zdGFudFByb2R1Y3RBTU0oQVJDNENvbnRyYWN0KToKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IGF4ZmVyCiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgYXhmZXIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDctMTUzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgInBvb2xfYXNzZXQiOiAicG9vbF90b2tlbiIsCiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgY2FsbHN1YiBidXJuCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zd2FwX3JvdXRlQDY6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjA0LTIwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBjbGFzcyBDb25zdGFudFByb2R1Y3RBTU0oQVJDNENvbnRyYWN0KToKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IGF4ZmVyCiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgYXhmZXIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjA0LTIwOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgY2FsbHN1YiBzd2FwCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAOToKICAgIC8vIGFtbS9jb250cmFjdC5weToyNwogICAgLy8gY2xhc3MgQ29uc3RhbnRQcm9kdWN0QU1NKEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBibnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMwogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMzoKICAgIC8vIGFtbS9jb250cmFjdC5weToyNwogICAgLy8gY2xhc3MgQ29uc3RhbnRQcm9kdWN0QU1NKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYW1tLmNvbnRyYWN0LkNvbnN0YW50UHJvZHVjdEFNTS5zZXRfZ292ZXJub3IobmV3X2dvdmVybm9yOiBieXRlcykgLT4gdm9pZDoKc2V0X2dvdmVybm9yOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjQzLTQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIHNldF9nb3Zlcm5vcihzZWxmLCBuZXdfZ292ZXJub3I6IEFjY291bnQpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIGFtbS9jb250cmFjdC5weTo0NgogICAgLy8gc2VsZi5fY2hlY2tfaXNfZ292ZXJub3IoKQogICAgY2FsbHN1YiBfY2hlY2tfaXNfZ292ZXJub3IKICAgIC8vIGFtbS9jb250cmFjdC5weTo0NwogICAgLy8gc2VsZi5nb3Zlcm5vciA9IG5ld19nb3Zlcm5vcgogICAgYnl0ZSAiZ292ZXJub3IiCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9jaGVja19pc19nb3Zlcm5vcigpIC0+IHZvaWQ6Cl9jaGVja19pc19nb3Zlcm5vcjoKICAgIC8vIGFtbS9jb250cmFjdC5weToyNjItMjYzCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9jaGVja19pc19nb3Zlcm5vcihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjY1CiAgICAvLyBUeG4uc2VuZGVyID09IHNlbGYuZ292ZXJub3IKICAgIHR4biBTZW5kZXIKICAgIGludCAwCiAgICBieXRlICJnb3Zlcm5vciIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nb3Zlcm5vciBleGlzdHMKICAgID09CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjY0LTI2NgogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBUeG4uc2VuZGVyID09IHNlbGYuZ292ZXJub3IKICAgIC8vICksICJPbmx5IHRoZSBhY2NvdW50IHNldCBpbiBnbG9iYWxfc3RhdGUuZ292ZXJub3IgbWF5IGNhbGwgdGhpcyBtZXRob2QiCiAgICBhc3NlcnQgLy8gT25seSB0aGUgYWNjb3VudCBzZXQgaW4gZ2xvYmFsX3N0YXRlLmdvdmVybm9yIG1heSBjYWxsIHRoaXMgbWV0aG9kCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLmJvb3RzdHJhcChzZWVkOiB1aW50NjQsIGFfYXNzZXQ6IHVpbnQ2NCwgYl9hc3NldDogdWludDY0KSAtPiB1aW50NjQ6CmJvb3RzdHJhcDoKICAgIC8vIGFtbS9jb250cmFjdC5weTo0OS01MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBib290c3RyYXAoc2VsZiwgc2VlZDogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24sIGFfYXNzZXQ6IEFzc2V0LCBiX2Fzc2V0OiBBc3NldCkgLT4gVUludDY0OgogICAgcHJvdG8gMyAxCiAgICAvLyBhbW0vY29udHJhY3QucHk6NjYKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5wb29sX3Rva2VuLCAiYXBwbGljYXRpb24gaGFzIGFscmVhZHkgYmVlbiBib290c3RyYXBwZWQiCiAgICBpbnQgMAogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wb29sX3Rva2VuIGV4aXN0cwogICAgIQogICAgYXNzZXJ0IC8vIGFwcGxpY2F0aW9uIGhhcyBhbHJlYWR5IGJlZW4gYm9vdHN0cmFwcGVkCiAgICAvLyBhbW0vY29udHJhY3QucHk6NjcKICAgIC8vIHNlbGYuX2NoZWNrX2lzX2dvdmVybm9yKCkKICAgIGNhbGxzdWIgX2NoZWNrX2lzX2dvdmVybm9yCiAgICAvLyBhbW0vY29udHJhY3QucHk6NjgKICAgIC8vIGFzc2VydCBHbG9iYWwuZ3JvdXBfc2l6ZSA9PSAyLCAiZ3JvdXAgc2l6ZSBub3QgMiIKICAgIGdsb2JhbCBHcm91cFNpemUKICAgIGludCAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGdyb3VwIHNpemUgbm90IDIKICAgIC8vIGFtbS9jb250cmFjdC5weTo2OQogICAgLy8gYXNzZXJ0IHNlZWQucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywgInJlY2VpdmVyIG5vdCBhcHAgYWRkcmVzcyIKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgUmVjZWl2ZXIKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICA9PQogICAgYXNzZXJ0IC8vIHJlY2VpdmVyIG5vdCBhcHAgYWRkcmVzcwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjcxCiAgICAvLyBhc3NlcnQgc2VlZC5hbW91bnQgPj0gMzAwXzAwMCwgImFtb3VudCBtaW5pbXVtIG5vdCBtZXQiICAjIDAuMyBBbGdvcwogICAgZnJhbWVfZGlnIC0zCiAgICBndHhucyBBbW91bnQKICAgIGludCAzMDAwMDAKICAgID49CiAgICBhc3NlcnQgLy8gYW1vdW50IG1pbmltdW0gbm90IG1ldAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjcyCiAgICAvLyBhc3NlcnQgYV9hc3NldC5pZCA8IGJfYXNzZXQuaWQsICJhc3NldCBhIG11c3QgYmUgbGVzcyB0aGFuIGFzc2V0IGIiCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgPAogICAgYXNzZXJ0IC8vIGFzc2V0IGEgbXVzdCBiZSBsZXNzIHRoYW4gYXNzZXQgYgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjczCiAgICAvLyBzZWxmLmFzc2V0X2EgPSBhX2Fzc2V0CiAgICBieXRlICJhc3NldF9hIgogICAgZnJhbWVfZGlnIC0yCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYW1tL2NvbnRyYWN0LnB5Ojc0CiAgICAvLyBzZWxmLmFzc2V0X2IgPSBiX2Fzc2V0CiAgICBieXRlICJhc3NldF9iIgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYW1tL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyBzZWxmLnBvb2xfdG9rZW4gPSBzZWxmLl9jcmVhdGVfcG9vbF90b2tlbigpCiAgICBjYWxsc3ViIF9jcmVhdGVfcG9vbF90b2tlbgogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhbW0vY29udHJhY3QucHk6NzcKICAgIC8vIHNlbGYuX2RvX29wdF9pbihzZWxmLmFzc2V0X2EpCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9hIGV4aXN0cwogICAgY2FsbHN1YiBfZG9fb3B0X2luCiAgICAvLyBhbW0vY29udHJhY3QucHk6NzgKICAgIC8vIHNlbGYuX2RvX29wdF9pbihzZWxmLmFzc2V0X2IpCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9iIGV4aXN0cwogICAgY2FsbHN1YiBfZG9fb3B0X2luCiAgICAvLyBhbW0vY29udHJhY3QucHk6NzkKICAgIC8vIHJldHVybiBzZWxmLnBvb2xfdG9rZW4uaWQKICAgIGludCAwCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnBvb2xfdG9rZW4gZXhpc3RzCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9jcmVhdGVfcG9vbF90b2tlbigpIC0+IHVpbnQ2NDoKX2NyZWF0ZV9wb29sX3Rva2VuOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI2OC0yNjkKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgX2NyZWF0ZV9wb29sX3Rva2VuKHNlbGYpIC0+IEFzc2V0OgogICAgcHJvdG8gMCAxCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcxLTI3OQogICAgLy8gaXR4bi5Bc3NldENvbmZpZygKICAgIC8vICAgICBhc3NldF9uYW1lPWIiRFBULSIgKyBzZWxmLmFzc2V0X2EudW5pdF9uYW1lICsgYiItIiArIHNlbGYuYXNzZXRfYi51bml0X25hbWUsCiAgICAvLyAgICAgdW5pdF9uYW1lPWIiZGJ0IiwKICAgIC8vICAgICB0b3RhbD1UT1RBTF9TVVBQTFksCiAgICAvLyAgICAgZGVjaW1hbHM9MywKICAgIC8vICAgICBtYW5hZ2VyPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyAgICAgcmVzZXJ2ZT1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gKQogICAgLy8gLnN1Ym1pdCgpCiAgICBpdHhuX2JlZ2luCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcyCiAgICAvLyBhc3NldF9uYW1lPWIiRFBULSIgKyBzZWxmLmFzc2V0X2EudW5pdF9uYW1lICsgYiItIiArIHNlbGYuYXNzZXRfYi51bml0X25hbWUsCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9hIGV4aXN0cwogICAgYXNzZXRfcGFyYW1zX2dldCBBc3NldFVuaXROYW1lCiAgICBhc3NlcnQgLy8gYXNzZXQgZXhpc3RzCiAgICBieXRlIDB4NDQ1MDU0MmQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDJkCiAgICBjb25jYXQKICAgIGludCAwCiAgICBieXRlICJhc3NldF9iIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCiAgICBhc3NldF9wYXJhbXNfZ2V0IEFzc2V0VW5pdE5hbWUKICAgIGFzc2VydCAvLyBhc3NldCBleGlzdHMKICAgIGNvbmNhdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3NgogICAgLy8gbWFuYWdlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgIC8vIGFtbS9jb250cmFjdC5weToyNzcKICAgIC8vIHJlc2VydmU9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIGR1cAogICAgaXR4bl9maWVsZCBDb25maWdBc3NldFJlc2VydmUKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRNYW5hZ2VyCiAgICAvLyBhbW0vY29udHJhY3QucHk6Mjc1CiAgICAvLyBkZWNpbWFscz0zLAogICAgaW50IDMKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXREZWNpbWFscwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3NAogICAgLy8gdG90YWw9VE9UQUxfU1VQUExZLAogICAgaW50IDEwMDAwMDAwMDAwCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VG90YWwKICAgIC8vIGFtbS9jb250cmFjdC5weToyNzMKICAgIC8vIHVuaXRfbmFtZT1iImRidCIsCiAgICBieXRlIDB4NjQ2Mjc0CiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VW5pdE5hbWUKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXROYW1lCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcxCiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgaW50IGFjZmcKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI3MS0yNzkKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICAvLyAgICAgYXNzZXRfbmFtZT1iIkRQVC0iICsgc2VsZi5hc3NldF9hLnVuaXRfbmFtZSArIGIiLSIgKyBzZWxmLmFzc2V0X2IudW5pdF9uYW1lLAogICAgLy8gICAgIHVuaXRfbmFtZT1iImRidCIsCiAgICAvLyAgICAgdG90YWw9VE9UQUxfU1VQUExZLAogICAgLy8gICAgIGRlY2ltYWxzPTMsCiAgICAvLyAgICAgbWFuYWdlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gICAgIHJlc2VydmU9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgaXR4bl9zdWJtaXQKICAgIC8vIGFtbS9jb250cmFjdC5weToyNzEtMjgwCiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgIGFzc2V0X25hbWU9YiJEUFQtIiArIHNlbGYuYXNzZXRfYS51bml0X25hbWUgKyBiIi0iICsgc2VsZi5hc3NldF9iLnVuaXRfbmFtZSwKICAgIC8vICAgICB1bml0X25hbWU9YiJkYnQiLAogICAgLy8gICAgIHRvdGFsPVRPVEFMX1NVUFBMWSwKICAgIC8vICAgICBkZWNpbWFscz0zLAogICAgLy8gICAgIG1hbmFnZXI9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIC8vICAgICByZXNlcnZlPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyApCiAgICAvLyAuc3VibWl0KCkKICAgIC8vIC5jcmVhdGVkX2Fzc2V0CiAgICBpdHhuIENyZWF0ZWRBc3NldElECiAgICAvLyBhbW0vY29udHJhY3QucHk6MjcwLTI4MQogICAgLy8gcmV0dXJuICgKICAgIC8vICAgICBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgICAgICBhc3NldF9uYW1lPWIiRFBULSIgKyBzZWxmLmFzc2V0X2EudW5pdF9uYW1lICsgYiItIiArIHNlbGYuYXNzZXRfYi51bml0X25hbWUsCiAgICAvLyAgICAgICAgIHVuaXRfbmFtZT1iImRidCIsCiAgICAvLyAgICAgICAgIHRvdGFsPVRPVEFMX1NVUFBMWSwKICAgIC8vICAgICAgICAgZGVjaW1hbHM9MywKICAgIC8vICAgICAgICAgbWFuYWdlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gICAgICAgICByZXNlcnZlPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyAgICAgKQogICAgLy8gICAgIC5zdWJtaXQoKQogICAgLy8gICAgIC5jcmVhdGVkX2Fzc2V0CiAgICAvLyApCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9kb19vcHRfaW4oYXNzZXQ6IHVpbnQ2NCkgLT4gdm9pZDoKX2RvX29wdF9pbjoKICAgIC8vIGFtbS9jb250cmFjdC5weToyODMtMjg0CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9kb19vcHRfaW4oc2VsZiwgYXNzZXQ6IEFzc2V0KSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6Mjg2CiAgICAvLyByZWNlaXZlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgIC8vIGFtbS9jb250cmFjdC5weToyODUtMjg5CiAgICAvLyBkb19hc3NldF90cmFuc2ZlcigKICAgIC8vICAgICByZWNlaXZlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gICAgIGFzc2V0PWFzc2V0LAogICAgLy8gICAgIGFtb3VudD1VSW50NjQoMCksCiAgICAvLyApCiAgICBmcmFtZV9kaWcgLTEKICAgIC8vIGFtbS9jb250cmFjdC5weToyODgKICAgIC8vIGFtb3VudD1VSW50NjQoMCksCiAgICBpbnQgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI4NS0yODkKICAgIC8vIGRvX2Fzc2V0X3RyYW5zZmVyKAogICAgLy8gICAgIHJlY2VpdmVyPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyAgICAgYXNzZXQ9YXNzZXQsCiAgICAvLyAgICAgYW1vdW50PVVJbnQ2NCgwKSwKICAgIC8vICkKICAgIGNhbGxzdWIgZG9fYXNzZXRfdHJhbnNmZXIKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5kb19hc3NldF90cmFuc2ZlcihyZWNlaXZlcjogYnl0ZXMsIGFzc2V0OiB1aW50NjQsIGFtb3VudDogdWludDY0KSAtPiB2b2lkOgpkb19hc3NldF90cmFuc2ZlcjoKICAgIC8vIGFtbS9jb250cmFjdC5weTozNTYtMzU3CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGRvX2Fzc2V0X3RyYW5zZmVyKCosIHJlY2VpdmVyOiBBY2NvdW50LCBhc3NldDogQXNzZXQsIGFtb3VudDogVUludDY0KSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzU4LTM2MgogICAgLy8gaXR4bi5Bc3NldFRyYW5zZmVyKAogICAgLy8gICAgIHhmZXJfYXNzZXQ9YXNzZXQsCiAgICAvLyAgICAgYXNzZXRfYW1vdW50PWFtb3VudCwKICAgIC8vICAgICBhc3NldF9yZWNlaXZlcj1yZWNlaXZlciwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIGZyYW1lX2RpZyAtMwogICAgaXR4bl9maWVsZCBBc3NldFJlY2VpdmVyCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0eG5fZmllbGQgQXNzZXRBbW91bnQKICAgIGZyYW1lX2RpZyAtMgogICAgaXR4bl9maWVsZCBYZmVyQXNzZXQKICAgIC8vIGFtbS9jb250cmFjdC5weTozNTgKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIGludCBheGZlcgogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzU4LTM2MgogICAgLy8gaXR4bi5Bc3NldFRyYW5zZmVyKAogICAgLy8gICAgIHhmZXJfYXNzZXQ9YXNzZXQsCiAgICAvLyAgICAgYXNzZXRfYW1vdW50PWFtb3VudCwKICAgIC8vICAgICBhc3NldF9yZWNlaXZlcj1yZWNlaXZlciwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLm1pbnQoYV94ZmVyOiB1aW50NjQsIGJfeGZlcjogdWludDY0LCBwb29sX2Fzc2V0OiB1aW50NjQsIGFfYXNzZXQ6IHVpbnQ2NCwgYl9hc3NldDogdWludDY0KSAtPiB2b2lkOgptaW50OgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjgxLTk1CiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgInBvb2xfYXNzZXQiOiAicG9vbF90b2tlbiIsCiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgLy8gZGVmIG1pbnQoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBhX3hmZXI6IGd0eG4uQXNzZXRUcmFuc2ZlclRyYW5zYWN0aW9uLAogICAgLy8gICAgIGJfeGZlcjogZ3R4bi5Bc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24sCiAgICAvLyAgICAgcG9vbF9hc3NldDogQXNzZXQsCiAgICAvLyAgICAgYV9hc3NldDogQXNzZXQsCiAgICAvLyAgICAgYl9hc3NldDogQXNzZXQsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byA1IDAKICAgIC8vIGFtbS9jb250cmFjdC5weToxMTEKICAgIC8vIHNlbGYuX2NoZWNrX2Jvb3RzdHJhcHBlZCgpCiAgICBjYWxsc3ViIF9jaGVja19ib290c3RyYXBwZWQKICAgIC8vIGFtbS9jb250cmFjdC5weToxMTMtMTE0CiAgICAvLyAjIHdlbGwtZm9ybWVkIG1pbnQKICAgIC8vIGFzc2VydCBwb29sX2Fzc2V0ID09IHNlbGYucG9vbF90b2tlbiwgImFzc2V0IHBvb2wgaW5jb3JyZWN0IgogICAgaW50IDAKICAgIGJ5dGUgInBvb2xfdG9rZW4iCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucG9vbF90b2tlbiBleGlzdHMKICAgIGZyYW1lX2RpZyAtMwogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBwb29sIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjExNQogICAgLy8gYXNzZXJ0IGFfYXNzZXQgPT0gc2VsZi5hc3NldF9hLCAiYXNzZXQgYSBpbmNvcnJlY3QiCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9hIGV4aXN0cwogICAgZnJhbWVfZGlnIC0yCiAgICA9PQogICAgYXNzZXJ0IC8vIGFzc2V0IGEgaW5jb3JyZWN0CiAgICAvLyBhbW0vY29udHJhY3QucHk6MTE2CiAgICAvLyBhc3NlcnQgYl9hc3NldCA9PSBzZWxmLmFzc2V0X2IsICJhc3NldCBiIGluY29ycmVjdCIKICAgIGludCAwCiAgICBieXRlICJhc3NldF9iIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTEKICAgID09CiAgICBhc3NlcnQgLy8gYXNzZXQgYiBpbmNvcnJlY3QKICAgIC8vIGFtbS9jb250cmFjdC5weToxMTcKICAgIC8vIGFzc2VydCBhX3hmZXIuc2VuZGVyID09IFR4bi5zZW5kZXIsICJzZW5kZXIgaW52YWxpZCIKICAgIGZyYW1lX2RpZyAtNQogICAgZ3R4bnMgU2VuZGVyCiAgICB0eG4gU2VuZGVyCiAgICA9PQogICAgYXNzZXJ0IC8vIHNlbmRlciBpbnZhbGlkCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTE4CiAgICAvLyBhc3NlcnQgYl94ZmVyLnNlbmRlciA9PSBUeG4uc2VuZGVyLCAic2VuZGVyIGludmFsaWQiCiAgICBmcmFtZV9kaWcgLTQKICAgIGd0eG5zIFNlbmRlcgogICAgdHhuIFNlbmRlcgogICAgPT0KICAgIGFzc2VydCAvLyBzZW5kZXIgaW52YWxpZAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjEyMgogICAgLy8gYV94ZmVyLmFzc2V0X3JlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIGZyYW1lX2RpZyAtNQogICAgZ3R4bnMgQXNzZXRSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyBhbW0vY29udHJhY3QucHk6MTIwLTEyMwogICAgLy8gIyB2YWxpZCBhc3NldCBhIHhmZXIKICAgIC8vIGFzc2VydCAoCiAgICAvLyAgICAgYV94ZmVyLmFzc2V0X3JlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIC8vICksICJyZWNlaXZlciBub3QgYXBwIGFkZHJlc3MiCiAgICBhc3NlcnQgLy8gcmVjZWl2ZXIgbm90IGFwcCBhZGRyZXNzCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTI0CiAgICAvLyBhc3NlcnQgYV94ZmVyLnhmZXJfYXNzZXQgPT0gc2VsZi5hc3NldF9hLCAiYXNzZXQgYSBpbmNvcnJlY3QiCiAgICBmcmFtZV9kaWcgLTUKICAgIGd0eG5zIFhmZXJBc3NldAogICAgaW50IDAKICAgIGJ5dGUgImFzc2V0X2EiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgID09CiAgICBhc3NlcnQgLy8gYXNzZXQgYSBpbmNvcnJlY3QKICAgIC8vIGFtbS9jb250cmFjdC5weToxMjUKICAgIC8vIGFzc2VydCBhX3hmZXIuYXNzZXRfYW1vdW50ID4gMCwgImFtb3VudCBtaW5pbXVtIG5vdCBtZXQiCiAgICBmcmFtZV9kaWcgLTUKICAgIGd0eG5zIEFzc2V0QW1vdW50CiAgICBkdXAKICAgIGFzc2VydCAvLyBhbW91bnQgbWluaW11bSBub3QgbWV0CiAgICAvLyBhbW0vY29udHJhY3QucHk6MTI5CiAgICAvLyBiX3hmZXIuYXNzZXRfcmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC00CiAgICBndHhucyBBc3NldFJlY2VpdmVyCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgPT0KICAgIC8vIGFtbS9jb250cmFjdC5weToxMjctMTMwCiAgICAvLyAjIHZhbGlkIGFzc2V0IGIgeGZlcgogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBiX3hmZXIuYXNzZXRfcmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gKSwgInJlY2VpdmVyIG5vdCBhcHAgYWRkcmVzcyIKICAgIGFzc2VydCAvLyByZWNlaXZlciBub3QgYXBwIGFkZHJlc3MKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzEKICAgIC8vIGFzc2VydCBiX3hmZXIueGZlcl9hc3NldCA9PSBzZWxmLmFzc2V0X2IsICJhc3NldCBiIGluY29ycmVjdCIKICAgIGZyYW1lX2RpZyAtNAogICAgZ3R4bnMgWGZlckFzc2V0CiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9iIGV4aXN0cwogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBiIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjEzMgogICAgLy8gYXNzZXJ0IGJfeGZlci5hc3NldF9hbW91bnQgPiAwLCAiYW1vdW50IG1pbmltdW0gbm90IG1ldCIKICAgIGZyYW1lX2RpZyAtNAogICAgZ3R4bnMgQXNzZXRBbW91bnQKICAgIGR1cAogICAgYXNzZXJ0IC8vIGFtb3VudCBtaW5pbXVtIG5vdCBtZXQKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzUKICAgIC8vIHBvb2xfYmFsYW5jZT1zZWxmLl9jdXJyZW50X3Bvb2xfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9wb29sX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzYKICAgIC8vIGFfYmFsYW5jZT1zZWxmLl9jdXJyZW50X2FfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9hX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzcKICAgIC8vIGJfYmFsYW5jZT1zZWxmLl9jdXJyZW50X2JfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9iX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxMzQtMTQwCiAgICAvLyB0b19taW50ID0gdG9rZW5zX3RvX21pbnQoCiAgICAvLyAgICAgcG9vbF9iYWxhbmNlPXNlbGYuX2N1cnJlbnRfcG9vbF9iYWxhbmNlKCksCiAgICAvLyAgICAgYV9iYWxhbmNlPXNlbGYuX2N1cnJlbnRfYV9iYWxhbmNlKCksCiAgICAvLyAgICAgYl9iYWxhbmNlPXNlbGYuX2N1cnJlbnRfYl9iYWxhbmNlKCksCiAgICAvLyAgICAgYV9hbW91bnQ9YV94ZmVyLmFzc2V0X2Ftb3VudCwKICAgIC8vICAgICBiX2Ftb3VudD1iX3hmZXIuYXNzZXRfYW1vdW50LAogICAgLy8gKQogICAgdW5jb3ZlciA0CiAgICB1bmNvdmVyIDQKICAgIGNhbGxzdWIgdG9rZW5zX3RvX21pbnQKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDEKICAgIC8vIGFzc2VydCB0b19taW50ID4gMCwgInNlbmQgYW1vdW50IHRvbyBsb3ciCiAgICBkdXAKICAgIGFzc2VydCAvLyBzZW5kIGFtb3VudCB0b28gbG93CiAgICAvLyBhbW0vY29udHJhY3QucHk6MTQzLTE0NAogICAgLy8gIyBtaW50IHRva2VucwogICAgLy8gZG9fYXNzZXRfdHJhbnNmZXIocmVjZWl2ZXI9VHhuLnNlbmRlciwgYXNzZXQ9c2VsZi5wb29sX3Rva2VuLCBhbW91bnQ9dG9fbWludCkKICAgIHR4biBTZW5kZXIKICAgIGludCAwCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnBvb2xfdG9rZW4gZXhpc3RzCiAgICB1bmNvdmVyIDIKICAgIGNhbGxzdWIgZG9fYXNzZXRfdHJhbnNmZXIKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDUKICAgIC8vIHNlbGYuX3VwZGF0ZV9yYXRpbygpCiAgICBjYWxsc3ViIF91cGRhdGVfcmF0aW8KICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uX2NoZWNrX2Jvb3RzdHJhcHBlZCgpIC0+IHZvaWQ6Cl9jaGVja19ib290c3RyYXBwZWQ6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjUxLTI1MgogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBfY2hlY2tfYm9vdHN0cmFwcGVkKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGFtbS9jb250cmFjdC5weToyNTMKICAgIC8vIGFzc2VydCBzZWxmLnBvb2xfdG9rZW4sICJib290c3RyYXAgbWV0aG9kIG5lZWRzIHRvIGJlIGNhbGxlZCBmaXJzdCIKICAgIGludCAwCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnBvb2xfdG9rZW4gZXhpc3RzCiAgICBhc3NlcnQgLy8gYm9vdHN0cmFwIG1ldGhvZCBuZWVkcyB0byBiZSBjYWxsZWQgZmlyc3QKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uX2N1cnJlbnRfcG9vbF9iYWxhbmNlKCkgLT4gdWludDY0OgpfY3VycmVudF9wb29sX2JhbGFuY2U6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjkxLTI5MgogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBfY3VycmVudF9wb29sX2JhbGFuY2Uoc2VsZikgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjkzCiAgICAvLyByZXR1cm4gc2VsZi5wb29sX3Rva2VuLmJhbGFuY2UoR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcykKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICBpbnQgMAogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wb29sX3Rva2VuIGV4aXN0cwogICAgYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRCYWxhbmNlCiAgICBhc3NlcnQgLy8gYWNjb3VudCBvcHRlZCBpbnRvIGFzc2V0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLl9jdXJyZW50X2FfYmFsYW5jZSgpIC0+IHVpbnQ2NDoKX2N1cnJlbnRfYV9iYWxhbmNlOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI5NS0yOTYKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgX2N1cnJlbnRfYV9iYWxhbmNlKHNlbGYpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDAgMQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI5NwogICAgLy8gcmV0dXJuIHNlbGYuYXNzZXRfYS5iYWxhbmNlKEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MpCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgaW50IDAKICAgIGJ5dGUgImFzc2V0X2EiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgIGFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQogICAgYXNzZXJ0IC8vIGFjY291bnQgb3B0ZWQgaW50byBhc3NldAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYW1tLmNvbnRyYWN0LkNvbnN0YW50UHJvZHVjdEFNTS5fY3VycmVudF9iX2JhbGFuY2UoKSAtPiB1aW50NjQ6Cl9jdXJyZW50X2JfYmFsYW5jZToKICAgIC8vIGFtbS9jb250cmFjdC5weToyOTktMzAwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9jdXJyZW50X2JfYmFsYW5jZShzZWxmKSAtPiBVSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGFtbS9jb250cmFjdC5weTozMDEKICAgIC8vIHJldHVybiBzZWxmLmFzc2V0X2IuYmFsYW5jZShHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzKQogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgIGludCAwCiAgICBieXRlICJhc3NldF9iIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCiAgICBhc3NldF9ob2xkaW5nX2dldCBBc3NldEJhbGFuY2UKICAgIGFzc2VydCAvLyBhY2NvdW50IG9wdGVkIGludG8gYXNzZXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC50b2tlbnNfdG9fbWludChwb29sX2JhbGFuY2U6IHVpbnQ2NCwgYV9iYWxhbmNlOiB1aW50NjQsIGJfYmFsYW5jZTogdWludDY0LCBhX2Ftb3VudDogdWludDY0LCBiX2Ftb3VudDogdWludDY0KSAtPiB1aW50NjQ6CnRva2Vuc190b19taW50OgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMyMi0zMzAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgdG9rZW5zX3RvX21pbnQoCiAgICAvLyAgICAgKiwKICAgIC8vICAgICBwb29sX2JhbGFuY2U6IFVJbnQ2NCwKICAgIC8vICAgICBhX2JhbGFuY2U6IFVJbnQ2NCwKICAgIC8vICAgICBiX2JhbGFuY2U6IFVJbnQ2NCwKICAgIC8vICAgICBhX2Ftb3VudDogVUludDY0LAogICAgLy8gICAgIGJfYW1vdW50OiBVSW50NjQsCiAgICAvLyApIC0+IFVJbnQ2NDoKICAgIHByb3RvIDUgMQogICAgYnl0ZSAiIgogICAgZHVwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzMxCiAgICAvLyBpc19pbml0aWFsX21pbnQgPSBhX2JhbGFuY2UgPT0gYV9hbW91bnQgYW5kIGJfYmFsYW5jZSA9PSBiX2Ftb3VudAogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTIKICAgID09CiAgICBieiB0b2tlbnNfdG9fbWludF9ib29sX2ZhbHNlQDMKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgYnogdG9rZW5zX3RvX21pbnRfYm9vbF9mYWxzZUAzCiAgICBpbnQgMQogICAgYiB0b2tlbnNfdG9fbWludF9ib29sX21lcmdlQDQKCnRva2Vuc190b19taW50X2Jvb2xfZmFsc2VAMzoKICAgIGludCAwCgp0b2tlbnNfdG9fbWludF9ib29sX21lcmdlQDQ6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzMyCiAgICAvLyBpZiBpc19pbml0aWFsX21pbnQ6CiAgICBieiB0b2tlbnNfdG9fbWludF9hZnRlcl9pZl9lbHNlQDYKICAgIC8vIGFtbS9jb250cmFjdC5weTozMzMKICAgIC8vIHJldHVybiBvcC5zcXJ0KGFfYW1vdW50ICogYl9hbW91bnQpIC0gU0NBTEUKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICAqCiAgICBzcXJ0CiAgICBpbnQgMTAwMAogICAgLQogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCnRva2Vuc190b19taW50X2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIGFtbS9jb250cmFjdC5weTozMzQKICAgIC8vIGlzc3VlZCA9IFRPVEFMX1NVUFBMWSAtIHBvb2xfYmFsYW5jZQogICAgaW50IDEwMDAwMDAwMDAwCiAgICBmcmFtZV9kaWcgLTUKICAgIC0KICAgIC8vIGFtbS9jb250cmFjdC5weTozMzUKICAgIC8vIGFfcmF0aW8gPSBTQ0FMRSAqIGFfYW1vdW50IC8vIChhX2JhbGFuY2UgLSBhX2Ftb3VudCkKICAgIGludCAxMDAwCiAgICBmcmFtZV9kaWcgLTIKICAgICoKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0yCiAgICAtCiAgICAvCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMzNgogICAgLy8gYl9yYXRpbyA9IFNDQUxFICogYl9hbW91bnQgLy8gKGJfYmFsYW5jZSAtIGJfYW1vdW50KQogICAgaW50IDEwMDAKICAgIGZyYW1lX2RpZyAtMQogICAgKgogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTEKICAgIC0KICAgIC8KICAgIGR1cAogICAgZnJhbWVfYnVyeSAxCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzM3CiAgICAvLyBpZiBhX3JhdGlvIDwgYl9yYXRpbzoKICAgIDwKICAgIGJ6IHRva2Vuc190b19taW50X2Vsc2VfYm9keUA4CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzM4CiAgICAvLyByZXR1cm4gYV9yYXRpbyAqIGlzc3VlZCAvLyBTQ0FMRQogICAgZnJhbWVfZGlnIDAKICAgICoKICAgIGludCAxMDAwCiAgICAvCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKdG9rZW5zX3RvX21pbnRfZWxzZV9ib2R5QDg6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzQwCiAgICAvLyByZXR1cm4gYl9yYXRpbyAqIGlzc3VlZCAvLyBTQ0FMRQogICAgZnJhbWVfZGlnIDEKICAgICoKICAgIGludCAxMDAwCiAgICAvCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uX3VwZGF0ZV9yYXRpbygpIC0+IHZvaWQ6Cl91cGRhdGVfcmF0aW86CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjU1LTI1NgogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBfdXBkYXRlX3JhdGlvKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGFtbS9jb250cmFjdC5weToyNTcKICAgIC8vIGFfYmFsYW5jZSA9IHNlbGYuX2N1cnJlbnRfYV9iYWxhbmNlKCkKICAgIGNhbGxzdWIgX2N1cnJlbnRfYV9iYWxhbmNlCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjU4CiAgICAvLyBiX2JhbGFuY2UgPSBzZWxmLl9jdXJyZW50X2JfYmFsYW5jZSgpCiAgICBjYWxsc3ViIF9jdXJyZW50X2JfYmFsYW5jZQogICAgc3dhcAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI2MAogICAgLy8gc2VsZi5yYXRpbyA9IGFfYmFsYW5jZSAqIFNDQUxFIC8vIGJfYmFsYW5jZQogICAgaW50IDEwMDAKICAgICoKICAgIHN3YXAKICAgIC8KICAgIGJ5dGUgInJhdGlvIgogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uYnVybihwb29sX3hmZXI6IHVpbnQ2NCwgcG9vbF9hc3NldDogdWludDY0LCBhX2Fzc2V0OiB1aW50NjQsIGJfYXNzZXQ6IHVpbnQ2NCkgLT4gdm9pZDoKYnVybjoKICAgIC8vIGFtbS9jb250cmFjdC5weToxNDctMTYwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgZGVmYXVsdF9hcmdzPXsKICAgIC8vICAgICAgICAgInBvb2xfYXNzZXQiOiAicG9vbF90b2tlbiIsCiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgLy8gZGVmIGJ1cm4oCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBwb29sX3hmZXI6IGd0eG4uQXNzZXRUcmFuc2ZlclRyYW5zYWN0aW9uLAogICAgLy8gICAgIHBvb2xfYXNzZXQ6IEFzc2V0LAogICAgLy8gICAgIGFfYXNzZXQ6IEFzc2V0LAogICAgLy8gICAgIGJfYXNzZXQ6IEFzc2V0LAogICAgLy8gKSAtPiBOb25lOgogICAgcHJvdG8gNCAwCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTcwCiAgICAvLyBzZWxmLl9jaGVja19ib290c3RyYXBwZWQoKQogICAgY2FsbHN1YiBfY2hlY2tfYm9vdHN0cmFwcGVkCiAgICAvLyBhbW0vY29udHJhY3QucHk6MTcyCiAgICAvLyBhc3NlcnQgcG9vbF9hc3NldCA9PSBzZWxmLnBvb2xfdG9rZW4sICJhc3NldCBwb29sIGluY29ycmVjdCIKICAgIGludCAwCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnBvb2xfdG9rZW4gZXhpc3RzCiAgICBmcmFtZV9kaWcgLTMKICAgID09CiAgICBhc3NlcnQgLy8gYXNzZXQgcG9vbCBpbmNvcnJlY3QKICAgIC8vIGFtbS9jb250cmFjdC5weToxNzMKICAgIC8vIGFzc2VydCBhX2Fzc2V0ID09IHNlbGYuYXNzZXRfYSwgImFzc2V0IGEgaW5jb3JyZWN0IgogICAgaW50IDAKICAgIGJ5dGUgImFzc2V0X2EiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMgogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBhIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjE3NAogICAgLy8gYXNzZXJ0IGJfYXNzZXQgPT0gc2VsZi5hc3NldF9iLCAiYXNzZXQgYiBpbmNvcnJlY3QiCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9iIGV4aXN0cwogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgYXNzZXJ0IC8vIGFzc2V0IGIgaW5jb3JyZWN0CiAgICAvLyBhbW0vY29udHJhY3QucHk6MTc3CiAgICAvLyBwb29sX3hmZXIuYXNzZXRfcmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC00CiAgICBndHhucyBBc3NldFJlY2VpdmVyCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgPT0KICAgIC8vIGFtbS9jb250cmFjdC5weToxNzYtMTc4CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIHBvb2xfeGZlci5hc3NldF9yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzCiAgICAvLyApLCAicmVjZWl2ZXIgbm90IGFwcCBhZGRyZXNzIgogICAgYXNzZXJ0IC8vIHJlY2VpdmVyIG5vdCBhcHAgYWRkcmVzcwogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjE3OQogICAgLy8gYXNzZXJ0IHBvb2xfeGZlci5hc3NldF9hbW91bnQgPiAwLCAiYW1vdW50IG1pbmltdW0gbm90IG1ldCIKICAgIGZyYW1lX2RpZyAtNAogICAgZ3R4bnMgQXNzZXRBbW91bnQKICAgIGR1cAogICAgYXNzZXJ0IC8vIGFtb3VudCBtaW5pbXVtIG5vdCBtZXQKICAgIC8vIGFtbS9jb250cmFjdC5weToxODAKICAgIC8vIGFzc2VydCBwb29sX3hmZXIueGZlcl9hc3NldCA9PSBzZWxmLnBvb2xfdG9rZW4sICJhc3NldCBwb29sIGluY29ycmVjdCIKICAgIGZyYW1lX2RpZyAtNAogICAgZ3R4bnMgWGZlckFzc2V0CiAgICBpbnQgMAogICAgYnl0ZSAicG9vbF90b2tlbiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wb29sX3Rva2VuIGV4aXN0cwogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBwb29sIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjE4MQogICAgLy8gYXNzZXJ0IHBvb2xfeGZlci5zZW5kZXIgPT0gVHhuLnNlbmRlciwgInNlbmRlciBpbnZhbGlkIgogICAgZnJhbWVfZGlnIC00CiAgICBndHhucyBTZW5kZXIKICAgIHR4biBTZW5kZXIKICAgID09CiAgICBhc3NlcnQgLy8gc2VuZGVyIGludmFsaWQKICAgIC8vIGFtbS9jb250cmFjdC5weToxODMtMTg1CiAgICAvLyAjIEdldCB0aGUgdG90YWwgbnVtYmVyIG9mIHRva2VucyBpc3N1ZWQKICAgIC8vICMgIWltcG9ydGFudDogdGhpcyBoYXBwZW5zIHByaW9yIHRvIHJlY2VpdmluZyB0aGUgY3VycmVudCBheGZlciBvZiBwb29sIHRva2VucwogICAgLy8gcG9vbF9iYWxhbmNlID0gc2VsZi5fY3VycmVudF9wb29sX2JhbGFuY2UoKQogICAgY2FsbHN1YiBfY3VycmVudF9wb29sX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxODgKICAgIC8vIHN1cHBseT1zZWxmLl9jdXJyZW50X2FfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9hX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxODYtMTkwCiAgICAvLyBhX2FtdCA9IHRva2Vuc190b19idXJuKAogICAgLy8gICAgIHBvb2xfYmFsYW5jZT1wb29sX2JhbGFuY2UsCiAgICAvLyAgICAgc3VwcGx5PXNlbGYuX2N1cnJlbnRfYV9iYWxhbmNlKCksCiAgICAvLyAgICAgYW1vdW50PXBvb2xfeGZlci5hc3NldF9hbW91bnQsCiAgICAvLyApCiAgICBkaWcgMQogICAgc3dhcAogICAgZGlnIDMKICAgIGNhbGxzdWIgdG9rZW5zX3RvX2J1cm4KICAgIGNvdmVyIDIKICAgIC8vIGFtbS9jb250cmFjdC5weToxOTMKICAgIC8vIHN1cHBseT1zZWxmLl9jdXJyZW50X2JfYmFsYW5jZSgpLAogICAgY2FsbHN1YiBfY3VycmVudF9iX2JhbGFuY2UKICAgIC8vIGFtbS9jb250cmFjdC5weToxOTEtMTk1CiAgICAvLyBiX2FtdCA9IHRva2Vuc190b19idXJuKAogICAgLy8gICAgIHBvb2xfYmFsYW5jZT1wb29sX2JhbGFuY2UsCiAgICAvLyAgICAgc3VwcGx5PXNlbGYuX2N1cnJlbnRfYl9iYWxhbmNlKCksCiAgICAvLyAgICAgYW1vdW50PXBvb2xfeGZlci5hc3NldF9hbW91bnQsCiAgICAvLyApCiAgICB1bmNvdmVyIDIKICAgIGNhbGxzdWIgdG9rZW5zX3RvX2J1cm4KICAgIHN3YXAKICAgIC8vIGFtbS9jb250cmFjdC5weToxOTctMTk4CiAgICAvLyAjIFNlbmQgYmFjayBjb21tZW5zdXJhdGUgYW10IG9mIGEKICAgIC8vIGRvX2Fzc2V0X3RyYW5zZmVyKHJlY2VpdmVyPVR4bi5zZW5kZXIsIGFzc2V0PXNlbGYuYXNzZXRfYSwgYW1vdW50PWFfYW10KQogICAgdHhuIFNlbmRlcgogICAgaW50IDAKICAgIGJ5dGUgImFzc2V0X2EiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgIHVuY292ZXIgMgogICAgY2FsbHN1YiBkb19hc3NldF90cmFuc2ZlcgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIwMC0yMDEKICAgIC8vICMgU2VuZCBiYWNrIGNvbW1lbnN1cmF0ZSBhbXQgb2YgYgogICAgLy8gZG9fYXNzZXRfdHJhbnNmZXIocmVjZWl2ZXI9VHhuLnNlbmRlciwgYXNzZXQ9c2VsZi5hc3NldF9iLCBhbW91bnQ9Yl9hbXQpCiAgICB0eG4gU2VuZGVyCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9iIGV4aXN0cwogICAgdW5jb3ZlciAyCiAgICBjYWxsc3ViIGRvX2Fzc2V0X3RyYW5zZmVyCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjAyCiAgICAvLyBzZWxmLl91cGRhdGVfcmF0aW8oKQogICAgY2FsbHN1YiBfdXBkYXRlX3JhdGlvCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hbW0uY29udHJhY3QudG9rZW5zX3RvX2J1cm4ocG9vbF9iYWxhbmNlOiB1aW50NjQsIHN1cHBseTogdWludDY0LCBhbW91bnQ6IHVpbnQ2NCkgLT4gdWludDY0Ogp0b2tlbnNfdG9fYnVybjoKICAgIC8vIGFtbS9jb250cmFjdC5weTozNDMtMzQ0CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHRva2Vuc190b19idXJuKCosIHBvb2xfYmFsYW5jZTogVUludDY0LCBzdXBwbHk6IFVJbnQ2NCwgYW1vdW50OiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDMgMQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM0NQogICAgLy8gaXNzdWVkID0gVE9UQUxfU1VQUExZIC0gcG9vbF9iYWxhbmNlIC0gYW1vdW50CiAgICBpbnQgMTAwMDAwMDAwMDAKICAgIGZyYW1lX2RpZyAtMwogICAgLQogICAgZnJhbWVfZGlnIC0xCiAgICAtCiAgICAvLyBhbW0vY29udHJhY3QucHk6MzQ2CiAgICAvLyByZXR1cm4gc3VwcGx5ICogYW1vdW50IC8vIGlzc3VlZAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICoKICAgIHN3YXAKICAgIC8KICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmFtbS5jb250cmFjdC5Db25zdGFudFByb2R1Y3RBTU0uc3dhcChzd2FwX3hmZXI6IHVpbnQ2NCwgYV9hc3NldDogdWludDY0LCBiX2Fzc2V0OiB1aW50NjQpIC0+IHZvaWQ6CnN3YXA6CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjA0LTIxNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJhX2Fzc2V0IjogImFzc2V0X2EiLAogICAgLy8gICAgICAgICAiYl9hc3NldCI6ICJhc3NldF9iIiwKICAgIC8vICAgICB9LAogICAgLy8gKQogICAgLy8gZGVmIHN3YXAoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBzd2FwX3hmZXI6IGd0eG4uQXNzZXRUcmFuc2ZlclRyYW5zYWN0aW9uLAogICAgLy8gICAgIGFfYXNzZXQ6IEFzc2V0LAogICAgLy8gICAgIGJfYXNzZXQ6IEFzc2V0LAogICAgLy8gKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICBieXRlICIiCiAgICBkdXAKICAgIC8vIGFtbS9jb250cmFjdC5weToyMjMKICAgIC8vIHNlbGYuX2NoZWNrX2Jvb3RzdHJhcHBlZCgpCiAgICBjYWxsc3ViIF9jaGVja19ib290c3RyYXBwZWQKICAgIC8vIGFtbS9jb250cmFjdC5weToyMjUKICAgIC8vIGFzc2VydCBhX2Fzc2V0ID09IHNlbGYuYXNzZXRfYSwgImFzc2V0IGEgaW5jb3JyZWN0IgogICAgaW50IDAKICAgIGJ5dGUgImFzc2V0X2EiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMgogICAgPT0KICAgIGFzc2VydCAvLyBhc3NldCBhIGluY29ycmVjdAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIyNgogICAgLy8gYXNzZXJ0IGJfYXNzZXQgPT0gc2VsZi5hc3NldF9iLCAiYXNzZXQgYiBpbmNvcnJlY3QiCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc3NldF9iIGV4aXN0cwogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgYXNzZXJ0IC8vIGFzc2V0IGIgaW5jb3JyZWN0CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjI4CiAgICAvLyBhc3NlcnQgc3dhcF94ZmVyLmFzc2V0X2Ftb3VudCA+IDAsICJhbW91bnQgbWluaW11bSBub3QgbWV0IgogICAgZnJhbWVfZGlnIC0zCiAgICBndHhucyBBc3NldEFtb3VudAogICAgZHVwCiAgICBhc3NlcnQgLy8gYW1vdW50IG1pbmltdW0gbm90IG1ldAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIyOQogICAgLy8gYXNzZXJ0IHN3YXBfeGZlci5zZW5kZXIgPT0gVHhuLnNlbmRlciwgInNlbmRlciBpbnZhbGlkIgogICAgZnJhbWVfZGlnIC0zCiAgICBndHhucyBTZW5kZXIKICAgIHR4biBTZW5kZXIKICAgID09CiAgICBhc3NlcnQgLy8gc2VuZGVyIGludmFsaWQKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzIKICAgIC8vIGNhc2Ugc2VsZi5hc3NldF9hOgogICAgaW50IDAKICAgIGJ5dGUgImFzc2V0X2EiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYSBleGlzdHMKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzYKICAgIC8vIGNhc2Ugc2VsZi5hc3NldF9iOgogICAgaW50IDAKICAgIGJ5dGUgImFzc2V0X2IiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNzZXRfYiBleGlzdHMKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzEKICAgIC8vIG1hdGNoIHN3YXBfeGZlci54ZmVyX2Fzc2V0OgogICAgZnJhbWVfZGlnIC0zCiAgICBndHhucyBYZmVyQXNzZXQKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzEtMjQxCiAgICAvLyBtYXRjaCBzd2FwX3hmZXIueGZlcl9hc3NldDoKICAgIC8vICAgICBjYXNlIHNlbGYuYXNzZXRfYToKICAgIC8vICAgICAgICAgaW5fc3VwcGx5ID0gc2VsZi5fY3VycmVudF9iX2JhbGFuY2UoKQogICAgLy8gICAgICAgICBvdXRfc3VwcGx5ID0gc2VsZi5fY3VycmVudF9hX2JhbGFuY2UoKQogICAgLy8gICAgICAgICBvdXRfYXNzZXQgPSBzZWxmLmFzc2V0X2EKICAgIC8vICAgICBjYXNlIHNlbGYuYXNzZXRfYjoKICAgIC8vICAgICAgICAgaW5fc3VwcGx5ID0gc2VsZi5fY3VycmVudF9hX2JhbGFuY2UoKQogICAgLy8gICAgICAgICBvdXRfc3VwcGx5ID0gc2VsZi5fY3VycmVudF9iX2JhbGFuY2UoKQogICAgLy8gICAgICAgICBvdXRfYXNzZXQgPSBzZWxmLmFzc2V0X2IKICAgIC8vICAgICBjYXNlIF86CiAgICAvLyAgICAgICAgIGFzc2VydCBGYWxzZSwgImFzc2V0IGlkIGluY29ycmVjdCIKICAgIG1hdGNoIHN3YXBfc3dpdGNoX2Nhc2VfMEAxIHN3YXBfc3dpdGNoX2Nhc2VfMUAyCiAgICAvLyBhbW0vY29udHJhY3QucHk6MjQxCiAgICAvLyBhc3NlcnQgRmFsc2UsICJhc3NldCBpZCBpbmNvcnJlY3QiCiAgICBlcnIgLy8gYXNzZXQgaWQgaW5jb3JyZWN0Cgpzd2FwX3N3aXRjaF9jYXNlXzBAMToKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzMKICAgIC8vIGluX3N1cHBseSA9IHNlbGYuX2N1cnJlbnRfYl9iYWxhbmNlKCkKICAgIGNhbGxzdWIgX2N1cnJlbnRfYl9iYWxhbmNlCiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzQKICAgIC8vIG91dF9zdXBwbHkgPSBzZWxmLl9jdXJyZW50X2FfYmFsYW5jZSgpCiAgICBjYWxsc3ViIF9jdXJyZW50X2FfYmFsYW5jZQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIzNQogICAgLy8gb3V0X2Fzc2V0ID0gc2VsZi5hc3NldF9hCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBzd2FwCiAgICBmcmFtZV9idXJ5IDEKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2EgZXhpc3RzCiAgICBiIHN3YXBfc3dpdGNoX2Nhc2VfbmV4dEA0Cgpzd2FwX3N3aXRjaF9jYXNlXzFAMjoKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzcKICAgIC8vIGluX3N1cHBseSA9IHNlbGYuX2N1cnJlbnRfYV9iYWxhbmNlKCkKICAgIGNhbGxzdWIgX2N1cnJlbnRfYV9iYWxhbmNlCiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIGFtbS9jb250cmFjdC5weToyMzgKICAgIC8vIG91dF9zdXBwbHkgPSBzZWxmLl9jdXJyZW50X2JfYmFsYW5jZSgpCiAgICBjYWxsc3ViIF9jdXJyZW50X2JfYmFsYW5jZQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjIzOQogICAgLy8gb3V0X2Fzc2V0ID0gc2VsZi5hc3NldF9iCiAgICBpbnQgMAogICAgYnl0ZSAiYXNzZXRfYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBzd2FwCiAgICBmcmFtZV9idXJ5IDEKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzc2V0X2IgZXhpc3RzCgpzd2FwX3N3aXRjaF9jYXNlX25leHRANDoKICAgIC8vIGFtbS9jb250cmFjdC5weToyNDMtMjQ1CiAgICAvLyB0b19zd2FwID0gdG9rZW5zX3RvX3N3YXAoCiAgICAvLyAgICAgaW5fYW1vdW50PXN3YXBfeGZlci5hc3NldF9hbW91bnQsIGluX3N1cHBseT1pbl9zdXBwbHksIG91dF9zdXBwbHk9b3V0X3N1cHBseQogICAgLy8gKQogICAgZnJhbWVfZGlnIDIKICAgIGZyYW1lX2RpZyAwCiAgICB1bmNvdmVyIDIKICAgIGNhbGxzdWIgdG9rZW5zX3RvX3N3YXAKICAgIC8vIGFtbS9jb250cmFjdC5weToyNDYKICAgIC8vIGFzc2VydCB0b19zd2FwID4gMCwgInNlbmQgYW1vdW50IHRvbyBsb3ciCiAgICBkdXAKICAgIGFzc2VydCAvLyBzZW5kIGFtb3VudCB0b28gbG93CiAgICAvLyBhbW0vY29udHJhY3QucHk6MjQ4CiAgICAvLyBkb19hc3NldF90cmFuc2ZlcihyZWNlaXZlcj1UeG4uc2VuZGVyLCBhc3NldD1vdXRfYXNzZXQsIGFtb3VudD10b19zd2FwKQogICAgdHhuIFNlbmRlcgogICAgZnJhbWVfZGlnIDEKICAgIHVuY292ZXIgMgogICAgY2FsbHN1YiBkb19hc3NldF90cmFuc2ZlcgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI0OQogICAgLy8gc2VsZi5fdXBkYXRlX3JhdGlvKCkKICAgIGNhbGxzdWIgX3VwZGF0ZV9yYXRpbwogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYW1tLmNvbnRyYWN0LnRva2Vuc190b19zd2FwKGluX2Ftb3VudDogdWludDY0LCBpbl9zdXBwbHk6IHVpbnQ2NCwgb3V0X3N1cHBseTogdWludDY0KSAtPiB1aW50NjQ6CnRva2Vuc190b19zd2FwOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM0OS0zNTAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgdG9rZW5zX3RvX3N3YXAoKiwgaW5fYW1vdW50OiBVSW50NjQsIGluX3N1cHBseTogVUludDY0LCBvdXRfc3VwcGx5OiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDMgMQogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM1MQogICAgLy8gaW5fdG90YWwgPSBTQ0FMRSAqIChpbl9zdXBwbHkgLSBpbl9hbW91bnQpICsgKGluX2Ftb3VudCAqIEZBQ1RPUikKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0zCiAgICAtCiAgICBpbnQgMTAwMAogICAgKgogICAgZnJhbWVfZGlnIC0zCiAgICBpbnQgOTk1CiAgICAqCiAgICBkdXAKICAgIGNvdmVyIDIKICAgICsKICAgIHN3YXAKICAgIC8vIGFtbS9jb250cmFjdC5weTozNTIKICAgIC8vIG91dF90b3RhbCA9IGluX2Ftb3VudCAqIEZBQ1RPUiAqIG91dF9zdXBwbHkKICAgIGZyYW1lX2RpZyAtMQogICAgKgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjM1MwogICAgLy8gcmV0dXJuIG91dF90b3RhbCAvLyBpbl90b3RhbAogICAgc3dhcAogICAgLwogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYW1tLmNvbnRyYWN0LkNvbnN0YW50UHJvZHVjdEFNTS5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjI4CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYW1tL2NvbnRyYWN0LnB5OjMyLTMzCiAgICAvLyAjIFRoZSBhc3NldCBpZCBvZiBhc3NldCBBCiAgICAvLyBzZWxmLmFzc2V0X2EgPSBBc3NldCgpCiAgICBieXRlICJhc3NldF9hIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhbW0vY29udHJhY3QucHk6MzQtMzUKICAgIC8vICMgVGhlIGFzc2V0IGlkIG9mIGFzc2V0IEIKICAgIC8vIHNlbGYuYXNzZXRfYiA9IEFzc2V0KCkKICAgIGJ5dGUgImFzc2V0X2IiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFtbS9jb250cmFjdC5weTozNi0zNwogICAgLy8gIyBUaGUgY3VycmVudCBnb3Zlcm5vciBvZiB0aGlzIGNvbnRyYWN0LCBhbGxvd2VkIHRvIGRvIGFkbWluIHR5cGUgYWN0aW9ucwogICAgLy8gc2VsZi5nb3Zlcm5vciA9IFR4bi5zZW5kZXIKICAgIGJ5dGUgImdvdmVybm9yIgogICAgdHhuIFNlbmRlcgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFtbS9jb250cmFjdC5weTozOC0zOQogICAgLy8gIyBUaGUgYXNzZXQgaWQgb2YgdGhlIFBvb2wgVG9rZW4sIHVzZWQgdG8gdHJhY2sgc2hhcmUgb2YgcG9vbCB0aGUgaG9sZGVyIG1heSByZWNvdmVyCiAgICAvLyBzZWxmLnBvb2xfdG9rZW4gPSBBc3NldCgpCiAgICBieXRlICJwb29sX3Rva2VuIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhbW0vY29udHJhY3QucHk6NDAtNDEKICAgIC8vICMgVGhlIHJhdGlvIGJldHdlZW4gYXNzZXRzIChBKlNjYWxlL0IpCiAgICAvLyBzZWxmLnJhdGlvID0gVUludDY0KDApCiAgICBieXRlICJyYXRpbyIKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5hbW0uY29udHJhY3QuQ29uc3RhbnRQcm9kdWN0QU1NLmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICBpbnQgMQogICAgcmV0dXJuCg==" }, "state": { diff --git a/examples/amm/out_unoptimized/ConstantProductAMM.approval.teal b/examples/amm/out_unoptimized/ConstantProductAMM.approval.teal index 0d313ba374..b5f90a8c90 100644 --- a/examples/amm/out_unoptimized/ConstantProductAMM.approval.teal +++ b/examples/amm/out_unoptimized/ConstantProductAMM.approval.teal @@ -292,12 +292,9 @@ set_governor: // amm/contract.py:46 // self._check_is_governor() callsub _check_is_governor - // amm/contract.py:36-37 - // # The current governor of this contract, allowed to do admin type actions - // self.governor = Txn.sender - byte "governor" // amm/contract.py:47 // self.governor = new_governor + byte "governor" frame_dig -1 app_global_put retsub @@ -313,12 +310,7 @@ _check_is_governor: // Txn.sender == self.governor txn Sender int 0 - // amm/contract.py:36-37 - // # The current governor of this contract, allowed to do admin type actions - // self.governor = Txn.sender byte "governor" - // amm/contract.py:265 - // Txn.sender == self.governor app_global_get_ex assert // check self.governor exists == @@ -339,12 +331,7 @@ bootstrap: // amm/contract.py:66 // assert not self.pool_token, "application has already been bootstrapped" int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:66 - // assert not self.pool_token, "application has already been bootstrapped" app_global_get_ex assert // check self.pool_token exists ! @@ -378,66 +365,40 @@ bootstrap: frame_dig -1 < assert // asset a must be less than asset b - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() - byte "asset_a" // amm/contract.py:73 // self.asset_a = a_asset + byte "asset_a" frame_dig -2 app_global_put - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() - byte "asset_b" // amm/contract.py:74 // self.asset_b = b_asset + byte "asset_b" frame_dig -1 app_global_put // amm/contract.py:75 // self.pool_token = self._create_pool_token() callsub _create_pool_token - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:75 - // self.pool_token = self._create_pool_token() uncover 1 app_global_put // amm/contract.py:77 // self._do_opt_in(self.asset_a) int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:77 - // self._do_opt_in(self.asset_a) app_global_get_ex assert // check self.asset_a exists callsub _do_opt_in // amm/contract.py:78 // self._do_opt_in(self.asset_b) int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:78 - // self._do_opt_in(self.asset_b) app_global_get_ex assert // check self.asset_b exists callsub _do_opt_in // amm/contract.py:79 // return self.pool_token.id int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:79 - // return self.pool_token.id app_global_get_ex assert // check self.pool_token exists retsub @@ -463,12 +424,7 @@ _create_pool_token: // amm/contract.py:272 // asset_name=b"DPT-" + self.asset_a.unit_name + b"-" + self.asset_b.unit_name, int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:272 - // asset_name=b"DPT-" + self.asset_a.unit_name + b"-" + self.asset_b.unit_name, app_global_get_ex assert // check self.asset_a exists asset_params_get AssetUnitName @@ -479,12 +435,7 @@ _create_pool_token: byte 0x2d concat int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:272 - // asset_name=b"DPT-" + self.asset_a.unit_name + b"-" + self.asset_b.unit_name, app_global_get_ex assert // check self.asset_b exists asset_params_get AssetUnitName @@ -648,13 +599,7 @@ mint: // # well-formed mint // assert pool_asset == self.pool_token, "asset pool incorrect" int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:113-114 - // # well-formed mint - // assert pool_asset == self.pool_token, "asset pool incorrect" app_global_get_ex assert // check self.pool_token exists frame_dig -3 @@ -664,12 +609,7 @@ mint: // amm/contract.py:115 // assert a_asset == self.asset_a, "asset a incorrect" int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:115 - // assert a_asset == self.asset_a, "asset a incorrect" app_global_get_ex assert // check self.asset_a exists frame_dig -2 @@ -679,12 +619,7 @@ mint: // amm/contract.py:116 // assert b_asset == self.asset_b, "asset b incorrect" int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:116 - // assert b_asset == self.asset_b, "asset b incorrect" app_global_get_ex assert // check self.asset_b exists frame_dig -1 @@ -722,12 +657,7 @@ mint: frame_dig -5 gtxns XferAsset int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:124 - // assert a_xfer.xfer_asset == self.asset_a, "asset a incorrect" app_global_get_ex assert // check self.asset_a exists == @@ -756,12 +686,7 @@ mint: frame_dig -4 gtxns XferAsset int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:131 - // assert b_xfer.xfer_asset == self.asset_b, "asset b incorrect" app_global_get_ex assert // check self.asset_b exists == @@ -815,13 +740,7 @@ mint: // do_asset_transfer(receiver=Txn.sender, asset=self.pool_token, amount=to_mint) txn Sender int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:143-144 - // # mint tokens - // do_asset_transfer(receiver=Txn.sender, asset=self.pool_token, amount=to_mint) app_global_get_ex assert // check self.pool_token exists uncover 2 @@ -841,12 +760,7 @@ _check_bootstrapped: // amm/contract.py:253 // assert self.pool_token, "bootstrap method needs to be called first" int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:253 - // assert self.pool_token, "bootstrap method needs to be called first" app_global_get_ex assert // check self.pool_token exists assert // bootstrap method needs to be called first @@ -863,12 +777,7 @@ _current_pool_balance: // return self.pool_token.balance(Global.current_application_address) global CurrentApplicationAddress int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:293 - // return self.pool_token.balance(Global.current_application_address) app_global_get_ex assert // check self.pool_token exists asset_holding_get AssetBalance @@ -886,12 +795,7 @@ _current_a_balance: // return self.asset_a.balance(Global.current_application_address) global CurrentApplicationAddress int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:297 - // return self.asset_a.balance(Global.current_application_address) app_global_get_ex assert // check self.asset_a exists asset_holding_get AssetBalance @@ -909,12 +813,7 @@ _current_b_balance: // return self.asset_b.balance(Global.current_application_address) global CurrentApplicationAddress int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:301 - // return self.asset_b.balance(Global.current_application_address) app_global_get_ex assert // check self.asset_b exists asset_holding_get AssetBalance @@ -1041,12 +940,7 @@ _update_ratio: * uncover 1 / - // amm/contract.py:40-41 - // # The ratio between assets (A*Scale/B) - // self.ratio = UInt64(0) byte "ratio" - // amm/contract.py:260 - // self.ratio = a_balance * SCALE // b_balance uncover 1 app_global_put retsub @@ -1076,12 +970,7 @@ burn: // amm/contract.py:172 // assert pool_asset == self.pool_token, "asset pool incorrect" int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:172 - // assert pool_asset == self.pool_token, "asset pool incorrect" app_global_get_ex assert // check self.pool_token exists frame_dig -3 @@ -1091,12 +980,7 @@ burn: // amm/contract.py:173 // assert a_asset == self.asset_a, "asset a incorrect" int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:173 - // assert a_asset == self.asset_a, "asset a incorrect" app_global_get_ex assert // check self.asset_a exists frame_dig -2 @@ -1106,12 +990,7 @@ burn: // amm/contract.py:174 // assert b_asset == self.asset_b, "asset b incorrect" int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:174 - // assert b_asset == self.asset_b, "asset b incorrect" app_global_get_ex assert // check self.asset_b exists frame_dig -1 @@ -1141,12 +1020,7 @@ burn: frame_dig -4 gtxns XferAsset int 0 - // amm/contract.py:38-39 - // # The asset id of the Pool Token, used to track share of pool the holder may recover - // self.pool_token = Asset() byte "pool_token" - // amm/contract.py:180 - // assert pool_xfer.xfer_asset == self.pool_token, "asset pool incorrect" app_global_get_ex assert // check self.pool_token exists == @@ -1204,13 +1078,7 @@ burn: // do_asset_transfer(receiver=Txn.sender, asset=self.asset_a, amount=a_amt) txn Sender int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:197-198 - // # Send back commensurate amt of a - // do_asset_transfer(receiver=Txn.sender, asset=self.asset_a, amount=a_amt) app_global_get_ex assert // check self.asset_a exists uncover 2 @@ -1220,13 +1088,7 @@ burn: // do_asset_transfer(receiver=Txn.sender, asset=self.asset_b, amount=b_amt) txn Sender int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:200-201 - // # Send back commensurate amt of b - // do_asset_transfer(receiver=Txn.sender, asset=self.asset_b, amount=b_amt) app_global_get_ex assert // check self.asset_b exists uncover 2 @@ -1284,12 +1146,7 @@ swap: // amm/contract.py:225 // assert a_asset == self.asset_a, "asset a incorrect" int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:225 - // assert a_asset == self.asset_a, "asset a incorrect" app_global_get_ex assert // check self.asset_a exists frame_dig -2 @@ -1299,12 +1156,7 @@ swap: // amm/contract.py:226 // assert b_asset == self.asset_b, "asset b incorrect" int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:226 - // assert b_asset == self.asset_b, "asset b incorrect" app_global_get_ex assert // check self.asset_b exists frame_dig -1 @@ -1328,23 +1180,13 @@ swap: // amm/contract.py:232 // case self.asset_a: int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:232 - // case self.asset_a: app_global_get_ex assert // check self.asset_a exists // amm/contract.py:236 // case self.asset_b: int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:236 - // case self.asset_b: app_global_get_ex assert // check self.asset_b exists // amm/contract.py:231 @@ -1382,12 +1224,7 @@ swap_switch_case_0@1: // amm/contract.py:235 // out_asset = self.asset_a int 0 - // amm/contract.py:32-33 - // # The asset id of asset A - // self.asset_a = Asset() byte "asset_a" - // amm/contract.py:235 - // out_asset = self.asset_a app_global_get_ex assert // check self.asset_a exists frame_bury 1 @@ -1404,12 +1241,7 @@ swap_switch_case_1@2: // amm/contract.py:239 // out_asset = self.asset_b int 0 - // amm/contract.py:34-35 - // # The asset id of asset B - // self.asset_b = Asset() byte "asset_b" - // amm/contract.py:239 - // out_asset = self.asset_b app_global_get_ex assert // check self.asset_b exists frame_bury 1 diff --git a/examples/auction/out/Auction.approval.mir b/examples/auction/out/Auction.approval.mir index 9e93d911bc..c6c93472b5 100644 --- a/examples/auction/out/Auction.approval.mir +++ b/examples/auction/out/Auction.approval.mir @@ -242,7 +242,7 @@ opt_into_asset_block@0: // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) asset#0 | tmp%2#0 # Only allow app creator to opt the app account into a ASA\nassert Txn.sender == Global.creator_a... auction/contract.py:27-28 assert // Only creator can opt in to ASA // (𝕡) asset#0 | # Only allow app creator to opt the app account into a ASA\nassert Txn.sender == Global.creator_a... auction/contract.py:27-28 int 0 // (𝕡) asset#0 | 0 y a ASA hasn't already been opted into\nassert self.asa auction/contract.py:29-30 - byte "asa" // (𝕡) asset#0 | 0,"asa" self.asa auction/contract.py:21 + byte "asa" // (𝕡) asset#0 | 0,"asa" y a ASA hasn't already been opted into\nassert self.asa auction/contract.py:29-30 app_global_get_ex // (𝕡) asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 y a ASA hasn't already been opted into\nassert self.asa auction/contract.py:29-30 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) asset#0 | maybe_exists%0#0,{app_global_get_ex}.0 y a ASA hasn't already been opted into\nassert self.asa auction/contract.py:29-30 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%0#0,maybe_exists%0#0 y a ASA hasn't already been opted into\nassert self.asa auction/contract.py:29-30 @@ -253,7 +253,7 @@ opt_into_asset_block@0: // virtual: store tmp%3#0 to l-stack (no copy) (𝕡) asset#0 | tmp%3#0 y a ASA hasn't already been opted into\nassert self.asa.id == 0 auction/contract.py:29-30 // virtual: load tmp%3#0 from l-stack (no copy) (𝕡) asset#0 | tmp%3#0 # Verify a ASA hasn't already been opted into\nassert self.asa.id == 0, "ASA already opted in" auction/contract.py:29-30 assert // ASA already opted in // (𝕡) asset#0 | # Verify a ASA hasn't already been opted into\nassert self.asa.id == 0, "ASA already opted in" auction/contract.py:29-30 - byte "asa" // (𝕡) asset#0 | "asa" self.asa auction/contract.py:21 + byte "asa" // (𝕡) asset#0 | "asa" # Save ASA ID in global state\nself.asa auction/contract.py:31-32 frame_dig -1 // load asset#0 from parameters (𝕡) asset#0 | "asa",asset#0 # Save ASA ID in global state\nself.asa = asset auction/contract.py:31-32 app_global_put // (𝕡) asset#0 | # Save ASA ID in global state\nself.asa = asset auction/contract.py:31-32 itxn_begin // (𝕡) asset#0 | # Submit opt-in transaction: 0 asset transfer to self\nitxn.AssetTransfer(\nasset_receiver=Global... auction/contract.py:34-38 @@ -287,7 +287,7 @@ start_auction_block@0: // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) starting_price#0,length#0,axfer#0 | tmp%2#0 assert Txn.sender == Global.creator_address, "auction must be started by creator" auction/contract.py:47 assert // auction must be started by creator // (𝕡) starting_price#0,length#0,axfer#0 | assert Txn.sender == Global.creator_address, "auction must be started by creator" auction/contract.py:47 int 0 // (𝕡) starting_price#0,length#0,axfer#0 | 0 e the auction hasn't already been started\nassert self.auction_end auction/contract.py:49-50 - byte "auction_end" // (𝕡) starting_price#0,length#0,axfer#0 | 0,"auction_end" self.auction_end auction/contract.py:18 + byte "auction_end" // (𝕡) starting_price#0,length#0,axfer#0 | 0,"auction_end" e the auction hasn't already been started\nassert self.auction_end auction/contract.py:49-50 app_global_get_ex // (𝕡) starting_price#0,length#0,axfer#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 e the auction hasn't already been started\nassert self.auction_end auction/contract.py:49-50 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) starting_price#0,length#0,axfer#0 | maybe_exists%0#0,{app_global_get_ex}.0 e the auction hasn't already been started\nassert self.auction_end auction/contract.py:49-50 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) starting_price#0,length#0,axfer#0 | maybe_value%0#0,maybe_exists%0#0 e the auction hasn't already been started\nassert self.auction_end auction/contract.py:49-50 @@ -312,7 +312,7 @@ start_auction_block@0: frame_dig -1 // load axfer#0 from parameters (𝕡) starting_price#0,length#0,axfer#0 | axfer#0 \nself.asa_amount = axfer.asset_amount auction/contract.py:57-58 gtxns AssetAmount // (𝕡) starting_price#0,length#0,axfer#0 | {gtxns} \nself.asa_amount = axfer.asset_amount auction/contract.py:57-58 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕡) starting_price#0,length#0,axfer#0 | new_state_value%0#0 \nself.asa_amount = axfer.asset_amount auction/contract.py:57-58 - byte "asa_amount" // (𝕡) starting_price#0,length#0,axfer#0 | new_state_value%0#0,"asa_amount" self.asa_amount auction/contract.py:20 + byte "asa_amount" // (𝕡) starting_price#0,length#0,axfer#0 | new_state_value%0#0,"asa_amount" # Set global state\nself.asa_amount auction/contract.py:57-58 uncover 1 // load new_state_value%0#0 from l-stack (no copy) (𝕡) starting_price#0,length#0,axfer#0 | "asa_amount",new_state_value%0#0 # Set global state\nself.asa_amount = axfer.asset_amount auction/contract.py:57-58 app_global_put // (𝕡) starting_price#0,length#0,axfer#0 | # Set global state\nself.asa_amount = axfer.asset_amount auction/contract.py:57-58 global LatestTimestamp // (𝕡) starting_price#0,length#0,axfer#0 | {global} Global.latest_timestamp auction/contract.py:59 @@ -321,10 +321,10 @@ start_auction_block@0: frame_dig -2 // load length#0 from parameters (𝕡) starting_price#0,length#0,axfer#0 | tmp%7#0,length#0 Global.latest_timestamp + length auction/contract.py:59 + // (𝕡) starting_price#0,length#0,axfer#0 | {+} Global.latest_timestamp + length auction/contract.py:59 // virtual: store new_state_value%1#0 to l-stack (no copy) (𝕡) starting_price#0,length#0,axfer#0 | new_state_value%1#0 Global.latest_timestamp + length auction/contract.py:59 - byte "auction_end" // (𝕡) starting_price#0,length#0,axfer#0 | new_state_value%1#0,"auction_end" self.auction_end auction/contract.py:18 + byte "auction_end" // (𝕡) starting_price#0,length#0,axfer#0 | new_state_value%1#0,"auction_end" self.auction_end auction/contract.py:59 uncover 1 // load new_state_value%1#0 from l-stack (no copy) (𝕡) starting_price#0,length#0,axfer#0 | "auction_end",new_state_value%1#0 self.auction_end = Global.latest_timestamp + length auction/contract.py:59 app_global_put // (𝕡) starting_price#0,length#0,axfer#0 | self.auction_end = Global.latest_timestamp + length auction/contract.py:59 - byte "previous_bid" // (𝕡) starting_price#0,length#0,axfer#0 | "previous_bid" self.previous_bid auction/contract.py:19 + byte "previous_bid" // (𝕡) starting_price#0,length#0,axfer#0 | "previous_bid" self.previous_bid auction/contract.py:60 frame_dig -3 // load starting_price#0 from parameters (𝕡) starting_price#0,length#0,axfer#0 | "previous_bid",starting_price#0 self.previous_bid = starting_price auction/contract.py:60 app_global_put // (𝕡) starting_price#0,length#0,axfer#0 | self.previous_bid = starting_price auction/contract.py:60 retsub // @@ -338,7 +338,7 @@ bid_block@0: global LatestTimestamp // (𝕡) pay#0 | {global} e auction hasn't ended\nassert Global.latest_timestamp auction/contract.py:68-69 // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) pay#0 | tmp%0#0 e auction hasn't ended\nassert Global.latest_timestamp auction/contract.py:68-69 int 0 // (𝕡) pay#0 | tmp%0#0,0 \nassert Global.latest_timestamp < self.auction_end auction/contract.py:68-69 - byte "auction_end" // (𝕡) pay#0 | tmp%0#0,0,"auction_end" self.auction_end auction/contract.py:18 + byte "auction_end" // (𝕡) pay#0 | tmp%0#0,0,"auction_end" \nassert Global.latest_timestamp < self.auction_end auction/contract.py:68-69 app_global_get_ex // (𝕡) pay#0 | tmp%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 \nassert Global.latest_timestamp < self.auction_end auction/contract.py:68-69 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) pay#0 | tmp%0#0,maybe_exists%0#0,{app_global_get_ex}.0 \nassert Global.latest_timestamp < self.auction_end auction/contract.py:68-69 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) pay#0 | tmp%0#0,maybe_value%0#0,maybe_exists%0#0 \nassert Global.latest_timestamp < self.auction_end auction/contract.py:68-69 @@ -365,7 +365,7 @@ bid_block@0: gtxns Amount // (𝕡) pay#0 | tmp%2#0,{gtxns} pay.amount auction/contract.py:73 // virtual: store tmp%5#0 to l-stack (no copy) (𝕡) pay#0 | tmp%2#0,tmp%5#0 pay.amount auction/contract.py:73 int 0 // (𝕡) pay#0 | tmp%2#0,tmp%5#0,0 self.previous_bid auction/contract.py:73 - byte "previous_bid" // (𝕡) pay#0 | tmp%2#0,tmp%5#0,0,"previous_bid" self.previous_bid auction/contract.py:19 + byte "previous_bid" // (𝕡) pay#0 | tmp%2#0,tmp%5#0,0,"previous_bid" self.previous_bid auction/contract.py:73 app_global_get_ex // (𝕡) pay#0 | tmp%2#0,tmp%5#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.previous_bid auction/contract.py:73 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) pay#0 | tmp%2#0,tmp%5#0,maybe_exists%1#0,{app_global_get_ex}.0 self.previous_bid auction/contract.py:73 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) pay#0 | tmp%2#0,tmp%5#0,maybe_value%1#0,maybe_exists%1#0 self.previous_bid auction/contract.py:73 @@ -377,16 +377,16 @@ bid_block@0: // virtual: store tmp%6#0 to l-stack (no copy) (𝕡) pay#0 | tmp%2#0,tmp%5#0,tmp%6#0 pay.amount > self.previous_bid, "Bid must be higher than previous bid" auction/contract.py:73 // virtual: load tmp%6#0 from l-stack (no copy) (𝕡) pay#0 | tmp%2#0,tmp%5#0,tmp%6#0 assert pay.amount > self.previous_bid, "Bid must be higher than previous bid" auction/contract.py:73 assert // Bid must be higher than previous bid // (𝕡) pay#0 | tmp%2#0,tmp%5#0 assert pay.amount > self.previous_bid, "Bid must be higher than previous bid" auction/contract.py:73 - byte "previous_bid" // (𝕡) pay#0 | tmp%2#0,tmp%5#0,"previous_bid" self.previous_bid auction/contract.py:19 + byte "previous_bid" // (𝕡) pay#0 | tmp%2#0,tmp%5#0,"previous_bid" # set global state\nself.previous_bid auction/contract.py:75-76 dig 1 // load tmp%5#0 from l-stack (copy) (𝕡) pay#0 | tmp%2#0,tmp%5#0,"previous_bid",tmp%5#0 # set global state\nself.previous_bid = pay.amount auction/contract.py:75-76 app_global_put // (𝕡) pay#0 | tmp%2#0,tmp%5#0 # set global state\nself.previous_bid = pay.amount auction/contract.py:75-76 - byte "previous_bidder" // (𝕡) pay#0 | tmp%2#0,tmp%5#0,"previous_bidder" self.previous_bidder auction/contract.py:22 + byte "previous_bidder" // (𝕡) pay#0 | tmp%2#0,tmp%5#0,"previous_bidder" self.previous_bidder auction/contract.py:77 uncover 2 // load tmp%2#0 from l-stack (no copy) (𝕡) pay#0 | tmp%5#0,"previous_bidder",tmp%2#0 self.previous_bidder = pay.sender auction/contract.py:77 app_global_put // (𝕡) pay#0 | tmp%5#0 self.previous_bidder = pay.sender auction/contract.py:77 txn Sender // (𝕡) pay#0 | tmp%5#0,{txn} unt\nself.claimable_amount[Txn.sender auction/contract.py:79-80 // virtual: store tmp%7#0 to l-stack (no copy) (𝕡) pay#0 | tmp%5#0,tmp%7#0 unt\nself.claimable_amount[Txn.sender auction/contract.py:79-80 // virtual: load tmp%7#0 from l-stack (no copy) (𝕡) pay#0 | tmp%5#0,tmp%7#0 # Update claimable amount\nself.claimable_amount[Txn.sender] = pay.amount auction/contract.py:79-80 - byte "claim" // (𝕡) pay#0 | tmp%5#0,tmp%7#0,"claim" "claim" auction/contract.py:23 + byte "claim" // (𝕡) pay#0 | tmp%5#0,tmp%7#0,"claim" # Update claimable amount\nself.claimable_amount auction/contract.py:79-80 uncover 2 // load tmp%5#0 from l-stack (no copy) (𝕡) pay#0 | tmp%7#0,"claim",tmp%5#0 # Update claimable amount\nself.claimable_amount[Txn.sender] = pay.amount auction/contract.py:79-80 app_local_put // (𝕡) pay#0 | # Update claimable amount\nself.claimable_amount[Txn.sender] = pay.amount auction/contract.py:79-80 retsub // @@ -401,7 +401,7 @@ claim_bids_block@0: // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Txn.sender auction/contract.py:84 // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 self.claimable_amount[Txn.sender] auction/contract.py:84 int 0 // tmp%0#0,0 self.claimable_amount[Txn.sender] auction/contract.py:84 - byte "claim" // tmp%0#0,0,"claim" "claim" auction/contract.py:23 + byte "claim" // tmp%0#0,0,"claim" self.claimable_amount auction/contract.py:84 app_local_get_ex // {app_local_get_ex}.0,{app_local_get_ex}.1 self.claimable_amount[Txn.sender] auction/contract.py:84 cover 1 // store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_local_get_ex}.0 self.claimable_amount[Txn.sender] auction/contract.py:84 dup @@ -412,7 +412,7 @@ claim_bids_block@0: txn Sender // (𝕗) original_amount#0 | original_amount#0,{txn} ubtract previous bid if sender is previous bidder\nif Txn.sender auction/contract.py:86-87 // virtual: store tmp%1#0 to l-stack (no copy) (𝕗) original_amount#0 | original_amount#0,tmp%1#0 ubtract previous bid if sender is previous bidder\nif Txn.sender auction/contract.py:86-87 int 0 // (𝕗) original_amount#0 | original_amount#0,tmp%1#0,0 us bid if sender is previous bidder\nif Txn.sender == self.previous_bidder auction/contract.py:86-87 - byte "previous_bidder" // (𝕗) original_amount#0 | original_amount#0,tmp%1#0,0,"previous_bidder" self.previous_bidder auction/contract.py:22 + byte "previous_bidder" // (𝕗) original_amount#0 | original_amount#0,tmp%1#0,0,"previous_bidder" us bid if sender is previous bidder\nif Txn.sender == self.previous_bidder auction/contract.py:86-87 app_global_get_ex // (𝕗) original_amount#0 | original_amount#0,tmp%1#0,{app_global_get_ex}.0,{app_global_get_ex}.1 us bid if sender is previous bidder\nif Txn.sender == self.previous_bidder auction/contract.py:86-87 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕗) original_amount#0 | original_amount#0,tmp%1#0,maybe_exists%1#0,{app_global_get_ex}.0 us bid if sender is previous bidder\nif Txn.sender == self.previous_bidder auction/contract.py:86-87 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕗) original_amount#0 | original_amount#0,tmp%1#0,maybe_value%1#0,maybe_exists%1#0 us bid if sender is previous bidder\nif Txn.sender == self.previous_bidder auction/contract.py:86-87 @@ -430,7 +430,7 @@ claim_bids_block@0: claim_bids_if_body@1: int 0 // (𝕗) original_amount#0,amount#1 | 0 self.previous_bid auction/contract.py:88 - byte "previous_bid" // (𝕗) original_amount#0,amount#1 | 0,"previous_bid" self.previous_bid auction/contract.py:19 + byte "previous_bid" // (𝕗) original_amount#0,amount#1 | 0,"previous_bid" self.previous_bid auction/contract.py:88 app_global_get_ex // (𝕗) original_amount#0,amount#1 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.previous_bid auction/contract.py:88 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕗) original_amount#0,amount#1 | maybe_exists%2#0,{app_global_get_ex}.0 self.previous_bid auction/contract.py:88 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕗) original_amount#0,amount#1 | maybe_value%2#0,maybe_exists%2#0 self.previous_bid auction/contract.py:88 @@ -463,7 +463,7 @@ claim_bids_after_if_else@2: - // (𝕗) original_amount#0,amount#1 | tmp%3#0,{-} original_amount - amount auction/contract.py:95 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕗) original_amount#0,amount#1 | tmp%3#0,new_state_value%0#0 original_amount - amount auction/contract.py:95 uncover 1 // load tmp%3#0 from l-stack (no copy) (𝕗) original_amount#0,amount#1 | new_state_value%0#0,tmp%3#0 self.claimable_amount[Txn.sender] = original_amount - amount auction/contract.py:95 - byte "claim" // (𝕗) original_amount#0,amount#1 | new_state_value%0#0,tmp%3#0,"claim" "claim" auction/contract.py:23 + byte "claim" // (𝕗) original_amount#0,amount#1 | new_state_value%0#0,tmp%3#0,"claim" self.claimable_amount auction/contract.py:95 uncover 2 // load new_state_value%0#0 from l-stack (no copy) (𝕗) original_amount#0,amount#1 | tmp%3#0,"claim",new_state_value%0#0 self.claimable_amount[Txn.sender] = original_amount - amount auction/contract.py:95 app_local_put // (𝕗) original_amount#0,amount#1 | self.claimable_amount[Txn.sender] = original_amount - amount auction/contract.py:95 retsub // @@ -477,7 +477,7 @@ claim_asset_block@0: global LatestTimestamp // (𝕡) asset#0 | {global} Global.latest_timestamp auction/contract.py:99 // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) asset#0 | tmp%0#0 Global.latest_timestamp auction/contract.py:99 int 0 // (𝕡) asset#0 | tmp%0#0,0 self.auction_end auction/contract.py:99 - byte "auction_end" // (𝕡) asset#0 | tmp%0#0,0,"auction_end" self.auction_end auction/contract.py:18 + byte "auction_end" // (𝕡) asset#0 | tmp%0#0,0,"auction_end" self.auction_end auction/contract.py:99 app_global_get_ex // (𝕡) asset#0 | tmp%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.auction_end auction/contract.py:99 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) asset#0 | tmp%0#0,maybe_exists%0#0,{app_global_get_ex}.0 self.auction_end auction/contract.py:99 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) asset#0 | tmp%0#0,maybe_value%0#0,maybe_exists%0#0 self.auction_end auction/contract.py:99 @@ -491,21 +491,21 @@ claim_asset_block@0: assert // auction has not ended // (𝕡) asset#0 | assert Global.latest_timestamp > self.auction_end, "auction has not ended" auction/contract.py:99 itxn_begin // (𝕡) asset#0 | # Send ASA to previous bidder\nitxn.AssetTransfer(\nxfer_asset=asset,\nasset_close_to=self.previo... auction/contract.py:100-106 int 0 // (𝕡) asset#0 | 0 self.previous_bidder auction/contract.py:103 - byte "previous_bidder" // (𝕡) asset#0 | 0,"previous_bidder" self.previous_bidder auction/contract.py:22 + byte "previous_bidder" // (𝕡) asset#0 | 0,"previous_bidder" self.previous_bidder auction/contract.py:103 app_global_get_ex // (𝕡) asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.previous_bidder auction/contract.py:103 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) asset#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.previous_bidder auction/contract.py:103 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%1#0,maybe_exists%1#0 self.previous_bidder auction/contract.py:103 // virtual: load maybe_exists%1#0 from l-stack (no copy) (𝕡) asset#0 | maybe_value%1#0,maybe_exists%1#0 self.previous_bidder auction/contract.py:103 assert // check self.previous_bidder exists // (𝕡) asset#0 | maybe_value%1#0 self.previous_bidder auction/contract.py:103 int 0 // (𝕡) asset#0 | maybe_value%1#0,0 self.previous_bidder auction/contract.py:104 - byte "previous_bidder" // (𝕡) asset#0 | maybe_value%1#0,0,"previous_bidder" self.previous_bidder auction/contract.py:22 + byte "previous_bidder" // (𝕡) asset#0 | maybe_value%1#0,0,"previous_bidder" self.previous_bidder auction/contract.py:104 app_global_get_ex // (𝕡) asset#0 | maybe_value%1#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.previous_bidder auction/contract.py:104 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%1#0,maybe_exists%2#0,{app_global_get_ex}.0 self.previous_bidder auction/contract.py:104 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0,maybe_exists%2#0 self.previous_bidder auction/contract.py:104 // virtual: load maybe_exists%2#0 from l-stack (no copy) (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0,maybe_exists%2#0 self.previous_bidder auction/contract.py:104 assert // check self.previous_bidder exists // (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0 self.previous_bidder auction/contract.py:104 int 0 // (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0,0 self.asa_amount auction/contract.py:105 - byte "asa_amount" // (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0,0,"asa_amount" self.asa_amount auction/contract.py:20 + byte "asa_amount" // (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0,0,"asa_amount" self.asa_amount auction/contract.py:105 app_global_get_ex // (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.asa_amount auction/contract.py:105 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0,maybe_exists%3#0,{app_global_get_ex}.0 self.asa_amount auction/contract.py:105 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%1#0,maybe_value%2#0,maybe_value%3#0,maybe_exists%3#0 self.asa_amount auction/contract.py:105 diff --git a/examples/auction/out/Auction.approval.teal b/examples/auction/out/Auction.approval.teal index a97cf7f7d2..e0c0187c8c 100644 --- a/examples/auction/out/Auction.approval.teal +++ b/examples/auction/out/Auction.approval.teal @@ -176,22 +176,15 @@ opt_into_asset: // # Verify a ASA hasn't already been opted into // assert self.asa.id == 0, "ASA already opted in" int 0 - // auction/contract.py:21 - // self.asa = Asset() byte "asa" - // auction/contract.py:29-30 - // # Verify a ASA hasn't already been opted into - // assert self.asa.id == 0, "ASA already opted in" app_global_get_ex assert // check self.asa exists ! assert // ASA already opted in - // auction/contract.py:21 - // self.asa = Asset() - byte "asa" // auction/contract.py:31-32 // # Save ASA ID in global state // self.asa = asset + byte "asa" frame_dig -1 app_global_put // auction/contract.py:34-38 @@ -245,12 +238,7 @@ start_auction: // # Ensure the auction hasn't already been started // assert self.auction_end == 0, "auction already started" int 0 - // auction/contract.py:18 - // self.auction_end = UInt64(0) byte "auction_end" - // auction/contract.py:49-50 - // # Ensure the auction hasn't already been started - // assert self.auction_end == 0, "auction already started" app_global_get_ex assert // check self.auction_end exists ! @@ -272,12 +260,7 @@ start_auction: // self.asa_amount = axfer.asset_amount frame_dig -1 gtxns AssetAmount - // auction/contract.py:20 - // self.asa_amount = UInt64(0) byte "asa_amount" - // auction/contract.py:57-58 - // # Set global state - // self.asa_amount = axfer.asset_amount swap app_global_put // auction/contract.py:59 @@ -285,18 +268,12 @@ start_auction: global LatestTimestamp frame_dig -2 + - // auction/contract.py:18 - // self.auction_end = UInt64(0) byte "auction_end" - // auction/contract.py:59 - // self.auction_end = Global.latest_timestamp + length swap app_global_put - // auction/contract.py:19 - // self.previous_bid = UInt64(0) - byte "previous_bid" // auction/contract.py:60 // self.previous_bid = starting_price + byte "previous_bid" frame_dig -3 app_global_put retsub @@ -313,12 +290,7 @@ bid: // assert Global.latest_timestamp < self.auction_end, "auction has ended" global LatestTimestamp int 0 - // auction/contract.py:18 - // self.auction_end = UInt64(0) byte "auction_end" - // auction/contract.py:68-69 - // # Ensure auction hasn't ended - // assert Global.latest_timestamp < self.auction_end, "auction has ended" app_global_get_ex assert // check self.auction_end exists < @@ -337,41 +309,28 @@ bid: frame_dig -1 gtxns Amount int 0 - // auction/contract.py:19 - // self.previous_bid = UInt64(0) byte "previous_bid" - // auction/contract.py:73 - // assert pay.amount > self.previous_bid, "Bid must be higher than previous bid" app_global_get_ex assert // check self.previous_bid exists dig 1 < assert // Bid must be higher than previous bid - // auction/contract.py:19 - // self.previous_bid = UInt64(0) - byte "previous_bid" // auction/contract.py:75-76 // # set global state // self.previous_bid = pay.amount + byte "previous_bid" dig 1 app_global_put - // auction/contract.py:22 - // self.previous_bidder = Account() - byte "previous_bidder" // auction/contract.py:77 // self.previous_bidder = pay.sender + byte "previous_bidder" uncover 2 app_global_put // auction/contract.py:79-80 // # Update claimable amount // self.claimable_amount[Txn.sender] = pay.amount txn Sender - // auction/contract.py:23 - // self.claimable_amount = LocalState(UInt64, key="claim", description="The claimable amount") byte "claim" - // auction/contract.py:79-80 - // # Update claimable amount - // self.claimable_amount[Txn.sender] = pay.amount uncover 2 app_local_put retsub @@ -387,11 +346,7 @@ claim_bids: // amount = original_amount = self.claimable_amount[Txn.sender] txn Sender int 0 - // auction/contract.py:23 - // self.claimable_amount = LocalState(UInt64, key="claim", description="The claimable amount") byte "claim" - // auction/contract.py:84 - // amount = original_amount = self.claimable_amount[Txn.sender] app_local_get_ex swap dup @@ -402,12 +357,7 @@ claim_bids: // if Txn.sender == self.previous_bidder: txn Sender int 0 - // auction/contract.py:22 - // self.previous_bidder = Account() byte "previous_bidder" - // auction/contract.py:86-87 - // # subtract previous bid if sender is previous bidder - // if Txn.sender == self.previous_bidder: app_global_get_ex assert // check self.previous_bidder exists == @@ -415,11 +365,7 @@ claim_bids: // auction/contract.py:88 // amount -= self.previous_bid int 0 - // auction/contract.py:19 - // self.previous_bid = UInt64(0) byte "previous_bid" - // auction/contract.py:88 - // amount -= self.previous_bid app_global_get_ex assert // check self.previous_bid exists frame_dig 0 @@ -459,11 +405,7 @@ claim_bids_after_if_else@2: frame_dig 0 uncover 2 - - // auction/contract.py:23 - // self.claimable_amount = LocalState(UInt64, key="claim", description="The claimable amount") byte "claim" - // auction/contract.py:95 - // self.claimable_amount[Txn.sender] = original_amount - amount swap app_local_put retsub @@ -479,11 +421,7 @@ claim_asset: // assert Global.latest_timestamp > self.auction_end, "auction has not ended" global LatestTimestamp int 0 - // auction/contract.py:18 - // self.auction_end = UInt64(0) byte "auction_end" - // auction/contract.py:99 - // assert Global.latest_timestamp > self.auction_end, "auction has not ended" app_global_get_ex assert // check self.auction_end exists > @@ -500,31 +438,19 @@ claim_asset: // auction/contract.py:103 // asset_close_to=self.previous_bidder, int 0 - // auction/contract.py:22 - // self.previous_bidder = Account() byte "previous_bidder" - // auction/contract.py:103 - // asset_close_to=self.previous_bidder, app_global_get_ex assert // check self.previous_bidder exists // auction/contract.py:104 // asset_receiver=self.previous_bidder, int 0 - // auction/contract.py:22 - // self.previous_bidder = Account() byte "previous_bidder" - // auction/contract.py:104 - // asset_receiver=self.previous_bidder, app_global_get_ex assert // check self.previous_bidder exists // auction/contract.py:105 // asset_amount=self.asa_amount, int 0 - // auction/contract.py:20 - // self.asa_amount = UInt64(0) byte "asa_amount" - // auction/contract.py:105 - // asset_amount=self.asa_amount, app_global_get_ex assert // check self.asa_amount exists itxn_field AssetAmount diff --git a/examples/auction/out/Auction.arc32.json b/examples/auction/out/Auction.arc32.json index b87591cbbb..33f045013a 100644 --- a/examples/auction/out/Auction.arc32.json +++ b/examples/auction/out/Auction.arc32.json @@ -32,7 +32,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5hdWN0aW9uLmNvbnRyYWN0LkF1Y3Rpb24uYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTYKICAgIC8vIGNsYXNzIEF1Y3Rpb24oQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMAogICAgbWV0aG9kICJvcHRfaW50b19hc3NldChhc3NldCl2b2lkIgogICAgbWV0aG9kICJzdGFydF9hdWN0aW9uKHVpbnQ2NCx1aW50NjQsYXhmZXIpdm9pZCIKICAgIG1ldGhvZCAib3B0X2luKCl2b2lkIgogICAgbWV0aG9kICJiaWQocGF5KXZvaWQiCiAgICBtZXRob2QgImNsYWltX2JpZHMoKXZvaWQiCiAgICBtZXRob2QgImNsYWltX2Fzc2V0KGFzc2V0KXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW50b19hc3NldF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3N0YXJ0X2F1Y3Rpb25fcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW5fcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iaWRfcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jbGFpbV9iaWRzX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fY2xhaW1fYXNzZXRfcm91dGVANwogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2ludG9fYXNzZXRfcm91dGVAMjoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgb3B0X2ludG9fYXNzZXQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3N0YXJ0X2F1Y3Rpb25fcm91dGVAMzoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgYXhmZXIKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBheGZlcgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHN0YXJ0X2F1Y3Rpb24KICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbl9yb3V0ZUA0OgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iaWRfcm91dGVANToKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgYmlkCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jbGFpbV9iaWRzX3JvdXRlQDY6CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgY2xhaW1fYmlkcwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fY2xhaW1fYXNzZXRfcm91dGVANzoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6OTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5Ojk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgY2xhaW1fYXNzZXQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMDoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTYKICAgIC8vIGNsYXNzIEF1Y3Rpb24oQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE0CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE0OgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmF1Y3Rpb24uY29udHJhY3QuQXVjdGlvbi5vcHRfaW50b19hc3NldChhc3NldDogdWludDY0KSAtPiB2b2lkOgpvcHRfaW50b19hc3NldDoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjUtMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIG9wdF9pbnRvX2Fzc2V0KHNlbGYsIGFzc2V0OiBBc3NldCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToyNy0yOAogICAgLy8gIyBPbmx5IGFsbG93IGFwcCBjcmVhdG9yIHRvIG9wdCB0aGUgYXBwIGFjY291bnQgaW50byBhIEFTQQogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gR2xvYmFsLmNyZWF0b3JfYWRkcmVzcywgIk9ubHkgY3JlYXRvciBjYW4gb3B0IGluIHRvIEFTQSIKICAgIHR4biBTZW5kZXIKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgPT0KICAgIGFzc2VydCAvLyBPbmx5IGNyZWF0b3IgY2FuIG9wdCBpbiB0byBBU0EKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjktMzAKICAgIC8vICMgVmVyaWZ5IGEgQVNBIGhhc24ndCBhbHJlYWR5IGJlZW4gb3B0ZWQgaW50bwogICAgLy8gYXNzZXJ0IHNlbGYuYXNhLmlkID09IDAsICJBU0EgYWxyZWFkeSBvcHRlZCBpbiIKICAgIGludCAwCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjIxCiAgICAvLyBzZWxmLmFzYSA9IEFzc2V0KCkKICAgIGJ5dGUgImFzYSIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjktMzAKICAgIC8vICMgVmVyaWZ5IGEgQVNBIGhhc24ndCBhbHJlYWR5IGJlZW4gb3B0ZWQgaW50bwogICAgLy8gYXNzZXJ0IHNlbGYuYXNhLmlkID09IDAsICJBU0EgYWxyZWFkeSBvcHRlZCBpbiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc2EgZXhpc3RzCiAgICAhCiAgICBhc3NlcnQgLy8gQVNBIGFscmVhZHkgb3B0ZWQgaW4KICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjEKICAgIC8vIHNlbGYuYXNhID0gQXNzZXQoKQogICAgYnl0ZSAiYXNhIgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTozMS0zMgogICAgLy8gIyBTYXZlIEFTQSBJRCBpbiBnbG9iYWwgc3RhdGUKICAgIC8vIHNlbGYuYXNhID0gYXNzZXQKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MzQtMzgKICAgIC8vICMgU3VibWl0IG9wdC1pbiB0cmFuc2FjdGlvbjogMCBhc3NldCB0cmFuc2ZlciB0byBzZWxmCiAgICAvLyBpdHhuLkFzc2V0VHJhbnNmZXIoCiAgICAvLyAgICAgYXNzZXRfcmVjZWl2ZXI9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIC8vICAgICB4ZmVyX2Fzc2V0PWFzc2V0LAogICAgLy8gKS5zdWJtaXQoKQogICAgaXR4bl9iZWdpbgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTozNgogICAgLy8gYXNzZXRfcmVjZWl2ZXI9R2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0eG5fZmllbGQgWGZlckFzc2V0CiAgICBpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MzQtMzUKICAgIC8vICMgU3VibWl0IG9wdC1pbiB0cmFuc2FjdGlvbjogMCBhc3NldCB0cmFuc2ZlciB0byBzZWxmCiAgICAvLyBpdHhuLkFzc2V0VHJhbnNmZXIoCiAgICBpbnQgYXhmZXIKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTozNC0zOAogICAgLy8gIyBTdWJtaXQgb3B0LWluIHRyYW5zYWN0aW9uOiAwIGFzc2V0IHRyYW5zZmVyIHRvIHNlbGYKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIC8vICAgICBhc3NldF9yZWNlaXZlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gICAgIHhmZXJfYXNzZXQ9YXNzZXQsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLnN0YXJ0X2F1Y3Rpb24oc3RhcnRpbmdfcHJpY2U6IHVpbnQ2NCwgbGVuZ3RoOiB1aW50NjQsIGF4ZmVyOiB1aW50NjQpIC0+IHZvaWQ6CnN0YXJ0X2F1Y3Rpb246CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjQwLTQ2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzdGFydF9hdWN0aW9uKAogICAgLy8gICAgIHNlbGYsCiAgICAvLyAgICAgc3RhcnRpbmdfcHJpY2U6IFVJbnQ2NCwKICAgIC8vICAgICBsZW5ndGg6IFVJbnQ2NCwKICAgIC8vICAgICBheGZlcjogZ3R4bi5Bc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24sCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NDcKICAgIC8vIGFzc2VydCBUeG4uc2VuZGVyID09IEdsb2JhbC5jcmVhdG9yX2FkZHJlc3MsICJhdWN0aW9uIG11c3QgYmUgc3RhcnRlZCBieSBjcmVhdG9yIgogICAgdHhuIFNlbmRlcgogICAgZ2xvYmFsIENyZWF0b3JBZGRyZXNzCiAgICA9PQogICAgYXNzZXJ0IC8vIGF1Y3Rpb24gbXVzdCBiZSBzdGFydGVkIGJ5IGNyZWF0b3IKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NDktNTAKICAgIC8vICMgRW5zdXJlIHRoZSBhdWN0aW9uIGhhc24ndCBhbHJlYWR5IGJlZW4gc3RhcnRlZAogICAgLy8gYXNzZXJ0IHNlbGYuYXVjdGlvbl9lbmQgPT0gMCwgImF1Y3Rpb24gYWxyZWFkeSBzdGFydGVkIgogICAgaW50IDAKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTgKICAgIC8vIHNlbGYuYXVjdGlvbl9lbmQgPSBVSW50NjQoMCkKICAgIGJ5dGUgImF1Y3Rpb25fZW5kIgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo0OS01MAogICAgLy8gIyBFbnN1cmUgdGhlIGF1Y3Rpb24gaGFzbid0IGFscmVhZHkgYmVlbiBzdGFydGVkCiAgICAvLyBhc3NlcnQgc2VsZi5hdWN0aW9uX2VuZCA9PSAwLCAiYXVjdGlvbiBhbHJlYWR5IHN0YXJ0ZWQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXVjdGlvbl9lbmQgZXhpc3RzCiAgICAhCiAgICBhc3NlcnQgLy8gYXVjdGlvbiBhbHJlYWR5IHN0YXJ0ZWQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NTQKICAgIC8vIGF4ZmVyLmFzc2V0X3JlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgQXNzZXRSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjUyLTU1CiAgICAvLyAjIFZlcmlmeSBheGZlcgogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBheGZlci5hc3NldF9yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzCiAgICAvLyApLCAiYXhmZXIgbXVzdCB0cmFuc2ZlciB0byB0aGlzIGFwcCIKICAgIGFzc2VydCAvLyBheGZlciBtdXN0IHRyYW5zZmVyIHRvIHRoaXMgYXBwCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjU3LTU4CiAgICAvLyAjIFNldCBnbG9iYWwgc3RhdGUKICAgIC8vIHNlbGYuYXNhX2Ftb3VudCA9IGF4ZmVyLmFzc2V0X2Ftb3VudAogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBBc3NldEFtb3VudAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToyMAogICAgLy8gc2VsZi5hc2FfYW1vdW50ID0gVUludDY0KDApCiAgICBieXRlICJhc2FfYW1vdW50IgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo1Ny01OAogICAgLy8gIyBTZXQgZ2xvYmFsIHN0YXRlCiAgICAvLyBzZWxmLmFzYV9hbW91bnQgPSBheGZlci5hc3NldF9hbW91bnQKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBzZWxmLmF1Y3Rpb25fZW5kID0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgKyBsZW5ndGgKICAgIGdsb2JhbCBMYXRlc3RUaW1lc3RhbXAKICAgIGZyYW1lX2RpZyAtMgogICAgKwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxOAogICAgLy8gc2VsZi5hdWN0aW9uX2VuZCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYXVjdGlvbl9lbmQiCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBzZWxmLmF1Y3Rpb25fZW5kID0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgKyBsZW5ndGgKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjE5CiAgICAvLyBzZWxmLnByZXZpb3VzX2JpZCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAicHJldmlvdXNfYmlkIgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo2MAogICAgLy8gc2VsZi5wcmV2aW91c19iaWQgPSBzdGFydGluZ19wcmljZQogICAgZnJhbWVfZGlnIC0zCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLmJpZChwYXk6IHVpbnQ2NCkgLT4gdm9pZDoKYmlkOgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo2Ni02NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYmlkKHNlbGYsIHBheTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24pIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NjgtNjkKICAgIC8vICMgRW5zdXJlIGF1Y3Rpb24gaGFzbid0IGVuZGVkCiAgICAvLyBhc3NlcnQgR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPCBzZWxmLmF1Y3Rpb25fZW5kLCAiYXVjdGlvbiBoYXMgZW5kZWQiCiAgICBnbG9iYWwgTGF0ZXN0VGltZXN0YW1wCiAgICBpbnQgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxOAogICAgLy8gc2VsZi5hdWN0aW9uX2VuZCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYXVjdGlvbl9lbmQiCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjY4LTY5CiAgICAvLyAjIEVuc3VyZSBhdWN0aW9uIGhhc24ndCBlbmRlZAogICAgLy8gYXNzZXJ0IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wIDwgc2VsZi5hdWN0aW9uX2VuZCwgImF1Y3Rpb24gaGFzIGVuZGVkIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmF1Y3Rpb25fZW5kIGV4aXN0cwogICAgPAogICAgYXNzZXJ0IC8vIGF1Y3Rpb24gaGFzIGVuZGVkCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjcxLTcyCiAgICAvLyAjIFZlcmlmeSBwYXltZW50IHRyYW5zYWN0aW9uCiAgICAvLyBhc3NlcnQgcGF5LnNlbmRlciA9PSBUeG4uc2VuZGVyLCAicGF5bWVudCBzZW5kZXIgbXVzdCBtYXRjaCB0cmFuc2FjdGlvbiBzZW5kZXIiCiAgICBmcmFtZV9kaWcgLTEKICAgIGd0eG5zIFNlbmRlcgogICAgZHVwCiAgICB0eG4gU2VuZGVyCiAgICA9PQogICAgYXNzZXJ0IC8vIHBheW1lbnQgc2VuZGVyIG11c3QgbWF0Y2ggdHJhbnNhY3Rpb24gc2VuZGVyCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjczCiAgICAvLyBhc3NlcnQgcGF5LmFtb3VudCA+IHNlbGYucHJldmlvdXNfYmlkLCAiQmlkIG11c3QgYmUgaGlnaGVyIHRoYW4gcHJldmlvdXMgYmlkIgogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBBbW91bnQKICAgIGludCAwCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjE5CiAgICAvLyBzZWxmLnByZXZpb3VzX2JpZCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAicHJldmlvdXNfYmlkIgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo3MwogICAgLy8gYXNzZXJ0IHBheS5hbW91bnQgPiBzZWxmLnByZXZpb3VzX2JpZCwgIkJpZCBtdXN0IGJlIGhpZ2hlciB0aGFuIHByZXZpb3VzIGJpZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wcmV2aW91c19iaWQgZXhpc3RzCiAgICBkaWcgMQogICAgPAogICAgYXNzZXJ0IC8vIEJpZCBtdXN0IGJlIGhpZ2hlciB0aGFuIHByZXZpb3VzIGJpZAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxOQogICAgLy8gc2VsZi5wcmV2aW91c19iaWQgPSBVSW50NjQoMCkKICAgIGJ5dGUgInByZXZpb3VzX2JpZCIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NzUtNzYKICAgIC8vICMgc2V0IGdsb2JhbCBzdGF0ZQogICAgLy8gc2VsZi5wcmV2aW91c19iaWQgPSBwYXkuYW1vdW50CiAgICBkaWcgMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjIKICAgIC8vIHNlbGYucHJldmlvdXNfYmlkZGVyID0gQWNjb3VudCgpCiAgICBieXRlICJwcmV2aW91c19iaWRkZXIiCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBzZWxmLnByZXZpb3VzX2JpZGRlciA9IHBheS5zZW5kZXIKICAgIHVuY292ZXIgMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NzktODAKICAgIC8vICMgVXBkYXRlIGNsYWltYWJsZSBhbW91bnQKICAgIC8vIHNlbGYuY2xhaW1hYmxlX2Ftb3VudFtUeG4uc2VuZGVyXSA9IHBheS5hbW91bnQKICAgIHR4biBTZW5kZXIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjMKICAgIC8vIHNlbGYuY2xhaW1hYmxlX2Ftb3VudCA9IExvY2FsU3RhdGUoVUludDY0LCBrZXk9ImNsYWltIiwgZGVzY3JpcHRpb249IlRoZSBjbGFpbWFibGUgYW1vdW50IikKICAgIGJ5dGUgImNsYWltIgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo3OS04MAogICAgLy8gIyBVcGRhdGUgY2xhaW1hYmxlIGFtb3VudAogICAgLy8gc2VsZi5jbGFpbWFibGVfYW1vdW50W1R4bi5zZW5kZXJdID0gcGF5LmFtb3VudAogICAgdW5jb3ZlciAyCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hdWN0aW9uLmNvbnRyYWN0LkF1Y3Rpb24uY2xhaW1fYmlkcygpIC0+IHZvaWQ6CmNsYWltX2JpZHM6CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjgyLTgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBjbGFpbV9iaWRzKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6ODQKICAgIC8vIGFtb3VudCA9IG9yaWdpbmFsX2Ftb3VudCA9IHNlbGYuY2xhaW1hYmxlX2Ftb3VudFtUeG4uc2VuZGVyXQogICAgdHhuIFNlbmRlcgogICAgaW50IDAKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjMKICAgIC8vIHNlbGYuY2xhaW1hYmxlX2Ftb3VudCA9IExvY2FsU3RhdGUoVUludDY0LCBrZXk9ImNsYWltIiwgZGVzY3JpcHRpb249IlRoZSBjbGFpbWFibGUgYW1vdW50IikKICAgIGJ5dGUgImNsYWltIgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo4NAogICAgLy8gYW1vdW50ID0gb3JpZ2luYWxfYW1vdW50ID0gc2VsZi5jbGFpbWFibGVfYW1vdW50W1R4bi5zZW5kZXJdCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBzd2FwCiAgICBkdXAKICAgIHVuY292ZXIgMgogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuY2xhaW1hYmxlX2Ftb3VudCBleGlzdHMgZm9yIGFjY291bnQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6ODYtODcKICAgIC8vICMgc3VidHJhY3QgcHJldmlvdXMgYmlkIGlmIHNlbmRlciBpcyBwcmV2aW91cyBiaWRkZXIKICAgIC8vIGlmIFR4bi5zZW5kZXIgPT0gc2VsZi5wcmV2aW91c19iaWRkZXI6CiAgICB0eG4gU2VuZGVyCiAgICBpbnQgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToyMgogICAgLy8gc2VsZi5wcmV2aW91c19iaWRkZXIgPSBBY2NvdW50KCkKICAgIGJ5dGUgInByZXZpb3VzX2JpZGRlciIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6ODYtODcKICAgIC8vICMgc3VidHJhY3QgcHJldmlvdXMgYmlkIGlmIHNlbmRlciBpcyBwcmV2aW91cyBiaWRkZXIKICAgIC8vIGlmIFR4bi5zZW5kZXIgPT0gc2VsZi5wcmV2aW91c19iaWRkZXI6CiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucHJldmlvdXNfYmlkZGVyIGV4aXN0cwogICAgPT0KICAgIGJ6IGNsYWltX2JpZHNfYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5Ojg4CiAgICAvLyBhbW91bnQgLT0gc2VsZi5wcmV2aW91c19iaWQKICAgIGludCAwCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjE5CiAgICAvLyBzZWxmLnByZXZpb3VzX2JpZCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAicHJldmlvdXNfYmlkIgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo4OAogICAgLy8gYW1vdW50IC09IHNlbGYucHJldmlvdXNfYmlkCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucHJldmlvdXNfYmlkIGV4aXN0cwogICAgZnJhbWVfZGlnIDAKICAgIHN3YXAKICAgIC0KICAgIGZyYW1lX2J1cnkgMQoKY2xhaW1fYmlkc19hZnRlcl9pZl9lbHNlQDI6CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjkwLTkzCiAgICAvLyBpdHhuLlBheW1lbnQoCiAgICAvLyAgICAgYW1vdW50PWFtb3VudCwKICAgIC8vICAgICByZWNlaXZlcj1UeG4uc2VuZGVyLAogICAgLy8gKS5zdWJtaXQoKQogICAgaXR4bl9iZWdpbgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo5MgogICAgLy8gcmVjZWl2ZXI9VHhuLnNlbmRlciwKICAgIHR4biBTZW5kZXIKICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGl0eG5fZmllbGQgQW1vdW50CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjkwCiAgICAvLyBpdHhuLlBheW1lbnQoCiAgICBpbnQgcGF5CiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6OTAtOTMKICAgIC8vIGl0eG4uUGF5bWVudCgKICAgIC8vICAgICBhbW91bnQ9YW1vdW50LAogICAgLy8gICAgIHJlY2VpdmVyPVR4bi5zZW5kZXIsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo5NQogICAgLy8gc2VsZi5jbGFpbWFibGVfYW1vdW50W1R4bi5zZW5kZXJdID0gb3JpZ2luYWxfYW1vdW50IC0gYW1vdW50CiAgICB0eG4gU2VuZGVyCiAgICBmcmFtZV9kaWcgMAogICAgdW5jb3ZlciAyCiAgICAtCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjIzCiAgICAvLyBzZWxmLmNsYWltYWJsZV9hbW91bnQgPSBMb2NhbFN0YXRlKFVJbnQ2NCwga2V5PSJjbGFpbSIsIGRlc2NyaXB0aW9uPSJUaGUgY2xhaW1hYmxlIGFtb3VudCIpCiAgICBieXRlICJjbGFpbSIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6OTUKICAgIC8vIHNlbGYuY2xhaW1hYmxlX2Ftb3VudFtUeG4uc2VuZGVyXSA9IG9yaWdpbmFsX2Ftb3VudCAtIGFtb3VudAogICAgc3dhcAogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLmNsYWltX2Fzc2V0KGFzc2V0OiB1aW50NjQpIC0+IHZvaWQ6CmNsYWltX2Fzc2V0OgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo5Ny05OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgY2xhaW1fYXNzZXQoc2VsZiwgYXNzZXQ6IEFzc2V0KSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5Ojk5CiAgICAvLyBhc3NlcnQgR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPiBzZWxmLmF1Y3Rpb25fZW5kLCAiYXVjdGlvbiBoYXMgbm90IGVuZGVkIgogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgaW50IDAKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTgKICAgIC8vIHNlbGYuYXVjdGlvbl9lbmQgPSBVSW50NjQoMCkKICAgIGJ5dGUgImF1Y3Rpb25fZW5kIgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo5OQogICAgLy8gYXNzZXJ0IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wID4gc2VsZi5hdWN0aW9uX2VuZCwgImF1Y3Rpb24gaGFzIG5vdCBlbmRlZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hdWN0aW9uX2VuZCBleGlzdHMKICAgID4KICAgIGFzc2VydCAvLyBhdWN0aW9uIGhhcyBub3QgZW5kZWQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTAwLTEwNgogICAgLy8gIyBTZW5kIEFTQSB0byBwcmV2aW91cyBiaWRkZXIKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIC8vICAgICB4ZmVyX2Fzc2V0PWFzc2V0LAogICAgLy8gICAgIGFzc2V0X2Nsb3NlX3RvPXNlbGYucHJldmlvdXNfYmlkZGVyLAogICAgLy8gICAgIGFzc2V0X3JlY2VpdmVyPXNlbGYucHJldmlvdXNfYmlkZGVyLAogICAgLy8gICAgIGFzc2V0X2Ftb3VudD1zZWxmLmFzYV9hbW91bnQsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX2JlZ2luCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjEwMwogICAgLy8gYXNzZXRfY2xvc2VfdG89c2VsZi5wcmV2aW91c19iaWRkZXIsCiAgICBpbnQgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToyMgogICAgLy8gc2VsZi5wcmV2aW91c19iaWRkZXIgPSBBY2NvdW50KCkKICAgIGJ5dGUgInByZXZpb3VzX2JpZGRlciIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTAzCiAgICAvLyBhc3NldF9jbG9zZV90bz1zZWxmLnByZXZpb3VzX2JpZGRlciwKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wcmV2aW91c19iaWRkZXIgZXhpc3RzCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjEwNAogICAgLy8gYXNzZXRfcmVjZWl2ZXI9c2VsZi5wcmV2aW91c19iaWRkZXIsCiAgICBpbnQgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToyMgogICAgLy8gc2VsZi5wcmV2aW91c19iaWRkZXIgPSBBY2NvdW50KCkKICAgIGJ5dGUgInByZXZpb3VzX2JpZGRlciIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTA0CiAgICAvLyBhc3NldF9yZWNlaXZlcj1zZWxmLnByZXZpb3VzX2JpZGRlciwKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wcmV2aW91c19iaWRkZXIgZXhpc3RzCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjEwNQogICAgLy8gYXNzZXRfYW1vdW50PXNlbGYuYXNhX2Ftb3VudCwKICAgIGludCAwCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjIwCiAgICAvLyBzZWxmLmFzYV9hbW91bnQgPSBVSW50NjQoMCkKICAgIGJ5dGUgImFzYV9hbW91bnQiCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjEwNQogICAgLy8gYXNzZXRfYW1vdW50PXNlbGYuYXNhX2Ftb3VudCwKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc2FfYW1vdW50IGV4aXN0cwogICAgaXR4bl9maWVsZCBBc3NldEFtb3VudAogICAgaXR4bl9maWVsZCBBc3NldFJlY2VpdmVyCiAgICBpdHhuX2ZpZWxkIEFzc2V0Q2xvc2VUbwogICAgZnJhbWVfZGlnIC0xCiAgICBpdHhuX2ZpZWxkIFhmZXJBc3NldAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxMDAtMTAxCiAgICAvLyAjIFNlbmQgQVNBIHRvIHByZXZpb3VzIGJpZGRlcgogICAgLy8gaXR4bi5Bc3NldFRyYW5zZmVyKAogICAgaW50IGF4ZmVyCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTAwLTEwNgogICAgLy8gIyBTZW5kIEFTQSB0byBwcmV2aW91cyBiaWRkZXIKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIC8vICAgICB4ZmVyX2Fzc2V0PWFzc2V0LAogICAgLy8gICAgIGFzc2V0X2Nsb3NlX3RvPXNlbGYucHJldmlvdXNfYmlkZGVyLAogICAgLy8gICAgIGFzc2V0X3JlY2VpdmVyPXNlbGYucHJldmlvdXNfYmlkZGVyLAogICAgLy8gICAgIGFzc2V0X2Ftb3VudD1zZWxmLmFzYV9hbW91bnQsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxOAogICAgLy8gc2VsZi5hdWN0aW9uX2VuZCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYXVjdGlvbl9lbmQiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTkKICAgIC8vIHNlbGYucHJldmlvdXNfYmlkID0gVUludDY0KDApCiAgICBieXRlICJwcmV2aW91c19iaWQiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjAKICAgIC8vIHNlbGYuYXNhX2Ftb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYXNhX2Ftb3VudCIKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToyMQogICAgLy8gc2VsZi5hc2EgPSBBc3NldCgpCiAgICBieXRlICJhc2EiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjIKICAgIC8vIHNlbGYucHJldmlvdXNfYmlkZGVyID0gQWNjb3VudCgpCiAgICBieXRlICJwcmV2aW91c19iaWRkZXIiCiAgICBnbG9iYWwgWmVyb0FkZHJlc3MKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5hdWN0aW9uLmNvbnRyYWN0LkF1Y3Rpb24uYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTYKICAgIC8vIGNsYXNzIEF1Y3Rpb24oQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMAogICAgbWV0aG9kICJvcHRfaW50b19hc3NldChhc3NldCl2b2lkIgogICAgbWV0aG9kICJzdGFydF9hdWN0aW9uKHVpbnQ2NCx1aW50NjQsYXhmZXIpdm9pZCIKICAgIG1ldGhvZCAib3B0X2luKCl2b2lkIgogICAgbWV0aG9kICJiaWQocGF5KXZvaWQiCiAgICBtZXRob2QgImNsYWltX2JpZHMoKXZvaWQiCiAgICBtZXRob2QgImNsYWltX2Fzc2V0KGFzc2V0KXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW50b19hc3NldF9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3N0YXJ0X2F1Y3Rpb25fcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW5fcm91dGVANCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iaWRfcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jbGFpbV9iaWRzX3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fY2xhaW1fYXNzZXRfcm91dGVANwogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2ludG9fYXNzZXRfcm91dGVAMjoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgb3B0X2ludG9fYXNzZXQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3N0YXJ0X2F1Y3Rpb25fcm91dGVAMzoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NDAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgYXhmZXIKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBheGZlcgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo0MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHN0YXJ0X2F1Y3Rpb24KICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbl9yb3V0ZUA0OgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iaWRfcm91dGVANToKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgYmlkCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jbGFpbV9iaWRzX3JvdXRlQDY6CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgY2xhaW1fYmlkcwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fY2xhaW1fYXNzZXRfcm91dGVANzoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6OTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5Ojk3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIGNhbGxzdWIgY2xhaW1fYXNzZXQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxMDoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTYKICAgIC8vIGNsYXNzIEF1Y3Rpb24oQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE0CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDE0OgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxNgogICAgLy8gY2xhc3MgQXVjdGlvbihBUkM0Q29udHJhY3QpOgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmF1Y3Rpb24uY29udHJhY3QuQXVjdGlvbi5vcHRfaW50b19hc3NldChhc3NldDogdWludDY0KSAtPiB2b2lkOgpvcHRfaW50b19hc3NldDoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjUtMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIG9wdF9pbnRvX2Fzc2V0KHNlbGYsIGFzc2V0OiBBc3NldCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToyNy0yOAogICAgLy8gIyBPbmx5IGFsbG93IGFwcCBjcmVhdG9yIHRvIG9wdCB0aGUgYXBwIGFjY291bnQgaW50byBhIEFTQQogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gR2xvYmFsLmNyZWF0b3JfYWRkcmVzcywgIk9ubHkgY3JlYXRvciBjYW4gb3B0IGluIHRvIEFTQSIKICAgIHR4biBTZW5kZXIKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgPT0KICAgIGFzc2VydCAvLyBPbmx5IGNyZWF0b3IgY2FuIG9wdCBpbiB0byBBU0EKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjktMzAKICAgIC8vICMgVmVyaWZ5IGEgQVNBIGhhc24ndCBhbHJlYWR5IGJlZW4gb3B0ZWQgaW50bwogICAgLy8gYXNzZXJ0IHNlbGYuYXNhLmlkID09IDAsICJBU0EgYWxyZWFkeSBvcHRlZCBpbiIKICAgIGludCAwCiAgICBieXRlICJhc2EiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXNhIGV4aXN0cwogICAgIQogICAgYXNzZXJ0IC8vIEFTQSBhbHJlYWR5IG9wdGVkIGluCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjMxLTMyCiAgICAvLyAjIFNhdmUgQVNBIElEIGluIGdsb2JhbCBzdGF0ZQogICAgLy8gc2VsZi5hc2EgPSBhc3NldAogICAgYnl0ZSAiYXNhIgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTozNC0zOAogICAgLy8gIyBTdWJtaXQgb3B0LWluIHRyYW5zYWN0aW9uOiAwIGFzc2V0IHRyYW5zZmVyIHRvIHNlbGYKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIC8vICAgICBhc3NldF9yZWNlaXZlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgLy8gICAgIHhmZXJfYXNzZXQ9YXNzZXQsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX2JlZ2luCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjM2CiAgICAvLyBhc3NldF9yZWNlaXZlcj1HbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLAogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgIGZyYW1lX2RpZyAtMQogICAgaXR4bl9maWVsZCBYZmVyQXNzZXQKICAgIGl0eG5fZmllbGQgQXNzZXRSZWNlaXZlcgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTozNC0zNQogICAgLy8gIyBTdWJtaXQgb3B0LWluIHRyYW5zYWN0aW9uOiAwIGFzc2V0IHRyYW5zZmVyIHRvIHNlbGYKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIGludCBheGZlcgogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjM0LTM4CiAgICAvLyAjIFN1Ym1pdCBvcHQtaW4gdHJhbnNhY3Rpb246IDAgYXNzZXQgdHJhbnNmZXIgdG8gc2VsZgogICAgLy8gaXR4bi5Bc3NldFRyYW5zZmVyKAogICAgLy8gICAgIGFzc2V0X3JlY2VpdmVyPUdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MsCiAgICAvLyAgICAgeGZlcl9hc3NldD1hc3NldCwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5hdWN0aW9uLmNvbnRyYWN0LkF1Y3Rpb24uc3RhcnRfYXVjdGlvbihzdGFydGluZ19wcmljZTogdWludDY0LCBsZW5ndGg6IHVpbnQ2NCwgYXhmZXI6IHVpbnQ2NCkgLT4gdm9pZDoKc3RhcnRfYXVjdGlvbjoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NDAtNDYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHN0YXJ0X2F1Y3Rpb24oCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBzdGFydGluZ19wcmljZTogVUludDY0LAogICAgLy8gICAgIGxlbmd0aDogVUludDY0LAogICAgLy8gICAgIGF4ZmVyOiBndHhuLkFzc2V0VHJhbnNmZXJUcmFuc2FjdGlvbiwKICAgIC8vICkgLT4gTm9uZToKICAgIHByb3RvIDMgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo0NwogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gR2xvYmFsLmNyZWF0b3JfYWRkcmVzcywgImF1Y3Rpb24gbXVzdCBiZSBzdGFydGVkIGJ5IGNyZWF0b3IiCiAgICB0eG4gU2VuZGVyCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgID09CiAgICBhc3NlcnQgLy8gYXVjdGlvbiBtdXN0IGJlIHN0YXJ0ZWQgYnkgY3JlYXRvcgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo0OS01MAogICAgLy8gIyBFbnN1cmUgdGhlIGF1Y3Rpb24gaGFzbid0IGFscmVhZHkgYmVlbiBzdGFydGVkCiAgICAvLyBhc3NlcnQgc2VsZi5hdWN0aW9uX2VuZCA9PSAwLCAiYXVjdGlvbiBhbHJlYWR5IHN0YXJ0ZWQiCiAgICBpbnQgMAogICAgYnl0ZSAiYXVjdGlvbl9lbmQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXVjdGlvbl9lbmQgZXhpc3RzCiAgICAhCiAgICBhc3NlcnQgLy8gYXVjdGlvbiBhbHJlYWR5IHN0YXJ0ZWQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NTQKICAgIC8vIGF4ZmVyLmFzc2V0X3JlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgQXNzZXRSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjUyLTU1CiAgICAvLyAjIFZlcmlmeSBheGZlcgogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBheGZlci5hc3NldF9yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzCiAgICAvLyApLCAiYXhmZXIgbXVzdCB0cmFuc2ZlciB0byB0aGlzIGFwcCIKICAgIGFzc2VydCAvLyBheGZlciBtdXN0IHRyYW5zZmVyIHRvIHRoaXMgYXBwCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjU3LTU4CiAgICAvLyAjIFNldCBnbG9iYWwgc3RhdGUKICAgIC8vIHNlbGYuYXNhX2Ftb3VudCA9IGF4ZmVyLmFzc2V0X2Ftb3VudAogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBBc3NldEFtb3VudAogICAgYnl0ZSAiYXNhX2Ftb3VudCIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBzZWxmLmF1Y3Rpb25fZW5kID0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgKyBsZW5ndGgKICAgIGdsb2JhbCBMYXRlc3RUaW1lc3RhbXAKICAgIGZyYW1lX2RpZyAtMgogICAgKwogICAgYnl0ZSAiYXVjdGlvbl9lbmQiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo2MAogICAgLy8gc2VsZi5wcmV2aW91c19iaWQgPSBzdGFydGluZ19wcmljZQogICAgYnl0ZSAicHJldmlvdXNfYmlkIgogICAgZnJhbWVfZGlnIC0zCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLmJpZChwYXk6IHVpbnQ2NCkgLT4gdm9pZDoKYmlkOgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo2Ni02NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYmlkKHNlbGYsIHBheTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24pIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NjgtNjkKICAgIC8vICMgRW5zdXJlIGF1Y3Rpb24gaGFzbid0IGVuZGVkCiAgICAvLyBhc3NlcnQgR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPCBzZWxmLmF1Y3Rpb25fZW5kLCAiYXVjdGlvbiBoYXMgZW5kZWQiCiAgICBnbG9iYWwgTGF0ZXN0VGltZXN0YW1wCiAgICBpbnQgMAogICAgYnl0ZSAiYXVjdGlvbl9lbmQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYXVjdGlvbl9lbmQgZXhpc3RzCiAgICA8CiAgICBhc3NlcnQgLy8gYXVjdGlvbiBoYXMgZW5kZWQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NzEtNzIKICAgIC8vICMgVmVyaWZ5IHBheW1lbnQgdHJhbnNhY3Rpb24KICAgIC8vIGFzc2VydCBwYXkuc2VuZGVyID09IFR4bi5zZW5kZXIsICJwYXltZW50IHNlbmRlciBtdXN0IG1hdGNoIHRyYW5zYWN0aW9uIHNlbmRlciIKICAgIGZyYW1lX2RpZyAtMQogICAgZ3R4bnMgU2VuZGVyCiAgICBkdXAKICAgIHR4biBTZW5kZXIKICAgID09CiAgICBhc3NlcnQgLy8gcGF5bWVudCBzZW5kZXIgbXVzdCBtYXRjaCB0cmFuc2FjdGlvbiBzZW5kZXIKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6NzMKICAgIC8vIGFzc2VydCBwYXkuYW1vdW50ID4gc2VsZi5wcmV2aW91c19iaWQsICJCaWQgbXVzdCBiZSBoaWdoZXIgdGhhbiBwcmV2aW91cyBiaWQiCiAgICBmcmFtZV9kaWcgLTEKICAgIGd0eG5zIEFtb3VudAogICAgaW50IDAKICAgIGJ5dGUgInByZXZpb3VzX2JpZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5wcmV2aW91c19iaWQgZXhpc3RzCiAgICBkaWcgMQogICAgPAogICAgYXNzZXJ0IC8vIEJpZCBtdXN0IGJlIGhpZ2hlciB0aGFuIHByZXZpb3VzIGJpZAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo3NS03NgogICAgLy8gIyBzZXQgZ2xvYmFsIHN0YXRlCiAgICAvLyBzZWxmLnByZXZpb3VzX2JpZCA9IHBheS5hbW91bnQKICAgIGJ5dGUgInByZXZpb3VzX2JpZCIKICAgIGRpZyAxCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo3NwogICAgLy8gc2VsZi5wcmV2aW91c19iaWRkZXIgPSBwYXkuc2VuZGVyCiAgICBieXRlICJwcmV2aW91c19iaWRkZXIiCiAgICB1bmNvdmVyIDIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5Ojc5LTgwCiAgICAvLyAjIFVwZGF0ZSBjbGFpbWFibGUgYW1vdW50CiAgICAvLyBzZWxmLmNsYWltYWJsZV9hbW91bnRbVHhuLnNlbmRlcl0gPSBwYXkuYW1vdW50CiAgICB0eG4gU2VuZGVyCiAgICBieXRlICJjbGFpbSIKICAgIHVuY292ZXIgMgogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLmNsYWltX2JpZHMoKSAtPiB2b2lkOgpjbGFpbV9iaWRzOgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo4Mi04MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgY2xhaW1fYmlkcyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5Ojg0CiAgICAvLyBhbW91bnQgPSBvcmlnaW5hbF9hbW91bnQgPSBzZWxmLmNsYWltYWJsZV9hbW91bnRbVHhuLnNlbmRlcl0KICAgIHR4biBTZW5kZXIKICAgIGludCAwCiAgICBieXRlICJjbGFpbSIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIHN3YXAKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5jbGFpbWFibGVfYW1vdW50IGV4aXN0cyBmb3IgYWNjb3VudAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo4Ni04NwogICAgLy8gIyBzdWJ0cmFjdCBwcmV2aW91cyBiaWQgaWYgc2VuZGVyIGlzIHByZXZpb3VzIGJpZGRlcgogICAgLy8gaWYgVHhuLnNlbmRlciA9PSBzZWxmLnByZXZpb3VzX2JpZGRlcjoKICAgIHR4biBTZW5kZXIKICAgIGludCAwCiAgICBieXRlICJwcmV2aW91c19iaWRkZXIiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucHJldmlvdXNfYmlkZGVyIGV4aXN0cwogICAgPT0KICAgIGJ6IGNsYWltX2JpZHNfYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5Ojg4CiAgICAvLyBhbW91bnQgLT0gc2VsZi5wcmV2aW91c19iaWQKICAgIGludCAwCiAgICBieXRlICJwcmV2aW91c19iaWQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucHJldmlvdXNfYmlkIGV4aXN0cwogICAgZnJhbWVfZGlnIDAKICAgIHN3YXAKICAgIC0KICAgIGZyYW1lX2J1cnkgMQoKY2xhaW1fYmlkc19hZnRlcl9pZl9lbHNlQDI6CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjkwLTkzCiAgICAvLyBpdHhuLlBheW1lbnQoCiAgICAvLyAgICAgYW1vdW50PWFtb3VudCwKICAgIC8vICAgICByZWNlaXZlcj1UeG4uc2VuZGVyLAogICAgLy8gKS5zdWJtaXQoKQogICAgaXR4bl9iZWdpbgogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo5MgogICAgLy8gcmVjZWl2ZXI9VHhuLnNlbmRlciwKICAgIHR4biBTZW5kZXIKICAgIGl0eG5fZmllbGQgUmVjZWl2ZXIKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGl0eG5fZmllbGQgQW1vdW50CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjkwCiAgICAvLyBpdHhuLlBheW1lbnQoCiAgICBpbnQgcGF5CiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6OTAtOTMKICAgIC8vIGl0eG4uUGF5bWVudCgKICAgIC8vICAgICBhbW91bnQ9YW1vdW50LAogICAgLy8gICAgIHJlY2VpdmVyPVR4bi5zZW5kZXIsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo5NQogICAgLy8gc2VsZi5jbGFpbWFibGVfYW1vdW50W1R4bi5zZW5kZXJdID0gb3JpZ2luYWxfYW1vdW50IC0gYW1vdW50CiAgICB0eG4gU2VuZGVyCiAgICBmcmFtZV9kaWcgMAogICAgdW5jb3ZlciAyCiAgICAtCiAgICBieXRlICJjbGFpbSIKICAgIHN3YXAKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmF1Y3Rpb24uY29udHJhY3QuQXVjdGlvbi5jbGFpbV9hc3NldChhc3NldDogdWludDY0KSAtPiB2b2lkOgpjbGFpbV9hc3NldDoKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6OTctOTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGNsYWltX2Fzc2V0KHNlbGYsIGFzc2V0OiBBc3NldCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weTo5OQogICAgLy8gYXNzZXJ0IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wID4gc2VsZi5hdWN0aW9uX2VuZCwgImF1Y3Rpb24gaGFzIG5vdCBlbmRlZCIKICAgIGdsb2JhbCBMYXRlc3RUaW1lc3RhbXAKICAgIGludCAwCiAgICBieXRlICJhdWN0aW9uX2VuZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hdWN0aW9uX2VuZCBleGlzdHMKICAgID4KICAgIGFzc2VydCAvLyBhdWN0aW9uIGhhcyBub3QgZW5kZWQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTAwLTEwNgogICAgLy8gIyBTZW5kIEFTQSB0byBwcmV2aW91cyBiaWRkZXIKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIC8vICAgICB4ZmVyX2Fzc2V0PWFzc2V0LAogICAgLy8gICAgIGFzc2V0X2Nsb3NlX3RvPXNlbGYucHJldmlvdXNfYmlkZGVyLAogICAgLy8gICAgIGFzc2V0X3JlY2VpdmVyPXNlbGYucHJldmlvdXNfYmlkZGVyLAogICAgLy8gICAgIGFzc2V0X2Ftb3VudD1zZWxmLmFzYV9hbW91bnQsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX2JlZ2luCiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjEwMwogICAgLy8gYXNzZXRfY2xvc2VfdG89c2VsZi5wcmV2aW91c19iaWRkZXIsCiAgICBpbnQgMAogICAgYnl0ZSAicHJldmlvdXNfYmlkZGVyIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnByZXZpb3VzX2JpZGRlciBleGlzdHMKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTA0CiAgICAvLyBhc3NldF9yZWNlaXZlcj1zZWxmLnByZXZpb3VzX2JpZGRlciwKICAgIGludCAwCiAgICBieXRlICJwcmV2aW91c19iaWRkZXIiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucHJldmlvdXNfYmlkZGVyIGV4aXN0cwogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxMDUKICAgIC8vIGFzc2V0X2Ftb3VudD1zZWxmLmFzYV9hbW91bnQsCiAgICBpbnQgMAogICAgYnl0ZSAiYXNhX2Ftb3VudCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc2FfYW1vdW50IGV4aXN0cwogICAgaXR4bl9maWVsZCBBc3NldEFtb3VudAogICAgaXR4bl9maWVsZCBBc3NldFJlY2VpdmVyCiAgICBpdHhuX2ZpZWxkIEFzc2V0Q2xvc2VUbwogICAgZnJhbWVfZGlnIC0xCiAgICBpdHhuX2ZpZWxkIFhmZXJBc3NldAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxMDAtMTAxCiAgICAvLyAjIFNlbmQgQVNBIHRvIHByZXZpb3VzIGJpZGRlcgogICAgLy8gaXR4bi5Bc3NldFRyYW5zZmVyKAogICAgaW50IGF4ZmVyCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTAwLTEwNgogICAgLy8gIyBTZW5kIEFTQSB0byBwcmV2aW91cyBiaWRkZXIKICAgIC8vIGl0eG4uQXNzZXRUcmFuc2ZlcigKICAgIC8vICAgICB4ZmVyX2Fzc2V0PWFzc2V0LAogICAgLy8gICAgIGFzc2V0X2Nsb3NlX3RvPXNlbGYucHJldmlvdXNfYmlkZGVyLAogICAgLy8gICAgIGFzc2V0X3JlY2VpdmVyPXNlbGYucHJldmlvdXNfYmlkZGVyLAogICAgLy8gICAgIGFzc2V0X2Ftb3VudD1zZWxmLmFzYV9hbW91bnQsCiAgICAvLyApLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYXVjdGlvbi5jb250cmFjdC5BdWN0aW9uLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyBhdWN0aW9uL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToxOAogICAgLy8gc2VsZi5hdWN0aW9uX2VuZCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYXVjdGlvbl9lbmQiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTkKICAgIC8vIHNlbGYucHJldmlvdXNfYmlkID0gVUludDY0KDApCiAgICBieXRlICJwcmV2aW91c19iaWQiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjAKICAgIC8vIHNlbGYuYXNhX2Ftb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYXNhX2Ftb3VudCIKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYXVjdGlvbi9jb250cmFjdC5weToyMQogICAgLy8gc2VsZi5hc2EgPSBBc3NldCgpCiAgICBieXRlICJhc2EiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MjIKICAgIC8vIHNlbGYucHJldmlvdXNfYmlkZGVyID0gQWNjb3VudCgpCiAgICBieXRlICJwcmV2aW91c19iaWRkZXIiCiAgICBnbG9iYWwgWmVyb0FkZHJlc3MKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5hdWN0aW9uLmNvbnRyYWN0LkF1Y3Rpb24uY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIC8vIGF1Y3Rpb24vY29udHJhY3QucHk6MTE2CiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/examples/auction/out_unoptimized/Auction.approval.teal b/examples/auction/out_unoptimized/Auction.approval.teal index bf03b35bed..bff061f477 100644 --- a/examples/auction/out_unoptimized/Auction.approval.teal +++ b/examples/auction/out_unoptimized/Auction.approval.teal @@ -214,23 +214,16 @@ opt_into_asset: // # Verify a ASA hasn't already been opted into // assert self.asa.id == 0, "ASA already opted in" int 0 - // auction/contract.py:21 - // self.asa = Asset() byte "asa" - // auction/contract.py:29-30 - // # Verify a ASA hasn't already been opted into - // assert self.asa.id == 0, "ASA already opted in" app_global_get_ex assert // check self.asa exists int 0 == assert // ASA already opted in - // auction/contract.py:21 - // self.asa = Asset() - byte "asa" // auction/contract.py:31-32 // # Save ASA ID in global state // self.asa = asset + byte "asa" frame_dig -1 app_global_put // auction/contract.py:34-38 @@ -286,12 +279,7 @@ start_auction: // # Ensure the auction hasn't already been started // assert self.auction_end == 0, "auction already started" int 0 - // auction/contract.py:18 - // self.auction_end = UInt64(0) byte "auction_end" - // auction/contract.py:49-50 - // # Ensure the auction hasn't already been started - // assert self.auction_end == 0, "auction already started" app_global_get_ex assert // check self.auction_end exists int 0 @@ -314,12 +302,7 @@ start_auction: // self.asa_amount = axfer.asset_amount frame_dig -1 gtxns AssetAmount - // auction/contract.py:20 - // self.asa_amount = UInt64(0) byte "asa_amount" - // auction/contract.py:57-58 - // # Set global state - // self.asa_amount = axfer.asset_amount uncover 1 app_global_put // auction/contract.py:59 @@ -327,18 +310,12 @@ start_auction: global LatestTimestamp frame_dig -2 + - // auction/contract.py:18 - // self.auction_end = UInt64(0) byte "auction_end" - // auction/contract.py:59 - // self.auction_end = Global.latest_timestamp + length uncover 1 app_global_put - // auction/contract.py:19 - // self.previous_bid = UInt64(0) - byte "previous_bid" // auction/contract.py:60 // self.previous_bid = starting_price + byte "previous_bid" frame_dig -3 app_global_put retsub @@ -364,12 +341,7 @@ bid: // assert Global.latest_timestamp < self.auction_end, "auction has ended" global LatestTimestamp int 0 - // auction/contract.py:18 - // self.auction_end = UInt64(0) byte "auction_end" - // auction/contract.py:68-69 - // # Ensure auction hasn't ended - // assert Global.latest_timestamp < self.auction_end, "auction has ended" app_global_get_ex assert // check self.auction_end exists < @@ -387,11 +359,7 @@ bid: frame_dig -1 gtxns Amount int 0 - // auction/contract.py:19 - // self.previous_bid = UInt64(0) byte "previous_bid" - // auction/contract.py:73 - // assert pay.amount > self.previous_bid, "Bid must be higher than previous bid" app_global_get_ex assert // check self.previous_bid exists > @@ -401,23 +369,14 @@ bid: // self.previous_bid = pay.amount frame_dig -1 gtxns Amount - // auction/contract.py:19 - // self.previous_bid = UInt64(0) byte "previous_bid" - // auction/contract.py:75-76 - // # set global state - // self.previous_bid = pay.amount uncover 1 app_global_put // auction/contract.py:77 // self.previous_bidder = pay.sender frame_dig -1 gtxns Sender - // auction/contract.py:22 - // self.previous_bidder = Account() byte "previous_bidder" - // auction/contract.py:77 - // self.previous_bidder = pay.sender uncover 1 app_global_put // auction/contract.py:79-80 @@ -427,12 +386,7 @@ bid: frame_dig -1 gtxns Amount uncover 1 - // auction/contract.py:23 - // self.claimable_amount = LocalState(UInt64, key="claim", description="The claimable amount") byte "claim" - // auction/contract.py:79-80 - // # Update claimable amount - // self.claimable_amount[Txn.sender] = pay.amount uncover 2 app_local_put retsub @@ -448,11 +402,7 @@ claim_bids: // amount = original_amount = self.claimable_amount[Txn.sender] txn Sender int 0 - // auction/contract.py:23 - // self.claimable_amount = LocalState(UInt64, key="claim", description="The claimable amount") byte "claim" - // auction/contract.py:84 - // amount = original_amount = self.claimable_amount[Txn.sender] app_local_get_ex assert // check self.claimable_amount exists for account dup @@ -464,12 +414,7 @@ claim_bids: // if Txn.sender == self.previous_bidder: txn Sender int 0 - // auction/contract.py:22 - // self.previous_bidder = Account() byte "previous_bidder" - // auction/contract.py:86-87 - // # subtract previous bid if sender is previous bidder - // if Txn.sender == self.previous_bidder: app_global_get_ex assert // check self.previous_bidder exists == @@ -477,11 +422,7 @@ claim_bids: // auction/contract.py:88 // amount -= self.previous_bid int 0 - // auction/contract.py:19 - // self.previous_bid = UInt64(0) byte "previous_bid" - // auction/contract.py:88 - // amount -= self.previous_bid app_global_get_ex assert // check self.previous_bid exists frame_dig 1 @@ -523,11 +464,7 @@ claim_bids_after_if_else@2: frame_dig 1 - uncover 1 - // auction/contract.py:23 - // self.claimable_amount = LocalState(UInt64, key="claim", description="The claimable amount") byte "claim" - // auction/contract.py:95 - // self.claimable_amount[Txn.sender] = original_amount - amount uncover 2 app_local_put retsub @@ -543,11 +480,7 @@ claim_asset: // assert Global.latest_timestamp > self.auction_end, "auction has not ended" global LatestTimestamp int 0 - // auction/contract.py:18 - // self.auction_end = UInt64(0) byte "auction_end" - // auction/contract.py:99 - // assert Global.latest_timestamp > self.auction_end, "auction has not ended" app_global_get_ex assert // check self.auction_end exists > @@ -567,31 +500,19 @@ claim_asset: // auction/contract.py:103 // asset_close_to=self.previous_bidder, int 0 - // auction/contract.py:22 - // self.previous_bidder = Account() byte "previous_bidder" - // auction/contract.py:103 - // asset_close_to=self.previous_bidder, app_global_get_ex assert // check self.previous_bidder exists // auction/contract.py:104 // asset_receiver=self.previous_bidder, int 0 - // auction/contract.py:22 - // self.previous_bidder = Account() byte "previous_bidder" - // auction/contract.py:104 - // asset_receiver=self.previous_bidder, app_global_get_ex assert // check self.previous_bidder exists // auction/contract.py:105 // asset_amount=self.asa_amount, int 0 - // auction/contract.py:20 - // self.asa_amount = UInt64(0) byte "asa_amount" - // auction/contract.py:105 - // asset_amount=self.asa_amount, app_global_get_ex assert // check self.asa_amount exists itxn_field AssetAmount diff --git a/examples/box_storage/out/BoxContract.approval.mir b/examples/box_storage/out/BoxContract.approval.mir index b0595b97cf..b422fbad2b 100644 --- a/examples/box_storage/out/BoxContract.approval.mir +++ b/examples/box_storage/out/BoxContract.approval.mir @@ -450,37 +450,37 @@ set_boxes_block@0: frame_dig -3 // load a#0 from parameters (𝕡) a#0,b#0,c#0 | a#0 self.box_a.value = a box_storage/contract.py:19 itob // (𝕡) a#0,b#0,c#0 | {itob} self.box_a.value = a box_storage/contract.py:19 // virtual: store new_box_value%0#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%0#0 self.box_a.value = a box_storage/contract.py:19 - byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%0#0,"box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%0#0,"box_a" self.box_a box_storage/contract.py:19 uncover 1 // load new_box_value%0#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | "box_a",new_box_value%0#0 self.box_a.value = a box_storage/contract.py:19 box_put // (𝕡) a#0,b#0,c#0 | self.box_a.value = a box_storage/contract.py:19 - byte "b" // (𝕡) a#0,b#0,c#0 | "b" "b" box_storage/contract.py:11 + byte "b" // (𝕡) a#0,b#0,c#0 | "b" self.box_b box_storage/contract.py:20 box_del // (𝕡) a#0,b#0,c#0 | {box_del} self.box_b.value = b.copy() box_storage/contract.py:20 pop // (𝕡) a#0,b#0,c#0 | - byte "b" // (𝕡) a#0,b#0,c#0 | "b" "b" box_storage/contract.py:11 + byte "b" // (𝕡) a#0,b#0,c#0 | "b" self.box_b box_storage/contract.py:20 frame_dig -2 // load b#0 from parameters (𝕡) a#0,b#0,c#0 | "b",b#0 self.box_b.value = b.copy() box_storage/contract.py:20 box_put // (𝕡) a#0,b#0,c#0 | self.box_b.value = b.copy() box_storage/contract.py:20 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | 0x424f585f43 self.box_c box_storage/contract.py:21 box_del // (𝕡) a#0,b#0,c#0 | {box_del} self.box_c.value = c box_storage/contract.py:21 pop // (𝕡) a#0,b#0,c#0 | - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | 0x424f585f43 self.box_c box_storage/contract.py:21 frame_dig -1 // load c#0 from parameters (𝕡) a#0,b#0,c#0 | 0x424f585f43,c#0 self.box_c.value = c box_storage/contract.py:21 box_put // (𝕡) a#0,b#0,c#0 | self.box_c.value = c box_storage/contract.py:21 frame_dig -2 // load b#0 from parameters (𝕡) a#0,b#0,c#0 | b#0 b.native box_storage/contract.py:22 extract 2 0 // (𝕡) a#0,b#0,c#0 | {extract} b.native box_storage/contract.py:22 // virtual: store new_box_value%1#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0 b.native box_storage/contract.py:22 - byte "box_d" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:22 box_del // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,{box_del} self.box_d.value = b.native box_storage/contract.py:22 pop // (𝕡) a#0,b#0,c#0 | new_box_value%1#0 - byte "box_d" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:22 dig 1 // load new_box_value%1#0 from l-stack (copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_d",new_box_value%1#0 self.box_d.value = b.native box_storage/contract.py:22 box_put // (𝕡) a#0,b#0,c#0 | new_box_value%1#0 self.box_d.value = b.native box_storage/contract.py:22 - byte "b" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"b" "b" box_storage/contract.py:11 + byte "b" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"b" self.box_b box_storage/contract.py:24 box_get // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,{box_get}.0,{box_get}.1 self.box_b.value box_storage/contract.py:24 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,maybe_exists%0#0,{box_get}.0 self.box_b.value box_storage/contract.py:24 // virtual: store b_value#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,b_value#0,maybe_exists%0#0 self.box_b.value box_storage/contract.py:24 // virtual: load maybe_exists%0#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,b_value#0,maybe_exists%0#0 self.box_b.value box_storage/contract.py:24 assert // check self.box_b exists // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,b_value#0 self.box_b.value box_storage/contract.py:24 - byte "b" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,b_value#0,"b" "b" box_storage/contract.py:11 + byte "b" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,b_value#0,"b" self.box_b box_storage/contract.py:25 box_get // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,b_value#0,{box_get}.0,{box_get}.1 self.box_b.value box_storage/contract.py:25 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,b_value#0,maybe_exists%1#0,{box_get}.0 self.box_b.value box_storage/contract.py:25 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,b_value#0,maybe_value%1#0,maybe_exists%1#0 self.box_b.value box_storage/contract.py:25 @@ -500,7 +500,7 @@ set_boxes_block@0: // virtual: store tmp%2#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%2#0 self.box_b.value.length == b_value.length, "direct reference should match copy" box_storage/contract.py:25 // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%2#0 assert self.box_b.value.length == b_value.length, "direct reference should match copy" box_storage/contract.py:25 assert // direct reference should match copy // (𝕡) a#0,b#0,c#0 | new_box_value%1#0 assert self.box_b.value.length == b_value.length, "direct reference should match copy" box_storage/contract.py:25 - byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_a" self.box_a box_storage/contract.py:27 box_get // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,{box_get}.0,{box_get}.1 self.box_a.value box_storage/contract.py:27 cover 1 // store maybe_exists%2#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,maybe_exists%2#0,{box_get}.0 self.box_a.value box_storage/contract.py:27 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,maybe_exists%2#0,maybe_value%2#0 self.box_a.value box_storage/contract.py:27 @@ -516,10 +516,10 @@ set_boxes_block@0: // virtual: load new_box_value%2#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,new_box_value%2#0 self.box_a.value += 3 box_storage/contract.py:27 itob // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,{itob} self.box_a.value += 3 box_storage/contract.py:27 // virtual: store new_box_value%3#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,new_box_value%3#0 self.box_a.value += 3 box_storage/contract.py:27 - byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,new_box_value%3#0,"box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,new_box_value%3#0,"box_a" self.box_a box_storage/contract.py:27 uncover 1 // load new_box_value%3#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_a",new_box_value%3#0 self.box_a.value += 3 box_storage/contract.py:27 box_put // (𝕡) a#0,b#0,c#0 | new_box_value%1#0 self.box_a.value += 3 box_storage/contract.py:27 - byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"box_a" .length\nassert self.box_a box_storage/contract.py:29-30 box_len // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,{box_len}.0,{box_len}.1 .length\nassert self.box_a.length box_storage/contract.py:29-30 // virtual: store check%0#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,check%0#0,{box_len}.0 .length\nassert self.box_a.length box_storage/contract.py:29-30 // virtual: store value%0#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,value%0#0,check%0#0 .length\nassert self.box_a.length box_storage/contract.py:29-30 @@ -531,7 +531,7 @@ set_boxes_block@0: // virtual: store tmp%3#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%3#0 .length\nassert self.box_a.length == 8 box_storage/contract.py:29-30 // virtual: load tmp%3#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%3#0 # test .length\nassert self.box_a.length == 8 box_storage/contract.py:29-30 assert // (𝕡) a#0,b#0,c#0 | new_box_value%1#0 # test .length\nassert self.box_a.length == 8 box_storage/contract.py:29-30 - byte "b" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"b" "b" box_storage/contract.py:11 + byte "b" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,"b" self.box_b box_storage/contract.py:31 box_len // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,{box_len}.0,{box_len}.1 self.box_b.length box_storage/contract.py:31 // virtual: store check%1#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,check%1#0,{box_len}.0 self.box_b.length box_storage/contract.py:31 // virtual: store value%1#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,value%1#0,check%1#0 self.box_b.length box_storage/contract.py:31 @@ -546,7 +546,7 @@ set_boxes_block@0: // virtual: store tmp%5#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%5#0 self.box_b.length == b.bytes.length box_storage/contract.py:31 // virtual: load tmp%5#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%5#0 assert self.box_b.length == b.bytes.length box_storage/contract.py:31 assert // (𝕡) a#0,b#0,c#0 | new_box_value%1#0 assert self.box_b.length == b.bytes.length box_storage/contract.py:31 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,0x424f585f43 self.box_c box_storage/contract.py:32 box_len // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,{box_len}.0,{box_len}.1 self.box_c.length box_storage/contract.py:32 // virtual: store check%2#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,check%2#0,{box_len}.0 self.box_c.length box_storage/contract.py:32 // virtual: store value%2#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,value%2#0,check%2#0 self.box_c.length box_storage/contract.py:32 @@ -563,7 +563,7 @@ set_boxes_block@0: // virtual: store tmp%7#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%6#0,tmp%7#0 self.box_c.length == c.bytes.length box_storage/contract.py:32 // virtual: load tmp%7#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%6#0,tmp%7#0 assert self.box_c.length == c.bytes.length box_storage/contract.py:32 assert // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%6#0 assert self.box_c.length == c.bytes.length box_storage/contract.py:32 - byte "box_d" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%6#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%6#0,"box_d" self.box_d box_storage/contract.py:33 box_len // (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%6#0,{box_len}.0,{box_len}.1 self.box_d.length box_storage/contract.py:33 // virtual: store check%3#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%6#0,check%3#0,{box_len}.0 self.box_d.length box_storage/contract.py:33 // virtual: store value%3#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | new_box_value%1#0,tmp%6#0,value%3#0,check%3#0 self.box_d.length box_storage/contract.py:33 @@ -580,7 +580,7 @@ set_boxes_block@0: // virtual: store tmp%10#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%10#0 self.box_d.length == b.native.length box_storage/contract.py:33 // virtual: load tmp%10#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%10#0 assert self.box_d.length == b.native.length box_storage/contract.py:33 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0 assert self.box_d.length == b.native.length box_storage/contract.py:33 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43 .value.bytes\nassert self.box_c box_storage/contract.py:35-36 int 0 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43,0 \nassert self.box_c.value.bytes[0 box_storage/contract.py:35-36 int 1 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43,0,1 .value.bytes\nassert self.box_c.value.bytes[0] box_storage/contract.py:35-36 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_extract} .value.bytes\nassert self.box_c.value.bytes[0] box_storage/contract.py:35-36 @@ -594,7 +594,7 @@ set_boxes_block@0: // virtual: store tmp%13#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%13#0 .value.bytes\nassert self.box_c.value.bytes[0] == c.bytes[0] box_storage/contract.py:35-36 // virtual: load tmp%13#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%13#0 # test .value.bytes\nassert self.box_c.value.bytes[0] == c.bytes[0] box_storage/contract.py:35-36 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0 # test .value.bytes\nassert self.box_c.value.bytes[0] == c.bytes[0] box_storage/contract.py:35-36 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43 self.box_c box_storage/contract.py:37 box_len // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_len}.0,{box_len}.1 self.box_c.value.bytes[-1] box_storage/contract.py:37 pop // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_len}.0 self.box_c.value.bytes[-1] box_storage/contract.py:37 // virtual: store tmp%14#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%14#0 self.box_c.value.bytes[-1] box_storage/contract.py:37 @@ -602,7 +602,7 @@ set_boxes_block@0: int 1 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%14#0,1 self.box_c.value.bytes[-1] box_storage/contract.py:37 - // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{-} self.box_c.value.bytes[-1] box_storage/contract.py:37 // virtual: store tmp%16#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%16#0 self.box_c.value.bytes[-1] box_storage/contract.py:37 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%16#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%16#0,0x424f585f43 self.box_c box_storage/contract.py:37 uncover 1 // load tmp%16#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43,tmp%16#0 self.box_c.value.bytes[-1] box_storage/contract.py:37 int 1 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43,tmp%16#0,1 self.box_c.value.bytes[-1] box_storage/contract.py:37 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_extract} self.box_c.value.bytes[-1] box_storage/contract.py:37 @@ -626,7 +626,7 @@ set_boxes_block@0: // virtual: store tmp%21#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%21#0 self.box_c.value.bytes[-1] == c.bytes[-1] box_storage/contract.py:37 // virtual: load tmp%21#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%21#0 assert self.box_c.value.bytes[-1] == c.bytes[-1] box_storage/contract.py:37 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0 assert self.box_c.value.bytes[-1] == c.bytes[-1] box_storage/contract.py:37 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43 self.box_c box_storage/contract.py:38 box_len // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_len}.0,{box_len}.1 self.box_c.value.bytes[:-1] box_storage/contract.py:38 pop // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_len}.0 self.box_c.value.bytes[:-1] box_storage/contract.py:38 // virtual: store tmp%22#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%22#0 self.box_c.value.bytes[:-1] box_storage/contract.py:38 @@ -643,7 +643,7 @@ set_boxes_block@0: // virtual: load tmp%25#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%22#0,tmp%25#0 self.box_c.value.bytes[:-1] box_storage/contract.py:38 - // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{-} self.box_c.value.bytes[:-1] box_storage/contract.py:38 // virtual: store tmp%26#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%26#0 self.box_c.value.bytes[:-1] box_storage/contract.py:38 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%26#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%26#0,0x424f585f43 self.box_c box_storage/contract.py:38 int 0 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%26#0,0x424f585f43,0 self.box_c.value.bytes[:-1] box_storage/contract.py:38 uncover 2 // load tmp%26#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43,0,tmp%26#0 self.box_c.value.bytes[:-1] box_storage/contract.py:38 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_extract} self.box_c.value.bytes[:-1] box_storage/contract.py:38 @@ -672,7 +672,7 @@ set_boxes_block@0: // virtual: store tmp%30#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%30#0 self.box_c.value.bytes[:-1] == c.bytes[:-1] box_storage/contract.py:38 // virtual: load tmp%30#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%30#0 assert self.box_c.value.bytes[:-1] == c.bytes[:-1] box_storage/contract.py:38 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0 assert self.box_c.value.bytes[:-1] == c.bytes[:-1] box_storage/contract.py:38 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43 self.box_c box_storage/contract.py:39 box_len // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_len}.0,{box_len}.1 self.box_c.value.bytes[:2] box_storage/contract.py:39 pop // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_len}.0 self.box_c.value.bytes[:2] box_storage/contract.py:39 // virtual: store tmp%31#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%31#0 self.box_c.value.bytes[:2] box_storage/contract.py:39 @@ -685,7 +685,7 @@ set_boxes_block@0: uncover 2 // load tmp%33#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%31#0,2,tmp%33#0 self.box_c.value.bytes[:2] box_storage/contract.py:39 select // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{select} self.box_c.value.bytes[:2] box_storage/contract.py:39 // virtual: store tmp%34#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%34#0 self.box_c.value.bytes[:2] box_storage/contract.py:39 - byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%34#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%34#0,0x424f585f43 self.box_c box_storage/contract.py:39 int 0 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,tmp%34#0,0x424f585f43,0 self.box_c.value.bytes[:2] box_storage/contract.py:39 uncover 2 // load tmp%34#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,0x424f585f43,0,tmp%34#0 self.box_c.value.bytes[:2] box_storage/contract.py:39 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%6#0,{box_extract} self.box_c.value.bytes[:2] box_storage/contract.py:39 @@ -710,7 +710,7 @@ set_boxes_block@0: // virtual: store tmp%38#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%38#0 self.box_c.value.bytes[:2] == c.bytes[:2] box_storage/contract.py:39 // virtual: load tmp%38#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%38#0 assert self.box_c.value.bytes[:2] == c.bytes[:2] box_storage/contract.py:39 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0 assert self.box_c.value.bytes[:2] == c.bytes[:2] box_storage/contract.py:39 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" .value with Bytes type\nassert self.box_d box_storage/contract.py:41-42 int 0 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d",0 type\nassert self.box_d.value[0 box_storage/contract.py:41-42 int 1 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d",0,1 .value with Bytes type\nassert self.box_d.value[0] box_storage/contract.py:41-42 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_extract} .value with Bytes type\nassert self.box_d.value[0] box_storage/contract.py:41-42 @@ -724,7 +724,7 @@ set_boxes_block@0: // virtual: store tmp%42#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%42#0 .value with Bytes type\nassert self.box_d.value[0] == b.native[0] box_storage/contract.py:41-42 // virtual: load tmp%42#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%42#0 # test .value with Bytes type\nassert self.box_d.value[0] == b.native[0] box_storage/contract.py:41-42 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0 # test .value with Bytes type\nassert self.box_d.value[0] == b.native[0] box_storage/contract.py:41-42 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:43 box_len // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_len}.0,{box_len}.1 self.box_d.value[-1] box_storage/contract.py:43 pop // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_len}.0 self.box_d.value[-1] box_storage/contract.py:43 // virtual: store tmp%43#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%43#0 self.box_d.value[-1] box_storage/contract.py:43 @@ -732,7 +732,7 @@ set_boxes_block@0: int 1 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%43#0,1 self.box_d.value[-1] box_storage/contract.py:43 - // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{-} self.box_d.value[-1] box_storage/contract.py:43 // virtual: store tmp%45#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%45#0 self.box_d.value[-1] box_storage/contract.py:43 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%45#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%45#0,"box_d" self.box_d box_storage/contract.py:43 uncover 1 // load tmp%45#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d",tmp%45#0 self.box_d.value[-1] box_storage/contract.py:43 int 1 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d",tmp%45#0,1 self.box_d.value[-1] box_storage/contract.py:43 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_extract} self.box_d.value[-1] box_storage/contract.py:43 @@ -756,7 +756,7 @@ set_boxes_block@0: // virtual: store tmp%52#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%52#0 self.box_d.value[-1] == b.native[-1] box_storage/contract.py:43 // virtual: load tmp%52#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%52#0 assert self.box_d.value[-1] == b.native[-1] box_storage/contract.py:43 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0 assert self.box_d.value[-1] == b.native[-1] box_storage/contract.py:43 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:44 box_len // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_len}.0,{box_len}.1 self.box_d.value[:-1] box_storage/contract.py:44 pop // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_len}.0 self.box_d.value[:-1] box_storage/contract.py:44 // virtual: store tmp%53#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%53#0 self.box_d.value[:-1] box_storage/contract.py:44 @@ -773,7 +773,7 @@ set_boxes_block@0: // virtual: load tmp%56#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%53#0,tmp%56#0 self.box_d.value[:-1] box_storage/contract.py:44 - // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{-} self.box_d.value[:-1] box_storage/contract.py:44 // virtual: store tmp%57#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%57#0 self.box_d.value[:-1] box_storage/contract.py:44 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%57#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%57#0,"box_d" self.box_d box_storage/contract.py:44 int 0 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%57#0,"box_d",0 self.box_d.value[:-1] box_storage/contract.py:44 uncover 2 // load tmp%57#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d",0,tmp%57#0 self.box_d.value[:-1] box_storage/contract.py:44 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_extract} self.box_d.value[:-1] box_storage/contract.py:44 @@ -802,7 +802,7 @@ set_boxes_block@0: // virtual: store tmp%62#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%62#0 self.box_d.value[:-1] == b.native[:-1] box_storage/contract.py:44 // virtual: load tmp%62#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%62#0 assert self.box_d.value[:-1] == b.native[:-1] box_storage/contract.py:44 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0 assert self.box_d.value[:-1] == b.native[:-1] box_storage/contract.py:44 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:45 box_len // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_len}.0,{box_len}.1 self.box_d.value[:5] box_storage/contract.py:45 pop // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_len}.0 self.box_d.value[:5] box_storage/contract.py:45 // virtual: store tmp%63#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%63#0 self.box_d.value[:5] box_storage/contract.py:45 @@ -815,7 +815,7 @@ set_boxes_block@0: uncover 2 // load tmp%65#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%63#0,5,tmp%65#0 self.box_d.value[:5] box_storage/contract.py:45 select // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{select} self.box_d.value[:5] box_storage/contract.py:45 // virtual: store tmp%66#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%66#0 self.box_d.value[:5] box_storage/contract.py:45 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%66#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%66#0,"box_d" self.box_d box_storage/contract.py:45 int 0 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%66#0,"box_d",0 self.box_d.value[:5] box_storage/contract.py:45 uncover 2 // load tmp%66#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d",0,tmp%66#0 self.box_d.value[:5] box_storage/contract.py:45 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_extract} self.box_d.value[:5] box_storage/contract.py:45 @@ -840,7 +840,7 @@ set_boxes_block@0: // virtual: store tmp%71#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%71#0 self.box_d.value[:5] == b.native[:5] box_storage/contract.py:45 // virtual: load tmp%71#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%71#0 assert self.box_d.value[:5] == b.native[:5] box_storage/contract.py:45 assert // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0 assert self.box_d.value[:5] == b.native[:5] box_storage/contract.py:45 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d" self.box_d box_storage/contract.py:46 box_len // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_len}.0,{box_len}.1 self.box_d.value[: UInt64(2)] box_storage/contract.py:46 pop // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_len}.0 self.box_d.value[: UInt64(2)] box_storage/contract.py:46 // virtual: store tmp%72#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%72#0 self.box_d.value[: UInt64(2)] box_storage/contract.py:46 @@ -853,7 +853,7 @@ set_boxes_block@0: uncover 2 // load tmp%74#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%72#0,2,tmp%74#0 self.box_d.value[: UInt64(2)] box_storage/contract.py:46 select // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{select} self.box_d.value[: UInt64(2)] box_storage/contract.py:46 // virtual: store tmp%75#0 to l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%75#0 self.box_d.value[: UInt64(2)] box_storage/contract.py:46 - byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%75#0,"box_d" self.box_d box_storage/contract.py:13 + byte "box_d" // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%75#0,"box_d" self.box_d box_storage/contract.py:46 int 0 // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,tmp%75#0,"box_d",0 self.box_d.value[: UInt64(2)] box_storage/contract.py:46 uncover 2 // load tmp%75#0 from l-stack (no copy) (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,"box_d",0,tmp%75#0 self.box_d.value[: UInt64(2)] box_storage/contract.py:46 box_extract // (𝕡) a#0,b#0,c#0 | tmp%9#0,new_box_value%1#0,{box_extract} self.box_d.value[: UInt64(2)] box_storage/contract.py:46 @@ -886,16 +886,16 @@ delete_boxes: proto 0 0 // @arc4.abimethod\ndef delete_boxes(self) -> None: box_storage/contract.py:54-55 delete_boxes_block@0: - byte "box_a" // "box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // "box_a" self.box_a box_storage/contract.py:56 box_del // {box_del} del self.box_a.value box_storage/contract.py:56 pop // - byte "b" // "b" "b" box_storage/contract.py:11 + byte "b" // "b" self.box_b box_storage/contract.py:57 box_del // {box_del} del self.box_b.value box_storage/contract.py:57 pop // - byte 0x424f585f43 // 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // 0x424f585f43 self.box_c box_storage/contract.py:58 box_del // {box_del} del self.box_c.value box_storage/contract.py:58 pop // - byte "box_a" // "box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // "box_a" self.box_a box_storage/contract.py:59 box_get // {box_get}.0,{box_get}.1 self.box_a.get(default=UInt64(42)) box_storage/contract.py:59 cover 1 // store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{box_get}.0 self.box_a.get(default=UInt64(42)) box_storage/contract.py:59 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_exists%0#0,maybe_value%0#0 self.box_a.get(default=UInt64(42)) box_storage/contract.py:59 @@ -913,7 +913,7 @@ delete_boxes_block@0: // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 self.box_a.get(default=UInt64(42)) == 42 box_storage/contract.py:59 // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 assert self.box_a.get(default=UInt64(42)) == 42 box_storage/contract.py:59 assert // assert self.box_a.get(default=UInt64(42)) == 42 box_storage/contract.py:59 - byte "b" // "b" "b" box_storage/contract.py:11 + byte "b" // "b" self.box_b box_storage/contract.py:60 box_get // {box_get}.0,{box_get}.1 self.box_b.get(default=arc4.DynamicBytes(b"42")) box_storage/contract.py:60 cover 1 // store maybe_exists%1#0 to l-stack (no copy) maybe_exists%1#0,{box_get}.0 self.box_b.get(default=arc4.DynamicBytes(b"42")) box_storage/contract.py:60 // virtual: store maybe_value%1#0 to l-stack (no copy) maybe_exists%1#0,maybe_value%1#0 self.box_b.get(default=arc4.DynamicBytes(b"42")) box_storage/contract.py:60 @@ -931,7 +931,7 @@ delete_boxes_block@0: // virtual: store tmp%4#0 to l-stack (no copy) tmp%4#0 self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" box_storage/contract.py:60 // virtual: load tmp%4#0 from l-stack (no copy) tmp%4#0 assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" box_storage/contract.py:60 assert // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" box_storage/contract.py:60 - byte 0x424f585f43 // 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // 0x424f585f43 self.box_c box_storage/contract.py:61 box_get // {box_get}.0,{box_get}.1 self.box_c.get(default=arc4.String("42")) box_storage/contract.py:61 cover 1 // store maybe_exists%2#0 to l-stack (no copy) maybe_exists%2#0,{box_get}.0 self.box_c.get(default=arc4.String("42")) box_storage/contract.py:61 // virtual: store maybe_value%2#0 to l-stack (no copy) maybe_exists%2#0,maybe_value%2#0 self.box_c.get(default=arc4.String("42")) box_storage/contract.py:61 @@ -946,7 +946,7 @@ delete_boxes_block@0: // virtual: store tmp%6#0 to l-stack (no copy) tmp%6#0 self.box_c.get(default=arc4.String("42")) == "42" box_storage/contract.py:61 // virtual: load tmp%6#0 from l-stack (no copy) tmp%6#0 assert self.box_c.get(default=arc4.String("42")) == "42" box_storage/contract.py:61 assert // assert self.box_c.get(default=arc4.String("42")) == "42" box_storage/contract.py:61 - byte "box_a" // "box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // "box_a" self.box_a box_storage/contract.py:62 box_get // {box_get}.0,{box_get}.1 self.box_a.maybe() box_storage/contract.py:62 cover 1 // store a_exists#0 to l-stack (no copy) a_exists#0,{box_get}.0 self.box_a.maybe() box_storage/contract.py:62 // virtual: store maybe_value%3#0 to l-stack (no copy) a_exists#0,maybe_value%3#0 self.box_a.maybe() box_storage/contract.py:62 @@ -971,14 +971,14 @@ read_boxes: proto 0 3 // @arc4.abimethod\ndef read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: box_storage/contract.py:66-67 read_boxes_block@0: - byte "box_a" // "box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // "box_a" self.box_a box_storage/contract.py:68 callsub get_box_value_plus_1 // {get_box_value_plus_1} get_box_value_plus_1(self.box_a) box_storage/contract.py:68 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 get_box_value_plus_1(self.box_a) box_storage/contract.py:68 // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 get_box_value_plus_1(self.box_a) - 1 box_storage/contract.py:68 int 1 // tmp%0#0,1 1 box_storage/contract.py:68 - // {-} get_box_value_plus_1(self.box_a) - 1 box_storage/contract.py:68 // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 get_box_value_plus_1(self.box_a) - 1 box_storage/contract.py:68 - byte "b" // tmp%1#0,"b" "b" box_storage/contract.py:11 + byte "b" // tmp%1#0,"b" self.box_b box_storage/contract.py:68 box_get // tmp%1#0,{box_get}.0,{box_get}.1 self.box_b.value box_storage/contract.py:68 // virtual: store maybe_exists%0#0 to l-stack (no copy) tmp%1#0,maybe_exists%0#0,{box_get}.0 self.box_b.value box_storage/contract.py:68 // virtual: store maybe_value%0#0 to l-stack (no copy) tmp%1#0,maybe_value%0#0,maybe_exists%0#0 self.box_b.value box_storage/contract.py:68 @@ -987,7 +987,7 @@ read_boxes_block@0: // virtual: load maybe_value%0#0 from l-stack (no copy) tmp%1#0,maybe_value%0#0 self.box_b.value.native box_storage/contract.py:68 extract 2 0 // tmp%1#0,{extract} self.box_b.value.native box_storage/contract.py:68 // virtual: store tmp%2#0 to l-stack (no copy) tmp%1#0,tmp%2#0 self.box_b.value.native box_storage/contract.py:68 - byte 0x424f585f43 // tmp%1#0,tmp%2#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // tmp%1#0,tmp%2#0,0x424f585f43 self.box_c box_storage/contract.py:68 box_get // tmp%1#0,tmp%2#0,{box_get}.0,{box_get}.1 self.box_c.value box_storage/contract.py:68 // virtual: store maybe_exists%1#0 to l-stack (no copy) tmp%1#0,tmp%2#0,maybe_exists%1#0,{box_get}.0 self.box_c.value box_storage/contract.py:68 // virtual: store maybe_value%1#0 to l-stack (no copy) tmp%1#0,tmp%2#0,maybe_value%1#0,maybe_exists%1#0 self.box_c.value box_storage/contract.py:68 @@ -1026,15 +1026,15 @@ boxes_exist: proto 0 3 // @arc4.abimethod\ndef boxes_exist(self) -> tuple[bool, bool, bool]: box_storage/contract.py:70-71 boxes_exist_block@0: - byte "box_a" // "box_a" self.box_a box_storage/contract.py:10 + byte "box_a" // "box_a" self.box_a box_storage/contract.py:72 box_len // {box_len}.0,{box_len}.1 bool(self.box_a) box_storage/contract.py:72 cover 1 // store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{box_len}.0 bool(self.box_a) box_storage/contract.py:72 pop // maybe_exists%0#0 bool(self.box_a) box_storage/contract.py:72 - byte "b" // maybe_exists%0#0,"b" "b" box_storage/contract.py:11 + byte "b" // maybe_exists%0#0,"b" self.box_b box_storage/contract.py:72 box_len // maybe_exists%0#0,{box_len}.0,{box_len}.1 bool(self.box_b) box_storage/contract.py:72 cover 1 // store maybe_exists%1#0 to l-stack (no copy) maybe_exists%0#0,maybe_exists%1#0,{box_len}.0 bool(self.box_b) box_storage/contract.py:72 pop // maybe_exists%0#0,maybe_exists%1#0 bool(self.box_b) box_storage/contract.py:72 - byte 0x424f585f43 // maybe_exists%0#0,maybe_exists%1#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // maybe_exists%0#0,maybe_exists%1#0,0x424f585f43 self.box_c box_storage/contract.py:72 box_len // maybe_exists%0#0,maybe_exists%1#0,{box_len}.0,{box_len}.1 bool(self.box_c) box_storage/contract.py:72 cover 1 // store maybe_exists%2#0 to l-stack (no copy) maybe_exists%0#0,maybe_exists%1#0,maybe_exists%2#0,{box_len}.0 bool(self.box_c) box_storage/contract.py:72 pop // maybe_exists%0#0,maybe_exists%1#0,maybe_exists%2#0 bool(self.box_c) box_storage/contract.py:72 @@ -1088,13 +1088,13 @@ slice_box_block@0: // virtual: store tmp%10#0 to l-stack (no copy) tmp%10#0 box_0.value[0:7] == b"Testing" box_storage/contract.py:78 // virtual: load tmp%10#0 from l-stack (no copy) tmp%10#0 assert box_0.value[0:7] == b"Testing" box_storage/contract.py:78 assert // assert box_0.value[0:7] == b"Testing" box_storage/contract.py:78 - byte 0x424f585f43 // 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // 0x424f585f43 self.box_c box_storage/contract.py:80 box_del // {box_del} self.box_c.value = arc4.String("Hello") box_storage/contract.py:80 pop // - byte 0x424f585f43 // 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // 0x424f585f43 self.box_c box_storage/contract.py:80 byte 0x000548656c6c6f // 0x424f585f43,0x000548656c6c6f arc4.String("Hello") box_storage/contract.py:80 box_put // self.box_c.value = arc4.String("Hello") box_storage/contract.py:80 - byte 0x424f585f43 // 0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // 0x424f585f43 self.box_c box_storage/contract.py:81 box_len // {box_len}.0,{box_len}.1 self.box_c.value.bytes[2:10] box_storage/contract.py:81 pop // {box_len}.0 self.box_c.value.bytes[2:10] box_storage/contract.py:81 // virtual: store tmp%11#0 to l-stack (no copy) tmp%11#0 self.box_c.value.bytes[2:10] box_storage/contract.py:81 @@ -1120,7 +1120,7 @@ slice_box_block@0: dig 1 // load tmp%14#0 from l-stack (copy) tmp%14#0,tmp%16#0,tmp%14#0 self.box_c.value.bytes[2:10] box_storage/contract.py:81 - // tmp%14#0,{-} self.box_c.value.bytes[2:10] box_storage/contract.py:81 // virtual: store tmp%19#0 to l-stack (no copy) tmp%14#0,tmp%19#0 self.box_c.value.bytes[2:10] box_storage/contract.py:81 - byte 0x424f585f43 // tmp%14#0,tmp%19#0,0x424f585f43 b"BOX_C" box_storage/contract.py:12 + byte 0x424f585f43 // tmp%14#0,tmp%19#0,0x424f585f43 self.box_c box_storage/contract.py:81 uncover 2 // load tmp%14#0 from l-stack (no copy) tmp%19#0,0x424f585f43,tmp%14#0 self.box_c.value.bytes[2:10] box_storage/contract.py:81 uncover 2 // load tmp%19#0 from l-stack (no copy) 0x424f585f43,tmp%14#0,tmp%19#0 self.box_c.value.bytes[2:10] box_storage/contract.py:81 box_extract // {box_extract} self.box_c.value.bytes[2:10] box_storage/contract.py:81 @@ -1366,17 +1366,17 @@ test_box_ref_block@0: // virtual: store tmp%19#0 to l-stack (no copy) tmp%19#0 get_box_ref_length(box_ref) == 64 box_storage/contract.py:134 // virtual: load tmp%19#0 from l-stack (no copy) tmp%19#0 assert get_box_ref_length(box_ref) == 64 box_storage/contract.py:134 assert // assert get_box_ref_length(box_ref) == 64 box_storage/contract.py:134 - byte "box_ref" // "box_ref" self.box_ref box_storage/contract.py:15 + byte "box_ref" // "box_ref" # instance box ref\nself.box_ref box_storage/contract.py:136-137 int 32 // "box_ref",32 \nself.box_ref.create(size=UInt64(32) box_storage/contract.py:136-137 box_create // {box_create} # instance box ref\nself.box_ref.create(size=UInt64(32)) box_storage/contract.py:136-137 pop // - byte "box_ref" // "box_ref" self.box_ref box_storage/contract.py:15 + byte "box_ref" // "box_ref" self.box_ref box_storage/contract.py:138 box_len // {box_len}.0,{box_len}.1 self.box_ref box_storage/contract.py:138 cover 1 // store maybe_exists%8#0 to l-stack (no copy) maybe_exists%8#0,{box_len}.0 self.box_ref box_storage/contract.py:138 pop // maybe_exists%8#0 self.box_ref box_storage/contract.py:138 // virtual: load maybe_exists%8#0 from l-stack (no copy) maybe_exists%8#0 assert self.box_ref, "has data" box_storage/contract.py:138 assert // has data // assert self.box_ref, "has data" box_storage/contract.py:138 - byte "box_ref" // "box_ref" self.box_ref box_storage/contract.py:15 + byte "box_ref" // "box_ref" self.box_ref box_storage/contract.py:139 box_del // {box_del} self.box_ref.delete() box_storage/contract.py:139 pop // retsub // @@ -1462,10 +1462,10 @@ box_map_test_block@0: // virtual: store tmp%16#0 to l-stack (no copy) tmp%0#0,tmp%10#0,tmp%16#0 not exists box_storage/contract.py:152 // virtual: load tmp%16#0 from l-stack (no copy) tmp%0#0,tmp%10#0,tmp%16#0 assert not exists box_storage/contract.py:152 assert // tmp%0#0,tmp%10#0 assert not exists box_storage/contract.py:152 - uncover 1 // load tmp%0#0 from l-stack (no copy) tmp%10#0,tmp%0#0 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-153 - box_len // tmp%10#0,{box_len}.0,{box_len}.1 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-153 - cover 1 // store maybe_exists%2#0 to l-stack (no copy) tmp%10#0,maybe_exists%2#0,{box_len}.0 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-153 - pop // tmp%10#0,maybe_exists%2#0 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-153 + uncover 1 // load tmp%0#0 from l-stack (no copy) tmp%10#0,tmp%0#0 key_0 in self.box_map box_storage/contract.py:153 + box_len // tmp%10#0,{box_len}.0,{box_len}.1 key_0 in self.box_map box_storage/contract.py:153 + cover 1 // store maybe_exists%2#0 to l-stack (no copy) tmp%10#0,maybe_exists%2#0,{box_len}.0 key_0 in self.box_map box_storage/contract.py:153 + pop // tmp%10#0,maybe_exists%2#0 key_0 in self.box_map box_storage/contract.py:153 // virtual: load maybe_exists%2#0 from l-stack (no copy) tmp%10#0,maybe_exists%2#0 assert key_0 in self.box_map box_storage/contract.py:153 assert // tmp%10#0 assert key_0 in self.box_map box_storage/contract.py:153 dup // load tmp%10#0 from l-stack (copy) tmp%10#0,tmp%10#0 tmp_box_map[key_1] = String("hello") box_storage/contract.py:158 @@ -1570,13 +1570,13 @@ box_map_exists: proto 1 1 // (𝕡) key#0 | @arc4.abimethod\ndef box_map_exists(self, key: UInt64) -> bool: box_storage/contract.py:174-175 box_map_exists_block@0: - frame_dig -1 // load key#0 from parameters (𝕡) key#0 | key#0 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-176 - itob // (𝕡) key#0 | {itob} "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-176 - // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) key#0 | tmp%0#0 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-176 - // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) key#0 | tmp%0#0 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-176 - box_len // (𝕡) key#0 | {box_len}.0,{box_len}.1 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-176 - cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕡) key#0 | maybe_exists%0#0,{box_len}.0 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-176 - pop // (𝕡) key#0 | maybe_exists%0#0 "")\nself.box_ref = BoxRef()\n\n@arc4.abimethod\ndef set_boxes(self, a: UInt64, b: arc4.DynamicBy... box_storage/contract.py:14-176 + frame_dig -1 // load key#0 from parameters (𝕡) key#0 | key#0 key in self.box_map box_storage/contract.py:176 + itob // (𝕡) key#0 | {itob} key in self.box_map box_storage/contract.py:176 + // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) key#0 | tmp%0#0 key in self.box_map box_storage/contract.py:176 + // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) key#0 | tmp%0#0 key in self.box_map box_storage/contract.py:176 + box_len // (𝕡) key#0 | {box_len}.0,{box_len}.1 key in self.box_map box_storage/contract.py:176 + cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕡) key#0 | maybe_exists%0#0,{box_len}.0 key in self.box_map box_storage/contract.py:176 + pop // (𝕡) key#0 | maybe_exists%0#0 key in self.box_map box_storage/contract.py:176 // virtual: load maybe_exists%0#0 from l-stack (no copy) (𝕡) key#0 | maybe_exists%0#0 return key in self.box_map box_storage/contract.py:176 retsub // maybe_exists%0#0 return key in self.box_map box_storage/contract.py:176 diff --git a/examples/box_storage/out/BoxContract.approval.teal b/examples/box_storage/out/BoxContract.approval.teal index e755a818a1..5fa76474d5 100644 --- a/examples/box_storage/out/BoxContract.approval.teal +++ b/examples/box_storage/out/BoxContract.approval.teal @@ -328,71 +328,43 @@ set_boxes: // self.box_a.value = a frame_dig -3 itob - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) byte "box_a" - // box_storage/contract.py:19 - // self.box_a.value = a swap box_put - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:20 // self.box_b.value = b.copy() + byte "b" box_del pop - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") byte "b" - // box_storage/contract.py:20 - // self.box_b.value = b.copy() frame_dig -2 box_put - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:21 // self.box_c.value = c + byte 0x424f585f43 box_del pop - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:21 - // self.box_c.value = c frame_dig -1 box_put // box_storage/contract.py:22 // self.box_d.value = b.native frame_dig -2 extract 2 0 - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:22 - // self.box_d.value = b.native box_del pop - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:22 - // self.box_d.value = b.native dig 1 box_put - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:24 // b_value = self.box_b.value.copy() + byte "b" box_get assert // check self.box_b exists - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:25 // assert self.box_b.value.length == b_value.length, "direct reference should match copy" + byte "b" box_get assert // check self.box_b exists int 0 @@ -402,11 +374,9 @@ set_boxes: extract_uint16 == assert // direct reference should match copy - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:27 // self.box_a.value += 3 + byte "box_a" box_get swap btoi @@ -415,40 +385,30 @@ set_boxes: int 3 + itob - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) byte "box_a" - // box_storage/contract.py:27 - // self.box_a.value += 3 swap box_put - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:29-30 // # test .length // assert self.box_a.length == 8 + byte "box_a" box_len assert // check self.box_a exists int 8 == assert - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:31 // assert self.box_b.length == b.bytes.length + byte "b" box_len assert // check self.box_b exists frame_dig -2 len == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:32 // assert self.box_c.length == c.bytes.length + byte 0x424f585f43 box_len assert // check self.box_c exists frame_dig -1 @@ -457,11 +417,9 @@ set_boxes: cover 2 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:33 // assert self.box_d.length == b.native.length + byte "box_d" box_len assert // check self.box_d exists dig 2 @@ -470,12 +428,10 @@ set_boxes: cover 4 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:35-36 // # test .value.bytes // assert self.box_c.value.bytes[0] == c.bytes[0] + byte 0x424f585f43 int 0 int 1 box_extract @@ -483,20 +439,14 @@ set_boxes: extract 0 1 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:37 // assert self.box_c.value.bytes[-1] == c.bytes[-1] + byte 0x424f585f43 box_len pop int 1 - - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:37 - // assert self.box_c.value.bytes[-1] == c.bytes[-1] swap int 1 box_extract @@ -511,11 +461,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:38 // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] + byte 0x424f585f43 box_len pop int 1 @@ -527,11 +475,7 @@ set_boxes: uncover 3 select - - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:38 - // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] int 0 uncover 2 box_extract @@ -551,11 +495,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:39 // assert self.box_c.value.bytes[:2] == c.bytes[:2] + byte 0x424f585f43 box_len pop int 2 @@ -564,11 +506,7 @@ set_boxes: int 2 swap select - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:39 - // assert self.box_c.value.bytes[:2] == c.bytes[:2] int 0 uncover 2 box_extract @@ -585,12 +523,10 @@ set_boxes: substring3 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:41-42 // # test .value with Bytes type // assert self.box_d.value[0] == b.native[0] + byte "box_d" int 0 int 1 box_extract @@ -598,20 +534,14 @@ set_boxes: extract 0 1 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:43 // assert self.box_d.value[-1] == b.native[-1] + byte "box_d" box_len pop int 1 - - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:43 - // assert self.box_d.value[-1] == b.native[-1] swap int 1 box_extract @@ -626,11 +556,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:44 // assert self.box_d.value[:-1] == b.native[:-1] + byte "box_d" box_len pop int 1 @@ -642,11 +570,7 @@ set_boxes: uncover 3 select - - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:44 - // assert self.box_d.value[:-1] == b.native[:-1] int 0 uncover 2 box_extract @@ -666,11 +590,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:45 // assert self.box_d.value[:5] == b.native[:5] + byte "box_d" box_len pop int 5 @@ -679,11 +601,7 @@ set_boxes: int 5 swap select - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:45 - // assert self.box_d.value[:5] == b.native[:5] int 0 uncover 2 box_extract @@ -700,11 +618,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:46 // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] + byte "box_d" box_len pop int 2 @@ -713,11 +629,7 @@ set_boxes: int 2 swap select - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:46 - // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] int 0 uncover 2 box_extract @@ -743,32 +655,24 @@ delete_boxes: // @arc4.abimethod // def delete_boxes(self) -> None: proto 0 0 - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:56 // del self.box_a.value + byte "box_a" box_del pop - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:57 // del self.box_b.value + byte "b" box_del pop - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:58 // del self.box_c.value + byte 0x424f585f43 box_del pop - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:59 // assert self.box_a.get(default=UInt64(42)) == 42 + byte "box_a" box_get swap btoi @@ -779,11 +683,9 @@ delete_boxes: int 42 == assert - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:60 // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" + byte "b" box_get byte 0x00023432 cover 2 @@ -792,11 +694,9 @@ delete_boxes: byte 0x3432 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:61 // assert self.box_c.get(default=arc4.String("42")) == "42" + byte 0x424f585f43 box_get byte 0x00023432 cover 2 @@ -804,11 +704,9 @@ delete_boxes: byte 0x00023432 == assert - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:62 // a, a_exists = self.box_a.maybe() + byte "box_a" box_get swap btoi @@ -830,27 +728,17 @@ read_boxes: // @arc4.abimethod // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: proto 0 3 - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:68 // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value + byte "box_a" callsub get_box_value_plus_1 int 1 - - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") byte "b" - // box_storage/contract.py:68 - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value box_get assert // check self.box_b exists extract 2 0 - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:68 - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value box_get assert // check self.box_c exists retsub @@ -881,25 +769,15 @@ boxes_exist: // @arc4.abimethod // def boxes_exist(self) -> tuple[bool, bool, bool]: proto 0 3 - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:72 // return bool(self.box_a), bool(self.box_b), bool(self.box_c) + byte "box_a" box_len bury 1 - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") byte "b" - // box_storage/contract.py:72 - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) box_len bury 1 - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:72 - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) box_len bury 1 retsub @@ -955,25 +833,17 @@ slice_box: byte 0x54657374696e67 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:80 // self.box_c.value = arc4.String("Hello") + byte 0x424f585f43 box_del pop - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:80 - // self.box_c.value = arc4.String("Hello") byte 0x000548656c6c6f box_put - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:81 // assert self.box_c.value.bytes[2:10] == b"Hello" + byte 0x424f585f43 box_len pop int 2 @@ -993,11 +863,7 @@ slice_box: select dig 1 - - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:81 - // assert self.box_c.value.bytes[2:10] == b"Hello" cover 2 box_extract byte 0x48656c6c6f @@ -1266,28 +1132,22 @@ test_box_ref: int 64 == assert - // box_storage/contract.py:15 - // self.box_ref = BoxRef() - byte "box_ref" // box_storage/contract.py:136-137 // # instance box ref // self.box_ref.create(size=UInt64(32)) + byte "box_ref" int 32 box_create pop - // box_storage/contract.py:15 - // self.box_ref = BoxRef() - byte "box_ref" // box_storage/contract.py:138 // assert self.box_ref, "has data" + byte "box_ref" box_len bury 1 assert // has data - // box_storage/contract.py:15 - // self.box_ref = BoxRef() - byte "box_ref" // box_storage/contract.py:139 // self.box_ref.delete() + byte "box_ref" box_del pop retsub @@ -1368,152 +1228,11 @@ box_map_test: // assert not exists ! assert - // box_storage/contract.py:14-153 - // self.box_map = BoxMap(UInt64, String, key_prefix="") - // self.box_ref = BoxRef() - // - // @arc4.abimethod - // def set_boxes(self, a: UInt64, b: arc4.DynamicBytes, c: arc4.String) -> None: - // self.box_a.value = a - // self.box_b.value = b.copy() - // self.box_c.value = c - // self.box_d.value = b.native - // - // b_value = self.box_b.value.copy() - // assert self.box_b.value.length == b_value.length, "direct reference should match copy" - // - // self.box_a.value += 3 - // - // # test .length - // assert self.box_a.length == 8 - // assert self.box_b.length == b.bytes.length - // assert self.box_c.length == c.bytes.length - // assert self.box_d.length == b.native.length - // - // # test .value.bytes - // assert self.box_c.value.bytes[0] == c.bytes[0] - // assert self.box_c.value.bytes[-1] == c.bytes[-1] - // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] - // assert self.box_c.value.bytes[:2] == c.bytes[:2] - // - // # test .value with Bytes type - // assert self.box_d.value[0] == b.native[0] - // assert self.box_d.value[-1] == b.native[-1] - // assert self.box_d.value[:-1] == b.native[:-1] - // assert self.box_d.value[:5] == b.native[:5] - // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] - // - // @arc4.abimethod - // def check_keys(self) -> None: - // assert self.box_a.key == b"box_a", "box a key ok" - // assert self.box_b.key == b"b", "box b key ok" - // assert self.box_c.key == b"BOX_C", "box c key ok" - // - // @arc4.abimethod - // def delete_boxes(self) -> None: - // del self.box_a.value - // del self.box_b.value - // del self.box_c.value - // assert self.box_a.get(default=UInt64(42)) == 42 - // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" - // assert self.box_c.get(default=arc4.String("42")) == "42" - // a, a_exists = self.box_a.maybe() - // assert not a_exists - // assert a == 0 - // - // @arc4.abimethod - // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value - // - // @arc4.abimethod - // def boxes_exist(self) -> tuple[bool, bool, bool]: - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) - // - // @arc4.abimethod - // def slice_box(self) -> None: - // box_0 = Box(Bytes, key=String("0")) - // box_0.value = Bytes(b"Testing testing 123") - // assert box_0.value[0:7] == b"Testing" - // - // self.box_c.value = arc4.String("Hello") - // assert self.box_c.value.bytes[2:10] == b"Hello" - // - // @arc4.abimethod - // def arc4_box(self) -> None: - // box_d = Box(StaticInts, key=Bytes(b"d")) - // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) - // - // assert box_d.value[0] == 0 - // assert box_d.value[1] == 1 - // assert box_d.value[2] == 2 - // assert box_d.value[3] == 3 - // - // @arc4.abimethod - // def test_box_ref(self) -> None: - // # init ref, with valid key types - // box_ref = BoxRef(key="blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=b"blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=Bytes(b"blob")) - // assert not box_ref, "no data" - // box_ref = BoxRef(key=String("blob")) - // assert not box_ref, "no data" - // - // # create - // assert box_ref.create(size=32) - // assert box_ref, "has data" - // - // # manipulate data - // sender_bytes = Txn.sender.bytes - // app_address = Global.current_application_address.bytes - // value_3 = Bytes(b"hello") - // box_ref.replace(0, sender_bytes) - // box_ref.resize(8000) - // box_ref.splice(0, 0, app_address) - // box_ref.replace(64, value_3) - // prefix = box_ref.extract(0, 32 * 2 + value_3.length) - // assert prefix == app_address + sender_bytes + value_3 - // - // # delete - // assert box_ref.delete() - // assert box_ref.key == b"blob" - // - // # query - // value, exists = box_ref.maybe() - // assert not exists - // assert value == b"" - // assert box_ref.get(default=sender_bytes) == sender_bytes - // - // # update - // box_ref.put(sender_bytes + app_address) - // assert box_ref, "Blob exists" - // assert box_ref.length == 64 - // assert get_box_ref_length(box_ref) == 64 - // - // # instance box ref - // self.box_ref.create(size=UInt64(32)) - // assert self.box_ref, "has data" - // self.box_ref.delete() - // - // @arc4.abimethod - // def box_map_test(self) -> None: - // key_0 = UInt64(0) - // key_1 = UInt64(1) - // value = String("Hmmmmm") - // self.box_map[key_0] = value - // assert self.box_map[key_0].bytes.length == value.bytes.length - // assert self.box_map.length(key_0) == value.bytes.length - // - // assert self.box_map.get(key_1, default=String("default")) == String("default") - // value, exists = self.box_map.maybe(key_1) - // assert not exists - // assert key_0 in self.box_map + // box_storage/contract.py:153 + // assert key_0 in self.box_map swap box_len bury 1 - // box_storage/contract.py:153 - // assert key_0 in self.box_map assert // box_storage/contract.py:158 // tmp_box_map[key_1] = String("hello") @@ -1615,174 +1334,10 @@ box_map_exists: // @arc4.abimethod // def box_map_exists(self, key: UInt64) -> bool: proto 1 1 - // box_storage/contract.py:14-176 - // self.box_map = BoxMap(UInt64, String, key_prefix="") - // self.box_ref = BoxRef() - // - // @arc4.abimethod - // def set_boxes(self, a: UInt64, b: arc4.DynamicBytes, c: arc4.String) -> None: - // self.box_a.value = a - // self.box_b.value = b.copy() - // self.box_c.value = c - // self.box_d.value = b.native - // - // b_value = self.box_b.value.copy() - // assert self.box_b.value.length == b_value.length, "direct reference should match copy" - // - // self.box_a.value += 3 - // - // # test .length - // assert self.box_a.length == 8 - // assert self.box_b.length == b.bytes.length - // assert self.box_c.length == c.bytes.length - // assert self.box_d.length == b.native.length - // - // # test .value.bytes - // assert self.box_c.value.bytes[0] == c.bytes[0] - // assert self.box_c.value.bytes[-1] == c.bytes[-1] - // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] - // assert self.box_c.value.bytes[:2] == c.bytes[:2] - // - // # test .value with Bytes type - // assert self.box_d.value[0] == b.native[0] - // assert self.box_d.value[-1] == b.native[-1] - // assert self.box_d.value[:-1] == b.native[:-1] - // assert self.box_d.value[:5] == b.native[:5] - // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] - // - // @arc4.abimethod - // def check_keys(self) -> None: - // assert self.box_a.key == b"box_a", "box a key ok" - // assert self.box_b.key == b"b", "box b key ok" - // assert self.box_c.key == b"BOX_C", "box c key ok" - // - // @arc4.abimethod - // def delete_boxes(self) -> None: - // del self.box_a.value - // del self.box_b.value - // del self.box_c.value - // assert self.box_a.get(default=UInt64(42)) == 42 - // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" - // assert self.box_c.get(default=arc4.String("42")) == "42" - // a, a_exists = self.box_a.maybe() - // assert not a_exists - // assert a == 0 - // - // @arc4.abimethod - // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value - // - // @arc4.abimethod - // def boxes_exist(self) -> tuple[bool, bool, bool]: - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) - // - // @arc4.abimethod - // def slice_box(self) -> None: - // box_0 = Box(Bytes, key=String("0")) - // box_0.value = Bytes(b"Testing testing 123") - // assert box_0.value[0:7] == b"Testing" - // - // self.box_c.value = arc4.String("Hello") - // assert self.box_c.value.bytes[2:10] == b"Hello" - // - // @arc4.abimethod - // def arc4_box(self) -> None: - // box_d = Box(StaticInts, key=Bytes(b"d")) - // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) - // - // assert box_d.value[0] == 0 - // assert box_d.value[1] == 1 - // assert box_d.value[2] == 2 - // assert box_d.value[3] == 3 - // - // @arc4.abimethod - // def test_box_ref(self) -> None: - // # init ref, with valid key types - // box_ref = BoxRef(key="blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=b"blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=Bytes(b"blob")) - // assert not box_ref, "no data" - // box_ref = BoxRef(key=String("blob")) - // assert not box_ref, "no data" - // - // # create - // assert box_ref.create(size=32) - // assert box_ref, "has data" - // - // # manipulate data - // sender_bytes = Txn.sender.bytes - // app_address = Global.current_application_address.bytes - // value_3 = Bytes(b"hello") - // box_ref.replace(0, sender_bytes) - // box_ref.resize(8000) - // box_ref.splice(0, 0, app_address) - // box_ref.replace(64, value_3) - // prefix = box_ref.extract(0, 32 * 2 + value_3.length) - // assert prefix == app_address + sender_bytes + value_3 - // - // # delete - // assert box_ref.delete() - // assert box_ref.key == b"blob" - // - // # query - // value, exists = box_ref.maybe() - // assert not exists - // assert value == b"" - // assert box_ref.get(default=sender_bytes) == sender_bytes - // - // # update - // box_ref.put(sender_bytes + app_address) - // assert box_ref, "Blob exists" - // assert box_ref.length == 64 - // assert get_box_ref_length(box_ref) == 64 - // - // # instance box ref - // self.box_ref.create(size=UInt64(32)) - // assert self.box_ref, "has data" - // self.box_ref.delete() - // - // @arc4.abimethod - // def box_map_test(self) -> None: - // key_0 = UInt64(0) - // key_1 = UInt64(1) - // value = String("Hmmmmm") - // self.box_map[key_0] = value - // assert self.box_map[key_0].bytes.length == value.bytes.length - // assert self.box_map.length(key_0) == value.bytes.length - // - // assert self.box_map.get(key_1, default=String("default")) == String("default") - // value, exists = self.box_map.maybe(key_1) - // assert not exists - // assert key_0 in self.box_map - // assert self.box_map.key_prefix == b"" - // - // # test box map not assigned to the class and passed to subroutine - // tmp_box_map = BoxMap(UInt64, String, key_prefix=Bytes()) - // tmp_box_map[key_1] = String("hello") - // assert get_box_map_value_from_key_plus_1(tmp_box_map, UInt64(0)) == "hello" - // del tmp_box_map[key_1] - // - // @arc4.abimethod - // def box_map_set(self, key: UInt64, value: String) -> None: - // self.box_map[key] = value - // - // @arc4.abimethod - // def box_map_get(self, key: UInt64) -> String: - // return self.box_map[key] - // - // @arc4.abimethod - // def box_map_del(self, key: UInt64) -> None: - // del self.box_map[key] - // - // @arc4.abimethod - // def box_map_exists(self, key: UInt64) -> bool: - // return key in self.box_map + // box_storage/contract.py:176 + // return key in self.box_map frame_dig -1 itob box_len bury 1 - // box_storage/contract.py:176 - // return key in self.box_map retsub diff --git a/examples/box_storage/out/BoxContract.arc32.json b/examples/box_storage/out/BoxContract.arc32.json index f78a508adc..cb0ec7a78f 100644 --- a/examples/box_storage/out/BoxContract.arc32.json +++ b/examples/box_storage/out/BoxContract.arc32.json @@ -67,7 +67,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE3CiAgICBtZXRob2QgInNldF9ib3hlcyh1aW50NjQsYnl0ZVtdLHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJjaGVja19rZXlzKCl2b2lkIgogICAgbWV0aG9kICJkZWxldGVfYm94ZXMoKXZvaWQiCiAgICBtZXRob2QgInJlYWRfYm94ZXMoKSh1aW50NjQsYnl0ZVtdLHN0cmluZykiCiAgICBtZXRob2QgImJveGVzX2V4aXN0KCkoYm9vbCxib29sLGJvb2wpIgogICAgbWV0aG9kICJzbGljZV9ib3goKXZvaWQiCiAgICBtZXRob2QgImFyYzRfYm94KCl2b2lkIgogICAgbWV0aG9kICJ0ZXN0X2JveF9yZWYoKXZvaWQiCiAgICBtZXRob2QgImJveF9tYXBfdGVzdCgpdm9pZCIKICAgIG1ldGhvZCAiYm94X21hcF9zZXQodWludDY0LHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJib3hfbWFwX2dldCh1aW50NjQpc3RyaW5nIgogICAgbWV0aG9kICJib3hfbWFwX2RlbCh1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAiYm94X21hcF9leGlzdHModWludDY0KWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYm94ZXNfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jaGVja19rZXlzX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX2JveGVzX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fcmVhZF9ib3hlc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JveGVzX2V4aXN0X3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fc2xpY2VfYm94X3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9ib3hfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX190ZXN0X2JveF9yZWZfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19ib3hfbWFwX3Rlc3Rfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9zZXRfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9nZXRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9kZWxfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9leGlzdHNfcm91dGVAMTQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9ib3hlc19yb3V0ZUAyOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBzZXRfYm94ZXMKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NoZWNrX2tleXNfcm91dGVAMzoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9ib3hlc19yb3V0ZUA0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBkZWxldGVfYm94ZXMKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3JlYWRfYm94ZXNfcm91dGVANToKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgcmVhZF9ib3hlcwogICAgY292ZXIgMgogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGJ5dGUgMHgwMDBjCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpbnQgMTIKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JveGVzX2V4aXN0X3JvdXRlQDY6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJveGVzX2V4aXN0CiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgY292ZXIgMgogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMwogICAgc2V0Yml0CiAgICBzd2FwCiAgICBpbnQgMAogICAgZ2V0Yml0CiAgICB1bmNvdmVyIDIKICAgIGludCAxCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgc3dhcAogICAgaW50IDAKICAgIGdldGJpdAogICAgaW50IDIKICAgIHN3YXAKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2xpY2VfYm94X3JvdXRlQDc6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHNsaWNlX2JveAogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9ib3hfcm91dGVAODoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgYXJjNF9ib3gKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3Rlc3RfYm94X3JlZl9yb3V0ZUA5OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB0ZXN0X2JveF9yZWYKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JveF9tYXBfdGVzdF9yb3V0ZUAxMDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJveF9tYXBfdGVzdAogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9zZXRfcm91dGVAMTE6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIGJveF9tYXBfc2V0CiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ib3hfbWFwX2dldF9yb3V0ZUAxMjoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib3hfbWFwX2dldAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JveF9tYXBfZGVsX3JvdXRlQDEzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgKICAgIC8vIGNsYXNzIEJveENvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIGJveF9tYXBfZGVsCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ib3hfbWFwX2V4aXN0c19yb3V0ZUAxNDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib3hfbWFwX2V4aXN0cwogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNzoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgKICAgIC8vIGNsYXNzIEJveENvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LnNldF9ib3hlcyhhOiB1aW50NjQsIGI6IGJ5dGVzLCBjOiBieXRlcykgLT4gdm9pZDoKc2V0X2JveGVzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTctMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHNldF9ib3hlcyhzZWxmLCBhOiBVSW50NjQsIGI6IGFyYzQuRHluYW1pY0J5dGVzLCBjOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIHByb3RvIDMgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTkKICAgIC8vIHNlbGYuYm94X2EudmFsdWUgPSBhCiAgICBmcmFtZV9kaWcgLTMKICAgIGl0b2IKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBzZWxmLmJveF9hID0gQm94KFVJbnQ2NCkKICAgIGJ5dGUgImJveF9hIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTkKICAgIC8vIHNlbGYuYm94X2EudmFsdWUgPSBhCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMQogICAgLy8gc2VsZi5ib3hfYiA9IEJveFthcmM0LkR5bmFtaWNCeXRlc10oYXJjNC5EeW5hbWljQnl0ZXMsIGtleT0iYiIpCiAgICBieXRlICJiIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjAKICAgIC8vIHNlbGYuYm94X2IudmFsdWUgPSBiLmNvcHkoKQogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMQogICAgLy8gc2VsZi5ib3hfYiA9IEJveFthcmM0LkR5bmFtaWNCeXRlc10oYXJjNC5EeW5hbWljQnl0ZXMsIGtleT0iYiIpCiAgICBieXRlICJiIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjAKICAgIC8vIHNlbGYuYm94X2IudmFsdWUgPSBiLmNvcHkoKQogICAgZnJhbWVfZGlnIC0yCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjIxCiAgICAvLyBzZWxmLmJveF9jLnZhbHVlID0gYwogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjIxCiAgICAvLyBzZWxmLmJveF9jLnZhbHVlID0gYwogICAgZnJhbWVfZGlnIC0xCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyMgogICAgLy8gc2VsZi5ib3hfZC52YWx1ZSA9IGIubmF0aXZlCiAgICBmcmFtZV9kaWcgLTIKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMwogICAgLy8gc2VsZi5ib3hfZCA9IEJveChCeXRlcykKICAgIGJ5dGUgImJveF9kIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjIKICAgIC8vIHNlbGYuYm94X2QudmFsdWUgPSBiLm5hdGl2ZQogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMwogICAgLy8gc2VsZi5ib3hfZCA9IEJveChCeXRlcykKICAgIGJ5dGUgImJveF9kIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjIKICAgIC8vIHNlbGYuYm94X2QudmFsdWUgPSBiLm5hdGl2ZQogICAgZGlnIDEKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExCiAgICAvLyBzZWxmLmJveF9iID0gQm94W2FyYzQuRHluYW1pY0J5dGVzXShhcmM0LkR5bmFtaWNCeXRlcywga2V5PSJiIikKICAgIGJ5dGUgImIiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNAogICAgLy8gYl92YWx1ZSA9IHNlbGYuYm94X2IudmFsdWUuY29weSgpCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ib3hfYiBleGlzdHMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExCiAgICAvLyBzZWxmLmJveF9iID0gQm94W2FyYzQuRHluYW1pY0J5dGVzXShhcmM0LkR5bmFtaWNCeXRlcywga2V5PSJiIikKICAgIGJ5dGUgImIiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNQogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2IudmFsdWUubGVuZ3RoID09IGJfdmFsdWUubGVuZ3RoLCAiZGlyZWN0IHJlZmVyZW5jZSBzaG91bGQgbWF0Y2ggY29weSIKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9iIGV4aXN0cwogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgID09CiAgICBhc3NlcnQgLy8gZGlyZWN0IHJlZmVyZW5jZSBzaG91bGQgbWF0Y2ggY29weQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0KQogICAgYnl0ZSAiYm94X2EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNwogICAgLy8gc2VsZi5ib3hfYS52YWx1ZSArPSAzCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBidG9pCiAgICBzd2FwCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ib3hfYSBleGlzdHMKICAgIGludCAzCiAgICArCiAgICBpdG9iCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMAogICAgLy8gc2VsZi5ib3hfYSA9IEJveChVSW50NjQpCiAgICBieXRlICJib3hfYSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBzZWxmLmJveF9hLnZhbHVlICs9IDMKICAgIHN3YXAKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBzZWxmLmJveF9hID0gQm94KFVJbnQ2NCkKICAgIGJ5dGUgImJveF9hIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjktMzAKICAgIC8vICMgdGVzdCAubGVuZ3RoCiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYS5sZW5ndGggPT0gOAogICAgYm94X2xlbgogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X2EgZXhpc3RzCiAgICBpbnQgOAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTEKICAgIC8vIHNlbGYuYm94X2IgPSBCb3hbYXJjNC5EeW5hbWljQnl0ZXNdKGFyYzQuRHluYW1pY0J5dGVzLCBrZXk9ImIiKQogICAgYnl0ZSAiYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjMxCiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYi5sZW5ndGggPT0gYi5ieXRlcy5sZW5ndGgKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9iIGV4aXN0cwogICAgZnJhbWVfZGlnIC0yCiAgICBsZW4KICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzIKICAgIC8vIGFzc2VydCBzZWxmLmJveF9jLmxlbmd0aCA9PSBjLmJ5dGVzLmxlbmd0aAogICAgYm94X2xlbgogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X2MgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgZHVwCiAgICBjb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMwogICAgLy8gc2VsZi5ib3hfZCA9IEJveChCeXRlcykKICAgIGJ5dGUgImJveF9kIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzMKICAgIC8vIGFzc2VydCBzZWxmLmJveF9kLmxlbmd0aCA9PSBiLm5hdGl2ZS5sZW5ndGgKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9kIGV4aXN0cwogICAgZGlnIDIKICAgIGxlbgogICAgZHVwCiAgICBjb3ZlciA0CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjM1LTM2CiAgICAvLyAjIHRlc3QgLnZhbHVlLmJ5dGVzCiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1swXSA9PSBjLmJ5dGVzWzBdCiAgICBpbnQgMAogICAgaW50IDEKICAgIGJveF9leHRyYWN0CiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1stMV0gPT0gYy5ieXRlc1stMV0KICAgIGJveF9sZW4KICAgIHBvcAogICAgaW50IDEKICAgIC0KICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzcKICAgIC8vIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWy0xXSA9PSBjLmJ5dGVzWy0xXQogICAgc3dhcAogICAgaW50IDEKICAgIGJveF9leHRyYWN0CiAgICBkaWcgMQogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2RpZyAtMQogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYuYm94X2MgPSBCb3goYXJjNC5TdHJpbmcsIGtleT1iIkJPWF9DIikKICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozOAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbOi0xXSA9PSBjLmJ5dGVzWzotMV0KICAgIGJveF9sZW4KICAgIHBvcAogICAgaW50IDEKICAgIGRpZyAxCiAgICA8CiAgICBzd2FwCiAgICBkdXAKICAgIGludCAxCiAgICB1bmNvdmVyIDMKICAgIHNlbGVjdAogICAgLQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYuYm94X2MgPSBCb3goYXJjNC5TdHJpbmcsIGtleT1iIkJPWF9DIikKICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozOAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbOi0xXSA9PSBjLmJ5dGVzWzotMV0KICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIGJveF9leHRyYWN0CiAgICBpbnQgMQogICAgZGlnIDIKICAgID49CiAgICBpbnQgMQogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICBkaWcgMgogICAgc3dhcAogICAgLQogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjM5CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1s6Ml0gPT0gYy5ieXRlc1s6Ml0KICAgIGJveF9sZW4KICAgIHBvcAogICAgaW50IDIKICAgIGRpZyAxCiAgICA8CiAgICBpbnQgMgogICAgc3dhcAogICAgc2VsZWN0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjM5CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1s6Ml0gPT0gYy5ieXRlc1s6Ml0KICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIGJveF9leHRyYWN0CiAgICBpbnQgMgogICAgZGlnIDIKICAgID49CiAgICBpbnQgMgogICAgdW5jb3ZlciAzCiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMwogICAgLy8gc2VsZi5ib3hfZCA9IEJveChCeXRlcykKICAgIGJ5dGUgImJveF9kIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDEtNDIKICAgIC8vICMgdGVzdCAudmFsdWUgd2l0aCBCeXRlcyB0eXBlCiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfZC52YWx1ZVswXSA9PSBiLm5hdGl2ZVswXQogICAgaW50IDAKICAgIGludCAxCiAgICBib3hfZXh0cmFjdAogICAgZGlnIDEKICAgIGV4dHJhY3QgMCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMwogICAgLy8gc2VsZi5ib3hfZCA9IEJveChCeXRlcykKICAgIGJ5dGUgImJveF9kIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDMKICAgIC8vIGFzc2VydCBzZWxmLmJveF9kLnZhbHVlWy0xXSA9PSBiLm5hdGl2ZVstMV0KICAgIGJveF9sZW4KICAgIHBvcAogICAgaW50IDEKICAgIC0KICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzCiAgICAvLyBzZWxmLmJveF9kID0gQm94KEJ5dGVzKQogICAgYnl0ZSAiYm94X2QiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0MwogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbLTFdID09IGIubmF0aXZlWy0xXQogICAgc3dhcAogICAgaW50IDEKICAgIGJveF9leHRyYWN0CiAgICBkaWcgMgogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgaW50IDEKICAgICsKICAgIGRpZyAzCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMwogICAgLy8gc2VsZi5ib3hfZCA9IEJveChCeXRlcykKICAgIGJ5dGUgImJveF9kIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDQKICAgIC8vIGFzc2VydCBzZWxmLmJveF9kLnZhbHVlWzotMV0gPT0gYi5uYXRpdmVbOi0xXQogICAgYm94X2xlbgogICAgcG9wCiAgICBpbnQgMQogICAgZGlnIDEKICAgIDwKICAgIHN3YXAKICAgIGR1cAogICAgaW50IDEKICAgIHVuY292ZXIgMwogICAgc2VsZWN0CiAgICAtCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMwogICAgLy8gc2VsZi5ib3hfZCA9IEJveChCeXRlcykKICAgIGJ5dGUgImJveF9kIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDQKICAgIC8vIGFzc2VydCBzZWxmLmJveF9kLnZhbHVlWzotMV0gPT0gYi5uYXRpdmVbOi0xXQogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgYm94X2V4dHJhY3QKICAgIGludCAxCiAgICBkaWcgMwogICAgPj0KICAgIGludCAxCiAgICBkaWcgNAogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIGRpZyAzCiAgICBzd2FwCiAgICAtCiAgICBkaWcgMgogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTMKICAgIC8vIHNlbGYuYm94X2QgPSBCb3goQnl0ZXMpCiAgICBieXRlICJib3hfZCIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ1CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfZC52YWx1ZVs6NV0gPT0gYi5uYXRpdmVbOjVdCiAgICBib3hfbGVuCiAgICBwb3AKICAgIGludCA1CiAgICBkaWcgMQogICAgPAogICAgaW50IDUKICAgIHN3YXAKICAgIHNlbGVjdAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTMKICAgIC8vIHNlbGYuYm94X2QgPSBCb3goQnl0ZXMpCiAgICBieXRlICJib3hfZCIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ1CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfZC52YWx1ZVs6NV0gPT0gYi5uYXRpdmVbOjVdCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBib3hfZXh0cmFjdAogICAgaW50IDUKICAgIGRpZyAzCiAgICA+PQogICAgaW50IDUKICAgIGRpZyA0CiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgZGlnIDIKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzCiAgICAvLyBzZWxmLmJveF9kID0gQm94KEJ5dGVzKQogICAgYnl0ZSAiYm94X2QiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0NgogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbOiBVSW50NjQoMildID09IGIubmF0aXZlWzogVUludDY0KDIpXQogICAgYm94X2xlbgogICAgcG9wCiAgICBpbnQgMgogICAgZGlnIDEKICAgIDwKICAgIGludCAyCiAgICBzd2FwCiAgICBzZWxlY3QKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzCiAgICAvLyBzZWxmLmJveF9kID0gQm94KEJ5dGVzKQogICAgYnl0ZSAiYm94X2QiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0NgogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbOiBVSW50NjQoMildID09IGIubmF0aXZlWzogVUludDY0KDIpXQogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgYm94X2V4dHJhY3QKICAgIGludCAyCiAgICBkaWcgMwogICAgPj0KICAgIGludCAyCiAgICB1bmNvdmVyIDQKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICB1bmNvdmVyIDIKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmRlbGV0ZV9ib3hlcygpIC0+IHZvaWQ6CmRlbGV0ZV9ib3hlczoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU0LTU1CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBkZWxldGVfYm94ZXMoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0KQogICAgYnl0ZSAiYm94X2EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1NgogICAgLy8gZGVsIHNlbGYuYm94X2EudmFsdWUKICAgIGJveF9kZWwKICAgIHBvcAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTEKICAgIC8vIHNlbGYuYm94X2IgPSBCb3hbYXJjNC5EeW5hbWljQnl0ZXNdKGFyYzQuRHluYW1pY0J5dGVzLCBrZXk9ImIiKQogICAgYnl0ZSAiYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU3CiAgICAvLyBkZWwgc2VsZi5ib3hfYi52YWx1ZQogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU4CiAgICAvLyBkZWwgc2VsZi5ib3hfYy52YWx1ZQogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMAogICAgLy8gc2VsZi5ib3hfYSA9IEJveChVSW50NjQpCiAgICBieXRlICJib3hfYSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYS5nZXQoZGVmYXVsdD1VSW50NjQoNDIpKSA9PSA0MgogICAgYm94X2dldAogICAgc3dhcAogICAgYnRvaQogICAgaW50IDQyCiAgICBzd2FwCiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgaW50IDQyCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMQogICAgLy8gc2VsZi5ib3hfYiA9IEJveFthcmM0LkR5bmFtaWNCeXRlc10oYXJjNC5EeW5hbWljQnl0ZXMsIGtleT0iYiIpCiAgICBieXRlICJiIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjAKICAgIC8vIGFzc2VydCBzZWxmLmJveF9iLmdldChkZWZhdWx0PWFyYzQuRHluYW1pY0J5dGVzKGIiNDIiKSkubmF0aXZlID09IGIiNDIiCiAgICBib3hfZ2V0CiAgICBieXRlIDB4MDAwMjM0MzIKICAgIGNvdmVyIDIKICAgIHNlbGVjdAogICAgZXh0cmFjdCAyIDAKICAgIGJ5dGUgMHgzNDMyCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjYxCiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYy5nZXQoZGVmYXVsdD1hcmM0LlN0cmluZygiNDIiKSkgPT0gIjQyIgogICAgYm94X2dldAogICAgYnl0ZSAweDAwMDIzNDMyCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGJ5dGUgMHgwMDAyMzQzMgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0KQogICAgYnl0ZSAiYm94X2EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo2MgogICAgLy8gYSwgYV9leGlzdHMgPSBzZWxmLmJveF9hLm1heWJlKCkKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjYzCiAgICAvLyBhc3NlcnQgbm90IGFfZXhpc3RzCiAgICAhCiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY0CiAgICAvLyBhc3NlcnQgYSA9PSAwCiAgICAhCiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LnJlYWRfYm94ZXMoKSAtPiB1aW50NjQsIGJ5dGVzLCBieXRlczoKcmVhZF9ib3hlczoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY2LTY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiByZWFkX2JveGVzKHNlbGYpIC0+IHR1cGxlW1VJbnQ2NCwgQnl0ZXMsIGFyYzQuU3RyaW5nXToKICAgIHByb3RvIDAgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAKICAgIC8vIHNlbGYuYm94X2EgPSBCb3goVUludDY0KQogICAgYnl0ZSAiYm94X2EiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo2OAogICAgLy8gcmV0dXJuIGdldF9ib3hfdmFsdWVfcGx1c18xKHNlbGYuYm94X2EpIC0gMSwgc2VsZi5ib3hfYi52YWx1ZS5uYXRpdmUsIHNlbGYuYm94X2MudmFsdWUKICAgIGNhbGxzdWIgZ2V0X2JveF92YWx1ZV9wbHVzXzEKICAgIGludCAxCiAgICAtCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMQogICAgLy8gc2VsZi5ib3hfYiA9IEJveFthcmM0LkR5bmFtaWNCeXRlc10oYXJjNC5EeW5hbWljQnl0ZXMsIGtleT0iYiIpCiAgICBieXRlICJiIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjgKICAgIC8vIHJldHVybiBnZXRfYm94X3ZhbHVlX3BsdXNfMShzZWxmLmJveF9hKSAtIDEsIHNlbGYuYm94X2IudmFsdWUubmF0aXZlLCBzZWxmLmJveF9jLnZhbHVlCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ib3hfYiBleGlzdHMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY4CiAgICAvLyByZXR1cm4gZ2V0X2JveF92YWx1ZV9wbHVzXzEoc2VsZi5ib3hfYSkgLSAxLCBzZWxmLmJveF9iLnZhbHVlLm5hdGl2ZSwgc2VsZi5ib3hfYy52YWx1ZQogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X2MgZXhpc3RzCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5nZXRfYm94X3ZhbHVlX3BsdXNfMShib3g6IGJ5dGVzKSAtPiB1aW50NjQ6CmdldF9ib3hfdmFsdWVfcGx1c18xOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTc5LTE4MAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBnZXRfYm94X3ZhbHVlX3BsdXNfMShib3g6IEJveFtVSW50NjRdKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE4MQogICAgLy8gcmV0dXJuIGJveC52YWx1ZSArIDEKICAgIGZyYW1lX2RpZyAtMQogICAgYm94X2dldAogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYXNzZXJ0IC8vIGNoZWNrIEJveCBleGlzdHMKICAgIGludCAxCiAgICArCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hlc19leGlzdCgpIC0+IHVpbnQ2NCwgdWludDY0LCB1aW50NjQ6CmJveGVzX2V4aXN0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzAtNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveGVzX2V4aXN0KHNlbGYpIC0+IHR1cGxlW2Jvb2wsIGJvb2wsIGJvb2xdOgogICAgcHJvdG8gMCAzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMAogICAgLy8gc2VsZi5ib3hfYSA9IEJveChVSW50NjQpCiAgICBieXRlICJib3hfYSIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjcyCiAgICAvLyByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMQogICAgLy8gc2VsZi5ib3hfYiA9IEJveFthcmM0LkR5bmFtaWNCeXRlc10oYXJjNC5EeW5hbWljQnl0ZXMsIGtleT0iYiIpCiAgICBieXRlICJiIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzIKICAgIC8vIHJldHVybiBib29sKHNlbGYuYm94X2EpLCBib29sKHNlbGYuYm94X2IpLCBib29sKHNlbGYuYm94X2MpCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzIKICAgIC8vIHJldHVybiBib29sKHNlbGYuYm94X2EpLCBib29sKHNlbGYuYm94X2IpLCBib29sKHNlbGYuYm94X2MpCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LnNsaWNlX2JveCgpIC0+IHZvaWQ6CnNsaWNlX2JveDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojc0LTc1CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzbGljZV9ib3goc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzYKICAgIC8vIGJveF8wID0gQm94KEJ5dGVzLCBrZXk9U3RyaW5nKCIwIikpCiAgICBieXRlICIwIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzcKICAgIC8vIGJveF8wLnZhbHVlID0gQnl0ZXMoYiJUZXN0aW5nIHRlc3RpbmcgMTIzIikKICAgIGJveF9kZWwKICAgIHBvcAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzYKICAgIC8vIGJveF8wID0gQm94KEJ5dGVzLCBrZXk9U3RyaW5nKCIwIikpCiAgICBieXRlICIwIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzcKICAgIC8vIGJveF8wLnZhbHVlID0gQnl0ZXMoYiJUZXN0aW5nIHRlc3RpbmcgMTIzIikKICAgIGJ5dGUgMHg1NDY1NzM3NDY5NmU2NzIwNzQ2NTczNzQ2OTZlNjcyMDMxMzIzMwogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzYKICAgIC8vIGJveF8wID0gQm94KEJ5dGVzLCBrZXk9U3RyaW5nKCIwIikpCiAgICBieXRlICIwIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzgKICAgIC8vIGFzc2VydCBib3hfMC52YWx1ZVswOjddID09IGIiVGVzdGluZyIKICAgIGJveF9sZW4KICAgIHBvcAogICAgZHVwCiAgICBpbnQgMAogICAgZGlnIDIKICAgIHNlbGVjdAogICAgc3dhcAogICAgaW50IDcKICAgIGRpZyAxCiAgICA8CiAgICBpbnQgNwogICAgc3dhcAogICAgc2VsZWN0CiAgICBkaWcgMQogICAgLQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzYKICAgIC8vIGJveF8wID0gQm94KEJ5dGVzLCBrZXk9U3RyaW5nKCIwIikpCiAgICBieXRlICIwIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzgKICAgIC8vIGFzc2VydCBib3hfMC52YWx1ZVswOjddID09IGIiVGVzdGluZyIKICAgIGNvdmVyIDIKICAgIGJveF9leHRyYWN0CiAgICBieXRlIDB4NTQ2NTczNzQ2OTZlNjcKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyCiAgICAvLyBzZWxmLmJveF9jID0gQm94KGFyYzQuU3RyaW5nLCBrZXk9YiJCT1hfQyIpCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODAKICAgIC8vIHNlbGYuYm94X2MudmFsdWUgPSBhcmM0LlN0cmluZygiSGVsbG8iKQogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgwCiAgICAvLyBzZWxmLmJveF9jLnZhbHVlID0gYXJjNC5TdHJpbmcoIkhlbGxvIikKICAgIGJ5dGUgMHgwMDA1NDg2NTZjNmM2ZgogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYuYm94X2MgPSBCb3goYXJjNC5TdHJpbmcsIGtleT1iIkJPWF9DIikKICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4MQogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbMjoxMF0gPT0gYiJIZWxsbyIKICAgIGJveF9sZW4KICAgIHBvcAogICAgaW50IDIKICAgIGRpZyAxCiAgICA8CiAgICBzd2FwCiAgICBkdXAKICAgIGludCAyCiAgICB1bmNvdmVyIDMKICAgIHNlbGVjdAogICAgc3dhcAogICAgaW50IDEwCiAgICBkaWcgMQogICAgPAogICAgaW50IDEwCiAgICBzd2FwCiAgICBzZWxlY3QKICAgIGRpZyAxCiAgICAtCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMgogICAgLy8gc2VsZi5ib3hfYyA9IEJveChhcmM0LlN0cmluZywga2V5PWIiQk9YX0MiKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgxCiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1syOjEwXSA9PSBiIkhlbGxvIgogICAgY292ZXIgMgogICAgYm94X2V4dHJhY3QKICAgIGJ5dGUgMHg0ODY1NmM2YzZmCiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5hcmM0X2JveCgpIC0+IHZvaWQ6CmFyYzRfYm94OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODMtODQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGFyYzRfYm94KHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojg1CiAgICAvLyBib3hfZCA9IEJveChTdGF0aWNJbnRzLCBrZXk9Qnl0ZXMoYiJkIikpCiAgICBieXRlIDB4NjQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojg2CiAgICAvLyBib3hfZC52YWx1ZSA9IFN0YXRpY0ludHMoYXJjNC5VSW50OCgwKSwgYXJjNC5VSW50OCgxKSwgYXJjNC5VSW50OCgyKSwgYXJjNC5VSW50OCgzKSkKICAgIGJ5dGUgMHgwMDAxMDIwMwogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODUKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1CeXRlcyhiImQiKSkKICAgIGJ5dGUgMHg2NAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODgKICAgIC8vIGFzc2VydCBib3hfZC52YWx1ZVswXSA9PSAwCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgQm94IGV4aXN0cwogICAgZXh0cmFjdCAwIDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBieXRlIDB4MDAKICAgIGI9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4NQogICAgLy8gYm94X2QgPSBCb3goU3RhdGljSW50cywga2V5PUJ5dGVzKGIiZCIpKQogICAgYnl0ZSAweDY0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4OQogICAgLy8gYXNzZXJ0IGJveF9kLnZhbHVlWzFdID09IDEKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBCb3ggZXhpc3RzCiAgICBleHRyYWN0IDEgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwMQogICAgYj09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojg1CiAgICAvLyBib3hfZCA9IEJveChTdGF0aWNJbnRzLCBrZXk9Qnl0ZXMoYiJkIikpCiAgICBieXRlIDB4NjQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjkwCiAgICAvLyBhc3NlcnQgYm94X2QudmFsdWVbMl0gPT0gMgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIEJveCBleGlzdHMKICAgIGV4dHJhY3QgMiAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnl0ZSAweDAyCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODUKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1CeXRlcyhiImQiKSkKICAgIGJ5dGUgMHg2NAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OTEKICAgIC8vIGFzc2VydCBib3hfZC52YWx1ZVszXSA9PSAzCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgQm94IGV4aXN0cwogICAgZXh0cmFjdCAzIDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBieXRlIDB4MDMKICAgIGI9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC50ZXN0X2JveF9yZWYoKSAtPiB2b2lkOgp0ZXN0X2JveF9yZWY6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo5My05NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgdGVzdF9ib3hfcmVmKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojk1LTk2CiAgICAvLyAjIGluaXQgcmVmLCB3aXRoIHZhbGlkIGtleSB0eXBlcwogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9ImJsb2IiKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojk3CiAgICAvLyBhc3NlcnQgbm90IGJveF9yZWYsICJubyBkYXRhIgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICAhCiAgICBhc3NlcnQgLy8gbm8gZGF0YQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OTgKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PWIiYmxvYiIpCiAgICBieXRlIDB4NjI2YzZmNjIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojk5CiAgICAvLyBhc3NlcnQgbm90IGJveF9yZWYsICJubyBkYXRhIgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICAhCiAgICBhc3NlcnQgLy8gbm8gZGF0YQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAwCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT1CeXRlcyhiImJsb2IiKSkKICAgIGJ5dGUgMHg2MjZjNmY2MgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAxCiAgICAvLyBhc3NlcnQgbm90IGJveF9yZWYsICJubyBkYXRhIgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICAhCiAgICBhc3NlcnQgLy8gbm8gZGF0YQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAyCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT1TdHJpbmcoImJsb2IiKSkKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDMKICAgIC8vIGFzc2VydCBub3QgYm94X3JlZiwgIm5vIGRhdGEiCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgICEKICAgIGFzc2VydCAvLyBubyBkYXRhCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwNS0xMDYKICAgIC8vICMgY3JlYXRlCiAgICAvLyBhc3NlcnQgYm94X3JlZi5jcmVhdGUoc2l6ZT0zMikKICAgIGludCAzMgogICAgYm94X2NyZWF0ZQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwNwogICAgLy8gYXNzZXJ0IGJveF9yZWYsICJoYXMgZGF0YSIKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgYXNzZXJ0IC8vIGhhcyBkYXRhCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMTEKICAgIC8vIGFwcF9hZGRyZXNzID0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcy5ieXRlcwogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwOS0xMTAKICAgIC8vICMgbWFuaXB1bGF0ZSBkYXRhCiAgICAvLyBzZW5kZXJfYnl0ZXMgPSBUeG4uc2VuZGVyLmJ5dGVzCiAgICB0eG4gU2VuZGVyCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExMwogICAgLy8gYm94X3JlZi5yZXBsYWNlKDAsIHNlbmRlcl9ieXRlcykKICAgIGludCAwCiAgICBkaWcgMgogICAgYm94X3JlcGxhY2UKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTE0CiAgICAvLyBib3hfcmVmLnJlc2l6ZSg4MDAwKQogICAgaW50IDgwMDAKICAgIGJveF9yZXNpemUKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTE1CiAgICAvLyBib3hfcmVmLnNwbGljZSgwLCAwLCBhcHBfYWRkcmVzcykKICAgIGludCAwCiAgICBkdXAKICAgIGRpZyA0CiAgICBib3hfc3BsaWNlCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExNgogICAgLy8gYm94X3JlZi5yZXBsYWNlKDY0LCB2YWx1ZV8zKQogICAgaW50IDY0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMTIKICAgIC8vIHZhbHVlXzMgPSBCeXRlcyhiImhlbGxvIikKICAgIGJ5dGUgMHg2ODY1NmM2YzZmCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMTYKICAgIC8vIGJveF9yZWYucmVwbGFjZSg2NCwgdmFsdWVfMykKICAgIGJveF9yZXBsYWNlCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExNwogICAgLy8gcHJlZml4ID0gYm94X3JlZi5leHRyYWN0KDAsIDMyICogMiArIHZhbHVlXzMubGVuZ3RoKQogICAgaW50IDAKICAgIGludCA2OQogICAgYm94X2V4dHJhY3QKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExOAogICAgLy8gYXNzZXJ0IHByZWZpeCA9PSBhcHBfYWRkcmVzcyArIHNlbmRlcl9ieXRlcyArIHZhbHVlXzMKICAgIGRpZyAyCiAgICBkaWcgMgogICAgY29uY2F0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMTIKICAgIC8vIHZhbHVlXzMgPSBCeXRlcyhiImhlbGxvIikKICAgIGJ5dGUgMHg2ODY1NmM2YzZmCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMTgKICAgIC8vIGFzc2VydCBwcmVmaXggPT0gYXBwX2FkZHJlc3MgKyBzZW5kZXJfYnl0ZXMgKyB2YWx1ZV8zCiAgICBjb25jYXQKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTIwLTEyMQogICAgLy8gIyBkZWxldGUKICAgIC8vIGFzc2VydCBib3hfcmVmLmRlbGV0ZSgpCiAgICBib3hfZGVsCiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTI0LTEyNQogICAgLy8gIyBxdWVyeQogICAgLy8gdmFsdWUsIGV4aXN0cyA9IGJveF9yZWYubWF5YmUoKQogICAgYm94X2dldAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTI2CiAgICAvLyBhc3NlcnQgbm90IGV4aXN0cwogICAgIQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMjcKICAgIC8vIGFzc2VydCB2YWx1ZSA9PSBiIiIKICAgIGJ5dGUgMHgKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTI4CiAgICAvLyBhc3NlcnQgYm94X3JlZi5nZXQoZGVmYXVsdD1zZW5kZXJfYnl0ZXMpID09IHNlbmRlcl9ieXRlcwogICAgYm94X2dldAogICAgZGlnIDIKICAgIGNvdmVyIDIKICAgIHNlbGVjdAogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzMC0xMzEKICAgIC8vICMgdXBkYXRlCiAgICAvLyBib3hfcmVmLnB1dChzZW5kZXJfYnl0ZXMgKyBhcHBfYWRkcmVzcykKICAgIHN3YXAKICAgIGNvbmNhdAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAyCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT1TdHJpbmcoImJsb2IiKSkKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMzAtMTMxCiAgICAvLyAjIHVwZGF0ZQogICAgLy8gYm94X3JlZi5wdXQoc2VuZGVyX2J5dGVzICsgYXBwX2FkZHJlc3MpCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzMgogICAgLy8gYXNzZXJ0IGJveF9yZWYsICJCbG9iIGV4aXN0cyIKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgYXNzZXJ0IC8vIEJsb2IgZXhpc3RzCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzMwogICAgLy8gYXNzZXJ0IGJveF9yZWYubGVuZ3RoID09IDY0CiAgICBib3hfbGVuCiAgICBhc3NlcnQgLy8gY2hlY2sgQm94UmVmIGV4aXN0cwogICAgaW50IDY0CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzNAogICAgLy8gYXNzZXJ0IGdldF9ib3hfcmVmX2xlbmd0aChib3hfcmVmKSA9PSA2NAogICAgY2FsbHN1YiBnZXRfYm94X3JlZl9sZW5ndGgKICAgIGludCA2NAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTUKICAgIC8vIHNlbGYuYm94X3JlZiA9IEJveFJlZigpCiAgICBieXRlICJib3hfcmVmIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTM2LTEzNwogICAgLy8gIyBpbnN0YW5jZSBib3ggcmVmCiAgICAvLyBzZWxmLmJveF9yZWYuY3JlYXRlKHNpemU9VUludDY0KDMyKSkKICAgIGludCAzMgogICAgYm94X2NyZWF0ZQogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNQogICAgLy8gc2VsZi5ib3hfcmVmID0gQm94UmVmKCkKICAgIGJ5dGUgImJveF9yZWYiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMzgKICAgIC8vIGFzc2VydCBzZWxmLmJveF9yZWYsICJoYXMgZGF0YSIKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgYXNzZXJ0IC8vIGhhcyBkYXRhCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNQogICAgLy8gc2VsZi5ib3hfcmVmID0gQm94UmVmKCkKICAgIGJ5dGUgImJveF9yZWYiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMzkKICAgIC8vIHNlbGYuYm94X3JlZi5kZWxldGUoKQogICAgYm94X2RlbAogICAgcG9wCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5nZXRfYm94X3JlZl9sZW5ndGgocmVmOiBieXRlcykgLT4gdWludDY0OgpnZXRfYm94X3JlZl9sZW5ndGg6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxODQtMTg1CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGdldF9ib3hfcmVmX2xlbmd0aChyZWY6IEJveFJlZikgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxODYKICAgIC8vIHJldHVybiByZWYubGVuZ3RoCiAgICBmcmFtZV9kaWcgLTEKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBjaGVjayBCb3hSZWYgZXhpc3RzCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX3Rlc3QoKSAtPiB2b2lkOgpib3hfbWFwX3Rlc3Q6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNDEtMTQyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX3Rlc3Qoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTQzCiAgICAvLyBrZXlfMCA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0NgogICAgLy8gc2VsZi5ib3hfbWFwW2tleV8wXSA9IHZhbHVlCiAgICBpdG9iCiAgICBkdXAKICAgIGJveF9kZWwKICAgIHBvcAogICAgZHVwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNDUKICAgIC8vIHZhbHVlID0gU3RyaW5nKCJIbW1tbW0iKQogICAgYnl0ZSAiSG1tbW1tIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTQ2CiAgICAvLyBzZWxmLmJveF9tYXBba2V5XzBdID0gdmFsdWUKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0NwogICAgLy8gYXNzZXJ0IHNlbGYuYm94X21hcFtrZXlfMF0uYnl0ZXMubGVuZ3RoID09IHZhbHVlLmJ5dGVzLmxlbmd0aAogICAgZHVwCiAgICBib3hfbGVuCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ib3hfbWFwIGVudHJ5IGV4aXN0cwogICAgaW50IDYKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0OAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X21hcC5sZW5ndGgoa2V5XzApID09IHZhbHVlLmJ5dGVzLmxlbmd0aAogICAgZHVwCiAgICBib3hfbGVuCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ib3hfbWFwIGVudHJ5IGV4aXN0cwogICAgaW50IDYKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0NAogICAgLy8ga2V5XzEgPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNTAKICAgIC8vIGFzc2VydCBzZWxmLmJveF9tYXAuZ2V0KGtleV8xLCBkZWZhdWx0PVN0cmluZygiZGVmYXVsdCIpKSA9PSBTdHJpbmcoImRlZmF1bHQiKQogICAgaXRvYgogICAgZHVwCiAgICBib3hfZ2V0CiAgICBieXRlICJkZWZhdWx0IgogICAgY292ZXIgMgogICAgc2VsZWN0CiAgICBieXRlICJkZWZhdWx0IgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTUxCiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gc2VsZi5ib3hfbWFwLm1heWJlKGtleV8xKQogICAgZHVwCiAgICBib3hfZ2V0CiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE1MgogICAgLy8gYXNzZXJ0IG5vdCBleGlzdHMKICAgICEKICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTQtMTUzCiAgICAvLyAgICAgc2VsZi5ib3hfbWFwID0gQm94TWFwKFVJbnQ2NCwgU3RyaW5nLCBrZXlfcHJlZml4PSIiKQogICAgLy8gICAgIHNlbGYuYm94X3JlZiA9IEJveFJlZigpCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHNldF9ib3hlcyhzZWxmLCBhOiBVSW50NjQsIGI6IGFyYzQuRHluYW1pY0J5dGVzLCBjOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIC8vICAgICBzZWxmLmJveF9hLnZhbHVlID0gYQogICAgLy8gICAgIHNlbGYuYm94X2IudmFsdWUgPSBiLmNvcHkoKQogICAgLy8gICAgIHNlbGYuYm94X2MudmFsdWUgPSBjCiAgICAvLyAgICAgc2VsZi5ib3hfZC52YWx1ZSA9IGIubmF0aXZlCiAgICAvLyAKICAgIC8vICAgICBiX3ZhbHVlID0gc2VsZi5ib3hfYi52YWx1ZS5jb3B5KCkKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYi52YWx1ZS5sZW5ndGggPT0gYl92YWx1ZS5sZW5ndGgsICJkaXJlY3QgcmVmZXJlbmNlIHNob3VsZCBtYXRjaCBjb3B5IgogICAgLy8gCiAgICAvLyAgICAgc2VsZi5ib3hfYS52YWx1ZSArPSAzCiAgICAvLyAKICAgIC8vICAgICAjIHRlc3QgLmxlbmd0aAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9hLmxlbmd0aCA9PSA4CiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2IubGVuZ3RoID09IGIuYnl0ZXMubGVuZ3RoCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2MubGVuZ3RoID09IGMuYnl0ZXMubGVuZ3RoCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2QubGVuZ3RoID09IGIubmF0aXZlLmxlbmd0aAogICAgLy8gCiAgICAvLyAgICAgIyB0ZXN0IC52YWx1ZS5ieXRlcwogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWzBdID09IGMuYnl0ZXNbMF0KICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1stMV0gPT0gYy5ieXRlc1stMV0KICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1s6LTFdID09IGMuYnl0ZXNbOi0xXQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWzoyXSA9PSBjLmJ5dGVzWzoyXQogICAgLy8gCiAgICAvLyAgICAgIyB0ZXN0IC52YWx1ZSB3aXRoIEJ5dGVzIHR5cGUKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfZC52YWx1ZVswXSA9PSBiLm5hdGl2ZVswXQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9kLnZhbHVlWy0xXSA9PSBiLm5hdGl2ZVstMV0KICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfZC52YWx1ZVs6LTFdID09IGIubmF0aXZlWzotMV0KICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfZC52YWx1ZVs6NV0gPT0gYi5uYXRpdmVbOjVdCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbOiBVSW50NjQoMildID09IGIubmF0aXZlWzogVUludDY0KDIpXQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBjaGVja19rZXlzKHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2Eua2V5ID09IGIiYm94X2EiLCAiYm94IGEga2V5IG9rIgogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9iLmtleSA9PSBiImIiLCAiYm94IGIga2V5IG9rIgogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9jLmtleSA9PSBiIkJPWF9DIiwgImJveCBjIGtleSBvayIKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgZGVsZXRlX2JveGVzKHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAgZGVsIHNlbGYuYm94X2EudmFsdWUKICAgIC8vICAgICBkZWwgc2VsZi5ib3hfYi52YWx1ZQogICAgLy8gICAgIGRlbCBzZWxmLmJveF9jLnZhbHVlCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2EuZ2V0KGRlZmF1bHQ9VUludDY0KDQyKSkgPT0gNDIKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYi5nZXQoZGVmYXVsdD1hcmM0LkR5bmFtaWNCeXRlcyhiIjQyIikpLm5hdGl2ZSA9PSBiIjQyIgogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9jLmdldChkZWZhdWx0PWFyYzQuU3RyaW5nKCI0MiIpKSA9PSAiNDIiCiAgICAvLyAgICAgYSwgYV9leGlzdHMgPSBzZWxmLmJveF9hLm1heWJlKCkKICAgIC8vICAgICBhc3NlcnQgbm90IGFfZXhpc3RzCiAgICAvLyAgICAgYXNzZXJ0IGEgPT0gMAogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiByZWFkX2JveGVzKHNlbGYpIC0+IHR1cGxlW1VJbnQ2NCwgQnl0ZXMsIGFyYzQuU3RyaW5nXToKICAgIC8vICAgICByZXR1cm4gZ2V0X2JveF92YWx1ZV9wbHVzXzEoc2VsZi5ib3hfYSkgLSAxLCBzZWxmLmJveF9iLnZhbHVlLm5hdGl2ZSwgc2VsZi5ib3hfYy52YWx1ZQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hlc19leGlzdChzZWxmKSAtPiB0dXBsZVtib29sLCBib29sLCBib29sXToKICAgIC8vICAgICByZXR1cm4gYm9vbChzZWxmLmJveF9hKSwgYm9vbChzZWxmLmJveF9iKSwgYm9vbChzZWxmLmJveF9jKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzbGljZV9ib3goc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBib3hfMCA9IEJveChCeXRlcywga2V5PVN0cmluZygiMCIpKQogICAgLy8gICAgIGJveF8wLnZhbHVlID0gQnl0ZXMoYiJUZXN0aW5nIHRlc3RpbmcgMTIzIikKICAgIC8vICAgICBhc3NlcnQgYm94XzAudmFsdWVbMDo3XSA9PSBiIlRlc3RpbmciCiAgICAvLyAKICAgIC8vICAgICBzZWxmLmJveF9jLnZhbHVlID0gYXJjNC5TdHJpbmcoIkhlbGxvIikKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1syOjEwXSA9PSBiIkhlbGxvIgogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBhcmM0X2JveChzZWxmKSAtPiBOb25lOgogICAgLy8gICAgIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1CeXRlcyhiImQiKSkKICAgIC8vICAgICBib3hfZC52YWx1ZSA9IFN0YXRpY0ludHMoYXJjNC5VSW50OCgwKSwgYXJjNC5VSW50OCgxKSwgYXJjNC5VSW50OCgyKSwgYXJjNC5VSW50OCgzKSkKICAgIC8vIAogICAgLy8gICAgIGFzc2VydCBib3hfZC52YWx1ZVswXSA9PSAwCiAgICAvLyAgICAgYXNzZXJ0IGJveF9kLnZhbHVlWzFdID09IDEKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbMl0gPT0gMgogICAgLy8gICAgIGFzc2VydCBib3hfZC52YWx1ZVszXSA9PSAzCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHRlc3RfYm94X3JlZihzZWxmKSAtPiBOb25lOgogICAgLy8gICAgICMgaW5pdCByZWYsIHdpdGggdmFsaWQga2V5IHR5cGVzCiAgICAvLyAgICAgYm94X3JlZiA9IEJveFJlZihrZXk9ImJsb2IiKQogICAgLy8gICAgIGFzc2VydCBub3QgYm94X3JlZiwgIm5vIGRhdGEiCiAgICAvLyAgICAgYm94X3JlZiA9IEJveFJlZihrZXk9YiJibG9iIikKICAgIC8vICAgICBhc3NlcnQgbm90IGJveF9yZWYsICJubyBkYXRhIgogICAgLy8gICAgIGJveF9yZWYgPSBCb3hSZWYoa2V5PUJ5dGVzKGIiYmxvYiIpKQogICAgLy8gICAgIGFzc2VydCBub3QgYm94X3JlZiwgIm5vIGRhdGEiCiAgICAvLyAgICAgYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBib3hfcmVmLCAibm8gZGF0YSIKICAgIC8vIAogICAgLy8gICAgICMgY3JlYXRlCiAgICAvLyAgICAgYXNzZXJ0IGJveF9yZWYuY3JlYXRlKHNpemU9MzIpCiAgICAvLyAgICAgYXNzZXJ0IGJveF9yZWYsICJoYXMgZGF0YSIKICAgIC8vIAogICAgLy8gICAgICMgbWFuaXB1bGF0ZSBkYXRhCiAgICAvLyAgICAgc2VuZGVyX2J5dGVzID0gVHhuLnNlbmRlci5ieXRlcwogICAgLy8gICAgIGFwcF9hZGRyZXNzID0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcy5ieXRlcwogICAgLy8gICAgIHZhbHVlXzMgPSBCeXRlcyhiImhlbGxvIikKICAgIC8vICAgICBib3hfcmVmLnJlcGxhY2UoMCwgc2VuZGVyX2J5dGVzKQogICAgLy8gICAgIGJveF9yZWYucmVzaXplKDgwMDApCiAgICAvLyAgICAgYm94X3JlZi5zcGxpY2UoMCwgMCwgYXBwX2FkZHJlc3MpCiAgICAvLyAgICAgYm94X3JlZi5yZXBsYWNlKDY0LCB2YWx1ZV8zKQogICAgLy8gICAgIHByZWZpeCA9IGJveF9yZWYuZXh0cmFjdCgwLCAzMiAqIDIgKyB2YWx1ZV8zLmxlbmd0aCkKICAgIC8vICAgICBhc3NlcnQgcHJlZml4ID09IGFwcF9hZGRyZXNzICsgc2VuZGVyX2J5dGVzICsgdmFsdWVfMwogICAgLy8gCiAgICAvLyAgICAgIyBkZWxldGUKICAgIC8vICAgICBhc3NlcnQgYm94X3JlZi5kZWxldGUoKQogICAgLy8gICAgIGFzc2VydCBib3hfcmVmLmtleSA9PSBiImJsb2IiCiAgICAvLyAKICAgIC8vICAgICAjIHF1ZXJ5CiAgICAvLyAgICAgdmFsdWUsIGV4aXN0cyA9IGJveF9yZWYubWF5YmUoKQogICAgLy8gICAgIGFzc2VydCBub3QgZXhpc3RzCiAgICAvLyAgICAgYXNzZXJ0IHZhbHVlID09IGIiIgogICAgLy8gICAgIGFzc2VydCBib3hfcmVmLmdldChkZWZhdWx0PXNlbmRlcl9ieXRlcykgPT0gc2VuZGVyX2J5dGVzCiAgICAvLyAKICAgIC8vICAgICAjIHVwZGF0ZQogICAgLy8gICAgIGJveF9yZWYucHV0KHNlbmRlcl9ieXRlcyArIGFwcF9hZGRyZXNzKQogICAgLy8gICAgIGFzc2VydCBib3hfcmVmLCAiQmxvYiBleGlzdHMiCiAgICAvLyAgICAgYXNzZXJ0IGJveF9yZWYubGVuZ3RoID09IDY0CiAgICAvLyAgICAgYXNzZXJ0IGdldF9ib3hfcmVmX2xlbmd0aChib3hfcmVmKSA9PSA2NAogICAgLy8gCiAgICAvLyAgICAgIyBpbnN0YW5jZSBib3ggcmVmCiAgICAvLyAgICAgc2VsZi5ib3hfcmVmLmNyZWF0ZShzaXplPVVJbnQ2NCgzMikpCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X3JlZiwgImhhcyBkYXRhIgogICAgLy8gICAgIHNlbGYuYm94X3JlZi5kZWxldGUoKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hfbWFwX3Rlc3Qoc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBrZXlfMCA9IFVJbnQ2NCgwKQogICAgLy8gICAgIGtleV8xID0gVUludDY0KDEpCiAgICAvLyAgICAgdmFsdWUgPSBTdHJpbmcoIkhtbW1tbSIpCiAgICAvLyAgICAgc2VsZi5ib3hfbWFwW2tleV8wXSA9IHZhbHVlCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X21hcFtrZXlfMF0uYnl0ZXMubGVuZ3RoID09IHZhbHVlLmJ5dGVzLmxlbmd0aAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAubGVuZ3RoKGtleV8wKSA9PSB2YWx1ZS5ieXRlcy5sZW5ndGgKICAgIC8vIAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAuZ2V0KGtleV8xLCBkZWZhdWx0PVN0cmluZygiZGVmYXVsdCIpKSA9PSBTdHJpbmcoImRlZmF1bHQiKQogICAgLy8gICAgIHZhbHVlLCBleGlzdHMgPSBzZWxmLmJveF9tYXAubWF5YmUoa2V5XzEpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBleGlzdHMKICAgIC8vICAgICBhc3NlcnQga2V5XzAgaW4gc2VsZi5ib3hfbWFwCiAgICBzd2FwCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE1MwogICAgLy8gYXNzZXJ0IGtleV8wIGluIHNlbGYuYm94X21hcAogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNTgKICAgIC8vIHRtcF9ib3hfbWFwW2tleV8xXSA9IFN0cmluZygiaGVsbG8iKQogICAgZHVwCiAgICBib3hfZGVsCiAgICBwb3AKICAgIGR1cAogICAgYnl0ZSAiaGVsbG8iCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNTYtMTU3CiAgICAvLyAjIHRlc3QgYm94IG1hcCBub3QgYXNzaWduZWQgdG8gdGhlIGNsYXNzIGFuZCBwYXNzZWQgdG8gc3Vicm91dGluZQogICAgLy8gdG1wX2JveF9tYXAgPSBCb3hNYXAoVUludDY0LCBTdHJpbmcsIGtleV9wcmVmaXg9Qnl0ZXMoKSkKICAgIGJ5dGUgMHgKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gYXNzZXJ0IGdldF9ib3hfbWFwX3ZhbHVlX2Zyb21fa2V5X3BsdXNfMSh0bXBfYm94X21hcCwgVUludDY0KDApKSA9PSAiaGVsbG8iCiAgICBpbnQgMAogICAgY2FsbHN1YiBnZXRfYm94X21hcF92YWx1ZV9mcm9tX2tleV9wbHVzXzEKICAgIGJ5dGUgImhlbGxvIgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTYwCiAgICAvLyBkZWwgdG1wX2JveF9tYXBba2V5XzFdCiAgICBib3hfZGVsCiAgICBwb3AKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LmdldF9ib3hfbWFwX3ZhbHVlX2Zyb21fa2V5X3BsdXNfMShib3hfbWFwOiBieXRlcywga2V5OiB1aW50NjQpIC0+IGJ5dGVzOgpnZXRfYm94X21hcF92YWx1ZV9mcm9tX2tleV9wbHVzXzE6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxODktMTkwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGdldF9ib3hfbWFwX3ZhbHVlX2Zyb21fa2V5X3BsdXNfMShib3hfbWFwOiBCb3hNYXBbVUludDY0LCBTdHJpbmddLCBrZXk6IFVJbnQ2NCkgLT4gU3RyaW5nOgogICAgcHJvdG8gMiAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxOTEKICAgIC8vIHJldHVybiBib3hfbWFwW2tleSArIDFdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAxCiAgICArCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIEJveE1hcCBlbnRyeSBleGlzdHMKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfc2V0KGtleTogdWludDY0LCB2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CmJveF9tYXBfc2V0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTYyLTE2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9zZXQoc2VsZiwga2V5OiBVSW50NjQsIHZhbHVlOiBTdHJpbmcpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE2NAogICAgLy8gc2VsZi5ib3hfbWFwW2tleV0gPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0yCiAgICBpdG9iCiAgICBkdXAKICAgIGJveF9kZWwKICAgIHBvcAogICAgZnJhbWVfZGlnIC0xCiAgICBib3hfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX2dldChrZXk6IHVpbnQ2NCkgLT4gYnl0ZXM6CmJveF9tYXBfZ2V0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTY2LTE2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9nZXQoc2VsZiwga2V5OiBVSW50NjQpIC0+IFN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTY4CiAgICAvLyByZXR1cm4gc2VsZi5ib3hfbWFwW2tleV0KICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X21hcCBlbnRyeSBleGlzdHMKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfZGVsKGtleTogdWludDY0KSAtPiB2b2lkOgpib3hfbWFwX2RlbDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3MC0xNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfZGVsKHNlbGYsIGtleTogVUludDY0KSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNzIKICAgIC8vIGRlbCBzZWxmLmJveF9tYXBba2V5XQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBib3hfZGVsCiAgICBwb3AKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfZXhpc3RzKGtleTogdWludDY0KSAtPiB1aW50NjQ6CmJveF9tYXBfZXhpc3RzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTc0LTE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9leGlzdHMoc2VsZiwga2V5OiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAxIDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0LTE3NgogICAgLy8gICAgIHNlbGYuYm94X21hcCA9IEJveE1hcChVSW50NjQsIFN0cmluZywga2V5X3ByZWZpeD0iIikKICAgIC8vICAgICBzZWxmLmJveF9yZWYgPSBCb3hSZWYoKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBzZXRfYm94ZXMoc2VsZiwgYTogVUludDY0LCBiOiBhcmM0LkR5bmFtaWNCeXRlcywgYzogYXJjNC5TdHJpbmcpIC0+IE5vbmU6CiAgICAvLyAgICAgc2VsZi5ib3hfYS52YWx1ZSA9IGEKICAgIC8vICAgICBzZWxmLmJveF9iLnZhbHVlID0gYi5jb3B5KCkKICAgIC8vICAgICBzZWxmLmJveF9jLnZhbHVlID0gYwogICAgLy8gICAgIHNlbGYuYm94X2QudmFsdWUgPSBiLm5hdGl2ZQogICAgLy8gCiAgICAvLyAgICAgYl92YWx1ZSA9IHNlbGYuYm94X2IudmFsdWUuY29weSgpCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2IudmFsdWUubGVuZ3RoID09IGJfdmFsdWUubGVuZ3RoLCAiZGlyZWN0IHJlZmVyZW5jZSBzaG91bGQgbWF0Y2ggY29weSIKICAgIC8vIAogICAgLy8gICAgIHNlbGYuYm94X2EudmFsdWUgKz0gMwogICAgLy8gCiAgICAvLyAgICAgIyB0ZXN0IC5sZW5ndGgKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYS5sZW5ndGggPT0gOAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9iLmxlbmd0aCA9PSBiLmJ5dGVzLmxlbmd0aAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9jLmxlbmd0aCA9PSBjLmJ5dGVzLmxlbmd0aAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9kLmxlbmd0aCA9PSBiLm5hdGl2ZS5sZW5ndGgKICAgIC8vIAogICAgLy8gICAgICMgdGVzdCAudmFsdWUuYnl0ZXMKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1swXSA9PSBjLmJ5dGVzWzBdCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbLTFdID09IGMuYnl0ZXNbLTFdCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbOi0xXSA9PSBjLmJ5dGVzWzotMV0KICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1s6Ml0gPT0gYy5ieXRlc1s6Ml0KICAgIC8vIAogICAgLy8gICAgICMgdGVzdCAudmFsdWUgd2l0aCBCeXRlcyB0eXBlCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbMF0gPT0gYi5uYXRpdmVbMF0KICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfZC52YWx1ZVstMV0gPT0gYi5uYXRpdmVbLTFdCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbOi0xXSA9PSBiLm5hdGl2ZVs6LTFdCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbOjVdID09IGIubmF0aXZlWzo1XQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9kLnZhbHVlWzogVUludDY0KDIpXSA9PSBiLm5hdGl2ZVs6IFVJbnQ2NCgyKV0KICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgY2hlY2tfa2V5cyhzZWxmKSAtPiBOb25lOgogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9hLmtleSA9PSBiImJveF9hIiwgImJveCBhIGtleSBvayIKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYi5rZXkgPT0gYiJiIiwgImJveCBiIGtleSBvayIKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYy5rZXkgPT0gYiJCT1hfQyIsICJib3ggYyBrZXkgb2siCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGRlbGV0ZV9ib3hlcyhzZWxmKSAtPiBOb25lOgogICAgLy8gICAgIGRlbCBzZWxmLmJveF9hLnZhbHVlCiAgICAvLyAgICAgZGVsIHNlbGYuYm94X2IudmFsdWUKICAgIC8vICAgICBkZWwgc2VsZi5ib3hfYy52YWx1ZQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9hLmdldChkZWZhdWx0PVVJbnQ2NCg0MikpID09IDQyCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2IuZ2V0KGRlZmF1bHQ9YXJjNC5EeW5hbWljQnl0ZXMoYiI0MiIpKS5uYXRpdmUgPT0gYiI0MiIKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfYy5nZXQoZGVmYXVsdD1hcmM0LlN0cmluZygiNDIiKSkgPT0gIjQyIgogICAgLy8gICAgIGEsIGFfZXhpc3RzID0gc2VsZi5ib3hfYS5tYXliZSgpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBhX2V4aXN0cwogICAgLy8gICAgIGFzc2VydCBhID09IDAKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgcmVhZF9ib3hlcyhzZWxmKSAtPiB0dXBsZVtVSW50NjQsIEJ5dGVzLCBhcmM0LlN0cmluZ106CiAgICAvLyAgICAgcmV0dXJuIGdldF9ib3hfdmFsdWVfcGx1c18xKHNlbGYuYm94X2EpIC0gMSwgc2VsZi5ib3hfYi52YWx1ZS5uYXRpdmUsIHNlbGYuYm94X2MudmFsdWUKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94ZXNfZXhpc3Qoc2VsZikgLT4gdHVwbGVbYm9vbCwgYm9vbCwgYm9vbF06CiAgICAvLyAgICAgcmV0dXJuIGJvb2woc2VsZi5ib3hfYSksIGJvb2woc2VsZi5ib3hfYiksIGJvb2woc2VsZi5ib3hfYykKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgc2xpY2VfYm94KHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAgYm94XzAgPSBCb3goQnl0ZXMsIGtleT1TdHJpbmcoIjAiKSkKICAgIC8vICAgICBib3hfMC52YWx1ZSA9IEJ5dGVzKGIiVGVzdGluZyB0ZXN0aW5nIDEyMyIpCiAgICAvLyAgICAgYXNzZXJ0IGJveF8wLnZhbHVlWzA6N10gPT0gYiJUZXN0aW5nIgogICAgLy8gCiAgICAvLyAgICAgc2VsZi5ib3hfYy52YWx1ZSA9IGFyYzQuU3RyaW5nKCJIZWxsbyIpCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbMjoxMF0gPT0gYiJIZWxsbyIKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYXJjNF9ib3goc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBib3hfZCA9IEJveChTdGF0aWNJbnRzLCBrZXk9Qnl0ZXMoYiJkIikpCiAgICAvLyAgICAgYm94X2QudmFsdWUgPSBTdGF0aWNJbnRzKGFyYzQuVUludDgoMCksIGFyYzQuVUludDgoMSksIGFyYzQuVUludDgoMiksIGFyYzQuVUludDgoMykpCiAgICAvLyAKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbMF0gPT0gMAogICAgLy8gICAgIGFzc2VydCBib3hfZC52YWx1ZVsxXSA9PSAxCiAgICAvLyAgICAgYXNzZXJ0IGJveF9kLnZhbHVlWzJdID09IDIKICAgIC8vICAgICBhc3NlcnQgYm94X2QudmFsdWVbM10gPT0gMwogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB0ZXN0X2JveF9yZWYoc2VsZikgLT4gTm9uZToKICAgIC8vICAgICAjIGluaXQgcmVmLCB3aXRoIHZhbGlkIGtleSB0eXBlcwogICAgLy8gICAgIGJveF9yZWYgPSBCb3hSZWYoa2V5PSJibG9iIikKICAgIC8vICAgICBhc3NlcnQgbm90IGJveF9yZWYsICJubyBkYXRhIgogICAgLy8gICAgIGJveF9yZWYgPSBCb3hSZWYoa2V5PWIiYmxvYiIpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBib3hfcmVmLCAibm8gZGF0YSIKICAgIC8vICAgICBib3hfcmVmID0gQm94UmVmKGtleT1CeXRlcyhiImJsb2IiKSkKICAgIC8vICAgICBhc3NlcnQgbm90IGJveF9yZWYsICJubyBkYXRhIgogICAgLy8gICAgIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgLy8gICAgIGFzc2VydCBub3QgYm94X3JlZiwgIm5vIGRhdGEiCiAgICAvLyAKICAgIC8vICAgICAjIGNyZWF0ZQogICAgLy8gICAgIGFzc2VydCBib3hfcmVmLmNyZWF0ZShzaXplPTMyKQogICAgLy8gICAgIGFzc2VydCBib3hfcmVmLCAiaGFzIGRhdGEiCiAgICAvLyAKICAgIC8vICAgICAjIG1hbmlwdWxhdGUgZGF0YQogICAgLy8gICAgIHNlbmRlcl9ieXRlcyA9IFR4bi5zZW5kZXIuYnl0ZXMKICAgIC8vICAgICBhcHBfYWRkcmVzcyA9IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MuYnl0ZXMKICAgIC8vICAgICB2YWx1ZV8zID0gQnl0ZXMoYiJoZWxsbyIpCiAgICAvLyAgICAgYm94X3JlZi5yZXBsYWNlKDAsIHNlbmRlcl9ieXRlcykKICAgIC8vICAgICBib3hfcmVmLnJlc2l6ZSg4MDAwKQogICAgLy8gICAgIGJveF9yZWYuc3BsaWNlKDAsIDAsIGFwcF9hZGRyZXNzKQogICAgLy8gICAgIGJveF9yZWYucmVwbGFjZSg2NCwgdmFsdWVfMykKICAgIC8vICAgICBwcmVmaXggPSBib3hfcmVmLmV4dHJhY3QoMCwgMzIgKiAyICsgdmFsdWVfMy5sZW5ndGgpCiAgICAvLyAgICAgYXNzZXJ0IHByZWZpeCA9PSBhcHBfYWRkcmVzcyArIHNlbmRlcl9ieXRlcyArIHZhbHVlXzMKICAgIC8vIAogICAgLy8gICAgICMgZGVsZXRlCiAgICAvLyAgICAgYXNzZXJ0IGJveF9yZWYuZGVsZXRlKCkKICAgIC8vICAgICBhc3NlcnQgYm94X3JlZi5rZXkgPT0gYiJibG9iIgogICAgLy8gCiAgICAvLyAgICAgIyBxdWVyeQogICAgLy8gICAgIHZhbHVlLCBleGlzdHMgPSBib3hfcmVmLm1heWJlKCkKICAgIC8vICAgICBhc3NlcnQgbm90IGV4aXN0cwogICAgLy8gICAgIGFzc2VydCB2YWx1ZSA9PSBiIiIKICAgIC8vICAgICBhc3NlcnQgYm94X3JlZi5nZXQoZGVmYXVsdD1zZW5kZXJfYnl0ZXMpID09IHNlbmRlcl9ieXRlcwogICAgLy8gCiAgICAvLyAgICAgIyB1cGRhdGUKICAgIC8vICAgICBib3hfcmVmLnB1dChzZW5kZXJfYnl0ZXMgKyBhcHBfYWRkcmVzcykKICAgIC8vICAgICBhc3NlcnQgYm94X3JlZiwgIkJsb2IgZXhpc3RzIgogICAgLy8gICAgIGFzc2VydCBib3hfcmVmLmxlbmd0aCA9PSA2NAogICAgLy8gICAgIGFzc2VydCBnZXRfYm94X3JlZl9sZW5ndGgoYm94X3JlZikgPT0gNjQKICAgIC8vIAogICAgLy8gICAgICMgaW5zdGFuY2UgYm94IHJlZgogICAgLy8gICAgIHNlbGYuYm94X3JlZi5jcmVhdGUoc2l6ZT1VSW50NjQoMzIpKQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9yZWYsICJoYXMgZGF0YSIKICAgIC8vICAgICBzZWxmLmJveF9yZWYuZGVsZXRlKCkKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF90ZXN0KHNlbGYpIC0+IE5vbmU6CiAgICAvLyAgICAga2V5XzAgPSBVSW50NjQoMCkKICAgIC8vICAgICBrZXlfMSA9IFVJbnQ2NCgxKQogICAgLy8gICAgIHZhbHVlID0gU3RyaW5nKCJIbW1tbW0iKQogICAgLy8gICAgIHNlbGYuYm94X21hcFtrZXlfMF0gPSB2YWx1ZQogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXBba2V5XzBdLmJ5dGVzLmxlbmd0aCA9PSB2YWx1ZS5ieXRlcy5sZW5ndGgKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfbWFwLmxlbmd0aChrZXlfMCkgPT0gdmFsdWUuYnl0ZXMubGVuZ3RoCiAgICAvLyAKICAgIC8vICAgICBhc3NlcnQgc2VsZi5ib3hfbWFwLmdldChrZXlfMSwgZGVmYXVsdD1TdHJpbmcoImRlZmF1bHQiKSkgPT0gU3RyaW5nKCJkZWZhdWx0IikKICAgIC8vICAgICB2YWx1ZSwgZXhpc3RzID0gc2VsZi5ib3hfbWFwLm1heWJlKGtleV8xKQogICAgLy8gICAgIGFzc2VydCBub3QgZXhpc3RzCiAgICAvLyAgICAgYXNzZXJ0IGtleV8wIGluIHNlbGYuYm94X21hcAogICAgLy8gICAgIGFzc2VydCBzZWxmLmJveF9tYXAua2V5X3ByZWZpeCA9PSBiIiIKICAgIC8vIAogICAgLy8gICAgICMgdGVzdCBib3ggbWFwIG5vdCBhc3NpZ25lZCB0byB0aGUgY2xhc3MgYW5kIHBhc3NlZCB0byBzdWJyb3V0aW5lCiAgICAvLyAgICAgdG1wX2JveF9tYXAgPSBCb3hNYXAoVUludDY0LCBTdHJpbmcsIGtleV9wcmVmaXg9Qnl0ZXMoKSkKICAgIC8vICAgICB0bXBfYm94X21hcFtrZXlfMV0gPSBTdHJpbmcoImhlbGxvIikKICAgIC8vICAgICBhc3NlcnQgZ2V0X2JveF9tYXBfdmFsdWVfZnJvbV9rZXlfcGx1c18xKHRtcF9ib3hfbWFwLCBVSW50NjQoMCkpID09ICJoZWxsbyIKICAgIC8vICAgICBkZWwgdG1wX2JveF9tYXBba2V5XzFdCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfc2V0KHNlbGYsIGtleTogVUludDY0LCB2YWx1ZTogU3RyaW5nKSAtPiBOb25lOgogICAgLy8gICAgIHNlbGYuYm94X21hcFtrZXldID0gdmFsdWUKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9nZXQoc2VsZiwga2V5OiBVSW50NjQpIC0+IFN0cmluZzoKICAgIC8vICAgICByZXR1cm4gc2VsZi5ib3hfbWFwW2tleV0KICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9kZWwoc2VsZiwga2V5OiBVSW50NjQpIC0+IE5vbmU6CiAgICAvLyAgICAgZGVsIHNlbGYuYm94X21hcFtrZXldCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfZXhpc3RzKHNlbGYsIGtleTogVUludDY0KSAtPiBib29sOgogICAgLy8gICAgIHJldHVybiBrZXkgaW4gc2VsZi5ib3hfbWFwCiAgICBmcmFtZV9kaWcgLTEKICAgIGl0b2IKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTc2CiAgICAvLyByZXR1cm4ga2V5IGluIHNlbGYuYm94X21hcAogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDE3CiAgICBtZXRob2QgInNldF9ib3hlcyh1aW50NjQsYnl0ZVtdLHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJjaGVja19rZXlzKCl2b2lkIgogICAgbWV0aG9kICJkZWxldGVfYm94ZXMoKXZvaWQiCiAgICBtZXRob2QgInJlYWRfYm94ZXMoKSh1aW50NjQsYnl0ZVtdLHN0cmluZykiCiAgICBtZXRob2QgImJveGVzX2V4aXN0KCkoYm9vbCxib29sLGJvb2wpIgogICAgbWV0aG9kICJzbGljZV9ib3goKXZvaWQiCiAgICBtZXRob2QgImFyYzRfYm94KCl2b2lkIgogICAgbWV0aG9kICJ0ZXN0X2JveF9yZWYoKXZvaWQiCiAgICBtZXRob2QgImJveF9tYXBfdGVzdCgpdm9pZCIKICAgIG1ldGhvZCAiYm94X21hcF9zZXQodWludDY0LHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJib3hfbWFwX2dldCh1aW50NjQpc3RyaW5nIgogICAgbWV0aG9kICJib3hfbWFwX2RlbCh1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAiYm94X21hcF9leGlzdHModWludDY0KWJvb2wiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19zZXRfYm94ZXNfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jaGVja19rZXlzX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX2JveGVzX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fcmVhZF9ib3hlc19yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JveGVzX2V4aXN0X3JvdXRlQDYgX19wdXlhX2FyYzRfcm91dGVyX19fc2xpY2VfYm94X3JvdXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9ib3hfcm91dGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX190ZXN0X2JveF9yZWZfcm91dGVAOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19ib3hfbWFwX3Rlc3Rfcm91dGVAMTAgX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9zZXRfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9nZXRfcm91dGVAMTIgX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9kZWxfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9leGlzdHNfcm91dGVAMTQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3NldF9ib3hlc19yb3V0ZUAyOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBzZXRfYm94ZXMKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NoZWNrX2tleXNfcm91dGVAMzoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9ib3hlc19yb3V0ZUA0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBkZWxldGVfYm94ZXMKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3JlYWRfYm94ZXNfcm91dGVANToKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgcmVhZF9ib3hlcwogICAgY292ZXIgMgogICAgc3dhcAogICAgaXRvYgogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGJ5dGUgMHgwMDBjCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGR1cAogICAgbGVuCiAgICBpbnQgMTIKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICB1bmNvdmVyIDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JveGVzX2V4aXN0X3JvdXRlQDY6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJveGVzX2V4aXN0CiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBieXRlIDB4MDAKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgY292ZXIgMgogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMwogICAgc2V0Yml0CiAgICBzd2FwCiAgICBpbnQgMAogICAgZ2V0Yml0CiAgICB1bmNvdmVyIDIKICAgIGludCAxCiAgICB1bmNvdmVyIDIKICAgIHNldGJpdAogICAgc3dhcAogICAgaW50IDAKICAgIGdldGJpdAogICAgaW50IDIKICAgIHN3YXAKICAgIHNldGJpdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fc2xpY2VfYm94X3JvdXRlQDc6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHNsaWNlX2JveAogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXJjNF9ib3hfcm91dGVAODoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgzCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgYXJjNF9ib3gKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3Rlc3RfYm94X3JlZl9yb3V0ZUA5OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OTMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB0ZXN0X2JveF9yZWYKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JveF9tYXBfdGVzdF9yb3V0ZUAxMDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJveF9tYXBfdGVzdAogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYm94X21hcF9zZXRfcm91dGVAMTE6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNjIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE2MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIGJveF9tYXBfc2V0CiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ib3hfbWFwX2dldF9yb3V0ZUAxMjoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib3hfbWFwX2dldAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JveF9tYXBfZGVsX3JvdXRlQDEzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgKICAgIC8vIGNsYXNzIEJveENvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIGJveF9tYXBfZGVsCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ib3hfbWFwX2V4aXN0c19yb3V0ZUAxNDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4CiAgICAvLyBjbGFzcyBCb3hDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBidG9pCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib3hfbWFwX2V4aXN0cwogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0AxNzoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjgKICAgIC8vIGNsYXNzIEJveENvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDIxOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OAogICAgLy8gY2xhc3MgQm94Q29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LnNldF9ib3hlcyhhOiB1aW50NjQsIGI6IGJ5dGVzLCBjOiBieXRlcykgLT4gdm9pZDoKc2V0X2JveGVzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTctMTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHNldF9ib3hlcyhzZWxmLCBhOiBVSW50NjQsIGI6IGFyYzQuRHluYW1pY0J5dGVzLCBjOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIHByb3RvIDMgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTkKICAgIC8vIHNlbGYuYm94X2EudmFsdWUgPSBhCiAgICBmcmFtZV9kaWcgLTMKICAgIGl0b2IKICAgIGJ5dGUgImJveF9hIgogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjAKICAgIC8vIHNlbGYuYm94X2IudmFsdWUgPSBiLmNvcHkoKQogICAgYnl0ZSAiYiIKICAgIGJveF9kZWwKICAgIHBvcAogICAgYnl0ZSAiYiIKICAgIGZyYW1lX2RpZyAtMgogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjEKICAgIC8vIHNlbGYuYm94X2MudmFsdWUgPSBjCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgYm94X2RlbAogICAgcG9wCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgZnJhbWVfZGlnIC0xCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyMgogICAgLy8gc2VsZi5ib3hfZC52YWx1ZSA9IGIubmF0aXZlCiAgICBmcmFtZV9kaWcgLTIKICAgIGV4dHJhY3QgMiAwCiAgICBieXRlICJib3hfZCIKICAgIGJveF9kZWwKICAgIHBvcAogICAgYnl0ZSAiYm94X2QiCiAgICBkaWcgMQogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjQKICAgIC8vIGJfdmFsdWUgPSBzZWxmLmJveF9iLnZhbHVlLmNvcHkoKQogICAgYnl0ZSAiYiIKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9iIGV4aXN0cwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjUKICAgIC8vIGFzc2VydCBzZWxmLmJveF9iLnZhbHVlLmxlbmd0aCA9PSBiX3ZhbHVlLmxlbmd0aCwgImRpcmVjdCByZWZlcmVuY2Ugc2hvdWxkIG1hdGNoIGNvcHkiCiAgICBieXRlICJiIgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X2IgZXhpc3RzCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgPT0KICAgIGFzc2VydCAvLyBkaXJlY3QgcmVmZXJlbmNlIHNob3VsZCBtYXRjaCBjb3B5CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToyNwogICAgLy8gc2VsZi5ib3hfYS52YWx1ZSArPSAzCiAgICBieXRlICJib3hfYSIKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9hIGV4aXN0cwogICAgaW50IDMKICAgICsKICAgIGl0b2IKICAgIGJ5dGUgImJveF9hIgogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MjktMzAKICAgIC8vICMgdGVzdCAubGVuZ3RoCiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYS5sZW5ndGggPT0gOAogICAgYnl0ZSAiYm94X2EiCiAgICBib3hfbGVuCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ib3hfYSBleGlzdHMKICAgIGludCA4CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozMQogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2IubGVuZ3RoID09IGIuYnl0ZXMubGVuZ3RoCiAgICBieXRlICJiIgogICAgYm94X2xlbgogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X2IgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTIKICAgIGxlbgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzIKICAgIC8vIGFzc2VydCBzZWxmLmJveF9jLmxlbmd0aCA9PSBjLmJ5dGVzLmxlbmd0aAogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9jIGV4aXN0cwogICAgZnJhbWVfZGlnIC0xCiAgICBsZW4KICAgIGR1cAogICAgY292ZXIgMgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzMKICAgIC8vIGFzc2VydCBzZWxmLmJveF9kLmxlbmd0aCA9PSBiLm5hdGl2ZS5sZW5ndGgKICAgIGJ5dGUgImJveF9kIgogICAgYm94X2xlbgogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X2QgZXhpc3RzCiAgICBkaWcgMgogICAgbGVuCiAgICBkdXAKICAgIGNvdmVyIDQKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjM1LTM2CiAgICAvLyAjIHRlc3QgLnZhbHVlLmJ5dGVzCiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfYy52YWx1ZS5ieXRlc1swXSA9PSBjLmJ5dGVzWzBdCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgaW50IDAKICAgIGludCAxCiAgICBib3hfZXh0cmFjdAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDAgMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzcKICAgIC8vIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWy0xXSA9PSBjLmJ5dGVzWy0xXQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIGJveF9sZW4KICAgIHBvcAogICAgaW50IDEKICAgIC0KICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICBzd2FwCiAgICBpbnQgMQogICAgYm94X2V4dHJhY3QKICAgIGRpZyAxCiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfZGlnIC0xCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTozOAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2MudmFsdWUuYnl0ZXNbOi0xXSA9PSBjLmJ5dGVzWzotMV0KICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICBib3hfbGVuCiAgICBwb3AKICAgIGludCAxCiAgICBkaWcgMQogICAgPAogICAgc3dhcAogICAgZHVwCiAgICBpbnQgMQogICAgdW5jb3ZlciAzCiAgICBzZWxlY3QKICAgIC0KICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBib3hfZXh0cmFjdAogICAgaW50IDEKICAgIGRpZyAyCiAgICA+PQogICAgaW50IDEKICAgIGRpZyAzCiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgZGlnIDIKICAgIHN3YXAKICAgIC0KICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MzkKICAgIC8vIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWzoyXSA9PSBjLmJ5dGVzWzoyXQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIGJveF9sZW4KICAgIHBvcAogICAgaW50IDIKICAgIGRpZyAxCiAgICA8CiAgICBpbnQgMgogICAgc3dhcAogICAgc2VsZWN0CiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgYm94X2V4dHJhY3QKICAgIGludCAyCiAgICBkaWcgMgogICAgPj0KICAgIGludCAyCiAgICB1bmNvdmVyIDMKICAgIHVuY292ZXIgMgogICAgc2VsZWN0CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAwCiAgICB1bmNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjQxLTQyCiAgICAvLyAjIHRlc3QgLnZhbHVlIHdpdGggQnl0ZXMgdHlwZQogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbMF0gPT0gYi5uYXRpdmVbMF0KICAgIGJ5dGUgImJveF9kIgogICAgaW50IDAKICAgIGludCAxCiAgICBib3hfZXh0cmFjdAogICAgZGlnIDEKICAgIGV4dHJhY3QgMCAxCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0MwogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbLTFdID09IGIubmF0aXZlWy0xXQogICAgYnl0ZSAiYm94X2QiCiAgICBib3hfbGVuCiAgICBwb3AKICAgIGludCAxCiAgICAtCiAgICBieXRlICJib3hfZCIKICAgIHN3YXAKICAgIGludCAxCiAgICBib3hfZXh0cmFjdAogICAgZGlnIDIKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGludCAxCiAgICArCiAgICBkaWcgMwogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDQKICAgIC8vIGFzc2VydCBzZWxmLmJveF9kLnZhbHVlWzotMV0gPT0gYi5uYXRpdmVbOi0xXQogICAgYnl0ZSAiYm94X2QiCiAgICBib3hfbGVuCiAgICBwb3AKICAgIGludCAxCiAgICBkaWcgMQogICAgPAogICAgc3dhcAogICAgZHVwCiAgICBpbnQgMQogICAgdW5jb3ZlciAzCiAgICBzZWxlY3QKICAgIC0KICAgIGJ5dGUgImJveF9kIgogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgYm94X2V4dHJhY3QKICAgIGludCAxCiAgICBkaWcgMwogICAgPj0KICAgIGludCAxCiAgICBkaWcgNAogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIGRpZyAzCiAgICBzd2FwCiAgICAtCiAgICBkaWcgMgogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NDUKICAgIC8vIGFzc2VydCBzZWxmLmJveF9kLnZhbHVlWzo1XSA9PSBiLm5hdGl2ZVs6NV0KICAgIGJ5dGUgImJveF9kIgogICAgYm94X2xlbgogICAgcG9wCiAgICBpbnQgNQogICAgZGlnIDEKICAgIDwKICAgIGludCA1CiAgICBzd2FwCiAgICBzZWxlY3QKICAgIGJ5dGUgImJveF9kIgogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgYm94X2V4dHJhY3QKICAgIGludCA1CiAgICBkaWcgMwogICAgPj0KICAgIGludCA1CiAgICBkaWcgNAogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIGRpZyAyCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo0NgogICAgLy8gYXNzZXJ0IHNlbGYuYm94X2QudmFsdWVbOiBVSW50NjQoMildID09IGIubmF0aXZlWzogVUludDY0KDIpXQogICAgYnl0ZSAiYm94X2QiCiAgICBib3hfbGVuCiAgICBwb3AKICAgIGludCAyCiAgICBkaWcgMQogICAgPAogICAgaW50IDIKICAgIHN3YXAKICAgIHNlbGVjdAogICAgYnl0ZSAiYm94X2QiCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBib3hfZXh0cmFjdAogICAgaW50IDIKICAgIGRpZyAzCiAgICA+PQogICAgaW50IDIKICAgIHVuY292ZXIgNAogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIHVuY292ZXIgMgogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgPT0KICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3QuZGVsZXRlX2JveGVzKCkgLT4gdm9pZDoKZGVsZXRlX2JveGVzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTQtNTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGRlbGV0ZV9ib3hlcyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1NgogICAgLy8gZGVsIHNlbGYuYm94X2EudmFsdWUKICAgIGJ5dGUgImJveF9hIgogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo1NwogICAgLy8gZGVsIHNlbGYuYm94X2IudmFsdWUKICAgIGJ5dGUgImIiCiAgICBib3hfZGVsCiAgICBwb3AKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjU4CiAgICAvLyBkZWwgc2VsZi5ib3hfYy52YWx1ZQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIGJveF9kZWwKICAgIHBvcAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NTkKICAgIC8vIGFzc2VydCBzZWxmLmJveF9hLmdldChkZWZhdWx0PVVJbnQ2NCg0MikpID09IDQyCiAgICBieXRlICJib3hfYSIKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIGludCA0MgogICAgc3dhcAogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIGludCA0MgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjAKICAgIC8vIGFzc2VydCBzZWxmLmJveF9iLmdldChkZWZhdWx0PWFyYzQuRHluYW1pY0J5dGVzKGIiNDIiKSkubmF0aXZlID09IGIiNDIiCiAgICBieXRlICJiIgogICAgYm94X2dldAogICAgYnl0ZSAweDAwMDIzNDMyCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGV4dHJhY3QgMiAwCiAgICBieXRlIDB4MzQzMgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjEKICAgIC8vIGFzc2VydCBzZWxmLmJveF9jLmdldChkZWZhdWx0PWFyYzQuU3RyaW5nKCI0MiIpKSA9PSAiNDIiCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgYm94X2dldAogICAgYnl0ZSAweDAwMDIzNDMyCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGJ5dGUgMHgwMDAyMzQzMgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjIKICAgIC8vIGEsIGFfZXhpc3RzID0gc2VsZi5ib3hfYS5tYXliZSgpCiAgICBieXRlICJib3hfYSIKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjYzCiAgICAvLyBhc3NlcnQgbm90IGFfZXhpc3RzCiAgICAhCiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY0CiAgICAvLyBhc3NlcnQgYSA9PSAwCiAgICAhCiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LnJlYWRfYm94ZXMoKSAtPiB1aW50NjQsIGJ5dGVzLCBieXRlczoKcmVhZF9ib3hlczoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjY2LTY3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiByZWFkX2JveGVzKHNlbGYpIC0+IHR1cGxlW1VJbnQ2NCwgQnl0ZXMsIGFyYzQuU3RyaW5nXToKICAgIHByb3RvIDAgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NjgKICAgIC8vIHJldHVybiBnZXRfYm94X3ZhbHVlX3BsdXNfMShzZWxmLmJveF9hKSAtIDEsIHNlbGYuYm94X2IudmFsdWUubmF0aXZlLCBzZWxmLmJveF9jLnZhbHVlCiAgICBieXRlICJib3hfYSIKICAgIGNhbGxzdWIgZ2V0X2JveF92YWx1ZV9wbHVzXzEKICAgIGludCAxCiAgICAtCiAgICBieXRlICJiIgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X2IgZXhpc3RzCiAgICBleHRyYWN0IDIgMAogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9jIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuZ2V0X2JveF92YWx1ZV9wbHVzXzEoYm94OiBieXRlcykgLT4gdWludDY0OgpnZXRfYm94X3ZhbHVlX3BsdXNfMToKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3OS0xODAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgZ2V0X2JveF92YWx1ZV9wbHVzXzEoYm94OiBCb3hbVUludDY0XSkgLT4gVUludDY0OgogICAgcHJvdG8gMSAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxODEKICAgIC8vIHJldHVybiBib3gudmFsdWUgKyAxCiAgICBmcmFtZV9kaWcgLTEKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGFzc2VydCAvLyBjaGVjayBCb3ggZXhpc3RzCiAgICBpbnQgMQogICAgKwogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3QuYm94ZXNfZXhpc3QoKSAtPiB1aW50NjQsIHVpbnQ2NCwgdWludDY0Ogpib3hlc19leGlzdDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjcwLTcxCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib3hlc19leGlzdChzZWxmKSAtPiB0dXBsZVtib29sLCBib29sLCBib29sXToKICAgIHByb3RvIDAgMwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzIKICAgIC8vIHJldHVybiBib29sKHNlbGYuYm94X2EpLCBib29sKHNlbGYuYm94X2IpLCBib29sKHNlbGYuYm94X2MpCiAgICBieXRlICJib3hfYSIKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgYnl0ZSAiYiIKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMuYm94X3N0b3JhZ2UuY29udHJhY3QuQm94Q29udHJhY3Quc2xpY2VfYm94KCkgLT4gdm9pZDoKc2xpY2VfYm94OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6NzQtNzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHNsaWNlX2JveChzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3NgogICAgLy8gYm94XzAgPSBCb3goQnl0ZXMsIGtleT1TdHJpbmcoIjAiKSkKICAgIGJ5dGUgIjAiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3NwogICAgLy8gYm94XzAudmFsdWUgPSBCeXRlcyhiIlRlc3RpbmcgdGVzdGluZyAxMjMiKQogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3NgogICAgLy8gYm94XzAgPSBCb3goQnl0ZXMsIGtleT1TdHJpbmcoIjAiKSkKICAgIGJ5dGUgIjAiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3NwogICAgLy8gYm94XzAudmFsdWUgPSBCeXRlcyhiIlRlc3RpbmcgdGVzdGluZyAxMjMiKQogICAgYnl0ZSAweDU0NjU3Mzc0Njk2ZTY3MjA3NDY1NzM3NDY5NmU2NzIwMzEzMjMzCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3NgogICAgLy8gYm94XzAgPSBCb3goQnl0ZXMsIGtleT1TdHJpbmcoIjAiKSkKICAgIGJ5dGUgIjAiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3OAogICAgLy8gYXNzZXJ0IGJveF8wLnZhbHVlWzA6N10gPT0gYiJUZXN0aW5nIgogICAgYm94X2xlbgogICAgcG9wCiAgICBkdXAKICAgIGludCAwCiAgICBkaWcgMgogICAgc2VsZWN0CiAgICBzd2FwCiAgICBpbnQgNwogICAgZGlnIDEKICAgIDwKICAgIGludCA3CiAgICBzd2FwCiAgICBzZWxlY3QKICAgIGRpZyAxCiAgICAtCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3NgogICAgLy8gYm94XzAgPSBCb3goQnl0ZXMsIGtleT1TdHJpbmcoIjAiKSkKICAgIGJ5dGUgIjAiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo3OAogICAgLy8gYXNzZXJ0IGJveF8wLnZhbHVlWzA6N10gPT0gYiJUZXN0aW5nIgogICAgY292ZXIgMgogICAgYm94X2V4dHJhY3QKICAgIGJ5dGUgMHg1NDY1NzM3NDY5NmU2NwogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODAKICAgIC8vIHNlbGYuYm94X2MudmFsdWUgPSBhcmM0LlN0cmluZygiSGVsbG8iKQogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIGJveF9kZWwKICAgIHBvcAogICAgYnl0ZSAweDQyNGY1ODVmNDMKICAgIGJ5dGUgMHgwMDA1NDg2NTZjNmM2ZgogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODEKICAgIC8vIGFzc2VydCBzZWxmLmJveF9jLnZhbHVlLmJ5dGVzWzI6MTBdID09IGIiSGVsbG8iCiAgICBieXRlIDB4NDI0ZjU4NWY0MwogICAgYm94X2xlbgogICAgcG9wCiAgICBpbnQgMgogICAgZGlnIDEKICAgIDwKICAgIHN3YXAKICAgIGR1cAogICAgaW50IDIKICAgIHVuY292ZXIgMwogICAgc2VsZWN0CiAgICBzd2FwCiAgICBpbnQgMTAKICAgIGRpZyAxCiAgICA8CiAgICBpbnQgMTAKICAgIHN3YXAKICAgIHNlbGVjdAogICAgZGlnIDEKICAgIC0KICAgIGJ5dGUgMHg0MjRmNTg1ZjQzCiAgICBjb3ZlciAyCiAgICBib3hfZXh0cmFjdAogICAgYnl0ZSAweDQ4NjU2YzZjNmYKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmFyYzRfYm94KCkgLT4gdm9pZDoKYXJjNF9ib3g6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4My04NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYXJjNF9ib3goc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODUKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1CeXRlcyhiImQiKSkKICAgIGJ5dGUgMHg2NAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODYKICAgIC8vIGJveF9kLnZhbHVlID0gU3RhdGljSW50cyhhcmM0LlVJbnQ4KDApLCBhcmM0LlVJbnQ4KDEpLCBhcmM0LlVJbnQ4KDIpLCBhcmM0LlVJbnQ4KDMpKQogICAgYnl0ZSAweDAwMDEwMjAzCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4NQogICAgLy8gYm94X2QgPSBCb3goU3RhdGljSW50cywga2V5PUJ5dGVzKGIiZCIpKQogICAgYnl0ZSAweDY0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4OAogICAgLy8gYXNzZXJ0IGJveF9kLnZhbHVlWzBdID09IDAKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBCb3ggZXhpc3RzCiAgICBleHRyYWN0IDAgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwMAogICAgYj09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojg1CiAgICAvLyBib3hfZCA9IEJveChTdGF0aWNJbnRzLCBrZXk9Qnl0ZXMoYiJkIikpCiAgICBieXRlIDB4NjQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5Ojg5CiAgICAvLyBhc3NlcnQgYm94X2QudmFsdWVbMV0gPT0gMQogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIEJveCBleGlzdHMKICAgIGV4dHJhY3QgMSAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnl0ZSAweDAxCiAgICBiPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6ODUKICAgIC8vIGJveF9kID0gQm94KFN0YXRpY0ludHMsIGtleT1CeXRlcyhiImQiKSkKICAgIGJ5dGUgMHg2NAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OTAKICAgIC8vIGFzc2VydCBib3hfZC52YWx1ZVsyXSA9PSAyCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgQm94IGV4aXN0cwogICAgZXh0cmFjdCAyIDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBieXRlIDB4MDIKICAgIGI9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo4NQogICAgLy8gYm94X2QgPSBCb3goU3RhdGljSW50cywga2V5PUJ5dGVzKGIiZCIpKQogICAgYnl0ZSAweDY0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo5MQogICAgLy8gYXNzZXJ0IGJveF9kLnZhbHVlWzNdID09IDMKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBCb3ggZXhpc3RzCiAgICBleHRyYWN0IDMgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwMwogICAgYj09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LnRlc3RfYm94X3JlZigpIC0+IHZvaWQ6CnRlc3RfYm94X3JlZjoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjkzLTk0CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiB0ZXN0X2JveF9yZWYoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OTUtOTYKICAgIC8vICMgaW5pdCByZWYsIHdpdGggdmFsaWQga2V5IHR5cGVzCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT0iYmxvYiIpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OTcKICAgIC8vIGFzc2VydCBub3QgYm94X3JlZiwgIm5vIGRhdGEiCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgICEKICAgIGFzc2VydCAvLyBubyBkYXRhCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weTo5OAogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9YiJibG9iIikKICAgIGJ5dGUgMHg2MjZjNmY2MgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6OTkKICAgIC8vIGFzc2VydCBub3QgYm94X3JlZiwgIm5vIGRhdGEiCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgICEKICAgIGFzc2VydCAvLyBubyBkYXRhCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDAKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PUJ5dGVzKGIiYmxvYiIpKQogICAgYnl0ZSAweDYyNmM2ZjYyCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDEKICAgIC8vIGFzc2VydCBub3QgYm94X3JlZiwgIm5vIGRhdGEiCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgICEKICAgIGFzc2VydCAvLyBubyBkYXRhCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMwogICAgLy8gYXNzZXJ0IG5vdCBib3hfcmVmLCAibm8gZGF0YSIKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgIQogICAgYXNzZXJ0IC8vIG5vIGRhdGEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTA1LTEwNgogICAgLy8gIyBjcmVhdGUKICAgIC8vIGFzc2VydCBib3hfcmVmLmNyZWF0ZShzaXplPTMyKQogICAgaW50IDMyCiAgICBib3hfY3JlYXRlCiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTA3CiAgICAvLyBhc3NlcnQgYm94X3JlZiwgImhhcyBkYXRhIgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICBhc3NlcnQgLy8gaGFzIGRhdGEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExMQogICAgLy8gYXBwX2FkZHJlc3MgPSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzLmJ5dGVzCiAgICBnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTA5LTExMAogICAgLy8gIyBtYW5pcHVsYXRlIGRhdGEKICAgIC8vIHNlbmRlcl9ieXRlcyA9IFR4bi5zZW5kZXIuYnl0ZXMKICAgIHR4biBTZW5kZXIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTEzCiAgICAvLyBib3hfcmVmLnJlcGxhY2UoMCwgc2VuZGVyX2J5dGVzKQogICAgaW50IDAKICAgIGRpZyAyCiAgICBib3hfcmVwbGFjZQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAyCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT1TdHJpbmcoImJsb2IiKSkKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMTQKICAgIC8vIGJveF9yZWYucmVzaXplKDgwMDApCiAgICBpbnQgODAwMAogICAgYm94X3Jlc2l6ZQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAyCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT1TdHJpbmcoImJsb2IiKSkKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMTUKICAgIC8vIGJveF9yZWYuc3BsaWNlKDAsIDAsIGFwcF9hZGRyZXNzKQogICAgaW50IDAKICAgIGR1cAogICAgZGlnIDQKICAgIGJveF9zcGxpY2UKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTE2CiAgICAvLyBib3hfcmVmLnJlcGxhY2UoNjQsIHZhbHVlXzMpCiAgICBpbnQgNjQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExMgogICAgLy8gdmFsdWVfMyA9IEJ5dGVzKGIiaGVsbG8iKQogICAgYnl0ZSAweDY4NjU2YzZjNmYKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExNgogICAgLy8gYm94X3JlZi5yZXBsYWNlKDY0LCB2YWx1ZV8zKQogICAgYm94X3JlcGxhY2UKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTE3CiAgICAvLyBwcmVmaXggPSBib3hfcmVmLmV4dHJhY3QoMCwgMzIgKiAyICsgdmFsdWVfMy5sZW5ndGgpCiAgICBpbnQgMAogICAgaW50IDY5CiAgICBib3hfZXh0cmFjdAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTE4CiAgICAvLyBhc3NlcnQgcHJlZml4ID09IGFwcF9hZGRyZXNzICsgc2VuZGVyX2J5dGVzICsgdmFsdWVfMwogICAgZGlnIDIKICAgIGRpZyAyCiAgICBjb25jYXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExMgogICAgLy8gdmFsdWVfMyA9IEJ5dGVzKGIiaGVsbG8iKQogICAgYnl0ZSAweDY4NjU2YzZjNmYKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjExOAogICAgLy8gYXNzZXJ0IHByZWZpeCA9PSBhcHBfYWRkcmVzcyArIHNlbmRlcl9ieXRlcyArIHZhbHVlXzMKICAgIGNvbmNhdAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAyCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT1TdHJpbmcoImJsb2IiKSkKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMjAtMTIxCiAgICAvLyAjIGRlbGV0ZQogICAgLy8gYXNzZXJ0IGJveF9yZWYuZGVsZXRlKCkKICAgIGJveF9kZWwKICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAyCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT1TdHJpbmcoImJsb2IiKSkKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMjQtMTI1CiAgICAvLyAjIHF1ZXJ5CiAgICAvLyB2YWx1ZSwgZXhpc3RzID0gYm94X3JlZi5tYXliZSgpCiAgICBib3hfZ2V0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMjYKICAgIC8vIGFzc2VydCBub3QgZXhpc3RzCiAgICAhCiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEyNwogICAgLy8gYXNzZXJ0IHZhbHVlID09IGIiIgogICAgYnl0ZSAweAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTAyCiAgICAvLyBib3hfcmVmID0gQm94UmVmKGtleT1TdHJpbmcoImJsb2IiKSkKICAgIGJ5dGUgImJsb2IiCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMjgKICAgIC8vIGFzc2VydCBib3hfcmVmLmdldChkZWZhdWx0PXNlbmRlcl9ieXRlcykgPT0gc2VuZGVyX2J5dGVzCiAgICBib3hfZ2V0CiAgICBkaWcgMgogICAgY292ZXIgMgogICAgc2VsZWN0CiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTMwLTEzMQogICAgLy8gIyB1cGRhdGUKICAgIC8vIGJveF9yZWYucHV0KHNlbmRlcl9ieXRlcyArIGFwcF9hZGRyZXNzKQogICAgc3dhcAogICAgY29uY2F0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMDIKICAgIC8vIGJveF9yZWYgPSBCb3hSZWYoa2V5PVN0cmluZygiYmxvYiIpKQogICAgYnl0ZSAiYmxvYiIKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEzMC0xMzEKICAgIC8vICMgdXBkYXRlCiAgICAvLyBib3hfcmVmLnB1dChzZW5kZXJfYnl0ZXMgKyBhcHBfYWRkcmVzcykKICAgIHN3YXAKICAgIGJveF9wdXQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTMyCiAgICAvLyBhc3NlcnQgYm94X3JlZiwgIkJsb2IgZXhpc3RzIgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICBhc3NlcnQgLy8gQmxvYiBleGlzdHMKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTMzCiAgICAvLyBhc3NlcnQgYm94X3JlZi5sZW5ndGggPT0gNjQKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBjaGVjayBCb3hSZWYgZXhpc3RzCiAgICBpbnQgNjQKICAgID09CiAgICBhc3NlcnQKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjEwMgogICAgLy8gYm94X3JlZiA9IEJveFJlZihrZXk9U3RyaW5nKCJibG9iIikpCiAgICBieXRlICJibG9iIgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTM0CiAgICAvLyBhc3NlcnQgZ2V0X2JveF9yZWZfbGVuZ3RoKGJveF9yZWYpID09IDY0CiAgICBjYWxsc3ViIGdldF9ib3hfcmVmX2xlbmd0aAogICAgaW50IDY0CiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMzYtMTM3CiAgICAvLyAjIGluc3RhbmNlIGJveCByZWYKICAgIC8vIHNlbGYuYm94X3JlZi5jcmVhdGUoc2l6ZT1VSW50NjQoMzIpKQogICAgYnl0ZSAiYm94X3JlZiIKICAgIGludCAzMgogICAgYm94X2NyZWF0ZQogICAgcG9wCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxMzgKICAgIC8vIGFzc2VydCBzZWxmLmJveF9yZWYsICJoYXMgZGF0YSIKICAgIGJ5dGUgImJveF9yZWYiCiAgICBib3hfbGVuCiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBoYXMgZGF0YQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTM5CiAgICAvLyBzZWxmLmJveF9yZWYuZGVsZXRlKCkKICAgIGJ5dGUgImJveF9yZWYiCiAgICBib3hfZGVsCiAgICBwb3AKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LmdldF9ib3hfcmVmX2xlbmd0aChyZWY6IGJ5dGVzKSAtPiB1aW50NjQ6CmdldF9ib3hfcmVmX2xlbmd0aDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE4NC0xODUKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgZ2V0X2JveF9yZWZfbGVuZ3RoKHJlZjogQm94UmVmKSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE4NgogICAgLy8gcmV0dXJuIHJlZi5sZW5ndGgKICAgIGZyYW1lX2RpZyAtMQogICAgYm94X2xlbgogICAgYXNzZXJ0IC8vIGNoZWNrIEJveFJlZiBleGlzdHMKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfdGVzdCgpIC0+IHZvaWQ6CmJveF9tYXBfdGVzdDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0MS0xNDIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfdGVzdChzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNDMKICAgIC8vIGtleV8wID0gVUludDY0KDApCiAgICBpbnQgMAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTQ2CiAgICAvLyBzZWxmLmJveF9tYXBba2V5XzBdID0gdmFsdWUKICAgIGl0b2IKICAgIGR1cAogICAgYm94X2RlbAogICAgcG9wCiAgICBkdXAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE0NQogICAgLy8gdmFsdWUgPSBTdHJpbmcoIkhtbW1tbSIpCiAgICBieXRlICJIbW1tbW0iCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNDYKICAgIC8vIHNlbGYuYm94X21hcFtrZXlfMF0gPSB2YWx1ZQogICAgYm94X3B1dAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTQ3CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfbWFwW2tleV8wXS5ieXRlcy5sZW5ndGggPT0gdmFsdWUuYnl0ZXMubGVuZ3RoCiAgICBkdXAKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9tYXAgZW50cnkgZXhpc3RzCiAgICBpbnQgNgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTQ4CiAgICAvLyBhc3NlcnQgc2VsZi5ib3hfbWFwLmxlbmd0aChrZXlfMCkgPT0gdmFsdWUuYnl0ZXMubGVuZ3RoCiAgICBkdXAKICAgIGJveF9sZW4KICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveF9tYXAgZW50cnkgZXhpc3RzCiAgICBpbnQgNgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTQ0CiAgICAvLyBrZXlfMSA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE1MAogICAgLy8gYXNzZXJ0IHNlbGYuYm94X21hcC5nZXQoa2V5XzEsIGRlZmF1bHQ9U3RyaW5nKCJkZWZhdWx0IikpID09IFN0cmluZygiZGVmYXVsdCIpCiAgICBpdG9iCiAgICBkdXAKICAgIGJveF9nZXQKICAgIGJ5dGUgImRlZmF1bHQiCiAgICBjb3ZlciAyCiAgICBzZWxlY3QKICAgIGJ5dGUgImRlZmF1bHQiCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNTEKICAgIC8vIHZhbHVlLCBleGlzdHMgPSBzZWxmLmJveF9tYXAubWF5YmUoa2V5XzEpCiAgICBkdXAKICAgIGJveF9nZXQKICAgIGJ1cnkgMQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTUyCiAgICAvLyBhc3NlcnQgbm90IGV4aXN0cwogICAgIQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNTMKICAgIC8vIGFzc2VydCBrZXlfMCBpbiBzZWxmLmJveF9tYXAKICAgIHN3YXAKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgYXNzZXJ0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNTgKICAgIC8vIHRtcF9ib3hfbWFwW2tleV8xXSA9IFN0cmluZygiaGVsbG8iKQogICAgZHVwCiAgICBib3hfZGVsCiAgICBwb3AKICAgIGR1cAogICAgYnl0ZSAiaGVsbG8iCiAgICBib3hfcHV0CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNTYtMTU3CiAgICAvLyAjIHRlc3QgYm94IG1hcCBub3QgYXNzaWduZWQgdG8gdGhlIGNsYXNzIGFuZCBwYXNzZWQgdG8gc3Vicm91dGluZQogICAgLy8gdG1wX2JveF9tYXAgPSBCb3hNYXAoVUludDY0LCBTdHJpbmcsIGtleV9wcmVmaXg9Qnl0ZXMoKSkKICAgIGJ5dGUgMHgKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE1OQogICAgLy8gYXNzZXJ0IGdldF9ib3hfbWFwX3ZhbHVlX2Zyb21fa2V5X3BsdXNfMSh0bXBfYm94X21hcCwgVUludDY0KDApKSA9PSAiaGVsbG8iCiAgICBpbnQgMAogICAgY2FsbHN1YiBnZXRfYm94X21hcF92YWx1ZV9mcm9tX2tleV9wbHVzXzEKICAgIGJ5dGUgImhlbGxvIgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTYwCiAgICAvLyBkZWwgdG1wX2JveF9tYXBba2V5XzFdCiAgICBib3hfZGVsCiAgICBwb3AKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LmdldF9ib3hfbWFwX3ZhbHVlX2Zyb21fa2V5X3BsdXNfMShib3hfbWFwOiBieXRlcywga2V5OiB1aW50NjQpIC0+IGJ5dGVzOgpnZXRfYm94X21hcF92YWx1ZV9mcm9tX2tleV9wbHVzXzE6CiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxODktMTkwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGdldF9ib3hfbWFwX3ZhbHVlX2Zyb21fa2V5X3BsdXNfMShib3hfbWFwOiBCb3hNYXBbVUludDY0LCBTdHJpbmddLCBrZXk6IFVJbnQ2NCkgLT4gU3RyaW5nOgogICAgcHJvdG8gMiAxCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxOTEKICAgIC8vIHJldHVybiBib3hfbWFwW2tleSArIDFdCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAxCiAgICArCiAgICBpdG9iCiAgICBmcmFtZV9kaWcgLTIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIEJveE1hcCBlbnRyeSBleGlzdHMKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfc2V0KGtleTogdWludDY0LCB2YWx1ZTogYnl0ZXMpIC0+IHZvaWQ6CmJveF9tYXBfc2V0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTYyLTE2MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9zZXQoc2VsZiwga2V5OiBVSW50NjQsIHZhbHVlOiBTdHJpbmcpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE2NAogICAgLy8gc2VsZi5ib3hfbWFwW2tleV0gPSB2YWx1ZQogICAgZnJhbWVfZGlnIC0yCiAgICBpdG9iCiAgICBkdXAKICAgIGJveF9kZWwKICAgIHBvcAogICAgZnJhbWVfZGlnIC0xCiAgICBib3hfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5ib3hfbWFwX2dldChrZXk6IHVpbnQ2NCkgLT4gYnl0ZXM6CmJveF9tYXBfZ2V0OgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTY2LTE2NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9nZXQoc2VsZiwga2V5OiBVSW50NjQpIC0+IFN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTY4CiAgICAvLyByZXR1cm4gc2VsZi5ib3hfbWFwW2tleV0KICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94X21hcCBlbnRyeSBleGlzdHMKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfZGVsKGtleTogdWludDY0KSAtPiB2b2lkOgpib3hfbWFwX2RlbDoKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3MC0xNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGJveF9tYXBfZGVsKHNlbGYsIGtleTogVUludDY0KSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBib3hfc3RvcmFnZS9jb250cmFjdC5weToxNzIKICAgIC8vIGRlbCBzZWxmLmJveF9tYXBba2V5XQogICAgZnJhbWVfZGlnIC0xCiAgICBpdG9iCiAgICBib3hfZGVsCiAgICBwb3AKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLmJveF9zdG9yYWdlLmNvbnRyYWN0LkJveENvbnRyYWN0LmJveF9tYXBfZXhpc3RzKGtleTogdWludDY0KSAtPiB1aW50NjQ6CmJveF9tYXBfZXhpc3RzOgogICAgLy8gYm94X3N0b3JhZ2UvY29udHJhY3QucHk6MTc0LTE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm94X21hcF9leGlzdHMoc2VsZiwga2V5OiBVSW50NjQpIC0+IGJvb2w6CiAgICBwcm90byAxIDEKICAgIC8vIGJveF9zdG9yYWdlL2NvbnRyYWN0LnB5OjE3NgogICAgLy8gcmV0dXJuIGtleSBpbiBzZWxmLmJveF9tYXAKICAgIGZyYW1lX2RpZyAtMQogICAgaXRvYgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5ib3hfc3RvcmFnZS5jb250cmFjdC5Cb3hDb250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/examples/box_storage/out_unoptimized/BoxContract.approval.teal b/examples/box_storage/out_unoptimized/BoxContract.approval.teal index 0142df0ec6..c4134f0a8a 100644 --- a/examples/box_storage/out_unoptimized/BoxContract.approval.teal +++ b/examples/box_storage/out_unoptimized/BoxContract.approval.teal @@ -400,74 +400,44 @@ set_boxes: // self.box_a.value = a frame_dig -3 itob - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) byte "box_a" - // box_storage/contract.py:19 - // self.box_a.value = a uncover 1 box_put // box_storage/contract.py:20 // self.box_b.value = b.copy() frame_dig -2 - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") byte "b" - // box_storage/contract.py:20 - // self.box_b.value = b.copy() box_del pop - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") byte "b" - // box_storage/contract.py:20 - // self.box_b.value = b.copy() uncover 1 box_put - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:21 // self.box_c.value = c + byte 0x424f585f43 box_del pop - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:21 - // self.box_c.value = c frame_dig -1 box_put // box_storage/contract.py:22 // self.box_d.value = b.native frame_dig -2 extract 2 0 - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:22 - // self.box_d.value = b.native box_del pop - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:22 - // self.box_d.value = b.native uncover 1 box_put - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:24 // b_value = self.box_b.value.copy() + byte "b" box_get assert // check self.box_b exists - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:25 // assert self.box_b.value.length == b_value.length, "direct reference should match copy" + byte "b" box_get assert // check self.box_b exists int 0 @@ -477,11 +447,9 @@ set_boxes: extract_uint16 == assert // direct reference should match copy - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:27 // self.box_a.value += 3 + byte "box_a" box_get cover 1 btoi @@ -490,51 +458,39 @@ set_boxes: int 3 + itob - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) byte "box_a" - // box_storage/contract.py:27 - // self.box_a.value += 3 uncover 1 box_put - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:29-30 // # test .length // assert self.box_a.length == 8 + byte "box_a" box_len assert // check self.box_a exists int 8 == assert - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:31 // assert self.box_b.length == b.bytes.length + byte "b" box_len assert // check self.box_b exists frame_dig -2 len == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:32 // assert self.box_c.length == c.bytes.length + byte 0x424f585f43 box_len assert // check self.box_c exists frame_dig -1 len == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:33 // assert self.box_d.length == b.native.length + byte "box_d" box_len assert // check self.box_d exists frame_dig -2 @@ -542,12 +498,10 @@ set_boxes: len == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:35-36 // # test .value.bytes // assert self.box_c.value.bytes[0] == c.bytes[0] + byte 0x424f585f43 int 0 int 1 box_extract @@ -555,20 +509,14 @@ set_boxes: extract 0 1 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:37 // assert self.box_c.value.bytes[-1] == c.bytes[-1] + byte 0x424f585f43 box_len pop int 1 - - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:37 - // assert self.box_c.value.bytes[-1] == c.bytes[-1] uncover 1 int 1 box_extract @@ -585,11 +533,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:38 // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] + byte 0x424f585f43 box_len pop int 1 @@ -603,11 +549,7 @@ set_boxes: - int 0 - - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:38 - // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] int 0 uncover 2 box_extract @@ -627,11 +569,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:39 // assert self.box_c.value.bytes[:2] == c.bytes[:2] + byte 0x424f585f43 box_len pop int 2 @@ -643,11 +583,7 @@ set_boxes: select int 0 - - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:39 - // assert self.box_c.value.bytes[:2] == c.bytes[:2] int 0 uncover 2 box_extract @@ -666,12 +602,10 @@ set_boxes: substring3 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:41-42 // # test .value with Bytes type // assert self.box_d.value[0] == b.native[0] + byte "box_d" int 0 int 1 box_extract @@ -680,20 +614,14 @@ set_boxes: extract 0 1 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:43 // assert self.box_d.value[-1] == b.native[-1] + byte "box_d" box_len pop int 1 - - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:43 - // assert self.box_d.value[-1] == b.native[-1] uncover 1 int 1 box_extract @@ -714,11 +642,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:44 // assert self.box_d.value[:-1] == b.native[:-1] + byte "box_d" box_len pop int 1 @@ -732,11 +658,7 @@ set_boxes: - int 0 - - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:44 - // assert self.box_d.value[:-1] == b.native[:-1] int 0 uncover 2 box_extract @@ -758,11 +680,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:45 // assert self.box_d.value[:5] == b.native[:5] + byte "box_d" box_len pop int 5 @@ -774,11 +694,7 @@ set_boxes: select int 0 - - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:45 - // assert self.box_d.value[:5] == b.native[:5] int 0 uncover 2 box_extract @@ -799,11 +715,9 @@ set_boxes: substring3 == assert - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) - byte "box_d" // box_storage/contract.py:46 // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] + byte "box_d" box_len pop int 2 @@ -815,11 +729,7 @@ set_boxes: select int 0 - - // box_storage/contract.py:13 - // self.box_d = Box(Bytes) byte "box_d" - // box_storage/contract.py:46 - // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] int 0 uncover 2 box_extract @@ -849,28 +759,22 @@ check_keys: // @arc4.abimethod // def check_keys(self) -> None: proto 0 0 - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:50 // assert self.box_a.key == b"box_a", "box a key ok" + byte "box_a" byte 0x626f785f61 == assert // box a key ok - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:51 // assert self.box_b.key == b"b", "box b key ok" + byte "b" byte 0x62 == assert // box b key ok - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:52 // assert self.box_c.key == b"BOX_C", "box c key ok" byte 0x424f585f43 + byte 0x424f585f43 == assert // box c key ok retsub @@ -882,32 +786,24 @@ delete_boxes: // @arc4.abimethod // def delete_boxes(self) -> None: proto 0 0 - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:56 // del self.box_a.value + byte "box_a" box_del pop - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") - byte "b" // box_storage/contract.py:57 // del self.box_b.value + byte "b" box_del pop - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:58 // del self.box_c.value + byte 0x424f585f43 box_del pop - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:59 // assert self.box_a.get(default=UInt64(42)) == 42 + byte "box_a" box_get cover 1 btoi @@ -926,11 +822,7 @@ delete_boxes: extract 6 2 byte 0x3432 concat - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") byte "b" - // box_storage/contract.py:60 - // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" box_get cover 1 uncover 2 @@ -949,11 +841,7 @@ delete_boxes: extract 6 2 byte "42" concat - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:61 - // assert self.box_c.get(default=arc4.String("42")) == "42" box_get cover 1 uncover 2 @@ -968,11 +856,9 @@ delete_boxes: concat == assert - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:62 // a, a_exists = self.box_a.maybe() + byte "box_a" box_get cover 1 btoi @@ -995,27 +881,17 @@ read_boxes: // @arc4.abimethod // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: proto 0 3 - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:68 // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value + byte "box_a" callsub get_box_value_plus_1 int 1 - - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") byte "b" - // box_storage/contract.py:68 - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value box_get assert // check self.box_b exists extract 2 0 - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:68 - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value box_get assert // check self.box_c exists uncover 2 @@ -1049,27 +925,17 @@ boxes_exist: // @arc4.abimethod // def boxes_exist(self) -> tuple[bool, bool, bool]: proto 0 3 - // box_storage/contract.py:10 - // self.box_a = Box(UInt64) - byte "box_a" // box_storage/contract.py:72 // return bool(self.box_a), bool(self.box_b), bool(self.box_c) + byte "box_a" box_len cover 1 pop - // box_storage/contract.py:11 - // self.box_b = Box[arc4.DynamicBytes](arc4.DynamicBytes, key="b") byte "b" - // box_storage/contract.py:72 - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) box_len cover 1 pop - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:72 - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) box_len cover 1 pop @@ -1151,25 +1017,15 @@ slice_box: extract 6 2 byte "Hello" concat - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:80 - // self.box_c.value = arc4.String("Hello") box_del pop - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:80 - // self.box_c.value = arc4.String("Hello") uncover 1 box_put - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") - byte 0x424f585f43 // box_storage/contract.py:81 // assert self.box_c.value.bytes[2:10] == b"Hello" + byte 0x424f585f43 box_len pop int 2 @@ -1198,11 +1054,7 @@ slice_box: uncover 2 select - - // box_storage/contract.py:12 - // self.box_c = Box(arc4.String, key=b"BOX_C") byte 0x424f585f43 - // box_storage/contract.py:81 - // assert self.box_c.value.bytes[2:10] == b"Hello" uncover 2 uncover 2 box_extract @@ -1528,29 +1380,23 @@ test_box_ref: int 64 == assert - // box_storage/contract.py:15 - // self.box_ref = BoxRef() - byte "box_ref" // box_storage/contract.py:136-137 // # instance box ref // self.box_ref.create(size=UInt64(32)) + byte "box_ref" int 32 box_create pop - // box_storage/contract.py:15 - // self.box_ref = BoxRef() - byte "box_ref" // box_storage/contract.py:138 // assert self.box_ref, "has data" + byte "box_ref" box_len cover 1 pop assert // has data - // box_storage/contract.py:15 - // self.box_ref = BoxRef() - byte "box_ref" // box_storage/contract.py:139 // self.box_ref.delete() + byte "box_ref" box_del pop retsub @@ -1582,11 +1428,7 @@ box_map_test: // box_storage/contract.py:146 // self.box_map[key_0] = value itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:146 - // self.box_map[key_0] = value uncover 1 concat dup @@ -1604,11 +1446,7 @@ box_map_test: // box_storage/contract.py:147 // assert self.box_map[key_0].bytes.length == value.bytes.length itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:147 - // assert self.box_map[key_0].bytes.length == value.bytes.length uncover 1 concat box_len @@ -1627,11 +1465,7 @@ box_map_test: // box_storage/contract.py:148 // assert self.box_map.length(key_0) == value.bytes.length itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:148 - // assert self.box_map.length(key_0) == value.bytes.length uncover 1 concat box_len @@ -1650,11 +1484,7 @@ box_map_test: // box_storage/contract.py:150 // assert self.box_map.get(key_1, default=String("default")) == String("default") itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:150 - // assert self.box_map.get(key_1, default=String("default")) == String("default") uncover 1 concat box_get @@ -1672,11 +1502,7 @@ box_map_test: // box_storage/contract.py:151 // value, exists = self.box_map.maybe(key_1) itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:151 - // value, exists = self.box_map.maybe(key_1) uncover 1 concat box_get @@ -1689,305 +1515,19 @@ box_map_test: // box_storage/contract.py:143 // key_0 = UInt64(0) int 0 - // box_storage/contract.py:14-153 - // self.box_map = BoxMap(UInt64, String, key_prefix="") - // self.box_ref = BoxRef() - // - // @arc4.abimethod - // def set_boxes(self, a: UInt64, b: arc4.DynamicBytes, c: arc4.String) -> None: - // self.box_a.value = a - // self.box_b.value = b.copy() - // self.box_c.value = c - // self.box_d.value = b.native - // - // b_value = self.box_b.value.copy() - // assert self.box_b.value.length == b_value.length, "direct reference should match copy" - // - // self.box_a.value += 3 - // - // # test .length - // assert self.box_a.length == 8 - // assert self.box_b.length == b.bytes.length - // assert self.box_c.length == c.bytes.length - // assert self.box_d.length == b.native.length - // - // # test .value.bytes - // assert self.box_c.value.bytes[0] == c.bytes[0] - // assert self.box_c.value.bytes[-1] == c.bytes[-1] - // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] - // assert self.box_c.value.bytes[:2] == c.bytes[:2] - // - // # test .value with Bytes type - // assert self.box_d.value[0] == b.native[0] - // assert self.box_d.value[-1] == b.native[-1] - // assert self.box_d.value[:-1] == b.native[:-1] - // assert self.box_d.value[:5] == b.native[:5] - // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] - // - // @arc4.abimethod - // def check_keys(self) -> None: - // assert self.box_a.key == b"box_a", "box a key ok" - // assert self.box_b.key == b"b", "box b key ok" - // assert self.box_c.key == b"BOX_C", "box c key ok" - // - // @arc4.abimethod - // def delete_boxes(self) -> None: - // del self.box_a.value - // del self.box_b.value - // del self.box_c.value - // assert self.box_a.get(default=UInt64(42)) == 42 - // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" - // assert self.box_c.get(default=arc4.String("42")) == "42" - // a, a_exists = self.box_a.maybe() - // assert not a_exists - // assert a == 0 - // - // @arc4.abimethod - // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value - // - // @arc4.abimethod - // def boxes_exist(self) -> tuple[bool, bool, bool]: - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) - // - // @arc4.abimethod - // def slice_box(self) -> None: - // box_0 = Box(Bytes, key=String("0")) - // box_0.value = Bytes(b"Testing testing 123") - // assert box_0.value[0:7] == b"Testing" - // - // self.box_c.value = arc4.String("Hello") - // assert self.box_c.value.bytes[2:10] == b"Hello" - // - // @arc4.abimethod - // def arc4_box(self) -> None: - // box_d = Box(StaticInts, key=Bytes(b"d")) - // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) - // - // assert box_d.value[0] == 0 - // assert box_d.value[1] == 1 - // assert box_d.value[2] == 2 - // assert box_d.value[3] == 3 - // - // @arc4.abimethod - // def test_box_ref(self) -> None: - // # init ref, with valid key types - // box_ref = BoxRef(key="blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=b"blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=Bytes(b"blob")) - // assert not box_ref, "no data" - // box_ref = BoxRef(key=String("blob")) - // assert not box_ref, "no data" - // - // # create - // assert box_ref.create(size=32) - // assert box_ref, "has data" - // - // # manipulate data - // sender_bytes = Txn.sender.bytes - // app_address = Global.current_application_address.bytes - // value_3 = Bytes(b"hello") - // box_ref.replace(0, sender_bytes) - // box_ref.resize(8000) - // box_ref.splice(0, 0, app_address) - // box_ref.replace(64, value_3) - // prefix = box_ref.extract(0, 32 * 2 + value_3.length) - // assert prefix == app_address + sender_bytes + value_3 - // - // # delete - // assert box_ref.delete() - // assert box_ref.key == b"blob" - // - // # query - // value, exists = box_ref.maybe() - // assert not exists - // assert value == b"" - // assert box_ref.get(default=sender_bytes) == sender_bytes - // - // # update - // box_ref.put(sender_bytes + app_address) - // assert box_ref, "Blob exists" - // assert box_ref.length == 64 - // assert get_box_ref_length(box_ref) == 64 - // - // # instance box ref - // self.box_ref.create(size=UInt64(32)) - // assert self.box_ref, "has data" - // self.box_ref.delete() - // - // @arc4.abimethod - // def box_map_test(self) -> None: - // key_0 = UInt64(0) - // key_1 = UInt64(1) - // value = String("Hmmmmm") - // self.box_map[key_0] = value - // assert self.box_map[key_0].bytes.length == value.bytes.length - // assert self.box_map.length(key_0) == value.bytes.length - // - // assert self.box_map.get(key_1, default=String("default")) == String("default") - // value, exists = self.box_map.maybe(key_1) - // assert not exists - // assert key_0 in self.box_map + // box_storage/contract.py:153 + // assert key_0 in self.box_map itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:14-153 - // self.box_map = BoxMap(UInt64, String, key_prefix="") - // self.box_ref = BoxRef() - // - // @arc4.abimethod - // def set_boxes(self, a: UInt64, b: arc4.DynamicBytes, c: arc4.String) -> None: - // self.box_a.value = a - // self.box_b.value = b.copy() - // self.box_c.value = c - // self.box_d.value = b.native - // - // b_value = self.box_b.value.copy() - // assert self.box_b.value.length == b_value.length, "direct reference should match copy" - // - // self.box_a.value += 3 - // - // # test .length - // assert self.box_a.length == 8 - // assert self.box_b.length == b.bytes.length - // assert self.box_c.length == c.bytes.length - // assert self.box_d.length == b.native.length - // - // # test .value.bytes - // assert self.box_c.value.bytes[0] == c.bytes[0] - // assert self.box_c.value.bytes[-1] == c.bytes[-1] - // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] - // assert self.box_c.value.bytes[:2] == c.bytes[:2] - // - // # test .value with Bytes type - // assert self.box_d.value[0] == b.native[0] - // assert self.box_d.value[-1] == b.native[-1] - // assert self.box_d.value[:-1] == b.native[:-1] - // assert self.box_d.value[:5] == b.native[:5] - // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] - // - // @arc4.abimethod - // def check_keys(self) -> None: - // assert self.box_a.key == b"box_a", "box a key ok" - // assert self.box_b.key == b"b", "box b key ok" - // assert self.box_c.key == b"BOX_C", "box c key ok" - // - // @arc4.abimethod - // def delete_boxes(self) -> None: - // del self.box_a.value - // del self.box_b.value - // del self.box_c.value - // assert self.box_a.get(default=UInt64(42)) == 42 - // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" - // assert self.box_c.get(default=arc4.String("42")) == "42" - // a, a_exists = self.box_a.maybe() - // assert not a_exists - // assert a == 0 - // - // @arc4.abimethod - // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value - // - // @arc4.abimethod - // def boxes_exist(self) -> tuple[bool, bool, bool]: - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) - // - // @arc4.abimethod - // def slice_box(self) -> None: - // box_0 = Box(Bytes, key=String("0")) - // box_0.value = Bytes(b"Testing testing 123") - // assert box_0.value[0:7] == b"Testing" - // - // self.box_c.value = arc4.String("Hello") - // assert self.box_c.value.bytes[2:10] == b"Hello" - // - // @arc4.abimethod - // def arc4_box(self) -> None: - // box_d = Box(StaticInts, key=Bytes(b"d")) - // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) - // - // assert box_d.value[0] == 0 - // assert box_d.value[1] == 1 - // assert box_d.value[2] == 2 - // assert box_d.value[3] == 3 - // - // @arc4.abimethod - // def test_box_ref(self) -> None: - // # init ref, with valid key types - // box_ref = BoxRef(key="blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=b"blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=Bytes(b"blob")) - // assert not box_ref, "no data" - // box_ref = BoxRef(key=String("blob")) - // assert not box_ref, "no data" - // - // # create - // assert box_ref.create(size=32) - // assert box_ref, "has data" - // - // # manipulate data - // sender_bytes = Txn.sender.bytes - // app_address = Global.current_application_address.bytes - // value_3 = Bytes(b"hello") - // box_ref.replace(0, sender_bytes) - // box_ref.resize(8000) - // box_ref.splice(0, 0, app_address) - // box_ref.replace(64, value_3) - // prefix = box_ref.extract(0, 32 * 2 + value_3.length) - // assert prefix == app_address + sender_bytes + value_3 - // - // # delete - // assert box_ref.delete() - // assert box_ref.key == b"blob" - // - // # query - // value, exists = box_ref.maybe() - // assert not exists - // assert value == b"" - // assert box_ref.get(default=sender_bytes) == sender_bytes - // - // # update - // box_ref.put(sender_bytes + app_address) - // assert box_ref, "Blob exists" - // assert box_ref.length == 64 - // assert get_box_ref_length(box_ref) == 64 - // - // # instance box ref - // self.box_ref.create(size=UInt64(32)) - // assert self.box_ref, "has data" - // self.box_ref.delete() - // - // @arc4.abimethod - // def box_map_test(self) -> None: - // key_0 = UInt64(0) - // key_1 = UInt64(1) - // value = String("Hmmmmm") - // self.box_map[key_0] = value - // assert self.box_map[key_0].bytes.length == value.bytes.length - // assert self.box_map.length(key_0) == value.bytes.length - // - // assert self.box_map.get(key_1, default=String("default")) == String("default") - // value, exists = self.box_map.maybe(key_1) - // assert not exists - // assert key_0 in self.box_map uncover 1 concat box_len cover 1 pop - // box_storage/contract.py:153 - // assert key_0 in self.box_map assert - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") - byte "" // box_storage/contract.py:154 // assert self.box_map.key_prefix == b"" + byte "" byte 0x == assert @@ -2070,11 +1610,7 @@ box_map_set: // self.box_map[key] = value frame_dig -2 itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:164 - // self.box_map[key] = value uncover 1 concat dup @@ -2095,11 +1631,7 @@ box_map_get: // return self.box_map[key] frame_dig -1 itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:168 - // return self.box_map[key] uncover 1 concat box_get @@ -2117,11 +1649,7 @@ box_map_del: // del self.box_map[key] frame_dig -1 itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:172 - // del self.box_map[key] uncover 1 concat box_del @@ -2135,346 +1663,16 @@ box_map_exists: // @arc4.abimethod // def box_map_exists(self, key: UInt64) -> bool: proto 1 1 - // box_storage/contract.py:14-176 - // self.box_map = BoxMap(UInt64, String, key_prefix="") - // self.box_ref = BoxRef() - // - // @arc4.abimethod - // def set_boxes(self, a: UInt64, b: arc4.DynamicBytes, c: arc4.String) -> None: - // self.box_a.value = a - // self.box_b.value = b.copy() - // self.box_c.value = c - // self.box_d.value = b.native - // - // b_value = self.box_b.value.copy() - // assert self.box_b.value.length == b_value.length, "direct reference should match copy" - // - // self.box_a.value += 3 - // - // # test .length - // assert self.box_a.length == 8 - // assert self.box_b.length == b.bytes.length - // assert self.box_c.length == c.bytes.length - // assert self.box_d.length == b.native.length - // - // # test .value.bytes - // assert self.box_c.value.bytes[0] == c.bytes[0] - // assert self.box_c.value.bytes[-1] == c.bytes[-1] - // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] - // assert self.box_c.value.bytes[:2] == c.bytes[:2] - // - // # test .value with Bytes type - // assert self.box_d.value[0] == b.native[0] - // assert self.box_d.value[-1] == b.native[-1] - // assert self.box_d.value[:-1] == b.native[:-1] - // assert self.box_d.value[:5] == b.native[:5] - // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] - // - // @arc4.abimethod - // def check_keys(self) -> None: - // assert self.box_a.key == b"box_a", "box a key ok" - // assert self.box_b.key == b"b", "box b key ok" - // assert self.box_c.key == b"BOX_C", "box c key ok" - // - // @arc4.abimethod - // def delete_boxes(self) -> None: - // del self.box_a.value - // del self.box_b.value - // del self.box_c.value - // assert self.box_a.get(default=UInt64(42)) == 42 - // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" - // assert self.box_c.get(default=arc4.String("42")) == "42" - // a, a_exists = self.box_a.maybe() - // assert not a_exists - // assert a == 0 - // - // @arc4.abimethod - // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value - // - // @arc4.abimethod - // def boxes_exist(self) -> tuple[bool, bool, bool]: - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) - // - // @arc4.abimethod - // def slice_box(self) -> None: - // box_0 = Box(Bytes, key=String("0")) - // box_0.value = Bytes(b"Testing testing 123") - // assert box_0.value[0:7] == b"Testing" - // - // self.box_c.value = arc4.String("Hello") - // assert self.box_c.value.bytes[2:10] == b"Hello" - // - // @arc4.abimethod - // def arc4_box(self) -> None: - // box_d = Box(StaticInts, key=Bytes(b"d")) - // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) - // - // assert box_d.value[0] == 0 - // assert box_d.value[1] == 1 - // assert box_d.value[2] == 2 - // assert box_d.value[3] == 3 - // - // @arc4.abimethod - // def test_box_ref(self) -> None: - // # init ref, with valid key types - // box_ref = BoxRef(key="blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=b"blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=Bytes(b"blob")) - // assert not box_ref, "no data" - // box_ref = BoxRef(key=String("blob")) - // assert not box_ref, "no data" - // - // # create - // assert box_ref.create(size=32) - // assert box_ref, "has data" - // - // # manipulate data - // sender_bytes = Txn.sender.bytes - // app_address = Global.current_application_address.bytes - // value_3 = Bytes(b"hello") - // box_ref.replace(0, sender_bytes) - // box_ref.resize(8000) - // box_ref.splice(0, 0, app_address) - // box_ref.replace(64, value_3) - // prefix = box_ref.extract(0, 32 * 2 + value_3.length) - // assert prefix == app_address + sender_bytes + value_3 - // - // # delete - // assert box_ref.delete() - // assert box_ref.key == b"blob" - // - // # query - // value, exists = box_ref.maybe() - // assert not exists - // assert value == b"" - // assert box_ref.get(default=sender_bytes) == sender_bytes - // - // # update - // box_ref.put(sender_bytes + app_address) - // assert box_ref, "Blob exists" - // assert box_ref.length == 64 - // assert get_box_ref_length(box_ref) == 64 - // - // # instance box ref - // self.box_ref.create(size=UInt64(32)) - // assert self.box_ref, "has data" - // self.box_ref.delete() - // - // @arc4.abimethod - // def box_map_test(self) -> None: - // key_0 = UInt64(0) - // key_1 = UInt64(1) - // value = String("Hmmmmm") - // self.box_map[key_0] = value - // assert self.box_map[key_0].bytes.length == value.bytes.length - // assert self.box_map.length(key_0) == value.bytes.length - // - // assert self.box_map.get(key_1, default=String("default")) == String("default") - // value, exists = self.box_map.maybe(key_1) - // assert not exists - // assert key_0 in self.box_map - // assert self.box_map.key_prefix == b"" - // - // # test box map not assigned to the class and passed to subroutine - // tmp_box_map = BoxMap(UInt64, String, key_prefix=Bytes()) - // tmp_box_map[key_1] = String("hello") - // assert get_box_map_value_from_key_plus_1(tmp_box_map, UInt64(0)) == "hello" - // del tmp_box_map[key_1] - // - // @arc4.abimethod - // def box_map_set(self, key: UInt64, value: String) -> None: - // self.box_map[key] = value - // - // @arc4.abimethod - // def box_map_get(self, key: UInt64) -> String: - // return self.box_map[key] - // - // @arc4.abimethod - // def box_map_del(self, key: UInt64) -> None: - // del self.box_map[key] - // - // @arc4.abimethod - // def box_map_exists(self, key: UInt64) -> bool: - // return key in self.box_map + // box_storage/contract.py:176 + // return key in self.box_map frame_dig -1 itob - // box_storage/contract.py:14 - // self.box_map = BoxMap(UInt64, String, key_prefix="") byte "" - // box_storage/contract.py:14-176 - // self.box_map = BoxMap(UInt64, String, key_prefix="") - // self.box_ref = BoxRef() - // - // @arc4.abimethod - // def set_boxes(self, a: UInt64, b: arc4.DynamicBytes, c: arc4.String) -> None: - // self.box_a.value = a - // self.box_b.value = b.copy() - // self.box_c.value = c - // self.box_d.value = b.native - // - // b_value = self.box_b.value.copy() - // assert self.box_b.value.length == b_value.length, "direct reference should match copy" - // - // self.box_a.value += 3 - // - // # test .length - // assert self.box_a.length == 8 - // assert self.box_b.length == b.bytes.length - // assert self.box_c.length == c.bytes.length - // assert self.box_d.length == b.native.length - // - // # test .value.bytes - // assert self.box_c.value.bytes[0] == c.bytes[0] - // assert self.box_c.value.bytes[-1] == c.bytes[-1] - // assert self.box_c.value.bytes[:-1] == c.bytes[:-1] - // assert self.box_c.value.bytes[:2] == c.bytes[:2] - // - // # test .value with Bytes type - // assert self.box_d.value[0] == b.native[0] - // assert self.box_d.value[-1] == b.native[-1] - // assert self.box_d.value[:-1] == b.native[:-1] - // assert self.box_d.value[:5] == b.native[:5] - // assert self.box_d.value[: UInt64(2)] == b.native[: UInt64(2)] - // - // @arc4.abimethod - // def check_keys(self) -> None: - // assert self.box_a.key == b"box_a", "box a key ok" - // assert self.box_b.key == b"b", "box b key ok" - // assert self.box_c.key == b"BOX_C", "box c key ok" - // - // @arc4.abimethod - // def delete_boxes(self) -> None: - // del self.box_a.value - // del self.box_b.value - // del self.box_c.value - // assert self.box_a.get(default=UInt64(42)) == 42 - // assert self.box_b.get(default=arc4.DynamicBytes(b"42")).native == b"42" - // assert self.box_c.get(default=arc4.String("42")) == "42" - // a, a_exists = self.box_a.maybe() - // assert not a_exists - // assert a == 0 - // - // @arc4.abimethod - // def read_boxes(self) -> tuple[UInt64, Bytes, arc4.String]: - // return get_box_value_plus_1(self.box_a) - 1, self.box_b.value.native, self.box_c.value - // - // @arc4.abimethod - // def boxes_exist(self) -> tuple[bool, bool, bool]: - // return bool(self.box_a), bool(self.box_b), bool(self.box_c) - // - // @arc4.abimethod - // def slice_box(self) -> None: - // box_0 = Box(Bytes, key=String("0")) - // box_0.value = Bytes(b"Testing testing 123") - // assert box_0.value[0:7] == b"Testing" - // - // self.box_c.value = arc4.String("Hello") - // assert self.box_c.value.bytes[2:10] == b"Hello" - // - // @arc4.abimethod - // def arc4_box(self) -> None: - // box_d = Box(StaticInts, key=Bytes(b"d")) - // box_d.value = StaticInts(arc4.UInt8(0), arc4.UInt8(1), arc4.UInt8(2), arc4.UInt8(3)) - // - // assert box_d.value[0] == 0 - // assert box_d.value[1] == 1 - // assert box_d.value[2] == 2 - // assert box_d.value[3] == 3 - // - // @arc4.abimethod - // def test_box_ref(self) -> None: - // # init ref, with valid key types - // box_ref = BoxRef(key="blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=b"blob") - // assert not box_ref, "no data" - // box_ref = BoxRef(key=Bytes(b"blob")) - // assert not box_ref, "no data" - // box_ref = BoxRef(key=String("blob")) - // assert not box_ref, "no data" - // - // # create - // assert box_ref.create(size=32) - // assert box_ref, "has data" - // - // # manipulate data - // sender_bytes = Txn.sender.bytes - // app_address = Global.current_application_address.bytes - // value_3 = Bytes(b"hello") - // box_ref.replace(0, sender_bytes) - // box_ref.resize(8000) - // box_ref.splice(0, 0, app_address) - // box_ref.replace(64, value_3) - // prefix = box_ref.extract(0, 32 * 2 + value_3.length) - // assert prefix == app_address + sender_bytes + value_3 - // - // # delete - // assert box_ref.delete() - // assert box_ref.key == b"blob" - // - // # query - // value, exists = box_ref.maybe() - // assert not exists - // assert value == b"" - // assert box_ref.get(default=sender_bytes) == sender_bytes - // - // # update - // box_ref.put(sender_bytes + app_address) - // assert box_ref, "Blob exists" - // assert box_ref.length == 64 - // assert get_box_ref_length(box_ref) == 64 - // - // # instance box ref - // self.box_ref.create(size=UInt64(32)) - // assert self.box_ref, "has data" - // self.box_ref.delete() - // - // @arc4.abimethod - // def box_map_test(self) -> None: - // key_0 = UInt64(0) - // key_1 = UInt64(1) - // value = String("Hmmmmm") - // self.box_map[key_0] = value - // assert self.box_map[key_0].bytes.length == value.bytes.length - // assert self.box_map.length(key_0) == value.bytes.length - // - // assert self.box_map.get(key_1, default=String("default")) == String("default") - // value, exists = self.box_map.maybe(key_1) - // assert not exists - // assert key_0 in self.box_map - // assert self.box_map.key_prefix == b"" - // - // # test box map not assigned to the class and passed to subroutine - // tmp_box_map = BoxMap(UInt64, String, key_prefix=Bytes()) - // tmp_box_map[key_1] = String("hello") - // assert get_box_map_value_from_key_plus_1(tmp_box_map, UInt64(0)) == "hello" - // del tmp_box_map[key_1] - // - // @arc4.abimethod - // def box_map_set(self, key: UInt64, value: String) -> None: - // self.box_map[key] = value - // - // @arc4.abimethod - // def box_map_get(self, key: UInt64) -> String: - // return self.box_map[key] - // - // @arc4.abimethod - // def box_map_del(self, key: UInt64) -> None: - // del self.box_map[key] - // - // @arc4.abimethod - // def box_map_exists(self, key: UInt64) -> bool: - // return key in self.box_map uncover 1 concat box_len cover 1 pop - // box_storage/contract.py:176 - // return key in self.box_map retsub diff --git a/examples/global_state/out/AppStateContract.approval.mir b/examples/global_state/out/AppStateContract.approval.mir index 92db086f95..eb65539de9 100644 --- a/examples/global_state/out/AppStateContract.approval.mir +++ b/examples/global_state/out/AppStateContract.approval.mir @@ -16,7 +16,7 @@ main_on_create@1: main_entrypoint@2: int 0 // 0 self.global_int_simplified global_state/contract.py:33 - byte "global_int_simplified" // 0,"global_int_simplified" self.global_int_simplified global_state/contract.py:17 + byte "global_int_simplified" // 0,"global_int_simplified" self.global_int_simplified global_state/contract.py:33 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_int_simplified global_state/contract.py:33 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.global_int_simplified global_state/contract.py:33 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.global_int_simplified global_state/contract.py:33 @@ -29,14 +29,14 @@ main_entrypoint@2: // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 assert self.global_int_simplified == 33 global_state/contract.py:33 assert // assert self.global_int_simplified == 33 global_state/contract.py:33 int 0 // 0 self.global_int_full global_state/contract.py:34 - byte "global_int_full" // 0,"global_int_full" self.global_int_full global_state/contract.py:16 + byte "global_int_full" // 0,"global_int_full" self.global_int_full global_state/contract.py:34 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_int_full global_state/contract.py:34 cover 1 // store maybe_exists%1#0 to l-stack (no copy) maybe_exists%1#0,{app_global_get_ex}.0 self.global_int_full global_state/contract.py:34 pop // maybe_exists%1#0 self.global_int_full global_state/contract.py:34 // virtual: load maybe_exists%1#0 from l-stack (no copy) maybe_exists%1#0 assert self.global_int_full global_state/contract.py:34 assert // assert self.global_int_full global_state/contract.py:34 int 0 // 0 self.global_int_full.value global_state/contract.py:35 - byte "global_int_full" // 0,"global_int_full" self.global_int_full global_state/contract.py:16 + byte "global_int_full" // 0,"global_int_full" self.global_int_full global_state/contract.py:35 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_int_full.value global_state/contract.py:35 // virtual: store maybe_exists%2#0 to l-stack (no copy) maybe_exists%2#0,{app_global_get_ex}.0 self.global_int_full.value global_state/contract.py:35 // virtual: store maybe_value%2#0 to l-stack (no copy) maybe_value%2#0,maybe_exists%2#0 self.global_int_full.value global_state/contract.py:35 @@ -49,7 +49,7 @@ main_entrypoint@2: // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 assert self.global_int_full.value == 55 global_state/contract.py:35 assert // assert self.global_int_full.value == 55 global_state/contract.py:35 int 0 // 0 not self.global_int_no_default global_state/contract.py:36 - byte "global_int_no_default" // 0,"global_int_no_default" self.global_int_no_default global_state/contract.py:18 + byte "global_int_no_default" // 0,"global_int_no_default" self.global_int_no_default global_state/contract.py:36 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 not self.global_int_no_default global_state/contract.py:36 cover 1 // store maybe_exists%3#0 to l-stack (no copy) maybe_exists%3#0,{app_global_get_ex}.0 not self.global_int_no_default global_state/contract.py:36 pop // maybe_exists%3#0 not self.global_int_no_default global_state/contract.py:36 @@ -58,11 +58,11 @@ main_entrypoint@2: // virtual: store tmp%2#0 to l-stack (no copy) tmp%2#0 not self.global_int_no_default global_state/contract.py:36 // virtual: load tmp%2#0 from l-stack (no copy) tmp%2#0 assert not self.global_int_no_default global_state/contract.py:36 assert // assert not self.global_int_no_default global_state/contract.py:36 - byte "global_int_no_default" // "global_int_no_default" self.global_int_no_default global_state/contract.py:18 + byte "global_int_no_default" // "global_int_no_default" self.global_int_no_default global_state/contract.py:37 int 44 // "global_int_no_default",44 UInt64(44) global_state/contract.py:37 app_global_put // self.global_int_no_default.value = UInt64(44) global_state/contract.py:37 int 0 // 0 self.global_int_no_default.maybe global_state/contract.py:38 - byte "global_int_no_default" // 0,"global_int_no_default" self.global_int_no_default global_state/contract.py:18 + byte "global_int_no_default" // 0,"global_int_no_default" self.global_int_no_default global_state/contract.py:38 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_int_no_default.maybe() global_state/contract.py:38 // virtual: store i_exists#0 to l-stack (no copy) i_exists#0,{app_global_get_ex}.0 self.global_int_no_default.maybe() global_state/contract.py:38 // virtual: store i_value#0 to l-stack (no copy) i_value#0,i_exists#0 self.global_int_no_default.maybe() global_state/contract.py:38 @@ -84,7 +84,7 @@ main_entrypoint@2: // virtual: load tmp%5#0 from l-stack (no copy) tmp%5#0 assert read_global_uint64(Bytes(b"global_int_no_default")) == 44 global_state/contract.py:41 assert // assert read_global_uint64(Bytes(b"global_int_no_default")) == 44 global_state/contract.py:41 int 0 // 0 self.global_bytes_simplified global_state/contract.py:43 - byte "global_bytes_simplified" // 0,"global_bytes_simplified" self.global_bytes_simplified global_state/contract.py:21 + byte "global_bytes_simplified" // 0,"global_bytes_simplified" self.global_bytes_simplified global_state/contract.py:43 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_simplified global_state/contract.py:43 // virtual: store maybe_exists%5#0 to l-stack (no copy) maybe_exists%5#0,{app_global_get_ex}.0 self.global_bytes_simplified global_state/contract.py:43 // virtual: store maybe_value%5#0 to l-stack (no copy) maybe_value%5#0,maybe_exists%5#0 self.global_bytes_simplified global_state/contract.py:43 @@ -97,14 +97,14 @@ main_entrypoint@2: // virtual: load tmp%6#0 from l-stack (no copy) tmp%6#0 assert self.global_bytes_simplified == b"Hello" global_state/contract.py:43 assert // assert self.global_bytes_simplified == b"Hello" global_state/contract.py:43 int 0 // 0 self.global_bytes_full global_state/contract.py:44 - byte "global_bytes_full" // 0,"global_bytes_full" self.global_bytes_full global_state/contract.py:20 + byte "global_bytes_full" // 0,"global_bytes_full" self.global_bytes_full global_state/contract.py:44 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_full global_state/contract.py:44 cover 1 // store maybe_exists%6#0 to l-stack (no copy) maybe_exists%6#0,{app_global_get_ex}.0 self.global_bytes_full global_state/contract.py:44 pop // maybe_exists%6#0 self.global_bytes_full global_state/contract.py:44 // virtual: load maybe_exists%6#0 from l-stack (no copy) maybe_exists%6#0 assert self.global_bytes_full global_state/contract.py:44 assert // assert self.global_bytes_full global_state/contract.py:44 int 0 // 0 self.global_bytes_full.value global_state/contract.py:45 - byte "global_bytes_full" // 0,"global_bytes_full" self.global_bytes_full global_state/contract.py:20 + byte "global_bytes_full" // 0,"global_bytes_full" self.global_bytes_full global_state/contract.py:45 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_full.value global_state/contract.py:45 // virtual: store maybe_exists%7#0 to l-stack (no copy) maybe_exists%7#0,{app_global_get_ex}.0 self.global_bytes_full.value global_state/contract.py:45 // virtual: store maybe_value%7#0 to l-stack (no copy) maybe_value%7#0,maybe_exists%7#0 self.global_bytes_full.value global_state/contract.py:45 @@ -117,7 +117,7 @@ main_entrypoint@2: // virtual: load tmp%7#0 from l-stack (no copy) tmp%7#0 assert self.global_bytes_full.value == b"Hello" global_state/contract.py:45 assert // assert self.global_bytes_full.value == b"Hello" global_state/contract.py:45 int 0 // 0 self.global_bytes_full.get global_state/contract.py:46 - byte "global_bytes_full" // 0,"global_bytes_full" self.global_bytes_full global_state/contract.py:20 + byte "global_bytes_full" // 0,"global_bytes_full" self.global_bytes_full global_state/contract.py:46 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_full.get(Bytes(b"default")) global_state/contract.py:46 cover 1 // store maybe_exists%8#0 to l-stack (no copy) maybe_exists%8#0,{app_global_get_ex}.0 self.global_bytes_full.get(Bytes(b"default")) global_state/contract.py:46 // virtual: store maybe_value%8#0 to l-stack (no copy) maybe_exists%8#0,maybe_value%8#0 self.global_bytes_full.get(Bytes(b"default")) global_state/contract.py:46 @@ -133,7 +133,7 @@ main_entrypoint@2: // virtual: load tmp%9#0 from l-stack (no copy) tmp%9#0 assert self.global_bytes_full.get(Bytes(b"default")) == b"Hello" global_state/contract.py:46 assert // assert self.global_bytes_full.get(Bytes(b"default")) == b"Hello" global_state/contract.py:46 int 0 // 0 not self.global_bytes_no_default global_state/contract.py:47 - byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:22 + byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:47 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 not self.global_bytes_no_default global_state/contract.py:47 cover 1 // store maybe_exists%9#0 to l-stack (no copy) maybe_exists%9#0,{app_global_get_ex}.0 not self.global_bytes_no_default global_state/contract.py:47 pop // maybe_exists%9#0 not self.global_bytes_no_default global_state/contract.py:47 @@ -142,11 +142,11 @@ main_entrypoint@2: // virtual: store tmp%10#0 to l-stack (no copy) tmp%10#0 not self.global_bytes_no_default global_state/contract.py:47 // virtual: load tmp%10#0 from l-stack (no copy) tmp%10#0 assert not self.global_bytes_no_default global_state/contract.py:47 assert // assert not self.global_bytes_no_default global_state/contract.py:47 - byte "global_bytes_no_default" // "global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:22 + byte "global_bytes_no_default" // "global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:48 byte 0x576f726c64 // "global_bytes_no_default",0x576f726c64 Bytes(b"World") global_state/contract.py:48 app_global_put // self.global_bytes_no_default.value = Bytes(b"World") global_state/contract.py:48 int 0 // 0 self.global_bytes_no_default.maybe global_state/contract.py:49 - byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:22 + byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:49 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_no_default.maybe() global_state/contract.py:49 // virtual: store b_exists#0 to l-stack (no copy) b_exists#0,{app_global_get_ex}.0 self.global_bytes_no_default.maybe() global_state/contract.py:49 // virtual: store b_value#0 to l-stack (no copy) b_value#0,b_exists#0 self.global_bytes_no_default.maybe() global_state/contract.py:49 @@ -167,10 +167,10 @@ main_entrypoint@2: // virtual: store tmp%13#0 to l-stack (no copy) tmp%13#0 read_global_bytes(String("global_bytes_no_default")) == b"World" global_state/contract.py:52 // virtual: load tmp%13#0 from l-stack (no copy) tmp%13#0 assert read_global_bytes(String("global_bytes_no_default")) == b"World" global_state/contract.py:52 assert // assert read_global_bytes(String("global_bytes_no_default")) == b"World" global_state/contract.py:52 - byte "global_bytes_no_default" // "global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:22 + byte "global_bytes_no_default" // "global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:53 app_global_del // del self.global_bytes_no_default.value global_state/contract.py:53 int 0 // 0 self.global_bytes_no_default.maybe global_state/contract.py:54 - byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:22 + byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:54 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_no_default.maybe() global_state/contract.py:54 cover 1 // store b_exists#0 to l-stack (no copy) b_exists#0,{app_global_get_ex}.0 self.global_bytes_no_default.maybe() global_state/contract.py:54 pop // b_exists#0 self.global_bytes_no_default.maybe() global_state/contract.py:54 @@ -180,7 +180,7 @@ main_entrypoint@2: // virtual: load tmp%14#0 from l-stack (no copy) tmp%14#0 assert not b_exists global_state/contract.py:55 assert // assert not b_exists global_state/contract.py:55 int 0 // 0 self.global_bytes_no_default.get global_state/contract.py:57 - byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:22 + byte "global_bytes_no_default" // 0,"global_bytes_no_default" self.global_bytes_no_default global_state/contract.py:57 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes_no_default.get(Bytes(b"default")) global_state/contract.py:57 cover 1 // store maybe_exists%12#0 to l-stack (no copy) maybe_exists%12#0,{app_global_get_ex}.0 self.global_bytes_no_default.get(Bytes(b"default")) global_state/contract.py:57 // virtual: store maybe_value%12#0 to l-stack (no copy) maybe_exists%12#0,maybe_value%12#0 self.global_bytes_no_default.get(Bytes(b"default")) global_state/contract.py:57 @@ -196,14 +196,14 @@ main_entrypoint@2: // virtual: load tmp%16#0 from l-stack (no copy) tmp%16#0 assert self.global_bytes_no_default.get(Bytes(b"default")) == b"default" global_state/contract.py:57 assert // assert self.global_bytes_no_default.get(Bytes(b"default")) == b"default" global_state/contract.py:57 int 0 // 0 t 'is set'\nassert self.global_bool_full global_state/contract.py:59-60 - byte "global_bool_full" // 0,"global_bool_full" self.global_bool_full global_state/contract.py:24 + byte "global_bool_full" // 0,"global_bool_full" t 'is set'\nassert self.global_bool_full global_state/contract.py:59-60 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 t 'is set'\nassert self.global_bool_full global_state/contract.py:59-60 cover 1 // store maybe_exists%13#0 to l-stack (no copy) maybe_exists%13#0,{app_global_get_ex}.0 t 'is set'\nassert self.global_bool_full global_state/contract.py:59-60 pop // maybe_exists%13#0 t 'is set'\nassert self.global_bool_full global_state/contract.py:59-60 // virtual: load maybe_exists%13#0 from l-stack (no copy) maybe_exists%13#0 # Assert 'is set'\nassert self.global_bool_full global_state/contract.py:59-60 assert // # Assert 'is set'\nassert self.global_bool_full global_state/contract.py:59-60 int 0 // 0 not self.global_bool_no_default global_state/contract.py:61 - byte "global_bool_no_default" // 0,"global_bool_no_default" self.global_bool_no_default global_state/contract.py:26 + byte "global_bool_no_default" // 0,"global_bool_no_default" self.global_bool_no_default global_state/contract.py:61 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 not self.global_bool_no_default global_state/contract.py:61 cover 1 // store maybe_exists%14#0 to l-stack (no copy) maybe_exists%14#0,{app_global_get_ex}.0 not self.global_bool_no_default global_state/contract.py:61 pop // maybe_exists%14#0 not self.global_bool_no_default global_state/contract.py:61 @@ -212,11 +212,11 @@ main_entrypoint@2: // virtual: store tmp%17#0 to l-stack (no copy) tmp%17#0 not self.global_bool_no_default global_state/contract.py:61 // virtual: load tmp%17#0 from l-stack (no copy) tmp%17#0 assert not self.global_bool_no_default global_state/contract.py:61 assert // assert not self.global_bool_no_default global_state/contract.py:61 - byte "global_bool_no_default" // "global_bool_no_default" self.global_bool_no_default global_state/contract.py:26 + byte "global_bool_no_default" // "global_bool_no_default" self.global_bool_no_default global_state/contract.py:63 int 1 // "global_bool_no_default",1 True global_state/contract.py:63 app_global_put // self.global_bool_no_default.value = True global_state/contract.py:63 int 0 // 0 alue'\nassert not self.global_bool_full.value global_state/contract.py:65-66 - byte "global_bool_full" // 0,"global_bool_full" self.global_bool_full global_state/contract.py:24 + byte "global_bool_full" // 0,"global_bool_full" alue'\nassert not self.global_bool_full global_state/contract.py:65-66 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 alue'\nassert not self.global_bool_full.value global_state/contract.py:65-66 // virtual: store maybe_exists%15#0 to l-stack (no copy) maybe_exists%15#0,{app_global_get_ex}.0 alue'\nassert not self.global_bool_full.value global_state/contract.py:65-66 // virtual: store maybe_value%15#0 to l-stack (no copy) maybe_value%15#0,maybe_exists%15#0 alue'\nassert not self.global_bool_full.value global_state/contract.py:65-66 @@ -228,7 +228,7 @@ main_entrypoint@2: // virtual: load tmp%18#0 from l-stack (no copy) tmp%18#0 # Assert 'value'\nassert not self.global_bool_full.value global_state/contract.py:65-66 assert // # Assert 'value'\nassert not self.global_bool_full.value global_state/contract.py:65-66 int 0 // 0 self.global_bool_simplified global_state/contract.py:67 - byte "global_bool_simplified" // 0,"global_bool_simplified" self.global_bool_simplified global_state/contract.py:25 + byte "global_bool_simplified" // 0,"global_bool_simplified" self.global_bool_simplified global_state/contract.py:67 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bool_simplified global_state/contract.py:67 // virtual: store maybe_exists%16#0 to l-stack (no copy) maybe_exists%16#0,{app_global_get_ex}.0 self.global_bool_simplified global_state/contract.py:67 // virtual: store maybe_value%16#0 to l-stack (no copy) maybe_value%16#0,maybe_exists%16#0 self.global_bool_simplified global_state/contract.py:67 @@ -237,7 +237,7 @@ main_entrypoint@2: // virtual: load maybe_value%16#0 from l-stack (no copy) maybe_value%16#0 assert self.global_bool_simplified global_state/contract.py:67 assert // assert self.global_bool_simplified global_state/contract.py:67 int 0 // 0 self.global_bool_no_default.value global_state/contract.py:68 - byte "global_bool_no_default" // 0,"global_bool_no_default" self.global_bool_no_default global_state/contract.py:26 + byte "global_bool_no_default" // 0,"global_bool_no_default" self.global_bool_no_default global_state/contract.py:68 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bool_no_default.value global_state/contract.py:68 // virtual: store maybe_exists%17#0 to l-stack (no copy) maybe_exists%17#0,{app_global_get_ex}.0 self.global_bool_no_default.value global_state/contract.py:68 // virtual: store maybe_value%17#0 to l-stack (no copy) maybe_value%17#0,maybe_exists%17#0 self.global_bool_no_default.value global_state/contract.py:68 @@ -245,7 +245,7 @@ main_entrypoint@2: assert // check self.global_bool_no_default exists // maybe_value%17#0 self.global_bool_no_default.value global_state/contract.py:68 // virtual: load maybe_value%17#0 from l-stack (no copy) maybe_value%17#0 assert self.global_bool_no_default.value global_state/contract.py:68 assert // assert self.global_bool_no_default.value global_state/contract.py:68 - byte "global_int_no_default" // "global_int_no_default" self.global_int_no_default global_state/contract.py:18 + byte "global_int_no_default" // "global_int_no_default" as an argument\nassert get_global_state_plus_1(self.global_int_no_default global_state/contract.py:70-71 callsub get_global_state_plus_1 // {get_global_state_plus_1} the proxy can be passed as an argument\nassert get_global_state_plus_1(self.global_int_no_default) global_state/contract.py:70-71 // virtual: store tmp%19#0 to l-stack (no copy) tmp%19#0 the proxy can be passed as an argument\nassert get_global_state_plus_1(self.global_int_no_default) global_state/contract.py:70-71 // virtual: load tmp%19#0 from l-stack (no copy) tmp%19#0 the proxy can be passed as an argument\nassert get_global_state_plus_1(self.global_int_no_default... global_state/contract.py:70-71 diff --git a/examples/global_state/out/AppStateContract.approval.teal b/examples/global_state/out/AppStateContract.approval.teal index d666ddc540..520400ad89 100644 --- a/examples/global_state/out/AppStateContract.approval.teal +++ b/examples/global_state/out/AppStateContract.approval.teal @@ -9,11 +9,7 @@ main_entrypoint@2: // global_state/contract.py:33 // assert self.global_int_simplified == 33 int 0 - // global_state/contract.py:17 - // self.global_int_simplified = UInt64(33) byte "global_int_simplified" - // global_state/contract.py:33 - // assert self.global_int_simplified == 33 app_global_get_ex assert // check self.global_int_simplified exists int 33 @@ -22,22 +18,14 @@ main_entrypoint@2: // global_state/contract.py:34 // assert self.global_int_full int 0 - // global_state/contract.py:16 - // self.global_int_full = GlobalState(UInt64(55)) byte "global_int_full" - // global_state/contract.py:34 - // assert self.global_int_full app_global_get_ex bury 1 assert // global_state/contract.py:35 // assert self.global_int_full.value == 55 int 0 - // global_state/contract.py:16 - // self.global_int_full = GlobalState(UInt64(55)) byte "global_int_full" - // global_state/contract.py:35 - // assert self.global_int_full.value == 55 app_global_get_ex assert // check self.global_int_full exists int 55 @@ -46,30 +34,20 @@ main_entrypoint@2: // global_state/contract.py:36 // assert not self.global_int_no_default int 0 - // global_state/contract.py:18 - // self.global_int_no_default = GlobalState(UInt64) byte "global_int_no_default" - // global_state/contract.py:36 - // assert not self.global_int_no_default app_global_get_ex bury 1 ! assert - // global_state/contract.py:18 - // self.global_int_no_default = GlobalState(UInt64) - byte "global_int_no_default" // global_state/contract.py:37 // self.global_int_no_default.value = UInt64(44) + byte "global_int_no_default" int 44 app_global_put // global_state/contract.py:38 // i_value, i_exists = self.global_int_no_default.maybe() int 0 - // global_state/contract.py:18 - // self.global_int_no_default = GlobalState(UInt64) byte "global_int_no_default" - // global_state/contract.py:38 - // i_value, i_exists = self.global_int_no_default.maybe() app_global_get_ex // global_state/contract.py:39 // assert i_exists @@ -89,11 +67,7 @@ main_entrypoint@2: // global_state/contract.py:43 // assert self.global_bytes_simplified == b"Hello" int 0 - // global_state/contract.py:21 - // self.global_bytes_simplified = Bytes(b"Hello") byte "global_bytes_simplified" - // global_state/contract.py:43 - // assert self.global_bytes_simplified == b"Hello" app_global_get_ex assert // check self.global_bytes_simplified exists byte 0x48656c6c6f @@ -102,22 +76,14 @@ main_entrypoint@2: // global_state/contract.py:44 // assert self.global_bytes_full int 0 - // global_state/contract.py:20 - // self.global_bytes_full = GlobalState(Bytes(b"Hello")) byte "global_bytes_full" - // global_state/contract.py:44 - // assert self.global_bytes_full app_global_get_ex bury 1 assert // global_state/contract.py:45 // assert self.global_bytes_full.value == b"Hello" int 0 - // global_state/contract.py:20 - // self.global_bytes_full = GlobalState(Bytes(b"Hello")) byte "global_bytes_full" - // global_state/contract.py:45 - // assert self.global_bytes_full.value == b"Hello" app_global_get_ex assert // check self.global_bytes_full exists byte 0x48656c6c6f @@ -126,11 +92,7 @@ main_entrypoint@2: // global_state/contract.py:46 // assert self.global_bytes_full.get(Bytes(b"default")) == b"Hello" int 0 - // global_state/contract.py:20 - // self.global_bytes_full = GlobalState(Bytes(b"Hello")) byte "global_bytes_full" - // global_state/contract.py:46 - // assert self.global_bytes_full.get(Bytes(b"default")) == b"Hello" app_global_get_ex byte 0x64656661756c74 cover 2 @@ -141,30 +103,20 @@ main_entrypoint@2: // global_state/contract.py:47 // assert not self.global_bytes_no_default int 0 - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) byte "global_bytes_no_default" - // global_state/contract.py:47 - // assert not self.global_bytes_no_default app_global_get_ex bury 1 ! assert - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) - byte "global_bytes_no_default" // global_state/contract.py:48 // self.global_bytes_no_default.value = Bytes(b"World") + byte "global_bytes_no_default" byte 0x576f726c64 app_global_put // global_state/contract.py:49 // b_value, b_exists = self.global_bytes_no_default.maybe() int 0 - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) byte "global_bytes_no_default" - // global_state/contract.py:49 - // b_value, b_exists = self.global_bytes_no_default.maybe() app_global_get_ex // global_state/contract.py:50 // assert b_exists @@ -181,20 +133,14 @@ main_entrypoint@2: byte 0x576f726c64 == assert - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) - byte "global_bytes_no_default" // global_state/contract.py:53 // del self.global_bytes_no_default.value + byte "global_bytes_no_default" app_global_del // global_state/contract.py:54 // b_value, b_exists = self.global_bytes_no_default.maybe() int 0 - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) byte "global_bytes_no_default" - // global_state/contract.py:54 - // b_value, b_exists = self.global_bytes_no_default.maybe() app_global_get_ex bury 1 // global_state/contract.py:55 @@ -204,11 +150,7 @@ main_entrypoint@2: // global_state/contract.py:57 // assert self.global_bytes_no_default.get(Bytes(b"default")) == b"default" int 0 - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) byte "global_bytes_no_default" - // global_state/contract.py:57 - // assert self.global_bytes_no_default.get(Bytes(b"default")) == b"default" app_global_get_ex byte 0x64656661756c74 cover 2 @@ -220,44 +162,28 @@ main_entrypoint@2: // # Assert 'is set' // assert self.global_bool_full int 0 - // global_state/contract.py:24 - // self.global_bool_full = GlobalState(False) byte "global_bool_full" - // global_state/contract.py:59-60 - // # Assert 'is set' - // assert self.global_bool_full app_global_get_ex bury 1 assert // global_state/contract.py:61 // assert not self.global_bool_no_default int 0 - // global_state/contract.py:26 - // self.global_bool_no_default = GlobalState(bool) byte "global_bool_no_default" - // global_state/contract.py:61 - // assert not self.global_bool_no_default app_global_get_ex bury 1 ! assert - // global_state/contract.py:26 - // self.global_bool_no_default = GlobalState(bool) - byte "global_bool_no_default" // global_state/contract.py:63 // self.global_bool_no_default.value = True + byte "global_bool_no_default" int 1 app_global_put // global_state/contract.py:65-66 // # Assert 'value' // assert not self.global_bool_full.value int 0 - // global_state/contract.py:24 - // self.global_bool_full = GlobalState(False) byte "global_bool_full" - // global_state/contract.py:65-66 - // # Assert 'value' - // assert not self.global_bool_full.value app_global_get_ex assert // check self.global_bool_full exists ! @@ -265,31 +191,21 @@ main_entrypoint@2: // global_state/contract.py:67 // assert self.global_bool_simplified int 0 - // global_state/contract.py:25 - // self.global_bool_simplified = True byte "global_bool_simplified" - // global_state/contract.py:67 - // assert self.global_bool_simplified app_global_get_ex assert // check self.global_bool_simplified exists assert // global_state/contract.py:68 // assert self.global_bool_no_default.value int 0 - // global_state/contract.py:26 - // self.global_bool_no_default = GlobalState(bool) byte "global_bool_no_default" - // global_state/contract.py:68 - // assert self.global_bool_no_default.value app_global_get_ex assert // check self.global_bool_no_default exists assert - // global_state/contract.py:18 - // self.global_int_no_default = GlobalState(UInt64) - byte "global_int_no_default" // global_state/contract.py:70-71 // # test the proxy can be passed as an argument // assert get_global_state_plus_1(self.global_int_no_default) == 45 + byte "global_int_no_default" callsub get_global_state_plus_1 int 45 == diff --git a/examples/global_state/out_unoptimized/AppStateContract.approval.teal b/examples/global_state/out_unoptimized/AppStateContract.approval.teal index 9cf12f6b3c..5b93f4e7dd 100644 --- a/examples/global_state/out_unoptimized/AppStateContract.approval.teal +++ b/examples/global_state/out_unoptimized/AppStateContract.approval.teal @@ -9,11 +9,7 @@ main_entrypoint@2: // global_state/contract.py:33 // assert self.global_int_simplified == 33 int 0 - // global_state/contract.py:17 - // self.global_int_simplified = UInt64(33) byte "global_int_simplified" - // global_state/contract.py:33 - // assert self.global_int_simplified == 33 app_global_get_ex assert // check self.global_int_simplified exists int 33 @@ -22,11 +18,7 @@ main_entrypoint@2: // global_state/contract.py:34 // assert self.global_int_full int 0 - // global_state/contract.py:16 - // self.global_int_full = GlobalState(UInt64(55)) byte "global_int_full" - // global_state/contract.py:34 - // assert self.global_int_full app_global_get_ex cover 1 pop @@ -34,11 +26,7 @@ main_entrypoint@2: // global_state/contract.py:35 // assert self.global_int_full.value == 55 int 0 - // global_state/contract.py:16 - // self.global_int_full = GlobalState(UInt64(55)) byte "global_int_full" - // global_state/contract.py:35 - // assert self.global_int_full.value == 55 app_global_get_ex assert // check self.global_int_full exists int 55 @@ -47,31 +35,21 @@ main_entrypoint@2: // global_state/contract.py:36 // assert not self.global_int_no_default int 0 - // global_state/contract.py:18 - // self.global_int_no_default = GlobalState(UInt64) byte "global_int_no_default" - // global_state/contract.py:36 - // assert not self.global_int_no_default app_global_get_ex cover 1 pop ! assert - // global_state/contract.py:18 - // self.global_int_no_default = GlobalState(UInt64) - byte "global_int_no_default" // global_state/contract.py:37 // self.global_int_no_default.value = UInt64(44) + byte "global_int_no_default" int 44 app_global_put // global_state/contract.py:38 // i_value, i_exists = self.global_int_no_default.maybe() int 0 - // global_state/contract.py:18 - // self.global_int_no_default = GlobalState(UInt64) byte "global_int_no_default" - // global_state/contract.py:38 - // i_value, i_exists = self.global_int_no_default.maybe() app_global_get_ex // global_state/contract.py:39 // assert i_exists @@ -91,11 +69,7 @@ main_entrypoint@2: // global_state/contract.py:43 // assert self.global_bytes_simplified == b"Hello" int 0 - // global_state/contract.py:21 - // self.global_bytes_simplified = Bytes(b"Hello") byte "global_bytes_simplified" - // global_state/contract.py:43 - // assert self.global_bytes_simplified == b"Hello" app_global_get_ex assert // check self.global_bytes_simplified exists byte 0x48656c6c6f @@ -104,11 +78,7 @@ main_entrypoint@2: // global_state/contract.py:44 // assert self.global_bytes_full int 0 - // global_state/contract.py:20 - // self.global_bytes_full = GlobalState(Bytes(b"Hello")) byte "global_bytes_full" - // global_state/contract.py:44 - // assert self.global_bytes_full app_global_get_ex cover 1 pop @@ -116,11 +86,7 @@ main_entrypoint@2: // global_state/contract.py:45 // assert self.global_bytes_full.value == b"Hello" int 0 - // global_state/contract.py:20 - // self.global_bytes_full = GlobalState(Bytes(b"Hello")) byte "global_bytes_full" - // global_state/contract.py:45 - // assert self.global_bytes_full.value == b"Hello" app_global_get_ex assert // check self.global_bytes_full exists byte 0x48656c6c6f @@ -129,11 +95,7 @@ main_entrypoint@2: // global_state/contract.py:46 // assert self.global_bytes_full.get(Bytes(b"default")) == b"Hello" int 0 - // global_state/contract.py:20 - // self.global_bytes_full = GlobalState(Bytes(b"Hello")) byte "global_bytes_full" - // global_state/contract.py:46 - // assert self.global_bytes_full.get(Bytes(b"default")) == b"Hello" app_global_get_ex cover 1 byte 0x64656661756c74 @@ -146,31 +108,21 @@ main_entrypoint@2: // global_state/contract.py:47 // assert not self.global_bytes_no_default int 0 - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) byte "global_bytes_no_default" - // global_state/contract.py:47 - // assert not self.global_bytes_no_default app_global_get_ex cover 1 pop ! assert - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) - byte "global_bytes_no_default" // global_state/contract.py:48 // self.global_bytes_no_default.value = Bytes(b"World") + byte "global_bytes_no_default" byte 0x576f726c64 app_global_put // global_state/contract.py:49 // b_value, b_exists = self.global_bytes_no_default.maybe() int 0 - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) byte "global_bytes_no_default" - // global_state/contract.py:49 - // b_value, b_exists = self.global_bytes_no_default.maybe() app_global_get_ex // global_state/contract.py:50 // assert b_exists @@ -187,20 +139,14 @@ main_entrypoint@2: byte 0x576f726c64 == assert - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) - byte "global_bytes_no_default" // global_state/contract.py:53 // del self.global_bytes_no_default.value + byte "global_bytes_no_default" app_global_del // global_state/contract.py:54 // b_value, b_exists = self.global_bytes_no_default.maybe() int 0 - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) byte "global_bytes_no_default" - // global_state/contract.py:54 - // b_value, b_exists = self.global_bytes_no_default.maybe() app_global_get_ex cover 1 pop @@ -211,11 +157,7 @@ main_entrypoint@2: // global_state/contract.py:57 // assert self.global_bytes_no_default.get(Bytes(b"default")) == b"default" int 0 - // global_state/contract.py:22 - // self.global_bytes_no_default = GlobalState(Bytes) byte "global_bytes_no_default" - // global_state/contract.py:57 - // assert self.global_bytes_no_default.get(Bytes(b"default")) == b"default" app_global_get_ex cover 1 byte 0x64656661756c74 @@ -229,12 +171,7 @@ main_entrypoint@2: // # Assert 'is set' // assert self.global_bool_full int 0 - // global_state/contract.py:24 - // self.global_bool_full = GlobalState(False) byte "global_bool_full" - // global_state/contract.py:59-60 - // # Assert 'is set' - // assert self.global_bool_full app_global_get_ex cover 1 pop @@ -242,33 +179,22 @@ main_entrypoint@2: // global_state/contract.py:61 // assert not self.global_bool_no_default int 0 - // global_state/contract.py:26 - // self.global_bool_no_default = GlobalState(bool) byte "global_bool_no_default" - // global_state/contract.py:61 - // assert not self.global_bool_no_default app_global_get_ex cover 1 pop ! assert - // global_state/contract.py:26 - // self.global_bool_no_default = GlobalState(bool) - byte "global_bool_no_default" // global_state/contract.py:63 // self.global_bool_no_default.value = True + byte "global_bool_no_default" int 1 app_global_put // global_state/contract.py:65-66 // # Assert 'value' // assert not self.global_bool_full.value int 0 - // global_state/contract.py:24 - // self.global_bool_full = GlobalState(False) byte "global_bool_full" - // global_state/contract.py:65-66 - // # Assert 'value' - // assert not self.global_bool_full.value app_global_get_ex assert // check self.global_bool_full exists ! @@ -276,31 +202,21 @@ main_entrypoint@2: // global_state/contract.py:67 // assert self.global_bool_simplified int 0 - // global_state/contract.py:25 - // self.global_bool_simplified = True byte "global_bool_simplified" - // global_state/contract.py:67 - // assert self.global_bool_simplified app_global_get_ex assert // check self.global_bool_simplified exists assert // global_state/contract.py:68 // assert self.global_bool_no_default.value int 0 - // global_state/contract.py:26 - // self.global_bool_no_default = GlobalState(bool) byte "global_bool_no_default" - // global_state/contract.py:68 - // assert self.global_bool_no_default.value app_global_get_ex assert // check self.global_bool_no_default exists assert - // global_state/contract.py:18 - // self.global_int_no_default = GlobalState(UInt64) - byte "global_int_no_default" // global_state/contract.py:70-71 // # test the proxy can be passed as an argument // assert get_global_state_plus_1(self.global_int_no_default) == 45 + byte "global_int_no_default" callsub get_global_state_plus_1 int 45 == diff --git a/examples/local_state/out/LocalStateContract.approval.mir b/examples/local_state/out/LocalStateContract.approval.mir index 8afe305507..517d836029 100644 --- a/examples/local_state/out/LocalStateContract.approval.mir +++ b/examples/local_state/out/LocalStateContract.approval.mir @@ -199,7 +199,7 @@ get_guaranteed_data: get_guaranteed_data_block@0: frame_dig -1 // load for_account#0 from parameters (𝕡) for_account#0 | for_account#0 self.local[for_account] local_state/local_state_contract.py:56 int 0 // (𝕡) for_account#0 | for_account#0,0 self.local[for_account] local_state/local_state_contract.py:56 - byte "local" // (𝕡) for_account#0 | for_account#0,0,"local" self.local local_state/local_state_contract.py:17 + byte "local" // (𝕡) for_account#0 | for_account#0,0,"local" self.local local_state/local_state_contract.py:56 app_local_get_ex // (𝕡) for_account#0 | {app_local_get_ex}.0,{app_local_get_ex}.1 self.local[for_account] local_state/local_state_contract.py:56 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) for_account#0 | maybe_exists%0#0,{app_local_get_ex}.0 self.local[for_account] local_state/local_state_contract.py:56 // virtual: store result#0 to l-stack (no copy) (𝕡) for_account#0 | result#0,maybe_exists%0#0 self.local[for_account] local_state/local_state_contract.py:56 @@ -208,7 +208,7 @@ get_guaranteed_data_block@0: dup // load result#0 from l-stack (copy) (𝕡) for_account#0 | result#0,result#0 just tests local state proxy can be passed around\nassert result.length local_state/local_state_contract.py:57-58 len // (𝕡) for_account#0 | result#0,{len} just tests local state proxy can be passed around\nassert result.length local_state/local_state_contract.py:57-58 // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) for_account#0 | result#0,tmp%0#0 just tests local state proxy can be passed around\nassert result.length local_state/local_state_contract.py:57-58 - byte "local" // (𝕡) for_account#0 | result#0,tmp%0#0,"local" self.local local_state/local_state_contract.py:17 + byte "local" // (𝕡) for_account#0 | result#0,tmp%0#0,"local" ed around\nassert result.length == get_local_state_length(self.local local_state/local_state_contract.py:57-58 frame_dig -1 // load for_account#0 from parameters (𝕡) for_account#0 | result#0,tmp%0#0,"local",for_account#0 state proxy can be passed around\nassert result.length == get_local_state_length(self.local, for_... local_state/local_state_contract.py:57-58 callsub get_local_state_length // (𝕡) for_account#0 | result#0,tmp%0#0,{get_local_state_length} state proxy can be passed around\nassert result.length == get_local_state_length(self.local, for_... local_state/local_state_contract.py:57-58 // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) for_account#0 | result#0,tmp%0#0,tmp%1#0 state proxy can be passed around\nassert result.length == get_local_state_length(self.local, for_... local_state/local_state_contract.py:57-58 @@ -297,7 +297,7 @@ get_data_or_assert: get_data_or_assert_block@0: frame_dig -1 // load for_account#0 from parameters (𝕡) for_account#0 | for_account#0 self.local.maybe(for_account) local_state/local_state_contract.py:70 int 0 // (𝕡) for_account#0 | for_account#0,0 self.local.maybe(for_account) local_state/local_state_contract.py:70 - byte "local" // (𝕡) for_account#0 | for_account#0,0,"local" self.local local_state/local_state_contract.py:17 + byte "local" // (𝕡) for_account#0 | for_account#0,0,"local" self.local local_state/local_state_contract.py:70 app_local_get_ex // (𝕡) for_account#0 | {app_local_get_ex}.0,{app_local_get_ex}.1 self.local.maybe(for_account) local_state/local_state_contract.py:70 // virtual: store exists#0 to l-stack (no copy) (𝕡) for_account#0 | exists#0,{app_local_get_ex}.0 self.local.maybe(for_account) local_state/local_state_contract.py:70 // virtual: store result#0 to l-stack (no copy) (𝕡) for_account#0 | result#0,exists#0 self.local.maybe(for_account) local_state/local_state_contract.py:70 @@ -313,7 +313,7 @@ delete_data: delete_data_block@0: frame_dig -1 // load for_account#0 from parameters (𝕡) for_account#0 | for_account#0 del self.local[for_account] local_state/local_state_contract.py:80 - byte "local" // (𝕡) for_account#0 | for_account#0,"local" self.local local_state/local_state_contract.py:17 + byte "local" // (𝕡) for_account#0 | for_account#0,"local" self.local local_state/local_state_contract.py:80 app_local_del // (𝕡) for_account#0 | del self.local[for_account] local_state/local_state_contract.py:80 retsub // @@ -324,7 +324,7 @@ set_data: set_data_block@0: frame_dig -2 // load for_account#0 from parameters (𝕡) for_account#0,value#0 | for_account#0 self.local[for_account] = value local_state/local_state_contract.py:76 - byte "local" // (𝕡) for_account#0,value#0 | for_account#0,"local" self.local local_state/local_state_contract.py:17 + byte "local" // (𝕡) for_account#0,value#0 | for_account#0,"local" self.local local_state/local_state_contract.py:76 frame_dig -1 // load value#0 from parameters (𝕡) for_account#0,value#0 | for_account#0,"local",value#0 self.local[for_account] = value local_state/local_state_contract.py:76 app_local_put // (𝕡) for_account#0,value#0 | self.local[for_account] = value local_state/local_state_contract.py:76 retsub // @@ -337,7 +337,7 @@ get_data_with_default: get_data_with_default_block@0: frame_dig -2 // load for_account#0 from parameters (𝕡) for_account#0,default#0 | for_account#0 self.local.get(for_account, default) local_state/local_state_contract.py:66 int 0 // (𝕡) for_account#0,default#0 | for_account#0,0 self.local.get(for_account, default) local_state/local_state_contract.py:66 - byte "local" // (𝕡) for_account#0,default#0 | for_account#0,0,"local" self.local local_state/local_state_contract.py:17 + byte "local" // (𝕡) for_account#0,default#0 | for_account#0,0,"local" self.local local_state/local_state_contract.py:66 app_local_get_ex // (𝕡) for_account#0,default#0 | {app_local_get_ex}.0,{app_local_get_ex}.1 self.local.get(for_account, default) local_state/local_state_contract.py:66 cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕡) for_account#0,default#0 | maybe_exists%0#0,{app_local_get_ex}.0 self.local.get(for_account, default) local_state/local_state_contract.py:66 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) for_account#0,default#0 | maybe_exists%0#0,maybe_value%0#0 self.local.get(for_account, default) local_state/local_state_contract.py:66 diff --git a/examples/local_state/out/LocalStateContract.approval.teal b/examples/local_state/out/LocalStateContract.approval.teal index cd5901fea1..f373eb6fca 100644 --- a/examples/local_state/out/LocalStateContract.approval.teal +++ b/examples/local_state/out/LocalStateContract.approval.teal @@ -169,11 +169,7 @@ get_guaranteed_data: // result = self.local[for_account] frame_dig -1 int 0 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:56 - // result = self.local[for_account] app_local_get_ex assert // check self.local exists for account // local_state/local_state_contract.py:57-58 @@ -181,12 +177,7 @@ get_guaranteed_data: // assert result.length == get_local_state_length(self.local, for_account) dup len - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:57-58 - // # this just tests local state proxy can be passed around - // assert result.length == get_local_state_length(self.local, for_account) frame_dig -1 callsub get_local_state_length == @@ -270,11 +261,7 @@ get_data_or_assert: // result, exists = self.local.maybe(for_account) frame_dig -1 int 0 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:70 - // result, exists = self.local.maybe(for_account) app_local_get_ex // local_state/local_state_contract.py:71 // assert exists, "no data for account" @@ -293,11 +280,7 @@ delete_data: // local_state/local_state_contract.py:80 // del self.local[for_account] frame_dig -1 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:80 - // del self.local[for_account] app_local_del retsub @@ -311,11 +294,7 @@ set_data: // local_state/local_state_contract.py:76 // self.local[for_account] = value frame_dig -2 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:76 - // self.local[for_account] = value frame_dig -1 app_local_put retsub @@ -331,11 +310,7 @@ get_data_with_default: // return self.local.get(for_account, default) frame_dig -2 int 0 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:66 - // return self.local.get(for_account, default) app_local_get_ex frame_dig -1 cover 2 diff --git a/examples/local_state/out/LocalStateWithOffsets.approval.mir b/examples/local_state/out/LocalStateWithOffsets.approval.mir index 41d662d7d9..7c61c679d7 100644 --- a/examples/local_state/out/LocalStateWithOffsets.approval.mir +++ b/examples/local_state/out/LocalStateWithOffsets.approval.mir @@ -199,7 +199,7 @@ get_guaranteed_data: get_guaranteed_data_block@0: frame_dig -1 // load for_account#0 from parameters (𝕡) for_account#0 | for_account#0 self.local[for_account] local_state/local_state_with_offsets.py:55 int 0 // (𝕡) for_account#0 | for_account#0,0 self.local[for_account] local_state/local_state_with_offsets.py:55 - byte "local" // (𝕡) for_account#0 | for_account#0,0,"local" self.local local_state/local_state_with_offsets.py:16 + byte "local" // (𝕡) for_account#0 | for_account#0,0,"local" self.local local_state/local_state_with_offsets.py:55 app_local_get_ex // (𝕡) for_account#0 | {app_local_get_ex}.0,{app_local_get_ex}.1 self.local[for_account] local_state/local_state_with_offsets.py:55 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) for_account#0 | maybe_exists%0#0,{app_local_get_ex}.0 self.local[for_account] local_state/local_state_with_offsets.py:55 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) for_account#0 | maybe_value%0#0,maybe_exists%0#0 self.local[for_account] local_state/local_state_with_offsets.py:55 @@ -216,7 +216,7 @@ get_data_or_assert: get_data_or_assert_block@0: frame_dig -1 // load for_account#0 from parameters (𝕡) for_account#0 | for_account#0 self.local.maybe(for_account) local_state/local_state_with_offsets.py:63 int 0 // (𝕡) for_account#0 | for_account#0,0 self.local.maybe(for_account) local_state/local_state_with_offsets.py:63 - byte "local" // (𝕡) for_account#0 | for_account#0,0,"local" self.local local_state/local_state_with_offsets.py:16 + byte "local" // (𝕡) for_account#0 | for_account#0,0,"local" self.local local_state/local_state_with_offsets.py:63 app_local_get_ex // (𝕡) for_account#0 | {app_local_get_ex}.0,{app_local_get_ex}.1 self.local.maybe(for_account) local_state/local_state_with_offsets.py:63 // virtual: store exists#0 to l-stack (no copy) (𝕡) for_account#0 | exists#0,{app_local_get_ex}.0 self.local.maybe(for_account) local_state/local_state_with_offsets.py:63 // virtual: store result#0 to l-stack (no copy) (𝕡) for_account#0 | result#0,exists#0 self.local.maybe(for_account) local_state/local_state_with_offsets.py:63 @@ -232,7 +232,7 @@ delete_data: delete_data_block@0: frame_dig -1 // load for_account#0 from parameters (𝕡) for_account#0 | for_account#0 del self.local[for_account] local_state/local_state_with_offsets.py:73 - byte "local" // (𝕡) for_account#0 | for_account#0,"local" self.local local_state/local_state_with_offsets.py:16 + byte "local" // (𝕡) for_account#0 | for_account#0,"local" self.local local_state/local_state_with_offsets.py:73 app_local_del // (𝕡) for_account#0 | del self.local[for_account] local_state/local_state_with_offsets.py:73 retsub // @@ -243,7 +243,7 @@ set_data: set_data_block@0: frame_dig -2 // load for_account#0 from parameters (𝕡) for_account#0,value#0 | for_account#0 self.local[for_account] = value local_state/local_state_with_offsets.py:69 - byte "local" // (𝕡) for_account#0,value#0 | for_account#0,"local" self.local local_state/local_state_with_offsets.py:16 + byte "local" // (𝕡) for_account#0,value#0 | for_account#0,"local" self.local local_state/local_state_with_offsets.py:69 frame_dig -1 // load value#0 from parameters (𝕡) for_account#0,value#0 | for_account#0,"local",value#0 self.local[for_account] = value local_state/local_state_with_offsets.py:69 app_local_put // (𝕡) for_account#0,value#0 | self.local[for_account] = value local_state/local_state_with_offsets.py:69 retsub // @@ -256,7 +256,7 @@ get_data_with_default: get_data_with_default_block@0: frame_dig -2 // load for_account#0 from parameters (𝕡) for_account#0,default#0 | for_account#0 self.local.get(for_account, default) local_state/local_state_with_offsets.py:59 int 0 // (𝕡) for_account#0,default#0 | for_account#0,0 self.local.get(for_account, default) local_state/local_state_with_offsets.py:59 - byte "local" // (𝕡) for_account#0,default#0 | for_account#0,0,"local" self.local local_state/local_state_with_offsets.py:16 + byte "local" // (𝕡) for_account#0,default#0 | for_account#0,0,"local" self.local local_state/local_state_with_offsets.py:59 app_local_get_ex // (𝕡) for_account#0,default#0 | {app_local_get_ex}.0,{app_local_get_ex}.1 self.local.get(for_account, default) local_state/local_state_with_offsets.py:59 cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕡) for_account#0,default#0 | maybe_exists%0#0,{app_local_get_ex}.0 self.local.get(for_account, default) local_state/local_state_with_offsets.py:59 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) for_account#0,default#0 | maybe_exists%0#0,maybe_value%0#0 self.local.get(for_account, default) local_state/local_state_with_offsets.py:59 diff --git a/examples/local_state/out/LocalStateWithOffsets.approval.teal b/examples/local_state/out/LocalStateWithOffsets.approval.teal index 7b4c731a6a..3d495b13e4 100644 --- a/examples/local_state/out/LocalStateWithOffsets.approval.teal +++ b/examples/local_state/out/LocalStateWithOffsets.approval.teal @@ -177,11 +177,7 @@ get_guaranteed_data: // return self.local[for_account] frame_dig -1 int 0 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:55 - // return self.local[for_account] app_local_get_ex assert // check self.local exists for account retsub @@ -197,11 +193,7 @@ get_data_or_assert: // result, exists = self.local.maybe(for_account) frame_dig -1 int 0 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:63 - // result, exists = self.local.maybe(for_account) app_local_get_ex // local_state/local_state_with_offsets.py:64 // assert exists, "no data for account" @@ -220,11 +212,7 @@ delete_data: // local_state/local_state_with_offsets.py:73 // del self.local[for_account] frame_dig -1 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:73 - // del self.local[for_account] app_local_del retsub @@ -238,11 +226,7 @@ set_data: // local_state/local_state_with_offsets.py:69 // self.local[for_account] = value frame_dig -2 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:69 - // self.local[for_account] = value frame_dig -1 app_local_put retsub @@ -258,11 +242,7 @@ get_data_with_default: // return self.local.get(for_account, default) frame_dig -2 int 0 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:59 - // return self.local.get(for_account, default) app_local_get_ex frame_dig -1 cover 2 diff --git a/examples/local_state/out_unoptimized/LocalStateContract.approval.teal b/examples/local_state/out_unoptimized/LocalStateContract.approval.teal index 4b055b7a27..42656874cf 100644 --- a/examples/local_state/out_unoptimized/LocalStateContract.approval.teal +++ b/examples/local_state/out_unoptimized/LocalStateContract.approval.teal @@ -186,11 +186,7 @@ get_guaranteed_data: // result = self.local[for_account] frame_dig -1 int 0 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:56 - // result = self.local[for_account] app_local_get_ex assert // check self.local exists for account // local_state/local_state_contract.py:57-58 @@ -198,12 +194,7 @@ get_guaranteed_data: // assert result.length == get_local_state_length(self.local, for_account) dup len - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:57-58 - // # this just tests local state proxy can be passed around - // assert result.length == get_local_state_length(self.local, for_account) frame_dig -1 callsub get_local_state_length == @@ -288,11 +279,7 @@ get_data_or_assert: // result, exists = self.local.maybe(for_account) frame_dig -1 int 0 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:70 - // result, exists = self.local.maybe(for_account) app_local_get_ex // local_state/local_state_contract.py:71 // assert exists, "no data for account" @@ -311,11 +298,7 @@ delete_data: // local_state/local_state_contract.py:80 // del self.local[for_account] frame_dig -1 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:80 - // del self.local[for_account] app_local_del retsub @@ -329,11 +312,7 @@ set_data: // local_state/local_state_contract.py:76 // self.local[for_account] = value frame_dig -2 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:76 - // self.local[for_account] = value frame_dig -1 app_local_put retsub @@ -349,11 +328,7 @@ get_data_with_default: // return self.local.get(for_account, default) frame_dig -2 int 0 - // local_state/local_state_contract.py:17 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_contract.py:66 - // return self.local.get(for_account, default) app_local_get_ex cover 1 frame_dig -1 diff --git a/examples/local_state/out_unoptimized/LocalStateWithOffsets.approval.teal b/examples/local_state/out_unoptimized/LocalStateWithOffsets.approval.teal index e8f5f42b50..7e47c341bd 100644 --- a/examples/local_state/out_unoptimized/LocalStateWithOffsets.approval.teal +++ b/examples/local_state/out_unoptimized/LocalStateWithOffsets.approval.teal @@ -194,11 +194,7 @@ get_guaranteed_data: // return self.local[for_account] frame_dig -1 int 0 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:55 - // return self.local[for_account] app_local_get_ex assert // check self.local exists for account retsub @@ -214,11 +210,7 @@ get_data_or_assert: // result, exists = self.local.maybe(for_account) frame_dig -1 int 0 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:63 - // result, exists = self.local.maybe(for_account) app_local_get_ex // local_state/local_state_with_offsets.py:64 // assert exists, "no data for account" @@ -237,11 +229,7 @@ delete_data: // local_state/local_state_with_offsets.py:73 // del self.local[for_account] frame_dig -1 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:73 - // del self.local[for_account] app_local_del retsub @@ -255,11 +243,7 @@ set_data: // local_state/local_state_with_offsets.py:69 // self.local[for_account] = value frame_dig -2 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:69 - // self.local[for_account] = value frame_dig -1 app_local_put retsub @@ -275,11 +259,7 @@ get_data_with_default: // return self.local.get(for_account, default) frame_dig -2 int 0 - // local_state/local_state_with_offsets.py:16 - // self.local = LocalState(Bytes) byte "local" - // local_state/local_state_with_offsets.py:59 - // return self.local.get(for_account, default) app_local_get_ex cover 1 frame_dig -1 diff --git a/examples/merkle/out/MerkleTree.approval.mir b/examples/merkle/out/MerkleTree.approval.mir index d07c0c1e37..9acd715d16 100644 --- a/examples/merkle/out/MerkleTree.approval.mir +++ b/examples/merkle/out/MerkleTree.approval.mir @@ -109,7 +109,7 @@ verify: verify_block@0: int 0 // (𝕡) proof#0,leaf#0 | 0 self.root merkle/contract.py:16 - byte "root" // (𝕡) proof#0,leaf#0 | 0,"root" self.root merkle/contract.py:12 + byte "root" // (𝕡) proof#0,leaf#0 | 0,"root" self.root merkle/contract.py:16 app_global_get_ex // (𝕡) proof#0,leaf#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.root merkle/contract.py:16 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) proof#0,leaf#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.root merkle/contract.py:16 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) proof#0,leaf#0 | maybe_value%0#0,maybe_exists%0#0 self.root merkle/contract.py:16 diff --git a/examples/merkle/out/MerkleTree.approval.teal b/examples/merkle/out/MerkleTree.approval.teal index 9a58611c2d..cffdd24650 100644 --- a/examples/merkle/out/MerkleTree.approval.teal +++ b/examples/merkle/out/MerkleTree.approval.teal @@ -93,11 +93,7 @@ verify: // merkle/contract.py:16 // return self.root == compute_root_hash(proof, leaf.bytes) int 0 - // merkle/contract.py:12 - // self.root = root.bytes byte "root" - // merkle/contract.py:16 - // return self.root == compute_root_hash(proof, leaf.bytes) app_global_get_ex assert // check self.root exists frame_dig -2 diff --git a/examples/merkle/out/MerkleTree.arc32.json b/examples/merkle/out/MerkleTree.arc32.json index 9ee4515db8..e61970cc35 100644 --- a/examples/merkle/out/MerkleTree.arc32.json +++ b/examples/merkle/out/MerkleTree.arc32.json @@ -12,7 +12,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5tZXJrbGUuY29udHJhY3QuTWVya2xlVHJlZS5hcHByb3ZhbF9wcm9ncmFtOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMubWVya2xlLmNvbnRyYWN0Lk1lcmtsZVRyZWUuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjkKICAgIC8vIGNsYXNzIE1lcmtsZVRyZWUoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA3CiAgICBtZXRob2QgImNyZWF0ZShieXRlWzMyXSl2b2lkIgogICAgbWV0aG9kICJ2ZXJpZnkoYnl0ZVszMl1bXSxieXRlWzMyXSlib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fY3JlYXRlX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3JvdXRlQDMKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjkKICAgIC8vIGNsYXNzIE1lcmtsZVRyZWUoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIGNhbGxzdWIgY3JlYXRlCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcm91dGVAMzoKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6OQogICAgLy8gY2xhc3MgTWVya2xlVHJlZShhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB2ZXJpZnkKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDc6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6OQogICAgLy8gY2xhc3MgTWVya2xlVHJlZShhcmM0LkFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMubWVya2xlLmNvbnRyYWN0Lk1lcmtsZVRyZWUuY3JlYXRlKHJvb3Q6IGJ5dGVzKSAtPiB2b2lkOgpjcmVhdGU6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTAtMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmLCByb290OiBCeXRlczMyKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYucm9vdCA9IHJvb3QuYnl0ZXMKICAgIGJ5dGUgInJvb3QiCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5tZXJrbGUuY29udHJhY3QuTWVya2xlVHJlZS52ZXJpZnkocHJvb2Y6IGJ5dGVzLCBsZWFmOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnk6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTQtMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZlcmlmeShzZWxmLCBwcm9vZjogUHJvb2YsIGxlYWY6IEJ5dGVzMzIpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToxNgogICAgLy8gcmV0dXJuIHNlbGYucm9vdCA9PSBjb21wdXRlX3Jvb3RfaGFzaChwcm9vZiwgbGVhZi5ieXRlcykKICAgIGludCAwCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYucm9vdCA9IHJvb3QuYnl0ZXMKICAgIGJ5dGUgInJvb3QiCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTYKICAgIC8vIHJldHVybiBzZWxmLnJvb3QgPT0gY29tcHV0ZV9yb290X2hhc2gocHJvb2YsIGxlYWYuYnl0ZXMpCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYucm9vdCBleGlzdHMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBjYWxsc3ViIGNvbXB1dGVfcm9vdF9oYXNoCiAgICBmcmFtZV9idXJ5IC0yCiAgICA9PQogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMubWVya2xlLmNvbnRyYWN0LmNvbXB1dGVfcm9vdF9oYXNoKHByb29mOiBieXRlcywgbGVhZjogYnl0ZXMpIC0+IGJ5dGVzLCBieXRlczoKY29tcHV0ZV9yb290X2hhc2g6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTktMjAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgY29tcHV0ZV9yb290X2hhc2gocHJvb2Y6IFByb29mLCBsZWFmOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDIKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToyMgogICAgLy8gZm9yIGlkeCBpbiB1cmFuZ2UocHJvb2YubGVuZ3RoKToKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMAogICAgZnJhbWVfZGlnIC0xCgpjb21wdXRlX3Jvb3RfaGFzaF9mb3JfaGVhZGVyQDE6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MjIKICAgIC8vIGZvciBpZHggaW4gdXJhbmdlKHByb29mLmxlbmd0aCk6CiAgICBmcmFtZV9kaWcgMQogICAgZnJhbWVfZGlnIDAKICAgIDwKICAgIGJ6IGNvbXB1dGVfcm9vdF9oYXNoX2FmdGVyX2ZvckA0CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MjMKICAgIC8vIGNvbXB1dGVkID0gaGFzaF9wYWlyKGNvbXB1dGVkLCBwcm9vZltpZHhdLmJ5dGVzKQogICAgZnJhbWVfZGlnIC0yCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIDEKICAgIGR1cAogICAgY292ZXIgMgogICAgaW50IDMyCiAgICAqCiAgICBpbnQgMzIKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIDIKICAgIHN3YXAKICAgIGNhbGxzdWIgaGFzaF9wYWlyCiAgICBmcmFtZV9idXJ5IDIKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToyMgogICAgLy8gZm9yIGlkeCBpbiB1cmFuZ2UocHJvb2YubGVuZ3RoKToKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDEKICAgIGIgY29tcHV0ZV9yb290X2hhc2hfZm9yX2hlYWRlckAxCgpjb21wdXRlX3Jvb3RfaGFzaF9hZnRlcl9mb3JANDoKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToyNAogICAgLy8gcmV0dXJuIGNvbXB1dGVkCiAgICBmcmFtZV9kaWcgMgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9idXJ5IDEKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMubWVya2xlLmNvbnRyYWN0Lmhhc2hfcGFpcihhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgpoYXNoX3BhaXI6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MjctMjgKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgaGFzaF9wYWlyKGE6IEJ5dGVzLCBiOiBCeXRlcykgLT4gQnl0ZXM6CiAgICBwcm90byAyIDEKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToyOQogICAgLy8gcmV0dXJuIG9wLnNoYTI1NihhICsgYiBpZiBCaWdVSW50LmZyb21fYnl0ZXMoYSkgPCBCaWdVSW50LmZyb21fYnl0ZXMoYikgZWxzZSBiICsgYSkKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBiPAogICAgYnogaGFzaF9wYWlyX3Rlcm5hcnlfZmFsc2VAMgogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgYiBoYXNoX3BhaXJfdGVybmFyeV9tZXJnZUAzCgpoYXNoX3BhaXJfdGVybmFyeV9mYWxzZUAyOgogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjI5CiAgICAvLyByZXR1cm4gb3Auc2hhMjU2KGEgKyBiIGlmIEJpZ1VJbnQuZnJvbV9ieXRlcyhhKSA8IEJpZ1VJbnQuZnJvbV9ieXRlcyhiKSBlbHNlIGIgKyBhKQogICAgZnJhbWVfZGlnIC0xCiAgICBmcmFtZV9kaWcgLTIKICAgIGNvbmNhdAoKaGFzaF9wYWlyX3Rlcm5hcnlfbWVyZ2VAMzoKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToyOQogICAgLy8gcmV0dXJuIG9wLnNoYTI1NihhICsgYiBpZiBCaWdVSW50LmZyb21fYnl0ZXMoYSkgPCBCaWdVSW50LmZyb21fYnl0ZXMoYikgZWxzZSBiICsgYSkKICAgIHNoYTI1NgogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5tZXJrbGUuY29udHJhY3QuTWVya2xlVHJlZS5hcHByb3ZhbF9wcm9ncmFtOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gZXhhbXBsZXMubWVya2xlLmNvbnRyYWN0Lk1lcmtsZVRyZWUuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjkKICAgIC8vIGNsYXNzIE1lcmtsZVRyZWUoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUA3CiAgICBtZXRob2QgImNyZWF0ZShieXRlWzMyXSl2b2lkIgogICAgbWV0aG9kICJ2ZXJpZnkoYnl0ZVszMl1bXSxieXRlWzMyXSlib29sIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fY3JlYXRlX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fdmVyaWZ5X3JvdXRlQDMKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjkKICAgIC8vIGNsYXNzIE1lcmtsZVRyZWUoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIGNhbGxzdWIgY3JlYXRlCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192ZXJpZnlfcm91dGVAMzoKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToxNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6OQogICAgLy8gY2xhc3MgTWVya2xlVHJlZShhcmM0LkFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB2ZXJpZnkKICAgIGJ5dGUgMHgwMAogICAgaW50IDAKICAgIHVuY292ZXIgMgogICAgc2V0Yml0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDc6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6OQogICAgLy8gY2xhc3MgTWVya2xlVHJlZShhcmM0LkFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMubWVya2xlLmNvbnRyYWN0Lk1lcmtsZVRyZWUuY3JlYXRlKHJvb3Q6IGJ5dGVzKSAtPiB2b2lkOgpjcmVhdGU6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTAtMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmLCByb290OiBCeXRlczMyKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTIKICAgIC8vIHNlbGYucm9vdCA9IHJvb3QuYnl0ZXMKICAgIGJ5dGUgInJvb3QiCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy5tZXJrbGUuY29udHJhY3QuTWVya2xlVHJlZS52ZXJpZnkocHJvb2Y6IGJ5dGVzLCBsZWFmOiBieXRlcykgLT4gdWludDY0Ogp2ZXJpZnk6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MTQtMTUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZlcmlmeShzZWxmLCBwcm9vZjogUHJvb2YsIGxlYWY6IEJ5dGVzMzIpIC0+IGJvb2w6CiAgICBwcm90byAyIDEKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToxNgogICAgLy8gcmV0dXJuIHNlbGYucm9vdCA9PSBjb21wdXRlX3Jvb3RfaGFzaChwcm9vZiwgbGVhZi5ieXRlcykKICAgIGludCAwCiAgICBieXRlICJyb290IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnJvb3QgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgY2FsbHN1YiBjb21wdXRlX3Jvb3RfaGFzaAogICAgZnJhbWVfYnVyeSAtMgogICAgPT0KICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLm1lcmtsZS5jb250cmFjdC5jb21wdXRlX3Jvb3RfaGFzaChwcm9vZjogYnl0ZXMsIGxlYWY6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CmNvbXB1dGVfcm9vdF9oYXNoOgogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjE5LTIwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGNvbXB1dGVfcm9vdF9oYXNoKHByb29mOiBQcm9vZiwgbGVhZjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAyCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MjIKICAgIC8vIGZvciBpZHggaW4gdXJhbmdlKHByb29mLmxlbmd0aCk6CiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDAKICAgIGZyYW1lX2RpZyAtMQoKY29tcHV0ZV9yb290X2hhc2hfZm9yX2hlYWRlckAxOgogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBmb3IgaWR4IGluIHVyYW5nZShwcm9vZi5sZW5ndGgpOgogICAgZnJhbWVfZGlnIDEKICAgIGZyYW1lX2RpZyAwCiAgICA8CiAgICBieiBjb21wdXRlX3Jvb3RfaGFzaF9hZnRlcl9mb3JANAogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjIzCiAgICAvLyBjb21wdXRlZCA9IGhhc2hfcGFpcihjb21wdXRlZCwgcHJvb2ZbaWR4XS5ieXRlcykKICAgIGZyYW1lX2RpZyAtMgogICAgZXh0cmFjdCAyIDAKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludCAzMgogICAgKgogICAgaW50IDMyCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAyCiAgICBzd2FwCiAgICBjYWxsc3ViIGhhc2hfcGFpcgogICAgZnJhbWVfYnVyeSAyCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MjIKICAgIC8vIGZvciBpZHggaW4gdXJhbmdlKHByb29mLmxlbmd0aCk6CiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSAxCiAgICBiIGNvbXB1dGVfcm9vdF9oYXNoX2Zvcl9oZWFkZXJAMQoKY29tcHV0ZV9yb290X2hhc2hfYWZ0ZXJfZm9yQDQ6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MjQKICAgIC8vIHJldHVybiBjb21wdXRlZAogICAgZnJhbWVfZGlnIDIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfYnVyeSAxCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLm1lcmtsZS5jb250cmFjdC5oYXNoX3BhaXIoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKaGFzaF9wYWlyOgogICAgLy8gbWVya2xlL2NvbnRyYWN0LnB5OjI3LTI4CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGhhc2hfcGFpcihhOiBCeXRlcywgYjogQnl0ZXMpIC0+IEJ5dGVzOgogICAgcHJvdG8gMiAxCiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MjkKICAgIC8vIHJldHVybiBvcC5zaGEyNTYoYSArIGIgaWYgQmlnVUludC5mcm9tX2J5dGVzKGEpIDwgQmlnVUludC5mcm9tX2J5dGVzKGIpIGVsc2UgYiArIGEpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYjwKICAgIGJ6IGhhc2hfcGFpcl90ZXJuYXJ5X2ZhbHNlQDIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIGIgaGFzaF9wYWlyX3Rlcm5hcnlfbWVyZ2VAMwoKaGFzaF9wYWlyX3Rlcm5hcnlfZmFsc2VAMjoKICAgIC8vIG1lcmtsZS9jb250cmFjdC5weToyOQogICAgLy8gcmV0dXJuIG9wLnNoYTI1NihhICsgYiBpZiBCaWdVSW50LmZyb21fYnl0ZXMoYSkgPCBCaWdVSW50LmZyb21fYnl0ZXMoYikgZWxzZSBiICsgYSkKICAgIGZyYW1lX2RpZyAtMQogICAgZnJhbWVfZGlnIC0yCiAgICBjb25jYXQKCmhhc2hfcGFpcl90ZXJuYXJ5X21lcmdlQDM6CiAgICAvLyBtZXJrbGUvY29udHJhY3QucHk6MjkKICAgIC8vIHJldHVybiBvcC5zaGEyNTYoYSArIGIgaWYgQmlnVUludC5mcm9tX2J5dGVzKGEpIDwgQmlnVUludC5mcm9tX2J5dGVzKGIpIGVsc2UgYiArIGEpCiAgICBzaGEyNTYKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy5tZXJrbGUuY29udHJhY3QuTWVya2xlVHJlZS5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/examples/merkle/out_unoptimized/MerkleTree.approval.teal b/examples/merkle/out_unoptimized/MerkleTree.approval.teal index ec8945114a..2e5dd87156 100644 --- a/examples/merkle/out_unoptimized/MerkleTree.approval.teal +++ b/examples/merkle/out_unoptimized/MerkleTree.approval.teal @@ -105,11 +105,7 @@ verify: // merkle/contract.py:16 // return self.root == compute_root_hash(proof, leaf.bytes) int 0 - // merkle/contract.py:12 - // self.root = root.bytes byte "root" - // merkle/contract.py:16 - // return self.root == compute_root_hash(proof, leaf.bytes) app_global_get_ex assert // check self.root exists frame_dig -2 diff --git a/examples/tictactoe/out/TicTacToeContract.approval.mir b/examples/tictactoe/out/TicTacToeContract.approval.mir index 1dc02e3c29..cd5ff92c1c 100644 --- a/examples/tictactoe/out/TicTacToeContract.approval.mir +++ b/examples/tictactoe/out/TicTacToeContract.approval.mir @@ -167,7 +167,7 @@ new_game_block@0: new_game_if_body@1: int 0 // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0 f a challenger has joined, don't allow starting a new game\n# until this one is complete\nif self... tictactoe/tictactoe.py:23-25 - byte "challenger" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"challenger" self.challenger tictactoe/tictactoe.py:17 + byte "challenger" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"challenger" f a challenger has joined, don't allow starting a new game\n# until this one is complete\nif self... tictactoe/tictactoe.py:23-25 app_global_get_ex // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 f a challenger has joined, don't allow starting a new game\n# until this one is complete\nif self... tictactoe/tictactoe.py:23-25 cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_exists%0#0,{app_global_get_ex}.0 f a challenger has joined, don't allow starting a new game\n# until this one is complete\nif self... tictactoe/tictactoe.py:23-25 pop // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_exists%0#0 f a challenger has joined, don't allow starting a new game\n# until this one is complete\nif self... tictactoe/tictactoe.py:23-25 @@ -177,7 +177,7 @@ new_game_if_body@1: new_game_if_body@2: int 0 // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0 self.winner tictactoe/tictactoe.py:26 - byte "winner" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"winner" self.winner tictactoe/tictactoe.py:18 + byte "winner" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"winner" self.winner tictactoe/tictactoe.py:26 app_global_get_ex // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.winner tictactoe/tictactoe.py:26 cover 1 // store maybe_exists%1#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.winner tictactoe/tictactoe.py:26 pop // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_exists%1#0 self.winner tictactoe/tictactoe.py:26 @@ -186,9 +186,9 @@ new_game_if_body@2: // Implicit fall through to new_game_after_if_else@3 // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | new_game_after_if_else@3: - byte "challenger" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | "challenger" self.challenger tictactoe/tictactoe.py:17 + byte "challenger" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | "challenger" set challenger and winner\ndel self.challenger tictactoe/tictactoe.py:27-28 app_global_del // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | # reset challenger and winner\ndel self.challenger.value tictactoe/tictactoe.py:27-28 - byte "winner" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | "winner" self.winner tictactoe/tictactoe.py:18 + byte "winner" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | "winner" self.winner tictactoe/tictactoe.py:29 app_global_del // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | del self.winner.value tictactoe/tictactoe.py:29 // Implicit fall through to new_game_after_if_else@4 // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | @@ -236,7 +236,7 @@ new_game_bool_merge@8: // virtual: load and_result%0#0 from x-stack (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | and_result%0#0 and_result%0#0 assert column < 3 and row < 3, "Move must be in range" tictactoe/tictactoe.py:33 assert // Move must be in range // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | assert column < 3 and row < 3, "Move must be in range" tictactoe/tictactoe.py:33 int 0 // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0 self.game tictactoe/tictactoe.py:34 - byte "game" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"game" self.game tictactoe/tictactoe.py:31 + byte "game" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"game" self.game tictactoe/tictactoe.py:34 app_global_get_ex // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.game tictactoe/tictactoe.py:34 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_exists%2#0,{app_global_get_ex}.0 self.game tictactoe/tictactoe.py:34 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_value%2#0,maybe_exists%2#0 self.game tictactoe/tictactoe.py:34 @@ -261,7 +261,7 @@ new_game_bool_merge@8: replace3 // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,{replace3} self.game[row][column] = arc4.UInt8(HOST) tictactoe/tictactoe.py:34 // virtual: store updated_target%0#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0 self.game[row][column] = arc4.UInt8(HOST) tictactoe/tictactoe.py:34 int 0 // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,0 self.game tictactoe/tictactoe.py:34 - byte "game" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,0,"game" self.game tictactoe/tictactoe.py:31 + byte "game" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,0,"game" self.game tictactoe/tictactoe.py:34 app_global_get_ex // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.game tictactoe/tictactoe.py:34 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,maybe_exists%3#0,{app_global_get_ex}.0 self.game tictactoe/tictactoe.py:34 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,maybe_value%3#0,maybe_exists%3#0 self.game tictactoe/tictactoe.py:34 @@ -278,7 +278,7 @@ new_game_bool_merge@8: uncover 2 // load updated_target%0#0 from l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_value%3#0,item_offset%0#0,updated_target%0#0 self.game[row][column] = arc4.UInt8(HOST) tictactoe/tictactoe.py:34 replace3 // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | {replace3} self.game[row][column] = arc4.UInt8(HOST) tictactoe/tictactoe.py:34 // virtual: store updated_target%1#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | updated_target%1#0 self.game[row][column] = arc4.UInt8(HOST) tictactoe/tictactoe.py:34 - byte "game" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | updated_target%1#0,"game" self.game tictactoe/tictactoe.py:31 + byte "game" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | updated_target%1#0,"game" self.game tictactoe/tictactoe.py:34 uncover 1 // load updated_target%1#0 from l-stack (no copy) (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | "game",updated_target%1#0 self.game[row][column] = arc4.UInt8(HOST) tictactoe/tictactoe.py:34 app_global_put // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | self.game[row][column] = arc4.UInt8(HOST) tictactoe/tictactoe.py:34 byte "turns" // (𝕡) move.0#0,move.1#0 | (𝕗) tmp%0#0 | "turns" self.turns tictactoe/tictactoe.py:35 @@ -293,7 +293,7 @@ join_game: join_game_block@0: int 0 // (𝕡) move.0#0,move.1#0 | 0 not self.challenger tictactoe/tictactoe.py:39 - byte "challenger" // (𝕡) move.0#0,move.1#0 | 0,"challenger" self.challenger tictactoe/tictactoe.py:17 + byte "challenger" // (𝕡) move.0#0,move.1#0 | 0,"challenger" self.challenger tictactoe/tictactoe.py:39 app_global_get_ex // (𝕡) move.0#0,move.1#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 not self.challenger tictactoe/tictactoe.py:39 cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | maybe_exists%0#0,{app_global_get_ex}.0 not self.challenger tictactoe/tictactoe.py:39 pop // (𝕡) move.0#0,move.1#0 | maybe_exists%0#0 not self.challenger tictactoe/tictactoe.py:39 @@ -304,7 +304,7 @@ join_game_block@0: assert // Host already has a challenger // (𝕡) move.0#0,move.1#0 | assert not self.challenger, "Host already has a challenger" tictactoe/tictactoe.py:39 txn Sender // (𝕡) move.0#0,move.1#0 | {txn} Txn.sender tictactoe/tictactoe.py:40 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | new_state_value%0#0 Txn.sender tictactoe/tictactoe.py:40 - byte "challenger" // (𝕡) move.0#0,move.1#0 | new_state_value%0#0,"challenger" self.challenger tictactoe/tictactoe.py:17 + byte "challenger" // (𝕡) move.0#0,move.1#0 | new_state_value%0#0,"challenger" self.challenger tictactoe/tictactoe.py:40 uncover 1 // load new_state_value%0#0 from l-stack (no copy) (𝕡) move.0#0,move.1#0 | "challenger",new_state_value%0#0 self.challenger.value = Txn.sender tictactoe/tictactoe.py:40 app_global_put // (𝕡) move.0#0,move.1#0 | self.challenger.value = Txn.sender tictactoe/tictactoe.py:40 byte 0x02 // (𝕡) move.0#0,move.1#0 | 0x02 arc4.UInt8(CHALLENGER) tictactoe/tictactoe.py:41 @@ -351,7 +351,7 @@ make_move_bool_merge@4: // virtual: load and_result%0#0 from x-stack (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | and_result%0#0 and_result%0#0 assert column < 3 and row < 3, "Move must be in range" tictactoe/tictactoe.py:63 assert // Move must be in range // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | assert column < 3 and row < 3, "Move must be in range" tictactoe/tictactoe.py:63 int 0 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0 self.game tictactoe/tictactoe.py:64 - byte "game" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"game" self.game tictactoe/tictactoe.py:31 + byte "game" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"game" self.game tictactoe/tictactoe.py:64 app_global_get_ex // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.game tictactoe/tictactoe.py:64 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.game tictactoe/tictactoe.py:64 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_value%0#0,maybe_exists%0#0 self.game tictactoe/tictactoe.py:64 @@ -380,7 +380,7 @@ make_move_bool_merge@4: // virtual: load tmp%3#0 from l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,tmp%3#0 assert self.game[row][column] == EMPTY, "Square is already taken" tictactoe/tictactoe.py:64 assert // Square is already taken // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0 assert self.game[row][column] == EMPTY, "Square is already taken" tictactoe/tictactoe.py:64 int 0 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,0 self.game tictactoe/tictactoe.py:65 - byte "game" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,0,"game" self.game tictactoe/tictactoe.py:31 + byte "game" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,0,"game" self.game tictactoe/tictactoe.py:65 app_global_get_ex // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.game tictactoe/tictactoe.py:65 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,maybe_exists%1#0,{app_global_get_ex}.0 self.game tictactoe/tictactoe.py:65 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,maybe_value%1#0,maybe_exists%1#0 self.game tictactoe/tictactoe.py:65 @@ -399,7 +399,7 @@ make_move_bool_merge@4: replace3 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,{replace3} self.game[row][column] = player tictactoe/tictactoe.py:65 // virtual: store updated_target%0#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0 self.game[row][column] = player tictactoe/tictactoe.py:65 int 0 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,0 self.game tictactoe/tictactoe.py:65 - byte "game" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,0,"game" self.game tictactoe/tictactoe.py:31 + byte "game" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,0,"game" self.game tictactoe/tictactoe.py:65 app_global_get_ex // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.game tictactoe/tictactoe.py:65 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,maybe_exists%2#0,{app_global_get_ex}.0 self.game tictactoe/tictactoe.py:65 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | item_offset%0#0,updated_target%0#0,maybe_value%2#0,maybe_exists%2#0 self.game tictactoe/tictactoe.py:65 @@ -416,11 +416,11 @@ make_move_bool_merge@4: uncover 2 // load updated_target%0#0 from l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_value%2#0,item_offset%0#0,updated_target%0#0 self.game[row][column] = player tictactoe/tictactoe.py:65 replace3 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | {replace3} self.game[row][column] = player tictactoe/tictactoe.py:65 // virtual: store updated_target%1#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | updated_target%1#0 self.game[row][column] = player tictactoe/tictactoe.py:65 - byte "game" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | updated_target%1#0,"game" self.game tictactoe/tictactoe.py:31 + byte "game" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | updated_target%1#0,"game" self.game tictactoe/tictactoe.py:65 uncover 1 // load updated_target%1#0 from l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | "game",updated_target%1#0 self.game[row][column] = player tictactoe/tictactoe.py:65 app_global_put // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | self.game[row][column] = player tictactoe/tictactoe.py:65 int 0 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0 self.turns tictactoe/tictactoe.py:66 - byte "turns" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"turns" self.turns tictactoe/tictactoe.py:35 + byte "turns" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"turns" self.turns tictactoe/tictactoe.py:66 app_global_get_ex // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.turns tictactoe/tictactoe.py:66 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_exists%3#0,{app_global_get_ex}.0 self.turns tictactoe/tictactoe.py:66 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_value%3#0,maybe_exists%3#0 self.turns tictactoe/tictactoe.py:66 @@ -430,7 +430,7 @@ make_move_bool_merge@4: int 1 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_value%3#0,1 1 tictactoe/tictactoe.py:66 + // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | {+} self.turns += 1 tictactoe/tictactoe.py:66 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | new_state_value%0#0 self.turns += 1 tictactoe/tictactoe.py:66 - byte "turns" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | new_state_value%0#0,"turns" self.turns tictactoe/tictactoe.py:35 + byte "turns" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | new_state_value%0#0,"turns" self.turns tictactoe/tictactoe.py:66 uncover 1 // load new_state_value%0#0 from l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | "turns",new_state_value%0#0 self.turns += 1 tictactoe/tictactoe.py:66 app_global_put // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | self.turns += 1 tictactoe/tictactoe.py:66 frame_dig -3 // load player#0 from parameters (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | player#0 self.did_win(player, column=column, row=row) tictactoe/tictactoe.py:67 @@ -443,14 +443,14 @@ make_move_bool_merge@4: // Implicit fall through to make_move_if_body@5 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | if self.did_win(player, column=column, row=row): tictactoe/tictactoe.py:67 make_move_if_body@5: - byte "winner" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | "winner" self.winner tictactoe/tictactoe.py:18 + byte "winner" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | "winner" self.winner tictactoe/tictactoe.py:68 frame_dig -3 // load player#0 from parameters (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | "winner",player#0 self.winner.value = player tictactoe/tictactoe.py:68 app_global_put // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | self.winner.value = player tictactoe/tictactoe.py:68 b make_move_after_if_else@9 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | make_move_else_body@6: int 0 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0 self.turns tictactoe/tictactoe.py:69 - byte "turns" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"turns" self.turns tictactoe/tictactoe.py:35 + byte "turns" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | 0,"turns" self.turns tictactoe/tictactoe.py:69 app_global_get_ex // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.turns tictactoe/tictactoe.py:69 // virtual: store maybe_exists%4#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_exists%4#0,{app_global_get_ex}.0 self.turns tictactoe/tictactoe.py:69 // virtual: store maybe_value%4#0 to l-stack (no copy) (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | maybe_value%4#0,maybe_exists%4#0 self.turns tictactoe/tictactoe.py:69 @@ -465,7 +465,7 @@ make_move_else_body@6: // Implicit fall through to make_move_if_body@7 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | elif self.turns == 9: tictactoe/tictactoe.py:69 make_move_if_body@7: - byte "winner" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | "winner" self.winner tictactoe/tictactoe.py:18 + byte "winner" // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | "winner" self.winner tictactoe/tictactoe.py:70 byte 0x03 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | "winner",0x03 arc4.UInt8(DRAW) tictactoe/tictactoe.py:70 app_global_put // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | self.winner.value = arc4.UInt8(DRAW) tictactoe/tictactoe.py:70 // Implicit fall through to make_move_after_if_else@9 // (𝕡) player#0,move.0#0,move.1#0 | (𝕗) tmp%0#0 | @@ -482,7 +482,7 @@ did_win: did_win_block@0: int 0 // (𝕡) player#0,column#0,row#0 | (𝕗) awst_tmp%1#0,tmp%5#0,tmp%6#0 | 0 self.game tictactoe/tictactoe.py:74 - byte "game" // (𝕡) player#0,column#0,row#0 | (𝕗) awst_tmp%1#0,tmp%5#0,tmp%6#0 | 0,"game" self.game tictactoe/tictactoe.py:31 + byte "game" // (𝕡) player#0,column#0,row#0 | (𝕗) awst_tmp%1#0,tmp%5#0,tmp%6#0 | 0,"game" self.game tictactoe/tictactoe.py:74 app_global_get_ex // (𝕡) player#0,column#0,row#0 | (𝕗) awst_tmp%1#0,tmp%5#0,tmp%6#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.game tictactoe/tictactoe.py:74 cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕡) player#0,column#0,row#0 | (𝕗) awst_tmp%1#0,tmp%5#0,tmp%6#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.game tictactoe/tictactoe.py:74 dup @@ -671,7 +671,7 @@ whose_turn: whose_turn_block@0: int 0 // 0 self.turns tictactoe/tictactoe.py:45 - byte "turns" // 0,"turns" self.turns tictactoe/tictactoe.py:35 + byte "turns" // 0,"turns" self.turns tictactoe/tictactoe.py:45 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.turns tictactoe/tictactoe.py:45 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.turns tictactoe/tictactoe.py:45 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.turns tictactoe/tictactoe.py:45 @@ -696,7 +696,7 @@ play: play_block@0: int 0 // (𝕡) move.0#0,move.1#0 | 0 not self.winner tictactoe/tictactoe.py:49 - byte "winner" // (𝕡) move.0#0,move.1#0 | 0,"winner" self.winner tictactoe/tictactoe.py:18 + byte "winner" // (𝕡) move.0#0,move.1#0 | 0,"winner" self.winner tictactoe/tictactoe.py:49 app_global_get_ex // (𝕡) move.0#0,move.1#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 not self.winner tictactoe/tictactoe.py:49 cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | maybe_exists%0#0,{app_global_get_ex}.0 not self.winner tictactoe/tictactoe.py:49 pop // (𝕡) move.0#0,move.1#0 | maybe_exists%0#0 not self.winner tictactoe/tictactoe.py:49 @@ -706,7 +706,7 @@ play_block@0: // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%0#0 assert not self.winner, "Game is already finished" tictactoe/tictactoe.py:49 assert // Game is already finished // (𝕡) move.0#0,move.1#0 | assert not self.winner, "Game is already finished" tictactoe/tictactoe.py:49 int 0 // (𝕡) move.0#0,move.1#0 | 0 self.turns tictactoe/tictactoe.py:50 - byte "turns" // (𝕡) move.0#0,move.1#0 | 0,"turns" self.turns tictactoe/tictactoe.py:35 + byte "turns" // (𝕡) move.0#0,move.1#0 | 0,"turns" self.turns tictactoe/tictactoe.py:50 app_global_get_ex // (𝕡) move.0#0,move.1#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.turns tictactoe/tictactoe.py:50 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.turns tictactoe/tictactoe.py:50 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | maybe_value%1#0,maybe_exists%1#0 self.turns tictactoe/tictactoe.py:50 @@ -724,7 +724,7 @@ play_if_body@1: txn Sender // (𝕡) move.0#0,move.1#0 | {txn} Txn.sender tictactoe/tictactoe.py:51 // virtual: store tmp%3#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%3#0 Txn.sender tictactoe/tictactoe.py:51 int 0 // (𝕡) move.0#0,move.1#0 | tmp%3#0,0 self.host tictactoe/tictactoe.py:51 - byte "host" // (𝕡) move.0#0,move.1#0 | tmp%3#0,0,"host" self.host tictactoe/tictactoe.py:30 + byte "host" // (𝕡) move.0#0,move.1#0 | tmp%3#0,0,"host" self.host tictactoe/tictactoe.py:51 app_global_get_ex // (𝕡) move.0#0,move.1#0 | tmp%3#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.host tictactoe/tictactoe.py:51 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%3#0,maybe_exists%2#0,{app_global_get_ex}.0 self.host tictactoe/tictactoe.py:51 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%3#0,maybe_value%2#0,maybe_exists%2#0 self.host tictactoe/tictactoe.py:51 @@ -746,7 +746,7 @@ play_else_body@2: global ZeroAddress // (𝕡) move.0#0,move.1#0 | tmp%5#0,{global} Account() tictactoe/tictactoe.py:55 // virtual: store tmp%6#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%5#0,tmp%6#0 Account() tictactoe/tictactoe.py:55 int 0 // (𝕡) move.0#0,move.1#0 | tmp%5#0,tmp%6#0,0 self.challenger.get tictactoe/tictactoe.py:54 - byte "challenger" // (𝕡) move.0#0,move.1#0 | tmp%5#0,tmp%6#0,0,"challenger" self.challenger tictactoe/tictactoe.py:17 + byte "challenger" // (𝕡) move.0#0,move.1#0 | tmp%5#0,tmp%6#0,0,"challenger" self.challenger tictactoe/tictactoe.py:54 app_global_get_ex // (𝕡) move.0#0,move.1#0 | tmp%5#0,tmp%6#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.challenger.get(\ndefault=Account()\n) tictactoe/tictactoe.py:54-56 cover 1 // store maybe_exists%3#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%5#0,tmp%6#0,maybe_exists%3#0,{app_global_get_ex}.0 self.challenger.get(\ndefault=Account()\n) tictactoe/tictactoe.py:54-56 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) move.0#0,move.1#0 | tmp%5#0,tmp%6#0,maybe_exists%3#0,maybe_value%3#0 self.challenger.get(\ndefault=Account()\n) tictactoe/tictactoe.py:54-56 diff --git a/examples/tictactoe/out/TicTacToeContract.approval.teal b/examples/tictactoe/out/TicTacToeContract.approval.teal index e1762cf8c1..f4e877f66e 100644 --- a/examples/tictactoe/out/TicTacToeContract.approval.teal +++ b/examples/tictactoe/out/TicTacToeContract.approval.teal @@ -133,41 +133,27 @@ new_game: // # until this one is complete // if self.challenger: int 0 - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) byte "challenger" - // tictactoe/tictactoe.py:23-25 - // # if a challenger has joined, don't allow starting a new game - // # until this one is complete - // if self.challenger: app_global_get_ex bury 1 bz new_game_after_if_else@3 // tictactoe/tictactoe.py:26 // assert self.winner, "Game isn't over" int 0 - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) byte "winner" - // tictactoe/tictactoe.py:26 - // assert self.winner, "Game isn't over" app_global_get_ex bury 1 assert // Game isn't over new_game_after_if_else@3: - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) - byte "challenger" // tictactoe/tictactoe.py:27-28 // # reset challenger and winner // del self.challenger.value + byte "challenger" app_global_del - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) - byte "winner" // tictactoe/tictactoe.py:29 // del self.winner.value + byte "winner" app_global_del new_game_after_if_else@4: @@ -208,11 +194,7 @@ new_game_bool_merge@8: // tictactoe/tictactoe.py:34 // self.game[row][column] = arc4.UInt8(HOST) int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:34 - // self.game[row][column] = arc4.UInt8(HOST) app_global_get_ex assert // check self.game exists frame_dig -1 @@ -228,11 +210,7 @@ new_game_bool_merge@8: byte 0x01 replace3 int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:34 - // self.game[row][column] = arc4.UInt8(HOST) app_global_get_ex assert // check self.game exists frame_dig -1 @@ -241,11 +219,7 @@ new_game_bool_merge@8: assert // Index access is out of bounds cover 2 replace3 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:34 - // self.game[row][column] = arc4.UInt8(HOST) swap app_global_put // tictactoe/tictactoe.py:35 @@ -265,20 +239,14 @@ join_game: // tictactoe/tictactoe.py:39 // assert not self.challenger, "Host already has a challenger" int 0 - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) byte "challenger" - // tictactoe/tictactoe.py:39 - // assert not self.challenger, "Host already has a challenger" app_global_get_ex bury 1 ! assert // Host already has a challenger - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) - byte "challenger" // tictactoe/tictactoe.py:40 // self.challenger.value = Txn.sender + byte "challenger" txn Sender app_global_put // tictactoe/tictactoe.py:41 @@ -320,11 +288,7 @@ make_move_bool_merge@4: // tictactoe/tictactoe.py:64 // assert self.game[row][column] == EMPTY, "Square is already taken" int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:64 - // assert self.game[row][column] == EMPTY, "Square is already taken" app_global_get_ex assert // check self.game exists frame_dig -1 @@ -343,11 +307,7 @@ make_move_bool_merge@4: // tictactoe/tictactoe.py:65 // self.game[row][column] = player int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:65 - // self.game[row][column] = player app_global_get_ex assert // check self.game exists dig 1 @@ -359,11 +319,7 @@ make_move_bool_merge@4: frame_dig -3 replace3 int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:65 - // self.game[row][column] = player app_global_get_ex assert // check self.game exists frame_dig -1 @@ -372,30 +328,18 @@ make_move_bool_merge@4: assert // Index access is out of bounds cover 2 replace3 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:65 - // self.game[row][column] = player swap app_global_put // tictactoe/tictactoe.py:66 // self.turns += 1 int 0 - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:66 - // self.turns += 1 app_global_get_ex assert // check self.turns exists int 1 + - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:66 - // self.turns += 1 swap app_global_put // tictactoe/tictactoe.py:67 @@ -405,11 +349,9 @@ make_move_bool_merge@4: frame_dig -1 callsub did_win bz make_move_else_body@6 - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) - byte "winner" // tictactoe/tictactoe.py:68 // self.winner.value = player + byte "winner" frame_dig -3 app_global_put b make_move_after_if_else@9 @@ -418,21 +360,15 @@ make_move_else_body@6: // tictactoe/tictactoe.py:69 // elif self.turns == 9: int 0 - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:69 - // elif self.turns == 9: app_global_get_ex assert // check self.turns exists int 9 == bz make_move_after_if_else@9 - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) - byte "winner" // tictactoe/tictactoe.py:70 // self.winner.value = arc4.UInt8(DRAW) + byte "winner" byte 0x03 app_global_put @@ -450,11 +386,7 @@ did_win: // tictactoe/tictactoe.py:74 // g = self.game.copy() dupn 3 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:74 - // g = self.game.copy() app_global_get_ex swap dup @@ -587,11 +519,7 @@ whose_turn: // tictactoe/tictactoe.py:45 // return arc4.UInt8(HOST) if self.turns % 2 else arc4.UInt8(CHALLENGER) int 0 - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:45 - // return arc4.UInt8(HOST) if self.turns % 2 else arc4.UInt8(CHALLENGER) app_global_get_ex assert // check self.turns exists int 2 @@ -612,11 +540,7 @@ play: // tictactoe/tictactoe.py:49 // assert not self.winner, "Game is already finished" int 0 - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) byte "winner" - // tictactoe/tictactoe.py:49 - // assert not self.winner, "Game is already finished" app_global_get_ex bury 1 ! @@ -624,11 +548,7 @@ play: // tictactoe/tictactoe.py:50 // if self.turns % 2: int 0 - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:50 - // if self.turns % 2: app_global_get_ex assert // check self.turns exists int 2 @@ -638,11 +558,7 @@ play: // assert Txn.sender == self.host, "It is the host's turn" txn Sender int 0 - // tictactoe/tictactoe.py:30 - // self.host = Txn.sender byte "host" - // tictactoe/tictactoe.py:51 - // assert Txn.sender == self.host, "It is the host's turn" app_global_get_ex assert // check self.host exists == @@ -662,8 +578,6 @@ play_else_body@2: // tictactoe/tictactoe.py:54 // assert Txn.sender == self.challenger.get( int 0 - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) byte "challenger" // tictactoe/tictactoe.py:54-56 // assert Txn.sender == self.challenger.get( diff --git a/examples/tictactoe/out/TicTacToeContract.arc32.json b/examples/tictactoe/out/TicTacToeContract.arc32.json index 60af04306c..d14297de7e 100644 --- a/examples/tictactoe/out/TicTacToeContract.arc32.json +++ b/examples/tictactoe/out/TicTacToeContract.arc32.json @@ -22,7 +22,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy50aWN0YWN0b2UudGljdGFjdG9lLlRpY1RhY1RvZUNvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyBleGFtcGxlcy50aWN0YWN0b2UudGljdGFjdG9lLlRpY1RhY1RvZUNvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTUKICAgIC8vIGNsYXNzIFRpY1RhY1RvZUNvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAOQogICAgbWV0aG9kICJuZXdfZ2FtZSgodWludDY0LHVpbnQ2NCkpdm9pZCIKICAgIG1ldGhvZCAiam9pbl9nYW1lKCh1aW50NjQsdWludDY0KSl2b2lkIgogICAgbWV0aG9kICJ3aG9zZV90dXJuKCl1aW50OCIKICAgIG1ldGhvZCAicGxheSgodWludDY0LHVpbnQ2NCkpdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX25ld19nYW1lX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fam9pbl9nYW1lX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fd2hvc2VfdHVybl9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3BsYXlfcm91dGVANQogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fbmV3X2dhbWVfcm91dGVAMjoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9ImFsbG93IikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToxNQogICAgLy8gY2xhc3MgVGljVGFjVG9lQ29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBleHRyYWN0IDAgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGV4dHJhY3QgOCA4IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0iYWxsb3ciKQogICAgY2FsbHN1YiBuZXdfZ2FtZQogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fam9pbl9nYW1lX3JvdXRlQDM6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTUKICAgIC8vIGNsYXNzIFRpY1RhY1RvZUNvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGR1cAogICAgZXh0cmFjdCAwIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBzd2FwCiAgICBleHRyYWN0IDggOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBqb2luX2dhbWUKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3dob3NlX3R1cm5fcm91dGVANDoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB3aG9zZV90dXJuCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19wbGF5X3JvdXRlQDU6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTUKICAgIC8vIGNsYXNzIFRpY1RhY1RvZUNvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGR1cAogICAgZXh0cmFjdCAwIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBzd2FwCiAgICBleHRyYWN0IDggOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBwbGF5CiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDk6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjE1CiAgICAvLyBjbGFzcyBUaWNUYWNUb2VDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudGljdGFjdG9lLnRpY3RhY3RvZS5UaWNUYWNUb2VDb250cmFjdC5uZXdfZ2FtZShtb3ZlLjA6IHVpbnQ2NCwgbW92ZS4xOiB1aW50NjQpIC0+IHZvaWQ6Cm5ld19nYW1lOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToyMC0yMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0iYWxsb3ciKQogICAgLy8gZGVmIG5ld19nYW1lKHNlbGYsIG1vdmU6IE1vdmUpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIGJ5dGUgIiIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MjIKICAgIC8vIGlmIFR4bi5hcHBsaWNhdGlvbl9pZDoKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBieiBuZXdfZ2FtZV9hZnRlcl9pZl9lbHNlQDQKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MjMtMjUKICAgIC8vICMgaWYgYSBjaGFsbGVuZ2VyIGhhcyBqb2luZWQsIGRvbid0IGFsbG93IHN0YXJ0aW5nIGEgbmV3IGdhbWUKICAgIC8vICMgdW50aWwgdGhpcyBvbmUgaXMgY29tcGxldGUKICAgIC8vIGlmIHNlbGYuY2hhbGxlbmdlcjoKICAgIGludCAwCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjE3CiAgICAvLyBzZWxmLmNoYWxsZW5nZXIgPSBHbG9iYWxTdGF0ZShBY2NvdW50KQogICAgYnl0ZSAiY2hhbGxlbmdlciIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MjMtMjUKICAgIC8vICMgaWYgYSBjaGFsbGVuZ2VyIGhhcyBqb2luZWQsIGRvbid0IGFsbG93IHN0YXJ0aW5nIGEgbmV3IGdhbWUKICAgIC8vICMgdW50aWwgdGhpcyBvbmUgaXMgY29tcGxldGUKICAgIC8vIGlmIHNlbGYuY2hhbGxlbmdlcjoKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgIGJ6IG5ld19nYW1lX2FmdGVyX2lmX2Vsc2VAMwogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToyNgogICAgLy8gYXNzZXJ0IHNlbGYud2lubmVyLCAiR2FtZSBpc24ndCBvdmVyIgogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTgKICAgIC8vIHNlbGYud2lubmVyID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50OCkKICAgIGJ5dGUgIndpbm5lciIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MjYKICAgIC8vIGFzc2VydCBzZWxmLndpbm5lciwgIkdhbWUgaXNuJ3Qgb3ZlciIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgIGFzc2VydCAvLyBHYW1lIGlzbid0IG92ZXIKCm5ld19nYW1lX2FmdGVyX2lmX2Vsc2VAMzoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTcKICAgIC8vIHNlbGYuY2hhbGxlbmdlciA9IEdsb2JhbFN0YXRlKEFjY291bnQpCiAgICBieXRlICJjaGFsbGVuZ2VyIgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToyNy0yOAogICAgLy8gIyByZXNldCBjaGFsbGVuZ2VyIGFuZCB3aW5uZXIKICAgIC8vIGRlbCBzZWxmLmNoYWxsZW5nZXIudmFsdWUKICAgIGFwcF9nbG9iYWxfZGVsCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjE4CiAgICAvLyBzZWxmLndpbm5lciA9IEdsb2JhbFN0YXRlKGFyYzQuVUludDgpCiAgICBieXRlICJ3aW5uZXIiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjI5CiAgICAvLyBkZWwgc2VsZi53aW5uZXIudmFsdWUKICAgIGFwcF9nbG9iYWxfZGVsCgpuZXdfZ2FtZV9hZnRlcl9pZl9lbHNlQDQ6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjMwCiAgICAvLyBzZWxmLmhvc3QgPSBUeG4uc2VuZGVyCiAgICBieXRlICJob3N0IgogICAgdHhuIFNlbmRlcgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzEKICAgIC8vIHNlbGYuZ2FtZSA9IEdhbWUuZnJvbV9ieXRlcyhvcC5iemVybyg5KSkKICAgIGludCA5CiAgICBiemVybwogICAgYnl0ZSAiZ2FtZSIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjMzCiAgICAvLyBhc3NlcnQgY29sdW1uIDwgMyBhbmQgcm93IDwgMywgIk1vdmUgbXVzdCBiZSBpbiByYW5nZSIKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDMKICAgIDwKICAgIGR1cAogICAgZnJhbWVfYnVyeSAwCiAgICBieiBuZXdfZ2FtZV9ib29sX2ZhbHNlQDcKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgIDwKICAgIGJ6IG5ld19nYW1lX2Jvb2xfZmFsc2VANwogICAgaW50IDEKICAgIGIgbmV3X2dhbWVfYm9vbF9tZXJnZUA4CgpuZXdfZ2FtZV9ib29sX2ZhbHNlQDc6CiAgICBpbnQgMAoKbmV3X2dhbWVfYm9vbF9tZXJnZUA4OgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozMwogICAgLy8gYXNzZXJ0IGNvbHVtbiA8IDMgYW5kIHJvdyA8IDMsICJNb3ZlIG11c3QgYmUgaW4gcmFuZ2UiCiAgICBhc3NlcnQgLy8gTW92ZSBtdXN0IGJlIGluIHJhbmdlCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjM0CiAgICAvLyBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID0gYXJjNC5VSW50OChIT1NUKQogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzEKICAgIC8vIHNlbGYuZ2FtZSA9IEdhbWUuZnJvbV9ieXRlcyhvcC5iemVybyg5KSkKICAgIGJ5dGUgImdhbWUiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjM0CiAgICAvLyBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID0gYXJjNC5VSW50OChIT1NUKQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdhbWUgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAzCiAgICAqCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludCAzCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAwCiAgICBhc3NlcnQgLy8gSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAtMgogICAgYnl0ZSAweDAxCiAgICByZXBsYWNlMwogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzEKICAgIC8vIHNlbGYuZ2FtZSA9IEdhbWUuZnJvbV9ieXRlcyhvcC5iemVybyg5KSkKICAgIGJ5dGUgImdhbWUiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjM0CiAgICAvLyBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID0gYXJjNC5VSW50OChIT1NUKQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdhbWUgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAzCiAgICA8CiAgICBhc3NlcnQgLy8gSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGNvdmVyIDIKICAgIHJlcGxhY2UzCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjMxCiAgICAvLyBzZWxmLmdhbWUgPSBHYW1lLmZyb21fYnl0ZXMob3AuYnplcm8oOSkpCiAgICBieXRlICJnYW1lIgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozNAogICAgLy8gc2VsZi5nYW1lW3Jvd11bY29sdW1uXSA9IGFyYzQuVUludDgoSE9TVCkKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjM1CiAgICAvLyBzZWxmLnR1cm5zID0gVUludDY0KDApCiAgICBieXRlICJ0dXJucyIKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudGljdGFjdG9lLnRpY3RhY3RvZS5UaWNUYWNUb2VDb250cmFjdC5qb2luX2dhbWUobW92ZS4wOiB1aW50NjQsIG1vdmUuMTogdWludDY0KSAtPiB2b2lkOgpqb2luX2dhbWU6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjM3LTM4CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBqb2luX2dhbWUoc2VsZiwgbW92ZTogTW92ZSkgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozOQogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLmNoYWxsZW5nZXIsICJIb3N0IGFscmVhZHkgaGFzIGEgY2hhbGxlbmdlciIKICAgIGludCAwCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjE3CiAgICAvLyBzZWxmLmNoYWxsZW5nZXIgPSBHbG9iYWxTdGF0ZShBY2NvdW50KQogICAgYnl0ZSAiY2hhbGxlbmdlciIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzkKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5jaGFsbGVuZ2VyLCAiSG9zdCBhbHJlYWR5IGhhcyBhIGNoYWxsZW5nZXIiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYnVyeSAxCiAgICAhCiAgICBhc3NlcnQgLy8gSG9zdCBhbHJlYWR5IGhhcyBhIGNoYWxsZW5nZXIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTcKICAgIC8vIHNlbGYuY2hhbGxlbmdlciA9IEdsb2JhbFN0YXRlKEFjY291bnQpCiAgICBieXRlICJjaGFsbGVuZ2VyIgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo0MAogICAgLy8gc2VsZi5jaGFsbGVuZ2VyLnZhbHVlID0gVHhuLnNlbmRlcgogICAgdHhuIFNlbmRlcgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NDEKICAgIC8vIHNlbGYubWFrZV9tb3ZlKGFyYzQuVUludDgoQ0hBTExFTkdFUiksIG1vdmUpCiAgICBieXRlIDB4MDIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBjYWxsc3ViIG1ha2VfbW92ZQogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudGljdGFjdG9lLnRpY3RhY3RvZS5UaWNUYWNUb2VDb250cmFjdC5tYWtlX21vdmUocGxheWVyOiBieXRlcywgbW92ZS4wOiB1aW50NjQsIG1vdmUuMTogdWludDY0KSAtPiB2b2lkOgptYWtlX21vdmU6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjYwLTYxCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIG1ha2VfbW92ZShzZWxmLCBwbGF5ZXI6IGFyYzQuVUludDgsIG1vdmU6IE1vdmUpIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NjMKICAgIC8vIGFzc2VydCBjb2x1bW4gPCAzIGFuZCByb3cgPCAzLCAiTW92ZSBtdXN0IGJlIGluIHJhbmdlIgogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMwogICAgPAogICAgZHVwCiAgICBieiBtYWtlX21vdmVfYm9vbF9mYWxzZUAzCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAzCiAgICA8CiAgICBieiBtYWtlX21vdmVfYm9vbF9mYWxzZUAzCiAgICBpbnQgMQogICAgYiBtYWtlX21vdmVfYm9vbF9tZXJnZUA0CgptYWtlX21vdmVfYm9vbF9mYWxzZUAzOgogICAgaW50IDAKCm1ha2VfbW92ZV9ib29sX21lcmdlQDQ6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjYzCiAgICAvLyBhc3NlcnQgY29sdW1uIDwgMyBhbmQgcm93IDwgMywgIk1vdmUgbXVzdCBiZSBpbiByYW5nZSIKICAgIGFzc2VydCAvLyBNb3ZlIG11c3QgYmUgaW4gcmFuZ2UKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NjQKICAgIC8vIGFzc2VydCBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID09IEVNUFRZLCAiU3F1YXJlIGlzIGFscmVhZHkgdGFrZW4iCiAgICBpbnQgMAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozMQogICAgLy8gc2VsZi5nYW1lID0gR2FtZS5mcm9tX2J5dGVzKG9wLmJ6ZXJvKDkpKQogICAgYnl0ZSAiZ2FtZSIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NjQKICAgIC8vIGFzc2VydCBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID09IEVNUFRZLCAiU3F1YXJlIGlzIGFscmVhZHkgdGFrZW4iCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ2FtZSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgICoKICAgIGR1cAogICAgY292ZXIgMgogICAgaW50IDMKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMQogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBieXRlIDB4MDAKICAgIGI9PQogICAgYXNzZXJ0IC8vIFNxdWFyZSBpcyBhbHJlYWR5IHRha2VuCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjY1CiAgICAvLyBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID0gcGxheWVyCiAgICBpbnQgMAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozMQogICAgLy8gc2VsZi5nYW1lID0gR2FtZS5mcm9tX2J5dGVzKG9wLmJ6ZXJvKDkpKQogICAgYnl0ZSAiZ2FtZSIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NjUKICAgIC8vIHNlbGYuZ2FtZVtyb3ddW2NvbHVtbl0gPSBwbGF5ZXIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nYW1lIGV4aXN0cwogICAgZGlnIDEKICAgIGludCAzCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAwCiAgICBhc3NlcnQgLy8gSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0zCiAgICByZXBsYWNlMwogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzEKICAgIC8vIHNlbGYuZ2FtZSA9IEdhbWUuZnJvbV9ieXRlcyhvcC5iemVybyg5KSkKICAgIGJ5dGUgImdhbWUiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjY1CiAgICAvLyBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID0gcGxheWVyCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ2FtZSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgIDwKICAgIGFzc2VydCAvLyBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgY292ZXIgMgogICAgcmVwbGFjZTMKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzEKICAgIC8vIHNlbGYuZ2FtZSA9IEdhbWUuZnJvbV9ieXRlcyhvcC5iemVybyg5KSkKICAgIGJ5dGUgImdhbWUiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjY1CiAgICAvLyBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID0gcGxheWVyCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo2NgogICAgLy8gc2VsZi50dXJucyArPSAxCiAgICBpbnQgMAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozNQogICAgLy8gc2VsZi50dXJucyA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidHVybnMiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjY2CiAgICAvLyBzZWxmLnR1cm5zICs9IDEKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi50dXJucyBleGlzdHMKICAgIGludCAxCiAgICArCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjM1CiAgICAvLyBzZWxmLnR1cm5zID0gVUludDY0KDApCiAgICBieXRlICJ0dXJucyIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NjYKICAgIC8vIHNlbGYudHVybnMgKz0gMQogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NjcKICAgIC8vIGlmIHNlbGYuZGlkX3dpbihwbGF5ZXIsIGNvbHVtbj1jb2x1bW4sIHJvdz1yb3cpOgogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgY2FsbHN1YiBkaWRfd2luCiAgICBieiBtYWtlX21vdmVfZWxzZV9ib2R5QDYKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTgKICAgIC8vIHNlbGYud2lubmVyID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50OCkKICAgIGJ5dGUgIndpbm5lciIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NjgKICAgIC8vIHNlbGYud2lubmVyLnZhbHVlID0gcGxheWVyCiAgICBmcmFtZV9kaWcgLTMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICBiIG1ha2VfbW92ZV9hZnRlcl9pZl9lbHNlQDkKCm1ha2VfbW92ZV9lbHNlX2JvZHlANjoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NjkKICAgIC8vIGVsaWYgc2VsZi50dXJucyA9PSA5OgogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzUKICAgIC8vIHNlbGYudHVybnMgPSBVSW50NjQoMCkKICAgIGJ5dGUgInR1cm5zIgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo2OQogICAgLy8gZWxpZiBzZWxmLnR1cm5zID09IDk6CiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudHVybnMgZXhpc3RzCiAgICBpbnQgOQogICAgPT0KICAgIGJ6IG1ha2VfbW92ZV9hZnRlcl9pZl9lbHNlQDkKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTgKICAgIC8vIHNlbGYud2lubmVyID0gR2xvYmFsU3RhdGUoYXJjNC5VSW50OCkKICAgIGJ5dGUgIndpbm5lciIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NzAKICAgIC8vIHNlbGYud2lubmVyLnZhbHVlID0gYXJjNC5VSW50OChEUkFXKQogICAgYnl0ZSAweDAzCiAgICBhcHBfZ2xvYmFsX3B1dAoKbWFrZV9tb3ZlX2FmdGVyX2lmX2Vsc2VAOToKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnRpY3RhY3RvZS50aWN0YWN0b2UuVGljVGFjVG9lQ29udHJhY3QuZGlkX3dpbihwbGF5ZXI6IGJ5dGVzLCBjb2x1bW46IHVpbnQ2NCwgcm93OiB1aW50NjQpIC0+IHVpbnQ2NDoKZGlkX3dpbjoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NzItNzMKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgZGlkX3dpbihzZWxmLCBwbGF5ZXI6IGFyYzQuVUludDgsIGNvbHVtbjogVUludDY0LCByb3c6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIHByb3RvIDMgMQogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NzQKICAgIC8vIGcgPSBzZWxmLmdhbWUuY29weSgpCiAgICBkdXBuIDMKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzEKICAgIC8vIHNlbGYuZ2FtZSA9IEdhbWUuZnJvbV9ieXRlcyhvcC5iemVybyg5KSkKICAgIGJ5dGUgImdhbWUiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5Ojc0CiAgICAvLyBnID0gc2VsZi5nYW1lLmNvcHkoKQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHN3YXAKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nYW1lIGV4aXN0cwogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo3NgogICAgLy8gaWYgZ1tyb3ddWzBdID09IGdbcm93XVsxXSA9PSBnW3Jvd11bMl06CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAzCiAgICAqCiAgICBpbnQgMwogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkdXBuIDIKICAgIGV4dHJhY3QgMCAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgc3dhcAogICAgZXh0cmFjdCAxIDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGI9PQogICAgYnogZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDMKICAgIGZyYW1lX2RpZyA0CiAgICBleHRyYWN0IDIgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyA1CiAgICBiPT0KICAgIGJ6IGRpZF93aW5fYWZ0ZXJfaWZfZWxzZUAzCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5Ojc3CiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgpkaWRfd2luX2FmdGVyX2lmX2Vsc2VAMzoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NzkKICAgIC8vIGlmIGdbMF1bY29sdW1uXSA9PSBnWzFdW2NvbHVtbl0gPT0gZ1syXVtjb2x1bW5dOgogICAgZnJhbWVfZGlnIDMKICAgIGR1cAogICAgZXh0cmFjdCAwIDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMQogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMQogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBzd2FwCiAgICBleHRyYWN0IDMgMyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGR1cAogICAgZnJhbWVfYnVyeSAyCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAxCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGR1cAogICAgZnJhbWVfYnVyeSAwCiAgICBiPT0KICAgIGJ6IGRpZF93aW5fYWZ0ZXJfaWZfZWxzZUA2CiAgICBmcmFtZV9kaWcgMwogICAgZXh0cmFjdCA2IDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAxCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAwCiAgICBiPT0KICAgIGJ6IGRpZF93aW5fYWZ0ZXJfaWZfZWxzZUA2CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjgwCiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgpkaWRfd2luX2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6ODItODMKICAgIC8vICMgaWYgcGxheWVyIG93bnMgY2VudGVyLCBjaGVjayBkaWFnb25hbHMKICAgIC8vIGlmIHBsYXllciA9PSBnWzFdWzFdOgogICAgZnJhbWVfZGlnIDIKICAgIGV4dHJhY3QgMSAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIC0zCiAgICBiPT0KICAgIGJ6IGRpZF93aW5fYWZ0ZXJfaWZfZWxzZUAxNAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo4NAogICAgLy8gaWYgZ1swXVswXSA9PSBwbGF5ZXIgPT0gZ1syXVsyXToKICAgIGZyYW1lX2RpZyAxCiAgICBleHRyYWN0IDAgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAtMwogICAgYj09CiAgICBieiBkaWRfd2luX2FmdGVyX2lmX2Vsc2VAMTAKICAgIGZyYW1lX2RpZyAzCiAgICBleHRyYWN0IDYgMyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGV4dHJhY3QgMiAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIC0zCiAgICBiPT0KICAgIGJ6IGRpZF93aW5fYWZ0ZXJfaWZfZWxzZUAxMAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo4NQogICAgLy8gcmV0dXJuIFRydWUKICAgIGludCAxCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDEwOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo4NgogICAgLy8gaWYgZ1swXVsyXSA9PSBwbGF5ZXIgPT0gZ1syXVswXToKICAgIGZyYW1lX2RpZyAxCiAgICBleHRyYWN0IDIgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAtMwogICAgYj09CiAgICBieiBkaWRfd2luX2FmdGVyX2lmX2Vsc2VAMTQKICAgIGZyYW1lX2RpZyAzCiAgICBleHRyYWN0IDYgMyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGV4dHJhY3QgMCAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIC0zCiAgICBiPT0KICAgIGJ6IGRpZF93aW5fYWZ0ZXJfaWZfZWxzZUAxNAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo4NwogICAgLy8gcmV0dXJuIFRydWUKICAgIGludCAxCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDE0OgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo4OAogICAgLy8gcmV0dXJuIEZhbHNlCiAgICBpbnQgMAogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy50aWN0YWN0b2UudGljdGFjdG9lLlRpY1RhY1RvZUNvbnRyYWN0Lndob3NlX3R1cm4oKSAtPiBieXRlczoKd2hvc2VfdHVybjoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NDMtNDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHdob3NlX3R1cm4oc2VsZikgLT4gYXJjNC5VSW50ODoKICAgIHByb3RvIDAgMQogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo0NQogICAgLy8gcmV0dXJuIGFyYzQuVUludDgoSE9TVCkgaWYgc2VsZi50dXJucyAlIDIgZWxzZSBhcmM0LlVJbnQ4KENIQUxMRU5HRVIpCiAgICBpbnQgMAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozNQogICAgLy8gc2VsZi50dXJucyA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidHVybnMiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjQ1CiAgICAvLyByZXR1cm4gYXJjNC5VSW50OChIT1NUKSBpZiBzZWxmLnR1cm5zICUgMiBlbHNlIGFyYzQuVUludDgoQ0hBTExFTkdFUikKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi50dXJucyBleGlzdHMKICAgIGludCAyCiAgICAlCiAgICBieXRlIDB4MDIKICAgIGJ5dGUgMHgwMQogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnRpY3RhY3RvZS50aWN0YWN0b2UuVGljVGFjVG9lQ29udHJhY3QucGxheShtb3ZlLjA6IHVpbnQ2NCwgbW92ZS4xOiB1aW50NjQpIC0+IHZvaWQ6CnBsYXk6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjQ3LTQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBwbGF5KHNlbGYsIG1vdmU6IE1vdmUpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NDkKICAgIC8vIGFzc2VydCBub3Qgc2VsZi53aW5uZXIsICJHYW1lIGlzIGFscmVhZHkgZmluaXNoZWQiCiAgICBpbnQgMAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToxOAogICAgLy8gc2VsZi53aW5uZXIgPSBHbG9iYWxTdGF0ZShhcmM0LlVJbnQ4KQogICAgYnl0ZSAid2lubmVyIgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo0OQogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLndpbm5lciwgIkdhbWUgaXMgYWxyZWFkeSBmaW5pc2hlZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgICEKICAgIGFzc2VydCAvLyBHYW1lIGlzIGFscmVhZHkgZmluaXNoZWQKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NTAKICAgIC8vIGlmIHNlbGYudHVybnMgJSAyOgogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzUKICAgIC8vIHNlbGYudHVybnMgPSBVSW50NjQoMCkKICAgIGJ5dGUgInR1cm5zIgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1MAogICAgLy8gaWYgc2VsZi50dXJucyAlIDI6CiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudHVybnMgZXhpc3RzCiAgICBpbnQgMgogICAgJQogICAgYnogcGxheV9lbHNlX2JvZHlAMgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1MQogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gc2VsZi5ob3N0LCAiSXQgaXMgdGhlIGhvc3QncyB0dXJuIgogICAgdHhuIFNlbmRlcgogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzAKICAgIC8vIHNlbGYuaG9zdCA9IFR4bi5zZW5kZXIKICAgIGJ5dGUgImhvc3QiCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjUxCiAgICAvLyBhc3NlcnQgVHhuLnNlbmRlciA9PSBzZWxmLmhvc3QsICJJdCBpcyB0aGUgaG9zdCdzIHR1cm4iCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaG9zdCBleGlzdHMKICAgID09CiAgICBhc3NlcnQgLy8gSXQgaXMgdGhlIGhvc3QncyB0dXJuCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjUyCiAgICAvLyBwbGF5ZXIgPSBhcmM0LlVJbnQ4KEhPU1QpCiAgICBieXRlIDB4MDEKICAgIGIgcGxheV9hZnRlcl9pZl9lbHNlQDMKCnBsYXlfZWxzZV9ib2R5QDI6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjU0CiAgICAvLyBhc3NlcnQgVHhuLnNlbmRlciA9PSBzZWxmLmNoYWxsZW5nZXIuZ2V0KAogICAgdHhuIFNlbmRlcgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1NQogICAgLy8gZGVmYXVsdD1BY2NvdW50KCkKICAgIGdsb2JhbCBaZXJvQWRkcmVzcwogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1NAogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gc2VsZi5jaGFsbGVuZ2VyLmdldCgKICAgIGludCAwCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjE3CiAgICAvLyBzZWxmLmNoYWxsZW5nZXIgPSBHbG9iYWxTdGF0ZShBY2NvdW50KQogICAgYnl0ZSAiY2hhbGxlbmdlciIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NTQtNTYKICAgIC8vIGFzc2VydCBUeG4uc2VuZGVyID09IHNlbGYuY2hhbGxlbmdlci5nZXQoCiAgICAvLyAgICAgZGVmYXVsdD1BY2NvdW50KCkKICAgIC8vICksICJJdCBpcyB0aGUgY2hhbGxlbmdlcidzIHR1cm4iCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgc2VsZWN0CiAgICA9PQogICAgYXNzZXJ0IC8vIEl0IGlzIHRoZSBjaGFsbGVuZ2VyJ3MgdHVybgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1NwogICAgLy8gcGxheWVyID0gYXJjNC5VSW50OChDSEFMTEVOR0VSKQogICAgYnl0ZSAweDAyCgpwbGF5X2FmdGVyX2lmX2Vsc2VAMzoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NTgKICAgIC8vIHNlbGYubWFrZV9tb3ZlKHBsYXllciwgbW92ZSkKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBjYWxsc3ViIG1ha2VfbW92ZQogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy50aWN0YWN0b2UudGljdGFjdG9lLlRpY1RhY1RvZUNvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyBleGFtcGxlcy50aWN0YWN0b2UudGljdGFjdG9lLlRpY1RhY1RvZUNvbnRyYWN0Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTUKICAgIC8vIGNsYXNzIFRpY1RhY1RvZUNvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAOQogICAgbWV0aG9kICJuZXdfZ2FtZSgodWludDY0LHVpbnQ2NCkpdm9pZCIKICAgIG1ldGhvZCAiam9pbl9nYW1lKCh1aW50NjQsdWludDY0KSl2b2lkIgogICAgbWV0aG9kICJ3aG9zZV90dXJuKCl1aW50OCIKICAgIG1ldGhvZCAicGxheSgodWludDY0LHVpbnQ2NCkpdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX25ld19nYW1lX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fam9pbl9nYW1lX3JvdXRlQDMgX19wdXlhX2FyYzRfcm91dGVyX19fd2hvc2VfdHVybl9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX3BsYXlfcm91dGVANQogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fbmV3X2dhbWVfcm91dGVAMjoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChjcmVhdGU9ImFsbG93IikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToxNQogICAgLy8gY2xhc3MgVGljVGFjVG9lQ29udHJhY3QoYXJjNC5BUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZHVwCiAgICBleHRyYWN0IDAgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGV4dHJhY3QgOCA4IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgc3dhcAogICAgYnRvaQogICAgc3dhcAogICAgYnRvaQogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToyMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0iYWxsb3ciKQogICAgY2FsbHN1YiBuZXdfZ2FtZQogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fam9pbl9nYW1lX3JvdXRlQDM6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTUKICAgIC8vIGNsYXNzIFRpY1RhY1RvZUNvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGR1cAogICAgZXh0cmFjdCAwIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBzd2FwCiAgICBleHRyYWN0IDggOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBqb2luX2dhbWUKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3dob3NlX3R1cm5fcm91dGVANDoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NDMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiB3aG9zZV90dXJuCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19wbGF5X3JvdXRlQDU6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjQ3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MTUKICAgIC8vIGNsYXNzIFRpY1RhY1RvZUNvbnRyYWN0KGFyYzQuQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGR1cAogICAgZXh0cmFjdCAwIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBzd2FwCiAgICBleHRyYWN0IDggOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGJ0b2kKICAgIHN3YXAKICAgIGJ0b2kKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NDcKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBwbGF5CiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDk6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjE1CiAgICAvLyBjbGFzcyBUaWNUYWNUb2VDb250cmFjdChhcmM0LkFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudGljdGFjdG9lLnRpY3RhY3RvZS5UaWNUYWNUb2VDb250cmFjdC5uZXdfZ2FtZShtb3ZlLjA6IHVpbnQ2NCwgbW92ZS4xOiB1aW50NjQpIC0+IHZvaWQ6Cm5ld19nYW1lOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToyMC0yMQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0iYWxsb3ciKQogICAgLy8gZGVmIG5ld19nYW1lKHNlbGYsIG1vdmU6IE1vdmUpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIGJ5dGUgIiIKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MjIKICAgIC8vIGlmIFR4bi5hcHBsaWNhdGlvbl9pZDoKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBieiBuZXdfZ2FtZV9hZnRlcl9pZl9lbHNlQDQKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MjMtMjUKICAgIC8vICMgaWYgYSBjaGFsbGVuZ2VyIGhhcyBqb2luZWQsIGRvbid0IGFsbG93IHN0YXJ0aW5nIGEgbmV3IGdhbWUKICAgIC8vICMgdW50aWwgdGhpcyBvbmUgaXMgY29tcGxldGUKICAgIC8vIGlmIHNlbGYuY2hhbGxlbmdlcjoKICAgIGludCAwCiAgICBieXRlICJjaGFsbGVuZ2VyIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYnogbmV3X2dhbWVfYWZ0ZXJfaWZfZWxzZUAzCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjI2CiAgICAvLyBhc3NlcnQgc2VsZi53aW5uZXIsICJHYW1lIGlzbid0IG92ZXIiCiAgICBpbnQgMAogICAgYnl0ZSAid2lubmVyIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYXNzZXJ0IC8vIEdhbWUgaXNuJ3Qgb3ZlcgoKbmV3X2dhbWVfYWZ0ZXJfaWZfZWxzZUAzOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToyNy0yOAogICAgLy8gIyByZXNldCBjaGFsbGVuZ2VyIGFuZCB3aW5uZXIKICAgIC8vIGRlbCBzZWxmLmNoYWxsZW5nZXIudmFsdWUKICAgIGJ5dGUgImNoYWxsZW5nZXIiCiAgICBhcHBfZ2xvYmFsX2RlbAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weToyOQogICAgLy8gZGVsIHNlbGYud2lubmVyLnZhbHVlCiAgICBieXRlICJ3aW5uZXIiCiAgICBhcHBfZ2xvYmFsX2RlbAoKbmV3X2dhbWVfYWZ0ZXJfaWZfZWxzZUA0OgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozMAogICAgLy8gc2VsZi5ob3N0ID0gVHhuLnNlbmRlcgogICAgYnl0ZSAiaG9zdCIKICAgIHR4biBTZW5kZXIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjMxCiAgICAvLyBzZWxmLmdhbWUgPSBHYW1lLmZyb21fYnl0ZXMob3AuYnplcm8oOSkpCiAgICBpbnQgOQogICAgYnplcm8KICAgIGJ5dGUgImdhbWUiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozMwogICAgLy8gYXNzZXJ0IGNvbHVtbiA8IDMgYW5kIHJvdyA8IDMsICJNb3ZlIG11c3QgYmUgaW4gcmFuZ2UiCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAzCiAgICA8CiAgICBkdXAKICAgIGZyYW1lX2J1cnkgMAogICAgYnogbmV3X2dhbWVfYm9vbF9mYWxzZUA3CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAzCiAgICA8CiAgICBieiBuZXdfZ2FtZV9ib29sX2ZhbHNlQDcKICAgIGludCAxCiAgICBiIG5ld19nYW1lX2Jvb2xfbWVyZ2VAOAoKbmV3X2dhbWVfYm9vbF9mYWxzZUA3OgogICAgaW50IDAKCm5ld19nYW1lX2Jvb2xfbWVyZ2VAODoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzMKICAgIC8vIGFzc2VydCBjb2x1bW4gPCAzIGFuZCByb3cgPCAzLCAiTW92ZSBtdXN0IGJlIGluIHJhbmdlIgogICAgYXNzZXJ0IC8vIE1vdmUgbXVzdCBiZSBpbiByYW5nZQogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozNAogICAgLy8gc2VsZi5nYW1lW3Jvd11bY29sdW1uXSA9IGFyYzQuVUludDgoSE9TVCkKICAgIGludCAwCiAgICBieXRlICJnYW1lIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdhbWUgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAzCiAgICAqCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludCAzCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAwCiAgICBhc3NlcnQgLy8gSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAtMgogICAgYnl0ZSAweDAxCiAgICByZXBsYWNlMwogICAgaW50IDAKICAgIGJ5dGUgImdhbWUiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ2FtZSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgIDwKICAgIGFzc2VydCAvLyBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgY292ZXIgMgogICAgcmVwbGFjZTMKICAgIGJ5dGUgImdhbWUiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozNQogICAgLy8gc2VsZi50dXJucyA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidHVybnMiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnRpY3RhY3RvZS50aWN0YWN0b2UuVGljVGFjVG9lQ29udHJhY3Quam9pbl9nYW1lKG1vdmUuMDogdWludDY0LCBtb3ZlLjE6IHVpbnQ2NCkgLT4gdm9pZDoKam9pbl9nYW1lOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTozNy0zOAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgam9pbl9nYW1lKHNlbGYsIG1vdmU6IE1vdmUpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6MzkKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5jaGFsbGVuZ2VyLCAiSG9zdCBhbHJlYWR5IGhhcyBhIGNoYWxsZW5nZXIiCiAgICBpbnQgMAogICAgYnl0ZSAiY2hhbGxlbmdlciIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgICEKICAgIGFzc2VydCAvLyBIb3N0IGFscmVhZHkgaGFzIGEgY2hhbGxlbmdlcgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo0MAogICAgLy8gc2VsZi5jaGFsbGVuZ2VyLnZhbHVlID0gVHhuLnNlbmRlcgogICAgYnl0ZSAiY2hhbGxlbmdlciIKICAgIHR4biBTZW5kZXIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjQxCiAgICAvLyBzZWxmLm1ha2VfbW92ZShhcmM0LlVJbnQ4KENIQUxMRU5HRVIpLCBtb3ZlKQogICAgYnl0ZSAweDAyCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgY2FsbHN1YiBtYWtlX21vdmUKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnRpY3RhY3RvZS50aWN0YWN0b2UuVGljVGFjVG9lQ29udHJhY3QubWFrZV9tb3ZlKHBsYXllcjogYnl0ZXMsIG1vdmUuMDogdWludDY0LCBtb3ZlLjE6IHVpbnQ2NCkgLT4gdm9pZDoKbWFrZV9tb3ZlOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo2MC02MQogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBtYWtlX21vdmUoc2VsZiwgcGxheWVyOiBhcmM0LlVJbnQ4LCBtb3ZlOiBNb3ZlKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjYzCiAgICAvLyBhc3NlcnQgY29sdW1uIDwgMyBhbmQgcm93IDwgMywgIk1vdmUgbXVzdCBiZSBpbiByYW5nZSIKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDMKICAgIDwKICAgIGR1cAogICAgYnogbWFrZV9tb3ZlX2Jvb2xfZmFsc2VAMwogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMwogICAgPAogICAgYnogbWFrZV9tb3ZlX2Jvb2xfZmFsc2VAMwogICAgaW50IDEKICAgIGIgbWFrZV9tb3ZlX2Jvb2xfbWVyZ2VANAoKbWFrZV9tb3ZlX2Jvb2xfZmFsc2VAMzoKICAgIGludCAwCgptYWtlX21vdmVfYm9vbF9tZXJnZUA0OgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo2MwogICAgLy8gYXNzZXJ0IGNvbHVtbiA8IDMgYW5kIHJvdyA8IDMsICJNb3ZlIG11c3QgYmUgaW4gcmFuZ2UiCiAgICBhc3NlcnQgLy8gTW92ZSBtdXN0IGJlIGluIHJhbmdlCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjY0CiAgICAvLyBhc3NlcnQgc2VsZi5nYW1lW3Jvd11bY29sdW1uXSA9PSBFTVBUWSwgIlNxdWFyZSBpcyBhbHJlYWR5IHRha2VuIgogICAgaW50IDAKICAgIGJ5dGUgImdhbWUiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ2FtZSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgICoKICAgIGR1cAogICAgY292ZXIgMgogICAgaW50IDMKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMQogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBieXRlIDB4MDAKICAgIGI9PQogICAgYXNzZXJ0IC8vIFNxdWFyZSBpcyBhbHJlYWR5IHRha2VuCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjY1CiAgICAvLyBzZWxmLmdhbWVbcm93XVtjb2x1bW5dID0gcGxheWVyCiAgICBpbnQgMAogICAgYnl0ZSAiZ2FtZSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nYW1lIGV4aXN0cwogICAgZGlnIDEKICAgIGludCAzCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAwCiAgICBhc3NlcnQgLy8gSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0zCiAgICByZXBsYWNlMwogICAgaW50IDAKICAgIGJ5dGUgImdhbWUiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ2FtZSBleGlzdHMKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgIDwKICAgIGFzc2VydCAvLyBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgY292ZXIgMgogICAgcmVwbGFjZTMKICAgIGJ5dGUgImdhbWUiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo2NgogICAgLy8gc2VsZi50dXJucyArPSAxCiAgICBpbnQgMAogICAgYnl0ZSAidHVybnMiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudHVybnMgZXhpc3RzCiAgICBpbnQgMQogICAgKwogICAgYnl0ZSAidHVybnMiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo2NwogICAgLy8gaWYgc2VsZi5kaWRfd2luKHBsYXllciwgY29sdW1uPWNvbHVtbiwgcm93PXJvdyk6CiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICBjYWxsc3ViIGRpZF93aW4KICAgIGJ6IG1ha2VfbW92ZV9lbHNlX2JvZHlANgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo2OAogICAgLy8gc2VsZi53aW5uZXIudmFsdWUgPSBwbGF5ZXIKICAgIGJ5dGUgIndpbm5lciIKICAgIGZyYW1lX2RpZyAtMwogICAgYXBwX2dsb2JhbF9wdXQKICAgIGIgbWFrZV9tb3ZlX2FmdGVyX2lmX2Vsc2VAOQoKbWFrZV9tb3ZlX2Vsc2VfYm9keUA2OgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo2OQogICAgLy8gZWxpZiBzZWxmLnR1cm5zID09IDk6CiAgICBpbnQgMAogICAgYnl0ZSAidHVybnMiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudHVybnMgZXhpc3RzCiAgICBpbnQgOQogICAgPT0KICAgIGJ6IG1ha2VfbW92ZV9hZnRlcl9pZl9lbHNlQDkKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NzAKICAgIC8vIHNlbGYud2lubmVyLnZhbHVlID0gYXJjNC5VSW50OChEUkFXKQogICAgYnl0ZSAid2lubmVyIgogICAgYnl0ZSAweDAzCiAgICBhcHBfZ2xvYmFsX3B1dAoKbWFrZV9tb3ZlX2FmdGVyX2lmX2Vsc2VAOToKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnRpY3RhY3RvZS50aWN0YWN0b2UuVGljVGFjVG9lQ29udHJhY3QuZGlkX3dpbihwbGF5ZXI6IGJ5dGVzLCBjb2x1bW46IHVpbnQ2NCwgcm93OiB1aW50NjQpIC0+IHVpbnQ2NDoKZGlkX3dpbjoKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NzItNzMKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgZGlkX3dpbihzZWxmLCBwbGF5ZXI6IGFyYzQuVUludDgsIGNvbHVtbjogVUludDY0LCByb3c6IFVJbnQ2NCkgLT4gYm9vbDoKICAgIHByb3RvIDMgMQogICAgaW50IDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NzQKICAgIC8vIGcgPSBzZWxmLmdhbWUuY29weSgpCiAgICBkdXBuIDMKICAgIGJ5dGUgImdhbWUiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgc3dhcAogICAgZHVwCiAgICB1bmNvdmVyIDIKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdhbWUgZXhpc3RzCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5Ojc2CiAgICAvLyBpZiBnW3Jvd11bMF0gPT0gZ1tyb3ddWzFdID09IGdbcm93XVsyXToKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgICoKICAgIGludCAzCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGR1cG4gMgogICAgZXh0cmFjdCAwIDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBzd2FwCiAgICBleHRyYWN0IDEgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGR1cAogICAgY292ZXIgMgogICAgYj09CiAgICBieiBkaWRfd2luX2FmdGVyX2lmX2Vsc2VAMwogICAgZnJhbWVfZGlnIDQKICAgIGV4dHJhY3QgMiAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIDUKICAgIGI9PQogICAgYnogZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDMKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NzcKICAgIC8vIHJldHVybiBUcnVlCiAgICBpbnQgMQogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCmRpZF93aW5fYWZ0ZXJfaWZfZWxzZUAzOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo3OQogICAgLy8gaWYgZ1swXVtjb2x1bW5dID09IGdbMV1bY29sdW1uXSA9PSBnWzJdW2NvbHVtbl06CiAgICBmcmFtZV9kaWcgMwogICAgZHVwCiAgICBleHRyYWN0IDAgMyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGR1cAogICAgZnJhbWVfYnVyeSAxCiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAxCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHN3YXAKICAgIGV4dHJhY3QgMyAzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZHVwCiAgICBmcmFtZV9idXJ5IDIKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDEKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZHVwCiAgICBmcmFtZV9idXJ5IDAKICAgIGI9PQogICAgYnogZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDYKICAgIGZyYW1lX2RpZyAzCiAgICBleHRyYWN0IDYgMyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDEKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIDAKICAgIGI9PQogICAgYnogZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDYKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6ODAKICAgIC8vIHJldHVybiBUcnVlCiAgICBpbnQgMQogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCmRpZF93aW5fYWZ0ZXJfaWZfZWxzZUA2OgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo4Mi04MwogICAgLy8gIyBpZiBwbGF5ZXIgb3ducyBjZW50ZXIsIGNoZWNrIGRpYWdvbmFscwogICAgLy8gaWYgcGxheWVyID09IGdbMV1bMV06CiAgICBmcmFtZV9kaWcgMgogICAgZXh0cmFjdCAxIDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBmcmFtZV9kaWcgLTMKICAgIGI9PQogICAgYnogZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDE0CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5Ojg0CiAgICAvLyBpZiBnWzBdWzBdID09IHBsYXllciA9PSBnWzJdWzJdOgogICAgZnJhbWVfZGlnIDEKICAgIGV4dHJhY3QgMCAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIC0zCiAgICBiPT0KICAgIGJ6IGRpZF93aW5fYWZ0ZXJfaWZfZWxzZUAxMAogICAgZnJhbWVfZGlnIDMKICAgIGV4dHJhY3QgNiAzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZXh0cmFjdCAyIDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBmcmFtZV9kaWcgLTMKICAgIGI9PQogICAgYnogZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDEwCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5Ojg1CiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgpkaWRfd2luX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5Ojg2CiAgICAvLyBpZiBnWzBdWzJdID09IHBsYXllciA9PSBnWzJdWzBdOgogICAgZnJhbWVfZGlnIDEKICAgIGV4dHJhY3QgMiAxIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZnJhbWVfZGlnIC0zCiAgICBiPT0KICAgIGJ6IGRpZF93aW5fYWZ0ZXJfaWZfZWxzZUAxNAogICAgZnJhbWVfZGlnIDMKICAgIGV4dHJhY3QgNiAzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZXh0cmFjdCAwIDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBmcmFtZV9kaWcgLTMKICAgIGI9PQogICAgYnogZGlkX3dpbl9hZnRlcl9pZl9lbHNlQDE0CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5Ojg3CiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgpkaWRfd2luX2FmdGVyX2lmX2Vsc2VAMTQ6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5Ojg4CiAgICAvLyByZXR1cm4gRmFsc2UKICAgIGludCAwCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnRpY3RhY3RvZS50aWN0YWN0b2UuVGljVGFjVG9lQ29udHJhY3Qud2hvc2VfdHVybigpIC0+IGJ5dGVzOgp3aG9zZV90dXJuOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo0My00NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgd2hvc2VfdHVybihzZWxmKSAtPiBhcmM0LlVJbnQ4OgogICAgcHJvdG8gMCAxCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjQ1CiAgICAvLyByZXR1cm4gYXJjNC5VSW50OChIT1NUKSBpZiBzZWxmLnR1cm5zICUgMiBlbHNlIGFyYzQuVUludDgoQ0hBTExFTkdFUikKICAgIGludCAwCiAgICBieXRlICJ0dXJucyIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi50dXJucyBleGlzdHMKICAgIGludCAyCiAgICAlCiAgICBieXRlIDB4MDIKICAgIGJ5dGUgMHgwMQogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnRpY3RhY3RvZS50aWN0YWN0b2UuVGljVGFjVG9lQ29udHJhY3QucGxheShtb3ZlLjA6IHVpbnQ2NCwgbW92ZS4xOiB1aW50NjQpIC0+IHZvaWQ6CnBsYXk6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjQ3LTQ4CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBwbGF5KHNlbGYsIG1vdmU6IE1vdmUpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIHRpY3RhY3RvZS90aWN0YWN0b2UucHk6NDkKICAgIC8vIGFzc2VydCBub3Qgc2VsZi53aW5uZXIsICJHYW1lIGlzIGFscmVhZHkgZmluaXNoZWQiCiAgICBpbnQgMAogICAgYnl0ZSAid2lubmVyIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgIQogICAgYXNzZXJ0IC8vIEdhbWUgaXMgYWxyZWFkeSBmaW5pc2hlZAogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1MAogICAgLy8gaWYgc2VsZi50dXJucyAlIDI6CiAgICBpbnQgMAogICAgYnl0ZSAidHVybnMiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudHVybnMgZXhpc3RzCiAgICBpbnQgMgogICAgJQogICAgYnogcGxheV9lbHNlX2JvZHlAMgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1MQogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gc2VsZi5ob3N0LCAiSXQgaXMgdGhlIGhvc3QncyB0dXJuIgogICAgdHhuIFNlbmRlcgogICAgaW50IDAKICAgIGJ5dGUgImhvc3QiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaG9zdCBleGlzdHMKICAgID09CiAgICBhc3NlcnQgLy8gSXQgaXMgdGhlIGhvc3QncyB0dXJuCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjUyCiAgICAvLyBwbGF5ZXIgPSBhcmM0LlVJbnQ4KEhPU1QpCiAgICBieXRlIDB4MDEKICAgIGIgcGxheV9hZnRlcl9pZl9lbHNlQDMKCnBsYXlfZWxzZV9ib2R5QDI6CiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjU0CiAgICAvLyBhc3NlcnQgVHhuLnNlbmRlciA9PSBzZWxmLmNoYWxsZW5nZXIuZ2V0KAogICAgdHhuIFNlbmRlcgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1NQogICAgLy8gZGVmYXVsdD1BY2NvdW50KCkKICAgIGdsb2JhbCBaZXJvQWRkcmVzcwogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1NAogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gc2VsZi5jaGFsbGVuZ2VyLmdldCgKICAgIGludCAwCiAgICBieXRlICJjaGFsbGVuZ2VyIgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1NC01NgogICAgLy8gYXNzZXJ0IFR4bi5zZW5kZXIgPT0gc2VsZi5jaGFsbGVuZ2VyLmdldCgKICAgIC8vICAgICBkZWZhdWx0PUFjY291bnQoKQogICAgLy8gKSwgIkl0IGlzIHRoZSBjaGFsbGVuZ2VyJ3MgdHVybiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBzZWxlY3QKICAgID09CiAgICBhc3NlcnQgLy8gSXQgaXMgdGhlIGNoYWxsZW5nZXIncyB0dXJuCiAgICAvLyB0aWN0YWN0b2UvdGljdGFjdG9lLnB5OjU3CiAgICAvLyBwbGF5ZXIgPSBhcmM0LlVJbnQ4KENIQUxMRU5HRVIpCiAgICBieXRlIDB4MDIKCnBsYXlfYWZ0ZXJfaWZfZWxzZUAzOgogICAgLy8gdGljdGFjdG9lL3RpY3RhY3RvZS5weTo1OAogICAgLy8gc2VsZi5tYWtlX21vdmUocGxheWVyLCBtb3ZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGNhbGxzdWIgbWFrZV9tb3ZlCiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy50aWN0YWN0b2UudGljdGFjdG9lLlRpY1RhY1RvZUNvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICBpbnQgMQogICAgcmV0dXJuCg==" }, "state": { diff --git a/examples/tictactoe/out_unoptimized/TicTacToeContract.approval.teal b/examples/tictactoe/out_unoptimized/TicTacToeContract.approval.teal index abb4ff331d..80524551d9 100644 --- a/examples/tictactoe/out_unoptimized/TicTacToeContract.approval.teal +++ b/examples/tictactoe/out_unoptimized/TicTacToeContract.approval.teal @@ -168,13 +168,7 @@ new_game: // # until this one is complete // if self.challenger: int 0 - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) byte "challenger" - // tictactoe/tictactoe.py:23-25 - // # if a challenger has joined, don't allow starting a new game - // # until this one is complete - // if self.challenger: app_global_get_ex cover 1 pop @@ -182,29 +176,21 @@ new_game: // tictactoe/tictactoe.py:26 // assert self.winner, "Game isn't over" int 0 - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) byte "winner" - // tictactoe/tictactoe.py:26 - // assert self.winner, "Game isn't over" app_global_get_ex cover 1 pop assert // Game isn't over new_game_after_if_else@3: - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) - byte "challenger" // tictactoe/tictactoe.py:27-28 // # reset challenger and winner // del self.challenger.value + byte "challenger" app_global_del - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) - byte "winner" // tictactoe/tictactoe.py:29 // del self.winner.value + byte "winner" app_global_del new_game_after_if_else@4: @@ -250,11 +236,7 @@ new_game_bool_merge@8: // tictactoe/tictactoe.py:34 // self.game[row][column] = arc4.UInt8(HOST) int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:34 - // self.game[row][column] = arc4.UInt8(HOST) app_global_get_ex assert // check self.game exists frame_dig 1 @@ -274,11 +256,7 @@ new_game_bool_merge@8: byte 0x01 replace3 int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:34 - // self.game[row][column] = arc4.UInt8(HOST) app_global_get_ex cover 1 cover 2 @@ -294,11 +272,7 @@ new_game_bool_merge@8: uncover 1 uncover 2 replace3 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:34 - // self.game[row][column] = arc4.UInt8(HOST) uncover 1 app_global_put // tictactoe/tictactoe.py:35 @@ -318,11 +292,7 @@ join_game: // tictactoe/tictactoe.py:39 // assert not self.challenger, "Host already has a challenger" int 0 - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) byte "challenger" - // tictactoe/tictactoe.py:39 - // assert not self.challenger, "Host already has a challenger" app_global_get_ex cover 1 pop @@ -331,11 +301,7 @@ join_game: // tictactoe/tictactoe.py:40 // self.challenger.value = Txn.sender txn Sender - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) byte "challenger" - // tictactoe/tictactoe.py:40 - // self.challenger.value = Txn.sender uncover 1 app_global_put // tictactoe/tictactoe.py:41 @@ -382,11 +348,7 @@ make_move_bool_merge@4: // tictactoe/tictactoe.py:64 // assert self.game[row][column] == EMPTY, "Square is already taken" int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:64 - // assert self.game[row][column] == EMPTY, "Square is already taken" app_global_get_ex assert // check self.game exists frame_dig 1 @@ -409,11 +371,7 @@ make_move_bool_merge@4: // tictactoe/tictactoe.py:65 // self.game[row][column] = player int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:65 - // self.game[row][column] = player app_global_get_ex assert // check self.game exists dig 1 @@ -433,11 +391,7 @@ make_move_bool_merge@4: uncover 2 replace3 int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:65 - // self.game[row][column] = player app_global_get_ex cover 1 cover 2 @@ -453,30 +407,18 @@ make_move_bool_merge@4: uncover 1 uncover 2 replace3 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:65 - // self.game[row][column] = player uncover 1 app_global_put // tictactoe/tictactoe.py:66 // self.turns += 1 int 0 - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:66 - // self.turns += 1 app_global_get_ex assert // check self.turns exists int 1 + - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:66 - // self.turns += 1 uncover 1 app_global_put // tictactoe/tictactoe.py:67 @@ -486,11 +428,9 @@ make_move_bool_merge@4: uncover 2 callsub did_win bz make_move_else_body@6 - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) - byte "winner" // tictactoe/tictactoe.py:68 // self.winner.value = player + byte "winner" frame_dig -3 app_global_put b make_move_after_if_else@9 @@ -499,21 +439,15 @@ make_move_else_body@6: // tictactoe/tictactoe.py:69 // elif self.turns == 9: int 0 - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:69 - // elif self.turns == 9: app_global_get_ex assert // check self.turns exists int 9 == bz make_move_after_if_else@8 - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) - byte "winner" // tictactoe/tictactoe.py:70 // self.winner.value = arc4.UInt8(DRAW) + byte "winner" byte 0x03 app_global_put @@ -533,11 +467,7 @@ did_win: // tictactoe/tictactoe.py:74 // g = self.game.copy() int 0 - // tictactoe/tictactoe.py:31 - // self.game = Game.from_bytes(op.bzero(9)) byte "game" - // tictactoe/tictactoe.py:74 - // g = self.game.copy() app_global_get_ex assert // check self.game exists dup @@ -750,11 +680,7 @@ whose_turn: // tictactoe/tictactoe.py:45 // return arc4.UInt8(HOST) if self.turns % 2 else arc4.UInt8(CHALLENGER) int 0 - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:45 - // return arc4.UInt8(HOST) if self.turns % 2 else arc4.UInt8(CHALLENGER) app_global_get_ex assert // check self.turns exists int 2 @@ -777,11 +703,7 @@ play: // tictactoe/tictactoe.py:49 // assert not self.winner, "Game is already finished" int 0 - // tictactoe/tictactoe.py:18 - // self.winner = GlobalState(arc4.UInt8) byte "winner" - // tictactoe/tictactoe.py:49 - // assert not self.winner, "Game is already finished" app_global_get_ex cover 1 pop @@ -790,11 +712,7 @@ play: // tictactoe/tictactoe.py:50 // if self.turns % 2: int 0 - // tictactoe/tictactoe.py:35 - // self.turns = UInt64(0) byte "turns" - // tictactoe/tictactoe.py:50 - // if self.turns % 2: app_global_get_ex assert // check self.turns exists int 2 @@ -806,11 +724,7 @@ play: // assert Txn.sender == self.host, "It is the host's turn" txn Sender int 0 - // tictactoe/tictactoe.py:30 - // self.host = Txn.sender byte "host" - // tictactoe/tictactoe.py:51 - // assert Txn.sender == self.host, "It is the host's turn" app_global_get_ex assert // check self.host exists == @@ -830,8 +744,6 @@ play_else_body@2: // tictactoe/tictactoe.py:54 // assert Txn.sender == self.challenger.get( int 0 - // tictactoe/tictactoe.py:17 - // self.challenger = GlobalState(Account) byte "challenger" // tictactoe/tictactoe.py:54-56 // assert Txn.sender == self.challenger.get( diff --git a/examples/voting/out/VotingRoundApp.approval.mir b/examples/voting/out/VotingRoundApp.approval.mir index 9673144970..c790b2bd25 100644 --- a/examples/voting/out/VotingRoundApp.approval.mir +++ b/examples/voting/out/VotingRoundApp.approval.mir @@ -360,7 +360,7 @@ bootstrap: bootstrap_block@0: int 0 // (𝕡) fund_min_bal_req#0 | 0 self.is_bootstrapped voting/voting.py:84 - byte "is_bootstrapped" // (𝕡) fund_min_bal_req#0 | 0,"is_bootstrapped" self.is_bootstrapped voting/voting.py:51 + byte "is_bootstrapped" // (𝕡) fund_min_bal_req#0 | 0,"is_bootstrapped" self.is_bootstrapped voting/voting.py:84 app_global_get_ex // (𝕡) fund_min_bal_req#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.is_bootstrapped voting/voting.py:84 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.is_bootstrapped voting/voting.py:84 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | maybe_value%0#0,maybe_exists%0#0 self.is_bootstrapped voting/voting.py:84 @@ -371,7 +371,7 @@ bootstrap_block@0: // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | tmp%0#0 not self.is_bootstrapped voting/voting.py:84 // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0 | tmp%0#0 assert not self.is_bootstrapped, "Must not be already bootstrapped" voting/voting.py:84 assert // Must not be already bootstrapped // (𝕡) fund_min_bal_req#0 | assert not self.is_bootstrapped, "Must not be already bootstrapped" voting/voting.py:84 - byte "is_bootstrapped" // (𝕡) fund_min_bal_req#0 | "is_bootstrapped" self.is_bootstrapped voting/voting.py:51 + byte "is_bootstrapped" // (𝕡) fund_min_bal_req#0 | "is_bootstrapped" self.is_bootstrapped voting/voting.py:85 int 1 // (𝕡) fund_min_bal_req#0 | "is_bootstrapped",1 True voting/voting.py:85 app_global_put // (𝕡) fund_min_bal_req#0 | self.is_bootstrapped = True voting/voting.py:85 frame_dig -1 // load fund_min_bal_req#0 from parameters (𝕡) fund_min_bal_req#0 | fund_min_bal_req#0 fund_min_bal_req.receiver voting/voting.py:88 @@ -386,7 +386,7 @@ bootstrap_block@0: // virtual: load tmp%3#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0 | tmp%3#0 assert (\nfund_min_bal_req.receiver == Global.current_application_address\n), "Payment must be to... voting/voting.py:87-89 assert // Payment must be to app address // (𝕡) fund_min_bal_req#0 | assert (\nfund_min_bal_req.receiver == Global.current_application_address\n), "Payment must be to... voting/voting.py:87-89 int 0 // (𝕡) fund_min_bal_req#0 | 0 self.total_options voting/voting.py:91 - byte "total_options" // (𝕡) fund_min_bal_req#0 | 0,"total_options" self.total_options voting/voting.py:228 + byte "total_options" // (𝕡) fund_min_bal_req#0 | 0,"total_options" self.total_options voting/voting.py:91 app_global_get_ex // (𝕡) fund_min_bal_req#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.total_options voting/voting.py:91 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.total_options voting/voting.py:91 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | maybe_value%1#0,maybe_exists%1#0 self.total_options voting/voting.py:91 @@ -418,7 +418,7 @@ bootstrap_block@0: // virtual: store tmp%7#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | tally_box_size#0,tmp%7#0 fund_min_bal_req.amount == min_balance_req voting/voting.py:106 // virtual: load tmp%7#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0 | tally_box_size#0,tmp%7#0 assert (\nfund_min_bal_req.amount == min_balance_req\n), "Payment must be for the exact min balan... voting/voting.py:105-107 assert // Payment must be for the exact min balance requirement // (𝕡) fund_min_bal_req#0 | tally_box_size#0 assert (\nfund_min_bal_req.amount == min_balance_req\n), "Payment must be for the exact min balan... voting/voting.py:105-107 - byte "V" // (𝕡) fund_min_bal_req#0 | tally_box_size#0,"V" "V" voting/voting.py:55 + byte "V" // (𝕡) fund_min_bal_req#0 | tally_box_size#0,"V" self.tally_box voting/voting.py:108 uncover 1 // load tally_box_size#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0 | "V",tally_box_size#0 self.tally_box.create(size=tally_box_size) voting/voting.py:108 box_create // (𝕡) fund_min_bal_req#0 | {box_create} self.tally_box.create(size=tally_box_size) voting/voting.py:108 // virtual: store tmp%8#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0 | tmp%8#0 self.tally_box.create(size=tally_box_size) voting/voting.py:108 @@ -440,7 +440,7 @@ close_block@0: int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | 20000,0 OpUpFeeSource.GroupCredit voting/voting.py:112 callsub ensure_budget // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | ensure_budget(20000, fee_source=OpUpFeeSource.GroupCredit) voting/voting.py:112 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | 0 not self.close_time voting/voting.py:113 - byte "close_time" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | 0,"close_time" self.close_time voting/voting.py:54 + byte "close_time" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | 0,"close_time" self.close_time voting/voting.py:113 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 not self.close_time voting/voting.py:113 cover 1 // store maybe_exists%0#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | maybe_exists%0#0,{app_global_get_ex}.0 not self.close_time voting/voting.py:113 pop // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | maybe_exists%0#0 not self.close_time voting/voting.py:113 @@ -451,11 +451,11 @@ close_block@0: assert // Already closed // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | assert not self.close_time, "Already closed" voting/voting.py:113 global LatestTimestamp // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | {global} Global.latest_timestamp voting/voting.py:114 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | new_state_value%0#0 Global.latest_timestamp voting/voting.py:114 - byte "close_time" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | new_state_value%0#0,"close_time" self.close_time voting/voting.py:54 + byte "close_time" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | new_state_value%0#0,"close_time" self.close_time voting/voting.py:114 uncover 1 // load new_state_value%0#0 from l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | "close_time",new_state_value%0#0 self.close_time.value = Global.latest_timestamp voting/voting.py:114 app_global_put // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | self.close_time.value = Global.latest_timestamp voting/voting.py:114 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | 0 self.vote_id voting/voting.py:119 - byte "vote_id" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | 0,"vote_id" self.vote_id voting/voting.py:73 + byte "vote_id" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | 0,"vote_id" self.vote_id voting/voting.py:119 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.vote_id voting/voting.py:119 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.vote_id voting/voting.py:119 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | maybe_value%1#0,maybe_exists%1#0 self.vote_id voting/voting.py:119 @@ -470,7 +470,7 @@ close_block@0: concat // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | {concat} '{"standard":"arc69",'\n'"description":"This is a voting result NFT for voting round with ID '\n+... voting/voting.py:117-120 // virtual: store tmp%2#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%2#0 '{"standard":"arc69",'\n'"description":"This is a voting result NFT for voting round with ID '\n+... voting/voting.py:117-120 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%2#0,0 self.metadata_ipfs_cid voting/voting.py:121 - byte "metadata_ipfs_cid" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%2#0,0,"metadata_ipfs_cid" self.metadata_ipfs_cid voting/voting.py:75 + byte "metadata_ipfs_cid" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%2#0,0,"metadata_ipfs_cid" self.metadata_ipfs_cid voting/voting.py:121 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%2#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.metadata_ipfs_cid voting/voting.py:121 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%2#0,maybe_exists%2#0,{app_global_get_ex}.0 self.metadata_ipfs_cid voting/voting.py:121 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%2#0,maybe_value%2#0,maybe_exists%2#0 self.metadata_ipfs_cid voting/voting.py:121 @@ -485,7 +485,7 @@ close_block@0: concat // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | {concat} '{"standard":"arc69",'\n'"description":"This is a voting result NFT for voting round with ID '\n+... voting/voting.py:117-122 // virtual: store tmp%4#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%4#0 '{"standard":"arc69",'\n'"description":"This is a voting result NFT for voting round with ID '\n+... voting/voting.py:117-122 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%4#0,0 self.vote_id voting/voting.py:123 - byte "vote_id" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%4#0,0,"vote_id" self.vote_id voting/voting.py:73 + byte "vote_id" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%4#0,0,"vote_id" self.vote_id voting/voting.py:123 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%4#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.vote_id voting/voting.py:123 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%4#0,maybe_exists%3#0,{app_global_get_ex}.0 self.vote_id voting/voting.py:123 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%4#0,maybe_value%3#0,maybe_exists%3#0 self.vote_id voting/voting.py:123 @@ -500,7 +500,7 @@ close_block@0: concat // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | {concat} '{"standard":"arc69",'\n'"description":"This is a voting result NFT for voting round with ID '\n+... voting/voting.py:117-124 // virtual: store tmp%6#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%6#0 '{"standard":"arc69",'\n'"description":"This is a voting result NFT for voting round with ID '\n+... voting/voting.py:117-124 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%6#0,0 self.quorum voting/voting.py:125 - byte "quorum" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%6#0,0,"quorum" self.quorum voting/voting.py:78 + byte "quorum" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%6#0,0,"quorum" self.quorum voting/voting.py:125 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%6#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.quorum voting/voting.py:125 // virtual: store maybe_exists%4#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%6#0,maybe_exists%4#0,{app_global_get_ex}.0 self.quorum voting/voting.py:125 // virtual: store maybe_value%4#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%6#0,maybe_value%4#0,maybe_exists%4#0 self.quorum voting/voting.py:125 @@ -518,7 +518,7 @@ close_block@0: concat // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | {concat} '{"standard":"arc69",'\n'"description":"This is a voting result NFT for voting round with ID '\n+... voting/voting.py:117-126 // virtual: store tmp%9#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%9#0 '{"standard":"arc69",'\n'"description":"This is a voting result NFT for voting round with ID '\n+... voting/voting.py:117-126 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%9#0,0 self.voter_count voting/voting.py:127 - byte "voter_count" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%9#0,0,"voter_count" # The minimum number of voters who have voted\nself.voter_count voting/voting.py:52-53 + byte "voter_count" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%9#0,0,"voter_count" self.voter_count voting/voting.py:127 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%9#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.voter_count voting/voting.py:127 // virtual: store maybe_exists%5#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%9#0,maybe_exists%5#0,{app_global_get_ex}.0 self.voter_count voting/voting.py:127 // virtual: store maybe_value%5#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0 | tmp%9#0,maybe_value%5#0,maybe_exists%5#0 self.voter_count voting/voting.py:127 @@ -538,7 +538,7 @@ close_block@0: int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0 | 0 UInt64(0) voting/voting.py:131 // virtual: store current_index#0 to f-stack (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0 | current_index = UInt64(0) voting/voting.py:131 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0 | 0 self.option_counts voting/voting.py:132 - byte "option_counts" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0 | 0,"option_counts" self.option_counts voting/voting.py:227 + byte "option_counts" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0 | 0,"option_counts" self.option_counts voting/voting.py:132 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.option_counts voting/voting.py:132 cover 1 // store maybe_exists%6#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0 | maybe_exists%6#0,{app_global_get_ex}.0 self.option_counts voting/voting.py:132 dup @@ -702,7 +702,7 @@ close_after_for@14: global MinTxnFee // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | note#0,{global} Global.min_txn_fee voting/voting.py:154 cover 1 // store inner_txn_params%0%%param_Fee_idx_0#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0 Global.min_txn_fee voting/voting.py:154 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,0 self.vote_id voting/voting.py:150 - byte "vote_id" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,0,"vote_id" self.vote_id voting/voting.py:73 + byte "vote_id" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,0,"vote_id" self.vote_id voting/voting.py:150 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.vote_id voting/voting.py:150 // virtual: store maybe_exists%7#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,maybe_exists%7#0,{app_global_get_ex}.0 self.vote_id voting/voting.py:150 // virtual: store maybe_value%7#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,maybe_value%7#0,maybe_exists%7#0 self.vote_id voting/voting.py:150 @@ -713,7 +713,7 @@ close_after_for@14: concat // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,{concat} "[VOTE RESULT] " + self.vote_id voting/voting.py:150 // virtual: store inner_txn_params%0%%param_ConfigAssetName_idx_0#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,inner_txn_params%0%%param_ConfigAssetName_idx_0#0 "[VOTE RESULT] " + self.vote_id voting/voting.py:150 int 0 // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,inner_txn_params%0%%param_ConfigAssetName_idx_0#0,0 self.nft_image_url voting/voting.py:152 - byte "nft_image_url" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,inner_txn_params%0%%param_ConfigAssetName_idx_0#0,0,"nft_image_url" self.nft_image_url voting/voting.py:79 + byte "nft_image_url" // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,inner_txn_params%0%%param_ConfigAssetName_idx_0#0,0,"nft_image_url" self.nft_image_url voting/voting.py:152 app_global_get_ex // (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,inner_txn_params%0%%param_ConfigAssetName_idx_0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.nft_image_url voting/voting.py:152 // virtual: store maybe_exists%8#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,inner_txn_params%0%%param_ConfigAssetName_idx_0#0,maybe_exists%8#0,{app_global_get_ex}.0 self.nft_image_url voting/voting.py:152 // virtual: store maybe_value%8#0 to l-stack (no copy) (𝕗) note#17,question_options#0,current_index#15,option_index#0,tmp%14#0,note#0,current_index#0,maybe_value%6#0,array_length%0#0,question_index#0 | inner_txn_params%0%%param_Fee_idx_0#0,note#0,inner_txn_params%0%%param_ConfigAssetName_idx_0#0,maybe_value%8#0,maybe_exists%8#0 self.nft_image_url voting/voting.py:152 @@ -806,7 +806,7 @@ get_vote_from_box: proto 1 1 // (𝕡) index#0 | @subroutine\ndef get_vote_from_box(self, index: UInt64) -> UInt64: voting/voting.py:239-240 get_vote_from_box_block@0: - byte "V" // (𝕡) index#0 | "V" "V" voting/voting.py:55 + byte "V" // (𝕡) index#0 | "V" self.tally_box voting/voting.py:241 frame_dig -1 // load index#0 from parameters (𝕡) index#0 | "V",index#0 self.tally_box.extract(index, VOTE_COUNT_BYTES) voting/voting.py:241 int 8 // (𝕡) index#0 | "V",index#0,8 VOTE_COUNT_BYTES voting/voting.py:241 box_extract // (𝕡) index#0 | {box_extract} self.tally_box.extract(index, VOTE_COUNT_BYTES) voting/voting.py:241 @@ -867,7 +867,7 @@ voting_open: voting_open_block@0: int 0 // (𝕗) awst_tmp%0#0 | 0 self.is_bootstrapped voting/voting.py:208 - byte "is_bootstrapped" // (𝕗) awst_tmp%0#0 | 0,"is_bootstrapped" self.is_bootstrapped voting/voting.py:51 + byte "is_bootstrapped" // (𝕗) awst_tmp%0#0 | 0,"is_bootstrapped" self.is_bootstrapped voting/voting.py:208 app_global_get_ex // (𝕗) awst_tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.is_bootstrapped voting/voting.py:208 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕗) awst_tmp%0#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.is_bootstrapped voting/voting.py:208 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕗) awst_tmp%0#0 | maybe_value%0#0,maybe_exists%0#0 self.is_bootstrapped voting/voting.py:208 @@ -879,7 +879,7 @@ voting_open_block@0: voting_open_and_contd@1: int 0 // (𝕗) awst_tmp%0#0 | 0 not self.close_time voting/voting.py:209 - byte "close_time" // (𝕗) awst_tmp%0#0 | 0,"close_time" self.close_time voting/voting.py:54 + byte "close_time" // (𝕗) awst_tmp%0#0 | 0,"close_time" self.close_time voting/voting.py:209 app_global_get_ex // (𝕗) awst_tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 not self.close_time voting/voting.py:209 cover 1 // store maybe_exists%1#0 to l-stack (no copy) (𝕗) awst_tmp%0#0 | maybe_exists%1#0,{app_global_get_ex}.0 not self.close_time voting/voting.py:209 pop // (𝕗) awst_tmp%0#0 | maybe_exists%1#0 not self.close_time voting/voting.py:209 @@ -889,7 +889,7 @@ voting_open_and_contd@1: voting_open_and_contd@2: int 0 // (𝕗) awst_tmp%0#0 | 0 self.start_time voting/voting.py:210 - byte "start_time" // (𝕗) awst_tmp%0#0 | 0,"start_time" self.start_time voting/voting.py:76 + byte "start_time" // (𝕗) awst_tmp%0#0 | 0,"start_time" self.start_time voting/voting.py:210 app_global_get_ex // (𝕗) awst_tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.start_time voting/voting.py:210 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕗) awst_tmp%0#0 | maybe_exists%2#0,{app_global_get_ex}.0 self.start_time voting/voting.py:210 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕗) awst_tmp%0#0 | maybe_value%2#0,maybe_exists%2#0 self.start_time voting/voting.py:210 @@ -908,7 +908,7 @@ voting_open_and_contd@2: voting_open_and_contd@3: int 0 // (𝕗) awst_tmp%0#0 | 0 self.end_time voting/voting.py:210 - byte "end_time" // (𝕗) awst_tmp%0#0 | 0,"end_time" self.end_time voting/voting.py:77 + byte "end_time" // (𝕗) awst_tmp%0#0 | 0,"end_time" self.end_time voting/voting.py:210 app_global_get_ex // (𝕗) awst_tmp%0#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.end_time voting/voting.py:210 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕗) awst_tmp%0#0 | maybe_exists%3#0,{app_global_get_ex}.0 self.end_time voting/voting.py:210 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕗) awst_tmp%0#0 | maybe_value%3#0,maybe_exists%3#0 self.end_time voting/voting.py:210 @@ -949,7 +949,7 @@ allowed_to_vote_block@0: txn Sender // (𝕡) signature#0 | {txn} Txn.sender voting/voting.py:234 // virtual: store tmp%0#0 to l-stack (no copy) (𝕡) signature#0 | tmp%0#0 Txn.sender voting/voting.py:234 int 0 // (𝕡) signature#0 | tmp%0#0,0 self.snapshot_public_key voting/voting.py:236 - byte "snapshot_public_key" // (𝕡) signature#0 | tmp%0#0,0,"snapshot_public_key" self.snapshot_public_key voting/voting.py:74 + byte "snapshot_public_key" // (𝕡) signature#0 | tmp%0#0,0,"snapshot_public_key" self.snapshot_public_key voting/voting.py:236 app_global_get_ex // (𝕡) signature#0 | tmp%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.snapshot_public_key voting/voting.py:236 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) signature#0 | tmp%0#0,maybe_exists%0#0,{app_global_get_ex}.0 self.snapshot_public_key voting/voting.py:236 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) signature#0 | tmp%0#0,maybe_value%0#0,maybe_exists%0#0 self.snapshot_public_key voting/voting.py:236 @@ -971,10 +971,10 @@ already_voted: already_voted_block@0: txn Sender // {txn} Txn.sender voting/voting.py:215 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Txn.sender voting/voting.py:215 - // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 "")\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id: String,\nsnapshot_public_k... voting/voting.py:56-215 - box_len // {box_len}.0,{box_len}.1 "")\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id: String,\nsnapshot_public_k... voting/voting.py:56-215 - cover 1 // store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{box_len}.0 "")\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id: String,\nsnapshot_public_k... voting/voting.py:56-215 - pop // maybe_exists%0#0 "")\n\n@arc4.abimethod(create="require")\ndef create(\nself,\nvote_id: String,\nsnapshot_public_k... voting/voting.py:56-215 + // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 Txn.sender in self.votes_by_account voting/voting.py:215 + box_len // {box_len}.0,{box_len}.1 Txn.sender in self.votes_by_account voting/voting.py:215 + cover 1 // store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{box_len}.0 Txn.sender in self.votes_by_account voting/voting.py:215 + pop // maybe_exists%0#0 Txn.sender in self.votes_by_account voting/voting.py:215 // virtual: load maybe_exists%0#0 from l-stack (no copy) maybe_exists%0#0 return Txn.sender in self.votes_by_account voting/voting.py:215 retsub // maybe_exists%0#0 return Txn.sender in self.votes_by_account voting/voting.py:215 @@ -1004,7 +1004,7 @@ vote_block@0: // virtual: load tmp%3#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | tmp%3#0 assert not self.already_voted(), "Already voted" voting/voting.py:180 assert // Already voted // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | assert not self.already_voted(), "Already voted" voting/voting.py:180 int 0 // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | 0 self.option_counts voting/voting.py:181 - byte "option_counts" // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | 0,"option_counts" self.option_counts voting/voting.py:227 + byte "option_counts" // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | 0,"option_counts" self.option_counts voting/voting.py:181 app_global_get_ex // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.option_counts voting/voting.py:181 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.option_counts voting/voting.py:181 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | maybe_value%0#0,maybe_exists%0#0 self.option_counts voting/voting.py:181 @@ -1092,7 +1092,7 @@ vote_for_body@2: btoi // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,{btoi} for this question\nanswer_option_index = answer_ids[question_index].native voting/voting.py:196-197 cover 1 // store answer_option_index#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | answer_option_index#0,question_index#0 # Load the user's vote for this question\nanswer_option_index = answer_ids[question_index].native voting/voting.py:196-197 int 0 // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | answer_option_index#0,question_index#0,0 self.option_counts voting/voting.py:198 - byte "option_counts" // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | answer_option_index#0,question_index#0,0,"option_counts" self.option_counts voting/voting.py:227 + byte "option_counts" // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | answer_option_index#0,question_index#0,0,"option_counts" self.option_counts voting/voting.py:198 app_global_get_ex // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | answer_option_index#0,question_index#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.option_counts voting/voting.py:198 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | answer_option_index#0,question_index#0,maybe_exists%1#0,{app_global_get_ex}.0 self.option_counts voting/voting.py:198 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | answer_option_index#0,question_index#0,maybe_value%1#0,maybe_exists%1#0 self.option_counts voting/voting.py:198 @@ -1135,7 +1135,7 @@ vote_for_body@2: frame_dig -1 // load answer_ids#0 from parameters (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,tmp%20#0,answer_ids#0 self.votes_by_account[Txn.sender] = answer_ids.copy() voting/voting.py:202 box_put // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0 self.votes_by_account[Txn.sender] = answer_ids.copy() voting/voting.py:202 int 0 // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,0 self.voter_count voting/voting.py:203 - byte "voter_count" // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,0,"voter_count" # The minimum number of voters who have voted\nself.voter_count voting/voting.py:52-53 + byte "voter_count" // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,0,"voter_count" self.voter_count voting/voting.py:203 app_global_get_ex // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.voter_count voting/voting.py:203 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,maybe_exists%2#0,{app_global_get_ex}.0 self.voter_count voting/voting.py:203 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,maybe_value%2#0,maybe_exists%2#0 self.voter_count voting/voting.py:203 @@ -1145,7 +1145,7 @@ vote_for_body@2: int 1 // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,maybe_value%2#0,1 1 voting/voting.py:203 + // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,{+} self.voter_count += 1 voting/voting.py:203 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,new_state_value%0#0 self.voter_count += 1 voting/voting.py:203 - byte "voter_count" // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,new_state_value%0#0,"voter_count" # The minimum number of voters who have voted\nself.voter_count voting/voting.py:52-53 + byte "voter_count" // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,new_state_value%0#0,"voter_count" self.voter_count voting/voting.py:203 uncover 1 // load new_state_value%0#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0,"voter_count",new_state_value%0#0 self.voter_count += 1 voting/voting.py:203 app_global_put // (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0 self.voter_count += 1 voting/voting.py:203 // virtual: load question_index#0 from l-stack (no copy) (𝕡) fund_min_bal_req#0,signature#0,answer_ids#0 | (𝕗) questions_count#0,cumulative_offset#0,question_index#0 | question_index#0 urange(questions_count) voting/voting.py:195 @@ -1173,7 +1173,7 @@ increment_vote_in_box_block@0: // virtual: load tmp%0#0 from l-stack (no copy) (𝕡) index#0 | tmp%0#0 op.itob(current_vote + 1) voting/voting.py:246 itob // (𝕡) index#0 | {itob} op.itob(current_vote + 1) voting/voting.py:246 // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) index#0 | tmp%1#0 op.itob(current_vote + 1) voting/voting.py:246 - byte "V" // (𝕡) index#0 | tmp%1#0,"V" "V" voting/voting.py:55 + byte "V" // (𝕡) index#0 | tmp%1#0,"V" self.tally_box voting/voting.py:246 frame_dig -1 // load index#0 from parameters (𝕡) index#0 | tmp%1#0,"V",index#0 self.tally_box.replace(index, op.itob(current_vote + 1)) voting/voting.py:246 uncover 2 // load tmp%1#0 from l-stack (no copy) (𝕡) index#0 | "V",index#0,tmp%1#0 self.tally_box.replace(index, op.itob(current_vote + 1)) voting/voting.py:246 box_replace // (𝕡) index#0 | self.tally_box.replace(index, op.itob(current_vote + 1)) voting/voting.py:246 diff --git a/examples/voting/out/VotingRoundApp.approval.teal b/examples/voting/out/VotingRoundApp.approval.teal index 9088b72195..d57bb77b27 100644 --- a/examples/voting/out/VotingRoundApp.approval.teal +++ b/examples/voting/out/VotingRoundApp.approval.teal @@ -302,20 +302,14 @@ bootstrap: // voting/voting.py:84 // assert not self.is_bootstrapped, "Must not be already bootstrapped" int 0 - // voting/voting.py:51 - // self.is_bootstrapped = False byte "is_bootstrapped" - // voting/voting.py:84 - // assert not self.is_bootstrapped, "Must not be already bootstrapped" app_global_get_ex assert // check self.is_bootstrapped exists ! assert // Must not be already bootstrapped - // voting/voting.py:51 - // self.is_bootstrapped = False - byte "is_bootstrapped" // voting/voting.py:85 // self.is_bootstrapped = True + byte "is_bootstrapped" int 1 app_global_put // voting/voting.py:88 @@ -332,11 +326,7 @@ bootstrap: // voting/voting.py:91 // tally_box_size = self.total_options * VOTE_COUNT_BYTES int 0 - // voting/voting.py:228 - // self.total_options = total_options byte "total_options" - // voting/voting.py:91 - // tally_box_size = self.total_options * VOTE_COUNT_BYTES app_global_get_ex assert // check self.total_options exists int 8 @@ -384,11 +374,9 @@ bootstrap: // fund_min_bal_req.amount == min_balance_req // ), "Payment must be for the exact min balance requirement" assert // Payment must be for the exact min balance requirement - // voting/voting.py:55 - // self.tally_box = BoxRef(key="V") - byte "V" // voting/voting.py:108 // assert self.tally_box.create(size=tally_box_size) + byte "V" swap box_create assert @@ -413,30 +401,20 @@ close: // voting/voting.py:113 // assert not self.close_time, "Already closed" int 0 - // voting/voting.py:54 - // self.close_time = GlobalState(UInt64) byte "close_time" - // voting/voting.py:113 - // assert not self.close_time, "Already closed" app_global_get_ex bury 1 ! assert // Already closed - // voting/voting.py:54 - // self.close_time = GlobalState(UInt64) - byte "close_time" // voting/voting.py:114 // self.close_time.value = Global.latest_timestamp + byte "close_time" global LatestTimestamp app_global_put // voting/voting.py:119 // + self.vote_id int 0 - // voting/voting.py:73 - // self.vote_id = vote_id byte "vote_id" - // voting/voting.py:119 - // + self.vote_id app_global_get_ex assert // check self.vote_id exists // voting/voting.py:117-118 @@ -461,11 +439,7 @@ close: // voting/voting.py:121 // + self.metadata_ipfs_cid int 0 - // voting/voting.py:75 - // self.metadata_ipfs_cid = metadata_ipfs_cid byte "metadata_ipfs_cid" - // voting/voting.py:121 - // + self.metadata_ipfs_cid app_global_get_ex assert // check self.metadata_ipfs_cid exists // voting/voting.py:117-121 @@ -489,11 +463,7 @@ close: // voting/voting.py:123 // + self.vote_id int 0 - // voting/voting.py:73 - // self.vote_id = vote_id byte "vote_id" - // voting/voting.py:123 - // + self.vote_id app_global_get_ex assert // check self.vote_id exists // voting/voting.py:117-123 @@ -521,11 +491,7 @@ close: // voting/voting.py:125 // + itoa(self.quorum) int 0 - // voting/voting.py:78 - // self.quorum = quorum byte "quorum" - // voting/voting.py:125 - // + itoa(self.quorum) app_global_get_ex assert // check self.quorum exists callsub itoa @@ -558,12 +524,7 @@ close: // voting/voting.py:127 // + itoa(self.voter_count) int 0 - // voting/voting.py:52-53 - // # The minimum number of voters who have voted - // self.voter_count = UInt64(0) byte "voter_count" - // voting/voting.py:127 - // + itoa(self.voter_count) app_global_get_ex assert // check self.voter_count exists callsub itoa @@ -603,11 +564,7 @@ close: // voting/voting.py:132 // for question_index, question_options in uenumerate(self.option_counts): dup - // voting/voting.py:227 - // self.option_counts = option_counts.copy() byte "option_counts" - // voting/voting.py:132 - // for question_index, question_options in uenumerate(self.option_counts): app_global_get_ex swap dup @@ -765,11 +722,7 @@ close_after_for@14: // voting/voting.py:150 // asset_name="[VOTE RESULT] " + self.vote_id, int 0 - // voting/voting.py:73 - // self.vote_id = vote_id byte "vote_id" - // voting/voting.py:150 - // asset_name="[VOTE RESULT] " + self.vote_id, app_global_get_ex assert // check self.vote_id exists byte "[VOTE RESULT] " @@ -778,11 +731,7 @@ close_after_for@14: // voting/voting.py:152 // url=self.nft_image_url, int 0 - // voting/voting.py:79 - // self.nft_image_url = nft_image_url byte "nft_image_url" - // voting/voting.py:152 - // url=self.nft_image_url, app_global_get_ex assert // check self.nft_image_url exists uncover 2 @@ -928,11 +877,9 @@ get_vote_from_box: // @subroutine // def get_vote_from_box(self, index: UInt64) -> UInt64: proto 1 1 - // voting/voting.py:55 - // self.tally_box = BoxRef(key="V") - byte "V" // voting/voting.py:241 // return op.btoi(self.tally_box.extract(index, VOTE_COUNT_BYTES)) + byte "V" frame_dig -1 int 8 box_extract @@ -990,11 +937,7 @@ voting_open: // voting/voting.py:208 // self.is_bootstrapped int 0 - // voting/voting.py:51 - // self.is_bootstrapped = False byte "is_bootstrapped" - // voting/voting.py:208 - // self.is_bootstrapped app_global_get_ex assert // check self.is_bootstrapped exists // voting/voting.py:208-210 @@ -1005,22 +948,14 @@ voting_open: // voting/voting.py:209 // and not self.close_time int 0 - // voting/voting.py:54 - // self.close_time = GlobalState(UInt64) byte "close_time" - // voting/voting.py:209 - // and not self.close_time app_global_get_ex bury 1 bnz voting_open_bool_false@5 // voting/voting.py:210 // and self.start_time <= Global.latest_timestamp <= self.end_time int 0 - // voting/voting.py:76 - // self.start_time = start_time byte "start_time" - // voting/voting.py:210 - // and self.start_time <= Global.latest_timestamp <= self.end_time app_global_get_ex assert // check self.start_time exists global LatestTimestamp @@ -1029,11 +964,7 @@ voting_open: <= bz voting_open_bool_false@5 int 0 - // voting/voting.py:77 - // self.end_time = end_time byte "end_time" - // voting/voting.py:210 - // and self.start_time <= Global.latest_timestamp <= self.end_time app_global_get_ex assert // check self.end_time exists frame_dig 0 @@ -1073,11 +1004,7 @@ allowed_to_vote: // voting/voting.py:236 // self.snapshot_public_key, int 0 - // voting/voting.py:74 - // self.snapshot_public_key = snapshot_public_key byte "snapshot_public_key" - // voting/voting.py:236 - // self.snapshot_public_key, app_global_get_ex assert // check self.snapshot_public_key exists // voting/voting.py:233-237 @@ -1101,171 +1028,8 @@ already_voted: // voting/voting.py:215 // return Txn.sender in self.votes_by_account txn Sender - // voting/voting.py:56-215 - // self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") - // - // @arc4.abimethod(create="require") - // def create( - // self, - // vote_id: String, - // snapshot_public_key: Bytes, - // metadata_ipfs_cid: String, - // start_time: UInt64, - // end_time: UInt64, - // option_counts: VoteIndexArray, - // quorum: UInt64, - // nft_image_url: String, - // ) -> None: - // assert start_time < end_time, "End time should be after start time" - // assert end_time >= Global.latest_timestamp, "End time should be in the future" - // - // self.vote_id = vote_id - // self.snapshot_public_key = snapshot_public_key - // self.metadata_ipfs_cid = metadata_ipfs_cid - // self.start_time = start_time - // self.end_time = end_time - // self.quorum = quorum - // self.nft_image_url = nft_image_url - // self.store_option_counts(option_counts.copy()) - // - // @arc4.abimethod - // def bootstrap(self, fund_min_bal_req: gtxn.PaymentTransaction) -> None: - // assert not self.is_bootstrapped, "Must not be already bootstrapped" - // self.is_bootstrapped = True - // - // assert ( - // fund_min_bal_req.receiver == Global.current_application_address - // ), "Payment must be to app address" - // - // tally_box_size = self.total_options * VOTE_COUNT_BYTES - // min_balance_req = ( - // # minimum balance req for: ALGOs + Vote result NFT asset - // ASSET_MIN_BALANCE * 2 - // # create NFT fee - // + 1000 - // # tally box - // + BOX_FLAT_MIN_BALANCE - // # tally box key "V" - // + BOX_BYTE_MIN_BALANCE - // # tally box value - // + (tally_box_size * BOX_BYTE_MIN_BALANCE) - // ) - // log(min_balance_req) - // assert ( - // fund_min_bal_req.amount == min_balance_req - // ), "Payment must be for the exact min balance requirement" - // assert self.tally_box.create(size=tally_box_size) - // - // @arc4.abimethod - // def close(self) -> None: - // ensure_budget(20000, fee_source=OpUpFeeSource.GroupCredit) - // assert not self.close_time, "Already closed" - // self.close_time.value = Global.latest_timestamp - // - // note = ( - // '{"standard":"arc69",' - // '"description":"This is a voting result NFT for voting round with ID ' - // + self.vote_id - // + '.","properties":{"metadata":"ipfs://' - // + self.metadata_ipfs_cid - // + '","id":"' - // + self.vote_id - // + '","quorum":' - // + itoa(self.quorum) - // + ',"voterCount":' - // + itoa(self.voter_count) - // + ',"tallies":[' - // ) - // - // current_index = UInt64(0) - // for question_index, question_options in uenumerate(self.option_counts): - // if question_index > 0: - // note += "," - // if question_options > 0: - // note += "[" - // for option_index in urange(question_options.native): - // if option_index > 0: - // note += "," - // votes_for_option = self.get_vote_from_box(current_index) - // note += itoa(votes_for_option) - // current_index += 1 - // note += "]" - // note += "]}}" - // self.nft_asset_id = ( - // itxn.AssetConfig( - // total=1, - // decimals=0, - // default_frozen=False, - // asset_name="[VOTE RESULT] " + self.vote_id, - // unit_name="VOTERSLT", - // url=self.nft_image_url, - // note=note, - // fee=Global.min_txn_fee, - // ) - // .submit() - // .created_asset.id - // ) - // - // @arc4.abimethod(readonly=True) - // def get_preconditions(self, signature: Bytes) -> VotingPreconditions: - // return VotingPreconditions( - // is_voting_open=arc4.UInt64(self.voting_open()), - // is_allowed_to_vote=arc4.UInt64(self.allowed_to_vote(signature)), - // has_already_voted=arc4.UInt64(self.already_voted()), - // current_time=arc4.UInt64(Global.latest_timestamp), - // ) - // - // @arc4.abimethod - // def vote( - // self, - // fund_min_bal_req: gtxn.PaymentTransaction, - // signature: Bytes, - // answer_ids: VoteIndexArray, - // ) -> None: - // ensure_budget(7700, fee_source=OpUpFeeSource.GroupCredit) - // # Check voting preconditions - // assert self.allowed_to_vote(signature), "Not allowed to vote" - // assert self.voting_open(), "Voting not open" - // assert not self.already_voted(), "Already voted" - // questions_count = self.option_counts.length - // assert answer_ids.length == questions_count, "Number of answers incorrect" - // # Check voter box is funded - // min_bal_req = BOX_FLAT_MIN_BALANCE + ( - // (32 + 2 + VOTE_INDEX_BYTES * answer_ids.length) * BOX_BYTE_MIN_BALANCE - // ) - // assert ( - // fund_min_bal_req.receiver == Global.current_application_address - // ), "Payment must be to app address" - // - // log(min_bal_req) - // assert fund_min_bal_req.amount == min_bal_req, "Payment must be the exact min balance" - // # Record the vote for each question - // cumulative_offset = UInt64(0) - // for question_index in urange(questions_count): - // # Load the user's vote for this question - // answer_option_index = answer_ids[question_index].native - // options_count = self.option_counts[question_index].native - // assert answer_option_index < options_count, "Answer option index invalid" - // self.increment_vote_in_box(cumulative_offset + answer_option_index) - // cumulative_offset += options_count - // self.votes_by_account[Txn.sender] = answer_ids.copy() - // self.voter_count += 1 - // - // @subroutine - // def voting_open(self) -> bool: - // return ( - // self.is_bootstrapped - // and not self.close_time - // and self.start_time <= Global.latest_timestamp <= self.end_time - // ) - // - // @subroutine - // def already_voted(self) -> bool: - // return Txn.sender in self.votes_by_account box_len bury 1 - // voting/voting.py:215 - // return Txn.sender in self.votes_by_account retsub @@ -1303,11 +1067,7 @@ vote: // voting/voting.py:181 // questions_count = self.option_counts.length int 0 - // voting/voting.py:227 - // self.option_counts = option_counts.copy() byte "option_counts" - // voting/voting.py:181 - // questions_count = self.option_counts.length app_global_get_ex assert // check self.option_counts exists int 0 @@ -1390,11 +1150,7 @@ vote_for_header@1: // voting/voting.py:198 // options_count = self.option_counts[question_index].native int 0 - // voting/voting.py:227 - // self.option_counts = option_counts.copy() byte "option_counts" - // voting/voting.py:198 - // options_count = self.option_counts[question_index].native app_global_get_ex assert // check self.option_counts exists extract 2 0 @@ -1430,22 +1186,12 @@ vote_for_header@1: // voting/voting.py:203 // self.voter_count += 1 int 0 - // voting/voting.py:52-53 - // # The minimum number of voters who have voted - // self.voter_count = UInt64(0) byte "voter_count" - // voting/voting.py:203 - // self.voter_count += 1 app_global_get_ex assert // check self.voter_count exists int 1 + - // voting/voting.py:52-53 - // # The minimum number of voters who have voted - // self.voter_count = UInt64(0) byte "voter_count" - // voting/voting.py:203 - // self.voter_count += 1 swap app_global_put // voting/voting.py:195 @@ -1474,11 +1220,7 @@ increment_vote_in_box: int 1 + itob - // voting/voting.py:55 - // self.tally_box = BoxRef(key="V") byte "V" - // voting/voting.py:246 - // self.tally_box.replace(index, op.itob(current_vote + 1)) frame_dig -1 uncover 2 box_replace diff --git a/examples/voting/out/VotingRoundApp.arc32.json b/examples/voting/out/VotingRoundApp.arc32.json index 227480334a..951b244c5b 100644 --- a/examples/voting/out/VotingRoundApp.arc32.json +++ b/examples/voting/out/VotingRoundApp.arc32.json @@ -51,7 +51,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo0OQogICAgLy8gY2xhc3MgVm90aW5nUm91bmRBcHAoQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTAKICAgIG1ldGhvZCAiY3JlYXRlKHN0cmluZyxieXRlW10sc3RyaW5nLHVpbnQ2NCx1aW50NjQsdWludDhbXSx1aW50NjQsc3RyaW5nKXZvaWQiCiAgICBtZXRob2QgImJvb3RzdHJhcChwYXkpdm9pZCIKICAgIG1ldGhvZCAiY2xvc2UoKXZvaWQiCiAgICBtZXRob2QgImdldF9wcmVjb25kaXRpb25zKGJ5dGVbXSkodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSIKICAgIG1ldGhvZCAidm90ZShwYXksYnl0ZVtdLHVpbnQ4W10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2Jvb3RzdHJhcF9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2Nsb3NlX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X3ByZWNvbmRpdGlvbnNfcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192b3RlX3JvdXRlQDYKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA2CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA3CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA4CiAgICBleHRyYWN0IDIgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICBjYWxsc3ViIGNyZWF0ZQogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYm9vdHN0cmFwX3JvdXRlQDM6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib290c3RyYXAKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2Nsb3NlX3JvdXRlQDQ6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGNsb3NlCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfcHJlY29uZGl0aW9uc19yb3V0ZUA1OgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdm90aW5nL3ZvdGluZy5weTo0OQogICAgLy8gY2xhc3MgVm90aW5nUm91bmRBcHAoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICBjYWxsc3ViIGdldF9wcmVjb25kaXRpb25zCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192b3RlX3JvdXRlQDY6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjQ5CiAgICAvLyBjbGFzcyBWb3RpbmdSb3VuZEFwcChBUkM0Q29udHJhY3QpOgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB2b3RlCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo0OQogICAgLy8gY2xhc3MgVm90aW5nUm91bmRBcHAoQVJDNENvbnRyYWN0KToKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmNyZWF0ZSh2b3RlX2lkOiBieXRlcywgc25hcHNob3RfcHVibGljX2tleTogYnl0ZXMsIG1ldGFkYXRhX2lwZnNfY2lkOiBieXRlcywgc3RhcnRfdGltZTogdWludDY0LCBlbmRfdGltZTogdWludDY0LCBvcHRpb25fY291bnRzOiBieXRlcywgcXVvcnVtOiB1aW50NjQsIG5mdF9pbWFnZV91cmw6IGJ5dGVzKSAtPiB2b2lkOgpjcmVhdGU6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU4LTY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIC8vIGRlZiBjcmVhdGUoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICB2b3RlX2lkOiBTdHJpbmcsCiAgICAvLyAgICAgc25hcHNob3RfcHVibGljX2tleTogQnl0ZXMsCiAgICAvLyAgICAgbWV0YWRhdGFfaXBmc19jaWQ6IFN0cmluZywKICAgIC8vICAgICBzdGFydF90aW1lOiBVSW50NjQsCiAgICAvLyAgICAgZW5kX3RpbWU6IFVJbnQ2NCwKICAgIC8vICAgICBvcHRpb25fY291bnRzOiBWb3RlSW5kZXhBcnJheSwKICAgIC8vICAgICBxdW9ydW06IFVJbnQ2NCwKICAgIC8vICAgICBuZnRfaW1hZ2VfdXJsOiBTdHJpbmcsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byA4IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzAKICAgIC8vIGFzc2VydCBzdGFydF90aW1lIDwgZW5kX3RpbWUsICJFbmQgdGltZSBzaG91bGQgYmUgYWZ0ZXIgc3RhcnQgdGltZSIKICAgIGZyYW1lX2RpZyAtNQogICAgZnJhbWVfZGlnIC00CiAgICA8CiAgICBhc3NlcnQgLy8gRW5kIHRpbWUgc2hvdWxkIGJlIGFmdGVyIHN0YXJ0IHRpbWUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzEKICAgIC8vIGFzc2VydCBlbmRfdGltZSA+PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCwgIkVuZCB0aW1lIHNob3VsZCBiZSBpbiB0aGUgZnV0dXJlIgogICAgZnJhbWVfZGlnIC00CiAgICBnbG9iYWwgTGF0ZXN0VGltZXN0YW1wCiAgICA+PQogICAgYXNzZXJ0IC8vIEVuZCB0aW1lIHNob3VsZCBiZSBpbiB0aGUgZnV0dXJlCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjczCiAgICAvLyBzZWxmLnZvdGVfaWQgPSB2b3RlX2lkCiAgICBieXRlICJ2b3RlX2lkIgogICAgZnJhbWVfZGlnIC04CiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NAogICAgLy8gc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5ID0gc25hcHNob3RfcHVibGljX2tleQogICAgYnl0ZSAic25hcHNob3RfcHVibGljX2tleSIKICAgIGZyYW1lX2RpZyAtNwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzUKICAgIC8vIHNlbGYubWV0YWRhdGFfaXBmc19jaWQgPSBtZXRhZGF0YV9pcGZzX2NpZAogICAgYnl0ZSAibWV0YWRhdGFfaXBmc19jaWQiCiAgICBmcmFtZV9kaWcgLTYKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc2CiAgICAvLyBzZWxmLnN0YXJ0X3RpbWUgPSBzdGFydF90aW1lCiAgICBieXRlICJzdGFydF90aW1lIgogICAgZnJhbWVfZGlnIC01CiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NwogICAgLy8gc2VsZi5lbmRfdGltZSA9IGVuZF90aW1lCiAgICBieXRlICJlbmRfdGltZSIKICAgIGZyYW1lX2RpZyAtNAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzgKICAgIC8vIHNlbGYucXVvcnVtID0gcXVvcnVtCiAgICBieXRlICJxdW9ydW0iCiAgICBmcmFtZV9kaWcgLTIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc5CiAgICAvLyBzZWxmLm5mdF9pbWFnZV91cmwgPSBuZnRfaW1hZ2VfdXJsCiAgICBieXRlICJuZnRfaW1hZ2VfdXJsIgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4MAogICAgLy8gc2VsZi5zdG9yZV9vcHRpb25fY291bnRzKG9wdGlvbl9jb3VudHMuY29weSgpKQogICAgZnJhbWVfZGlnIC0zCiAgICBjYWxsc3ViIHN0b3JlX29wdGlvbl9jb3VudHMKICAgIHBvcAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5zdG9yZV9vcHRpb25fY291bnRzKG9wdGlvbl9jb3VudHM6IGJ5dGVzKSAtPiBieXRlczoKc3RvcmVfb3B0aW9uX2NvdW50czoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjE3LTIxOAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBzdG9yZV9vcHRpb25fY291bnRzKHNlbGYsIG9wdGlvbl9jb3VudHM6IFZvdGVJbmRleEFycmF5KSAtPiBOb25lOgogICAgcHJvdG8gMSAxCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxOQogICAgLy8gYXNzZXJ0IG9wdGlvbl9jb3VudHMubGVuZ3RoLCAib3B0aW9uX2NvdW50cyBzaG91bGQgYmUgbm9uLWVtcHR5IgogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGR1cG4gMgogICAgYXNzZXJ0IC8vIG9wdGlvbl9jb3VudHMgc2hvdWxkIGJlIG5vbi1lbXB0eQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjAKICAgIC8vIGFzc2VydCBvcHRpb25fY291bnRzLmxlbmd0aCA8PSAxMTIsICJDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMTIgcXVlc3Rpb25zIgogICAgaW50IDExMgogICAgPD0KICAgIGFzc2VydCAvLyBDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMTIgcXVlc3Rpb25zCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyMgogICAgLy8gdG90YWxfb3B0aW9ucyA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIGR1cAoKc3RvcmVfb3B0aW9uX2NvdW50c19mb3JfaGVhZGVyQDE6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyMwogICAgLy8gZm9yIGl0ZW0gaW4gb3B0aW9uX2NvdW50czoKICAgIGZyYW1lX2RpZyAyCiAgICBmcmFtZV9kaWcgMAogICAgPAogICAgYnogc3RvcmVfb3B0aW9uX2NvdW50c19hZnRlcl9mb3JANAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIDIKICAgIGR1cAogICAgY292ZXIgMgogICAgaW50IDEKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjQKICAgIC8vIHRvdGFsX29wdGlvbnMgKz0gaXRlbS5uYXRpdmUKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAxCiAgICArCiAgICBmcmFtZV9idXJ5IDEKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDIKICAgIGIgc3RvcmVfb3B0aW9uX2NvdW50c19mb3JfaGVhZGVyQDEKCnN0b3JlX29wdGlvbl9jb3VudHNfYWZ0ZXJfZm9yQDQ6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyNQogICAgLy8gYXNzZXJ0IHRvdGFsX29wdGlvbnMgPD0gMTI4LCAiQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gMTI4IHZvdGUgb3B0aW9ucyIKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGludCAxMjgKICAgIDw9CiAgICBhc3NlcnQgLy8gQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gMTI4IHZvdGUgb3B0aW9ucwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjcKICAgIC8vIHNlbGYub3B0aW9uX2NvdW50cyA9IG9wdGlvbl9jb3VudHMuY29weSgpCiAgICBieXRlICJvcHRpb25fY291bnRzIgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjgKICAgIC8vIHNlbGYudG90YWxfb3B0aW9ucyA9IHRvdGFsX29wdGlvbnMKICAgIGJ5dGUgInRvdGFsX29wdGlvbnMiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgZnJhbWVfZGlnIC0xCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuYm9vdHN0cmFwKGZ1bmRfbWluX2JhbF9yZXE6IHVpbnQ2NCkgLT4gdm9pZDoKYm9vdHN0cmFwOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4Mi04MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm9vdHN0cmFwKHNlbGYsIGZ1bmRfbWluX2JhbF9yZXE6IGd0eG4uUGF5bWVudFRyYW5zYWN0aW9uKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojg0CiAgICAvLyBhc3NlcnQgbm90IHNlbGYuaXNfYm9vdHN0cmFwcGVkLCAiTXVzdCBub3QgYmUgYWxyZWFkeSBib290c3RyYXBwZWQiCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1MQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBGYWxzZQogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4NAogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLmlzX2Jvb3RzdHJhcHBlZCwgIk11c3Qgbm90IGJlIGFscmVhZHkgYm9vdHN0cmFwcGVkIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmlzX2Jvb3RzdHJhcHBlZCBleGlzdHMKICAgICEKICAgIGFzc2VydCAvLyBNdXN0IG5vdCBiZSBhbHJlYWR5IGJvb3RzdHJhcHBlZAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1MQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBGYWxzZQogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4NQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBUcnVlCiAgICBpbnQgMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODgKICAgIC8vIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojg3LTg5CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gKSwgIlBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcyIKICAgIGFzc2VydCAvLyBQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MKICAgIC8vIHZvdGluZy92b3RpbmcucHk6OTEKICAgIC8vIHRhbGx5X2JveF9zaXplID0gc2VsZi50b3RhbF9vcHRpb25zICogVk9URV9DT1VOVF9CWVRFUwogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI4CiAgICAvLyBzZWxmLnRvdGFsX29wdGlvbnMgPSB0b3RhbF9vcHRpb25zCiAgICBieXRlICJ0b3RhbF9vcHRpb25zIgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo5MQogICAgLy8gdGFsbHlfYm94X3NpemUgPSBzZWxmLnRvdGFsX29wdGlvbnMgKiBWT1RFX0NPVU5UX0JZVEVTCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudG90YWxfb3B0aW9ucyBleGlzdHMKICAgIGludCA4CiAgICAqCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEwMS0xMDIKICAgIC8vICMgdGFsbHkgYm94IHZhbHVlCiAgICAvLyArICh0YWxseV9ib3hfc2l6ZSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFKQogICAgZHVwCiAgICBpbnQgNDAwCiAgICAqCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjkzLTEwMAogICAgLy8gIyBtaW5pbXVtIGJhbGFuY2UgcmVxIGZvcjogQUxHT3MgKyBWb3RlIHJlc3VsdCBORlQgYXNzZXQKICAgIC8vIEFTU0VUX01JTl9CQUxBTkNFICogMgogICAgLy8gIyBjcmVhdGUgTkZUIGZlZQogICAgLy8gKyAxMDAwCiAgICAvLyAjIHRhbGx5IGJveAogICAgLy8gKyBCT1hfRkxBVF9NSU5fQkFMQU5DRQogICAgLy8gIyB0YWxseSBib3gga2V5ICJWIgogICAgLy8gKyBCT1hfQllURV9NSU5fQkFMQU5DRQogICAgaW50IDIwMzkwMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo5My0xMDIKICAgIC8vICMgbWluaW11bSBiYWxhbmNlIHJlcSBmb3I6IEFMR09zICsgVm90ZSByZXN1bHQgTkZUIGFzc2V0CiAgICAvLyBBU1NFVF9NSU5fQkFMQU5DRSAqIDIKICAgIC8vICMgY3JlYXRlIE5GVCBmZWUKICAgIC8vICsgMTAwMAogICAgLy8gIyB0YWxseSBib3gKICAgIC8vICsgQk9YX0ZMQVRfTUlOX0JBTEFOQ0UKICAgIC8vICMgdGFsbHkgYm94IGtleSAiViIKICAgIC8vICsgQk9YX0JZVEVfTUlOX0JBTEFOQ0UKICAgIC8vICMgdGFsbHkgYm94IHZhbHVlCiAgICAvLyArICh0YWxseV9ib3hfc2l6ZSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFKQogICAgKwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDQKICAgIC8vIGxvZyhtaW5fYmFsYW5jZV9yZXEpCiAgICBkdXAKICAgIGl0b2IKICAgIGxvZwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDYKICAgIC8vIGZ1bmRfbWluX2JhbF9yZXEuYW1vdW50ID09IG1pbl9iYWxhbmNlX3JlcQogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBBbW91bnQKICAgID09CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEwNS0xMDcKICAgIC8vIGFzc2VydCAoCiAgICAvLyAgICAgZnVuZF9taW5fYmFsX3JlcS5hbW91bnQgPT0gbWluX2JhbGFuY2VfcmVxCiAgICAvLyApLCAiUGF5bWVudCBtdXN0IGJlIGZvciB0aGUgZXhhY3QgbWluIGJhbGFuY2UgcmVxdWlyZW1lbnQiCiAgICBhc3NlcnQgLy8gUGF5bWVudCBtdXN0IGJlIGZvciB0aGUgZXhhY3QgbWluIGJhbGFuY2UgcmVxdWlyZW1lbnQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTUKICAgIC8vIHNlbGYudGFsbHlfYm94ID0gQm94UmVmKGtleT0iViIpCiAgICBieXRlICJWIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDgKICAgIC8vIGFzc2VydCBzZWxmLnRhbGx5X2JveC5jcmVhdGUoc2l6ZT10YWxseV9ib3hfc2l6ZSkKICAgIHN3YXAKICAgIGJveF9jcmVhdGUKICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5jbG9zZSgpIC0+IHZvaWQ6CmNsb3NlOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTAtMTExCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBjbG9zZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICBpbnQgMAogICAgZHVwCiAgICBieXRlICIiCiAgICBkdXBuIDIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTEyCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDIwMDAwLCBmZWVfc291cmNlPU9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgMjAwMDAKICAgIGludCAwCiAgICBjYWxsc3ViIGVuc3VyZV9idWRnZXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTEzCiAgICAvLyBhc3NlcnQgbm90IHNlbGYuY2xvc2VfdGltZSwgIkFscmVhZHkgY2xvc2VkIgogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTQKICAgIC8vIHNlbGYuY2xvc2VfdGltZSA9IEdsb2JhbFN0YXRlKFVJbnQ2NCkKICAgIGJ5dGUgImNsb3NlX3RpbWUiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExMwogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLmNsb3NlX3RpbWUsICJBbHJlYWR5IGNsb3NlZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgICEKICAgIGFzc2VydCAvLyBBbHJlYWR5IGNsb3NlZAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1NAogICAgLy8gc2VsZi5jbG9zZV90aW1lID0gR2xvYmFsU3RhdGUoVUludDY0KQogICAgYnl0ZSAiY2xvc2VfdGltZSIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE0CiAgICAvLyBzZWxmLmNsb3NlX3RpbWUudmFsdWUgPSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcAogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE5CiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzMKICAgIC8vIHNlbGYudm90ZV9pZCA9IHZvdGVfaWQKICAgIGJ5dGUgInZvdGVfaWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExOQogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi52b3RlX2lkIGV4aXN0cwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTE4CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICBieXRlICJ7XCJzdGFuZGFyZFwiOlwiYXJjNjlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTExOQogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjAKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIGJ5dGUgIi5cIixcInByb3BlcnRpZXNcIjp7XCJtZXRhZGF0YVwiOlwiaXBmczovLyIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyMAogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjEKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzUKICAgIC8vIHNlbGYubWV0YWRhdGFfaXBmc19jaWQgPSBtZXRhZGF0YV9pcGZzX2NpZAogICAgYnl0ZSAibWV0YWRhdGFfaXBmc19jaWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyMQogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubWV0YWRhdGFfaXBmc19jaWQgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjEKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjIKICAgIC8vICsgJyIsImlkIjoiJwogICAgYnl0ZSAiXCIsXCJpZFwiOlwiIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTIyCiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjMKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3MwogICAgLy8gc2VsZi52b3RlX2lkID0gdm90ZV9pZAogICAgYnl0ZSAidm90ZV9pZCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTIzCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnZvdGVfaWQgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjMKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgYnl0ZSAiXCIsXCJxdW9ydW1cIjoiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjQKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyNQogICAgLy8gKyBpdG9hKHNlbGYucXVvcnVtKQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzgKICAgIC8vIHNlbGYucXVvcnVtID0gcXVvcnVtCiAgICBieXRlICJxdW9ydW0iCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyNQogICAgLy8gKyBpdG9hKHNlbGYucXVvcnVtKQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnF1b3J1bSBleGlzdHMKICAgIGNhbGxzdWIgaXRvYQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTI1CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICciLCJxdW9ydW0iOicKICAgIC8vICsgaXRvYShzZWxmLnF1b3J1bSkKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjYKICAgIC8vICsgJywidm90ZXJDb3VudCI6JwogICAgYnl0ZSAiLFwidm90ZXJDb3VudFwiOiIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyNgogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnIiwicXVvcnVtIjonCiAgICAvLyArIGl0b2Eoc2VsZi5xdW9ydW0pCiAgICAvLyArICcsInZvdGVyQ291bnQiOicKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjcKICAgIC8vICsgaXRvYShzZWxmLnZvdGVyX2NvdW50KQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTItNTMKICAgIC8vICMgVGhlIG1pbmltdW0gbnVtYmVyIG9mIHZvdGVycyB3aG8gaGF2ZSB2b3RlZAogICAgLy8gc2VsZi52b3Rlcl9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidm90ZXJfY291bnQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyNwogICAgLy8gKyBpdG9hKHNlbGYudm90ZXJfY291bnQpCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudm90ZXJfY291bnQgZXhpc3RzCiAgICBjYWxsc3ViIGl0b2EKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyNwogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnIiwicXVvcnVtIjonCiAgICAvLyArIGl0b2Eoc2VsZi5xdW9ydW0pCiAgICAvLyArICcsInZvdGVyQ291bnQiOicKICAgIC8vICsgaXRvYShzZWxmLnZvdGVyX2NvdW50KQogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyOAogICAgLy8gKyAnLCJ0YWxsaWVzIjpbJwogICAgYnl0ZSAiLFwidGFsbGllc1wiOlsiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjgKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgLy8gKyBpdG9hKHNlbGYucXVvcnVtKQogICAgLy8gKyAnLCJ2b3RlckNvdW50IjonCiAgICAvLyArIGl0b2Eoc2VsZi52b3Rlcl9jb3VudCkKICAgIC8vICsgJywidGFsbGllcyI6WycKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzEKICAgIC8vIGN1cnJlbnRfaW5kZXggPSBVSW50NjQoMCkKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzMgogICAgLy8gZm9yIHF1ZXN0aW9uX2luZGV4LCBxdWVzdGlvbl9vcHRpb25zIGluIHVlbnVtZXJhdGUoc2VsZi5vcHRpb25fY291bnRzKToKICAgIGR1cAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjcKICAgIC8vIHNlbGYub3B0aW9uX2NvdW50cyA9IG9wdGlvbl9jb3VudHMuY29weSgpCiAgICBieXRlICJvcHRpb25fY291bnRzIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzIKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCwgcXVlc3Rpb25fb3B0aW9ucyBpbiB1ZW51bWVyYXRlKHNlbGYub3B0aW9uX2NvdW50cyk6CiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgc3dhcAogICAgZHVwCiAgICB1bmNvdmVyIDIKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLm9wdGlvbl9jb3VudHMgZXhpc3RzCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGludCAwCgpjbG9zZV9mb3JfaGVhZGVyQDE6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzMgogICAgLy8gZm9yIHF1ZXN0aW9uX2luZGV4LCBxdWVzdGlvbl9vcHRpb25zIGluIHVlbnVtZXJhdGUoc2VsZi5vcHRpb25fY291bnRzKToKICAgIGZyYW1lX2RpZyA5CiAgICBmcmFtZV9kaWcgOAogICAgPAogICAgYnogY2xvc2VfYWZ0ZXJfZm9yQDE0CiAgICBmcmFtZV9kaWcgNwogICAgZXh0cmFjdCAyIDAKICAgIGZyYW1lX2RpZyA5CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludCAxCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGZyYW1lX2J1cnkgMQogICAgZnJhbWVfZGlnIDUKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzMKICAgIC8vIGlmIHF1ZXN0aW9uX2luZGV4ID4gMDoKICAgIGJ6IGNsb3NlX2FmdGVyX2lmX2Vsc2VANAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzQKICAgIC8vIG5vdGUgKz0gIiwiCiAgICBmcmFtZV9kaWcgNQogICAgYnl0ZSAiLCIKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAwCgpjbG9zZV9hZnRlcl9pZl9lbHNlQDQ6CiAgICBmcmFtZV9kaWcgMAogICAgZHVwCiAgICBmcmFtZV9idXJ5IDUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM1CiAgICAvLyBpZiBxdWVzdGlvbl9vcHRpb25zID4gMDoKICAgIGZyYW1lX2RpZyAxCiAgICBieXRlIDB4MDAKICAgIGI+CiAgICBmcmFtZV9kaWcgNgogICAgZnJhbWVfYnVyeSAyCiAgICBzd2FwCiAgICBmcmFtZV9idXJ5IDAKICAgIGJ6IGNsb3NlX2FmdGVyX2lmX2Vsc2VAMTIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM2CiAgICAvLyBub3RlICs9ICJbIgogICAgZnJhbWVfZGlnIDUKICAgIGJ5dGUgIlsiCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgNQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzcKICAgIC8vIGZvciBvcHRpb25faW5kZXggaW4gdXJhbmdlKHF1ZXN0aW9uX29wdGlvbnMubmF0aXZlKToKICAgIGZyYW1lX2RpZyAxCiAgICBidG9pCiAgICBmcmFtZV9idXJ5IDQKICAgIGludCAwCiAgICBmcmFtZV9idXJ5IDMKCmNsb3NlX2Zvcl9oZWFkZXJANjoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM3CiAgICAvLyBmb3Igb3B0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbl9vcHRpb25zLm5hdGl2ZSk6CiAgICBmcmFtZV9kaWcgMwogICAgZnJhbWVfZGlnIDQKICAgIDwKICAgIGJ6IGNsb3NlX2FmdGVyX2ZvckAxMQogICAgZnJhbWVfZGlnIDUKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzgKICAgIC8vIGlmIG9wdGlvbl9pbmRleCA+IDA6CiAgICBmcmFtZV9kaWcgMwogICAgYnogY2xvc2VfYWZ0ZXJfaWZfZWxzZUA5CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzOQogICAgLy8gbm90ZSArPSAiLCIKICAgIGZyYW1lX2RpZyA1CiAgICBieXRlICIsIgogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IDAKCmNsb3NlX2FmdGVyX2lmX2Vsc2VAOToKICAgIGZyYW1lX2RpZyAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0MAogICAgLy8gdm90ZXNfZm9yX29wdGlvbiA9IHNlbGYuZ2V0X3ZvdGVfZnJvbV9ib3goY3VycmVudF9pbmRleCkKICAgIGZyYW1lX2RpZyA2CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGNhbGxzdWIgZ2V0X3ZvdGVfZnJvbV9ib3gKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQxCiAgICAvLyBub3RlICs9IGl0b2Eodm90ZXNfZm9yX29wdGlvbikKICAgIGNhbGxzdWIgaXRvYQogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IDUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQyCiAgICAvLyBjdXJyZW50X2luZGV4ICs9IDEKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDYKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM3CiAgICAvLyBmb3Igb3B0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbl9vcHRpb25zLm5hdGl2ZSk6CiAgICBmcmFtZV9kaWcgMwogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2J1cnkgMwogICAgYiBjbG9zZV9mb3JfaGVhZGVyQDYKCmNsb3NlX2FmdGVyX2ZvckAxMToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQzCiAgICAvLyBub3RlICs9ICJdIgogICAgZnJhbWVfZGlnIDUKICAgIGJ5dGUgIl0iCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyA2CiAgICBmcmFtZV9idXJ5IDIKICAgIGZyYW1lX2J1cnkgMAoKY2xvc2VfYWZ0ZXJfaWZfZWxzZUAxMjoKICAgIGZyYW1lX2RpZyAyCiAgICBmcmFtZV9idXJ5IDYKICAgIGZyYW1lX2RpZyAwCiAgICBmcmFtZV9idXJ5IDUKICAgIGZyYW1lX2RpZyA5CiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSA5CiAgICBiIGNsb3NlX2Zvcl9oZWFkZXJAMQoKY2xvc2VfYWZ0ZXJfZm9yQDE0OgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDQKICAgIC8vIG5vdGUgKz0gIl19fSIKICAgIGZyYW1lX2RpZyA1CiAgICBieXRlICJdfX0iCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ2LTE1NgogICAgLy8gaXR4bi5Bc3NldENvbmZpZygKICAgIC8vICAgICB0b3RhbD0xLAogICAgLy8gICAgIGRlY2ltYWxzPTAsCiAgICAvLyAgICAgZGVmYXVsdF9mcm96ZW49RmFsc2UsCiAgICAvLyAgICAgYXNzZXRfbmFtZT0iW1ZPVEUgUkVTVUxUXSAiICsgc2VsZi52b3RlX2lkLAogICAgLy8gICAgIHVuaXRfbmFtZT0iVk9URVJTTFQiLAogICAgLy8gICAgIHVybD1zZWxmLm5mdF9pbWFnZV91cmwsCiAgICAvLyAgICAgbm90ZT1ub3RlLAogICAgLy8gICAgIGZlZT1HbG9iYWwubWluX3R4bl9mZWUsCiAgICAvLyApCiAgICAvLyAuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTU0CiAgICAvLyBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgZ2xvYmFsIE1pblR4bkZlZQogICAgc3dhcAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNTAKICAgIC8vIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjczCiAgICAvLyBzZWxmLnZvdGVfaWQgPSB2b3RlX2lkCiAgICBieXRlICJ2b3RlX2lkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNTAKICAgIC8vIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi52b3RlX2lkIGV4aXN0cwogICAgYnl0ZSAiW1ZPVEUgUkVTVUxUXSAiCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUyCiAgICAvLyB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzkKICAgIC8vIHNlbGYubmZ0X2ltYWdlX3VybCA9IG5mdF9pbWFnZV91cmwKICAgIGJ5dGUgIm5mdF9pbWFnZV91cmwiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE1MgogICAgLy8gdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5uZnRfaW1hZ2VfdXJsIGV4aXN0cwogICAgdW5jb3ZlciAyCiAgICBpdHhuX2ZpZWxkIE5vdGUKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRVUkwKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUxCiAgICAvLyB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIGJ5dGUgIlZPVEVSU0xUIgogICAgaXR4bl9maWVsZCBDb25maWdBc3NldFVuaXROYW1lCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0TmFtZQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDkKICAgIC8vIGRlZmF1bHRfZnJvemVuPUZhbHNlLAogICAgaW50IDAKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXREZWZhdWx0RnJvemVuCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0OAogICAgLy8gZGVjaW1hbHM9MCwKICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0RGVjaW1hbHMKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ3CiAgICAvLyB0b3RhbD0xLAogICAgaW50IDEKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRUb3RhbAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDYKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICBpbnQgYWNmZwogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ2LTE1NgogICAgLy8gaXR4bi5Bc3NldENvbmZpZygKICAgIC8vICAgICB0b3RhbD0xLAogICAgLy8gICAgIGRlY2ltYWxzPTAsCiAgICAvLyAgICAgZGVmYXVsdF9mcm96ZW49RmFsc2UsCiAgICAvLyAgICAgYXNzZXRfbmFtZT0iW1ZPVEUgUkVTVUxUXSAiICsgc2VsZi52b3RlX2lkLAogICAgLy8gICAgIHVuaXRfbmFtZT0iVk9URVJTTFQiLAogICAgLy8gICAgIHVybD1zZWxmLm5mdF9pbWFnZV91cmwsCiAgICAvLyAgICAgbm90ZT1ub3RlLAogICAgLy8gICAgIGZlZT1HbG9iYWwubWluX3R4bl9mZWUsCiAgICAvLyApCiAgICAvLyAuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0NQogICAgLy8gc2VsZi5uZnRfYXNzZXRfaWQgPSAoCiAgICBieXRlICJuZnRfYXNzZXRfaWQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0Ni0xNTcKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICAvLyAgICAgdG90YWw9MSwKICAgIC8vICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgIGRlZmF1bHRfZnJvemVuPUZhbHNlLAogICAgLy8gICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgLy8gICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gKQogICAgLy8gLnN1Ym1pdCgpCiAgICAvLyAuY3JlYXRlZF9hc3NldC5pZAogICAgaXR4biBDcmVhdGVkQXNzZXRJRAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDUtMTU4CiAgICAvLyBzZWxmLm5mdF9hc3NldF9pZCA9ICgKICAgIC8vICAgICBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgICAgICB0b3RhbD0xLAogICAgLy8gICAgICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgICAgICBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIC8vICAgICAgICAgYXNzZXRfbmFtZT0iW1ZPVEUgUkVTVUxUXSAiICsgc2VsZi52b3RlX2lkLAogICAgLy8gICAgICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICAgICAgdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIC8vICAgICAgICAgbm90ZT1ub3RlLAogICAgLy8gICAgICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gICAgICkKICAgIC8vICAgICAuc3VibWl0KCkKICAgIC8vICAgICAuY3JlYXRlZF9hc3NldC5pZAogICAgLy8gKQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuaXRvYShpOiB1aW50NjQpIC0+IGJ5dGVzOgppdG9hOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNDktMjUwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGl0b2EoaTogVUludDY0KSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUzCiAgICAvLyBpZiBpIDwgcmFkaXg6CiAgICBmcmFtZV9kaWcgLTEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUyCiAgICAvLyByYWRpeCA9IGRpZ2l0cy5sZW5ndGgKICAgIGludCAxMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTMKICAgIC8vIGlmIGkgPCByYWRpeDoKICAgIDwKICAgIGJ6IGl0b2FfYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1NAogICAgLy8gcmV0dXJuIFN0cmluZy5mcm9tX2J5dGVzKGRpZ2l0c1tpXSkKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDEKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUxCiAgICAvLyBkaWdpdHMgPSBCeXRlcyhiIjAxMjM0NTY3ODkiKQogICAgYnl0ZSAweDMwMzEzMjMzMzQzNTM2MzczODM5CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1NAogICAgLy8gcmV0dXJuIFN0cmluZy5mcm9tX2J5dGVzKGRpZ2l0c1tpXSkKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICByZXRzdWIKCml0b2FfYWZ0ZXJfaWZfZWxzZUAyOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTUKICAgIC8vIHJldHVybiBpdG9hKGkgLy8gcmFkaXgpICsgU3RyaW5nLmZyb21fYnl0ZXMoZGlnaXRzW2kgJSByYWRpeF0pCiAgICBmcmFtZV9kaWcgLTEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUyCiAgICAvLyByYWRpeCA9IGRpZ2l0cy5sZW5ndGgKICAgIGludCAxMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTUKICAgIC8vIHJldHVybiBpdG9hKGkgLy8gcmFkaXgpICsgU3RyaW5nLmZyb21fYnl0ZXMoZGlnaXRzW2kgJSByYWRpeF0pCiAgICAvCiAgICBjYWxsc3ViIGl0b2EKICAgIGZyYW1lX2RpZyAtMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTIKICAgIC8vIHJhZGl4ID0gZGlnaXRzLmxlbmd0aAogICAgaW50IDEwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1NQogICAgLy8gcmV0dXJuIGl0b2EoaSAvLyByYWRpeCkgKyBTdHJpbmcuZnJvbV9ieXRlcyhkaWdpdHNbaSAlIHJhZGl4XSkKICAgICUKICAgIGR1cAogICAgaW50IDEKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUxCiAgICAvLyBkaWdpdHMgPSBCeXRlcyhiIjAxMjM0NTY3ODkiKQogICAgYnl0ZSAweDMwMzEzMjMzMzQzNTM2MzczODM5CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1NQogICAgLy8gcmV0dXJuIGl0b2EoaSAvLyByYWRpeCkgKyBTdHJpbmcuZnJvbV9ieXRlcyhkaWdpdHNbaSAlIHJhZGl4XSkKICAgIGNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5nZXRfdm90ZV9mcm9tX2JveChpbmRleDogdWludDY0KSAtPiB1aW50NjQ6CmdldF92b3RlX2Zyb21fYm94OgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMzktMjQwCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGdldF92b3RlX2Zyb21fYm94KHNlbGYsIGluZGV4OiBVSW50NjQpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDEgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1NQogICAgLy8gc2VsZi50YWxseV9ib3ggPSBCb3hSZWYoa2V5PSJWIikKICAgIGJ5dGUgIlYiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI0MQogICAgLy8gcmV0dXJuIG9wLmJ0b2koc2VsZi50YWxseV9ib3guZXh0cmFjdChpbmRleCwgVk9URV9DT1VOVF9CWVRFUykpCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCA4CiAgICBib3hfZXh0cmFjdAogICAgYnRvaQogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5nZXRfcHJlY29uZGl0aW9ucyhzaWduYXR1cmU6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X3ByZWNvbmRpdGlvbnM6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2MC0xNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgLy8gZGVmIGdldF9wcmVjb25kaXRpb25zKHNlbGYsIHNpZ25hdHVyZTogQnl0ZXMpIC0+IFZvdGluZ1ByZWNvbmRpdGlvbnM6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTYzCiAgICAvLyBpc192b3Rpbmdfb3Blbj1hcmM0LlVJbnQ2NChzZWxmLnZvdGluZ19vcGVuKCkpLAogICAgY2FsbHN1YiB2b3Rpbmdfb3BlbgogICAgaXRvYgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjQKICAgIC8vIGlzX2FsbG93ZWRfdG9fdm90ZT1hcmM0LlVJbnQ2NChzZWxmLmFsbG93ZWRfdG9fdm90ZShzaWduYXR1cmUpKSwKICAgIGZyYW1lX2RpZyAtMQogICAgY2FsbHN1YiBhbGxvd2VkX3RvX3ZvdGUKICAgIGl0b2IKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTY1CiAgICAvLyBoYXNfYWxyZWFkeV92b3RlZD1hcmM0LlVJbnQ2NChzZWxmLmFscmVhZHlfdm90ZWQoKSksCiAgICBjYWxsc3ViIGFscmVhZHlfdm90ZWQKICAgIGl0b2IKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTY2CiAgICAvLyBjdXJyZW50X3RpbWU9YXJjNC5VSW50NjQoR2xvYmFsLmxhdGVzdF90aW1lc3RhbXApLAogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgaXRvYgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjItMTY3CiAgICAvLyByZXR1cm4gVm90aW5nUHJlY29uZGl0aW9ucygKICAgIC8vICAgICBpc192b3Rpbmdfb3Blbj1hcmM0LlVJbnQ2NChzZWxmLnZvdGluZ19vcGVuKCkpLAogICAgLy8gICAgIGlzX2FsbG93ZWRfdG9fdm90ZT1hcmM0LlVJbnQ2NChzZWxmLmFsbG93ZWRfdG9fdm90ZShzaWduYXR1cmUpKSwKICAgIC8vICAgICBoYXNfYWxyZWFkeV92b3RlZD1hcmM0LlVJbnQ2NChzZWxmLmFscmVhZHlfdm90ZWQoKSksCiAgICAvLyAgICAgY3VycmVudF90aW1lPWFyYzQuVUludDY0KEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wKSwKICAgIC8vICkKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAudm90aW5nX29wZW4oKSAtPiB1aW50NjQ6CnZvdGluZ19vcGVuOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDUtMjA2CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHZvdGluZ19vcGVuKHNlbGYpIC0+IGJvb2w6CiAgICBwcm90byAwIDEKICAgIGJ5dGUgIiIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA4CiAgICAvLyBzZWxmLmlzX2Jvb3RzdHJhcHBlZAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTEKICAgIC8vIHNlbGYuaXNfYm9vdHN0cmFwcGVkID0gRmFsc2UKICAgIGJ5dGUgImlzX2Jvb3RzdHJhcHBlZCIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA4CiAgICAvLyBzZWxmLmlzX2Jvb3RzdHJhcHBlZAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmlzX2Jvb3RzdHJhcHBlZCBleGlzdHMKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA4LTIxMAogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQKICAgIC8vIGFuZCBub3Qgc2VsZi5jbG9zZV90aW1lCiAgICAvLyBhbmQgc2VsZi5zdGFydF90aW1lIDw9IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wIDw9IHNlbGYuZW5kX3RpbWUKICAgIGJ6IHZvdGluZ19vcGVuX2Jvb2xfZmFsc2VANQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDkKICAgIC8vIGFuZCBub3Qgc2VsZi5jbG9zZV90aW1lCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1NAogICAgLy8gc2VsZi5jbG9zZV90aW1lID0gR2xvYmFsU3RhdGUoVUludDY0KQogICAgYnl0ZSAiY2xvc2VfdGltZSIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA5CiAgICAvLyBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgYm56IHZvdGluZ19vcGVuX2Jvb2xfZmFsc2VANQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTAKICAgIC8vIGFuZCBzZWxmLnN0YXJ0X3RpbWUgPD0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPD0gc2VsZi5lbmRfdGltZQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzYKICAgIC8vIHNlbGYuc3RhcnRfdGltZSA9IHN0YXJ0X3RpbWUKICAgIGJ5dGUgInN0YXJ0X3RpbWUiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxMAogICAgLy8gYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuc3RhcnRfdGltZSBleGlzdHMKICAgIGdsb2JhbCBMYXRlc3RUaW1lc3RhbXAKICAgIGR1cAogICAgZnJhbWVfYnVyeSAwCiAgICA8PQogICAgYnogdm90aW5nX29wZW5fYm9vbF9mYWxzZUA1CiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NwogICAgLy8gc2VsZi5lbmRfdGltZSA9IGVuZF90aW1lCiAgICBieXRlICJlbmRfdGltZSIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjEwCiAgICAvLyBhbmQgc2VsZi5zdGFydF90aW1lIDw9IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wIDw9IHNlbGYuZW5kX3RpbWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5lbmRfdGltZSBleGlzdHMKICAgIGZyYW1lX2RpZyAwCiAgICA+PQogICAgYnogdm90aW5nX29wZW5fYm9vbF9mYWxzZUA1CiAgICBpbnQgMQogICAgYiB2b3Rpbmdfb3Blbl9ib29sX21lcmdlQDYKCnZvdGluZ19vcGVuX2Jvb2xfZmFsc2VANToKICAgIGludCAwCgp2b3Rpbmdfb3Blbl9ib29sX21lcmdlQDY6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwNy0yMTEKICAgIC8vIHJldHVybiAoCiAgICAvLyAgICAgc2VsZi5pc19ib290c3RyYXBwZWQKICAgIC8vICAgICBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgLy8gICAgIGFuZCBzZWxmLnN0YXJ0X3RpbWUgPD0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPD0gc2VsZi5lbmRfdGltZQogICAgLy8gKQogICAgc3dhcAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlOiBieXRlcykgLT4gdWludDY0OgphbGxvd2VkX3RvX3ZvdGU6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzMC0yMzEKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgYWxsb3dlZF90b192b3RlKHNlbGYsIHNpZ25hdHVyZTogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjMyCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDIwMDApCiAgICBpbnQgMjAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMzQKICAgIC8vIFR4bi5zZW5kZXIuYnl0ZXMsCiAgICB0eG4gU2VuZGVyCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzNgogICAgLy8gc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5LAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzQKICAgIC8vIHNlbGYuc25hcHNob3RfcHVibGljX2tleSA9IHNuYXBzaG90X3B1YmxpY19rZXkKICAgIGJ5dGUgInNuYXBzaG90X3B1YmxpY19rZXkiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzNgogICAgLy8gc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5LAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnNuYXBzaG90X3B1YmxpY19rZXkgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzMy0yMzcKICAgIC8vIHJldHVybiBvcC5lZDI1NTE5dmVyaWZ5X2JhcmUoCiAgICAvLyAgICAgVHhuLnNlbmRlci5ieXRlcywKICAgIC8vICAgICBzaWduYXR1cmUsCiAgICAvLyAgICAgc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5LAogICAgLy8gKQogICAgZnJhbWVfZGlnIC0xCiAgICBzd2FwCiAgICBlZDI1NTE5dmVyaWZ5X2JhcmUKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuYWxyZWFkeV92b3RlZCgpIC0+IHVpbnQ2NDoKYWxyZWFkeV92b3RlZDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjEzLTIxNAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBhbHJlYWR5X3ZvdGVkKHNlbGYpIC0+IGJvb2w6CiAgICBwcm90byAwIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjE1CiAgICAvLyByZXR1cm4gVHhuLnNlbmRlciBpbiBzZWxmLnZvdGVzX2J5X2FjY291bnQKICAgIHR4biBTZW5kZXIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTYtMjE1CiAgICAvLyAgICAgc2VsZi52b3Rlc19ieV9hY2NvdW50ID0gQm94TWFwKEFjY291bnQsIFZvdGVJbmRleEFycmF5LCBrZXlfcHJlZml4PSIiKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIC8vIGRlZiBjcmVhdGUoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICB2b3RlX2lkOiBTdHJpbmcsCiAgICAvLyAgICAgc25hcHNob3RfcHVibGljX2tleTogQnl0ZXMsCiAgICAvLyAgICAgbWV0YWRhdGFfaXBmc19jaWQ6IFN0cmluZywKICAgIC8vICAgICBzdGFydF90aW1lOiBVSW50NjQsCiAgICAvLyAgICAgZW5kX3RpbWU6IFVJbnQ2NCwKICAgIC8vICAgICBvcHRpb25fY291bnRzOiBWb3RlSW5kZXhBcnJheSwKICAgIC8vICAgICBxdW9ydW06IFVJbnQ2NCwKICAgIC8vICAgICBuZnRfaW1hZ2VfdXJsOiBTdHJpbmcsCiAgICAvLyApIC0+IE5vbmU6CiAgICAvLyAgICAgYXNzZXJ0IHN0YXJ0X3RpbWUgPCBlbmRfdGltZSwgIkVuZCB0aW1lIHNob3VsZCBiZSBhZnRlciBzdGFydCB0aW1lIgogICAgLy8gICAgIGFzc2VydCBlbmRfdGltZSA+PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCwgIkVuZCB0aW1lIHNob3VsZCBiZSBpbiB0aGUgZnV0dXJlIgogICAgLy8gCiAgICAvLyAgICAgc2VsZi52b3RlX2lkID0gdm90ZV9pZAogICAgLy8gICAgIHNlbGYuc25hcHNob3RfcHVibGljX2tleSA9IHNuYXBzaG90X3B1YmxpY19rZXkKICAgIC8vICAgICBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkID0gbWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICAgICBzZWxmLnN0YXJ0X3RpbWUgPSBzdGFydF90aW1lCiAgICAvLyAgICAgc2VsZi5lbmRfdGltZSA9IGVuZF90aW1lCiAgICAvLyAgICAgc2VsZi5xdW9ydW0gPSBxdW9ydW0KICAgIC8vICAgICBzZWxmLm5mdF9pbWFnZV91cmwgPSBuZnRfaW1hZ2VfdXJsCiAgICAvLyAgICAgc2VsZi5zdG9yZV9vcHRpb25fY291bnRzKG9wdGlvbl9jb3VudHMuY29weSgpKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBib290c3RyYXAoc2VsZiwgZnVuZF9taW5fYmFsX3JlcTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24pIC0+IE5vbmU6CiAgICAvLyAgICAgYXNzZXJ0IG5vdCBzZWxmLmlzX2Jvb3RzdHJhcHBlZCwgIk11c3Qgbm90IGJlIGFscmVhZHkgYm9vdHN0cmFwcGVkIgogICAgLy8gICAgIHNlbGYuaXNfYm9vdHN0cmFwcGVkID0gVHJ1ZQogICAgLy8gCiAgICAvLyAgICAgYXNzZXJ0ICgKICAgIC8vICAgICAgICAgZnVuZF9taW5fYmFsX3JlcS5yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzCiAgICAvLyAgICAgKSwgIlBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcyIKICAgIC8vIAogICAgLy8gICAgIHRhbGx5X2JveF9zaXplID0gc2VsZi50b3RhbF9vcHRpb25zICogVk9URV9DT1VOVF9CWVRFUwogICAgLy8gICAgIG1pbl9iYWxhbmNlX3JlcSA9ICgKICAgIC8vICAgICAgICAgIyBtaW5pbXVtIGJhbGFuY2UgcmVxIGZvcjogQUxHT3MgKyBWb3RlIHJlc3VsdCBORlQgYXNzZXQKICAgIC8vICAgICAgICAgQVNTRVRfTUlOX0JBTEFOQ0UgKiAyCiAgICAvLyAgICAgICAgICMgY3JlYXRlIE5GVCBmZWUKICAgIC8vICAgICAgICAgKyAxMDAwCiAgICAvLyAgICAgICAgICMgdGFsbHkgYm94CiAgICAvLyAgICAgICAgICsgQk9YX0ZMQVRfTUlOX0JBTEFOQ0UKICAgIC8vICAgICAgICAgIyB0YWxseSBib3gga2V5ICJWIgogICAgLy8gICAgICAgICArIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICAvLyAgICAgICAgICMgdGFsbHkgYm94IHZhbHVlCiAgICAvLyAgICAgICAgICsgKHRhbGx5X2JveF9zaXplICogQk9YX0JZVEVfTUlOX0JBTEFOQ0UpCiAgICAvLyAgICAgKQogICAgLy8gICAgIGxvZyhtaW5fYmFsYW5jZV9yZXEpCiAgICAvLyAgICAgYXNzZXJ0ICgKICAgIC8vICAgICAgICAgZnVuZF9taW5fYmFsX3JlcS5hbW91bnQgPT0gbWluX2JhbGFuY2VfcmVxCiAgICAvLyAgICAgKSwgIlBheW1lbnQgbXVzdCBiZSBmb3IgdGhlIGV4YWN0IG1pbiBiYWxhbmNlIHJlcXVpcmVtZW50IgogICAgLy8gICAgIGFzc2VydCBzZWxmLnRhbGx5X2JveC5jcmVhdGUoc2l6ZT10YWxseV9ib3hfc2l6ZSkKICAgIC8vIAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgY2xvc2Uoc2VsZikgLT4gTm9uZToKICAgIC8vICAgICBlbnN1cmVfYnVkZ2V0KDIwMDAwLCBmZWVfc291cmNlPU9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICAvLyAgICAgYXNzZXJ0IG5vdCBzZWxmLmNsb3NlX3RpbWUsICJBbHJlYWR5IGNsb3NlZCIKICAgIC8vICAgICBzZWxmLmNsb3NlX3RpbWUudmFsdWUgPSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcAogICAgLy8gCiAgICAvLyAgICAgbm90ZSA9ICgKICAgIC8vICAgICAgICAgJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gICAgICAgICAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyAgICAgICAgICsgc2VsZi52b3RlX2lkCiAgICAvLyAgICAgICAgICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICAgICAgICAgKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyAgICAgICAgICsgJyIsImlkIjoiJwogICAgLy8gICAgICAgICArIHNlbGYudm90ZV9pZAogICAgLy8gICAgICAgICArICciLCJxdW9ydW0iOicKICAgIC8vICAgICAgICAgKyBpdG9hKHNlbGYucXVvcnVtKQogICAgLy8gICAgICAgICArICcsInZvdGVyQ291bnQiOicKICAgIC8vICAgICAgICAgKyBpdG9hKHNlbGYudm90ZXJfY291bnQpCiAgICAvLyAgICAgICAgICsgJywidGFsbGllcyI6WycKICAgIC8vICAgICApCiAgICAvLyAKICAgIC8vICAgICBjdXJyZW50X2luZGV4ID0gVUludDY0KDApCiAgICAvLyAgICAgZm9yIHF1ZXN0aW9uX2luZGV4LCBxdWVzdGlvbl9vcHRpb25zIGluIHVlbnVtZXJhdGUoc2VsZi5vcHRpb25fY291bnRzKToKICAgIC8vICAgICAgICAgaWYgcXVlc3Rpb25faW5kZXggPiAwOgogICAgLy8gICAgICAgICAgICAgbm90ZSArPSAiLCIKICAgIC8vICAgICAgICAgaWYgcXVlc3Rpb25fb3B0aW9ucyA+IDA6CiAgICAvLyAgICAgICAgICAgICBub3RlICs9ICJbIgogICAgLy8gICAgICAgICAgICAgZm9yIG9wdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25fb3B0aW9ucy5uYXRpdmUpOgogICAgLy8gICAgICAgICAgICAgICAgIGlmIG9wdGlvbl9pbmRleCA+IDA6CiAgICAvLyAgICAgICAgICAgICAgICAgICAgIG5vdGUgKz0gIiwiCiAgICAvLyAgICAgICAgICAgICAgICAgdm90ZXNfZm9yX29wdGlvbiA9IHNlbGYuZ2V0X3ZvdGVfZnJvbV9ib3goY3VycmVudF9pbmRleCkKICAgIC8vICAgICAgICAgICAgICAgICBub3RlICs9IGl0b2Eodm90ZXNfZm9yX29wdGlvbikKICAgIC8vICAgICAgICAgICAgICAgICBjdXJyZW50X2luZGV4ICs9IDEKICAgIC8vICAgICAgICAgICAgIG5vdGUgKz0gIl0iCiAgICAvLyAgICAgbm90ZSArPSAiXX19IgogICAgLy8gICAgIHNlbGYubmZ0X2Fzc2V0X2lkID0gKAogICAgLy8gICAgICAgICBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgICAgICAgICAgdG90YWw9MSwKICAgIC8vICAgICAgICAgICAgIGRlY2ltYWxzPTAsCiAgICAvLyAgICAgICAgICAgICBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIC8vICAgICAgICAgICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICAgICAgICAgIHVuaXRfbmFtZT0iVk9URVJTTFQiLAogICAgLy8gICAgICAgICAgICAgdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIC8vICAgICAgICAgICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICAgICAgICAgIGZlZT1HbG9iYWwubWluX3R4bl9mZWUsCiAgICAvLyAgICAgICAgICkKICAgIC8vICAgICAgICAgLnN1Ym1pdCgpCiAgICAvLyAgICAgICAgIC5jcmVhdGVkX2Fzc2V0LmlkCiAgICAvLyAgICAgKQogICAgLy8gCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIC8vIGRlZiBnZXRfcHJlY29uZGl0aW9ucyhzZWxmLCBzaWduYXR1cmU6IEJ5dGVzKSAtPiBWb3RpbmdQcmVjb25kaXRpb25zOgogICAgLy8gICAgIHJldHVybiBWb3RpbmdQcmVjb25kaXRpb25zKAogICAgLy8gICAgICAgICBpc192b3Rpbmdfb3Blbj1hcmM0LlVJbnQ2NChzZWxmLnZvdGluZ19vcGVuKCkpLAogICAgLy8gICAgICAgICBpc19hbGxvd2VkX3RvX3ZvdGU9YXJjNC5VSW50NjQoc2VsZi5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlKSksCiAgICAvLyAgICAgICAgIGhhc19hbHJlYWR5X3ZvdGVkPWFyYzQuVUludDY0KHNlbGYuYWxyZWFkeV92b3RlZCgpKSwKICAgIC8vICAgICAgICAgY3VycmVudF90aW1lPWFyYzQuVUludDY0KEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wKSwKICAgIC8vICAgICApCiAgICAvLyAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZvdGUoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBmdW5kX21pbl9iYWxfcmVxOiBndHhuLlBheW1lbnRUcmFuc2FjdGlvbiwKICAgIC8vICAgICBzaWduYXR1cmU6IEJ5dGVzLAogICAgLy8gICAgIGFuc3dlcl9pZHM6IFZvdGVJbmRleEFycmF5LAogICAgLy8gKSAtPiBOb25lOgogICAgLy8gICAgIGVuc3VyZV9idWRnZXQoNzcwMCwgZmVlX3NvdXJjZT1PcFVwRmVlU291cmNlLkdyb3VwQ3JlZGl0KQogICAgLy8gICAgICMgQ2hlY2sgdm90aW5nIHByZWNvbmRpdGlvbnMKICAgIC8vICAgICBhc3NlcnQgc2VsZi5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlKSwgIk5vdCBhbGxvd2VkIHRvIHZvdGUiCiAgICAvLyAgICAgYXNzZXJ0IHNlbGYudm90aW5nX29wZW4oKSwgIlZvdGluZyBub3Qgb3BlbiIKICAgIC8vICAgICBhc3NlcnQgbm90IHNlbGYuYWxyZWFkeV92b3RlZCgpLCAiQWxyZWFkeSB2b3RlZCIKICAgIC8vICAgICBxdWVzdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHMubGVuZ3RoCiAgICAvLyAgICAgYXNzZXJ0IGFuc3dlcl9pZHMubGVuZ3RoID09IHF1ZXN0aW9uc19jb3VudCwgIk51bWJlciBvZiBhbnN3ZXJzIGluY29ycmVjdCIKICAgIC8vICAgICAjIENoZWNrIHZvdGVyIGJveCBpcyBmdW5kZWQKICAgIC8vICAgICBtaW5fYmFsX3JlcSA9IEJPWF9GTEFUX01JTl9CQUxBTkNFICsgKAogICAgLy8gICAgICAgICAoMzIgKyAyICsgVk9URV9JTkRFWF9CWVRFUyAqIGFuc3dlcl9pZHMubGVuZ3RoKSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICAvLyAgICAgKQogICAgLy8gICAgIGFzc2VydCAoCiAgICAvLyAgICAgICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gICAgICksICJQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MiCiAgICAvLyAKICAgIC8vICAgICBsb2cobWluX2JhbF9yZXEpCiAgICAvLyAgICAgYXNzZXJ0IGZ1bmRfbWluX2JhbF9yZXEuYW1vdW50ID09IG1pbl9iYWxfcmVxLCAiUGF5bWVudCBtdXN0IGJlIHRoZSBleGFjdCBtaW4gYmFsYW5jZSIKICAgIC8vICAgICAjIFJlY29yZCB0aGUgdm90ZSBmb3IgZWFjaCBxdWVzdGlvbgogICAgLy8gICAgIGN1bXVsYXRpdmVfb2Zmc2V0ID0gVUludDY0KDApCiAgICAvLyAgICAgZm9yIHF1ZXN0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbnNfY291bnQpOgogICAgLy8gICAgICAgICAjIExvYWQgdGhlIHVzZXIncyB2b3RlIGZvciB0aGlzIHF1ZXN0aW9uCiAgICAvLyAgICAgICAgIGFuc3dlcl9vcHRpb25faW5kZXggPSBhbnN3ZXJfaWRzW3F1ZXN0aW9uX2luZGV4XS5uYXRpdmUKICAgIC8vICAgICAgICAgb3B0aW9uc19jb3VudCA9IHNlbGYub3B0aW9uX2NvdW50c1txdWVzdGlvbl9pbmRleF0ubmF0aXZlCiAgICAvLyAgICAgICAgIGFzc2VydCBhbnN3ZXJfb3B0aW9uX2luZGV4IDwgb3B0aW9uc19jb3VudCwgIkFuc3dlciBvcHRpb24gaW5kZXggaW52YWxpZCIKICAgIC8vICAgICAgICAgc2VsZi5pbmNyZW1lbnRfdm90ZV9pbl9ib3goY3VtdWxhdGl2ZV9vZmZzZXQgKyBhbnN3ZXJfb3B0aW9uX2luZGV4KQogICAgLy8gICAgICAgICBjdW11bGF0aXZlX29mZnNldCArPSBvcHRpb25zX2NvdW50CiAgICAvLyAgICAgICAgIHNlbGYudm90ZXNfYnlfYWNjb3VudFtUeG4uc2VuZGVyXSA9IGFuc3dlcl9pZHMuY29weSgpCiAgICAvLyAgICAgICAgIHNlbGYudm90ZXJfY291bnQgKz0gMQogICAgLy8gCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHZvdGluZ19vcGVuKHNlbGYpIC0+IGJvb2w6CiAgICAvLyAgICAgcmV0dXJuICgKICAgIC8vICAgICAgICAgc2VsZi5pc19ib290c3RyYXBwZWQKICAgIC8vICAgICAgICAgYW5kIG5vdCBzZWxmLmNsb3NlX3RpbWUKICAgIC8vICAgICAgICAgYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICAvLyAgICAgKQogICAgLy8gCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGFscmVhZHlfdm90ZWQoc2VsZikgLT4gYm9vbDoKICAgIC8vICAgICByZXR1cm4gVHhuLnNlbmRlciBpbiBzZWxmLnZvdGVzX2J5X2FjY291bnQKICAgIGJveF9sZW4KICAgIGJ1cnkgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTUKICAgIC8vIHJldHVybiBUeG4uc2VuZGVyIGluIHNlbGYudm90ZXNfYnlfYWNjb3VudAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC52b3RlKGZ1bmRfbWluX2JhbF9yZXE6IHVpbnQ2NCwgc2lnbmF0dXJlOiBieXRlcywgYW5zd2VyX2lkczogYnl0ZXMpIC0+IHZvaWQ6CnZvdGU6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2OS0xNzUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIHZvdGUoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBmdW5kX21pbl9iYWxfcmVxOiBndHhuLlBheW1lbnRUcmFuc2FjdGlvbiwKICAgIC8vICAgICBzaWduYXR1cmU6IEJ5dGVzLAogICAgLy8gICAgIGFuc3dlcl9pZHM6IFZvdGVJbmRleEFycmF5LAogICAgLy8gKSAtPiBOb25lOgogICAgcHJvdG8gMyAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE3NgogICAgLy8gZW5zdXJlX2J1ZGdldCg3NzAwLCBmZWVfc291cmNlPU9wVXBGZWVTb3VyY2UuR3JvdXBDcmVkaXQpCiAgICBpbnQgNzcwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNzctMTc4CiAgICAvLyAjIENoZWNrIHZvdGluZyBwcmVjb25kaXRpb25zCiAgICAvLyBhc3NlcnQgc2VsZi5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlKSwgIk5vdCBhbGxvd2VkIHRvIHZvdGUiCiAgICBmcmFtZV9kaWcgLTIKICAgIGNhbGxzdWIgYWxsb3dlZF90b192b3RlCiAgICBhc3NlcnQgLy8gTm90IGFsbG93ZWQgdG8gdm90ZQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNzkKICAgIC8vIGFzc2VydCBzZWxmLnZvdGluZ19vcGVuKCksICJWb3Rpbmcgbm90IG9wZW4iCiAgICBjYWxsc3ViIHZvdGluZ19vcGVuCiAgICBhc3NlcnQgLy8gVm90aW5nIG5vdCBvcGVuCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4MAogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLmFscmVhZHlfdm90ZWQoKSwgIkFscmVhZHkgdm90ZWQiCiAgICBjYWxsc3ViIGFscmVhZHlfdm90ZWQKICAgICEKICAgIGFzc2VydCAvLyBBbHJlYWR5IHZvdGVkCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4MQogICAgLy8gcXVlc3Rpb25zX2NvdW50ID0gc2VsZi5vcHRpb25fY291bnRzLmxlbmd0aAogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjI3CiAgICAvLyBzZWxmLm9wdGlvbl9jb3VudHMgPSBvcHRpb25fY291bnRzLmNvcHkoKQogICAgYnl0ZSAib3B0aW9uX2NvdW50cyIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgxCiAgICAvLyBxdWVzdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHMubGVuZ3RoCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYub3B0aW9uX2NvdW50cyBleGlzdHMKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgZHVwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4MgogICAgLy8gYXNzZXJ0IGFuc3dlcl9pZHMubGVuZ3RoID09IHF1ZXN0aW9uc19jb3VudCwgIk51bWJlciBvZiBhbnN3ZXJzIGluY29ycmVjdCIKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkdXAKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBOdW1iZXIgb2YgYW5zd2VycyBpbmNvcnJlY3QKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTg1CiAgICAvLyAoMzIgKyAyICsgVk9URV9JTkRFWF9CWVRFUyAqIGFuc3dlcl9pZHMubGVuZ3RoKSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFCiAgICBpbnQgMzQKICAgICsKICAgIGludCA0MDAKICAgICoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgzLTE4NAogICAgLy8gIyBDaGVjayB2b3RlciBib3ggaXMgZnVuZGVkCiAgICAvLyBtaW5fYmFsX3JlcSA9IEJPWF9GTEFUX01JTl9CQUxBTkNFICsgKAogICAgaW50IDI1MDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgzLTE4NgogICAgLy8gIyBDaGVjayB2b3RlciBib3ggaXMgZnVuZGVkCiAgICAvLyBtaW5fYmFsX3JlcSA9IEJPWF9GTEFUX01JTl9CQUxBTkNFICsgKAogICAgLy8gICAgICgzMiArIDIgKyBWT1RFX0lOREVYX0JZVEVTICogYW5zd2VyX2lkcy5sZW5ndGgpICogQk9YX0JZVEVfTUlOX0JBTEFOQ0UKICAgIC8vICkKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTg4CiAgICAvLyBmdW5kX21pbl9iYWxfcmVxLnJlY2VpdmVyID09IEdsb2JhbC5jdXJyZW50X2FwcGxpY2F0aW9uX2FkZHJlc3MKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgUmVjZWl2ZXIKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICA9PQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODctMTg5CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gKSwgIlBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcyIKICAgIGFzc2VydCAvLyBQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTkxCiAgICAvLyBsb2cobWluX2JhbF9yZXEpCiAgICBkdXAKICAgIGl0b2IKICAgIGxvZwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTIKICAgIC8vIGFzc2VydCBmdW5kX21pbl9iYWxfcmVxLmFtb3VudCA9PSBtaW5fYmFsX3JlcSwgIlBheW1lbnQgbXVzdCBiZSB0aGUgZXhhY3QgbWluIGJhbGFuY2UiCiAgICBmcmFtZV9kaWcgLTMKICAgIGd0eG5zIEFtb3VudAogICAgPT0KICAgIGFzc2VydCAvLyBQYXltZW50IG11c3QgYmUgdGhlIGV4YWN0IG1pbiBiYWxhbmNlCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5My0xOTQKICAgIC8vICMgUmVjb3JkIHRoZSB2b3RlIGZvciBlYWNoIHF1ZXN0aW9uCiAgICAvLyBjdW11bGF0aXZlX29mZnNldCA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTk1CiAgICAvLyBmb3IgcXVlc3Rpb25faW5kZXggaW4gdXJhbmdlKHF1ZXN0aW9uc19jb3VudCk6CiAgICBkdXAKCnZvdGVfZm9yX2hlYWRlckAxOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTUKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25zX2NvdW50KToKICAgIGZyYW1lX2RpZyAyCiAgICBmcmFtZV9kaWcgMAogICAgPAogICAgYnogdm90ZV9hZnRlcl9mb3JANAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTYtMTk3CiAgICAvLyAjIExvYWQgdGhlIHVzZXIncyB2b3RlIGZvciB0aGlzIHF1ZXN0aW9uCiAgICAvLyBhbnN3ZXJfb3B0aW9uX2luZGV4ID0gYW5zd2VyX2lkc1txdWVzdGlvbl9pbmRleF0ubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEKICAgIGV4dHJhY3QgMiAwCiAgICBmcmFtZV9kaWcgMgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBpbnQgMQogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBidG9pCiAgICBzd2FwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5OAogICAgLy8gb3B0aW9uc19jb3VudCA9IHNlbGYub3B0aW9uX2NvdW50c1txdWVzdGlvbl9pbmRleF0ubmF0aXZlCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjcKICAgIC8vIHNlbGYub3B0aW9uX2NvdW50cyA9IG9wdGlvbl9jb3VudHMuY29weSgpCiAgICBieXRlICJvcHRpb25fY291bnRzIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTgKICAgIC8vIG9wdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHNbcXVlc3Rpb25faW5kZXhdLm5hdGl2ZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLm9wdGlvbl9jb3VudHMgZXhpc3RzCiAgICBleHRyYWN0IDIgMAogICAgZGlnIDEKICAgIGludCAxCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ0b2kKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTk5CiAgICAvLyBhc3NlcnQgYW5zd2VyX29wdGlvbl9pbmRleCA8IG9wdGlvbnNfY291bnQsICJBbnN3ZXIgb3B0aW9uIGluZGV4IGludmFsaWQiCiAgICBkaWcgMgogICAgZGlnIDEKICAgIDwKICAgIGFzc2VydCAvLyBBbnN3ZXIgb3B0aW9uIGluZGV4IGludmFsaWQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjAwCiAgICAvLyBzZWxmLmluY3JlbWVudF92b3RlX2luX2JveChjdW11bGF0aXZlX29mZnNldCArIGFuc3dlcl9vcHRpb25faW5kZXgpCiAgICBmcmFtZV9kaWcgMQogICAgZHVwCiAgICB1bmNvdmVyIDQKICAgICsKICAgIGNhbGxzdWIgaW5jcmVtZW50X3ZvdGVfaW5fYm94CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMQogICAgLy8gY3VtdWxhdGl2ZV9vZmZzZXQgKz0gb3B0aW9uc19jb3VudAogICAgKwogICAgZnJhbWVfYnVyeSAxCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMgogICAgLy8gc2VsZi52b3Rlc19ieV9hY2NvdW50W1R4bi5zZW5kZXJdID0gYW5zd2VyX2lkcy5jb3B5KCkKICAgIHR4biBTZW5kZXIKICAgIGR1cAogICAgYm94X2RlbAogICAgcG9wCiAgICBmcmFtZV9kaWcgLTEKICAgIGJveF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjAzCiAgICAvLyBzZWxmLnZvdGVyX2NvdW50ICs9IDEKICAgIGludCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUyLTUzCiAgICAvLyAjIFRoZSBtaW5pbXVtIG51bWJlciBvZiB2b3RlcnMgd2hvIGhhdmUgdm90ZWQKICAgIC8vIHNlbGYudm90ZXJfY291bnQgPSBVSW50NjQoMCkKICAgIGJ5dGUgInZvdGVyX2NvdW50IgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDMKICAgIC8vIHNlbGYudm90ZXJfY291bnQgKz0gMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnZvdGVyX2NvdW50IGV4aXN0cwogICAgaW50IDEKICAgICsKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTItNTMKICAgIC8vICMgVGhlIG1pbmltdW0gbnVtYmVyIG9mIHZvdGVycyB3aG8gaGF2ZSB2b3RlZAogICAgLy8gc2VsZi52b3Rlcl9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidm90ZXJfY291bnQiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMwogICAgLy8gc2VsZi52b3Rlcl9jb3VudCArPSAxCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTUKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25zX2NvdW50KToKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDIKICAgIGIgdm90ZV9mb3JfaGVhZGVyQDEKCnZvdGVfYWZ0ZXJfZm9yQDQ6CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmluY3JlbWVudF92b3RlX2luX2JveChpbmRleDogdWludDY0KSAtPiB2b2lkOgppbmNyZW1lbnRfdm90ZV9pbl9ib3g6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI0My0yNDQKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgaW5jcmVtZW50X3ZvdGVfaW5fYm94KHNlbGYsIGluZGV4OiBVSW50NjQpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQ1CiAgICAvLyBjdXJyZW50X3ZvdGUgPSBzZWxmLmdldF92b3RlX2Zyb21fYm94KGluZGV4KQogICAgZnJhbWVfZGlnIC0xCiAgICBjYWxsc3ViIGdldF92b3RlX2Zyb21fYm94CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI0NgogICAgLy8gc2VsZi50YWxseV9ib3gucmVwbGFjZShpbmRleCwgb3AuaXRvYihjdXJyZW50X3ZvdGUgKyAxKSkKICAgIGludCAxCiAgICArCiAgICBpdG9iCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU1CiAgICAvLyBzZWxmLnRhbGx5X2JveCA9IEJveFJlZihrZXk9IlYiKQogICAgYnl0ZSAiViIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQ2CiAgICAvLyBzZWxmLnRhbGx5X2JveC5yZXBsYWNlKGluZGV4LCBvcC5pdG9iKGN1cnJlbnRfdm90ZSArIDEpKQogICAgZnJhbWVfZGlnIC0xCiAgICB1bmNvdmVyIDIKICAgIGJveF9yZXBsYWNlCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUwCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1MQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBGYWxzZQogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUyLTUzCiAgICAvLyAjIFRoZSBtaW5pbXVtIG51bWJlciBvZiB2b3RlcnMgd2hvIGhhdmUgdm90ZWQKICAgIC8vIHNlbGYudm90ZXJfY291bnQgPSBVSW50NjQoMCkKICAgIGJ5dGUgInZvdGVyX2NvdW50IgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyBfcHV5YV9saWIudXRpbC5lbnN1cmVfYnVkZ2V0KHJlcXVpcmVkX2J1ZGdldDogdWludDY0LCBmZWVfc291cmNlOiB1aW50NjQpIC0+IHZvaWQ6CmVuc3VyZV9idWRnZXQ6CiAgICAvLyBfcHV5YV9saWIvdXRpbC5weToxMi0xMwogICAgcHJvdG8gMiAwCiAgICAvLyBfcHV5YV9saWIvdXRpbC5weToxNC0xOQogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMTAKICAgICsKCmVuc3VyZV9idWRnZXRfd2hpbGVfdG9wQDE6CiAgICAvLyBfcHV5YV9saWIvdXRpbC5weToyMAogICAgZnJhbWVfZGlnIDAKICAgIGdsb2JhbCBPcGNvZGVCdWRnZXQKICAgID4KICAgIGJ6IGVuc3VyZV9idWRnZXRfYWZ0ZXJfd2hpbGVANwogICAgLy8gX3B1eWFfbGliL3V0aWwucHk6MjEKICAgIGl0eG5fYmVnaW4KICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjIyCiAgICBpbnQgYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gX3B1eWFfbGliL3V0aWwucHk6MjMKICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgaXR4bl9maWVsZCBPbkNvbXBsZXRpb24KICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjI0CiAgICBieXRlIDB4MDY4MTAxCiAgICBpdHhuX2ZpZWxkIEFwcHJvdmFsUHJvZ3JhbQogICAgLy8gX3B1eWFfbGliL3V0aWwucHk6MjUKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW0KICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjI2LTMwCiAgICBmcmFtZV9kaWcgLTEKICAgIHN3aXRjaCBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzBAMyBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzFANAogICAgYiBlbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANgoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV8wQDM6CiAgICAvLyBfcHV5YV9saWIvdXRpbC5weToyOAogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICBiIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfbmV4dEA2CgplbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzFANDoKICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjMwCiAgICBnbG9iYWwgTWluVHhuRmVlCiAgICBpdHhuX2ZpZWxkIEZlZQoKZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDY6CiAgICAvLyBfcHV5YV9saWIvdXRpbC5weTozMS0zMwogICAgaXR4bl9zdWJtaXQKICAgIGIgZW5zdXJlX2J1ZGdldF93aGlsZV90b3BAMQoKZW5zdXJlX2J1ZGdldF9hZnRlcl93aGlsZUA3OgogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo0OQogICAgLy8gY2xhc3MgVm90aW5nUm91bmRBcHAoQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTAKICAgIG1ldGhvZCAiY3JlYXRlKHN0cmluZyxieXRlW10sc3RyaW5nLHVpbnQ2NCx1aW50NjQsdWludDhbXSx1aW50NjQsc3RyaW5nKXZvaWQiCiAgICBtZXRob2QgImJvb3RzdHJhcChwYXkpdm9pZCIKICAgIG1ldGhvZCAiY2xvc2UoKXZvaWQiCiAgICBtZXRob2QgImdldF9wcmVjb25kaXRpb25zKGJ5dGVbXSkodWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0KSIKICAgIG1ldGhvZCAidm90ZShwYXksYnl0ZVtdLHVpbnQ4W10pdm9pZCIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2Jvb3RzdHJhcF9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2Nsb3NlX3JvdXRlQDQgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X3ByZWNvbmRpdGlvbnNfcm91dGVANSBfX3B1eWFfYXJjNF9yb3V0ZXJfX192b3RlX3JvdXRlQDYKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA2CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA3CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA4CiAgICBleHRyYWN0IDIgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo1OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICBjYWxsc3ViIGNyZWF0ZQogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYm9vdHN0cmFwX3JvdXRlQDM6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjgyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NDkKICAgIC8vIGNsYXNzIFZvdGluZ1JvdW5kQXBwKEFSQzRDb250cmFjdCk6CiAgICB0eG4gR3JvdXBJbmRleAogICAgaW50IDEKICAgIC0KICAgIGR1cAogICAgZ3R4bnMgVHlwZUVudW0KICAgIGludCBwYXkKICAgID09CiAgICBhc3NlcnQgLy8gdHJhbnNhY3Rpb24gdHlwZSBpcyBwYXkKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODIKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBib290c3RyYXAKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2Nsb3NlX3JvdXRlQDQ6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExMAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGNsb3NlCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfcHJlY29uZGl0aW9uc19yb3V0ZUA1OgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gdm90aW5nL3ZvdGluZy5weTo0OQogICAgLy8gY2xhc3MgVm90aW5nUm91bmRBcHAoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICBjYWxsc3ViIGdldF9wcmVjb25kaXRpb25zCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX192b3RlX3JvdXRlQDY6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjQ5CiAgICAvLyBjbGFzcyBWb3RpbmdSb3VuZEFwcChBUkM0Q29udHJhY3QpOgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICBleHRyYWN0IDIgMAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiB2b3RlCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo0OQogICAgLy8gY2xhc3MgVm90aW5nUm91bmRBcHAoQVJDNENvbnRyYWN0KToKICAgIGludCAwCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmNyZWF0ZSh2b3RlX2lkOiBieXRlcywgc25hcHNob3RfcHVibGljX2tleTogYnl0ZXMsIG1ldGFkYXRhX2lwZnNfY2lkOiBieXRlcywgc3RhcnRfdGltZTogdWludDY0LCBlbmRfdGltZTogdWludDY0LCBvcHRpb25fY291bnRzOiBieXRlcywgcXVvcnVtOiB1aW50NjQsIG5mdF9pbWFnZV91cmw6IGJ5dGVzKSAtPiB2b2lkOgpjcmVhdGU6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjU4LTY5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIC8vIGRlZiBjcmVhdGUoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICB2b3RlX2lkOiBTdHJpbmcsCiAgICAvLyAgICAgc25hcHNob3RfcHVibGljX2tleTogQnl0ZXMsCiAgICAvLyAgICAgbWV0YWRhdGFfaXBmc19jaWQ6IFN0cmluZywKICAgIC8vICAgICBzdGFydF90aW1lOiBVSW50NjQsCiAgICAvLyAgICAgZW5kX3RpbWU6IFVJbnQ2NCwKICAgIC8vICAgICBvcHRpb25fY291bnRzOiBWb3RlSW5kZXhBcnJheSwKICAgIC8vICAgICBxdW9ydW06IFVJbnQ2NCwKICAgIC8vICAgICBuZnRfaW1hZ2VfdXJsOiBTdHJpbmcsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byA4IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzAKICAgIC8vIGFzc2VydCBzdGFydF90aW1lIDwgZW5kX3RpbWUsICJFbmQgdGltZSBzaG91bGQgYmUgYWZ0ZXIgc3RhcnQgdGltZSIKICAgIGZyYW1lX2RpZyAtNQogICAgZnJhbWVfZGlnIC00CiAgICA8CiAgICBhc3NlcnQgLy8gRW5kIHRpbWUgc2hvdWxkIGJlIGFmdGVyIHN0YXJ0IHRpbWUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzEKICAgIC8vIGFzc2VydCBlbmRfdGltZSA+PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCwgIkVuZCB0aW1lIHNob3VsZCBiZSBpbiB0aGUgZnV0dXJlIgogICAgZnJhbWVfZGlnIC00CiAgICBnbG9iYWwgTGF0ZXN0VGltZXN0YW1wCiAgICA+PQogICAgYXNzZXJ0IC8vIEVuZCB0aW1lIHNob3VsZCBiZSBpbiB0aGUgZnV0dXJlCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjczCiAgICAvLyBzZWxmLnZvdGVfaWQgPSB2b3RlX2lkCiAgICBieXRlICJ2b3RlX2lkIgogICAgZnJhbWVfZGlnIC04CiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NAogICAgLy8gc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5ID0gc25hcHNob3RfcHVibGljX2tleQogICAgYnl0ZSAic25hcHNob3RfcHVibGljX2tleSIKICAgIGZyYW1lX2RpZyAtNwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzUKICAgIC8vIHNlbGYubWV0YWRhdGFfaXBmc19jaWQgPSBtZXRhZGF0YV9pcGZzX2NpZAogICAgYnl0ZSAibWV0YWRhdGFfaXBmc19jaWQiCiAgICBmcmFtZV9kaWcgLTYKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc2CiAgICAvLyBzZWxmLnN0YXJ0X3RpbWUgPSBzdGFydF90aW1lCiAgICBieXRlICJzdGFydF90aW1lIgogICAgZnJhbWVfZGlnIC01CiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo3NwogICAgLy8gc2VsZi5lbmRfdGltZSA9IGVuZF90aW1lCiAgICBieXRlICJlbmRfdGltZSIKICAgIGZyYW1lX2RpZyAtNAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NzgKICAgIC8vIHNlbGYucXVvcnVtID0gcXVvcnVtCiAgICBieXRlICJxdW9ydW0iCiAgICBmcmFtZV9kaWcgLTIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojc5CiAgICAvLyBzZWxmLm5mdF9pbWFnZV91cmwgPSBuZnRfaW1hZ2VfdXJsCiAgICBieXRlICJuZnRfaW1hZ2VfdXJsIgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4MAogICAgLy8gc2VsZi5zdG9yZV9vcHRpb25fY291bnRzKG9wdGlvbl9jb3VudHMuY29weSgpKQogICAgZnJhbWVfZGlnIC0zCiAgICBjYWxsc3ViIHN0b3JlX29wdGlvbl9jb3VudHMKICAgIHBvcAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5zdG9yZV9vcHRpb25fY291bnRzKG9wdGlvbl9jb3VudHM6IGJ5dGVzKSAtPiBieXRlczoKc3RvcmVfb3B0aW9uX2NvdW50czoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjE3LTIxOAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBzdG9yZV9vcHRpb25fY291bnRzKHNlbGYsIG9wdGlvbl9jb3VudHM6IFZvdGVJbmRleEFycmF5KSAtPiBOb25lOgogICAgcHJvdG8gMSAxCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxOQogICAgLy8gYXNzZXJ0IG9wdGlvbl9jb3VudHMubGVuZ3RoLCAib3B0aW9uX2NvdW50cyBzaG91bGQgYmUgbm9uLWVtcHR5IgogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGR1cG4gMgogICAgYXNzZXJ0IC8vIG9wdGlvbl9jb3VudHMgc2hvdWxkIGJlIG5vbi1lbXB0eQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjAKICAgIC8vIGFzc2VydCBvcHRpb25fY291bnRzLmxlbmd0aCA8PSAxMTIsICJDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMTIgcXVlc3Rpb25zIgogICAgaW50IDExMgogICAgPD0KICAgIGFzc2VydCAvLyBDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMTIgcXVlc3Rpb25zCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyMgogICAgLy8gdG90YWxfb3B0aW9ucyA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIGR1cAoKc3RvcmVfb3B0aW9uX2NvdW50c19mb3JfaGVhZGVyQDE6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyMwogICAgLy8gZm9yIGl0ZW0gaW4gb3B0aW9uX2NvdW50czoKICAgIGZyYW1lX2RpZyAyCiAgICBmcmFtZV9kaWcgMAogICAgPAogICAgYnogc3RvcmVfb3B0aW9uX2NvdW50c19hZnRlcl9mb3JANAogICAgZnJhbWVfZGlnIC0xCiAgICBleHRyYWN0IDIgMAogICAgZnJhbWVfZGlnIDIKICAgIGR1cAogICAgY292ZXIgMgogICAgaW50IDEKICAgIGV4dHJhY3QzIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjQKICAgIC8vIHRvdGFsX29wdGlvbnMgKz0gaXRlbS5uYXRpdmUKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAxCiAgICArCiAgICBmcmFtZV9idXJ5IDEKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDIKICAgIGIgc3RvcmVfb3B0aW9uX2NvdW50c19mb3JfaGVhZGVyQDEKCnN0b3JlX29wdGlvbl9jb3VudHNfYWZ0ZXJfZm9yQDQ6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIyNQogICAgLy8gYXNzZXJ0IHRvdGFsX29wdGlvbnMgPD0gMTI4LCAiQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gMTI4IHZvdGUgb3B0aW9ucyIKICAgIGZyYW1lX2RpZyAxCiAgICBkdXAKICAgIGludCAxMjgKICAgIDw9CiAgICBhc3NlcnQgLy8gQ2FuJ3QgaGF2ZSBtb3JlIHRoYW4gMTI4IHZvdGUgb3B0aW9ucwogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjcKICAgIC8vIHNlbGYub3B0aW9uX2NvdW50cyA9IG9wdGlvbl9jb3VudHMuY29weSgpCiAgICBieXRlICJvcHRpb25fY291bnRzIgogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMjgKICAgIC8vIHNlbGYudG90YWxfb3B0aW9ucyA9IHRvdGFsX29wdGlvbnMKICAgIGJ5dGUgInRvdGFsX29wdGlvbnMiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgZnJhbWVfZGlnIC0xCiAgICBmcmFtZV9idXJ5IDAKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuYm9vdHN0cmFwKGZ1bmRfbWluX2JhbF9yZXE6IHVpbnQ2NCkgLT4gdm9pZDoKYm9vdHN0cmFwOgogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4Mi04MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgYm9vdHN0cmFwKHNlbGYsIGZ1bmRfbWluX2JhbF9yZXE6IGd0eG4uUGF5bWVudFRyYW5zYWN0aW9uKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojg0CiAgICAvLyBhc3NlcnQgbm90IHNlbGYuaXNfYm9vdHN0cmFwcGVkLCAiTXVzdCBub3QgYmUgYWxyZWFkeSBib290c3RyYXBwZWQiCiAgICBpbnQgMAogICAgYnl0ZSAiaXNfYm9vdHN0cmFwcGVkIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmlzX2Jvb3RzdHJhcHBlZCBleGlzdHMKICAgICEKICAgIGFzc2VydCAvLyBNdXN0IG5vdCBiZSBhbHJlYWR5IGJvb3RzdHJhcHBlZAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo4NQogICAgLy8gc2VsZi5pc19ib290c3RyYXBwZWQgPSBUcnVlCiAgICBieXRlICJpc19ib290c3RyYXBwZWQiCiAgICBpbnQgMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6ODgKICAgIC8vIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5Ojg3LTg5CiAgICAvLyBhc3NlcnQgKAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgLy8gKSwgIlBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcyIKICAgIGFzc2VydCAvLyBQYXltZW50IG11c3QgYmUgdG8gYXBwIGFkZHJlc3MKICAgIC8vIHZvdGluZy92b3RpbmcucHk6OTEKICAgIC8vIHRhbGx5X2JveF9zaXplID0gc2VsZi50b3RhbF9vcHRpb25zICogVk9URV9DT1VOVF9CWVRFUwogICAgaW50IDAKICAgIGJ5dGUgInRvdGFsX29wdGlvbnMiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudG90YWxfb3B0aW9ucyBleGlzdHMKICAgIGludCA4CiAgICAqCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEwMS0xMDIKICAgIC8vICMgdGFsbHkgYm94IHZhbHVlCiAgICAvLyArICh0YWxseV9ib3hfc2l6ZSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFKQogICAgZHVwCiAgICBpbnQgNDAwCiAgICAqCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjkzLTEwMAogICAgLy8gIyBtaW5pbXVtIGJhbGFuY2UgcmVxIGZvcjogQUxHT3MgKyBWb3RlIHJlc3VsdCBORlQgYXNzZXQKICAgIC8vIEFTU0VUX01JTl9CQUxBTkNFICogMgogICAgLy8gIyBjcmVhdGUgTkZUIGZlZQogICAgLy8gKyAxMDAwCiAgICAvLyAjIHRhbGx5IGJveAogICAgLy8gKyBCT1hfRkxBVF9NSU5fQkFMQU5DRQogICAgLy8gIyB0YWxseSBib3gga2V5ICJWIgogICAgLy8gKyBCT1hfQllURV9NSU5fQkFMQU5DRQogICAgaW50IDIwMzkwMAogICAgLy8gdm90aW5nL3ZvdGluZy5weTo5My0xMDIKICAgIC8vICMgbWluaW11bSBiYWxhbmNlIHJlcSBmb3I6IEFMR09zICsgVm90ZSByZXN1bHQgTkZUIGFzc2V0CiAgICAvLyBBU1NFVF9NSU5fQkFMQU5DRSAqIDIKICAgIC8vICMgY3JlYXRlIE5GVCBmZWUKICAgIC8vICsgMTAwMAogICAgLy8gIyB0YWxseSBib3gKICAgIC8vICsgQk9YX0ZMQVRfTUlOX0JBTEFOQ0UKICAgIC8vICMgdGFsbHkgYm94IGtleSAiViIKICAgIC8vICsgQk9YX0JZVEVfTUlOX0JBTEFOQ0UKICAgIC8vICMgdGFsbHkgYm94IHZhbHVlCiAgICAvLyArICh0YWxseV9ib3hfc2l6ZSAqIEJPWF9CWVRFX01JTl9CQUxBTkNFKQogICAgKwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDQKICAgIC8vIGxvZyhtaW5fYmFsYW5jZV9yZXEpCiAgICBkdXAKICAgIGl0b2IKICAgIGxvZwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMDYKICAgIC8vIGZ1bmRfbWluX2JhbF9yZXEuYW1vdW50ID09IG1pbl9iYWxhbmNlX3JlcQogICAgZnJhbWVfZGlnIC0xCiAgICBndHhucyBBbW91bnQKICAgID09CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEwNS0xMDcKICAgIC8vIGFzc2VydCAoCiAgICAvLyAgICAgZnVuZF9taW5fYmFsX3JlcS5hbW91bnQgPT0gbWluX2JhbGFuY2VfcmVxCiAgICAvLyApLCAiUGF5bWVudCBtdXN0IGJlIGZvciB0aGUgZXhhY3QgbWluIGJhbGFuY2UgcmVxdWlyZW1lbnQiCiAgICBhc3NlcnQgLy8gUGF5bWVudCBtdXN0IGJlIGZvciB0aGUgZXhhY3QgbWluIGJhbGFuY2UgcmVxdWlyZW1lbnQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTA4CiAgICAvLyBhc3NlcnQgc2VsZi50YWxseV9ib3guY3JlYXRlKHNpemU9dGFsbHlfYm94X3NpemUpCiAgICBieXRlICJWIgogICAgc3dhcAogICAgYm94X2NyZWF0ZQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmNsb3NlKCkgLT4gdm9pZDoKY2xvc2U6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExMC0xMTEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGNsb3NlKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIGludCAwCiAgICBkdXAKICAgIGJ5dGUgIiIKICAgIGR1cG4gMgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTIKICAgIC8vIGVuc3VyZV9idWRnZXQoMjAwMDAsIGZlZV9zb3VyY2U9T3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCAyMDAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTMKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5jbG9zZV90aW1lLCAiQWxyZWFkeSBjbG9zZWQiCiAgICBpbnQgMAogICAgYnl0ZSAiY2xvc2VfdGltZSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBidXJ5IDEKICAgICEKICAgIGFzc2VydCAvLyBBbHJlYWR5IGNsb3NlZAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTQKICAgIC8vIHNlbGYuY2xvc2VfdGltZS52YWx1ZSA9IEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wCiAgICBieXRlICJjbG9zZV90aW1lIgogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE5CiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgaW50IDAKICAgIGJ5dGUgInZvdGVfaWQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYudm90ZV9pZCBleGlzdHMKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTExOAogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgYnl0ZSAie1wic3RhbmRhcmRcIjpcImFyYzY5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMTkKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTIwCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICBieXRlICIuXCIsXCJwcm9wZXJ0aWVzXCI6e1wibWV0YWRhdGFcIjpcImlwZnM6Ly8iCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjAKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTIxCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIGludCAwCiAgICBieXRlICJtZXRhZGF0YV9pcGZzX2NpZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZCBleGlzdHMKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyMQogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyMgogICAgLy8gKyAnIiwiaWQiOiInCiAgICBieXRlICJcIixcImlkXCI6XCIiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjIKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyMwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIGludCAwCiAgICBieXRlICJ2b3RlX2lkIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLnZvdGVfaWQgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjMKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIGNvbmNhdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMjQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgYnl0ZSAiXCIsXCJxdW9ydW1cIjoiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjQKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEyNQogICAgLy8gKyBpdG9hKHNlbGYucXVvcnVtKQogICAgaW50IDAKICAgIGJ5dGUgInF1b3J1bSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5xdW9ydW0gZXhpc3RzCiAgICBjYWxsc3ViIGl0b2EKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyNQogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnIiwicXVvcnVtIjonCiAgICAvLyArIGl0b2Eoc2VsZi5xdW9ydW0pCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTI2CiAgICAvLyArICcsInZvdGVyQ291bnQiOicKICAgIGJ5dGUgIixcInZvdGVyQ291bnRcIjoiCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjExNy0xMjYKICAgIC8vICd7InN0YW5kYXJkIjoiYXJjNjkiLCcKICAgIC8vICciZGVzY3JpcHRpb24iOiJUaGlzIGlzIGEgdm90aW5nIHJlc3VsdCBORlQgZm9yIHZvdGluZyByb3VuZCB3aXRoIElEICcKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICcuIiwicHJvcGVydGllcyI6eyJtZXRhZGF0YSI6ImlwZnM6Ly8nCiAgICAvLyArIHNlbGYubWV0YWRhdGFfaXBmc19jaWQKICAgIC8vICsgJyIsImlkIjoiJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJyIsInF1b3J1bSI6JwogICAgLy8gKyBpdG9hKHNlbGYucXVvcnVtKQogICAgLy8gKyAnLCJ2b3RlckNvdW50IjonCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTI3CiAgICAvLyArIGl0b2Eoc2VsZi52b3Rlcl9jb3VudCkKICAgIGludCAwCiAgICBieXRlICJ2b3Rlcl9jb3VudCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi52b3Rlcl9jb3VudCBleGlzdHMKICAgIGNhbGxzdWIgaXRvYQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMTctMTI3CiAgICAvLyAneyJzdGFuZGFyZCI6ImFyYzY5IiwnCiAgICAvLyAnImRlc2NyaXB0aW9uIjoiVGhpcyBpcyBhIHZvdGluZyByZXN1bHQgTkZUIGZvciB2b3Rpbmcgcm91bmQgd2l0aCBJRCAnCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnLiIsInByb3BlcnRpZXMiOnsibWV0YWRhdGEiOiJpcGZzOi8vJwogICAgLy8gKyBzZWxmLm1ldGFkYXRhX2lwZnNfY2lkCiAgICAvLyArICciLCJpZCI6IicKICAgIC8vICsgc2VsZi52b3RlX2lkCiAgICAvLyArICciLCJxdW9ydW0iOicKICAgIC8vICsgaXRvYShzZWxmLnF1b3J1bSkKICAgIC8vICsgJywidm90ZXJDb3VudCI6JwogICAgLy8gKyBpdG9hKHNlbGYudm90ZXJfY291bnQpCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTI4CiAgICAvLyArICcsInRhbGxpZXMiOlsnCiAgICBieXRlICIsXCJ0YWxsaWVzXCI6WyIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTE3LTEyOAogICAgLy8gJ3sic3RhbmRhcmQiOiJhcmM2OSIsJwogICAgLy8gJyJkZXNjcmlwdGlvbiI6IlRoaXMgaXMgYSB2b3RpbmcgcmVzdWx0IE5GVCBmb3Igdm90aW5nIHJvdW5kIHdpdGggSUQgJwogICAgLy8gKyBzZWxmLnZvdGVfaWQKICAgIC8vICsgJy4iLCJwcm9wZXJ0aWVzIjp7Im1ldGFkYXRhIjoiaXBmczovLycKICAgIC8vICsgc2VsZi5tZXRhZGF0YV9pcGZzX2NpZAogICAgLy8gKyAnIiwiaWQiOiInCiAgICAvLyArIHNlbGYudm90ZV9pZAogICAgLy8gKyAnIiwicXVvcnVtIjonCiAgICAvLyArIGl0b2Eoc2VsZi5xdW9ydW0pCiAgICAvLyArICcsInZvdGVyQ291bnQiOicKICAgIC8vICsgaXRvYShzZWxmLnZvdGVyX2NvdW50KQogICAgLy8gKyAnLCJ0YWxsaWVzIjpbJwogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzMQogICAgLy8gY3VycmVudF9pbmRleCA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTMyCiAgICAvLyBmb3IgcXVlc3Rpb25faW5kZXgsIHF1ZXN0aW9uX29wdGlvbnMgaW4gdWVudW1lcmF0ZShzZWxmLm9wdGlvbl9jb3VudHMpOgogICAgZHVwCiAgICBieXRlICJvcHRpb25fY291bnRzIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIHN3YXAKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5vcHRpb25fY291bnRzIGV4aXN0cwogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMAoKY2xvc2VfZm9yX2hlYWRlckAxOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzIKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCwgcXVlc3Rpb25fb3B0aW9ucyBpbiB1ZW51bWVyYXRlKHNlbGYub3B0aW9uX2NvdW50cyk6CiAgICBmcmFtZV9kaWcgOQogICAgZnJhbWVfZGlnIDgKICAgIDwKICAgIGJ6IGNsb3NlX2FmdGVyX2ZvckAxNAogICAgZnJhbWVfZGlnIDcKICAgIGV4dHJhY3QgMiAwCiAgICBmcmFtZV9kaWcgOQogICAgZHVwCiAgICBjb3ZlciAyCiAgICBpbnQgMQogICAgZXh0cmFjdDMgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBmcmFtZV9idXJ5IDEKICAgIGZyYW1lX2RpZyA1CiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTMzCiAgICAvLyBpZiBxdWVzdGlvbl9pbmRleCA+IDA6CiAgICBieiBjbG9zZV9hZnRlcl9pZl9lbHNlQDQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM0CiAgICAvLyBub3RlICs9ICIsIgogICAgZnJhbWVfZGlnIDUKICAgIGJ5dGUgIiwiCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgMAoKY2xvc2VfYWZ0ZXJfaWZfZWxzZUA0OgogICAgZnJhbWVfZGlnIDAKICAgIGR1cAogICAgZnJhbWVfYnVyeSA1CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNQogICAgLy8gaWYgcXVlc3Rpb25fb3B0aW9ucyA+IDA6CiAgICBmcmFtZV9kaWcgMQogICAgYnl0ZSAweDAwCiAgICBiPgogICAgZnJhbWVfZGlnIDYKICAgIGZyYW1lX2J1cnkgMgogICAgc3dhcAogICAgZnJhbWVfYnVyeSAwCiAgICBieiBjbG9zZV9hZnRlcl9pZl9lbHNlQDEyCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNgogICAgLy8gbm90ZSArPSAiWyIKICAgIGZyYW1lX2RpZyA1CiAgICBieXRlICJbIgogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IDUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM3CiAgICAvLyBmb3Igb3B0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbl9vcHRpb25zLm5hdGl2ZSk6CiAgICBmcmFtZV9kaWcgMQogICAgYnRvaQogICAgZnJhbWVfYnVyeSA0CiAgICBpbnQgMAogICAgZnJhbWVfYnVyeSAzCgpjbG9zZV9mb3JfaGVhZGVyQDY6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNwogICAgLy8gZm9yIG9wdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25fb3B0aW9ucy5uYXRpdmUpOgogICAgZnJhbWVfZGlnIDMKICAgIGZyYW1lX2RpZyA0CiAgICA8CiAgICBieiBjbG9zZV9hZnRlcl9mb3JAMTEKICAgIGZyYW1lX2RpZyA1CiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTM4CiAgICAvLyBpZiBvcHRpb25faW5kZXggPiAwOgogICAgZnJhbWVfZGlnIDMKICAgIGJ6IGNsb3NlX2FmdGVyX2lmX2Vsc2VAOQogICAgLy8gdm90aW5nL3ZvdGluZy5weToxMzkKICAgIC8vIG5vdGUgKz0gIiwiCiAgICBmcmFtZV9kaWcgNQogICAgYnl0ZSAiLCIKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAwCgpjbG9zZV9hZnRlcl9pZl9lbHNlQDk6CiAgICBmcmFtZV9kaWcgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDAKICAgIC8vIHZvdGVzX2Zvcl9vcHRpb24gPSBzZWxmLmdldF92b3RlX2Zyb21fYm94KGN1cnJlbnRfaW5kZXgpCiAgICBmcmFtZV9kaWcgNgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBjYWxsc3ViIGdldF92b3RlX2Zyb21fYm94CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0MQogICAgLy8gbm90ZSArPSBpdG9hKHZvdGVzX2Zvcl9vcHRpb24pCiAgICBjYWxsc3ViIGl0b2EKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSA1CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0MgogICAgLy8gY3VycmVudF9pbmRleCArPSAxCiAgICBpbnQgMQogICAgKwogICAgZnJhbWVfYnVyeSA2CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjEzNwogICAgLy8gZm9yIG9wdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25fb3B0aW9ucy5uYXRpdmUpOgogICAgZnJhbWVfZGlnIDMKICAgIGludCAxCiAgICArCiAgICBmcmFtZV9idXJ5IDMKICAgIGIgY2xvc2VfZm9yX2hlYWRlckA2CgpjbG9zZV9hZnRlcl9mb3JAMTE6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0MwogICAgLy8gbm90ZSArPSAiXSIKICAgIGZyYW1lX2RpZyA1CiAgICBieXRlICJdIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgNgogICAgZnJhbWVfYnVyeSAyCiAgICBmcmFtZV9idXJ5IDAKCmNsb3NlX2FmdGVyX2lmX2Vsc2VAMTI6CiAgICBmcmFtZV9kaWcgMgogICAgZnJhbWVfYnVyeSA2CiAgICBmcmFtZV9kaWcgMAogICAgZnJhbWVfYnVyeSA1CiAgICBmcmFtZV9kaWcgOQogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2J1cnkgOQogICAgYiBjbG9zZV9mb3JfaGVhZGVyQDEKCmNsb3NlX2FmdGVyX2ZvckAxNDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ0CiAgICAvLyBub3RlICs9ICJdfX0iCiAgICBmcmFtZV9kaWcgNQogICAgYnl0ZSAiXX19IgogICAgY29uY2F0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0Ni0xNTYKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICAvLyAgICAgdG90YWw9MSwKICAgIC8vICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgIGRlZmF1bHRfZnJvemVuPUZhbHNlLAogICAgLy8gICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgLy8gICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gKQogICAgLy8gLnN1Ym1pdCgpCiAgICBpdHhuX2JlZ2luCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE1NAogICAgLy8gZmVlPUdsb2JhbC5taW5fdHhuX2ZlZSwKICAgIGdsb2JhbCBNaW5UeG5GZWUKICAgIHN3YXAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUwCiAgICAvLyBhc3NldF9uYW1lPSJbVk9URSBSRVNVTFRdICIgKyBzZWxmLnZvdGVfaWQsCiAgICBpbnQgMAogICAgYnl0ZSAidm90ZV9pZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi52b3RlX2lkIGV4aXN0cwogICAgYnl0ZSAiW1ZPVEUgUkVTVUxUXSAiCiAgICBzd2FwCiAgICBjb25jYXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTUyCiAgICAvLyB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgaW50IDAKICAgIGJ5dGUgIm5mdF9pbWFnZV91cmwiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubmZ0X2ltYWdlX3VybCBleGlzdHMKICAgIHVuY292ZXIgMgogICAgaXR4bl9maWVsZCBOb3RlCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VVJMCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE1MQogICAgLy8gdW5pdF9uYW1lPSJWT1RFUlNMVCIsCiAgICBieXRlICJWT1RFUlNMVCIKICAgIGl0eG5fZmllbGQgQ29uZmlnQXNzZXRVbml0TmFtZQogICAgaXR4bl9maWVsZCBDb25maWdBc3NldE5hbWUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ5CiAgICAvLyBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0RGVmYXVsdEZyb3plbgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDgKICAgIC8vIGRlY2ltYWxzPTAsCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBDb25maWdBc3NldERlY2ltYWxzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0NwogICAgLy8gdG90YWw9MSwKICAgIGludCAxCiAgICBpdHhuX2ZpZWxkIENvbmZpZ0Fzc2V0VG90YWwKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ2CiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgaW50IGFjZmcKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE0Ni0xNTYKICAgIC8vIGl0eG4uQXNzZXRDb25maWcoCiAgICAvLyAgICAgdG90YWw9MSwKICAgIC8vICAgICBkZWNpbWFscz0wLAogICAgLy8gICAgIGRlZmF1bHRfZnJvemVuPUZhbHNlLAogICAgLy8gICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICB1bml0X25hbWU9IlZPVEVSU0xUIiwKICAgIC8vICAgICB1cmw9c2VsZi5uZnRfaW1hZ2VfdXJsLAogICAgLy8gICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICBmZWU9R2xvYmFsLm1pbl90eG5fZmVlLAogICAgLy8gKQogICAgLy8gLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDUKICAgIC8vIHNlbGYubmZ0X2Fzc2V0X2lkID0gKAogICAgYnl0ZSAibmZ0X2Fzc2V0X2lkIgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNDYtMTU3CiAgICAvLyBpdHhuLkFzc2V0Q29uZmlnKAogICAgLy8gICAgIHRvdGFsPTEsCiAgICAvLyAgICAgZGVjaW1hbHM9MCwKICAgIC8vICAgICBkZWZhdWx0X2Zyb3plbj1GYWxzZSwKICAgIC8vICAgICBhc3NldF9uYW1lPSJbVk9URSBSRVNVTFRdICIgKyBzZWxmLnZvdGVfaWQsCiAgICAvLyAgICAgdW5pdF9uYW1lPSJWT1RFUlNMVCIsCiAgICAvLyAgICAgdXJsPXNlbGYubmZ0X2ltYWdlX3VybCwKICAgIC8vICAgICBub3RlPW5vdGUsCiAgICAvLyAgICAgZmVlPUdsb2JhbC5taW5fdHhuX2ZlZSwKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgLy8gLmNyZWF0ZWRfYXNzZXQuaWQKICAgIGl0eG4gQ3JlYXRlZEFzc2V0SUQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTQ1LTE1OAogICAgLy8gc2VsZi5uZnRfYXNzZXRfaWQgPSAoCiAgICAvLyAgICAgaXR4bi5Bc3NldENvbmZpZygKICAgIC8vICAgICAgICAgdG90YWw9MSwKICAgIC8vICAgICAgICAgZGVjaW1hbHM9MCwKICAgIC8vICAgICAgICAgZGVmYXVsdF9mcm96ZW49RmFsc2UsCiAgICAvLyAgICAgICAgIGFzc2V0X25hbWU9IltWT1RFIFJFU1VMVF0gIiArIHNlbGYudm90ZV9pZCwKICAgIC8vICAgICAgICAgdW5pdF9uYW1lPSJWT1RFUlNMVCIsCiAgICAvLyAgICAgICAgIHVybD1zZWxmLm5mdF9pbWFnZV91cmwsCiAgICAvLyAgICAgICAgIG5vdGU9bm90ZSwKICAgIC8vICAgICAgICAgZmVlPUdsb2JhbC5taW5fdHhuX2ZlZSwKICAgIC8vICAgICApCiAgICAvLyAgICAgLnN1Ym1pdCgpCiAgICAvLyAgICAgLmNyZWF0ZWRfYXNzZXQuaWQKICAgIC8vICkKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLml0b2EoaTogdWludDY0KSAtPiBieXRlczoKaXRvYToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQ5LTI1MAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBpdG9hKGk6IFVJbnQ2NCkgLT4gU3RyaW5nOgogICAgcHJvdG8gMSAxCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MwogICAgLy8gaWYgaSA8IHJhZGl4OgogICAgZnJhbWVfZGlnIC0xCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MgogICAgLy8gcmFkaXggPSBkaWdpdHMubGVuZ3RoCiAgICBpbnQgMTAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUzCiAgICAvLyBpZiBpIDwgcmFkaXg6CiAgICA8CiAgICBieiBpdG9hX2FmdGVyX2lmX2Vsc2VAMgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTQKICAgIC8vIHJldHVybiBTdHJpbmcuZnJvbV9ieXRlcyhkaWdpdHNbaV0pCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAxCiAgICArCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MQogICAgLy8gZGlnaXRzID0gQnl0ZXMoYiIwMTIzNDU2Nzg5IikKICAgIGJ5dGUgMHgzMDMxMzIzMzM0MzUzNjM3MzgzOQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTQKICAgIC8vIHJldHVybiBTdHJpbmcuZnJvbV9ieXRlcyhkaWdpdHNbaV0pCiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgcmV0c3ViCgppdG9hX2FmdGVyX2lmX2Vsc2VAMjoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjU1CiAgICAvLyByZXR1cm4gaXRvYShpIC8vIHJhZGl4KSArIFN0cmluZy5mcm9tX2J5dGVzKGRpZ2l0c1tpICUgcmFkaXhdKQogICAgZnJhbWVfZGlnIC0xCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MgogICAgLy8gcmFkaXggPSBkaWdpdHMubGVuZ3RoCiAgICBpbnQgMTAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjU1CiAgICAvLyByZXR1cm4gaXRvYShpIC8vIHJhZGl4KSArIFN0cmluZy5mcm9tX2J5dGVzKGRpZ2l0c1tpICUgcmFkaXhdKQogICAgLwogICAgY2FsbHN1YiBpdG9hCiAgICBmcmFtZV9kaWcgLTEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjUyCiAgICAvLyByYWRpeCA9IGRpZ2l0cy5sZW5ndGgKICAgIGludCAxMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTUKICAgIC8vIHJldHVybiBpdG9hKGkgLy8gcmFkaXgpICsgU3RyaW5nLmZyb21fYnl0ZXMoZGlnaXRzW2kgJSByYWRpeF0pCiAgICAlCiAgICBkdXAKICAgIGludCAxCiAgICArCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjI1MQogICAgLy8gZGlnaXRzID0gQnl0ZXMoYiIwMTIzNDU2Nzg5IikKICAgIGJ5dGUgMHgzMDMxMzIzMzM0MzUzNjM3MzgzOQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNTUKICAgIC8vIHJldHVybiBpdG9hKGkgLy8gcmFkaXgpICsgU3RyaW5nLmZyb21fYnl0ZXMoZGlnaXRzW2kgJSByYWRpeF0pCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICBjb25jYXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuZ2V0X3ZvdGVfZnJvbV9ib3goaW5kZXg6IHVpbnQ2NCkgLT4gdWludDY0OgpnZXRfdm90ZV9mcm9tX2JveDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjM5LTI0MAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBnZXRfdm90ZV9mcm9tX2JveChzZWxmLCBpbmRleDogVUludDY0KSAtPiBVSW50NjQ6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQxCiAgICAvLyByZXR1cm4gb3AuYnRvaShzZWxmLnRhbGx5X2JveC5leHRyYWN0KGluZGV4LCBWT1RFX0NPVU5UX0JZVEVTKSkKICAgIGJ5dGUgIlYiCiAgICBmcmFtZV9kaWcgLTEKICAgIGludCA4CiAgICBib3hfZXh0cmFjdAogICAgYnRvaQogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5nZXRfcHJlY29uZGl0aW9ucyhzaWduYXR1cmU6IGJ5dGVzKSAtPiBieXRlczoKZ2V0X3ByZWNvbmRpdGlvbnM6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE2MC0xNjEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlKQogICAgLy8gZGVmIGdldF9wcmVjb25kaXRpb25zKHNlbGYsIHNpZ25hdHVyZTogQnl0ZXMpIC0+IFZvdGluZ1ByZWNvbmRpdGlvbnM6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTYzCiAgICAvLyBpc192b3Rpbmdfb3Blbj1hcmM0LlVJbnQ2NChzZWxmLnZvdGluZ19vcGVuKCkpLAogICAgY2FsbHN1YiB2b3Rpbmdfb3BlbgogICAgaXRvYgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjQKICAgIC8vIGlzX2FsbG93ZWRfdG9fdm90ZT1hcmM0LlVJbnQ2NChzZWxmLmFsbG93ZWRfdG9fdm90ZShzaWduYXR1cmUpKSwKICAgIGZyYW1lX2RpZyAtMQogICAgY2FsbHN1YiBhbGxvd2VkX3RvX3ZvdGUKICAgIGl0b2IKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTY1CiAgICAvLyBoYXNfYWxyZWFkeV92b3RlZD1hcmM0LlVJbnQ2NChzZWxmLmFscmVhZHlfdm90ZWQoKSksCiAgICBjYWxsc3ViIGFscmVhZHlfdm90ZWQKICAgIGl0b2IKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTY2CiAgICAvLyBjdXJyZW50X3RpbWU9YXJjNC5VSW50NjQoR2xvYmFsLmxhdGVzdF90aW1lc3RhbXApLAogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgaXRvYgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxNjItMTY3CiAgICAvLyByZXR1cm4gVm90aW5nUHJlY29uZGl0aW9ucygKICAgIC8vICAgICBpc192b3Rpbmdfb3Blbj1hcmM0LlVJbnQ2NChzZWxmLnZvdGluZ19vcGVuKCkpLAogICAgLy8gICAgIGlzX2FsbG93ZWRfdG9fdm90ZT1hcmM0LlVJbnQ2NChzZWxmLmFsbG93ZWRfdG9fdm90ZShzaWduYXR1cmUpKSwKICAgIC8vICAgICBoYXNfYWxyZWFkeV92b3RlZD1hcmM0LlVJbnQ2NChzZWxmLmFscmVhZHlfdm90ZWQoKSksCiAgICAvLyAgICAgY3VycmVudF90aW1lPWFyYzQuVUludDY0KEdsb2JhbC5sYXRlc3RfdGltZXN0YW1wKSwKICAgIC8vICkKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAzCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAudm90aW5nX29wZW4oKSAtPiB1aW50NjQ6CnZvdGluZ19vcGVuOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMDUtMjA2CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHZvdGluZ19vcGVuKHNlbGYpIC0+IGJvb2w6CiAgICBwcm90byAwIDEKICAgIGJ5dGUgIiIKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA4CiAgICAvLyBzZWxmLmlzX2Jvb3RzdHJhcHBlZAogICAgaW50IDAKICAgIGJ5dGUgImlzX2Jvb3RzdHJhcHBlZCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5pc19ib290c3RyYXBwZWQgZXhpc3RzCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwOC0yMTAKICAgIC8vIHNlbGYuaXNfYm9vdHN0cmFwcGVkCiAgICAvLyBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgLy8gYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICBieiB2b3Rpbmdfb3Blbl9ib29sX2ZhbHNlQDUKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjA5CiAgICAvLyBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgaW50IDAKICAgIGJ5dGUgImNsb3NlX3RpbWUiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYnVyeSAxCiAgICBibnogdm90aW5nX29wZW5fYm9vbF9mYWxzZUA1CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIxMAogICAgLy8gYW5kIHNlbGYuc3RhcnRfdGltZSA8PSBHbG9iYWwubGF0ZXN0X3RpbWVzdGFtcCA8PSBzZWxmLmVuZF90aW1lCiAgICBpbnQgMAogICAgYnl0ZSAic3RhcnRfdGltZSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5zdGFydF90aW1lIGV4aXN0cwogICAgZ2xvYmFsIExhdGVzdFRpbWVzdGFtcAogICAgZHVwCiAgICBmcmFtZV9idXJ5IDAKICAgIDw9CiAgICBieiB2b3Rpbmdfb3Blbl9ib29sX2ZhbHNlQDUKICAgIGludCAwCiAgICBieXRlICJlbmRfdGltZSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5lbmRfdGltZSBleGlzdHMKICAgIGZyYW1lX2RpZyAwCiAgICA+PQogICAgYnogdm90aW5nX29wZW5fYm9vbF9mYWxzZUA1CiAgICBpbnQgMQogICAgYiB2b3Rpbmdfb3Blbl9ib29sX21lcmdlQDYKCnZvdGluZ19vcGVuX2Jvb2xfZmFsc2VANToKICAgIGludCAwCgp2b3Rpbmdfb3Blbl9ib29sX21lcmdlQDY6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwNy0yMTEKICAgIC8vIHJldHVybiAoCiAgICAvLyAgICAgc2VsZi5pc19ib290c3RyYXBwZWQKICAgIC8vICAgICBhbmQgbm90IHNlbGYuY2xvc2VfdGltZQogICAgLy8gICAgIGFuZCBzZWxmLnN0YXJ0X3RpbWUgPD0gR2xvYmFsLmxhdGVzdF90aW1lc3RhbXAgPD0gc2VsZi5lbmRfdGltZQogICAgLy8gKQogICAgc3dhcAogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5hbGxvd2VkX3RvX3ZvdGUoc2lnbmF0dXJlOiBieXRlcykgLT4gdWludDY0OgphbGxvd2VkX3RvX3ZvdGU6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzMC0yMzEKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgYWxsb3dlZF90b192b3RlKHNlbGYsIHNpZ25hdHVyZTogQnl0ZXMpIC0+IGJvb2w6CiAgICBwcm90byAxIDEKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjMyCiAgICAvLyBlbnN1cmVfYnVkZ2V0KDIwMDApCiAgICBpbnQgMjAwMAogICAgaW50IDAKICAgIGNhbGxzdWIgZW5zdXJlX2J1ZGdldAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMzQKICAgIC8vIFR4bi5zZW5kZXIuYnl0ZXMsCiAgICB0eG4gU2VuZGVyCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIzNgogICAgLy8gc2VsZi5zbmFwc2hvdF9wdWJsaWNfa2V5LAogICAgaW50IDAKICAgIGJ5dGUgInNuYXBzaG90X3B1YmxpY19rZXkiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuc25hcHNob3RfcHVibGljX2tleSBleGlzdHMKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjMzLTIzNwogICAgLy8gcmV0dXJuIG9wLmVkMjU1MTl2ZXJpZnlfYmFyZSgKICAgIC8vICAgICBUeG4uc2VuZGVyLmJ5dGVzLAogICAgLy8gICAgIHNpZ25hdHVyZSwKICAgIC8vICAgICBzZWxmLnNuYXBzaG90X3B1YmxpY19rZXksCiAgICAvLyApCiAgICBmcmFtZV9kaWcgLTEKICAgIHN3YXAKICAgIGVkMjU1MTl2ZXJpZnlfYmFyZQogICAgcmV0c3ViCgoKLy8gZXhhbXBsZXMudm90aW5nLnZvdGluZy5Wb3RpbmdSb3VuZEFwcC5hbHJlYWR5X3ZvdGVkKCkgLT4gdWludDY0OgphbHJlYWR5X3ZvdGVkOgogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTMtMjE0CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGFscmVhZHlfdm90ZWQoc2VsZikgLT4gYm9vbDoKICAgIHByb3RvIDAgMQogICAgLy8gdm90aW5nL3ZvdGluZy5weToyMTUKICAgIC8vIHJldHVybiBUeG4uc2VuZGVyIGluIHNlbGYudm90ZXNfYnlfYWNjb3VudAogICAgdHhuIFNlbmRlcgogICAgYm94X2xlbgogICAgYnVyeSAxCiAgICByZXRzdWIKCgovLyBleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLnZvdGUoZnVuZF9taW5fYmFsX3JlcTogdWludDY0LCBzaWduYXR1cmU6IGJ5dGVzLCBhbnN3ZXJfaWRzOiBieXRlcykgLT4gdm9pZDoKdm90ZToKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTY5LTE3NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgdm90ZSgKICAgIC8vICAgICBzZWxmLAogICAgLy8gICAgIGZ1bmRfbWluX2JhbF9yZXE6IGd0eG4uUGF5bWVudFRyYW5zYWN0aW9uLAogICAgLy8gICAgIHNpZ25hdHVyZTogQnl0ZXMsCiAgICAvLyAgICAgYW5zd2VyX2lkczogVm90ZUluZGV4QXJyYXksCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byAzIDAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTc2CiAgICAvLyBlbnN1cmVfYnVkZ2V0KDc3MDAsIGZlZV9zb3VyY2U9T3BVcEZlZVNvdXJjZS5Hcm91cENyZWRpdCkKICAgIGludCA3NzAwCiAgICBpbnQgMAogICAgY2FsbHN1YiBlbnN1cmVfYnVkZ2V0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE3Ny0xNzgKICAgIC8vICMgQ2hlY2sgdm90aW5nIHByZWNvbmRpdGlvbnMKICAgIC8vIGFzc2VydCBzZWxmLmFsbG93ZWRfdG9fdm90ZShzaWduYXR1cmUpLCAiTm90IGFsbG93ZWQgdG8gdm90ZSIKICAgIGZyYW1lX2RpZyAtMgogICAgY2FsbHN1YiBhbGxvd2VkX3RvX3ZvdGUKICAgIGFzc2VydCAvLyBOb3QgYWxsb3dlZCB0byB2b3RlCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE3OQogICAgLy8gYXNzZXJ0IHNlbGYudm90aW5nX29wZW4oKSwgIlZvdGluZyBub3Qgb3BlbiIKICAgIGNhbGxzdWIgdm90aW5nX29wZW4KICAgIGFzc2VydCAvLyBWb3Rpbmcgbm90IG9wZW4KICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgwCiAgICAvLyBhc3NlcnQgbm90IHNlbGYuYWxyZWFkeV92b3RlZCgpLCAiQWxyZWFkeSB2b3RlZCIKICAgIGNhbGxzdWIgYWxyZWFkeV92b3RlZAogICAgIQogICAgYXNzZXJ0IC8vIEFscmVhZHkgdm90ZWQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgxCiAgICAvLyBxdWVzdGlvbnNfY291bnQgPSBzZWxmLm9wdGlvbl9jb3VudHMubGVuZ3RoCiAgICBpbnQgMAogICAgYnl0ZSAib3B0aW9uX2NvdW50cyIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5vcHRpb25fY291bnRzIGV4aXN0cwogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBkdXAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTgyCiAgICAvLyBhc3NlcnQgYW5zd2VyX2lkcy5sZW5ndGggPT0gcXVlc3Rpb25zX2NvdW50LCAiTnVtYmVyIG9mIGFuc3dlcnMgaW5jb3JyZWN0IgogICAgZnJhbWVfZGlnIC0xCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGR1cAogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIE51bWJlciBvZiBhbnN3ZXJzIGluY29ycmVjdAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODUKICAgIC8vICgzMiArIDIgKyBWT1RFX0lOREVYX0JZVEVTICogYW5zd2VyX2lkcy5sZW5ndGgpICogQk9YX0JZVEVfTUlOX0JBTEFOQ0UKICAgIGludCAzNAogICAgKwogICAgaW50IDQwMAogICAgKgogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODMtMTg0CiAgICAvLyAjIENoZWNrIHZvdGVyIGJveCBpcyBmdW5kZWQKICAgIC8vIG1pbl9iYWxfcmVxID0gQk9YX0ZMQVRfTUlOX0JBTEFOQ0UgKyAoCiAgICBpbnQgMjUwMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODMtMTg2CiAgICAvLyAjIENoZWNrIHZvdGVyIGJveCBpcyBmdW5kZWQKICAgIC8vIG1pbl9iYWxfcmVxID0gQk9YX0ZMQVRfTUlOX0JBTEFOQ0UgKyAoCiAgICAvLyAgICAgKDMyICsgMiArIFZPVEVfSU5ERVhfQllURVMgKiBhbnN3ZXJfaWRzLmxlbmd0aCkgKiBCT1hfQllURV9NSU5fQkFMQU5DRQogICAgLy8gKQogICAgKwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxODgKICAgIC8vIGZ1bmRfbWluX2JhbF9yZXEucmVjZWl2ZXIgPT0gR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcwogICAgZnJhbWVfZGlnIC0zCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE4Ny0xODkKICAgIC8vIGFzc2VydCAoCiAgICAvLyAgICAgZnVuZF9taW5fYmFsX3JlcS5yZWNlaXZlciA9PSBHbG9iYWwuY3VycmVudF9hcHBsaWNhdGlvbl9hZGRyZXNzCiAgICAvLyApLCAiUGF5bWVudCBtdXN0IGJlIHRvIGFwcCBhZGRyZXNzIgogICAgYXNzZXJ0IC8vIFBheW1lbnQgbXVzdCBiZSB0byBhcHAgYWRkcmVzcwogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTEKICAgIC8vIGxvZyhtaW5fYmFsX3JlcSkKICAgIGR1cAogICAgaXRvYgogICAgbG9nCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5MgogICAgLy8gYXNzZXJ0IGZ1bmRfbWluX2JhbF9yZXEuYW1vdW50ID09IG1pbl9iYWxfcmVxLCAiUGF5bWVudCBtdXN0IGJlIHRoZSBleGFjdCBtaW4gYmFsYW5jZSIKICAgIGZyYW1lX2RpZyAtMwogICAgZ3R4bnMgQW1vdW50CiAgICA9PQogICAgYXNzZXJ0IC8vIFBheW1lbnQgbXVzdCBiZSB0aGUgZXhhY3QgbWluIGJhbGFuY2UKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTkzLTE5NAogICAgLy8gIyBSZWNvcmQgdGhlIHZvdGUgZm9yIGVhY2ggcXVlc3Rpb24KICAgIC8vIGN1bXVsYXRpdmVfb2Zmc2V0ID0gVUludDY0KDApCiAgICBpbnQgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToxOTUKICAgIC8vIGZvciBxdWVzdGlvbl9pbmRleCBpbiB1cmFuZ2UocXVlc3Rpb25zX2NvdW50KToKICAgIGR1cAoKdm90ZV9mb3JfaGVhZGVyQDE6CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5NQogICAgLy8gZm9yIHF1ZXN0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbnNfY291bnQpOgogICAgZnJhbWVfZGlnIDIKICAgIGZyYW1lX2RpZyAwCiAgICA8CiAgICBieiB2b3RlX2FmdGVyX2ZvckA0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5Ni0xOTcKICAgIC8vICMgTG9hZCB0aGUgdXNlcidzIHZvdGUgZm9yIHRoaXMgcXVlc3Rpb24KICAgIC8vIGFuc3dlcl9vcHRpb25faW5kZXggPSBhbnN3ZXJfaWRzW3F1ZXN0aW9uX2luZGV4XS5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMQogICAgZXh0cmFjdCAyIDAKICAgIGZyYW1lX2RpZyAyCiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGludCAxCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ0b2kKICAgIHN3YXAKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTk4CiAgICAvLyBvcHRpb25zX2NvdW50ID0gc2VsZi5vcHRpb25fY291bnRzW3F1ZXN0aW9uX2luZGV4XS5uYXRpdmUKICAgIGludCAwCiAgICBieXRlICJvcHRpb25fY291bnRzIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLm9wdGlvbl9jb3VudHMgZXhpc3RzCiAgICBleHRyYWN0IDIgMAogICAgZGlnIDEKICAgIGludCAxCiAgICBleHRyYWN0MyAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ0b2kKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MTk5CiAgICAvLyBhc3NlcnQgYW5zd2VyX29wdGlvbl9pbmRleCA8IG9wdGlvbnNfY291bnQsICJBbnN3ZXIgb3B0aW9uIGluZGV4IGludmFsaWQiCiAgICBkaWcgMgogICAgZGlnIDEKICAgIDwKICAgIGFzc2VydCAvLyBBbnN3ZXIgb3B0aW9uIGluZGV4IGludmFsaWQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjAwCiAgICAvLyBzZWxmLmluY3JlbWVudF92b3RlX2luX2JveChjdW11bGF0aXZlX29mZnNldCArIGFuc3dlcl9vcHRpb25faW5kZXgpCiAgICBmcmFtZV9kaWcgMQogICAgZHVwCiAgICB1bmNvdmVyIDQKICAgICsKICAgIGNhbGxzdWIgaW5jcmVtZW50X3ZvdGVfaW5fYm94CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMQogICAgLy8gY3VtdWxhdGl2ZV9vZmZzZXQgKz0gb3B0aW9uc19jb3VudAogICAgKwogICAgZnJhbWVfYnVyeSAxCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjIwMgogICAgLy8gc2VsZi52b3Rlc19ieV9hY2NvdW50W1R4bi5zZW5kZXJdID0gYW5zd2VyX2lkcy5jb3B5KCkKICAgIHR4biBTZW5kZXIKICAgIGR1cAogICAgYm94X2RlbAogICAgcG9wCiAgICBmcmFtZV9kaWcgLTEKICAgIGJveF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjAzCiAgICAvLyBzZWxmLnZvdGVyX2NvdW50ICs9IDEKICAgIGludCAwCiAgICBieXRlICJ2b3Rlcl9jb3VudCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi52b3Rlcl9jb3VudCBleGlzdHMKICAgIGludCAxCiAgICArCiAgICBieXRlICJ2b3Rlcl9jb3VudCIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjE5NQogICAgLy8gZm9yIHF1ZXN0aW9uX2luZGV4IGluIHVyYW5nZShxdWVzdGlvbnNfY291bnQpOgogICAgaW50IDEKICAgICsKICAgIGZyYW1lX2J1cnkgMgogICAgYiB2b3RlX2Zvcl9oZWFkZXJAMQoKdm90ZV9hZnRlcl9mb3JANDoKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuaW5jcmVtZW50X3ZvdGVfaW5fYm94KGluZGV4OiB1aW50NjQpIC0+IHZvaWQ6CmluY3JlbWVudF92b3RlX2luX2JveDoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQzLTI0NAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBpbmNyZW1lbnRfdm90ZV9pbl9ib3goc2VsZiwgaW5kZXg6IFVJbnQ2NCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gdm90aW5nL3ZvdGluZy5weToyNDUKICAgIC8vIGN1cnJlbnRfdm90ZSA9IHNlbGYuZ2V0X3ZvdGVfZnJvbV9ib3goaW5kZXgpCiAgICBmcmFtZV9kaWcgLTEKICAgIGNhbGxzdWIgZ2V0X3ZvdGVfZnJvbV9ib3gKICAgIC8vIHZvdGluZy92b3RpbmcucHk6MjQ2CiAgICAvLyBzZWxmLnRhbGx5X2JveC5yZXBsYWNlKGluZGV4LCBvcC5pdG9iKGN1cnJlbnRfdm90ZSArIDEpKQogICAgaW50IDEKICAgICsKICAgIGl0b2IKICAgIGJ5dGUgIlYiCiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMgogICAgYm94X3JlcGxhY2UKICAgIHJldHN1YgoKCi8vIGV4YW1wbGVzLnZvdGluZy52b3RpbmcuVm90aW5nUm91bmRBcHAuX19pbml0X18oKSAtPiB2b2lkOgpfX2luaXRfXzoKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTAKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB2b3Rpbmcvdm90aW5nLnB5OjUxCiAgICAvLyBzZWxmLmlzX2Jvb3RzdHJhcHBlZCA9IEZhbHNlCiAgICBieXRlICJpc19ib290c3RyYXBwZWQiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHZvdGluZy92b3RpbmcucHk6NTItNTMKICAgIC8vICMgVGhlIG1pbmltdW0gbnVtYmVyIG9mIHZvdGVycyB3aG8gaGF2ZSB2b3RlZAogICAgLy8gc2VsZi52b3Rlcl9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAidm90ZXJfY291bnQiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIF9wdXlhX2xpYi51dGlsLmVuc3VyZV9idWRnZXQocmVxdWlyZWRfYnVkZ2V0OiB1aW50NjQsIGZlZV9zb3VyY2U6IHVpbnQ2NCkgLT4gdm9pZDoKZW5zdXJlX2J1ZGdldDoKICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjEyLTEzCiAgICBwcm90byAyIDAKICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjE0LTE5CiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAxMAogICAgKwoKZW5zdXJlX2J1ZGdldF93aGlsZV90b3BAMToKICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjIwCiAgICBmcmFtZV9kaWcgMAogICAgZ2xvYmFsIE9wY29kZUJ1ZGdldAogICAgPgogICAgYnogZW5zdXJlX2J1ZGdldF9hZnRlcl93aGlsZUA3CiAgICAvLyBfcHV5YV9saWIvdXRpbC5weToyMQogICAgaXR4bl9iZWdpbgogICAgLy8gX3B1eWFfbGliL3V0aWwucHk6MjIKICAgIGludCBhcHBsCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICAvLyBfcHV5YV9saWIvdXRpbC5weToyMwogICAgaW50IERlbGV0ZUFwcGxpY2F0aW9uCiAgICBpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgogICAgLy8gX3B1eWFfbGliL3V0aWwucHk6MjQKICAgIGJ5dGUgMHgwNjgxMDEKICAgIGl0eG5fZmllbGQgQXBwcm92YWxQcm9ncmFtCiAgICAvLyBfcHV5YV9saWIvdXRpbC5weToyNQogICAgYnl0ZSAweDA2ODEwMQogICAgaXR4bl9maWVsZCBDbGVhclN0YXRlUHJvZ3JhbQogICAgLy8gX3B1eWFfbGliL3V0aWwucHk6MjYtMzAKICAgIGZyYW1lX2RpZyAtMQogICAgc3dpdGNoIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMEAzIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMUA0CiAgICBiIGVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfbmV4dEA2CgplbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlXzBAMzoKICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjI4CiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIGIgZW5zdXJlX2J1ZGdldF9zd2l0Y2hfY2FzZV9uZXh0QDYKCmVuc3VyZV9idWRnZXRfc3dpdGNoX2Nhc2VfMUA0OgogICAgLy8gX3B1eWFfbGliL3V0aWwucHk6MzAKICAgIGdsb2JhbCBNaW5UeG5GZWUKICAgIGl0eG5fZmllbGQgRmVlCgplbnN1cmVfYnVkZ2V0X3N3aXRjaF9jYXNlX25leHRANjoKICAgIC8vIF9wdXlhX2xpYi91dGlsLnB5OjMxLTMzCiAgICBpdHhuX3N1Ym1pdAogICAgYiBlbnN1cmVfYnVkZ2V0X3doaWxlX3RvcEAxCgplbnN1cmVfYnVkZ2V0X2FmdGVyX3doaWxlQDc6CiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgpleGFtcGxlcy52b3Rpbmcudm90aW5nLlZvdGluZ1JvdW5kQXBwLmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICBpbnQgMQogICAgcmV0dXJuCg==" }, "state": { diff --git a/examples/voting/out_unoptimized/VotingRoundApp.approval.teal b/examples/voting/out_unoptimized/VotingRoundApp.approval.teal index 7eccb41a6b..6441d8f048 100644 --- a/examples/voting/out_unoptimized/VotingRoundApp.approval.teal +++ b/examples/voting/out_unoptimized/VotingRoundApp.approval.teal @@ -347,20 +347,14 @@ bootstrap: // voting/voting.py:84 // assert not self.is_bootstrapped, "Must not be already bootstrapped" int 0 - // voting/voting.py:51 - // self.is_bootstrapped = False byte "is_bootstrapped" - // voting/voting.py:84 - // assert not self.is_bootstrapped, "Must not be already bootstrapped" app_global_get_ex assert // check self.is_bootstrapped exists ! assert // Must not be already bootstrapped - // voting/voting.py:51 - // self.is_bootstrapped = False - byte "is_bootstrapped" // voting/voting.py:85 // self.is_bootstrapped = True + byte "is_bootstrapped" int 1 app_global_put // voting/voting.py:88 @@ -377,11 +371,7 @@ bootstrap: // voting/voting.py:91 // tally_box_size = self.total_options * VOTE_COUNT_BYTES int 0 - // voting/voting.py:228 - // self.total_options = total_options byte "total_options" - // voting/voting.py:91 - // tally_box_size = self.total_options * VOTE_COUNT_BYTES app_global_get_ex assert // check self.total_options exists int 8 @@ -444,11 +434,9 @@ bootstrap: // fund_min_bal_req.amount == min_balance_req // ), "Payment must be for the exact min balance requirement" assert // Payment must be for the exact min balance requirement - // voting/voting.py:55 - // self.tally_box = BoxRef(key="V") - byte "V" // voting/voting.py:108 // assert self.tally_box.create(size=tally_box_size) + byte "V" uncover 1 box_create assert @@ -473,11 +461,7 @@ close: // voting/voting.py:113 // assert not self.close_time, "Already closed" int 0 - // voting/voting.py:54 - // self.close_time = GlobalState(UInt64) byte "close_time" - // voting/voting.py:113 - // assert not self.close_time, "Already closed" app_global_get_ex cover 1 pop @@ -486,21 +470,13 @@ close: // voting/voting.py:114 // self.close_time.value = Global.latest_timestamp global LatestTimestamp - // voting/voting.py:54 - // self.close_time = GlobalState(UInt64) byte "close_time" - // voting/voting.py:114 - // self.close_time.value = Global.latest_timestamp uncover 1 app_global_put // voting/voting.py:119 // + self.vote_id int 0 - // voting/voting.py:73 - // self.vote_id = vote_id byte "vote_id" - // voting/voting.py:119 - // + self.vote_id app_global_get_ex assert // check self.vote_id exists // voting/voting.py:117-118 @@ -525,11 +501,7 @@ close: // voting/voting.py:121 // + self.metadata_ipfs_cid int 0 - // voting/voting.py:75 - // self.metadata_ipfs_cid = metadata_ipfs_cid byte "metadata_ipfs_cid" - // voting/voting.py:121 - // + self.metadata_ipfs_cid app_global_get_ex assert // check self.metadata_ipfs_cid exists // voting/voting.py:117-121 @@ -553,11 +525,7 @@ close: // voting/voting.py:123 // + self.vote_id int 0 - // voting/voting.py:73 - // self.vote_id = vote_id byte "vote_id" - // voting/voting.py:123 - // + self.vote_id app_global_get_ex assert // check self.vote_id exists // voting/voting.py:117-123 @@ -585,11 +553,7 @@ close: // voting/voting.py:125 // + itoa(self.quorum) int 0 - // voting/voting.py:78 - // self.quorum = quorum byte "quorum" - // voting/voting.py:125 - // + itoa(self.quorum) app_global_get_ex assert // check self.quorum exists callsub itoa @@ -622,12 +586,7 @@ close: // voting/voting.py:127 // + itoa(self.voter_count) int 0 - // voting/voting.py:52-53 - // # The minimum number of voters who have voted - // self.voter_count = UInt64(0) byte "voter_count" - // voting/voting.py:127 - // + itoa(self.voter_count) app_global_get_ex assert // check self.voter_count exists callsub itoa @@ -667,11 +626,7 @@ close: // voting/voting.py:132 // for question_index, question_options in uenumerate(self.option_counts): int 0 - // voting/voting.py:227 - // self.option_counts = option_counts.copy() byte "option_counts" - // voting/voting.py:132 - // for question_index, question_options in uenumerate(self.option_counts): app_global_get_ex cover 1 dup @@ -838,11 +793,7 @@ close_after_for@14: // voting/voting.py:150 // asset_name="[VOTE RESULT] " + self.vote_id, int 0 - // voting/voting.py:73 - // self.vote_id = vote_id byte "vote_id" - // voting/voting.py:150 - // asset_name="[VOTE RESULT] " + self.vote_id, app_global_get_ex assert // check self.vote_id exists byte "[VOTE RESULT] " @@ -851,11 +802,7 @@ close_after_for@14: // voting/voting.py:152 // url=self.nft_image_url, int 0 - // voting/voting.py:79 - // self.nft_image_url = nft_image_url byte "nft_image_url" - // voting/voting.py:152 - // url=self.nft_image_url, app_global_get_ex assert // check self.nft_image_url exists // voting/voting.py:144 @@ -1006,11 +953,9 @@ get_vote_from_box: // @subroutine // def get_vote_from_box(self, index: UInt64) -> UInt64: proto 1 1 - // voting/voting.py:55 - // self.tally_box = BoxRef(key="V") - byte "V" // voting/voting.py:241 // return op.btoi(self.tally_box.extract(index, VOTE_COUNT_BYTES)) + byte "V" frame_dig -1 int 8 box_extract @@ -1070,11 +1015,7 @@ voting_open: // voting/voting.py:208 // self.is_bootstrapped int 0 - // voting/voting.py:51 - // self.is_bootstrapped = False byte "is_bootstrapped" - // voting/voting.py:208 - // self.is_bootstrapped app_global_get_ex assert // check self.is_bootstrapped exists // voting/voting.py:208-210 @@ -1085,11 +1026,7 @@ voting_open: // voting/voting.py:209 // and not self.close_time int 0 - // voting/voting.py:54 - // self.close_time = GlobalState(UInt64) byte "close_time" - // voting/voting.py:209 - // and not self.close_time app_global_get_ex cover 1 pop @@ -1097,11 +1034,7 @@ voting_open: // voting/voting.py:210 // and self.start_time <= Global.latest_timestamp <= self.end_time int 0 - // voting/voting.py:76 - // self.start_time = start_time byte "start_time" - // voting/voting.py:210 - // and self.start_time <= Global.latest_timestamp <= self.end_time app_global_get_ex assert // check self.start_time exists global LatestTimestamp @@ -1110,11 +1043,7 @@ voting_open: <= bz voting_open_bool_false@5 int 0 - // voting/voting.py:77 - // self.end_time = end_time byte "end_time" - // voting/voting.py:210 - // and self.start_time <= Global.latest_timestamp <= self.end_time app_global_get_ex assert // check self.end_time exists frame_dig 0 @@ -1155,11 +1084,7 @@ allowed_to_vote: // voting/voting.py:236 // self.snapshot_public_key, int 0 - // voting/voting.py:74 - // self.snapshot_public_key = snapshot_public_key byte "snapshot_public_key" - // voting/voting.py:236 - // self.snapshot_public_key, app_global_get_ex assert // check self.snapshot_public_key exists // voting/voting.py:233-237 @@ -1184,177 +1109,12 @@ already_voted: // voting/voting.py:215 // return Txn.sender in self.votes_by_account txn Sender - // voting/voting.py:56 - // self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") byte "" - // voting/voting.py:56-215 - // self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") - // - // @arc4.abimethod(create="require") - // def create( - // self, - // vote_id: String, - // snapshot_public_key: Bytes, - // metadata_ipfs_cid: String, - // start_time: UInt64, - // end_time: UInt64, - // option_counts: VoteIndexArray, - // quorum: UInt64, - // nft_image_url: String, - // ) -> None: - // assert start_time < end_time, "End time should be after start time" - // assert end_time >= Global.latest_timestamp, "End time should be in the future" - // - // self.vote_id = vote_id - // self.snapshot_public_key = snapshot_public_key - // self.metadata_ipfs_cid = metadata_ipfs_cid - // self.start_time = start_time - // self.end_time = end_time - // self.quorum = quorum - // self.nft_image_url = nft_image_url - // self.store_option_counts(option_counts.copy()) - // - // @arc4.abimethod - // def bootstrap(self, fund_min_bal_req: gtxn.PaymentTransaction) -> None: - // assert not self.is_bootstrapped, "Must not be already bootstrapped" - // self.is_bootstrapped = True - // - // assert ( - // fund_min_bal_req.receiver == Global.current_application_address - // ), "Payment must be to app address" - // - // tally_box_size = self.total_options * VOTE_COUNT_BYTES - // min_balance_req = ( - // # minimum balance req for: ALGOs + Vote result NFT asset - // ASSET_MIN_BALANCE * 2 - // # create NFT fee - // + 1000 - // # tally box - // + BOX_FLAT_MIN_BALANCE - // # tally box key "V" - // + BOX_BYTE_MIN_BALANCE - // # tally box value - // + (tally_box_size * BOX_BYTE_MIN_BALANCE) - // ) - // log(min_balance_req) - // assert ( - // fund_min_bal_req.amount == min_balance_req - // ), "Payment must be for the exact min balance requirement" - // assert self.tally_box.create(size=tally_box_size) - // - // @arc4.abimethod - // def close(self) -> None: - // ensure_budget(20000, fee_source=OpUpFeeSource.GroupCredit) - // assert not self.close_time, "Already closed" - // self.close_time.value = Global.latest_timestamp - // - // note = ( - // '{"standard":"arc69",' - // '"description":"This is a voting result NFT for voting round with ID ' - // + self.vote_id - // + '.","properties":{"metadata":"ipfs://' - // + self.metadata_ipfs_cid - // + '","id":"' - // + self.vote_id - // + '","quorum":' - // + itoa(self.quorum) - // + ',"voterCount":' - // + itoa(self.voter_count) - // + ',"tallies":[' - // ) - // - // current_index = UInt64(0) - // for question_index, question_options in uenumerate(self.option_counts): - // if question_index > 0: - // note += "," - // if question_options > 0: - // note += "[" - // for option_index in urange(question_options.native): - // if option_index > 0: - // note += "," - // votes_for_option = self.get_vote_from_box(current_index) - // note += itoa(votes_for_option) - // current_index += 1 - // note += "]" - // note += "]}}" - // self.nft_asset_id = ( - // itxn.AssetConfig( - // total=1, - // decimals=0, - // default_frozen=False, - // asset_name="[VOTE RESULT] " + self.vote_id, - // unit_name="VOTERSLT", - // url=self.nft_image_url, - // note=note, - // fee=Global.min_txn_fee, - // ) - // .submit() - // .created_asset.id - // ) - // - // @arc4.abimethod(readonly=True) - // def get_preconditions(self, signature: Bytes) -> VotingPreconditions: - // return VotingPreconditions( - // is_voting_open=arc4.UInt64(self.voting_open()), - // is_allowed_to_vote=arc4.UInt64(self.allowed_to_vote(signature)), - // has_already_voted=arc4.UInt64(self.already_voted()), - // current_time=arc4.UInt64(Global.latest_timestamp), - // ) - // - // @arc4.abimethod - // def vote( - // self, - // fund_min_bal_req: gtxn.PaymentTransaction, - // signature: Bytes, - // answer_ids: VoteIndexArray, - // ) -> None: - // ensure_budget(7700, fee_source=OpUpFeeSource.GroupCredit) - // # Check voting preconditions - // assert self.allowed_to_vote(signature), "Not allowed to vote" - // assert self.voting_open(), "Voting not open" - // assert not self.already_voted(), "Already voted" - // questions_count = self.option_counts.length - // assert answer_ids.length == questions_count, "Number of answers incorrect" - // # Check voter box is funded - // min_bal_req = BOX_FLAT_MIN_BALANCE + ( - // (32 + 2 + VOTE_INDEX_BYTES * answer_ids.length) * BOX_BYTE_MIN_BALANCE - // ) - // assert ( - // fund_min_bal_req.receiver == Global.current_application_address - // ), "Payment must be to app address" - // - // log(min_bal_req) - // assert fund_min_bal_req.amount == min_bal_req, "Payment must be the exact min balance" - // # Record the vote for each question - // cumulative_offset = UInt64(0) - // for question_index in urange(questions_count): - // # Load the user's vote for this question - // answer_option_index = answer_ids[question_index].native - // options_count = self.option_counts[question_index].native - // assert answer_option_index < options_count, "Answer option index invalid" - // self.increment_vote_in_box(cumulative_offset + answer_option_index) - // cumulative_offset += options_count - // self.votes_by_account[Txn.sender] = answer_ids.copy() - // self.voter_count += 1 - // - // @subroutine - // def voting_open(self) -> bool: - // return ( - // self.is_bootstrapped - // and not self.close_time - // and self.start_time <= Global.latest_timestamp <= self.end_time - // ) - // - // @subroutine - // def already_voted(self) -> bool: - // return Txn.sender in self.votes_by_account uncover 1 concat box_len cover 1 pop - // voting/voting.py:215 - // return Txn.sender in self.votes_by_account retsub @@ -1392,11 +1152,7 @@ vote: // voting/voting.py:181 // questions_count = self.option_counts.length int 0 - // voting/voting.py:227 - // self.option_counts = option_counts.copy() byte "option_counts" - // voting/voting.py:181 - // questions_count = self.option_counts.length app_global_get_ex assert // check self.option_counts exists int 0 @@ -1492,11 +1248,7 @@ vote_for_header@1: // voting/voting.py:198 // options_count = self.option_counts[question_index].native int 0 - // voting/voting.py:227 - // self.option_counts = option_counts.copy() byte "option_counts" - // voting/voting.py:198 - // options_count = self.option_counts[question_index].native app_global_get_ex assert // check self.option_counts exists extract 2 0 @@ -1528,11 +1280,7 @@ vote_for_header@1: // self.votes_by_account[Txn.sender] = answer_ids.copy() frame_dig -1 txn Sender - // voting/voting.py:56 - // self.votes_by_account = BoxMap(Account, VoteIndexArray, key_prefix="") byte "" - // voting/voting.py:202 - // self.votes_by_account[Txn.sender] = answer_ids.copy() uncover 1 concat dup @@ -1543,22 +1291,12 @@ vote_for_header@1: // voting/voting.py:203 // self.voter_count += 1 int 0 - // voting/voting.py:52-53 - // # The minimum number of voters who have voted - // self.voter_count = UInt64(0) byte "voter_count" - // voting/voting.py:203 - // self.voter_count += 1 app_global_get_ex assert // check self.voter_count exists int 1 + - // voting/voting.py:52-53 - // # The minimum number of voters who have voted - // self.voter_count = UInt64(0) byte "voter_count" - // voting/voting.py:203 - // self.voter_count += 1 uncover 1 app_global_put // voting/voting.py:195 @@ -1588,11 +1326,7 @@ increment_vote_in_box: int 1 + itob - // voting/voting.py:55 - // self.tally_box = BoxRef(key="V") byte "V" - // voting/voting.py:246 - // self.tally_box.replace(index, op.itob(current_vote + 1)) frame_dig -1 uncover 2 box_replace diff --git a/src/puyapy/awst_build/eb/contracts.py b/src/puyapy/awst_build/eb/contracts.py index 49d6a0a834..5d4bf94ee1 100644 --- a/src/puyapy/awst_build/eb/contracts.py +++ b/src/puyapy/awst_build/eb/contracts.py @@ -129,30 +129,23 @@ def bool_eval(self, location: SourceLocation, *, negate: bool = False) -> Instan def _builder_for_storage_access( storage_decl: AppStorageDeclaration, location: SourceLocation ) -> NodeBuilder: + key = attrs.evolve(storage_decl.key, source_location=location) match storage_decl.typ: case pytypes.PyType(generic=pytypes.GenericLocalStateType): - return LocalStateExpressionBuilder( - storage_decl.key, storage_decl.typ, storage_decl.member_name - ) + return LocalStateExpressionBuilder(key, storage_decl.typ, storage_decl.member_name) case pytypes.PyType(generic=pytypes.GenericGlobalStateType): - return GlobalStateExpressionBuilder( - storage_decl.key, storage_decl.typ, storage_decl.member_name - ) + return GlobalStateExpressionBuilder(key, storage_decl.typ, storage_decl.member_name) case pytypes.BoxRefType: - return BoxRefProxyExpressionBuilder(storage_decl.key, storage_decl.member_name) + return BoxRefProxyExpressionBuilder(key, storage_decl.member_name) case pytypes.PyType(generic=pytypes.GenericBoxType): - return BoxProxyExpressionBuilder( - storage_decl.key, storage_decl.typ, storage_decl.member_name - ) + return BoxProxyExpressionBuilder(key, storage_decl.typ, storage_decl.member_name) case pytypes.PyType(generic=pytypes.GenericBoxMapType): - return BoxMapProxyExpressionBuilder( - storage_decl.key, storage_decl.typ, storage_decl.member_name - ) + return BoxMapProxyExpressionBuilder(key, storage_decl.typ, storage_decl.member_name) case content_type: return builder_for_instance( content_type, AppStateExpression( - key=storage_decl.key, + key=key, wtype=content_type.wtype, exists_assertion_message=f"check self.{storage_decl.member_name} exists", source_location=location, diff --git a/src/puyapy/awst_build/eb/interface.py b/src/puyapy/awst_build/eb/interface.py index dd0549f85b..58d9de6c7f 100644 --- a/src/puyapy/awst_build/eb/interface.py +++ b/src/puyapy/awst_build/eb/interface.py @@ -61,7 +61,7 @@ class BuilderBinaryOp(enum.StrEnum): class NodeBuilder(abc.ABC): def __init__(self, location: SourceLocation): - self.source_location = location + self.source_location: typing.Final = location @property @abc.abstractmethod diff --git a/test_cases/abi_routing/out/Reference.approval.mir b/test_cases/abi_routing/out/Reference.approval.mir index b24af926db..776473241f 100644 --- a/test_cases/abi_routing/out/Reference.approval.mir +++ b/test_cases/abi_routing/out/Reference.approval.mir @@ -878,7 +878,7 @@ opt_into_asset_block@0: // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) asset#0 | tmp%2#0 # Only allow app creator to opt the app account into a ASA\nassert op.Txn.sender == op.Global.cre... abi_routing/contract.py:81-82 assert // Only creator can opt in to ASA // (𝕡) asset#0 | # Only allow app creator to opt the app account into a ASA\nassert op.Txn.sender == op.Global.cre... abi_routing/contract.py:81-82 int 0 // (𝕡) asset#0 | 0 ASA hasn't already been opted into\nassert not self.asa abi_routing/contract.py:83-84 - byte "asa" // (𝕡) asset#0 | 0,"asa" self.asa abi_routing/contract.py:24 + byte "asa" // (𝕡) asset#0 | 0,"asa" ASA hasn't already been opted into\nassert not self.asa abi_routing/contract.py:83-84 app_global_get_ex // (𝕡) asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 ASA hasn't already been opted into\nassert not self.asa abi_routing/contract.py:83-84 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) asset#0 | maybe_exists%0#0,{app_global_get_ex}.0 ASA hasn't already been opted into\nassert not self.asa abi_routing/contract.py:83-84 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%0#0,maybe_exists%0#0 ASA hasn't already been opted into\nassert not self.asa abi_routing/contract.py:83-84 @@ -889,7 +889,7 @@ opt_into_asset_block@0: // virtual: store tmp%3#0 to l-stack (no copy) (𝕡) asset#0 | tmp%3#0 y a ASA hasn't already been opted into\nassert not self.asa abi_routing/contract.py:83-84 // virtual: load tmp%3#0 from l-stack (no copy) (𝕡) asset#0 | tmp%3#0 # Verify a ASA hasn't already been opted into\nassert not self.asa, "ASA already opted in" abi_routing/contract.py:83-84 assert // ASA already opted in // (𝕡) asset#0 | # Verify a ASA hasn't already been opted into\nassert not self.asa, "ASA already opted in" abi_routing/contract.py:83-84 - byte "asa" // (𝕡) asset#0 | "asa" self.asa abi_routing/contract.py:24 + byte "asa" // (𝕡) asset#0 | "asa" # Save ASA ID in global state\nself.asa abi_routing/contract.py:85-86 frame_dig -1 // load asset#0 from parameters (𝕡) asset#0 | "asa",asset#0 # Save ASA ID in global state\nself.asa = asset abi_routing/contract.py:85-86 app_global_put // (𝕡) asset#0 | # Save ASA ID in global state\nself.asa = asset abi_routing/contract.py:85-86 itxn_begin // (𝕡) asset#0 | # Submit opt-in transaction: 0 asset transfer to self\nop.ITxnCreate.begin() abi_routing/contract.py:88-89 @@ -913,7 +913,7 @@ with_transactions: with_transactions_block@0: int 0 // (𝕡) asset#0,an_int#0,pay#0,another_int#0 | 0 self.asa abi_routing/contract.py:104 - byte "asa" // (𝕡) asset#0,an_int#0,pay#0,another_int#0 | 0,"asa" self.asa abi_routing/contract.py:24 + byte "asa" // (𝕡) asset#0,an_int#0,pay#0,another_int#0 | 0,"asa" self.asa abi_routing/contract.py:104 app_global_get_ex // (𝕡) asset#0,an_int#0,pay#0,another_int#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asa abi_routing/contract.py:104 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) asset#0,an_int#0,pay#0,another_int#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.asa abi_routing/contract.py:104 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) asset#0,an_int#0,pay#0,another_int#0 | maybe_value%0#0,maybe_exists%0#0 self.asa abi_routing/contract.py:104 diff --git a/test_cases/abi_routing/out/Reference.approval.teal b/test_cases/abi_routing/out/Reference.approval.teal index 3af86e070b..455229403f 100644 --- a/test_cases/abi_routing/out/Reference.approval.teal +++ b/test_cases/abi_routing/out/Reference.approval.teal @@ -635,22 +635,15 @@ opt_into_asset: // # Verify a ASA hasn't already been opted into // assert not self.asa, "ASA already opted in" int 0 - // abi_routing/contract.py:24 - // self.asa = Asset(123) byte "asa" - // abi_routing/contract.py:83-84 - // # Verify a ASA hasn't already been opted into - // assert not self.asa, "ASA already opted in" app_global_get_ex assert // check self.asa exists ! assert // ASA already opted in - // abi_routing/contract.py:24 - // self.asa = Asset(123) - byte "asa" // abi_routing/contract.py:85-86 // # Save ASA ID in global state // self.asa = asset + byte "asa" frame_dig -1 app_global_put // abi_routing/contract.py:88-89 @@ -694,11 +687,7 @@ with_transactions: // abi_routing/contract.py:104 // assert self.asa == asset, "is correct asset" int 0 - // abi_routing/contract.py:24 - // self.asa = Asset(123) byte "asa" - // abi_routing/contract.py:104 - // assert self.asa == asset, "is correct asset" app_global_get_ex assert // check self.asa exists frame_dig -4 diff --git a/test_cases/abi_routing/out/Reference.arc32.json b/test_cases/abi_routing/out/Reference.arc32.json index 17727dbec5..5f28a537ee 100644 --- a/test_cases/abi_routing/out/Reference.arc32.json +++ b/test_cases/abi_routing/out/Reference.arc32.json @@ -150,7 +150,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5hcHByb3ZhbF9wcm9ncmFtOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2VudHJ5cG9pbnRAMgogICAgY2FsbHN1YiBfX2luaXRfXwoKbWFpbl9lbnRyeXBvaW50QDI6CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTgKICAgIG1ldGhvZCAibm9vcF93aXRoX3VpbnQ2NCh1aW50NjQpdWludDgiCiAgICBtZXRob2QgImFsbF90aGVfdGhpbmdzKHVpbnQ2NCl1aW50OCIKICAgIG1ldGhvZCAibWl4ZWRfb2NhKHVpbnQ2NCl1aW50OCIKICAgIG1ldGhvZCAib3B0X2ludG9fYXNzZXQoYXNzZXQpdm9pZCIKICAgIG1ldGhvZCAid2l0aF90cmFuc2FjdGlvbnMoYXNzZXQsdWludDY0LHBheSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAiY29tcGFyZV9hc3NldHMoYXNzZXQsYXNzZXQpdm9pZCIKICAgIG1ldGhvZCAiZ2V0X2FkZHJlc3MoKWFkZHJlc3MiCiAgICBtZXRob2QgImdldF9hc3NldCgpdWludDY0IgogICAgbWV0aG9kICJnZXRfYXBwbGljYXRpb24oKXVpbnQ2NCIKICAgIG1ldGhvZCAiZ2V0X2FuX2ludCgpdWludDY0IgogICAgbWV0aG9kICJtZXRob2Rfd2l0aF9kZWZhdWx0X2FyZ3MoYXNzZXQsYXNzZXQsYWNjb3VudCxhY2NvdW50LGFwcGxpY2F0aW9uLGFwcGxpY2F0aW9uLGJ5dGVbM10sdWludDY0LHVpbnQ2NCl2b2lkIgogICAgbWV0aG9kICJtZXRob2Rfd2l0aF8xNV9hcmdzKHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAibWV0aG9kX3dpdGhfbW9yZV90aGFuXzE1X2FyZ3ModWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LGFzc2V0LHVpbnQ2NCx1aW50NjQscGF5LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LGJ5dGVbXSxieXRlW10sYXNzZXQscGF5LHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJoZWxsb193aXRoX2FsZ29weV9zdHJpbmcoc3RyaW5nKXN0cmluZyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX25vb3Bfd2l0aF91aW50NjRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hbGxfdGhlX3RoaW5nc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX21peGVkX29jYV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbnRvX2Fzc2V0X3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fd2l0aF90cmFuc2FjdGlvbnNfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jb21wYXJlX2Fzc2V0c19yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hZGRyZXNzX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2Fzc2V0X3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FwcGxpY2F0aW9uX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hbl9pbnRfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fbWV0aG9kX3dpdGhfZGVmYXVsdF9hcmdzX3JvdXRlQDEyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX21ldGhvZF93aXRoXzE1X2FyZ3Nfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fbWV0aG9kX3dpdGhfbW9yZV90aGFuXzE1X2FyZ3Nfcm91dGVAMTQgX19wdXlhX2FyYzRfcm91dGVyX19faGVsbG9fd2l0aF9hbGdvcHlfc3RyaW5nX3JvdXRlQDE1CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ub29wX3dpdGhfdWludDY0X3JvdXRlQDI6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIG5vb3Bfd2l0aF91aW50NjQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FsbF90aGVfdGhpbmdzX3JvdXRlQDM6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozNy00OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGFsbG93X2FjdGlvbnM9WwogICAgLy8gICAgICAgICAiTm9PcCIsCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uT3B0SW4sCiAgICAvLyAgICAgICAgICJDbG9zZU91dCIsCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uVXBkYXRlQXBwbGljYXRpb24sCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uRGVsZXRlQXBwbGljYXRpb24sCiAgICAvLyAgICAgXSwKICAgIC8vICAgICBuYW1lPSJhbGxfdGhlX3RoaW5ncyIsCiAgICAvLyAgICAgY3JlYXRlPSJhbGxvdyIsCiAgICAvLyAgICAgcmVhZG9ubHk9VHJ1ZSwKICAgIC8vICkKICAgIGNhbGxzdWIgZnVsbF9hYmlfY29uZmlnCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19taXhlZF9vY2Ffcm91dGVANDoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjUzLTYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgYWxsb3dfYWN0aW9ucz1bCiAgICAvLyAgICAgICAgICJOb09wIiwKICAgIC8vICAgICAgICAgIkNsb3NlT3V0IiwKICAgIC8vICAgICAgICAgIkRlbGV0ZUFwcGxpY2F0aW9uIiwKICAgIC8vICAgICBdLAogICAgLy8gICAgIGNyZWF0ZT0iZGlzYWxsb3ciLAogICAgLy8gICAgIHJlYWRvbmx5PVRydWUsCiAgICAvLyApCiAgICBpbnQgMQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgc2hsCiAgICBpbnQgMzcKICAgICYKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgb25lIG9mIE5vT3AsIENsb3NlT3V0LCBEZWxldGVBcHBsaWNhdGlvbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjUzLTYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgYWxsb3dfYWN0aW9ucz1bCiAgICAvLyAgICAgICAgICJOb09wIiwKICAgIC8vICAgICAgICAgIkNsb3NlT3V0IiwKICAgIC8vICAgICAgICAgIkRlbGV0ZUFwcGxpY2F0aW9uIiwKICAgIC8vICAgICBdLAogICAgLy8gICAgIGNyZWF0ZT0iZGlzYWxsb3ciLAogICAgLy8gICAgIHJlYWRvbmx5PVRydWUsCiAgICAvLyApCiAgICBjYWxsc3ViIG1peGVkX29jYQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2ludG9fYXNzZXRfcm91dGVANToKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBvcHRfaW50b19hc3NldAogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fd2l0aF90cmFuc2FjdGlvbnNfcm91dGVANjoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5Ojk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHdpdGhfdHJhbnNhY3Rpb25zCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jb21wYXJlX2Fzc2V0c19yb3V0ZUA3OgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBjb21wYXJlX2Fzc2V0cwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FkZHJlc3Nfcm91dGVAODoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hZGRyZXNzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXNzZXRfcm91dGVAOToKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hc3NldAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FwcGxpY2F0aW9uX3JvdXRlQDEwOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSwgbmFtZT0iZ2V0X2FwcGxpY2F0aW9uIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2FwcAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FuX2ludF9yb3V0ZUAxMToKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUsIG5hbWU9ImdldF9hbl9pbnQiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYV9pbnQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX21ldGhvZF93aXRoX2RlZmF1bHRfYXJnc19yb3V0ZUAxMjoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyOS0xNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgKICAgIC8vICAgICBkZWZhdWx0X2FyZ3M9ewogICAgLy8gICAgICAgICAiYXNzZXRfZnJvbV9zdG9yYWdlIjogImFzYSIsCiAgICAvLyAgICAgICAgICJhc3NldF9mcm9tX2Z1bmN0aW9uIjogZ2V0X2Fzc2V0LAogICAgLy8gICAgICAgICAiYWNjb3VudF9mcm9tX3N0b3JhZ2UiOiAiY3JlYXRvciIsCiAgICAvLyAgICAgICAgICJhY2NvdW50X2Zyb21fZnVuY3Rpb24iOiAiZ2V0X2FkZHJlc3MiLAogICAgLy8gICAgICAgICAiYXBwbGljYXRpb25fZnJvbV9zdG9yYWdlIjogImFwcCIsCiAgICAvLyAgICAgICAgICJhcHBsaWNhdGlvbl9mcm9tX2Z1bmN0aW9uIjogZ2V0X2FwcCwKICAgIC8vICAgICAgICAgImJ5dGVzX2Zyb21fc3RvcmFnZSI6ICJzb21lX2J5dGVzIiwKICAgIC8vICAgICAgICAgImludF9mcm9tX3N0b3JhZ2UiOiAiYW5faW50IiwKICAgIC8vICAgICAgICAgImludF9mcm9tX2Z1bmN0aW9uIjogImdldF9hX2ludCIsCiAgICAvLyAgICAgfQogICAgLy8gKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjIKICAgIC8vIGNsYXNzIFJlZmVyZW5jZShBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA2CiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDgKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDkKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyOS0xNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgKICAgIC8vICAgICBkZWZhdWx0X2FyZ3M9ewogICAgLy8gICAgICAgICAiYXNzZXRfZnJvbV9zdG9yYWdlIjogImFzYSIsCiAgICAvLyAgICAgICAgICJhc3NldF9mcm9tX2Z1bmN0aW9uIjogZ2V0X2Fzc2V0LAogICAgLy8gICAgICAgICAiYWNjb3VudF9mcm9tX3N0b3JhZ2UiOiAiY3JlYXRvciIsCiAgICAvLyAgICAgICAgICJhY2NvdW50X2Zyb21fZnVuY3Rpb24iOiAiZ2V0X2FkZHJlc3MiLAogICAgLy8gICAgICAgICAiYXBwbGljYXRpb25fZnJvbV9zdG9yYWdlIjogImFwcCIsCiAgICAvLyAgICAgICAgICJhcHBsaWNhdGlvbl9mcm9tX2Z1bmN0aW9uIjogZ2V0X2FwcCwKICAgIC8vICAgICAgICAgImJ5dGVzX2Zyb21fc3RvcmFnZSI6ICJzb21lX2J5dGVzIiwKICAgIC8vICAgICAgICAgImludF9mcm9tX3N0b3JhZ2UiOiAiYW5faW50IiwKICAgIC8vICAgICAgICAgImludF9mcm9tX2Z1bmN0aW9uIjogImdldF9hX2ludCIsCiAgICAvLyAgICAgfQogICAgLy8gKQogICAgY2FsbHN1YiBtZXRob2Rfd2l0aF9kZWZhdWx0X2FyZ3MKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX21ldGhvZF93aXRoXzE1X2FyZ3Nfcm91dGVAMTM6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjIKICAgIC8vIGNsYXNzIFJlZmVyZW5jZShBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTAKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDExCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTMKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE0CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIG1ldGhvZF93aXRoXzE1X2FyZ3MKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19tZXRob2Rfd2l0aF9tb3JlX3RoYW5fMTVfYXJnc19yb3V0ZUAxNDoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDYKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDcKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMgogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IHBheQogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIHBheQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDExCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE0CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZXh0cmFjdCAwIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZXh0cmFjdCA4IDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZXh0cmFjdCAxNiA4IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTUKICAgIGV4dHJhY3QgMjQgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE1CiAgICBleHRyYWN0IDMyIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZHVwCiAgICBpbnQgNDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGludCA0MgogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIGNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZHVwCiAgICBpbnQgNDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgc3dhcAogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE1CiAgICBleHRyYWN0IDQ0IDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IHBheQogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIHBheQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTUKICAgIGV4dHJhY3QgNDUgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE1CiAgICBleHRyYWN0IDUzIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBtZXRob2Rfd2l0aF9tb3JlX3RoYW5fMTVfYXJncwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19faGVsbG9fd2l0aF9hbGdvcHlfc3RyaW5nX3JvdXRlQDE1OgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBoZWxsb193aXRoX2FsZ29weV9zdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTg6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBzd2l0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9hYmlfY29uZmlnQDE5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfYWJpX2NvbmZpZ0AxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX2FiaV9jb25maWdAMTkgX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX2FiaV9jb25maWdAMTkgX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9hYmlfY29uZmlnQDE5CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX2FiaV9jb25maWdAMTk6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo2Ni03NQogICAgLy8gQGFyYzQuYmFyZW1ldGhvZCgKICAgIC8vICAgICBhbGxvd19hY3Rpb25zPVsKICAgIC8vICAgICAgICAgIk5vT3AiLAogICAgLy8gICAgICAgICAiT3B0SW4iLAogICAgLy8gICAgICAgICAiQ2xvc2VPdXQiLAogICAgLy8gICAgICAgICAiVXBkYXRlQXBwbGljYXRpb24iLAogICAgLy8gICAgICAgICAiRGVsZXRlQXBwbGljYXRpb24iLAogICAgLy8gICAgIF0sCiAgICAvLyAgICAgY3JlYXRlPSJyZXF1aXJlIiwKICAgIC8vICkKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjY2LTc2CiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKAogICAgLy8gICAgIGFsbG93X2FjdGlvbnM9WwogICAgLy8gICAgICAgICAiTm9PcCIsCiAgICAvLyAgICAgICAgICJPcHRJbiIsCiAgICAvLyAgICAgICAgICJDbG9zZU91dCIsCiAgICAvLyAgICAgICAgICJVcGRhdGVBcHBsaWNhdGlvbiIsCiAgICAvLyAgICAgICAgICJEZWxldGVBcHBsaWNhdGlvbiIsCiAgICAvLyAgICAgXSwKICAgIC8vICAgICBjcmVhdGU9InJlcXVpcmUiLAogICAgLy8gKQogICAgLy8gZGVmIGJhcmVfYWJpX2NvbmZpZyhzZWxmKSAtPiBOb25lOgogICAgY2FsbHN1YiBiYXJlX2FiaV9jb25maWcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjI6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2Uubm9vcF93aXRoX3VpbnQ2NChhOiBieXRlcykgLT4gYnl0ZXM6Cm5vb3Bfd2l0aF91aW50NjQ6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozMi0zMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgbm9vcF93aXRoX3VpbnQ2NChzZWxmLCBhOiBhcmM0LlVJbnQ2NCkgLT4gYXJjNC5VSW50ODoKICAgIHByb3RvIDEgMQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MzQKICAgIC8vIHJlc3VsdCA9IDEgKyBhLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICBpbnQgMQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MzUKICAgIC8vIHJldHVybiBhcmM0LlVJbnQ4KHJlc3VsdCkKICAgIGl0b2IKICAgIGV4dHJhY3QgNyAxCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5mdWxsX2FiaV9jb25maWcoYTogYnl0ZXMpIC0+IGJ5dGVzOgpmdWxsX2FiaV9jb25maWc6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozNy00OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGFsbG93X2FjdGlvbnM9WwogICAgLy8gICAgICAgICAiTm9PcCIsCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uT3B0SW4sCiAgICAvLyAgICAgICAgICJDbG9zZU91dCIsCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uVXBkYXRlQXBwbGljYXRpb24sCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uRGVsZXRlQXBwbGljYXRpb24sCiAgICAvLyAgICAgXSwKICAgIC8vICAgICBuYW1lPSJhbGxfdGhlX3RoaW5ncyIsCiAgICAvLyAgICAgY3JlYXRlPSJhbGxvdyIsCiAgICAvLyAgICAgcmVhZG9ubHk9VHJ1ZSwKICAgIC8vICkKICAgIC8vIGRlZiBmdWxsX2FiaV9jb25maWcoc2VsZiwgYTogYXJjNC5VSW50NjQpIC0+IGFyYzQuVUludDg6CiAgICBwcm90byAxIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjUwCiAgICAvLyByZXN1bHQgPSBVSW50NjQoMSkgKyBhLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICBpbnQgMQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NTEKICAgIC8vIHJldHVybiBhcmM0LlVJbnQ4KHJlc3VsdCkKICAgIGl0b2IKICAgIGV4dHJhY3QgNyAxCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5taXhlZF9vY2EoYTogYnl0ZXMpIC0+IGJ5dGVzOgptaXhlZF9vY2E6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo1My02MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGFsbG93X2FjdGlvbnM9WwogICAgLy8gICAgICAgICAiTm9PcCIsCiAgICAvLyAgICAgICAgICJDbG9zZU91dCIsCiAgICAvLyAgICAgICAgICJEZWxldGVBcHBsaWNhdGlvbiIsCiAgICAvLyAgICAgXSwKICAgIC8vICAgICBjcmVhdGU9ImRpc2FsbG93IiwKICAgIC8vICAgICByZWFkb25seT1UcnVlLAogICAgLy8gKQogICAgLy8gZGVmIG1peGVkX29jYShzZWxmLCBhOiBhcmM0LlVJbnQ2NCkgLT4gYXJjNC5VSW50ODoKICAgIHByb3RvIDEgMQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NjMKICAgIC8vIHJlc3VsdCA9IFVJbnQ2NCgxKSArIGEubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIGludCAxCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo2NAogICAgLy8gcmV0dXJuIGFyYzQuVUludDgocmVzdWx0KQogICAgaXRvYgogICAgZXh0cmFjdCA3IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuYWJpX3JvdXRpbmcuY29udHJhY3QuUmVmZXJlbmNlLm9wdF9pbnRvX2Fzc2V0KGFzc2V0OiB1aW50NjQpIC0+IHZvaWQ6Cm9wdF9pbnRvX2Fzc2V0OgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NzktODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIG9wdF9pbnRvX2Fzc2V0KHNlbGYsIGFzc2V0OiBBc3NldCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6ODEtODIKICAgIC8vICMgT25seSBhbGxvdyBhcHAgY3JlYXRvciB0byBvcHQgdGhlIGFwcCBhY2NvdW50IGludG8gYSBBU0EKICAgIC8vIGFzc2VydCBvcC5UeG4uc2VuZGVyID09IG9wLkdsb2JhbC5jcmVhdG9yX2FkZHJlc3MsICJPbmx5IGNyZWF0b3IgY2FuIG9wdCBpbiB0byBBU0EiCiAgICB0eG4gU2VuZGVyCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgID09CiAgICBhc3NlcnQgLy8gT25seSBjcmVhdG9yIGNhbiBvcHQgaW4gdG8gQVNBCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo4My04NAogICAgLy8gIyBWZXJpZnkgYSBBU0EgaGFzbid0IGFscmVhZHkgYmVlbiBvcHRlZCBpbnRvCiAgICAvLyBhc3NlcnQgbm90IHNlbGYuYXNhLCAiQVNBIGFscmVhZHkgb3B0ZWQgaW4iCiAgICBpbnQgMAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQKICAgIC8vIHNlbGYuYXNhID0gQXNzZXQoMTIzKQogICAgYnl0ZSAiYXNhIgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6ODMtODQKICAgIC8vICMgVmVyaWZ5IGEgQVNBIGhhc24ndCBhbHJlYWR5IGJlZW4gb3B0ZWQgaW50bwogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLmFzYSwgIkFTQSBhbHJlYWR5IG9wdGVkIGluIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzYSBleGlzdHMKICAgICEKICAgIGFzc2VydCAvLyBBU0EgYWxyZWFkeSBvcHRlZCBpbgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQKICAgIC8vIHNlbGYuYXNhID0gQXNzZXQoMTIzKQogICAgYnl0ZSAiYXNhIgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6ODUtODYKICAgIC8vICMgU2F2ZSBBU0EgSUQgaW4gZ2xvYmFsIHN0YXRlCiAgICAvLyBzZWxmLmFzYSA9IGFzc2V0CiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo4OC04OQogICAgLy8gIyBTdWJtaXQgb3B0LWluIHRyYW5zYWN0aW9uOiAwIGFzc2V0IHRyYW5zZmVyIHRvIHNlbGYKICAgIC8vIG9wLklUeG5DcmVhdGUuYmVnaW4oKQogICAgaXR4bl9iZWdpbgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6OTAKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0X3R5cGVfZW51bShUcmFuc2FjdGlvblR5cGUuQXNzZXRUcmFuc2ZlcikKICAgIGludCBheGZlcgogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6OTEKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0X2ZlZShVSW50NjQoMCkpICAjIGNvdmVyIGZlZSB3aXRoIG91dGVyIHR4bgogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo5MgogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRfYXNzZXRfcmVjZWl2ZXIob3AuR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcykKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICBpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjkzCiAgICAvLyBvcC5JVHhuQ3JlYXRlLnNldF94ZmVyX2Fzc2V0KGFzc2V0KQogICAgZnJhbWVfZGlnIC0xCiAgICBpdHhuX2ZpZWxkIFhmZXJBc3NldAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6OTQKICAgIC8vIG9wLklUeG5DcmVhdGUuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS53aXRoX3RyYW5zYWN0aW9ucyhhc3NldDogdWludDY0LCBhbl9pbnQ6IGJ5dGVzLCBwYXk6IHVpbnQ2NCwgYW5vdGhlcl9pbnQ6IGJ5dGVzKSAtPiB2b2lkOgp3aXRoX3RyYW5zYWN0aW9uczoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5Ojk2LTEwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgd2l0aF90cmFuc2FjdGlvbnMoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBhc3NldDogQXNzZXQsCiAgICAvLyAgICAgYW5faW50OiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBwYXk6IGd0eG4uUGF5bWVudFRyYW5zYWN0aW9uLAogICAgLy8gICAgIGFub3RoZXJfaW50OiBhcmM0LlVJbnQ2NCwKICAgIC8vICkgLT4gTm9uZToKICAgIHByb3RvIDQgMAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTA0CiAgICAvLyBhc3NlcnQgc2VsZi5hc2EgPT0gYXNzZXQsICJpcyBjb3JyZWN0IGFzc2V0IgogICAgaW50IDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBzZWxmLmFzYSA9IEFzc2V0KDEyMykKICAgIGJ5dGUgImFzYSIKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEwNAogICAgLy8gYXNzZXJ0IHNlbGYuYXNhID09IGFzc2V0LCAiaXMgY29ycmVjdCBhc3NldCIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc2EgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTQKICAgID09CiAgICBhc3NlcnQgLy8gaXMgY29ycmVjdCBhc3NldAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTA1CiAgICAvLyBhc3NlcnQgYW5faW50Lm5hdGl2ZSA9PSAxLCAiaXMgY29ycmVjdCBpbnQiCiAgICBmcmFtZV9kaWcgLTMKICAgIGJ0b2kKICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGlzIGNvcnJlY3QgaW50CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMDYKICAgIC8vIGFzc2VydCBwYXkucmVjZWl2ZXIgPT0gb3AuR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywgImlzIHBheW1lbnQgdG8gYXBwIgogICAgZnJhbWVfZGlnIC0yCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICBhc3NlcnQgLy8gaXMgcGF5bWVudCB0byBhcHAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEwNwogICAgLy8gYXNzZXJ0IGFub3RoZXJfaW50Lm5hdGl2ZSA9PSAyLCAiaXMgY29ycmVjdCBpbnQiCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIGludCAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGlzIGNvcnJlY3QgaW50CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5jb21wYXJlX2Fzc2V0cyhhc3NldF9hOiB1aW50NjQsIGFzc2V0X2I6IHVpbnQ2NCkgLT4gdm9pZDoKY29tcGFyZV9hc3NldHM6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMDktMTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBjb21wYXJlX2Fzc2V0cyhzZWxmLCBhc3NldF9hOiBBc3NldCwgYXNzZXRfYjogQXNzZXQpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExMQogICAgLy8gYXNzZXJ0IGFzc2V0X2EgPT0gYXNzZXRfYiwgImFzc2V0IGEgPT0gYiIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgYXNzZXJ0IC8vIGFzc2V0IGEgPT0gYgogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2UuZ2V0X2FkZHJlc3MoKSAtPiBieXRlczoKZ2V0X2FkZHJlc3M6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMTMtMTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIC8vIGRlZiBnZXRfYWRkcmVzcyhzZWxmKSAtPiBhcmM0LkFkZHJlc3M6CiAgICBwcm90byAwIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExNQogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcygpCiAgICBnbG9iYWwgWmVyb0FkZHJlc3MKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuYWJpX3JvdXRpbmcuY29udHJhY3QuUmVmZXJlbmNlLmdldF9hc3NldCgpIC0+IGJ5dGVzOgpnZXRfYXNzZXQ6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMTctMTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIC8vIGRlZiBnZXRfYXNzZXQoc2VsZikgLT4gYXJjNC5VSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExOQogICAgLy8gcmV0dXJuIGFyYzQuVUludDY0KDQ1NikKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwMWM4CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5nZXRfYXBwKCkgLT4gYnl0ZXM6CmdldF9hcHA6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMjEtMTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSwgbmFtZT0iZ2V0X2FwcGxpY2F0aW9uIikKICAgIC8vIGRlZiBnZXRfYXBwKHNlbGYpIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMjMKICAgIC8vIHJldHVybiBhcmM0LlVJbnQ2NCg0NTYpCiAgICBieXRlIDB4MDAwMDAwMDAwMDAwMDFjOAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2UuZ2V0X2FfaW50KCkgLT4gYnl0ZXM6CmdldF9hX2ludDoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyNS0xMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlLCBuYW1lPSJnZXRfYW5faW50IikKICAgIC8vIGRlZiBnZXRfYV9pbnQoc2VsZikgLT4gYXJjNC5VSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyNwogICAgLy8gcmV0dXJuIGFyYzQuVUludDY0KDMpCiAgICBieXRlIDB4MDAwMDAwMDAwMDAwMDAwMwogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2UubWV0aG9kX3dpdGhfZGVmYXVsdF9hcmdzKGFzc2V0X2Zyb21fc3RvcmFnZTogdWludDY0LCBhc3NldF9mcm9tX2Z1bmN0aW9uOiB1aW50NjQsIGFjY291bnRfZnJvbV9zdG9yYWdlOiBieXRlcywgYWNjb3VudF9mcm9tX2Z1bmN0aW9uOiBieXRlcywgYXBwbGljYXRpb25fZnJvbV9zdG9yYWdlOiB1aW50NjQsIGFwcGxpY2F0aW9uX2Zyb21fZnVuY3Rpb246IHVpbnQ2NCwgYnl0ZXNfZnJvbV9zdG9yYWdlOiBieXRlcywgaW50X2Zyb21fc3RvcmFnZTogYnl0ZXMsIGludF9mcm9tX2Z1bmN0aW9uOiBieXRlcykgLT4gdm9pZDoKbWV0aG9kX3dpdGhfZGVmYXVsdF9hcmdzOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTI5LTE1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJhc3NldF9mcm9tX3N0b3JhZ2UiOiAiYXNhIiwKICAgIC8vICAgICAgICAgImFzc2V0X2Zyb21fZnVuY3Rpb24iOiBnZXRfYXNzZXQsCiAgICAvLyAgICAgICAgICJhY2NvdW50X2Zyb21fc3RvcmFnZSI6ICJjcmVhdG9yIiwKICAgIC8vICAgICAgICAgImFjY291bnRfZnJvbV9mdW5jdGlvbiI6ICJnZXRfYWRkcmVzcyIsCiAgICAvLyAgICAgICAgICJhcHBsaWNhdGlvbl9mcm9tX3N0b3JhZ2UiOiAiYXBwIiwKICAgIC8vICAgICAgICAgImFwcGxpY2F0aW9uX2Zyb21fZnVuY3Rpb24iOiBnZXRfYXBwLAogICAgLy8gICAgICAgICAiYnl0ZXNfZnJvbV9zdG9yYWdlIjogInNvbWVfYnl0ZXMiLAogICAgLy8gICAgICAgICAiaW50X2Zyb21fc3RvcmFnZSI6ICJhbl9pbnQiLAogICAgLy8gICAgICAgICAiaW50X2Zyb21fZnVuY3Rpb24iOiAiZ2V0X2FfaW50IiwKICAgIC8vICAgICB9CiAgICAvLyApCiAgICAvLyBkZWYgbWV0aG9kX3dpdGhfZGVmYXVsdF9hcmdzKAogICAgLy8gICAgIHNlbGYsCiAgICAvLyAgICAgYXNzZXRfZnJvbV9zdG9yYWdlOiBBc3NldCwKICAgIC8vICAgICBhc3NldF9mcm9tX2Z1bmN0aW9uOiBBc3NldCwKICAgIC8vICAgICBhY2NvdW50X2Zyb21fc3RvcmFnZTogQWNjb3VudCwKICAgIC8vICAgICBhY2NvdW50X2Zyb21fZnVuY3Rpb246IEFjY291bnQsCiAgICAvLyAgICAgYXBwbGljYXRpb25fZnJvbV9zdG9yYWdlOiBBcHBsaWNhdGlvbiwKICAgIC8vICAgICBhcHBsaWNhdGlvbl9mcm9tX2Z1bmN0aW9uOiBBcHBsaWNhdGlvbiwKICAgIC8vICAgICBieXRlc19mcm9tX3N0b3JhZ2U6IEJ5dGVzMywKICAgIC8vICAgICBpbnRfZnJvbV9zdG9yYWdlOiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBpbnRfZnJvbV9mdW5jdGlvbjogYXJjNC5VSW50NjQsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byA5IDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE1NAogICAgLy8gYXNzZXJ0IGFzc2V0X2Zyb21fc3RvcmFnZSA9PSBBc3NldCgxMjMpLCAid3JvbmcgYXNzZXQgZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC05CiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0IC8vIHdyb25nIGFzc2V0IGZyb20gc3RvcmFnZQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTU1CiAgICAvLyBhc3NlcnQgYXNzZXRfZnJvbV9mdW5jdGlvbiA9PSBBc3NldCg0NTYpLCAid3JvbmcgYXNzZXQgZnJvbSBmdW5jdGlvbiIKICAgIGZyYW1lX2RpZyAtOAogICAgaW50IDQ1NgogICAgPT0KICAgIGFzc2VydCAvLyB3cm9uZyBhc3NldCBmcm9tIGZ1bmN0aW9uCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNTYKICAgIC8vIGFzc2VydCBhY2NvdW50X2Zyb21fc3RvcmFnZSA9PSBvcC5HbG9iYWwuY3JlYXRvcl9hZGRyZXNzLCAid3JvbmcgYWNjb3VudCBmcm9tIHN0b3JhZ2UiCiAgICBmcmFtZV9kaWcgLTcKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgPT0KICAgIGFzc2VydCAvLyB3cm9uZyBhY2NvdW50IGZyb20gc3RvcmFnZQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTU3CiAgICAvLyBhc3NlcnQgYWNjb3VudF9mcm9tX2Z1bmN0aW9uID09IG9wLkdsb2JhbC56ZXJvX2FkZHJlc3MsICJ3cm9uZyBhY2NvdW50IGZyb20gZnVuY3Rpb24iCiAgICBmcmFtZV9kaWcgLTYKICAgIGdsb2JhbCBaZXJvQWRkcmVzcwogICAgPT0KICAgIGFzc2VydCAvLyB3cm9uZyBhY2NvdW50IGZyb20gZnVuY3Rpb24KICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE1OAogICAgLy8gYXNzZXJ0IGFwcGxpY2F0aW9uX2Zyb21fc3RvcmFnZSA9PSBBcHBsaWNhdGlvbigxMjMpLCAid3JvbmcgYXBwbGljYXRpb24gZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC01CiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0IC8vIHdyb25nIGFwcGxpY2F0aW9uIGZyb20gc3RvcmFnZQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTU5CiAgICAvLyBhc3NlcnQgYXBwbGljYXRpb25fZnJvbV9mdW5jdGlvbiA9PSBBcHBsaWNhdGlvbig0NTYpLCAid3JvbmcgYXBwbGljYXRpb24gZnJvbSBmdW5jdGlvbiIKICAgIGZyYW1lX2RpZyAtNAogICAgaW50IDQ1NgogICAgPT0KICAgIGFzc2VydCAvLyB3cm9uZyBhcHBsaWNhdGlvbiBmcm9tIGZ1bmN0aW9uCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjAKICAgIC8vIGFzc2VydCBieXRlc19mcm9tX3N0b3JhZ2VbMF0gPT0gYXJjNC5CeXRlKDcpLCAid3JvbmcgMHRoIGJ5dGUgZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC0zCiAgICBleHRyYWN0IDAgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwNwogICAgYj09CiAgICBhc3NlcnQgLy8gd3JvbmcgMHRoIGJ5dGUgZnJvbSBzdG9yYWdlCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjEKICAgIC8vIGFzc2VydCBieXRlc19mcm9tX3N0b3JhZ2VbMV0gPT0gYXJjNC5CeXRlKDgpLCAid3JvbmcgMXN0IGJ5dGUgZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC0zCiAgICBleHRyYWN0IDEgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwOAogICAgYj09CiAgICBhc3NlcnQgLy8gd3JvbmcgMXN0IGJ5dGUgZnJvbSBzdG9yYWdlCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjIKICAgIC8vIGFzc2VydCBieXRlc19mcm9tX3N0b3JhZ2VbMl0gPT0gYXJjNC5CeXRlKDkpLCAid3JvbmcgMm5kIGJ5dGUgZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC0zCiAgICBleHRyYWN0IDIgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwOQogICAgYj09CiAgICBhc3NlcnQgLy8gd3JvbmcgMm5kIGJ5dGUgZnJvbSBzdG9yYWdlCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjMKICAgIC8vIGFzc2VydCBpbnRfZnJvbV9zdG9yYWdlLm5hdGl2ZSA9PSAyLCAid3JvbmcgaW50IGZyb20gc3RvcmFnZSIKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQgLy8gd3JvbmcgaW50IGZyb20gc3RvcmFnZQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTY0CiAgICAvLyBhc3NlcnQgaW50X2Zyb21fZnVuY3Rpb24ubmF0aXZlID09IDMsICJ3cm9uZyBpbnQgZnJvbSBmdW5jdGlvbiIKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgaW50IDMKICAgID09CiAgICBhc3NlcnQgLy8gd3JvbmcgaW50IGZyb20gZnVuY3Rpb24KICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuYWJpX3JvdXRpbmcuY29udHJhY3QuUmVmZXJlbmNlLm1ldGhvZF93aXRoXzE1X2FyZ3Mob25lOiB1aW50NjQsIHR3bzogdWludDY0LCB0aHJlZTogdWludDY0LCBmb3VyOiB1aW50NjQsIGZpdmU6IHVpbnQ2NCwgc2l4OiB1aW50NjQsIHNldmVuOiB1aW50NjQsIGVpZ2h0OiB1aW50NjQsIG5pbmU6IHVpbnQ2NCwgdGVuOiB1aW50NjQsIGVsZXZlbjogdWludDY0LCB0d2VsdmU6IHVpbnQ2NCwgdGhpcnRlZW46IHVpbnQ2NCwgZm91cnRlZW46IHVpbnQ2NCwgZmlmdGVlbjogYnl0ZXMpIC0+IGJ5dGVzOgptZXRob2Rfd2l0aF8xNV9hcmdzOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTY2LTE4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgbWV0aG9kX3dpdGhfMTVfYXJncygKICAgIC8vICAgICBzZWxmLAogICAgLy8gICAgIG9uZTogVUludDY0LAogICAgLy8gICAgIHR3bzogVUludDY0LAogICAgLy8gICAgIHRocmVlOiBVSW50NjQsCiAgICAvLyAgICAgZm91cjogVUludDY0LAogICAgLy8gICAgIGZpdmU6IFVJbnQ2NCwKICAgIC8vICAgICBzaXg6IFVJbnQ2NCwKICAgIC8vICAgICBzZXZlbjogVUludDY0LAogICAgLy8gICAgIGVpZ2h0OiBVSW50NjQsCiAgICAvLyAgICAgbmluZTogVUludDY0LAogICAgLy8gICAgIHRlbjogVUludDY0LAogICAgLy8gICAgIGVsZXZlbjogVUludDY0LAogICAgLy8gICAgIHR3ZWx2ZTogVUludDY0LAogICAgLy8gICAgIHRoaXJ0ZWVuOiBVSW50NjQsCiAgICAvLyAgICAgZm91cnRlZW46IFVJbnQ2NCwKICAgIC8vICAgICBmaWZ0ZWVuOiBCeXRlcywKICAgIC8vICkgLT4gQnl0ZXM6CiAgICBwcm90byAxNSAxCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTg4CiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICBmcmFtZV9kaWcgLTE1CiAgICBmcmFtZV9kaWcgLTE0CiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTg5CiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICAvLyArIHRocmVlCiAgICBmcmFtZV9kaWcgLTEzCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTkwCiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICAvLyArIHRocmVlCiAgICAvLyArIGZvdXIKICAgIGZyYW1lX2RpZyAtMTIKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE4Ny0xOTEKICAgIC8vIG9uZQogICAgLy8gKyB0d28KICAgIC8vICsgdGhyZWUKICAgIC8vICsgZm91cgogICAgLy8gKyBmaXZlCiAgICBmcmFtZV9kaWcgLTExCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTkyCiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICAvLyArIHRocmVlCiAgICAvLyArIGZvdXIKICAgIC8vICsgZml2ZQogICAgLy8gKyBzaXgKICAgIGZyYW1lX2RpZyAtMTAKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE4Ny0xOTMKICAgIC8vIG9uZQogICAgLy8gKyB0d28KICAgIC8vICsgdGhyZWUKICAgIC8vICsgZm91cgogICAgLy8gKyBmaXZlCiAgICAvLyArIHNpeAogICAgLy8gKyBzZXZlbgogICAgZnJhbWVfZGlnIC05CiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTk0CiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICAvLyArIHRocmVlCiAgICAvLyArIGZvdXIKICAgIC8vICsgZml2ZQogICAgLy8gKyBzaXgKICAgIC8vICsgc2V2ZW4KICAgIC8vICsgZWlnaHQKICAgIGZyYW1lX2RpZyAtOAogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTE5NQogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIGZyYW1lX2RpZyAtNwogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTE5NgogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIC8vICsgdGVuCiAgICBmcmFtZV9kaWcgLTYKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE4Ny0xOTcKICAgIC8vIG9uZQogICAgLy8gKyB0d28KICAgIC8vICsgdGhyZWUKICAgIC8vICsgZm91cgogICAgLy8gKyBmaXZlCiAgICAvLyArIHNpeAogICAgLy8gKyBzZXZlbgogICAgLy8gKyBlaWdodAogICAgLy8gKyBuaW5lCiAgICAvLyArIHRlbgogICAgLy8gKyBlbGV2ZW4KICAgIGZyYW1lX2RpZyAtNQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTE5OAogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIC8vICsgdGVuCiAgICAvLyArIGVsZXZlbgogICAgLy8gKyB0d2VsdmUKICAgIGZyYW1lX2RpZyAtNAogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTE5OQogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIC8vICsgdGVuCiAgICAvLyArIGVsZXZlbgogICAgLy8gKyB0d2VsdmUKICAgIC8vICsgdGhpcnRlZW4KICAgIGZyYW1lX2RpZyAtMwogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTIwMAogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIC8vICsgdGVuCiAgICAvLyArIGVsZXZlbgogICAgLy8gKyB0d2VsdmUKICAgIC8vICsgdGhpcnRlZW4KICAgIC8vICsgZm91cnRlZW4KICAgIGZyYW1lX2RpZyAtMgogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg2LTIwMQogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBvbmUKICAgIC8vICAgICArIHR3bwogICAgLy8gICAgICsgdGhyZWUKICAgIC8vICAgICArIGZvdXIKICAgIC8vICAgICArIGZpdmUKICAgIC8vICAgICArIHNpeAogICAgLy8gICAgICsgc2V2ZW4KICAgIC8vICAgICArIGVpZ2h0CiAgICAvLyAgICAgKyBuaW5lCiAgICAvLyAgICAgKyB0ZW4KICAgIC8vICAgICArIGVsZXZlbgogICAgLy8gICAgICsgdHdlbHZlCiAgICAvLyAgICAgKyB0aGlydGVlbgogICAgLy8gICAgICsgZm91cnRlZW4KICAgIC8vICkKICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjAyCiAgICAvLyByZXR1cm4gZmlmdGVlbgogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5tZXRob2Rfd2l0aF9tb3JlX3RoYW5fMTVfYXJncyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiB1aW50NjQsIGFzc2V0OiB1aW50NjQsIGU6IGJ5dGVzLCBmOiBieXRlcywgcGF5OiB1aW50NjQsIGc6IGJ5dGVzLCBoOiBieXRlcywgaTogYnl0ZXMsIGo6IGJ5dGVzLCBrOiBieXRlcywgbDogYnl0ZXMsIG06IGJ5dGVzLCBuOiBieXRlcywgbzogYnl0ZXMsIHA6IHVpbnQ2NCwgcTogYnl0ZXMsIHI6IGJ5dGVzLCBzOiBieXRlcywgdDogYnl0ZXMsIGFzc2V0MjogdWludDY0LCBwYXkyOiB1aW50NjQsIHU6IGJ5dGVzLCB2OiBieXRlcykgLT4gYnl0ZXM6Cm1ldGhvZF93aXRoX21vcmVfdGhhbl8xNV9hcmdzOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjA0LTIzNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgbWV0aG9kX3dpdGhfbW9yZV90aGFuXzE1X2FyZ3MoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBhOiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBiOiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBjOiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBkOiBVSW50NjQsCiAgICAvLyAgICAgYXNzZXQ6IEFzc2V0LAogICAgLy8gICAgIGU6IGFyYzQuVUludDY0LAogICAgLy8gICAgIGY6IGFyYzQuVUludDY0LAogICAgLy8gICAgIHBheTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24sCiAgICAvLyAgICAgZzogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgaDogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgaTogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgajogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgazogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgIyBydWZmOiBub3FhOiBFNzQxCiAgICAvLyAgICAgbDogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgbTogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgbjogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgbzogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgcDogVUludDY0LAogICAgLy8gICAgIHE6IGFyYzQuVUludDY0LAogICAgLy8gICAgIHI6IGFyYzQuVUludDY0LAogICAgLy8gICAgIHM6IEJ5dGVzLAogICAgLy8gICAgIHQ6IEJ5dGVzLAogICAgLy8gICAgIGFzc2V0MjogQXNzZXQsCiAgICAvLyAgICAgcGF5MjogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24sCiAgICAvLyAgICAgdTogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgdjogYXJjNC5VSW50NjQsCiAgICAvLyApIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMjYgMQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjM5CiAgICAvLyBhc3NlcnQgb3AuVHhuLm51bV9hcHBfYXJncyA9PSAxNgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGludCAxNgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQwCiAgICAvLyBhc3NlcnQgcGF5LmFtb3VudCA9PSAxMDAwMDAKICAgIGZyYW1lX2RpZyAtMTkKICAgIGd0eG5zIEFtb3VudAogICAgaW50IDEwMDAwMAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQxCiAgICAvLyBhc3NlcnQgcGF5Mi5hbW91bnQgPT0gMjAwMDAwCiAgICBmcmFtZV9kaWcgLTMKICAgIGd0eG5zIEFtb3VudAogICAgaW50IDIwMDAwMAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQyCiAgICAvLyBhc3NlcnQgYXNzZXQuaWQKICAgIGZyYW1lX2RpZyAtMjIKICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQzCiAgICAvLyBhc3NlcnQgYXNzZXQyLmlkCiAgICBmcmFtZV9kaWcgLTQKICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ1CiAgICAvLyBsb2cocyArIHQpCiAgICBmcmFtZV9kaWcgLTYKICAgIGZyYW1lX2RpZyAtNQogICAgY29uY2F0CiAgICBsb2cKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gYS5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMjYKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OQogICAgLy8gKyBiLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0yNQogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI0OQogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI1MAogICAgLy8gKyBjLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0yNAogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI1MAogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNTEKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIGZyYW1lX2RpZyAtMjMKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI1MgogICAgLy8gKyBlLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0yMQogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI1MgogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgIC8vICsgZAogICAgLy8gKyBlLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjUzCiAgICAvLyArIGYubmF0aXZlCiAgICBmcmFtZV9kaWcgLTIwCiAgICBidG9pCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjUzCiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNTQKICAgIC8vICsgZy5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMTgKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNTQKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI1NQogICAgLy8gKyBoLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xNwogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI1NQogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgIC8vICsgZAogICAgLy8gKyBlLm5hdGl2ZQogICAgLy8gKyBmLm5hdGl2ZQogICAgLy8gKyBnLm5hdGl2ZQogICAgLy8gKyBoLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjU2CiAgICAvLyArIGkubmF0aXZlCiAgICBmcmFtZV9kaWcgLTE2CiAgICBidG9pCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjU2CiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICAvLyArIGcubmF0aXZlCiAgICAvLyArIGgubmF0aXZlCiAgICAvLyArIGkubmF0aXZlCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNTcKICAgIC8vICsgai5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMTUKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNTcKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI1OAogICAgLy8gKyBrLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xNAogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI1OAogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgIC8vICsgZAogICAgLy8gKyBlLm5hdGl2ZQogICAgLy8gKyBmLm5hdGl2ZQogICAgLy8gKyBnLm5hdGl2ZQogICAgLy8gKyBoLm5hdGl2ZQogICAgLy8gKyBpLm5hdGl2ZQogICAgLy8gKyBqLm5hdGl2ZQogICAgLy8gKyBrLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjU5CiAgICAvLyArIGwubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEzCiAgICBidG9pCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjU5CiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICAvLyArIGcubmF0aXZlCiAgICAvLyArIGgubmF0aXZlCiAgICAvLyArIGkubmF0aXZlCiAgICAvLyArIGoubmF0aXZlCiAgICAvLyArIGsubmF0aXZlCiAgICAvLyArIGwubmF0aXZlCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNjAKICAgIC8vICsgbS5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMTIKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjAKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI2MQogICAgLy8gKyBuLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xMQogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI2MQogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgIC8vICsgZAogICAgLy8gKyBlLm5hdGl2ZQogICAgLy8gKyBmLm5hdGl2ZQogICAgLy8gKyBnLm5hdGl2ZQogICAgLy8gKyBoLm5hdGl2ZQogICAgLy8gKyBpLm5hdGl2ZQogICAgLy8gKyBqLm5hdGl2ZQogICAgLy8gKyBrLm5hdGl2ZQogICAgLy8gKyBsLm5hdGl2ZQogICAgLy8gKyBtLm5hdGl2ZQogICAgLy8gKyBuLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjYyCiAgICAvLyArIG8ubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEwCiAgICBidG9pCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjYyCiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICAvLyArIGcubmF0aXZlCiAgICAvLyArIGgubmF0aXZlCiAgICAvLyArIGkubmF0aXZlCiAgICAvLyArIGoubmF0aXZlCiAgICAvLyArIGsubmF0aXZlCiAgICAvLyArIGwubmF0aXZlCiAgICAvLyArIG0ubmF0aXZlCiAgICAvLyArIG4ubmF0aXZlCiAgICAvLyArIG8ubmF0aXZlCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjYzCiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICAvLyArIGcubmF0aXZlCiAgICAvLyArIGgubmF0aXZlCiAgICAvLyArIGkubmF0aXZlCiAgICAvLyArIGoubmF0aXZlCiAgICAvLyArIGsubmF0aXZlCiAgICAvLyArIGwubmF0aXZlCiAgICAvLyArIG0ubmF0aXZlCiAgICAvLyArIG4ubmF0aXZlCiAgICAvLyArIG8ubmF0aXZlCiAgICAvLyArIHAKICAgIGZyYW1lX2RpZyAtOQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjY0CiAgICAvLyArIHEubmF0aXZlCiAgICBmcmFtZV9kaWcgLTgKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjQKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgIC8vICsgbi5uYXRpdmUKICAgIC8vICsgby5uYXRpdmUKICAgIC8vICsgcAogICAgLy8gKyBxLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjY1CiAgICAvLyArIHIubmF0aXZlCiAgICBmcmFtZV9kaWcgLTcKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjUKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgIC8vICsgbi5uYXRpdmUKICAgIC8vICsgby5uYXRpdmUKICAgIC8vICsgcAogICAgLy8gKyBxLm5hdGl2ZQogICAgLy8gKyByLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjY2CiAgICAvLyArIHUubmF0aXZlCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjYKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgIC8vICsgbi5uYXRpdmUKICAgIC8vICsgby5uYXRpdmUKICAgIC8vICsgcAogICAgLy8gKyBxLm5hdGl2ZQogICAgLy8gKyByLm5hdGl2ZQogICAgLy8gKyB1Lm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjY3CiAgICAvLyArIHYubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjcKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgIC8vICsgbi5uYXRpdmUKICAgIC8vICsgby5uYXRpdmUKICAgIC8vICsgcAogICAgLy8gKyBxLm5hdGl2ZQogICAgLy8gKyByLm5hdGl2ZQogICAgLy8gKyB1Lm5hdGl2ZQogICAgLy8gKyB2Lm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ3LTI2OAogICAgLy8gcmV0dXJuIGFyYzQuVUludDY0KAogICAgLy8gICAgIGEubmF0aXZlCiAgICAvLyAgICAgKyBiLm5hdGl2ZQogICAgLy8gICAgICsgYy5uYXRpdmUKICAgIC8vICAgICArIGQKICAgIC8vICAgICArIGUubmF0aXZlCiAgICAvLyAgICAgKyBmLm5hdGl2ZQogICAgLy8gICAgICsgZy5uYXRpdmUKICAgIC8vICAgICArIGgubmF0aXZlCiAgICAvLyAgICAgKyBpLm5hdGl2ZQogICAgLy8gICAgICsgai5uYXRpdmUKICAgIC8vICAgICArIGsubmF0aXZlCiAgICAvLyAgICAgKyBsLm5hdGl2ZQogICAgLy8gICAgICsgbS5uYXRpdmUKICAgIC8vICAgICArIG4ubmF0aXZlCiAgICAvLyAgICAgKyBvLm5hdGl2ZQogICAgLy8gICAgICsgcAogICAgLy8gICAgICsgcS5uYXRpdmUKICAgIC8vICAgICArIHIubmF0aXZlCiAgICAvLyAgICAgKyB1Lm5hdGl2ZQogICAgLy8gICAgICsgdi5uYXRpdmUKICAgIC8vICkKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuYWJpX3JvdXRpbmcuY29udHJhY3QuUmVmZXJlbmNlLmhlbGxvX3dpdGhfYWxnb3B5X3N0cmluZyhuYW1lOiBieXRlcykgLT4gYnl0ZXM6CmhlbGxvX3dpdGhfYWxnb3B5X3N0cmluZzoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI3MC0yNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGhlbGxvX3dpdGhfYWxnb3B5X3N0cmluZyhzZWxmLCBuYW1lOiBTdHJpbmcpIC0+IFN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjcyCiAgICAvLyByZXR1cm4gIkhlbGxvICIgKyBuYW1lICsgIiEiCiAgICBieXRlICJIZWxsbyAiCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgYnl0ZSAiISIKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2UuYmFyZV9hYmlfY29uZmlnKCkgLT4gdm9pZDoKYmFyZV9hYmlfY29uZmlnOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NjYtNzYKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoCiAgICAvLyAgICAgYWxsb3dfYWN0aW9ucz1bCiAgICAvLyAgICAgICAgICJOb09wIiwKICAgIC8vICAgICAgICAgIk9wdEluIiwKICAgIC8vICAgICAgICAgIkNsb3NlT3V0IiwKICAgIC8vICAgICAgICAgIlVwZGF0ZUFwcGxpY2F0aW9uIiwKICAgIC8vICAgICAgICAgIkRlbGV0ZUFwcGxpY2F0aW9uIiwKICAgIC8vICAgICBdLAogICAgLy8gICAgIGNyZWF0ZT0icmVxdWlyZSIsCiAgICAvLyApCiAgICAvLyBkZWYgYmFyZV9hYmlfY29uZmlnKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBsb2coIkhlbGxvIFdvcmxkIikKICAgIGJ5dGUgIkhlbGxvIFdvcmxkIgogICAgbG9nCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjMKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNAogICAgLy8gc2VsZi5hc2EgPSBBc3NldCgxMjMpCiAgICBieXRlICJhc2EiCiAgICBpbnQgMTIzCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjUKICAgIC8vIHNlbGYuYW5faW50ID0gVUludDY0KDIpCiAgICBieXRlICJhbl9pbnQiCiAgICBpbnQgMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI2CiAgICAvLyBzZWxmLnNvbWVfYnl0ZXMgPSBCeXRlczMoYXJjNC5CeXRlKDcpLCBhcmM0LkJ5dGUoOCksIGFyYzQuQnl0ZSg5KSkKICAgIGJ5dGUgInNvbWVfYnl0ZXMiCiAgICBieXRlIDB4MDcwODA5CiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjcKICAgIC8vIHNlbGYuY3JlYXRvciA9IG9wLlR4bi5zZW5kZXIKICAgIGJ5dGUgImNyZWF0b3IiCiAgICB0eG4gU2VuZGVyCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjgKICAgIC8vIHNlbGYuYXBwID0gQXBwbGljYXRpb24oMTIzKQogICAgYnl0ZSAiYXBwIgogICAgaW50IDEyMwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjMwCiAgICAvLyBhc3NlcnQgYXJjNC5hcmM0X3NpZ25hdHVyZSgiZ2V0KHVpbnQ2NCxieXRlW10pYnl0ZVtdIiksICJoYXMgbWV0aG9kIHNlbGVjdG9yIgogICAgbWV0aG9kICJnZXQodWludDY0LGJ5dGVbXSlieXRlW10iCiAgICBsZW4KICAgIGFzc2VydCAvLyBoYXMgbWV0aG9kIHNlbGVjdG9yCiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5hcHByb3ZhbF9wcm9ncmFtOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2VudHJ5cG9pbnRAMgogICAgY2FsbHN1YiBfX2luaXRfXwoKbWFpbl9lbnRyeXBvaW50QDI6CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTgKICAgIG1ldGhvZCAibm9vcF93aXRoX3VpbnQ2NCh1aW50NjQpdWludDgiCiAgICBtZXRob2QgImFsbF90aGVfdGhpbmdzKHVpbnQ2NCl1aW50OCIKICAgIG1ldGhvZCAibWl4ZWRfb2NhKHVpbnQ2NCl1aW50OCIKICAgIG1ldGhvZCAib3B0X2ludG9fYXNzZXQoYXNzZXQpdm9pZCIKICAgIG1ldGhvZCAid2l0aF90cmFuc2FjdGlvbnMoYXNzZXQsdWludDY0LHBheSx1aW50NjQpdm9pZCIKICAgIG1ldGhvZCAiY29tcGFyZV9hc3NldHMoYXNzZXQsYXNzZXQpdm9pZCIKICAgIG1ldGhvZCAiZ2V0X2FkZHJlc3MoKWFkZHJlc3MiCiAgICBtZXRob2QgImdldF9hc3NldCgpdWludDY0IgogICAgbWV0aG9kICJnZXRfYXBwbGljYXRpb24oKXVpbnQ2NCIKICAgIG1ldGhvZCAiZ2V0X2FuX2ludCgpdWludDY0IgogICAgbWV0aG9kICJtZXRob2Rfd2l0aF9kZWZhdWx0X2FyZ3MoYXNzZXQsYXNzZXQsYWNjb3VudCxhY2NvdW50LGFwcGxpY2F0aW9uLGFwcGxpY2F0aW9uLGJ5dGVbM10sdWludDY0LHVpbnQ2NCl2b2lkIgogICAgbWV0aG9kICJtZXRob2Rfd2l0aF8xNV9hcmdzKHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKICAgIG1ldGhvZCAibWV0aG9kX3dpdGhfbW9yZV90aGFuXzE1X2FyZ3ModWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LGFzc2V0LHVpbnQ2NCx1aW50NjQscGF5LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LHVpbnQ2NCx1aW50NjQsdWludDY0LGJ5dGVbXSxieXRlW10sYXNzZXQscGF5LHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJoZWxsb193aXRoX2FsZ29weV9zdHJpbmcoc3RyaW5nKXN0cmluZyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX25vb3Bfd2l0aF91aW50NjRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hbGxfdGhlX3RoaW5nc19yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX21peGVkX29jYV9yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbnRvX2Fzc2V0X3JvdXRlQDUgX19wdXlhX2FyYzRfcm91dGVyX19fd2l0aF90cmFuc2FjdGlvbnNfcm91dGVANiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jb21wYXJlX2Fzc2V0c19yb3V0ZUA3IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hZGRyZXNzX3JvdXRlQDggX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2Fzc2V0X3JvdXRlQDkgX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FwcGxpY2F0aW9uX3JvdXRlQDEwIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dldF9hbl9pbnRfcm91dGVAMTEgX19wdXlhX2FyYzRfcm91dGVyX19fbWV0aG9kX3dpdGhfZGVmYXVsdF9hcmdzX3JvdXRlQDEyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX21ldGhvZF93aXRoXzE1X2FyZ3Nfcm91dGVAMTMgX19wdXlhX2FyYzRfcm91dGVyX19fbWV0aG9kX3dpdGhfbW9yZV90aGFuXzE1X2FyZ3Nfcm91dGVAMTQgX19wdXlhX2FyYzRfcm91dGVyX19faGVsbG9fd2l0aF9hbGdvcHlfc3RyaW5nX3JvdXRlQDE1CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ub29wX3dpdGhfdWludDY0X3JvdXRlQDI6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozMgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIG5vb3Bfd2l0aF91aW50NjQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FsbF90aGVfdGhpbmdzX3JvdXRlQDM6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozNy00OAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGFsbG93X2FjdGlvbnM9WwogICAgLy8gICAgICAgICAiTm9PcCIsCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uT3B0SW4sCiAgICAvLyAgICAgICAgICJDbG9zZU91dCIsCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uVXBkYXRlQXBwbGljYXRpb24sCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uRGVsZXRlQXBwbGljYXRpb24sCiAgICAvLyAgICAgXSwKICAgIC8vICAgICBuYW1lPSJhbGxfdGhlX3RoaW5ncyIsCiAgICAvLyAgICAgY3JlYXRlPSJhbGxvdyIsCiAgICAvLyAgICAgcmVhZG9ubHk9VHJ1ZSwKICAgIC8vICkKICAgIGNhbGxzdWIgZnVsbF9hYmlfY29uZmlnCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19taXhlZF9vY2Ffcm91dGVANDoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjUzLTYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgYWxsb3dfYWN0aW9ucz1bCiAgICAvLyAgICAgICAgICJOb09wIiwKICAgIC8vICAgICAgICAgIkNsb3NlT3V0IiwKICAgIC8vICAgICAgICAgIkRlbGV0ZUFwcGxpY2F0aW9uIiwKICAgIC8vICAgICBdLAogICAgLy8gICAgIGNyZWF0ZT0iZGlzYWxsb3ciLAogICAgLy8gICAgIHJlYWRvbmx5PVRydWUsCiAgICAvLyApCiAgICBpbnQgMQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgc2hsCiAgICBpbnQgMzcKICAgICYKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgb25lIG9mIE5vT3AsIENsb3NlT3V0LCBEZWxldGVBcHBsaWNhdGlvbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjUzLTYxCiAgICAvLyBAYXJjNC5hYmltZXRob2QoCiAgICAvLyAgICAgYWxsb3dfYWN0aW9ucz1bCiAgICAvLyAgICAgICAgICJOb09wIiwKICAgIC8vICAgICAgICAgIkNsb3NlT3V0IiwKICAgIC8vICAgICAgICAgIkRlbGV0ZUFwcGxpY2F0aW9uIiwKICAgIC8vICAgICBdLAogICAgLy8gICAgIGNyZWF0ZT0iZGlzYWxsb3ciLAogICAgLy8gICAgIHJlYWRvbmx5PVRydWUsCiAgICAvLyApCiAgICBjYWxsc3ViIG1peGVkX29jYQogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fb3B0X2ludG9fYXNzZXRfcm91dGVANToKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NzkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBvcHRfaW50b19hc3NldAogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fd2l0aF90cmFuc2FjdGlvbnNfcm91dGVANjoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5Ojk2CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgdHhuIEdyb3VwSW5kZXgKICAgIGludCAxCiAgICAtCiAgICBkdXAKICAgIGd0eG5zIFR5cGVFbnVtCiAgICBpbnQgcGF5CiAgICA9PQogICAgYXNzZXJ0IC8vIHRyYW5zYWN0aW9uIHR5cGUgaXMgcGF5CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo5NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIHdpdGhfdHJhbnNhY3Rpb25zCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jb21wYXJlX2Fzc2V0c19yb3V0ZUA3OgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTA5CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGJ0b2kKICAgIHR4bmFzIEFzc2V0cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMDkKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBjb21wYXJlX2Fzc2V0cwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FkZHJlc3Nfcm91dGVAODoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hZGRyZXNzCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfYXNzZXRfcm91dGVAOToKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldF9hc3NldAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FwcGxpY2F0aW9uX3JvdXRlQDEwOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTIxCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSwgbmFtZT0iZ2V0X2FwcGxpY2F0aW9uIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgZ2V0X2FwcAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ2V0X2FuX2ludF9yb3V0ZUAxMToKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKHJlYWRvbmx5PVRydWUsIG5hbWU9ImdldF9hbl9pbnQiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBnZXRfYV9pbnQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX21ldGhvZF93aXRoX2RlZmF1bHRfYXJnc19yb3V0ZUAxMjoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyOS0xNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgKICAgIC8vICAgICBkZWZhdWx0X2FyZ3M9ewogICAgLy8gICAgICAgICAiYXNzZXRfZnJvbV9zdG9yYWdlIjogImFzYSIsCiAgICAvLyAgICAgICAgICJhc3NldF9mcm9tX2Z1bmN0aW9uIjogZ2V0X2Fzc2V0LAogICAgLy8gICAgICAgICAiYWNjb3VudF9mcm9tX3N0b3JhZ2UiOiAiY3JlYXRvciIsCiAgICAvLyAgICAgICAgICJhY2NvdW50X2Zyb21fZnVuY3Rpb24iOiAiZ2V0X2FkZHJlc3MiLAogICAgLy8gICAgICAgICAiYXBwbGljYXRpb25fZnJvbV9zdG9yYWdlIjogImFwcCIsCiAgICAvLyAgICAgICAgICJhcHBsaWNhdGlvbl9mcm9tX2Z1bmN0aW9uIjogZ2V0X2FwcCwKICAgIC8vICAgICAgICAgImJ5dGVzX2Zyb21fc3RvcmFnZSI6ICJzb21lX2J5dGVzIiwKICAgIC8vICAgICAgICAgImludF9mcm9tX3N0b3JhZ2UiOiAiYW5faW50IiwKICAgIC8vICAgICAgICAgImludF9mcm9tX2Z1bmN0aW9uIjogImdldF9hX2ludCIsCiAgICAvLyAgICAgfQogICAgLy8gKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjIKICAgIC8vIGNsYXNzIFJlZmVyZW5jZShBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYXMgQXNzZXRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDMKICAgIGJ0b2kKICAgIHR4bmFzIEFjY291bnRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICB0eG5hcyBBY2NvdW50cwogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgYnRvaQogICAgdHhuYXMgQXBwbGljYXRpb25zCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA2CiAgICBidG9pCiAgICB0eG5hcyBBcHBsaWNhdGlvbnMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDcKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDgKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDkKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyOS0xNDEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgKICAgIC8vICAgICBkZWZhdWx0X2FyZ3M9ewogICAgLy8gICAgICAgICAiYXNzZXRfZnJvbV9zdG9yYWdlIjogImFzYSIsCiAgICAvLyAgICAgICAgICJhc3NldF9mcm9tX2Z1bmN0aW9uIjogZ2V0X2Fzc2V0LAogICAgLy8gICAgICAgICAiYWNjb3VudF9mcm9tX3N0b3JhZ2UiOiAiY3JlYXRvciIsCiAgICAvLyAgICAgICAgICJhY2NvdW50X2Zyb21fZnVuY3Rpb24iOiAiZ2V0X2FkZHJlc3MiLAogICAgLy8gICAgICAgICAiYXBwbGljYXRpb25fZnJvbV9zdG9yYWdlIjogImFwcCIsCiAgICAvLyAgICAgICAgICJhcHBsaWNhdGlvbl9mcm9tX2Z1bmN0aW9uIjogZ2V0X2FwcCwKICAgIC8vICAgICAgICAgImJ5dGVzX2Zyb21fc3RvcmFnZSI6ICJzb21lX2J5dGVzIiwKICAgIC8vICAgICAgICAgImludF9mcm9tX3N0b3JhZ2UiOiAiYW5faW50IiwKICAgIC8vICAgICAgICAgImludF9mcm9tX2Z1bmN0aW9uIjogImdldF9hX2ludCIsCiAgICAvLyAgICAgfQogICAgLy8gKQogICAgY2FsbHN1YiBtZXRob2Rfd2l0aF9kZWZhdWx0X2FyZ3MKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX21ldGhvZF93aXRoXzE1X2FyZ3Nfcm91dGVAMTM6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjIKICAgIC8vIGNsYXNzIFJlZmVyZW5jZShBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNAogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgNwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTAKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDExCiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMgogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTMKICAgIGJ0b2kKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE0CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE2NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICBjYWxsc3ViIG1ldGhvZF93aXRoXzE1X2FyZ3MKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19tZXRob2Rfd2l0aF9tb3JlX3RoYW5fMTVfYXJnc19yb3V0ZUAxNDoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIwNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAyCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA0CiAgICBidG9pCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyA1CiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDYKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDcKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMgogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IHBheQogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIHBheQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOAogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgOQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDExCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxMgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE0CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZXh0cmFjdCAwIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZXh0cmFjdCA4IDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZXh0cmFjdCAxNiA4IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnRvaQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTUKICAgIGV4dHJhY3QgMjQgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE1CiAgICBleHRyYWN0IDMyIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZHVwCiAgICBpbnQgNDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGludCA0MgogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIGNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGV4dHJhY3QgMiAwCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxNQogICAgZHVwCiAgICBpbnQgNDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgc3dhcAogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgZXh0cmFjdCAyIDAKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE1CiAgICBleHRyYWN0IDQ0IDEgLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBidG9pCiAgICB0eG5hcyBBc3NldHMKICAgIHR4biBHcm91cEluZGV4CiAgICBpbnQgMQogICAgLQogICAgZHVwCiAgICBndHhucyBUeXBlRW51bQogICAgaW50IHBheQogICAgPT0KICAgIGFzc2VydCAvLyB0cmFuc2FjdGlvbiB0eXBlIGlzIHBheQogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMTUKICAgIGV4dHJhY3QgNDUgOCAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDE1CiAgICBleHRyYWN0IDUzIDggLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMDQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBtZXRob2Rfd2l0aF9tb3JlX3RoYW5fMTVfYXJncwogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19faGVsbG9fd2l0aF9hbGdvcHlfc3RyaW5nX3JvdXRlQDE1OgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjcwCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBSZWZlcmVuY2UoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNzAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgY2FsbHN1YiBoZWxsb193aXRoX2FsZ29weV9zdHJpbmcKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdAMTg6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBzd2l0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9hYmlfY29uZmlnQDE5IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfYWJpX2NvbmZpZ0AxOSBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX2FiaV9jb25maWdAMTkgX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAyMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX2FiaV9jb25maWdAMTkgX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9hYmlfY29uZmlnQDE5CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX2FiaV9jb25maWdAMTk6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo2Ni03NQogICAgLy8gQGFyYzQuYmFyZW1ldGhvZCgKICAgIC8vICAgICBhbGxvd19hY3Rpb25zPVsKICAgIC8vICAgICAgICAgIk5vT3AiLAogICAgLy8gICAgICAgICAiT3B0SW4iLAogICAgLy8gICAgICAgICAiQ2xvc2VPdXQiLAogICAgLy8gICAgICAgICAiVXBkYXRlQXBwbGljYXRpb24iLAogICAgLy8gICAgICAgICAiRGVsZXRlQXBwbGljYXRpb24iLAogICAgLy8gICAgIF0sCiAgICAvLyAgICAgY3JlYXRlPSJyZXF1aXJlIiwKICAgIC8vICkKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjY2LTc2CiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKAogICAgLy8gICAgIGFsbG93X2FjdGlvbnM9WwogICAgLy8gICAgICAgICAiTm9PcCIsCiAgICAvLyAgICAgICAgICJPcHRJbiIsCiAgICAvLyAgICAgICAgICJDbG9zZU91dCIsCiAgICAvLyAgICAgICAgICJVcGRhdGVBcHBsaWNhdGlvbiIsCiAgICAvLyAgICAgICAgICJEZWxldGVBcHBsaWNhdGlvbiIsCiAgICAvLyAgICAgXSwKICAgIC8vICAgICBjcmVhdGU9InJlcXVpcmUiLAogICAgLy8gKQogICAgLy8gZGVmIGJhcmVfYWJpX2NvbmZpZyhzZWxmKSAtPiBOb25lOgogICAgY2FsbHN1YiBiYXJlX2FiaV9jb25maWcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMjI6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgUmVmZXJlbmNlKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2Uubm9vcF93aXRoX3VpbnQ2NChhOiBieXRlcykgLT4gYnl0ZXM6Cm5vb3Bfd2l0aF91aW50NjQ6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozMi0zMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgbm9vcF93aXRoX3VpbnQ2NChzZWxmLCBhOiBhcmM0LlVJbnQ2NCkgLT4gYXJjNC5VSW50ODoKICAgIHByb3RvIDEgMQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MzQKICAgIC8vIHJlc3VsdCA9IDEgKyBhLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICBpbnQgMQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MzUKICAgIC8vIHJldHVybiBhcmM0LlVJbnQ4KHJlc3VsdCkKICAgIGl0b2IKICAgIGV4dHJhY3QgNyAxCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5mdWxsX2FiaV9jb25maWcoYTogYnl0ZXMpIC0+IGJ5dGVzOgpmdWxsX2FiaV9jb25maWc6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTozNy00OQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGFsbG93X2FjdGlvbnM9WwogICAgLy8gICAgICAgICAiTm9PcCIsCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uT3B0SW4sCiAgICAvLyAgICAgICAgICJDbG9zZU91dCIsCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uVXBkYXRlQXBwbGljYXRpb24sCiAgICAvLyAgICAgICAgIE9uQ29tcGxldGVBY3Rpb24uRGVsZXRlQXBwbGljYXRpb24sCiAgICAvLyAgICAgXSwKICAgIC8vICAgICBuYW1lPSJhbGxfdGhlX3RoaW5ncyIsCiAgICAvLyAgICAgY3JlYXRlPSJhbGxvdyIsCiAgICAvLyAgICAgcmVhZG9ubHk9VHJ1ZSwKICAgIC8vICkKICAgIC8vIGRlZiBmdWxsX2FiaV9jb25maWcoc2VsZiwgYTogYXJjNC5VSW50NjQpIC0+IGFyYzQuVUludDg6CiAgICBwcm90byAxIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjUwCiAgICAvLyByZXN1bHQgPSBVSW50NjQoMSkgKyBhLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICBpbnQgMQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NTEKICAgIC8vIHJldHVybiBhcmM0LlVJbnQ4KHJlc3VsdCkKICAgIGl0b2IKICAgIGV4dHJhY3QgNyAxCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5taXhlZF9vY2EoYTogYnl0ZXMpIC0+IGJ5dGVzOgptaXhlZF9vY2E6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo1My02MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGFsbG93X2FjdGlvbnM9WwogICAgLy8gICAgICAgICAiTm9PcCIsCiAgICAvLyAgICAgICAgICJDbG9zZU91dCIsCiAgICAvLyAgICAgICAgICJEZWxldGVBcHBsaWNhdGlvbiIsCiAgICAvLyAgICAgXSwKICAgIC8vICAgICBjcmVhdGU9ImRpc2FsbG93IiwKICAgIC8vICAgICByZWFkb25seT1UcnVlLAogICAgLy8gKQogICAgLy8gZGVmIG1peGVkX29jYShzZWxmLCBhOiBhcmM0LlVJbnQ2NCkgLT4gYXJjNC5VSW50ODoKICAgIHByb3RvIDEgMQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NjMKICAgIC8vIHJlc3VsdCA9IFVJbnQ2NCgxKSArIGEubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIGludCAxCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo2NAogICAgLy8gcmV0dXJuIGFyYzQuVUludDgocmVzdWx0KQogICAgaXRvYgogICAgZXh0cmFjdCA3IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuYWJpX3JvdXRpbmcuY29udHJhY3QuUmVmZXJlbmNlLm9wdF9pbnRvX2Fzc2V0KGFzc2V0OiB1aW50NjQpIC0+IHZvaWQ6Cm9wdF9pbnRvX2Fzc2V0OgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NzktODAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIG9wdF9pbnRvX2Fzc2V0KHNlbGYsIGFzc2V0OiBBc3NldCkgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6ODEtODIKICAgIC8vICMgT25seSBhbGxvdyBhcHAgY3JlYXRvciB0byBvcHQgdGhlIGFwcCBhY2NvdW50IGludG8gYSBBU0EKICAgIC8vIGFzc2VydCBvcC5UeG4uc2VuZGVyID09IG9wLkdsb2JhbC5jcmVhdG9yX2FkZHJlc3MsICJPbmx5IGNyZWF0b3IgY2FuIG9wdCBpbiB0byBBU0EiCiAgICB0eG4gU2VuZGVyCiAgICBnbG9iYWwgQ3JlYXRvckFkZHJlc3MKICAgID09CiAgICBhc3NlcnQgLy8gT25seSBjcmVhdG9yIGNhbiBvcHQgaW4gdG8gQVNBCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo4My04NAogICAgLy8gIyBWZXJpZnkgYSBBU0EgaGFzbid0IGFscmVhZHkgYmVlbiBvcHRlZCBpbnRvCiAgICAvLyBhc3NlcnQgbm90IHNlbGYuYXNhLCAiQVNBIGFscmVhZHkgb3B0ZWQgaW4iCiAgICBpbnQgMAogICAgYnl0ZSAiYXNhIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFzYSBleGlzdHMKICAgICEKICAgIGFzc2VydCAvLyBBU0EgYWxyZWFkeSBvcHRlZCBpbgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6ODUtODYKICAgIC8vICMgU2F2ZSBBU0EgSUQgaW4gZ2xvYmFsIHN0YXRlCiAgICAvLyBzZWxmLmFzYSA9IGFzc2V0CiAgICBieXRlICJhc2EiCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo4OC04OQogICAgLy8gIyBTdWJtaXQgb3B0LWluIHRyYW5zYWN0aW9uOiAwIGFzc2V0IHRyYW5zZmVyIHRvIHNlbGYKICAgIC8vIG9wLklUeG5DcmVhdGUuYmVnaW4oKQogICAgaXR4bl9iZWdpbgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6OTAKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0X3R5cGVfZW51bShUcmFuc2FjdGlvblR5cGUuQXNzZXRUcmFuc2ZlcikKICAgIGludCBheGZlcgogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6OTEKICAgIC8vIG9wLklUeG5DcmVhdGUuc2V0X2ZlZShVSW50NjQoMCkpICAjIGNvdmVyIGZlZSB3aXRoIG91dGVyIHR4bgogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weTo5MgogICAgLy8gb3AuSVR4bkNyZWF0ZS5zZXRfYXNzZXRfcmVjZWl2ZXIob3AuR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcykKICAgIGdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCiAgICBpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjkzCiAgICAvLyBvcC5JVHhuQ3JlYXRlLnNldF94ZmVyX2Fzc2V0KGFzc2V0KQogICAgZnJhbWVfZGlnIC0xCiAgICBpdHhuX2ZpZWxkIFhmZXJBc3NldAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6OTQKICAgIC8vIG9wLklUeG5DcmVhdGUuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS53aXRoX3RyYW5zYWN0aW9ucyhhc3NldDogdWludDY0LCBhbl9pbnQ6IGJ5dGVzLCBwYXk6IHVpbnQ2NCwgYW5vdGhlcl9pbnQ6IGJ5dGVzKSAtPiB2b2lkOgp3aXRoX3RyYW5zYWN0aW9uczoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5Ojk2LTEwMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgd2l0aF90cmFuc2FjdGlvbnMoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBhc3NldDogQXNzZXQsCiAgICAvLyAgICAgYW5faW50OiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBwYXk6IGd0eG4uUGF5bWVudFRyYW5zYWN0aW9uLAogICAgLy8gICAgIGFub3RoZXJfaW50OiBhcmM0LlVJbnQ2NCwKICAgIC8vICkgLT4gTm9uZToKICAgIHByb3RvIDQgMAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTA0CiAgICAvLyBhc3NlcnQgc2VsZi5hc2EgPT0gYXNzZXQsICJpcyBjb3JyZWN0IGFzc2V0IgogICAgaW50IDAKICAgIGJ5dGUgImFzYSIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5hc2EgZXhpc3RzCiAgICBmcmFtZV9kaWcgLTQKICAgID09CiAgICBhc3NlcnQgLy8gaXMgY29ycmVjdCBhc3NldAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTA1CiAgICAvLyBhc3NlcnQgYW5faW50Lm5hdGl2ZSA9PSAxLCAiaXMgY29ycmVjdCBpbnQiCiAgICBmcmFtZV9kaWcgLTMKICAgIGJ0b2kKICAgIGludCAxCiAgICA9PQogICAgYXNzZXJ0IC8vIGlzIGNvcnJlY3QgaW50CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMDYKICAgIC8vIGFzc2VydCBwYXkucmVjZWl2ZXIgPT0gb3AuR2xvYmFsLmN1cnJlbnRfYXBwbGljYXRpb25fYWRkcmVzcywgImlzIHBheW1lbnQgdG8gYXBwIgogICAgZnJhbWVfZGlnIC0yCiAgICBndHhucyBSZWNlaXZlcgogICAgZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKICAgID09CiAgICBhc3NlcnQgLy8gaXMgcGF5bWVudCB0byBhcHAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEwNwogICAgLy8gYXNzZXJ0IGFub3RoZXJfaW50Lm5hdGl2ZSA9PSAyLCAiaXMgY29ycmVjdCBpbnQiCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIGludCAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGlzIGNvcnJlY3QgaW50CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5jb21wYXJlX2Fzc2V0cyhhc3NldF9hOiB1aW50NjQsIGFzc2V0X2I6IHVpbnQ2NCkgLT4gdm9pZDoKY29tcGFyZV9hc3NldHM6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMDktMTEwCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBjb21wYXJlX2Fzc2V0cyhzZWxmLCBhc3NldF9hOiBBc3NldCwgYXNzZXRfYjogQXNzZXQpIC0+IE5vbmU6CiAgICBwcm90byAyIDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExMQogICAgLy8gYXNzZXJ0IGFzc2V0X2EgPT0gYXNzZXRfYiwgImFzc2V0IGEgPT0gYiIKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0xCiAgICA9PQogICAgYXNzZXJ0IC8vIGFzc2V0IGEgPT0gYgogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2UuZ2V0X2FkZHJlc3MoKSAtPiBieXRlczoKZ2V0X2FkZHJlc3M6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMTMtMTE0CiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIC8vIGRlZiBnZXRfYWRkcmVzcyhzZWxmKSAtPiBhcmM0LkFkZHJlc3M6CiAgICBwcm90byAwIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExNQogICAgLy8gcmV0dXJuIGFyYzQuQWRkcmVzcygpCiAgICBnbG9iYWwgWmVyb0FkZHJlc3MKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuYWJpX3JvdXRpbmcuY29udHJhY3QuUmVmZXJlbmNlLmdldF9hc3NldCgpIC0+IGJ5dGVzOgpnZXRfYXNzZXQ6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMTctMTE4CiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSkKICAgIC8vIGRlZiBnZXRfYXNzZXQoc2VsZikgLT4gYXJjNC5VSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjExOQogICAgLy8gcmV0dXJuIGFyYzQuVUludDY0KDQ1NikKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwMWM4CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5nZXRfYXBwKCkgLT4gYnl0ZXM6CmdldF9hcHA6CiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMjEtMTIyCiAgICAvLyBAYXJjNC5hYmltZXRob2QocmVhZG9ubHk9VHJ1ZSwgbmFtZT0iZ2V0X2FwcGxpY2F0aW9uIikKICAgIC8vIGRlZiBnZXRfYXBwKHNlbGYpIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxMjMKICAgIC8vIHJldHVybiBhcmM0LlVJbnQ2NCg0NTYpCiAgICBieXRlIDB4MDAwMDAwMDAwMDAwMDFjOAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2UuZ2V0X2FfaW50KCkgLT4gYnl0ZXM6CmdldF9hX2ludDoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyNS0xMjYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChyZWFkb25seT1UcnVlLCBuYW1lPSJnZXRfYW5faW50IikKICAgIC8vIGRlZiBnZXRfYV9pbnQoc2VsZikgLT4gYXJjNC5VSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjEyNwogICAgLy8gcmV0dXJuIGFyYzQuVUludDY0KDMpCiAgICBieXRlIDB4MDAwMDAwMDAwMDAwMDAwMwogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2UubWV0aG9kX3dpdGhfZGVmYXVsdF9hcmdzKGFzc2V0X2Zyb21fc3RvcmFnZTogdWludDY0LCBhc3NldF9mcm9tX2Z1bmN0aW9uOiB1aW50NjQsIGFjY291bnRfZnJvbV9zdG9yYWdlOiBieXRlcywgYWNjb3VudF9mcm9tX2Z1bmN0aW9uOiBieXRlcywgYXBwbGljYXRpb25fZnJvbV9zdG9yYWdlOiB1aW50NjQsIGFwcGxpY2F0aW9uX2Zyb21fZnVuY3Rpb246IHVpbnQ2NCwgYnl0ZXNfZnJvbV9zdG9yYWdlOiBieXRlcywgaW50X2Zyb21fc3RvcmFnZTogYnl0ZXMsIGludF9mcm9tX2Z1bmN0aW9uOiBieXRlcykgLT4gdm9pZDoKbWV0aG9kX3dpdGhfZGVmYXVsdF9hcmdzOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTI5LTE1MwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKAogICAgLy8gICAgIGRlZmF1bHRfYXJncz17CiAgICAvLyAgICAgICAgICJhc3NldF9mcm9tX3N0b3JhZ2UiOiAiYXNhIiwKICAgIC8vICAgICAgICAgImFzc2V0X2Zyb21fZnVuY3Rpb24iOiBnZXRfYXNzZXQsCiAgICAvLyAgICAgICAgICJhY2NvdW50X2Zyb21fc3RvcmFnZSI6ICJjcmVhdG9yIiwKICAgIC8vICAgICAgICAgImFjY291bnRfZnJvbV9mdW5jdGlvbiI6ICJnZXRfYWRkcmVzcyIsCiAgICAvLyAgICAgICAgICJhcHBsaWNhdGlvbl9mcm9tX3N0b3JhZ2UiOiAiYXBwIiwKICAgIC8vICAgICAgICAgImFwcGxpY2F0aW9uX2Zyb21fZnVuY3Rpb24iOiBnZXRfYXBwLAogICAgLy8gICAgICAgICAiYnl0ZXNfZnJvbV9zdG9yYWdlIjogInNvbWVfYnl0ZXMiLAogICAgLy8gICAgICAgICAiaW50X2Zyb21fc3RvcmFnZSI6ICJhbl9pbnQiLAogICAgLy8gICAgICAgICAiaW50X2Zyb21fZnVuY3Rpb24iOiAiZ2V0X2FfaW50IiwKICAgIC8vICAgICB9CiAgICAvLyApCiAgICAvLyBkZWYgbWV0aG9kX3dpdGhfZGVmYXVsdF9hcmdzKAogICAgLy8gICAgIHNlbGYsCiAgICAvLyAgICAgYXNzZXRfZnJvbV9zdG9yYWdlOiBBc3NldCwKICAgIC8vICAgICBhc3NldF9mcm9tX2Z1bmN0aW9uOiBBc3NldCwKICAgIC8vICAgICBhY2NvdW50X2Zyb21fc3RvcmFnZTogQWNjb3VudCwKICAgIC8vICAgICBhY2NvdW50X2Zyb21fZnVuY3Rpb246IEFjY291bnQsCiAgICAvLyAgICAgYXBwbGljYXRpb25fZnJvbV9zdG9yYWdlOiBBcHBsaWNhdGlvbiwKICAgIC8vICAgICBhcHBsaWNhdGlvbl9mcm9tX2Z1bmN0aW9uOiBBcHBsaWNhdGlvbiwKICAgIC8vICAgICBieXRlc19mcm9tX3N0b3JhZ2U6IEJ5dGVzMywKICAgIC8vICAgICBpbnRfZnJvbV9zdG9yYWdlOiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBpbnRfZnJvbV9mdW5jdGlvbjogYXJjNC5VSW50NjQsCiAgICAvLyApIC0+IE5vbmU6CiAgICBwcm90byA5IDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE1NAogICAgLy8gYXNzZXJ0IGFzc2V0X2Zyb21fc3RvcmFnZSA9PSBBc3NldCgxMjMpLCAid3JvbmcgYXNzZXQgZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC05CiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0IC8vIHdyb25nIGFzc2V0IGZyb20gc3RvcmFnZQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTU1CiAgICAvLyBhc3NlcnQgYXNzZXRfZnJvbV9mdW5jdGlvbiA9PSBBc3NldCg0NTYpLCAid3JvbmcgYXNzZXQgZnJvbSBmdW5jdGlvbiIKICAgIGZyYW1lX2RpZyAtOAogICAgaW50IDQ1NgogICAgPT0KICAgIGFzc2VydCAvLyB3cm9uZyBhc3NldCBmcm9tIGZ1bmN0aW9uCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNTYKICAgIC8vIGFzc2VydCBhY2NvdW50X2Zyb21fc3RvcmFnZSA9PSBvcC5HbG9iYWwuY3JlYXRvcl9hZGRyZXNzLCAid3JvbmcgYWNjb3VudCBmcm9tIHN0b3JhZ2UiCiAgICBmcmFtZV9kaWcgLTcKICAgIGdsb2JhbCBDcmVhdG9yQWRkcmVzcwogICAgPT0KICAgIGFzc2VydCAvLyB3cm9uZyBhY2NvdW50IGZyb20gc3RvcmFnZQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTU3CiAgICAvLyBhc3NlcnQgYWNjb3VudF9mcm9tX2Z1bmN0aW9uID09IG9wLkdsb2JhbC56ZXJvX2FkZHJlc3MsICJ3cm9uZyBhY2NvdW50IGZyb20gZnVuY3Rpb24iCiAgICBmcmFtZV9kaWcgLTYKICAgIGdsb2JhbCBaZXJvQWRkcmVzcwogICAgPT0KICAgIGFzc2VydCAvLyB3cm9uZyBhY2NvdW50IGZyb20gZnVuY3Rpb24KICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE1OAogICAgLy8gYXNzZXJ0IGFwcGxpY2F0aW9uX2Zyb21fc3RvcmFnZSA9PSBBcHBsaWNhdGlvbigxMjMpLCAid3JvbmcgYXBwbGljYXRpb24gZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC01CiAgICBpbnQgMTIzCiAgICA9PQogICAgYXNzZXJ0IC8vIHdyb25nIGFwcGxpY2F0aW9uIGZyb20gc3RvcmFnZQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTU5CiAgICAvLyBhc3NlcnQgYXBwbGljYXRpb25fZnJvbV9mdW5jdGlvbiA9PSBBcHBsaWNhdGlvbig0NTYpLCAid3JvbmcgYXBwbGljYXRpb24gZnJvbSBmdW5jdGlvbiIKICAgIGZyYW1lX2RpZyAtNAogICAgaW50IDQ1NgogICAgPT0KICAgIGFzc2VydCAvLyB3cm9uZyBhcHBsaWNhdGlvbiBmcm9tIGZ1bmN0aW9uCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjAKICAgIC8vIGFzc2VydCBieXRlc19mcm9tX3N0b3JhZ2VbMF0gPT0gYXJjNC5CeXRlKDcpLCAid3JvbmcgMHRoIGJ5dGUgZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC0zCiAgICBleHRyYWN0IDAgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwNwogICAgYj09CiAgICBhc3NlcnQgLy8gd3JvbmcgMHRoIGJ5dGUgZnJvbSBzdG9yYWdlCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjEKICAgIC8vIGFzc2VydCBieXRlc19mcm9tX3N0b3JhZ2VbMV0gPT0gYXJjNC5CeXRlKDgpLCAid3JvbmcgMXN0IGJ5dGUgZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC0zCiAgICBleHRyYWN0IDEgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwOAogICAgYj09CiAgICBhc3NlcnQgLy8gd3JvbmcgMXN0IGJ5dGUgZnJvbSBzdG9yYWdlCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjIKICAgIC8vIGFzc2VydCBieXRlc19mcm9tX3N0b3JhZ2VbMl0gPT0gYXJjNC5CeXRlKDkpLCAid3JvbmcgMm5kIGJ5dGUgZnJvbSBzdG9yYWdlIgogICAgZnJhbWVfZGlnIC0zCiAgICBleHRyYWN0IDIgMSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGJ5dGUgMHgwOQogICAgYj09CiAgICBhc3NlcnQgLy8gd3JvbmcgMm5kIGJ5dGUgZnJvbSBzdG9yYWdlCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxNjMKICAgIC8vIGFzc2VydCBpbnRfZnJvbV9zdG9yYWdlLm5hdGl2ZSA9PSAyLCAid3JvbmcgaW50IGZyb20gc3RvcmFnZSIKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgaW50IDIKICAgID09CiAgICBhc3NlcnQgLy8gd3JvbmcgaW50IGZyb20gc3RvcmFnZQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTY0CiAgICAvLyBhc3NlcnQgaW50X2Zyb21fZnVuY3Rpb24ubmF0aXZlID09IDMsICJ3cm9uZyBpbnQgZnJvbSBmdW5jdGlvbiIKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgaW50IDMKICAgID09CiAgICBhc3NlcnQgLy8gd3JvbmcgaW50IGZyb20gZnVuY3Rpb24KICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuYWJpX3JvdXRpbmcuY29udHJhY3QuUmVmZXJlbmNlLm1ldGhvZF93aXRoXzE1X2FyZ3Mob25lOiB1aW50NjQsIHR3bzogdWludDY0LCB0aHJlZTogdWludDY0LCBmb3VyOiB1aW50NjQsIGZpdmU6IHVpbnQ2NCwgc2l4OiB1aW50NjQsIHNldmVuOiB1aW50NjQsIGVpZ2h0OiB1aW50NjQsIG5pbmU6IHVpbnQ2NCwgdGVuOiB1aW50NjQsIGVsZXZlbjogdWludDY0LCB0d2VsdmU6IHVpbnQ2NCwgdGhpcnRlZW46IHVpbnQ2NCwgZm91cnRlZW46IHVpbnQ2NCwgZmlmdGVlbjogYnl0ZXMpIC0+IGJ5dGVzOgptZXRob2Rfd2l0aF8xNV9hcmdzOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTY2LTE4NAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgbWV0aG9kX3dpdGhfMTVfYXJncygKICAgIC8vICAgICBzZWxmLAogICAgLy8gICAgIG9uZTogVUludDY0LAogICAgLy8gICAgIHR3bzogVUludDY0LAogICAgLy8gICAgIHRocmVlOiBVSW50NjQsCiAgICAvLyAgICAgZm91cjogVUludDY0LAogICAgLy8gICAgIGZpdmU6IFVJbnQ2NCwKICAgIC8vICAgICBzaXg6IFVJbnQ2NCwKICAgIC8vICAgICBzZXZlbjogVUludDY0LAogICAgLy8gICAgIGVpZ2h0OiBVSW50NjQsCiAgICAvLyAgICAgbmluZTogVUludDY0LAogICAgLy8gICAgIHRlbjogVUludDY0LAogICAgLy8gICAgIGVsZXZlbjogVUludDY0LAogICAgLy8gICAgIHR3ZWx2ZTogVUludDY0LAogICAgLy8gICAgIHRoaXJ0ZWVuOiBVSW50NjQsCiAgICAvLyAgICAgZm91cnRlZW46IFVJbnQ2NCwKICAgIC8vICAgICBmaWZ0ZWVuOiBCeXRlcywKICAgIC8vICkgLT4gQnl0ZXM6CiAgICBwcm90byAxNSAxCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTg4CiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICBmcmFtZV9kaWcgLTE1CiAgICBmcmFtZV9kaWcgLTE0CiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTg5CiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICAvLyArIHRocmVlCiAgICBmcmFtZV9kaWcgLTEzCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTkwCiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICAvLyArIHRocmVlCiAgICAvLyArIGZvdXIKICAgIGZyYW1lX2RpZyAtMTIKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE4Ny0xOTEKICAgIC8vIG9uZQogICAgLy8gKyB0d28KICAgIC8vICsgdGhyZWUKICAgIC8vICsgZm91cgogICAgLy8gKyBmaXZlCiAgICBmcmFtZV9kaWcgLTExCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTkyCiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICAvLyArIHRocmVlCiAgICAvLyArIGZvdXIKICAgIC8vICsgZml2ZQogICAgLy8gKyBzaXgKICAgIGZyYW1lX2RpZyAtMTAKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE4Ny0xOTMKICAgIC8vIG9uZQogICAgLy8gKyB0d28KICAgIC8vICsgdGhyZWUKICAgIC8vICsgZm91cgogICAgLy8gKyBmaXZlCiAgICAvLyArIHNpeAogICAgLy8gKyBzZXZlbgogICAgZnJhbWVfZGlnIC05CiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToxODctMTk0CiAgICAvLyBvbmUKICAgIC8vICsgdHdvCiAgICAvLyArIHRocmVlCiAgICAvLyArIGZvdXIKICAgIC8vICsgZml2ZQogICAgLy8gKyBzaXgKICAgIC8vICsgc2V2ZW4KICAgIC8vICsgZWlnaHQKICAgIGZyYW1lX2RpZyAtOAogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTE5NQogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIGZyYW1lX2RpZyAtNwogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTE5NgogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIC8vICsgdGVuCiAgICBmcmFtZV9kaWcgLTYKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjE4Ny0xOTcKICAgIC8vIG9uZQogICAgLy8gKyB0d28KICAgIC8vICsgdGhyZWUKICAgIC8vICsgZm91cgogICAgLy8gKyBmaXZlCiAgICAvLyArIHNpeAogICAgLy8gKyBzZXZlbgogICAgLy8gKyBlaWdodAogICAgLy8gKyBuaW5lCiAgICAvLyArIHRlbgogICAgLy8gKyBlbGV2ZW4KICAgIGZyYW1lX2RpZyAtNQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTE5OAogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIC8vICsgdGVuCiAgICAvLyArIGVsZXZlbgogICAgLy8gKyB0d2VsdmUKICAgIGZyYW1lX2RpZyAtNAogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTE5OQogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIC8vICsgdGVuCiAgICAvLyArIGVsZXZlbgogICAgLy8gKyB0d2VsdmUKICAgIC8vICsgdGhpcnRlZW4KICAgIGZyYW1lX2RpZyAtMwogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg3LTIwMAogICAgLy8gb25lCiAgICAvLyArIHR3bwogICAgLy8gKyB0aHJlZQogICAgLy8gKyBmb3VyCiAgICAvLyArIGZpdmUKICAgIC8vICsgc2l4CiAgICAvLyArIHNldmVuCiAgICAvLyArIGVpZ2h0CiAgICAvLyArIG5pbmUKICAgIC8vICsgdGVuCiAgICAvLyArIGVsZXZlbgogICAgLy8gKyB0d2VsdmUKICAgIC8vICsgdGhpcnRlZW4KICAgIC8vICsgZm91cnRlZW4KICAgIGZyYW1lX2RpZyAtMgogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MTg2LTIwMQogICAgLy8gYXNzZXJ0ICgKICAgIC8vICAgICBvbmUKICAgIC8vICAgICArIHR3bwogICAgLy8gICAgICsgdGhyZWUKICAgIC8vICAgICArIGZvdXIKICAgIC8vICAgICArIGZpdmUKICAgIC8vICAgICArIHNpeAogICAgLy8gICAgICsgc2V2ZW4KICAgIC8vICAgICArIGVpZ2h0CiAgICAvLyAgICAgKyBuaW5lCiAgICAvLyAgICAgKyB0ZW4KICAgIC8vICAgICArIGVsZXZlbgogICAgLy8gICAgICsgdHdlbHZlCiAgICAvLyAgICAgKyB0aGlydGVlbgogICAgLy8gICAgICsgZm91cnRlZW4KICAgIC8vICkKICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjAyCiAgICAvLyByZXR1cm4gZmlmdGVlbgogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5tZXRob2Rfd2l0aF9tb3JlX3RoYW5fMTVfYXJncyhhOiBieXRlcywgYjogYnl0ZXMsIGM6IGJ5dGVzLCBkOiB1aW50NjQsIGFzc2V0OiB1aW50NjQsIGU6IGJ5dGVzLCBmOiBieXRlcywgcGF5OiB1aW50NjQsIGc6IGJ5dGVzLCBoOiBieXRlcywgaTogYnl0ZXMsIGo6IGJ5dGVzLCBrOiBieXRlcywgbDogYnl0ZXMsIG06IGJ5dGVzLCBuOiBieXRlcywgbzogYnl0ZXMsIHA6IHVpbnQ2NCwgcTogYnl0ZXMsIHI6IGJ5dGVzLCBzOiBieXRlcywgdDogYnl0ZXMsIGFzc2V0MjogdWludDY0LCBwYXkyOiB1aW50NjQsIHU6IGJ5dGVzLCB2OiBieXRlcykgLT4gYnl0ZXM6Cm1ldGhvZF93aXRoX21vcmVfdGhhbl8xNV9hcmdzOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjA0LTIzNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgbWV0aG9kX3dpdGhfbW9yZV90aGFuXzE1X2FyZ3MoCiAgICAvLyAgICAgc2VsZiwKICAgIC8vICAgICBhOiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBiOiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBjOiBhcmM0LlVJbnQ2NCwKICAgIC8vICAgICBkOiBVSW50NjQsCiAgICAvLyAgICAgYXNzZXQ6IEFzc2V0LAogICAgLy8gICAgIGU6IGFyYzQuVUludDY0LAogICAgLy8gICAgIGY6IGFyYzQuVUludDY0LAogICAgLy8gICAgIHBheTogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24sCiAgICAvLyAgICAgZzogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgaDogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgaTogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgajogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgazogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgIyBydWZmOiBub3FhOiBFNzQxCiAgICAvLyAgICAgbDogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgbTogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgbjogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgbzogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgcDogVUludDY0LAogICAgLy8gICAgIHE6IGFyYzQuVUludDY0LAogICAgLy8gICAgIHI6IGFyYzQuVUludDY0LAogICAgLy8gICAgIHM6IEJ5dGVzLAogICAgLy8gICAgIHQ6IEJ5dGVzLAogICAgLy8gICAgIGFzc2V0MjogQXNzZXQsCiAgICAvLyAgICAgcGF5MjogZ3R4bi5QYXltZW50VHJhbnNhY3Rpb24sCiAgICAvLyAgICAgdTogYXJjNC5VSW50NjQsCiAgICAvLyAgICAgdjogYXJjNC5VSW50NjQsCiAgICAvLyApIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMjYgMQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjM5CiAgICAvLyBhc3NlcnQgb3AuVHhuLm51bV9hcHBfYXJncyA9PSAxNgogICAgdHhuIE51bUFwcEFyZ3MKICAgIGludCAxNgogICAgPT0KICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQwCiAgICAvLyBhc3NlcnQgcGF5LmFtb3VudCA9PSAxMDAwMDAKICAgIGZyYW1lX2RpZyAtMTkKICAgIGd0eG5zIEFtb3VudAogICAgaW50IDEwMDAwMAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQxCiAgICAvLyBhc3NlcnQgcGF5Mi5hbW91bnQgPT0gMjAwMDAwCiAgICBmcmFtZV9kaWcgLTMKICAgIGd0eG5zIEFtb3VudAogICAgaW50IDIwMDAwMAogICAgPT0KICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQyCiAgICAvLyBhc3NlcnQgYXNzZXQuaWQKICAgIGZyYW1lX2RpZyAtMjIKICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQzCiAgICAvLyBhc3NlcnQgYXNzZXQyLmlkCiAgICBmcmFtZV9kaWcgLTQKICAgIGFzc2VydAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ1CiAgICAvLyBsb2cocyArIHQpCiAgICBmcmFtZV9kaWcgLTYKICAgIGZyYW1lX2RpZyAtNQogICAgY29uY2F0CiAgICBsb2cKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OAogICAgLy8gYS5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMjYKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OQogICAgLy8gKyBiLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0yNQogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI0OQogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI1MAogICAgLy8gKyBjLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0yNAogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI1MAogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNTEKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIGZyYW1lX2RpZyAtMjMKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI1MgogICAgLy8gKyBlLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0yMQogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI1MgogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgIC8vICsgZAogICAgLy8gKyBlLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjUzCiAgICAvLyArIGYubmF0aXZlCiAgICBmcmFtZV9kaWcgLTIwCiAgICBidG9pCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjUzCiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNTQKICAgIC8vICsgZy5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMTgKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNTQKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI1NQogICAgLy8gKyBoLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xNwogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI1NQogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgIC8vICsgZAogICAgLy8gKyBlLm5hdGl2ZQogICAgLy8gKyBmLm5hdGl2ZQogICAgLy8gKyBnLm5hdGl2ZQogICAgLy8gKyBoLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjU2CiAgICAvLyArIGkubmF0aXZlCiAgICBmcmFtZV9kaWcgLTE2CiAgICBidG9pCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjU2CiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICAvLyArIGcubmF0aXZlCiAgICAvLyArIGgubmF0aXZlCiAgICAvLyArIGkubmF0aXZlCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNTcKICAgIC8vICsgai5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMTUKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNTcKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI1OAogICAgLy8gKyBrLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xNAogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI1OAogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgIC8vICsgZAogICAgLy8gKyBlLm5hdGl2ZQogICAgLy8gKyBmLm5hdGl2ZQogICAgLy8gKyBnLm5hdGl2ZQogICAgLy8gKyBoLm5hdGl2ZQogICAgLy8gKyBpLm5hdGl2ZQogICAgLy8gKyBqLm5hdGl2ZQogICAgLy8gKyBrLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjU5CiAgICAvLyArIGwubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEzCiAgICBidG9pCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjU5CiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICAvLyArIGcubmF0aXZlCiAgICAvLyArIGgubmF0aXZlCiAgICAvLyArIGkubmF0aXZlCiAgICAvLyArIGoubmF0aXZlCiAgICAvLyArIGsubmF0aXZlCiAgICAvLyArIGwubmF0aXZlCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNjAKICAgIC8vICsgbS5uYXRpdmUKICAgIGZyYW1lX2RpZyAtMTIKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjAKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgICsKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI2MQogICAgLy8gKyBuLm5hdGl2ZQogICAgZnJhbWVfZGlnIC0xMQogICAgYnRvaQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ4LTI2MQogICAgLy8gYS5uYXRpdmUKICAgIC8vICsgYi5uYXRpdmUKICAgIC8vICsgYy5uYXRpdmUKICAgIC8vICsgZAogICAgLy8gKyBlLm5hdGl2ZQogICAgLy8gKyBmLm5hdGl2ZQogICAgLy8gKyBnLm5hdGl2ZQogICAgLy8gKyBoLm5hdGl2ZQogICAgLy8gKyBpLm5hdGl2ZQogICAgLy8gKyBqLm5hdGl2ZQogICAgLy8gKyBrLm5hdGl2ZQogICAgLy8gKyBsLm5hdGl2ZQogICAgLy8gKyBtLm5hdGl2ZQogICAgLy8gKyBuLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjYyCiAgICAvLyArIG8ubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEwCiAgICBidG9pCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjYyCiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICAvLyArIGcubmF0aXZlCiAgICAvLyArIGgubmF0aXZlCiAgICAvLyArIGkubmF0aXZlCiAgICAvLyArIGoubmF0aXZlCiAgICAvLyArIGsubmF0aXZlCiAgICAvLyArIGwubmF0aXZlCiAgICAvLyArIG0ubmF0aXZlCiAgICAvLyArIG4ubmF0aXZlCiAgICAvLyArIG8ubmF0aXZlCiAgICArCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNDgtMjYzCiAgICAvLyBhLm5hdGl2ZQogICAgLy8gKyBiLm5hdGl2ZQogICAgLy8gKyBjLm5hdGl2ZQogICAgLy8gKyBkCiAgICAvLyArIGUubmF0aXZlCiAgICAvLyArIGYubmF0aXZlCiAgICAvLyArIGcubmF0aXZlCiAgICAvLyArIGgubmF0aXZlCiAgICAvLyArIGkubmF0aXZlCiAgICAvLyArIGoubmF0aXZlCiAgICAvLyArIGsubmF0aXZlCiAgICAvLyArIGwubmF0aXZlCiAgICAvLyArIG0ubmF0aXZlCiAgICAvLyArIG4ubmF0aXZlCiAgICAvLyArIG8ubmF0aXZlCiAgICAvLyArIHAKICAgIGZyYW1lX2RpZyAtOQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjY0CiAgICAvLyArIHEubmF0aXZlCiAgICBmcmFtZV9kaWcgLTgKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjQKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgIC8vICsgbi5uYXRpdmUKICAgIC8vICsgby5uYXRpdmUKICAgIC8vICsgcAogICAgLy8gKyBxLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjY1CiAgICAvLyArIHIubmF0aXZlCiAgICBmcmFtZV9kaWcgLTcKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjUKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgIC8vICsgbi5uYXRpdmUKICAgIC8vICsgby5uYXRpdmUKICAgIC8vICsgcAogICAgLy8gKyBxLm5hdGl2ZQogICAgLy8gKyByLm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjY2CiAgICAvLyArIHUubmF0aXZlCiAgICBmcmFtZV9kaWcgLTIKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjYKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgIC8vICsgbi5uYXRpdmUKICAgIC8vICsgby5uYXRpdmUKICAgIC8vICsgcAogICAgLy8gKyBxLm5hdGl2ZQogICAgLy8gKyByLm5hdGl2ZQogICAgLy8gKyB1Lm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjY3CiAgICAvLyArIHYubmF0aXZlCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI0OC0yNjcKICAgIC8vIGEubmF0aXZlCiAgICAvLyArIGIubmF0aXZlCiAgICAvLyArIGMubmF0aXZlCiAgICAvLyArIGQKICAgIC8vICsgZS5uYXRpdmUKICAgIC8vICsgZi5uYXRpdmUKICAgIC8vICsgZy5uYXRpdmUKICAgIC8vICsgaC5uYXRpdmUKICAgIC8vICsgaS5uYXRpdmUKICAgIC8vICsgai5uYXRpdmUKICAgIC8vICsgay5uYXRpdmUKICAgIC8vICsgbC5uYXRpdmUKICAgIC8vICsgbS5uYXRpdmUKICAgIC8vICsgbi5uYXRpdmUKICAgIC8vICsgby5uYXRpdmUKICAgIC8vICsgcAogICAgLy8gKyBxLm5hdGl2ZQogICAgLy8gKyByLm5hdGl2ZQogICAgLy8gKyB1Lm5hdGl2ZQogICAgLy8gKyB2Lm5hdGl2ZQogICAgKwogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjQ3LTI2OAogICAgLy8gcmV0dXJuIGFyYzQuVUludDY0KAogICAgLy8gICAgIGEubmF0aXZlCiAgICAvLyAgICAgKyBiLm5hdGl2ZQogICAgLy8gICAgICsgYy5uYXRpdmUKICAgIC8vICAgICArIGQKICAgIC8vICAgICArIGUubmF0aXZlCiAgICAvLyAgICAgKyBmLm5hdGl2ZQogICAgLy8gICAgICsgZy5uYXRpdmUKICAgIC8vICAgICArIGgubmF0aXZlCiAgICAvLyAgICAgKyBpLm5hdGl2ZQogICAgLy8gICAgICsgai5uYXRpdmUKICAgIC8vICAgICArIGsubmF0aXZlCiAgICAvLyAgICAgKyBsLm5hdGl2ZQogICAgLy8gICAgICsgbS5uYXRpdmUKICAgIC8vICAgICArIG4ubmF0aXZlCiAgICAvLyAgICAgKyBvLm5hdGl2ZQogICAgLy8gICAgICsgcAogICAgLy8gICAgICsgcS5uYXRpdmUKICAgIC8vICAgICArIHIubmF0aXZlCiAgICAvLyAgICAgKyB1Lm5hdGl2ZQogICAgLy8gICAgICsgdi5uYXRpdmUKICAgIC8vICkKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuYWJpX3JvdXRpbmcuY29udHJhY3QuUmVmZXJlbmNlLmhlbGxvX3dpdGhfYWxnb3B5X3N0cmluZyhuYW1lOiBieXRlcykgLT4gYnl0ZXM6CmhlbGxvX3dpdGhfYWxnb3B5X3N0cmluZzoKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI3MC0yNzEKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgLy8gZGVmIGhlbGxvX3dpdGhfYWxnb3B5X3N0cmluZyhzZWxmLCBuYW1lOiBTdHJpbmcpIC0+IFN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjcyCiAgICAvLyByZXR1cm4gIkhlbGxvICIgKyBuYW1lICsgIiEiCiAgICBieXRlICJIZWxsbyAiCiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgYnl0ZSAiISIKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5hYmlfcm91dGluZy5jb250cmFjdC5SZWZlcmVuY2UuYmFyZV9hYmlfY29uZmlnKCkgLT4gdm9pZDoKYmFyZV9hYmlfY29uZmlnOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6NjYtNzYKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoCiAgICAvLyAgICAgYWxsb3dfYWN0aW9ucz1bCiAgICAvLyAgICAgICAgICJOb09wIiwKICAgIC8vICAgICAgICAgIk9wdEluIiwKICAgIC8vICAgICAgICAgIkNsb3NlT3V0IiwKICAgIC8vICAgICAgICAgIlVwZGF0ZUFwcGxpY2F0aW9uIiwKICAgIC8vICAgICAgICAgIkRlbGV0ZUFwcGxpY2F0aW9uIiwKICAgIC8vICAgICBdLAogICAgLy8gICAgIGNyZWF0ZT0icmVxdWlyZSIsCiAgICAvLyApCiAgICAvLyBkZWYgYmFyZV9hYmlfY29uZmlnKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5Ojc3CiAgICAvLyBsb2coIkhlbGxvIFdvcmxkIikKICAgIGJ5dGUgIkhlbGxvIFdvcmxkIgogICAgbG9nCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjMKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBhYmlfcm91dGluZy9jb250cmFjdC5weToyNAogICAgLy8gc2VsZi5hc2EgPSBBc3NldCgxMjMpCiAgICBieXRlICJhc2EiCiAgICBpbnQgMTIzCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjUKICAgIC8vIHNlbGYuYW5faW50ID0gVUludDY0KDIpCiAgICBieXRlICJhbl9pbnQiCiAgICBpbnQgMgogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjI2CiAgICAvLyBzZWxmLnNvbWVfYnl0ZXMgPSBCeXRlczMoYXJjNC5CeXRlKDcpLCBhcmM0LkJ5dGUoOCksIGFyYzQuQnl0ZSg5KSkKICAgIGJ5dGUgInNvbWVfYnl0ZXMiCiAgICBieXRlIDB4MDcwODA5CiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjcKICAgIC8vIHNlbGYuY3JlYXRvciA9IG9wLlR4bi5zZW5kZXIKICAgIGJ5dGUgImNyZWF0b3IiCiAgICB0eG4gU2VuZGVyCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gYWJpX3JvdXRpbmcvY29udHJhY3QucHk6MjgKICAgIC8vIHNlbGYuYXBwID0gQXBwbGljYXRpb24oMTIzKQogICAgYnl0ZSAiYXBwIgogICAgaW50IDEyMwogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGFiaV9yb3V0aW5nL2NvbnRyYWN0LnB5OjMwCiAgICAvLyBhc3NlcnQgYXJjNC5hcmM0X3NpZ25hdHVyZSgiZ2V0KHVpbnQ2NCxieXRlW10pYnl0ZVtdIiksICJoYXMgbWV0aG9kIHNlbGVjdG9yIgogICAgbWV0aG9kICJnZXQodWludDY0LGJ5dGVbXSlieXRlW10iCiAgICBsZW4KICAgIGFzc2VydCAvLyBoYXMgbWV0aG9kIHNlbGVjdG9yCiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmFiaV9yb3V0aW5nLmNvbnRyYWN0LlJlZmVyZW5jZS5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/test_cases/abi_routing/out_unoptimized/Reference.approval.teal b/test_cases/abi_routing/out_unoptimized/Reference.approval.teal index ae90824b17..10e03e3e09 100644 --- a/test_cases/abi_routing/out_unoptimized/Reference.approval.teal +++ b/test_cases/abi_routing/out_unoptimized/Reference.approval.teal @@ -762,22 +762,15 @@ opt_into_asset: // # Verify a ASA hasn't already been opted into // assert not self.asa, "ASA already opted in" int 0 - // abi_routing/contract.py:24 - // self.asa = Asset(123) byte "asa" - // abi_routing/contract.py:83-84 - // # Verify a ASA hasn't already been opted into - // assert not self.asa, "ASA already opted in" app_global_get_ex assert // check self.asa exists ! assert // ASA already opted in - // abi_routing/contract.py:24 - // self.asa = Asset(123) - byte "asa" // abi_routing/contract.py:85-86 // # Save ASA ID in global state // self.asa = asset + byte "asa" frame_dig -1 app_global_put // abi_routing/contract.py:88-89 @@ -821,11 +814,7 @@ with_transactions: // abi_routing/contract.py:104 // assert self.asa == asset, "is correct asset" int 0 - // abi_routing/contract.py:24 - // self.asa = Asset(123) byte "asa" - // abi_routing/contract.py:104 - // assert self.asa == asset, "is correct asset" app_global_get_ex assert // check self.asa exists frame_dig -4 diff --git a/test_cases/asset/out/Reference.approval.mir b/test_cases/asset/out/Reference.approval.mir index 390817a55c..a5fa1f0687 100644 --- a/test_cases/asset/out/Reference.approval.mir +++ b/test_cases/asset/out/Reference.approval.mir @@ -79,7 +79,7 @@ opt_into_asset_block@0: // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) asset#0 | tmp%2#0 # Only allow app creator to opt the app account into a ASA\nassert Txn.sender == Global.creator_a... asset/contract.py:37-38 assert // Only creator can opt in to ASA // (𝕡) asset#0 | # Only allow app creator to opt the app account into a ASA\nassert Txn.sender == Global.creator_a... asset/contract.py:37-38 int 0 // (𝕡) asset#0 | 0 ASA hasn't already been opted into\nassert not self.asa asset/contract.py:39-40 - byte "asa" // (𝕡) asset#0 | 0,"asa" self.asa asset/contract.py:18 + byte "asa" // (𝕡) asset#0 | 0,"asa" ASA hasn't already been opted into\nassert not self.asa asset/contract.py:39-40 app_global_get_ex // (𝕡) asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 ASA hasn't already been opted into\nassert not self.asa asset/contract.py:39-40 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) asset#0 | maybe_exists%0#0,{app_global_get_ex}.0 ASA hasn't already been opted into\nassert not self.asa asset/contract.py:39-40 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%0#0,maybe_exists%0#0 ASA hasn't already been opted into\nassert not self.asa asset/contract.py:39-40 @@ -90,7 +90,7 @@ opt_into_asset_block@0: // virtual: store tmp%3#0 to l-stack (no copy) (𝕡) asset#0 | tmp%3#0 y a ASA hasn't already been opted into\nassert not self.asa asset/contract.py:39-40 // virtual: load tmp%3#0 from l-stack (no copy) (𝕡) asset#0 | tmp%3#0 # Verify a ASA hasn't already been opted into\nassert not self.asa, "ASA already opted in" asset/contract.py:39-40 assert // ASA already opted in // (𝕡) asset#0 | # Verify a ASA hasn't already been opted into\nassert not self.asa, "ASA already opted in" asset/contract.py:39-40 - byte "asa" // (𝕡) asset#0 | "asa" self.asa asset/contract.py:18 + byte "asa" // (𝕡) asset#0 | "asa" # Save ASA ID in global state\nself.asa asset/contract.py:41-42 frame_dig -1 // load asset#0 from parameters (𝕡) asset#0 | "asa",asset#0 # Save ASA ID in global state\nself.asa = asset asset/contract.py:41-42 app_global_put // (𝕡) asset#0 | # Save ASA ID in global state\nself.asa = asset asset/contract.py:41-42 itxn_begin // (𝕡) asset#0 | # Submit opt-in transaction: 0 asset transfer to self\nITxnCreate.begin() asset/contract.py:44-45 @@ -114,7 +114,7 @@ is_opted_asset: is_opted_asset_block@0: int 0 // (𝕡) asset#0 | 0 self.asa asset/contract.py:54 - byte "asa" // (𝕡) asset#0 | 0,"asa" self.asa asset/contract.py:18 + byte "asa" // (𝕡) asset#0 | 0,"asa" self.asa asset/contract.py:54 app_global_get_ex // (𝕡) asset#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.asa asset/contract.py:54 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) asset#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.asa asset/contract.py:54 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) asset#0 | maybe_value%0#0,maybe_exists%0#0 self.asa asset/contract.py:54 diff --git a/test_cases/asset/out/Reference.approval.teal b/test_cases/asset/out/Reference.approval.teal index 4c7aa03f41..275830dbc6 100644 --- a/test_cases/asset/out/Reference.approval.teal +++ b/test_cases/asset/out/Reference.approval.teal @@ -64,22 +64,15 @@ opt_into_asset: // # Verify a ASA hasn't already been opted into // assert not self.asa, "ASA already opted in" int 0 - // asset/contract.py:18 - // self.asa = Asset() byte "asa" - // asset/contract.py:39-40 - // # Verify a ASA hasn't already been opted into - // assert not self.asa, "ASA already opted in" app_global_get_ex assert // check self.asa exists ! assert // ASA already opted in - // asset/contract.py:18 - // self.asa = Asset() - byte "asa" // asset/contract.py:41-42 // # Save ASA ID in global state // self.asa = asset + byte "asa" frame_dig -1 app_global_put // asset/contract.py:44-45 @@ -117,11 +110,7 @@ is_opted_asset: // asset/contract.py:54 // assert self.asa == asset, "asset self.asa == asset" int 0 - // asset/contract.py:18 - // self.asa = Asset() byte "asa" - // asset/contract.py:54 - // assert self.asa == asset, "asset self.asa == asset" app_global_get_ex assert // check self.asa exists frame_dig -1 diff --git a/test_cases/asset/out_unoptimized/Reference.approval.teal b/test_cases/asset/out_unoptimized/Reference.approval.teal index 4fb7cfea02..1622d6466b 100644 --- a/test_cases/asset/out_unoptimized/Reference.approval.teal +++ b/test_cases/asset/out_unoptimized/Reference.approval.teal @@ -74,22 +74,15 @@ opt_into_asset: // # Verify a ASA hasn't already been opted into // assert not self.asa, "ASA already opted in" int 0 - // asset/contract.py:18 - // self.asa = Asset() byte "asa" - // asset/contract.py:39-40 - // # Verify a ASA hasn't already been opted into - // assert not self.asa, "ASA already opted in" app_global_get_ex assert // check self.asa exists ! assert // ASA already opted in - // asset/contract.py:18 - // self.asa = Asset() - byte "asa" // asset/contract.py:41-42 // # Save ASA ID in global state // self.asa = asset + byte "asa" frame_dig -1 app_global_put // asset/contract.py:44-45 @@ -127,11 +120,7 @@ is_opted_asset: // asset/contract.py:54 // assert self.asa == asset, "asset self.asa == asset" int 0 - // asset/contract.py:18 - // self.asa = Asset() byte "asa" - // asset/contract.py:54 - // assert self.asa == asset, "asset self.asa == asset" app_global_get_ex assert // check self.asa exists frame_dig -1 diff --git a/test_cases/augmented_assignment/out/Augmented.approval.mir b/test_cases/augmented_assignment/out/Augmented.approval.mir index 068f06d7fe..1d3c6d1ab1 100644 --- a/test_cases/augmented_assignment/out/Augmented.approval.mir +++ b/test_cases/augmented_assignment/out/Augmented.approval.mir @@ -33,11 +33,11 @@ main_entrypoint@2: main_if_body@3: dup // load me#0 from f-stack (𝕗) me#0 | me#0 self.my_uint[me] = UInt64(0) augmented_assignment/contract.py:23 dup // store me#0 to l-stack (copy) (𝕗) me#0 | me#0,me#0 self.my_uint[me] = UInt64(0) augmented_assignment/contract.py:23 - byte "my_uint" // (𝕗) me#0 | me#0,me#0,"my_uint" self.my_uint augmented_assignment/contract.py:14 + byte "my_uint" // (𝕗) me#0 | me#0,me#0,"my_uint" self.my_uint augmented_assignment/contract.py:23 int 0 // (𝕗) me#0 | me#0,me#0,"my_uint",0 UInt64(0) augmented_assignment/contract.py:23 app_local_put // (𝕗) me#0 | me#0 self.my_uint[me] = UInt64(0) augmented_assignment/contract.py:23 // virtual: load me#0 from l-stack (no copy) (𝕗) me#0 | me#0 self.my_bytes[me] = Bytes(b"") augmented_assignment/contract.py:24 - byte "my_bytes" // (𝕗) me#0 | me#0,"my_bytes" self.my_bytes augmented_assignment/contract.py:15 + byte "my_bytes" // (𝕗) me#0 | me#0,"my_bytes" self.my_bytes augmented_assignment/contract.py:24 byte 0x // (𝕗) me#0 | me#0,"my_bytes",0x Bytes(b"") augmented_assignment/contract.py:24 app_local_put // (𝕗) me#0 | self.my_bytes[me] = Bytes(b"") augmented_assignment/contract.py:24 // Implicit fall through to main_after_if_else@4 // (𝕗) me#0 | @@ -59,7 +59,7 @@ main_if_body@5: dup cover 2 // store me#0 to l-stack (copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] augmented_assignment/contract.py:30-32 int 0 // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0,0 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] augmented_assignment/contract.py:30-32 - byte "my_uint" // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0,0,"my_uint" self.my_uint augmented_assignment/contract.py:14 + byte "my_uint" // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0,0,"my_uint" # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint augmented_assignment/contract.py:30-32 app_local_get_ex // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,{app_local_get_ex}.0,{app_local_get_ex}.1 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] augmented_assignment/contract.py:30-32 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,maybe_exists%0#0,{app_local_get_ex}.0 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] augmented_assignment/contract.py:30-32 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,maybe_value%0#0,maybe_exists%0#0 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] augmented_assignment/contract.py:30-32 @@ -70,12 +70,12 @@ main_if_body@5: + // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,{+} # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] += n augmented_assignment/contract.py:30-32 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,new_state_value%0#0 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] += n augmented_assignment/contract.py:30-32 dig 2 // load me#0 from l-stack (copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,new_state_value%0#0,me#0 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] += n augmented_assignment/contract.py:30-32 - byte "my_uint" // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,new_state_value%0#0,me#0,"my_uint" self.my_uint augmented_assignment/contract.py:14 + byte "my_uint" // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,new_state_value%0#0,me#0,"my_uint" # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint augmented_assignment/contract.py:30-32 uncover 2 // load new_state_value%0#0 from l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0,"my_uint",new_state_value%0#0 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] += n augmented_assignment/contract.py:30-32 app_local_put // (𝕗) me#0 | bytes_to_add#0,me#0,n#0 # local augmented assignment\n# this works, but need to silence mypy\nself.my_uint[me] += n augmented_assignment/contract.py:30-32 dig 1 // load me#0 from l-stack (copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0 self.my_bytes[me] augmented_assignment/contract.py:33 int 0 // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0,0 self.my_bytes[me] augmented_assignment/contract.py:33 - byte "my_bytes" // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0,0,"my_bytes" self.my_bytes augmented_assignment/contract.py:15 + byte "my_bytes" // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,me#0,0,"my_bytes" self.my_bytes augmented_assignment/contract.py:33 app_local_get_ex // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,{app_local_get_ex}.0,{app_local_get_ex}.1 self.my_bytes[me] augmented_assignment/contract.py:33 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,maybe_exists%1#0,{app_local_get_ex}.0 self.my_bytes[me] augmented_assignment/contract.py:33 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,maybe_value%1#0,maybe_exists%1#0 self.my_bytes[me] augmented_assignment/contract.py:33 @@ -86,11 +86,11 @@ main_if_body@5: concat // (𝕗) me#0 | bytes_to_add#0,me#0,n#0,{concat} self.my_bytes[me] += bytes_to_add augmented_assignment/contract.py:33 // virtual: store new_state_value%1#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,me#0,n#0,new_state_value%1#0 self.my_bytes[me] += bytes_to_add augmented_assignment/contract.py:33 uncover 2 // load me#0 from l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,n#0,new_state_value%1#0,me#0 self.my_bytes[me] += bytes_to_add augmented_assignment/contract.py:33 - byte "my_bytes" // (𝕗) me#0 | bytes_to_add#0,n#0,new_state_value%1#0,me#0,"my_bytes" self.my_bytes augmented_assignment/contract.py:15 + byte "my_bytes" // (𝕗) me#0 | bytes_to_add#0,n#0,new_state_value%1#0,me#0,"my_bytes" self.my_bytes augmented_assignment/contract.py:33 uncover 2 // load new_state_value%1#0 from l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,n#0,me#0,"my_bytes",new_state_value%1#0 self.my_bytes[me] += bytes_to_add augmented_assignment/contract.py:33 app_local_put // (𝕗) me#0 | bytes_to_add#0,n#0 self.my_bytes[me] += bytes_to_add augmented_assignment/contract.py:33 int 0 // (𝕗) me#0 | bytes_to_add#0,n#0,0 # global augmented assignment\nself.global_uint augmented_assignment/contract.py:35-36 - byte "global_uint" // (𝕗) me#0 | bytes_to_add#0,n#0,0,"global_uint" self.global_uint augmented_assignment/contract.py:16 + byte "global_uint" // (𝕗) me#0 | bytes_to_add#0,n#0,0,"global_uint" # global augmented assignment\nself.global_uint augmented_assignment/contract.py:35-36 app_global_get_ex // (𝕗) me#0 | bytes_to_add#0,n#0,{app_global_get_ex}.0,{app_global_get_ex}.1 # global augmented assignment\nself.global_uint augmented_assignment/contract.py:35-36 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,n#0,maybe_exists%2#0,{app_global_get_ex}.0 # global augmented assignment\nself.global_uint augmented_assignment/contract.py:35-36 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,n#0,maybe_value%2#0,maybe_exists%2#0 # global augmented assignment\nself.global_uint augmented_assignment/contract.py:35-36 @@ -100,11 +100,11 @@ main_if_body@5: uncover 1 // load n#0 from l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,maybe_value%2#0,n#0 # global augmented assignment\nself.global_uint += n augmented_assignment/contract.py:35-36 + // (𝕗) me#0 | bytes_to_add#0,{+} # global augmented assignment\nself.global_uint += n augmented_assignment/contract.py:35-36 // virtual: store new_state_value%2#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,new_state_value%2#0 # global augmented assignment\nself.global_uint += n augmented_assignment/contract.py:35-36 - byte "global_uint" // (𝕗) me#0 | bytes_to_add#0,new_state_value%2#0,"global_uint" self.global_uint augmented_assignment/contract.py:16 + byte "global_uint" // (𝕗) me#0 | bytes_to_add#0,new_state_value%2#0,"global_uint" # global augmented assignment\nself.global_uint augmented_assignment/contract.py:35-36 uncover 1 // load new_state_value%2#0 from l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,"global_uint",new_state_value%2#0 # global augmented assignment\nself.global_uint += n augmented_assignment/contract.py:35-36 app_global_put // (𝕗) me#0 | bytes_to_add#0 # global augmented assignment\nself.global_uint += n augmented_assignment/contract.py:35-36 int 0 // (𝕗) me#0 | bytes_to_add#0,0 self.global_bytes augmented_assignment/contract.py:37 - byte "global_bytes" // (𝕗) me#0 | bytes_to_add#0,0,"global_bytes" self.global_bytes augmented_assignment/contract.py:17 + byte "global_bytes" // (𝕗) me#0 | bytes_to_add#0,0,"global_bytes" self.global_bytes augmented_assignment/contract.py:37 app_global_get_ex // (𝕗) me#0 | bytes_to_add#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.global_bytes augmented_assignment/contract.py:37 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,maybe_exists%3#0,{app_global_get_ex}.0 self.global_bytes augmented_assignment/contract.py:37 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕗) me#0 | bytes_to_add#0,maybe_value%3#0,maybe_exists%3#0 self.global_bytes augmented_assignment/contract.py:37 @@ -114,7 +114,7 @@ main_if_body@5: uncover 1 // load bytes_to_add#0 from l-stack (no copy) (𝕗) me#0 | maybe_value%3#0,bytes_to_add#0 self.global_bytes += bytes_to_add augmented_assignment/contract.py:37 concat // (𝕗) me#0 | {concat} self.global_bytes += bytes_to_add augmented_assignment/contract.py:37 // virtual: store new_state_value%3#0 to l-stack (no copy) (𝕗) me#0 | new_state_value%3#0 self.global_bytes += bytes_to_add augmented_assignment/contract.py:37 - byte "global_bytes" // (𝕗) me#0 | new_state_value%3#0,"global_bytes" self.global_bytes augmented_assignment/contract.py:17 + byte "global_bytes" // (𝕗) me#0 | new_state_value%3#0,"global_bytes" self.global_bytes augmented_assignment/contract.py:37 uncover 1 // load new_state_value%3#0 from l-stack (no copy) (𝕗) me#0 | "global_bytes",new_state_value%3#0 self.global_bytes += bytes_to_add augmented_assignment/contract.py:37 app_global_put // (𝕗) me#0 | self.global_bytes += bytes_to_add augmented_assignment/contract.py:37 // Implicit fall through to main_after_if_else@6 // (𝕗) me#0 | diff --git a/test_cases/augmented_assignment/out/Augmented.approval.teal b/test_cases/augmented_assignment/out/Augmented.approval.teal index d7a319b8a4..61d0427487 100644 --- a/test_cases/augmented_assignment/out/Augmented.approval.teal +++ b/test_cases/augmented_assignment/out/Augmented.approval.teal @@ -20,18 +20,12 @@ main_entrypoint@2: // augmented_assignment/contract.py:23 // self.my_uint[me] = UInt64(0) dupn 2 - // augmented_assignment/contract.py:14 - // self.my_uint = LocalState(UInt64) byte "my_uint" - // augmented_assignment/contract.py:23 - // self.my_uint[me] = UInt64(0) int 0 app_local_put - // augmented_assignment/contract.py:15 - // self.my_bytes = LocalState(Bytes) - byte "my_bytes" // augmented_assignment/contract.py:24 // self.my_bytes[me] = Bytes(b"") + byte "my_bytes" byte 0x app_local_put @@ -57,86 +51,48 @@ main_after_if_else@4: dup cover 2 int 0 - // augmented_assignment/contract.py:14 - // self.my_uint = LocalState(UInt64) byte "my_uint" - // augmented_assignment/contract.py:30-32 - // # local augmented assignment - // # this works, but need to silence mypy - // self.my_uint[me] += n app_local_get_ex assert // check self.my_uint exists for account dig 1 + dig 2 - // augmented_assignment/contract.py:14 - // self.my_uint = LocalState(UInt64) byte "my_uint" - // augmented_assignment/contract.py:30-32 - // # local augmented assignment - // # this works, but need to silence mypy - // self.my_uint[me] += n uncover 2 app_local_put // augmented_assignment/contract.py:33 // self.my_bytes[me] += bytes_to_add dig 1 int 0 - // augmented_assignment/contract.py:15 - // self.my_bytes = LocalState(Bytes) byte "my_bytes" - // augmented_assignment/contract.py:33 - // self.my_bytes[me] += bytes_to_add app_local_get_ex assert // check self.my_bytes exists for account dig 3 concat uncover 2 - // augmented_assignment/contract.py:15 - // self.my_bytes = LocalState(Bytes) byte "my_bytes" - // augmented_assignment/contract.py:33 - // self.my_bytes[me] += bytes_to_add uncover 2 app_local_put // augmented_assignment/contract.py:35-36 // # global augmented assignment // self.global_uint += n int 0 - // augmented_assignment/contract.py:16 - // self.global_uint = UInt64(0) byte "global_uint" - // augmented_assignment/contract.py:35-36 - // # global augmented assignment - // self.global_uint += n app_global_get_ex assert // check self.global_uint exists + - // augmented_assignment/contract.py:16 - // self.global_uint = UInt64(0) byte "global_uint" - // augmented_assignment/contract.py:35-36 - // # global augmented assignment - // self.global_uint += n swap app_global_put // augmented_assignment/contract.py:37 // self.global_bytes += bytes_to_add int 0 - // augmented_assignment/contract.py:17 - // self.global_bytes = Bytes(b"") byte "global_bytes" - // augmented_assignment/contract.py:37 - // self.global_bytes += bytes_to_add app_global_get_ex assert // check self.global_bytes exists swap concat - // augmented_assignment/contract.py:17 - // self.global_bytes = Bytes(b"") byte "global_bytes" - // augmented_assignment/contract.py:37 - // self.global_bytes += bytes_to_add swap app_global_put diff --git a/test_cases/augmented_assignment/out_unoptimized/Augmented.approval.teal b/test_cases/augmented_assignment/out_unoptimized/Augmented.approval.teal index 52e523e40d..0d61d03890 100644 --- a/test_cases/augmented_assignment/out_unoptimized/Augmented.approval.teal +++ b/test_cases/augmented_assignment/out_unoptimized/Augmented.approval.teal @@ -21,18 +21,12 @@ main_entrypoint@2: // self.my_uint[me] = UInt64(0) dup dup - // augmented_assignment/contract.py:14 - // self.my_uint = LocalState(UInt64) byte "my_uint" - // augmented_assignment/contract.py:23 - // self.my_uint[me] = UInt64(0) int 0 app_local_put - // augmented_assignment/contract.py:15 - // self.my_bytes = LocalState(Bytes) - byte "my_bytes" // augmented_assignment/contract.py:24 // self.my_bytes[me] = Bytes(b"") + byte "my_bytes" byte 0x app_local_put @@ -57,87 +51,49 @@ main_after_if_else@4: dig 2 dup int 0 - // augmented_assignment/contract.py:14 - // self.my_uint = LocalState(UInt64) byte "my_uint" - // augmented_assignment/contract.py:30-32 - // # local augmented assignment - // # this works, but need to silence mypy - // self.my_uint[me] += n app_local_get_ex assert // check self.my_uint exists for account dig 2 + dig 1 - // augmented_assignment/contract.py:14 - // self.my_uint = LocalState(UInt64) byte "my_uint" - // augmented_assignment/contract.py:30-32 - // # local augmented assignment - // # this works, but need to silence mypy - // self.my_uint[me] += n uncover 2 app_local_put // augmented_assignment/contract.py:33 // self.my_bytes[me] += bytes_to_add dup int 0 - // augmented_assignment/contract.py:15 - // self.my_bytes = LocalState(Bytes) byte "my_bytes" - // augmented_assignment/contract.py:33 - // self.my_bytes[me] += bytes_to_add app_local_get_ex assert // check self.my_bytes exists for account dig 3 concat uncover 1 - // augmented_assignment/contract.py:15 - // self.my_bytes = LocalState(Bytes) byte "my_bytes" - // augmented_assignment/contract.py:33 - // self.my_bytes[me] += bytes_to_add uncover 2 app_local_put // augmented_assignment/contract.py:35-36 // # global augmented assignment // self.global_uint += n int 0 - // augmented_assignment/contract.py:16 - // self.global_uint = UInt64(0) byte "global_uint" - // augmented_assignment/contract.py:35-36 - // # global augmented assignment - // self.global_uint += n app_global_get_ex assert // check self.global_uint exists uncover 1 + - // augmented_assignment/contract.py:16 - // self.global_uint = UInt64(0) byte "global_uint" - // augmented_assignment/contract.py:35-36 - // # global augmented assignment - // self.global_uint += n uncover 1 app_global_put // augmented_assignment/contract.py:37 // self.global_bytes += bytes_to_add int 0 - // augmented_assignment/contract.py:17 - // self.global_bytes = Bytes(b"") byte "global_bytes" - // augmented_assignment/contract.py:37 - // self.global_bytes += bytes_to_add app_global_get_ex assert // check self.global_bytes exists uncover 1 concat - // augmented_assignment/contract.py:17 - // self.global_bytes = Bytes(b"") byte "global_bytes" - // augmented_assignment/contract.py:37 - // self.global_bytes += bytes_to_add uncover 1 app_global_put diff --git a/test_cases/compile/out/Hello.approval.mir b/test_cases/compile/out/Hello.approval.mir index 00d63abc10..4f29369f29 100644 --- a/test_cases/compile/out/Hello.approval.mir +++ b/test_cases/compile/out/Hello.approval.mir @@ -149,7 +149,7 @@ create: proto 1 0 // (𝕡) greeting#0 | @arc4.abimethod(create="require")\ndef create(self, greeting: String) -> None: compile/apps.py:56-57 create_block@0: - byte "greeting" // (𝕡) greeting#0 | "greeting" self.greeting compile/apps.py:23 + byte "greeting" // (𝕡) greeting#0 | "greeting" self.greeting compile/apps.py:58 frame_dig -1 // load greeting#0 from parameters (𝕡) greeting#0 | "greeting",greeting#0 self.greeting = greeting compile/apps.py:58 app_global_put // (𝕡) greeting#0 | self.greeting = greeting compile/apps.py:58 retsub // @@ -161,7 +161,7 @@ greet: greet_block@0: int 0 // (𝕡) name#0 | 0 self.greeting compile/apps.py:35 - byte "greeting" // (𝕡) name#0 | 0,"greeting" self.greeting compile/apps.py:23 + byte "greeting" // (𝕡) name#0 | 0,"greeting" self.greeting compile/apps.py:35 app_global_get_ex // (𝕡) name#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.greeting compile/apps.py:35 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.greeting compile/apps.py:35 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_value%0#0,maybe_exists%0#0 self.greeting compile/apps.py:35 diff --git a/test_cases/compile/out/Hello.approval.teal b/test_cases/compile/out/Hello.approval.teal index 738c356211..53ab199209 100644 --- a/test_cases/compile/out/Hello.approval.teal +++ b/test_cases/compile/out/Hello.approval.teal @@ -111,11 +111,9 @@ create: // @arc4.abimethod(create="require") // def create(self, greeting: String) -> None: proto 1 0 - // compile/apps.py:23 - // self.greeting = String() - byte "greeting" // compile/apps.py:58 // self.greeting = greeting + byte "greeting" frame_dig -1 app_global_put retsub @@ -130,11 +128,7 @@ greet: // compile/apps.py:35 // return self.greeting + " " + name int 0 - // compile/apps.py:23 - // self.greeting = String() byte "greeting" - // compile/apps.py:35 - // return self.greeting + " " + name app_global_get_ex assert // check self.greeting exists byte " " diff --git a/test_cases/compile/out/Hello.arc32.json b/test_cases/compile/out/Hello.arc32.json index 37f5dcf6eb..47ace02499 100644 --- a/test_cases/compile/out/Hello.arc32.json +++ b/test_cases/compile/out/Hello.arc32.json @@ -17,7 +17,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsby5hcHByb3ZhbF9wcm9ncmFtOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2VudHJ5cG9pbnRAMgogICAgY2FsbHN1YiBfX2luaXRfXwoKbWFpbl9lbnRyeXBvaW50QDI6CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsby5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyBjb21waWxlL2FwcHMucHk6NTQKICAgIC8vIGNsYXNzIEhlbGxvKEhlbGxvQmFzZSk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANwogICAgbWV0aG9kICJjcmVhdGUoc3RyaW5nKXZvaWQiCiAgICBtZXRob2QgImRlbGV0ZSgpdm9pZCIKICAgIG1ldGhvZCAiZ3JlZXQoc3RyaW5nKXN0cmluZyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjU0CiAgICAvLyBjbGFzcyBIZWxsbyhIZWxsb0Jhc2UpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICBjYWxsc3ViIGNyZWF0ZQogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX3JvdXRlQDM6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiRGVsZXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgRGVsZXRlQXBwbGljYXRpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ncmVldF9yb3V0ZUA0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjU0CiAgICAvLyBjbGFzcyBIZWxsbyhIZWxsb0Jhc2UpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ3JlZXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo1NAogICAgLy8gY2xhc3MgSGVsbG8oSGVsbG9CYXNlKToKICAgIGludCA0CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX191cGRhdGVAOAogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdXBkYXRlQDg6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjkKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjI5LTMwCiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJVcGRhdGVBcHBsaWNhdGlvbiJdKQogICAgLy8gZGVmIHVwZGF0ZShzZWxmKSAtPiBOb25lOgogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvLmNyZWF0ZShncmVldGluZzogYnl0ZXMpIC0+IHZvaWQ6CmNyZWF0ZToKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo1Ni01NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICAvLyBkZWYgY3JlYXRlKHNlbGYsIGdyZWV0aW5nOiBTdHJpbmcpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyMwogICAgLy8gc2VsZi5ncmVldGluZyA9IFN0cmluZygpCiAgICBieXRlICJncmVldGluZyIKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo1OAogICAgLy8gc2VsZi5ncmVldGluZyA9IGdyZWV0aW5nCiAgICBmcmFtZV9kaWcgLTEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb0Jhc2UuZ3JlZXQobmFtZTogYnl0ZXMpIC0+IGJ5dGVzOgpncmVldDoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozMy0zNAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBncmVldChzZWxmLCBuYW1lOiBTdHJpbmcpIC0+IFN0cmluZzoKICAgIHByb3RvIDEgMQogICAgLy8gY29tcGlsZS9hcHBzLnB5OjM1CiAgICAvLyByZXR1cm4gc2VsZi5ncmVldGluZyArICIgIiArIG5hbWUKICAgIGludCAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6MjMKICAgIC8vIHNlbGYuZ3JlZXRpbmcgPSBTdHJpbmcoKQogICAgYnl0ZSAiZ3JlZXRpbmciCiAgICAvLyBjb21waWxlL2FwcHMucHk6MzUKICAgIC8vIHJldHVybiBzZWxmLmdyZWV0aW5nICsgIiAiICsgbmFtZQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdyZWV0aW5nIGV4aXN0cwogICAgYnl0ZSAiICIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvQmFzZS5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjIyCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gY29tcGlsZS9hcHBzLnB5OjIzCiAgICAvLyBzZWxmLmdyZWV0aW5nID0gU3RyaW5nKCkKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgYnl0ZSAiIgogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsby5hcHByb3ZhbF9wcm9ncmFtOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2VudHJ5cG9pbnRAMgogICAgY2FsbHN1YiBfX2luaXRfXwoKbWFpbl9lbnRyeXBvaW50QDI6CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsby5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyBjb21waWxlL2FwcHMucHk6NTQKICAgIC8vIGNsYXNzIEhlbGxvKEhlbGxvQmFzZSk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANwogICAgbWV0aG9kICJjcmVhdGUoc3RyaW5nKXZvaWQiCiAgICBtZXRob2QgImRlbGV0ZSgpdm9pZCIKICAgIG1ldGhvZCAiZ3JlZXQoc3RyaW5nKXN0cmluZyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjU2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjU0CiAgICAvLyBjbGFzcyBIZWxsbyhIZWxsb0Jhc2UpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo1NgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICBjYWxsc3ViIGNyZWF0ZQogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX3JvdXRlQDM6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiRGVsZXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgRGVsZXRlQXBwbGljYXRpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ncmVldF9yb3V0ZUA0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjU0CiAgICAvLyBjbGFzcyBIZWxsbyhIZWxsb0Jhc2UpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ3JlZXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo1NAogICAgLy8gY2xhc3MgSGVsbG8oSGVsbG9CYXNlKToKICAgIGludCA0CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX191cGRhdGVAOAogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdXBkYXRlQDg6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjkKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjI5LTMwCiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJVcGRhdGVBcHBsaWNhdGlvbiJdKQogICAgLy8gZGVmIHVwZGF0ZShzZWxmKSAtPiBOb25lOgogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvLmNyZWF0ZShncmVldGluZzogYnl0ZXMpIC0+IHZvaWQ6CmNyZWF0ZToKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo1Ni01NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGNyZWF0ZT0icmVxdWlyZSIpCiAgICAvLyBkZWYgY3JlYXRlKHNlbGYsIGdyZWV0aW5nOiBTdHJpbmcpIC0+IE5vbmU6CiAgICBwcm90byAxIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo1OAogICAgLy8gc2VsZi5ncmVldGluZyA9IGdyZWV0aW5nCiAgICBieXRlICJncmVldGluZyIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvQmFzZS5ncmVldChuYW1lOiBieXRlcykgLT4gYnl0ZXM6CmdyZWV0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzLTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdyZWV0KHNlbGYsIG5hbWU6IFN0cmluZykgLT4gU3RyaW5nOgogICAgcHJvdG8gMSAxCiAgICAvLyBjb21waWxlL2FwcHMucHk6MzUKICAgIC8vIHJldHVybiBzZWxmLmdyZWV0aW5nICsgIiAiICsgbmFtZQogICAgaW50IDAKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdyZWV0aW5nIGV4aXN0cwogICAgYnl0ZSAiICIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvQmFzZS5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjIyCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gY29tcGlsZS9hcHBzLnB5OjIzCiAgICAvLyBzZWxmLmdyZWV0aW5nID0gU3RyaW5nKCkKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgYnl0ZSAiIgogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsby5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/test_cases/compile/out/HelloBase.approval.mir b/test_cases/compile/out/HelloBase.approval.mir index f6acde993b..1e62d712a8 100644 --- a/test_cases/compile/out/HelloBase.approval.mir +++ b/test_cases/compile/out/HelloBase.approval.mir @@ -136,7 +136,7 @@ greet: greet_block@0: int 0 // (𝕡) name#0 | 0 self.greeting compile/apps.py:35 - byte "greeting" // (𝕡) name#0 | 0,"greeting" self.greeting compile/apps.py:23 + byte "greeting" // (𝕡) name#0 | 0,"greeting" self.greeting compile/apps.py:35 app_global_get_ex // (𝕡) name#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.greeting compile/apps.py:35 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.greeting compile/apps.py:35 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_value%0#0,maybe_exists%0#0 self.greeting compile/apps.py:35 diff --git a/test_cases/compile/out/HelloBase.approval.teal b/test_cases/compile/out/HelloBase.approval.teal index ccc368e5f8..592a328d86 100644 --- a/test_cases/compile/out/HelloBase.approval.teal +++ b/test_cases/compile/out/HelloBase.approval.teal @@ -104,11 +104,7 @@ greet: // compile/apps.py:35 // return self.greeting + " " + name int 0 - // compile/apps.py:23 - // self.greeting = String() byte "greeting" - // compile/apps.py:35 - // return self.greeting + " " + name app_global_get_ex assert // check self.greeting exists byte " " diff --git a/test_cases/compile/out/HelloBase.arc32.json b/test_cases/compile/out/HelloBase.arc32.json index 98e35f3e49..52ece49800 100644 --- a/test_cases/compile/out/HelloBase.arc32.json +++ b/test_cases/compile/out/HelloBase.arc32.json @@ -12,7 +12,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb0Jhc2UuYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9CYXNlLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyMAogICAgLy8gY2xhc3MgSGVsbG9CYXNlKEFSQzRDb250cmFjdCk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANgogICAgbWV0aG9kICJkZWxldGUoKXZvaWQiCiAgICBtZXRob2QgImdyZWV0KHN0cmluZylzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19kZWxldGVfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19ncmVldF9yb3V0ZUAzCiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19kZWxldGVfcm91dGVAMjoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJEZWxldGVBcHBsaWNhdGlvbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IERlbGV0ZUFwcGxpY2F0aW9uCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBEZWxldGVBcHBsaWNhdGlvbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDM6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBjb21waWxlL2FwcHMucHk6MjAKICAgIC8vIGNsYXNzIEhlbGxvQmFzZShBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ3JlZXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyMAogICAgLy8gY2xhc3MgSGVsbG9CYXNlKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgaW50IDQKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3B5X2RlZmF1bHRfY3JlYXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdXBkYXRlQDgKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3B5X2RlZmF1bHRfY3JlYXRlQDc6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjAKICAgIC8vIGNsYXNzIEhlbGxvQmFzZShBUkM0Q29udHJhY3QpOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdXBkYXRlQDg6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjkKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjI5LTMwCiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJVcGRhdGVBcHBsaWNhdGlvbiJdKQogICAgLy8gZGVmIHVwZGF0ZShzZWxmKSAtPiBOb25lOgogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvQmFzZS5ncmVldChuYW1lOiBieXRlcykgLT4gYnl0ZXM6CmdyZWV0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzLTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdyZWV0KHNlbGYsIG5hbWU6IFN0cmluZykgLT4gU3RyaW5nOgogICAgcHJvdG8gMSAxCiAgICAvLyBjb21waWxlL2FwcHMucHk6MzUKICAgIC8vIHJldHVybiBzZWxmLmdyZWV0aW5nICsgIiAiICsgbmFtZQogICAgaW50IDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyMwogICAgLy8gc2VsZi5ncmVldGluZyA9IFN0cmluZygpCiAgICBieXRlICJncmVldGluZyIKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozNQogICAgLy8gcmV0dXJuIHNlbGYuZ3JlZXRpbmcgKyAiICIgKyBuYW1lCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ3JlZXRpbmcgZXhpc3RzCiAgICBieXRlICIgIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9CYXNlLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjIKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6MjMKICAgIC8vIHNlbGYuZ3JlZXRpbmcgPSBTdHJpbmcoKQogICAgYnl0ZSAiZ3JlZXRpbmciCiAgICBieXRlICIiCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb0Jhc2UuYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9CYXNlLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyMAogICAgLy8gY2xhc3MgSGVsbG9CYXNlKEFSQzRDb250cmFjdCk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANgogICAgbWV0aG9kICJkZWxldGUoKXZvaWQiCiAgICBtZXRob2QgImdyZWV0KHN0cmluZylzdHJpbmciCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19kZWxldGVfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19ncmVldF9yb3V0ZUAzCiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19kZWxldGVfcm91dGVAMjoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJEZWxldGVBcHBsaWNhdGlvbiJdKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IERlbGV0ZUFwcGxpY2F0aW9uCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBEZWxldGVBcHBsaWNhdGlvbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDM6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBjb21waWxlL2FwcHMucHk6MjAKICAgIC8vIGNsYXNzIEhlbGxvQmFzZShBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ3JlZXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANjoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyMAogICAgLy8gY2xhc3MgSGVsbG9CYXNlKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgaW50IDQKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3B5X2RlZmF1bHRfY3JlYXRlQDcgX19wdXlhX2FyYzRfcm91dGVyX19fdXBkYXRlQDgKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX19fYWxnb3B5X2RlZmF1bHRfY3JlYXRlQDc6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjAKICAgIC8vIGNsYXNzIEhlbGxvQmFzZShBUkM0Q29udHJhY3QpOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fdXBkYXRlQDg6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjkKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjI5LTMwCiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJVcGRhdGVBcHBsaWNhdGlvbiJdKQogICAgLy8gZGVmIHVwZGF0ZShzZWxmKSAtPiBOb25lOgogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvQmFzZS5ncmVldChuYW1lOiBieXRlcykgLT4gYnl0ZXM6CmdyZWV0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzLTM0CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGdyZWV0KHNlbGYsIG5hbWU6IFN0cmluZykgLT4gU3RyaW5nOgogICAgcHJvdG8gMSAxCiAgICAvLyBjb21waWxlL2FwcHMucHk6MzUKICAgIC8vIHJldHVybiBzZWxmLmdyZWV0aW5nICsgIiAiICsgbmFtZQogICAgaW50IDAKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdyZWV0aW5nIGV4aXN0cwogICAgYnl0ZSAiICIKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvQmFzZS5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjIyCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gY29tcGlsZS9hcHBzLnB5OjIzCiAgICAvLyBzZWxmLmdyZWV0aW5nID0gU3RyaW5nKCkKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgYnl0ZSAiIgogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb0Jhc2UuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { diff --git a/test_cases/compile/out/HelloOtherConstants.approval.mir b/test_cases/compile/out/HelloOtherConstants.approval.mir index 22c74796e0..0d1d6e35e6 100644 --- a/test_cases/compile/out/HelloOtherConstants.approval.mir +++ b/test_cases/compile/out/HelloOtherConstants.approval.mir @@ -150,7 +150,7 @@ greet: greet_block@0: int 0 // (𝕡) name#0 | 0 self.num compile/apps.py:99 - byte "num" // (𝕡) name#0 | 0,"num" self.num compile/apps.py:85 + byte "num" // (𝕡) name#0 | 0,"num" self.num compile/apps.py:99 app_global_get_ex // (𝕡) name#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.num compile/apps.py:99 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.num compile/apps.py:99 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_value%0#0,maybe_exists%0#0 self.num compile/apps.py:99 @@ -168,7 +168,7 @@ greet_block@0: - // (𝕡) name#0 | {-} (self.num + 48).bytes[-1] compile/apps.py:99 // virtual: store tmp%1#0 to l-stack (no copy) (𝕡) name#0 | tmp%1#0 (self.num + 48).bytes[-1] compile/apps.py:99 int 0 // (𝕡) name#0 | tmp%1#0,0 self.num compile/apps.py:99 - byte "num" // (𝕡) name#0 | tmp%1#0,0,"num" self.num compile/apps.py:85 + byte "num" // (𝕡) name#0 | tmp%1#0,0,"num" self.num compile/apps.py:99 app_global_get_ex // (𝕡) name#0 | tmp%1#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.num compile/apps.py:99 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) name#0 | tmp%1#0,maybe_exists%1#0,{app_global_get_ex}.0 self.num compile/apps.py:99 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) name#0 | tmp%1#0,maybe_value%1#0,maybe_exists%1#0 self.num compile/apps.py:99 @@ -188,7 +188,7 @@ greet_block@0: substring3 // (𝕡) name#0 | {substring3} (self.num + 48).bytes[-1] compile/apps.py:99 // virtual: store num_alpha#0 to l-stack (no copy) (𝕡) name#0 | num_alpha#0 num_alpha = (self.num + 48).bytes[-1] compile/apps.py:99 int 0 // (𝕡) name#0 | num_alpha#0,0 self.greeting compile/apps.py:101 - byte "greeting" // (𝕡) name#0 | num_alpha#0,0,"greeting" self.greeting compile/apps.py:84 + byte "greeting" // (𝕡) name#0 | num_alpha#0,0,"greeting" self.greeting compile/apps.py:101 app_global_get_ex // (𝕡) name#0 | num_alpha#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.greeting compile/apps.py:101 // virtual: store maybe_exists%2#0 to l-stack (no copy) (𝕡) name#0 | num_alpha#0,maybe_exists%2#0,{app_global_get_ex}.0 self.greeting compile/apps.py:101 // virtual: store maybe_value%2#0 to l-stack (no copy) (𝕡) name#0 | num_alpha#0,maybe_value%2#0,maybe_exists%2#0 self.greeting compile/apps.py:101 @@ -207,7 +207,7 @@ greet_block@0: concat // (𝕡) name#0 | {concat} self.greeting.bytes + b" " + name.bytes + num_alpha compile/apps.py:101 // virtual: store tmp%4#0 to l-stack (no copy) (𝕡) name#0 | tmp%4#0 self.greeting.bytes + b" " + name.bytes + num_alpha compile/apps.py:101 int 0 // (𝕡) name#0 | tmp%4#0,0 self.address compile/apps.py:101 - byte "address" // (𝕡) name#0 | tmp%4#0,0,"address" self.address compile/apps.py:86 + byte "address" // (𝕡) name#0 | tmp%4#0,0,"address" self.address compile/apps.py:101 app_global_get_ex // (𝕡) name#0 | tmp%4#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.address compile/apps.py:101 // virtual: store maybe_exists%3#0 to l-stack (no copy) (𝕡) name#0 | tmp%4#0,maybe_exists%3#0,{app_global_get_ex}.0 self.address compile/apps.py:101 // virtual: store maybe_value%3#0 to l-stack (no copy) (𝕡) name#0 | tmp%4#0,maybe_value%3#0,maybe_exists%3#0 self.address compile/apps.py:101 @@ -218,7 +218,7 @@ greet_block@0: concat // (𝕡) name#0 | {concat} self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes compile/apps.py:101 // virtual: store tmp%5#0 to l-stack (no copy) (𝕡) name#0 | tmp%5#0 self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes compile/apps.py:101 int 0 // (𝕡) name#0 | tmp%5#0,0 self.method compile/apps.py:101 - byte "method" // (𝕡) name#0 | tmp%5#0,0,"method" self.method compile/apps.py:87 + byte "method" // (𝕡) name#0 | tmp%5#0,0,"method" self.method compile/apps.py:101 app_global_get_ex // (𝕡) name#0 | tmp%5#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.method compile/apps.py:101 // virtual: store maybe_exists%4#0 to l-stack (no copy) (𝕡) name#0 | tmp%5#0,maybe_exists%4#0,{app_global_get_ex}.0 self.method compile/apps.py:101 // virtual: store maybe_value%4#0 to l-stack (no copy) (𝕡) name#0 | tmp%5#0,maybe_value%4#0,maybe_exists%4#0 self.method compile/apps.py:101 diff --git a/test_cases/compile/out/HelloOtherConstants.approval.teal b/test_cases/compile/out/HelloOtherConstants.approval.teal index fcb1284bd8..400ae18105 100644 --- a/test_cases/compile/out/HelloOtherConstants.approval.teal +++ b/test_cases/compile/out/HelloOtherConstants.approval.teal @@ -111,11 +111,7 @@ greet: // compile/apps.py:99 // num_alpha = (self.num + 48).bytes[-1] int 0 - // compile/apps.py:85 - // self.num = TemplateVar[BigUInt]("NUM") byte "num" - // compile/apps.py:99 - // num_alpha = (self.num + 48).bytes[-1] app_global_get_ex assert // check self.num exists byte 0x30 @@ -124,11 +120,7 @@ greet: int 1 - int 0 - // compile/apps.py:85 - // self.num = TemplateVar[BigUInt]("NUM") byte "num" - // compile/apps.py:99 - // num_alpha = (self.num + 48).bytes[-1] app_global_get_ex assert // check self.num exists byte 0x30 @@ -142,11 +134,7 @@ greet: // compile/apps.py:101 // self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes + self.method int 0 - // compile/apps.py:84 - // self.greeting = TemplateVar[String]("GREETING") byte "greeting" - // compile/apps.py:101 - // self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes + self.method app_global_get_ex assert // check self.greeting exists byte 0x20 @@ -156,20 +144,12 @@ greet: swap concat int 0 - // compile/apps.py:86 - // self.address = TemplateVar[Account]("ACCOUNT") byte "address" - // compile/apps.py:101 - // self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes + self.method app_global_get_ex assert // check self.address exists concat int 0 - // compile/apps.py:87 - // self.method = TemplateVar[Bytes]("METHOD") byte "method" - // compile/apps.py:101 - // self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes + self.method app_global_get_ex assert // check self.method exists concat diff --git a/test_cases/compile/out/HelloOtherConstants.arc32.json b/test_cases/compile/out/HelloOtherConstants.arc32.json index e8558dbfb0..320d7d6535 100644 --- a/test_cases/compile/out/HelloOtherConstants.arc32.json +++ b/test_cases/compile/out/HelloOtherConstants.arc32.json @@ -17,7 +17,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb090aGVyQ29uc3RhbnRzLmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvT3RoZXJDb25zdGFudHMuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjgxCiAgICAvLyBjbGFzcyBIZWxsb090aGVyQ29uc3RhbnRzKEFSQzRDb250cmFjdCk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDgKICAgIG1ldGhvZCAiY3JlYXRlKCl1aW50NjQiCiAgICBtZXRob2QgImRlbGV0ZSgpdm9pZCIKICAgIG1ldGhvZCAiZ3JlZXQoc3RyaW5nKWJ5dGVbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgY2FsbHN1YiBjcmVhdGUKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIkRlbGV0ZUFwcGxpY2F0aW9uIl0pCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBpbnQgRGVsZXRlQXBwbGljYXRpb24KICAgID09CiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIERlbGV0ZUFwcGxpY2F0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ3JlZXRfcm91dGVANDoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo4MQogICAgLy8gY2xhc3MgSGVsbG9PdGhlckNvbnN0YW50cyhBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ3JlZXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDg6CiAgICAvLyBjb21waWxlL2FwcHMucHk6ODEKICAgIC8vIGNsYXNzIEhlbGxvT3RoZXJDb25zdGFudHMoQVJDNENvbnRyYWN0KToKICAgIGludCAwCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb090aGVyQ29uc3RhbnRzLmNyZWF0ZSgpIC0+IHVpbnQ2NDoKY3JlYXRlOgogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg5LTkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIC8vIGRlZiBjcmVhdGUoc2VsZikgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyBjb21waWxlL2FwcHMucHk6OTEKICAgIC8vIHJldHVybiBVSW50NjQoMSkKICAgIGludCAxCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb090aGVyQ29uc3RhbnRzLmdyZWV0KG5hbWU6IGJ5dGVzKSAtPiBieXRlczoKZ3JlZXQ6CiAgICAvLyBjb21waWxlL2FwcHMucHk6OTctOTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ3JlZXQoc2VsZiwgbmFtZTogU3RyaW5nKSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojk5CiAgICAvLyBudW1fYWxwaGEgPSAoc2VsZi5udW0gKyA0OCkuYnl0ZXNbLTFdCiAgICBpbnQgMAogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg1CiAgICAvLyBzZWxmLm51bSA9IFRlbXBsYXRlVmFyW0JpZ1VJbnRdKCJOVU0iKQogICAgYnl0ZSAibnVtIgogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojk5CiAgICAvLyBudW1fYWxwaGEgPSAoc2VsZi5udW0gKyA0OCkuYnl0ZXNbLTFdCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubnVtIGV4aXN0cwogICAgYnl0ZSAweDMwCiAgICBiKwogICAgbGVuCiAgICBpbnQgMQogICAgLQogICAgaW50IDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo4NQogICAgLy8gc2VsZi5udW0gPSBUZW1wbGF0ZVZhcltCaWdVSW50XSgiTlVNIikKICAgIGJ5dGUgIm51bSIKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo5OQogICAgLy8gbnVtX2FscGhhID0gKHNlbGYubnVtICsgNDgpLmJ5dGVzWy0xXQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLm51bSBleGlzdHMKICAgIGJ5dGUgMHgzMAogICAgYisKICAgIGRpZyAxCiAgICBpbnQgMQogICAgKwogICAgc3dhcAogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjEwMQogICAgLy8gc2VsZi5ncmVldGluZy5ieXRlcyArIGIiICIgKyBuYW1lLmJ5dGVzICsgbnVtX2FscGhhICsgc2VsZi5hZGRyZXNzLmJ5dGVzICsgc2VsZi5tZXRob2QKICAgIGludCAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6ODQKICAgIC8vIHNlbGYuZ3JlZXRpbmcgPSBUZW1wbGF0ZVZhcltTdHJpbmddKCJHUkVFVElORyIpCiAgICBieXRlICJncmVldGluZyIKICAgIC8vIGNvbXBpbGUvYXBwcy5weToxMDEKICAgIC8vIHNlbGYuZ3JlZXRpbmcuYnl0ZXMgKyBiIiAiICsgbmFtZS5ieXRlcyArIG51bV9hbHBoYSArIHNlbGYuYWRkcmVzcy5ieXRlcyArIHNlbGYubWV0aG9kCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ3JlZXRpbmcgZXhpc3RzCiAgICBieXRlIDB4MjAKICAgIGNvbmNhdAogICAgZnJhbWVfZGlnIC0xCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGNvbmNhdAogICAgaW50IDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo4NgogICAgLy8gc2VsZi5hZGRyZXNzID0gVGVtcGxhdGVWYXJbQWNjb3VudF0oIkFDQ09VTlQiKQogICAgYnl0ZSAiYWRkcmVzcyIKICAgIC8vIGNvbXBpbGUvYXBwcy5weToxMDEKICAgIC8vIHNlbGYuZ3JlZXRpbmcuYnl0ZXMgKyBiIiAiICsgbmFtZS5ieXRlcyArIG51bV9hbHBoYSArIHNlbGYuYWRkcmVzcy5ieXRlcyArIHNlbGYubWV0aG9kCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYWRkcmVzcyBleGlzdHMKICAgIGNvbmNhdAogICAgaW50IDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo4NwogICAgLy8gc2VsZi5tZXRob2QgPSBUZW1wbGF0ZVZhcltCeXRlc10oIk1FVEhPRCIpCiAgICBieXRlICJtZXRob2QiCiAgICAvLyBjb21waWxlL2FwcHMucHk6MTAxCiAgICAvLyBzZWxmLmdyZWV0aW5nLmJ5dGVzICsgYiIgIiArIG5hbWUuYnl0ZXMgKyBudW1fYWxwaGEgKyBzZWxmLmFkZHJlc3MuYnl0ZXMgKyBzZWxmLm1ldGhvZAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLm1ldGhvZCBleGlzdHMKICAgIGNvbmNhdAogICAgLy8gY29tcGlsZS9hcHBzLnB5OjEwMC0xMDIKICAgIC8vIHJldHVybiAoCiAgICAvLyAgICAgc2VsZi5ncmVldGluZy5ieXRlcyArIGIiICIgKyBuYW1lLmJ5dGVzICsgbnVtX2FscGhhICsgc2VsZi5hZGRyZXNzLmJ5dGVzICsgc2VsZi5tZXRob2QKICAgIC8vICkKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvT3RoZXJDb25zdGFudHMuX19pbml0X18oKSAtPiB2b2lkOgpfX2luaXRfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo4MwogICAgLy8gZGVmIF9faW5pdF9fKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo4NAogICAgLy8gc2VsZi5ncmVldGluZyA9IFRlbXBsYXRlVmFyW1N0cmluZ10oIkdSRUVUSU5HIikKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgYnl0ZSBUTVBMX0dSRUVUSU5HCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg1CiAgICAvLyBzZWxmLm51bSA9IFRlbXBsYXRlVmFyW0JpZ1VJbnRdKCJOVU0iKQogICAgYnl0ZSAibnVtIgogICAgYnl0ZSBUTVBMX05VTQogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo4NgogICAgLy8gc2VsZi5hZGRyZXNzID0gVGVtcGxhdGVWYXJbQWNjb3VudF0oIkFDQ09VTlQiKQogICAgYnl0ZSAiYWRkcmVzcyIKICAgIGJ5dGUgVE1QTF9BQ0NPVU5UCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg3CiAgICAvLyBzZWxmLm1ldGhvZCA9IFRlbXBsYXRlVmFyW0J5dGVzXSgiTUVUSE9EIikKICAgIGJ5dGUgIm1ldGhvZCIKICAgIGJ5dGUgVE1QTF9NRVRIT0QKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb090aGVyQ29uc3RhbnRzLmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuY29tcGlsZS5hcHBzLkhlbGxvT3RoZXJDb25zdGFudHMuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjgxCiAgICAvLyBjbGFzcyBIZWxsb090aGVyQ29uc3RhbnRzKEFSQzRDb250cmFjdCk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDgKICAgIG1ldGhvZCAiY3JlYXRlKCl1aW50NjQiCiAgICBtZXRob2QgImRlbGV0ZSgpdm9pZCIKICAgIG1ldGhvZCAiZ3JlZXQoc3RyaW5nKWJ5dGVbXSIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg5CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgY2FsbHN1YiBjcmVhdGUKICAgIGl0b2IKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjkzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIkRlbGV0ZUFwcGxpY2F0aW9uIl0pCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBpbnQgRGVsZXRlQXBwbGljYXRpb24KICAgID09CiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIERlbGV0ZUFwcGxpY2F0aW9uCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZ3JlZXRfcm91dGVANDoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo4MQogICAgLy8gY2xhc3MgSGVsbG9PdGhlckNvbnN0YW50cyhBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgZXh0cmFjdCAyIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo5NwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgZ3JlZXQKICAgIGR1cAogICAgbGVuCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgc3dhcAogICAgY29uY2F0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDg6CiAgICAvLyBjb21waWxlL2FwcHMucHk6ODEKICAgIC8vIGNsYXNzIEhlbGxvT3RoZXJDb25zdGFudHMoQVJDNENvbnRyYWN0KToKICAgIGludCAwCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb090aGVyQ29uc3RhbnRzLmNyZWF0ZSgpIC0+IHVpbnQ2NDoKY3JlYXRlOgogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg5LTkwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIC8vIGRlZiBjcmVhdGUoc2VsZikgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyBjb21waWxlL2FwcHMucHk6OTEKICAgIC8vIHJldHVybiBVSW50NjQoMSkKICAgIGludCAxCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb090aGVyQ29uc3RhbnRzLmdyZWV0KG5hbWU6IGJ5dGVzKSAtPiBieXRlczoKZ3JlZXQ6CiAgICAvLyBjb21waWxlL2FwcHMucHk6OTctOTgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ3JlZXQoc2VsZiwgbmFtZTogU3RyaW5nKSAtPiBCeXRlczoKICAgIHByb3RvIDEgMQogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojk5CiAgICAvLyBudW1fYWxwaGEgPSAoc2VsZi5udW0gKyA0OCkuYnl0ZXNbLTFdCiAgICBpbnQgMAogICAgYnl0ZSAibnVtIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLm51bSBleGlzdHMKICAgIGJ5dGUgMHgzMAogICAgYisKICAgIGxlbgogICAgaW50IDEKICAgIC0KICAgIGludCAwCiAgICBieXRlICJudW0iCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubnVtIGV4aXN0cwogICAgYnl0ZSAweDMwCiAgICBiKwogICAgZGlnIDEKICAgIGludCAxCiAgICArCiAgICBzd2FwCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICAvLyBjb21waWxlL2FwcHMucHk6MTAxCiAgICAvLyBzZWxmLmdyZWV0aW5nLmJ5dGVzICsgYiIgIiArIG5hbWUuYnl0ZXMgKyBudW1fYWxwaGEgKyBzZWxmLmFkZHJlc3MuYnl0ZXMgKyBzZWxmLm1ldGhvZAogICAgaW50IDAKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdyZWV0aW5nIGV4aXN0cwogICAgYnl0ZSAweDIwCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMQogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGludCAwCiAgICBieXRlICJhZGRyZXNzIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmFkZHJlc3MgZXhpc3RzCiAgICBjb25jYXQKICAgIGludCAwCiAgICBieXRlICJtZXRob2QiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubWV0aG9kIGV4aXN0cwogICAgY29uY2F0CiAgICAvLyBjb21waWxlL2FwcHMucHk6MTAwLTEwMgogICAgLy8gcmV0dXJuICgKICAgIC8vICAgICBzZWxmLmdyZWV0aW5nLmJ5dGVzICsgYiIgIiArIG5hbWUuYnl0ZXMgKyBudW1fYWxwaGEgKyBzZWxmLmFkZHJlc3MuYnl0ZXMgKyBzZWxmLm1ldGhvZAogICAgLy8gKQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9PdGhlckNvbnN0YW50cy5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjgzCiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg0CiAgICAvLyBzZWxmLmdyZWV0aW5nID0gVGVtcGxhdGVWYXJbU3RyaW5nXSgiR1JFRVRJTkciKQogICAgYnl0ZSAiZ3JlZXRpbmciCiAgICBieXRlIFRNUExfR1JFRVRJTkcKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBjb21waWxlL2FwcHMucHk6ODUKICAgIC8vIHNlbGYubnVtID0gVGVtcGxhdGVWYXJbQmlnVUludF0oIk5VTSIpCiAgICBieXRlICJudW0iCiAgICBieXRlIFRNUExfTlVNCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojg2CiAgICAvLyBzZWxmLmFkZHJlc3MgPSBUZW1wbGF0ZVZhcltBY2NvdW50XSgiQUNDT1VOVCIpCiAgICBieXRlICJhZGRyZXNzIgogICAgYnl0ZSBUTVBMX0FDQ09VTlQKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBjb21waWxlL2FwcHMucHk6ODcKICAgIC8vIHNlbGYubWV0aG9kID0gVGVtcGxhdGVWYXJbQnl0ZXNdKCJNRVRIT0QiKQogICAgYnl0ZSAibWV0aG9kIgogICAgYnl0ZSBUTVBMX01FVEhPRAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb090aGVyQ29uc3RhbnRzLmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICBpbnQgMQogICAgcmV0dXJuCg==" }, "state": { diff --git a/test_cases/compile/out/HelloPrfx.approval.mir b/test_cases/compile/out/HelloPrfx.approval.mir index 3be283d1b1..0e455f8a05 100644 --- a/test_cases/compile/out/HelloPrfx.approval.mir +++ b/test_cases/compile/out/HelloPrfx.approval.mir @@ -143,7 +143,7 @@ greet: greet_block@0: int 0 // (𝕡) name#0 | 0 self.greeting compile/apps.py:35 - byte "greeting" // (𝕡) name#0 | 0,"greeting" self.greeting compile/apps.py:23 + byte "greeting" // (𝕡) name#0 | 0,"greeting" self.greeting compile/apps.py:35 app_global_get_ex // (𝕡) name#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.greeting compile/apps.py:35 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.greeting compile/apps.py:35 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_value%0#0,maybe_exists%0#0 self.greeting compile/apps.py:35 @@ -166,7 +166,7 @@ __init__: proto 0 0 // def __init__(self) -> None: compile/apps.py:73 __init___block@0: - byte "greeting" // "greeting" self.greeting compile/apps.py:23 + byte "greeting" // "greeting" self.greeting compile/apps.py:74 byte PRFX_GREETING // "greeting",PRFX_GREETING TemplateVar[String]("GREETING", prefix="PRFX_") compile/apps.py:74 app_global_put // self.greeting = TemplateVar[String]("GREETING", prefix="PRFX_") compile/apps.py:74 retsub // diff --git a/test_cases/compile/out/HelloPrfx.approval.teal b/test_cases/compile/out/HelloPrfx.approval.teal index c0decb2fb2..6533d38cb6 100644 --- a/test_cases/compile/out/HelloPrfx.approval.teal +++ b/test_cases/compile/out/HelloPrfx.approval.teal @@ -107,11 +107,7 @@ greet: // compile/apps.py:35 // return self.greeting + " " + name int 0 - // compile/apps.py:23 - // self.greeting = String() byte "greeting" - // compile/apps.py:35 - // return self.greeting + " " + name app_global_get_ex assert // check self.greeting exists byte " " @@ -126,11 +122,9 @@ __init__: // compile/apps.py:73 // def __init__(self) -> None: proto 0 0 - // compile/apps.py:23 - // self.greeting = String() - byte "greeting" // compile/apps.py:74 // self.greeting = TemplateVar[String]("GREETING", prefix="PRFX_") + byte "greeting" byte PRFX_GREETING app_global_put retsub diff --git a/test_cases/compile/out/HelloPrfx.arc32.json b/test_cases/compile/out/HelloPrfx.arc32.json index 00bea0ae8a..2c5c3ed2f4 100644 --- a/test_cases/compile/out/HelloPrfx.arc32.json +++ b/test_cases/compile/out/HelloPrfx.arc32.json @@ -17,7 +17,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb1ByZnguYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9QcmZ4Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo3MQogICAgLy8gY2xhc3MgSGVsbG9QcmZ4KEhlbGxvQmFzZSk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANwogICAgbWV0aG9kICJjcmVhdGUoKXZvaWQiCiAgICBtZXRob2QgImRlbGV0ZSgpdm9pZCIKICAgIG1ldGhvZCAiZ3JlZXQoc3RyaW5nKXN0cmluZyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX3JvdXRlQDM6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiRGVsZXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgRGVsZXRlQXBwbGljYXRpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ncmVldF9yb3V0ZUA0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjcxCiAgICAvLyBjbGFzcyBIZWxsb1ByZngoSGVsbG9CYXNlKToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdyZWV0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDc6CiAgICAvLyBjb21waWxlL2FwcHMucHk6NzEKICAgIC8vIGNsYXNzIEhlbGxvUHJmeChIZWxsb0Jhc2UpOgogICAgaW50IDQKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3VwZGF0ZUA4CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX191cGRhdGVAODoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyOQogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiVXBkYXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBjb21waWxlL2FwcHMucHk6MjktMzAKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICAvLyBkZWYgdXBkYXRlKHNlbGYpIC0+IE5vbmU6CiAgICBpbnQgMQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9CYXNlLmdyZWV0KG5hbWU6IGJ5dGVzKSAtPiBieXRlczoKZ3JlZXQ6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMtMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ3JlZXQoc2VsZiwgbmFtZTogU3RyaW5nKSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozNQogICAgLy8gcmV0dXJuIHNlbGYuZ3JlZXRpbmcgKyAiICIgKyBuYW1lCiAgICBpbnQgMAogICAgLy8gY29tcGlsZS9hcHBzLnB5OjIzCiAgICAvLyBzZWxmLmdyZWV0aW5nID0gU3RyaW5nKCkKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjM1CiAgICAvLyByZXR1cm4gc2VsZi5ncmVldGluZyArICIgIiArIG5hbWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ncmVldGluZyBleGlzdHMKICAgIGJ5dGUgIiAiCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMQogICAgY29uY2F0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb1ByZnguX19pbml0X18oKSAtPiB2b2lkOgpfX2luaXRfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo3MwogICAgLy8gZGVmIF9faW5pdF9fKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyMwogICAgLy8gc2VsZi5ncmVldGluZyA9IFN0cmluZygpCiAgICBieXRlICJncmVldGluZyIKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo3NAogICAgLy8gc2VsZi5ncmVldGluZyA9IFRlbXBsYXRlVmFyW1N0cmluZ10oIkdSRUVUSU5HIiwgcHJlZml4PSJQUkZYXyIpCiAgICBieXRlIFBSRlhfR1JFRVRJTkcKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb1ByZnguYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9QcmZ4Ll9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo3MQogICAgLy8gY2xhc3MgSGVsbG9QcmZ4KEhlbGxvQmFzZSk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANwogICAgbWV0aG9kICJjcmVhdGUoKXZvaWQiCiAgICBtZXRob2QgImRlbGV0ZSgpdm9pZCIKICAgIG1ldGhvZCAiZ3JlZXQoc3RyaW5nKXN0cmluZyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gY29tcGlsZS9hcHBzLnB5Ojc2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX3JvdXRlQDM6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiRGVsZXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgRGVsZXRlQXBwbGljYXRpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ncmVldF9yb3V0ZUA0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjcxCiAgICAvLyBjbGFzcyBIZWxsb1ByZngoSGVsbG9CYXNlKToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdyZWV0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDc6CiAgICAvLyBjb21waWxlL2FwcHMucHk6NzEKICAgIC8vIGNsYXNzIEhlbGxvUHJmeChIZWxsb0Jhc2UpOgogICAgaW50IDQKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3VwZGF0ZUA4CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX191cGRhdGVAODoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyOQogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiVXBkYXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBjb21waWxlL2FwcHMucHk6MjktMzAKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICAvLyBkZWYgdXBkYXRlKHNlbGYpIC0+IE5vbmU6CiAgICBpbnQgMQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9CYXNlLmdyZWV0KG5hbWU6IGJ5dGVzKSAtPiBieXRlczoKZ3JlZXQ6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMtMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ3JlZXQoc2VsZiwgbmFtZTogU3RyaW5nKSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozNQogICAgLy8gcmV0dXJuIHNlbGYuZ3JlZXRpbmcgKyAiICIgKyBuYW1lCiAgICBpbnQgMAogICAgYnl0ZSAiZ3JlZXRpbmciCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ3JlZXRpbmcgZXhpc3RzCiAgICBieXRlICIgIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9QcmZ4Ll9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyBjb21waWxlL2FwcHMucHk6NzMKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6NzQKICAgIC8vIHNlbGYuZ3JlZXRpbmcgPSBUZW1wbGF0ZVZhcltTdHJpbmddKCJHUkVFVElORyIsIHByZWZpeD0iUFJGWF8iKQogICAgYnl0ZSAiZ3JlZXRpbmciCiAgICBieXRlIFBSRlhfR1JFRVRJTkcKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb1ByZnguY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { diff --git a/test_cases/compile/out/HelloTmpl.approval.mir b/test_cases/compile/out/HelloTmpl.approval.mir index 95fe4f544c..b1b4b1177e 100644 --- a/test_cases/compile/out/HelloTmpl.approval.mir +++ b/test_cases/compile/out/HelloTmpl.approval.mir @@ -143,7 +143,7 @@ greet: greet_block@0: int 0 // (𝕡) name#0 | 0 self.greeting compile/apps.py:35 - byte "greeting" // (𝕡) name#0 | 0,"greeting" self.greeting compile/apps.py:23 + byte "greeting" // (𝕡) name#0 | 0,"greeting" self.greeting compile/apps.py:35 app_global_get_ex // (𝕡) name#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.greeting compile/apps.py:35 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.greeting compile/apps.py:35 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_value%0#0,maybe_exists%0#0 self.greeting compile/apps.py:35 @@ -166,7 +166,7 @@ __init__: proto 0 0 // def __init__(self) -> None: compile/apps.py:63 __init___block@0: - byte "greeting" // "greeting" self.greeting compile/apps.py:23 + byte "greeting" // "greeting" self.greeting compile/apps.py:64 byte TMPL_GREETING // "greeting",TMPL_GREETING TemplateVar[String]("GREETING") compile/apps.py:64 app_global_put // self.greeting = TemplateVar[String]("GREETING") compile/apps.py:64 retsub // diff --git a/test_cases/compile/out/HelloTmpl.approval.teal b/test_cases/compile/out/HelloTmpl.approval.teal index 016a4f9e5b..74824b9afa 100644 --- a/test_cases/compile/out/HelloTmpl.approval.teal +++ b/test_cases/compile/out/HelloTmpl.approval.teal @@ -107,11 +107,7 @@ greet: // compile/apps.py:35 // return self.greeting + " " + name int 0 - // compile/apps.py:23 - // self.greeting = String() byte "greeting" - // compile/apps.py:35 - // return self.greeting + " " + name app_global_get_ex assert // check self.greeting exists byte " " @@ -126,11 +122,9 @@ __init__: // compile/apps.py:63 // def __init__(self) -> None: proto 0 0 - // compile/apps.py:23 - // self.greeting = String() - byte "greeting" // compile/apps.py:64 // self.greeting = TemplateVar[String]("GREETING") + byte "greeting" byte TMPL_GREETING app_global_put retsub diff --git a/test_cases/compile/out/HelloTmpl.arc32.json b/test_cases/compile/out/HelloTmpl.arc32.json index 4370f01447..7edacf8b77 100644 --- a/test_cases/compile/out/HelloTmpl.arc32.json +++ b/test_cases/compile/out/HelloTmpl.arc32.json @@ -17,7 +17,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb1RtcGwuYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9UbXBsLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo2MQogICAgLy8gY2xhc3MgSGVsbG9UbXBsKEhlbGxvQmFzZSk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANwogICAgbWV0aG9kICJjcmVhdGUoKXZvaWQiCiAgICBtZXRob2QgImRlbGV0ZSgpdm9pZCIKICAgIG1ldGhvZCAiZ3JlZXQoc3RyaW5nKXN0cmluZyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX3JvdXRlQDM6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiRGVsZXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgRGVsZXRlQXBwbGljYXRpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ncmVldF9yb3V0ZUA0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjYxCiAgICAvLyBjbGFzcyBIZWxsb1RtcGwoSGVsbG9CYXNlKToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdyZWV0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDc6CiAgICAvLyBjb21waWxlL2FwcHMucHk6NjEKICAgIC8vIGNsYXNzIEhlbGxvVG1wbChIZWxsb0Jhc2UpOgogICAgaW50IDQKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3VwZGF0ZUA4CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX191cGRhdGVAODoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyOQogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiVXBkYXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBjb21waWxlL2FwcHMucHk6MjktMzAKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICAvLyBkZWYgdXBkYXRlKHNlbGYpIC0+IE5vbmU6CiAgICBpbnQgMQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9CYXNlLmdyZWV0KG5hbWU6IGJ5dGVzKSAtPiBieXRlczoKZ3JlZXQ6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMtMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ3JlZXQoc2VsZiwgbmFtZTogU3RyaW5nKSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozNQogICAgLy8gcmV0dXJuIHNlbGYuZ3JlZXRpbmcgKyAiICIgKyBuYW1lCiAgICBpbnQgMAogICAgLy8gY29tcGlsZS9hcHBzLnB5OjIzCiAgICAvLyBzZWxmLmdyZWV0aW5nID0gU3RyaW5nKCkKICAgIGJ5dGUgImdyZWV0aW5nIgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjM1CiAgICAvLyByZXR1cm4gc2VsZi5ncmVldGluZyArICIgIiArIG5hbWUKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ncmVldGluZyBleGlzdHMKICAgIGJ5dGUgIiAiCiAgICBjb25jYXQKICAgIGZyYW1lX2RpZyAtMQogICAgY29uY2F0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb1RtcGwuX19pbml0X18oKSAtPiB2b2lkOgpfX2luaXRfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo2MwogICAgLy8gZGVmIF9faW5pdF9fKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyMwogICAgLy8gc2VsZi5ncmVldGluZyA9IFN0cmluZygpCiAgICBieXRlICJncmVldGluZyIKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo2NAogICAgLy8gc2VsZi5ncmVldGluZyA9IFRlbXBsYXRlVmFyW1N0cmluZ10oIkdSRUVUSU5HIikKICAgIGJ5dGUgVE1QTF9HUkVFVElORwogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb1RtcGwuYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9UbXBsLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIGNvbXBpbGUvYXBwcy5weTo2MQogICAgLy8gY2xhc3MgSGVsbG9UbXBsKEhlbGxvQmFzZSk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19iYXJlX3JvdXRpbmdANwogICAgbWV0aG9kICJjcmVhdGUoKXZvaWQiCiAgICBtZXRob2QgImRlbGV0ZSgpdm9pZCIKICAgIG1ldGhvZCAiZ3JlZXQoc3RyaW5nKXN0cmluZyIKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDAKICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2RlbGV0ZV9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX2dyZWV0X3JvdXRlQDQKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjY2CiAgICAvLyBAYXJjNC5hYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fZGVsZXRlX3JvdXRlQDM6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MjUKICAgIC8vIEBhcmM0LmFiaW1ldGhvZChhbGxvd19hY3Rpb25zPVsiRGVsZXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBEZWxldGVBcHBsaWNhdGlvbgogICAgPT0KICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgRGVsZXRlQXBwbGljYXRpb24KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ncmVldF9yb3V0ZUA0OgogICAgLy8gY29tcGlsZS9hcHBzLnB5OjMzCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgLy8gY29tcGlsZS9hcHBzLnB5OjYxCiAgICAvLyBjbGFzcyBIZWxsb1RtcGwoSGVsbG9CYXNlKToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICBjYWxsc3ViIGdyZWV0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDc6CiAgICAvLyBjb21waWxlL2FwcHMucHk6NjEKICAgIC8vIGNsYXNzIEhlbGxvVG1wbChIZWxsb0Jhc2UpOgogICAgaW50IDQKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIG1hdGNoIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3VwZGF0ZUA4CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX191cGRhdGVAODoKICAgIC8vIGNvbXBpbGUvYXBwcy5weToyOQogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiVXBkYXRlQXBwbGljYXRpb24iXSkKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBjb21waWxlL2FwcHMucHk6MjktMzAKICAgIC8vIEBhcmM0LmJhcmVtZXRob2QoYWxsb3dfYWN0aW9ucz1bIlVwZGF0ZUFwcGxpY2F0aW9uIl0pCiAgICAvLyBkZWYgdXBkYXRlKHNlbGYpIC0+IE5vbmU6CiAgICBpbnQgMQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9CYXNlLmdyZWV0KG5hbWU6IGJ5dGVzKSAtPiBieXRlczoKZ3JlZXQ6CiAgICAvLyBjb21waWxlL2FwcHMucHk6MzMtMzQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgZ3JlZXQoc2VsZiwgbmFtZTogU3RyaW5nKSAtPiBTdHJpbmc6CiAgICBwcm90byAxIDEKICAgIC8vIGNvbXBpbGUvYXBwcy5weTozNQogICAgLy8gcmV0dXJuIHNlbGYuZ3JlZXRpbmcgKyAiICIgKyBuYW1lCiAgICBpbnQgMAogICAgYnl0ZSAiZ3JlZXRpbmciCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ3JlZXRpbmcgZXhpc3RzCiAgICBieXRlICIgIgogICAgY29uY2F0CiAgICBmcmFtZV9kaWcgLTEKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5jb21waWxlLmFwcHMuSGVsbG9UbXBsLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyBjb21waWxlL2FwcHMucHk6NjMKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBjb21waWxlL2FwcHMucHk6NjQKICAgIC8vIHNlbGYuZ3JlZXRpbmcgPSBUZW1wbGF0ZVZhcltTdHJpbmddKCJHUkVFVElORyIpCiAgICBieXRlICJncmVldGluZyIKICAgIGJ5dGUgVE1QTF9HUkVFVElORwogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmNvbXBpbGUuYXBwcy5IZWxsb1RtcGwuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { diff --git a/test_cases/compile/out_unoptimized/Hello.approval.teal b/test_cases/compile/out_unoptimized/Hello.approval.teal index b24bcf36bd..b3523a95ca 100644 --- a/test_cases/compile/out_unoptimized/Hello.approval.teal +++ b/test_cases/compile/out_unoptimized/Hello.approval.teal @@ -135,11 +135,9 @@ create: // @arc4.abimethod(create="require") // def create(self, greeting: String) -> None: proto 1 0 - // compile/apps.py:23 - // self.greeting = String() - byte "greeting" // compile/apps.py:58 // self.greeting = greeting + byte "greeting" frame_dig -1 app_global_put retsub @@ -163,11 +161,7 @@ greet: // compile/apps.py:35 // return self.greeting + " " + name int 0 - // compile/apps.py:23 - // self.greeting = String() byte "greeting" - // compile/apps.py:35 - // return self.greeting + " " + name app_global_get_ex assert // check self.greeting exists byte " " diff --git a/test_cases/compile/out_unoptimized/HelloBase.approval.teal b/test_cases/compile/out_unoptimized/HelloBase.approval.teal index e73746abb8..7ccc04c18c 100644 --- a/test_cases/compile/out_unoptimized/HelloBase.approval.teal +++ b/test_cases/compile/out_unoptimized/HelloBase.approval.teal @@ -137,11 +137,7 @@ greet: // compile/apps.py:35 // return self.greeting + " " + name int 0 - // compile/apps.py:23 - // self.greeting = String() byte "greeting" - // compile/apps.py:35 - // return self.greeting + " " + name app_global_get_ex assert // check self.greeting exists byte " " diff --git a/test_cases/compile/out_unoptimized/HelloOtherConstants.approval.teal b/test_cases/compile/out_unoptimized/HelloOtherConstants.approval.teal index f4ed490978..cd33d2522d 100644 --- a/test_cases/compile/out_unoptimized/HelloOtherConstants.approval.teal +++ b/test_cases/compile/out_unoptimized/HelloOtherConstants.approval.teal @@ -135,11 +135,7 @@ greet: // compile/apps.py:99 // num_alpha = (self.num + 48).bytes[-1] int 0 - // compile/apps.py:85 - // self.num = TemplateVar[BigUInt]("NUM") byte "num" - // compile/apps.py:99 - // num_alpha = (self.num + 48).bytes[-1] app_global_get_ex assert // check self.num exists byte 0x30 @@ -148,11 +144,7 @@ greet: int 1 - int 0 - // compile/apps.py:85 - // self.num = TemplateVar[BigUInt]("NUM") byte "num" - // compile/apps.py:99 - // num_alpha = (self.num + 48).bytes[-1] app_global_get_ex assert // check self.num exists byte 0x30 @@ -167,11 +159,7 @@ greet: // compile/apps.py:101 // self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes + self.method int 0 - // compile/apps.py:84 - // self.greeting = TemplateVar[String]("GREETING") byte "greeting" - // compile/apps.py:101 - // self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes + self.method app_global_get_ex assert // check self.greeting exists byte 0x20 @@ -181,20 +169,12 @@ greet: uncover 1 concat int 0 - // compile/apps.py:86 - // self.address = TemplateVar[Account]("ACCOUNT") byte "address" - // compile/apps.py:101 - // self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes + self.method app_global_get_ex assert // check self.address exists concat int 0 - // compile/apps.py:87 - // self.method = TemplateVar[Bytes]("METHOD") byte "method" - // compile/apps.py:101 - // self.greeting.bytes + b" " + name.bytes + num_alpha + self.address.bytes + self.method app_global_get_ex assert // check self.method exists concat diff --git a/test_cases/compile/out_unoptimized/HelloPrfx.approval.teal b/test_cases/compile/out_unoptimized/HelloPrfx.approval.teal index 80b7a6fa5e..c3f7b44564 100644 --- a/test_cases/compile/out_unoptimized/HelloPrfx.approval.teal +++ b/test_cases/compile/out_unoptimized/HelloPrfx.approval.teal @@ -150,11 +150,7 @@ greet: // compile/apps.py:35 // return self.greeting + " " + name int 0 - // compile/apps.py:23 - // self.greeting = String() byte "greeting" - // compile/apps.py:35 - // return self.greeting + " " + name app_global_get_ex assert // check self.greeting exists byte " " @@ -178,11 +174,9 @@ __init__: // compile/apps.py:73 // def __init__(self) -> None: proto 0 0 - // compile/apps.py:23 - // self.greeting = String() - byte "greeting" // compile/apps.py:74 // self.greeting = TemplateVar[String]("GREETING", prefix="PRFX_") + byte "greeting" byte PRFX_GREETING app_global_put retsub diff --git a/test_cases/compile/out_unoptimized/HelloTmpl.approval.teal b/test_cases/compile/out_unoptimized/HelloTmpl.approval.teal index 033ab8c55a..deff46f1a0 100644 --- a/test_cases/compile/out_unoptimized/HelloTmpl.approval.teal +++ b/test_cases/compile/out_unoptimized/HelloTmpl.approval.teal @@ -150,11 +150,7 @@ greet: // compile/apps.py:35 // return self.greeting + " " + name int 0 - // compile/apps.py:23 - // self.greeting = String() byte "greeting" - // compile/apps.py:35 - // return self.greeting + " " + name app_global_get_ex assert // check self.greeting exists byte " " @@ -178,11 +174,9 @@ __init__: // compile/apps.py:63 // def __init__(self) -> None: proto 0 0 - // compile/apps.py:23 - // self.greeting = String() - byte "greeting" // compile/apps.py:64 // self.greeting = TemplateVar[String]("GREETING") + byte "greeting" byte TMPL_GREETING app_global_put retsub diff --git a/test_cases/conditional_execution/out/ConditionalExecutionContract.approval.mir b/test_cases/conditional_execution/out/ConditionalExecutionContract.approval.mir index 41948fc6f7..adf8547d09 100644 --- a/test_cases/conditional_execution/out/ConditionalExecutionContract.approval.mir +++ b/test_cases/conditional_execution/out/ConditionalExecutionContract.approval.mir @@ -30,7 +30,7 @@ main_or_contd@3: main_bool_merge@6: int 0 // 0 self.did_execute_a conditional_execution/contract.py:13 - byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:13 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_a conditional_execution/contract.py:13 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.did_execute_a conditional_execution/contract.py:13 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.did_execute_a conditional_execution/contract.py:13 @@ -42,7 +42,7 @@ main_bool_merge@6: main_and_contd@7: int 0 // 0 self.did_execute_b conditional_execution/contract.py:13 - byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:13 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_b conditional_execution/contract.py:13 // virtual: store maybe_exists%1#0 to l-stack (no copy) maybe_exists%1#0,{app_global_get_ex}.0 self.did_execute_b conditional_execution/contract.py:13 // virtual: store maybe_value%1#0 to l-stack (no copy) maybe_value%1#0,maybe_exists%1#0 self.did_execute_b conditional_execution/contract.py:13 @@ -80,7 +80,7 @@ main_or_contd@11: main_bool_merge@14: int 0 // 0 self.did_execute_a conditional_execution/contract.py:19 - byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:19 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_a conditional_execution/contract.py:19 // virtual: store maybe_exists%2#0 to l-stack (no copy) maybe_exists%2#0,{app_global_get_ex}.0 self.did_execute_a conditional_execution/contract.py:19 // virtual: store maybe_value%2#0 to l-stack (no copy) maybe_value%2#0,maybe_exists%2#0 self.did_execute_a conditional_execution/contract.py:19 @@ -92,7 +92,7 @@ main_bool_merge@14: main_and_contd@15: int 0 // 0 self.did_execute_b conditional_execution/contract.py:19 - byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:19 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_b conditional_execution/contract.py:19 // virtual: store maybe_exists%3#0 to l-stack (no copy) maybe_exists%3#0,{app_global_get_ex}.0 self.did_execute_b conditional_execution/contract.py:19 // virtual: store maybe_value%3#0 to l-stack (no copy) maybe_value%3#0,maybe_exists%3#0 self.did_execute_b conditional_execution/contract.py:19 @@ -130,7 +130,7 @@ main_and_contd@19: main_bool_merge@22: int 0 // 0 self.did_execute_a conditional_execution/contract.py:25 - byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:25 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_a conditional_execution/contract.py:25 // virtual: store maybe_exists%4#0 to l-stack (no copy) maybe_exists%4#0,{app_global_get_ex}.0 self.did_execute_a conditional_execution/contract.py:25 // virtual: store maybe_value%4#0 to l-stack (no copy) maybe_value%4#0,maybe_exists%4#0 self.did_execute_a conditional_execution/contract.py:25 @@ -142,7 +142,7 @@ main_bool_merge@22: main_and_contd@23: int 0 // 0 self.did_execute_b conditional_execution/contract.py:25 - byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:25 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_b conditional_execution/contract.py:25 // virtual: store maybe_exists%5#0 to l-stack (no copy) maybe_exists%5#0,{app_global_get_ex}.0 self.did_execute_b conditional_execution/contract.py:25 // virtual: store maybe_value%5#0 to l-stack (no copy) maybe_value%5#0,maybe_exists%5#0 self.did_execute_b conditional_execution/contract.py:25 @@ -180,7 +180,7 @@ main_and_contd@27: main_bool_merge@30: int 0 // 0 self.did_execute_a conditional_execution/contract.py:31 - byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:31 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_a conditional_execution/contract.py:31 // virtual: store maybe_exists%6#0 to l-stack (no copy) maybe_exists%6#0,{app_global_get_ex}.0 self.did_execute_a conditional_execution/contract.py:31 // virtual: store maybe_value%6#0 to l-stack (no copy) maybe_value%6#0,maybe_exists%6#0 self.did_execute_a conditional_execution/contract.py:31 @@ -192,7 +192,7 @@ main_bool_merge@30: main_and_contd@31: int 0 // 0 self.did_execute_b conditional_execution/contract.py:31 - byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:31 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_b conditional_execution/contract.py:31 // virtual: store maybe_exists%7#0 to l-stack (no copy) maybe_exists%7#0,{app_global_get_ex}.0 self.did_execute_b conditional_execution/contract.py:31 // virtual: store maybe_value%7#0 to l-stack (no copy) maybe_value%7#0,maybe_exists%7#0 self.did_execute_b conditional_execution/contract.py:31 @@ -222,7 +222,7 @@ main_bool_merge@34: callsub func_b // {func_b} valuated before indexing is done\n(self.func_a(True), self.func_b(True) conditional_execution/contract.py:34-35 pop // valuated before indexing is done\n(self.func_a(True), self.func_b(True) conditional_execution/contract.py:34-35 int 0 // 0 self.did_execute_a conditional_execution/contract.py:37 - byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:37 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_a conditional_execution/contract.py:37 // virtual: store maybe_exists%8#0 to l-stack (no copy) maybe_exists%8#0,{app_global_get_ex}.0 self.did_execute_a conditional_execution/contract.py:37 // virtual: store maybe_value%8#0 to l-stack (no copy) maybe_value%8#0,maybe_exists%8#0 self.did_execute_a conditional_execution/contract.py:37 @@ -234,7 +234,7 @@ main_bool_merge@34: main_and_contd@35: int 0 // 0 self.did_execute_b conditional_execution/contract.py:37 - byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:37 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_b conditional_execution/contract.py:37 // virtual: store maybe_exists%9#0 to l-stack (no copy) maybe_exists%9#0,{app_global_get_ex}.0 self.did_execute_b conditional_execution/contract.py:37 // virtual: store maybe_value%9#0 to l-stack (no copy) maybe_value%9#0,maybe_exists%9#0 self.did_execute_b conditional_execution/contract.py:37 @@ -278,7 +278,7 @@ main_ternary_false@40: main_ternary_merge@41: int 0 // 0 self.did_execute_a conditional_execution/contract.py:43 - byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:43 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_a conditional_execution/contract.py:43 // virtual: store maybe_exists%10#0 to l-stack (no copy) maybe_exists%10#0,{app_global_get_ex}.0 self.did_execute_a conditional_execution/contract.py:43 // virtual: store maybe_value%10#0 to l-stack (no copy) maybe_value%10#0,maybe_exists%10#0 self.did_execute_a conditional_execution/contract.py:43 @@ -290,7 +290,7 @@ main_ternary_merge@41: main_and_contd@42: int 0 // 0 self.did_execute_b conditional_execution/contract.py:43 - byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:43 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_b conditional_execution/contract.py:43 // virtual: store maybe_exists%11#0 to l-stack (no copy) maybe_exists%11#0,{app_global_get_ex}.0 self.did_execute_b conditional_execution/contract.py:43 // virtual: store maybe_value%11#0 to l-stack (no copy) maybe_value%11#0,maybe_exists%11#0 self.did_execute_b conditional_execution/contract.py:43 @@ -334,7 +334,7 @@ main_ternary_false@47: main_ternary_merge@48: int 0 // 0 self.did_execute_a conditional_execution/contract.py:49 - byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // 0,"did_execute_a" self.did_execute_a conditional_execution/contract.py:49 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_a conditional_execution/contract.py:49 // virtual: store maybe_exists%12#0 to l-stack (no copy) maybe_exists%12#0,{app_global_get_ex}.0 self.did_execute_a conditional_execution/contract.py:49 // virtual: store maybe_value%12#0 to l-stack (no copy) maybe_value%12#0,maybe_exists%12#0 self.did_execute_a conditional_execution/contract.py:49 @@ -346,7 +346,7 @@ main_ternary_merge@48: main_and_contd@49: int 0 // 0 self.did_execute_b conditional_execution/contract.py:49 - byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // 0,"did_execute_b" self.did_execute_b conditional_execution/contract.py:49 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.did_execute_b conditional_execution/contract.py:49 // virtual: store maybe_exists%13#0 to l-stack (no copy) maybe_exists%13#0,{app_global_get_ex}.0 self.did_execute_b conditional_execution/contract.py:49 // virtual: store maybe_value%13#0 to l-stack (no copy) maybe_value%13#0,maybe_exists%13#0 self.did_execute_b conditional_execution/contract.py:49 @@ -378,7 +378,7 @@ func_a: proto 1 1 // (𝕡) ret_val#0 | @subroutine\ndef func_a(self, ret_val: bool) -> bool: conditional_execution/contract.py:63-64 func_a_block@0: - byte "did_execute_a" // (𝕡) ret_val#0 | "did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // (𝕡) ret_val#0 | "did_execute_a" self.did_execute_a conditional_execution/contract.py:65 int 1 // (𝕡) ret_val#0 | "did_execute_a",1 True conditional_execution/contract.py:65 app_global_put // (𝕡) ret_val#0 | self.did_execute_a = True conditional_execution/contract.py:65 frame_dig -1 // load ret_val#0 from parameters (𝕡) ret_val#0 | ret_val#0 return ret_val conditional_execution/contract.py:66 @@ -390,7 +390,7 @@ func_b: proto 1 1 // (𝕡) ret_val#0 | @subroutine\ndef func_b(self, ret_val: bool) -> bool: conditional_execution/contract.py:68-69 func_b_block@0: - byte "did_execute_b" // (𝕡) ret_val#0 | "did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // (𝕡) ret_val#0 | "did_execute_b" self.did_execute_b conditional_execution/contract.py:70 int 1 // (𝕡) ret_val#0 | "did_execute_b",1 True conditional_execution/contract.py:70 app_global_put // (𝕡) ret_val#0 | self.did_execute_b = True conditional_execution/contract.py:70 frame_dig -1 // load ret_val#0 from parameters (𝕡) ret_val#0 | ret_val#0 return ret_val conditional_execution/contract.py:71 @@ -404,10 +404,10 @@ assert_and_reset: assert_and_reset_block@0: frame_dig -1 // load condition#0 from parameters (𝕡) condition#0 | condition#0 assert condition conditional_execution/contract.py:59 assert // (𝕡) condition#0 | assert condition conditional_execution/contract.py:59 - byte "did_execute_b" // (𝕡) condition#0 | "did_execute_b" self.did_execute_b conditional_execution/contract.py:7 + byte "did_execute_b" // (𝕡) condition#0 | "did_execute_b" self.did_execute_b conditional_execution/contract.py:60 int 0 // (𝕡) condition#0 | "did_execute_b",0 False conditional_execution/contract.py:60 app_global_put // (𝕡) condition#0 | self.did_execute_b = False conditional_execution/contract.py:60 - byte "did_execute_a" // (𝕡) condition#0 | "did_execute_a" self.did_execute_a conditional_execution/contract.py:6 + byte "did_execute_a" // (𝕡) condition#0 | "did_execute_a" self.did_execute_a conditional_execution/contract.py:61 int 0 // (𝕡) condition#0 | "did_execute_a",0 False conditional_execution/contract.py:61 app_global_put // (𝕡) condition#0 | self.did_execute_a = False conditional_execution/contract.py:61 retsub // diff --git a/test_cases/conditional_execution/out/ConditionalExecutionContract.approval.teal b/test_cases/conditional_execution/out/ConditionalExecutionContract.approval.teal index cb2e8a301f..0153bf4454 100644 --- a/test_cases/conditional_execution/out/ConditionalExecutionContract.approval.teal +++ b/test_cases/conditional_execution/out/ConditionalExecutionContract.approval.teal @@ -20,20 +20,12 @@ main_bool_merge@6: // conditional_execution/contract.py:13 // self.did_execute_a and not self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:13 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@9 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:13 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bnz main_bool_false@9 @@ -63,20 +55,12 @@ main_bool_merge@14: // conditional_execution/contract.py:19 // self.did_execute_a and self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:19 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@17 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:19 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bz main_bool_false@17 @@ -106,20 +90,12 @@ main_bool_merge@22: // conditional_execution/contract.py:25 // self.did_execute_a and not self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:25 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@25 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:25 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bnz main_bool_false@25 @@ -149,20 +125,12 @@ main_bool_merge@30: // conditional_execution/contract.py:31 // self.did_execute_a and self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:31 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@33 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:31 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bz main_bool_false@33 @@ -190,20 +158,12 @@ main_bool_merge@34: // conditional_execution/contract.py:37 // self.did_execute_a and self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:37 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@37 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:37 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bz main_bool_false@37 @@ -242,20 +202,12 @@ main_ternary_merge@41: // conditional_execution/contract.py:43 // self.did_execute_a and not self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:43 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@44 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:43 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bnz main_bool_false@44 @@ -294,20 +246,12 @@ main_ternary_merge@48: // conditional_execution/contract.py:49 // not self.did_execute_a and self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:49 - // not self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bnz main_bool_false@51 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:49 - // not self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bz main_bool_false@51 @@ -335,11 +279,9 @@ func_a: // @subroutine // def func_a(self, ret_val: bool) -> bool: proto 1 1 - // conditional_execution/contract.py:6 - // self.did_execute_a = False - byte "did_execute_a" // conditional_execution/contract.py:65 // self.did_execute_a = True + byte "did_execute_a" int 1 app_global_put // conditional_execution/contract.py:66 @@ -354,11 +296,9 @@ func_b: // @subroutine // def func_b(self, ret_val: bool) -> bool: proto 1 1 - // conditional_execution/contract.py:7 - // self.did_execute_b = False - byte "did_execute_b" // conditional_execution/contract.py:70 // self.did_execute_b = True + byte "did_execute_b" int 1 app_global_put // conditional_execution/contract.py:71 @@ -377,18 +317,14 @@ assert_and_reset: // assert condition frame_dig -1 assert - // conditional_execution/contract.py:7 - // self.did_execute_b = False - byte "did_execute_b" // conditional_execution/contract.py:60 // self.did_execute_b = False + byte "did_execute_b" int 0 app_global_put - // conditional_execution/contract.py:6 - // self.did_execute_a = False - byte "did_execute_a" // conditional_execution/contract.py:61 // self.did_execute_a = False + byte "did_execute_a" int 0 app_global_put retsub diff --git a/test_cases/conditional_execution/out_unoptimized/ConditionalExecutionContract.approval.teal b/test_cases/conditional_execution/out_unoptimized/ConditionalExecutionContract.approval.teal index d235457b98..1e59823476 100644 --- a/test_cases/conditional_execution/out_unoptimized/ConditionalExecutionContract.approval.teal +++ b/test_cases/conditional_execution/out_unoptimized/ConditionalExecutionContract.approval.teal @@ -25,20 +25,12 @@ main_bool_merge@6: // conditional_execution/contract.py:13 // self.did_execute_a and not self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:13 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@9 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:13 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bnz main_bool_false@9 @@ -73,20 +65,12 @@ main_bool_merge@14: // conditional_execution/contract.py:19 // self.did_execute_a and self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:19 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@17 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:19 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bz main_bool_false@17 @@ -119,20 +103,12 @@ main_bool_merge@22: // conditional_execution/contract.py:25 // self.did_execute_a and not self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:25 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@25 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:25 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bnz main_bool_false@25 @@ -165,20 +141,12 @@ main_bool_merge@30: // conditional_execution/contract.py:31 // self.did_execute_a and self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:31 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@33 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:31 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bz main_bool_false@33 @@ -206,20 +174,12 @@ main_bool_merge@34: // conditional_execution/contract.py:37 // self.did_execute_a and self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:37 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@37 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:37 - // self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bz main_bool_false@37 @@ -258,20 +218,12 @@ main_ternary_merge@41: // conditional_execution/contract.py:43 // self.did_execute_a and not self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:43 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bz main_bool_false@44 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:43 - // self.did_execute_a and not self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bnz main_bool_false@44 @@ -310,20 +262,12 @@ main_ternary_merge@48: // conditional_execution/contract.py:49 // not self.did_execute_a and self.did_execute_b, int 0 - // conditional_execution/contract.py:6 - // self.did_execute_a = False byte "did_execute_a" - // conditional_execution/contract.py:49 - // not self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_a exists bnz main_bool_false@51 int 0 - // conditional_execution/contract.py:7 - // self.did_execute_b = False byte "did_execute_b" - // conditional_execution/contract.py:49 - // not self.did_execute_a and self.did_execute_b, app_global_get_ex assert // check self.did_execute_b exists bz main_bool_false@51 @@ -351,11 +295,9 @@ func_a: // @subroutine // def func_a(self, ret_val: bool) -> bool: proto 1 1 - // conditional_execution/contract.py:6 - // self.did_execute_a = False - byte "did_execute_a" // conditional_execution/contract.py:65 // self.did_execute_a = True + byte "did_execute_a" int 1 app_global_put // conditional_execution/contract.py:66 @@ -370,11 +312,9 @@ func_b: // @subroutine // def func_b(self, ret_val: bool) -> bool: proto 1 1 - // conditional_execution/contract.py:7 - // self.did_execute_b = False - byte "did_execute_b" // conditional_execution/contract.py:70 // self.did_execute_b = True + byte "did_execute_b" int 1 app_global_put // conditional_execution/contract.py:71 @@ -393,18 +333,14 @@ assert_and_reset: // assert condition frame_dig -1 assert - // conditional_execution/contract.py:7 - // self.did_execute_b = False - byte "did_execute_b" // conditional_execution/contract.py:60 // self.did_execute_b = False + byte "did_execute_b" int 0 app_global_put - // conditional_execution/contract.py:6 - // self.did_execute_a = False - byte "did_execute_a" // conditional_execution/contract.py:61 // self.did_execute_a = False + byte "did_execute_a" int 0 app_global_put retsub diff --git a/test_cases/everything/out/MyContract.approval.mir b/test_cases/everything/out/MyContract.approval.mir index e005971fdd..5f68239146 100644 --- a/test_cases/everything/out/MyContract.approval.mir +++ b/test_cases/everything/out/MyContract.approval.mir @@ -223,7 +223,7 @@ register_block@0: register_if_body@1: int 0 // (𝕡) name#0 | 0 0 everything/contract.py:51 int 0 // (𝕡) name#0 | 0,0 self.name.maybe(account=0) everything/contract.py:51 - byte "name" // (𝕡) name#0 | 0,0,"name" self.name everything/contract.py:39 + byte "name" // (𝕡) name#0 | 0,0,"name" self.name everything/contract.py:51 app_local_get_ex // (𝕡) name#0 | {app_local_get_ex}.0,{app_local_get_ex}.1 self.name.maybe(account=0) everything/contract.py:51 cover 1 // store sender_name_existed#0 to l-stack (no copy) (𝕡) name#0 | sender_name_existed#0,{app_local_get_ex}.0 self.name.maybe(account=0) everything/contract.py:51 pop // (𝕡) name#0 | sender_name_existed#0 self.name.maybe(account=0) everything/contract.py:51 @@ -233,7 +233,7 @@ register_if_body@1: register_if_body@2: int 0 // (𝕡) name#0 | 0 self.counter everything/contract.py:53 - byte "counter" // (𝕡) name#0 | 0,"counter" self.counter everything/contract.py:45 + byte "counter" // (𝕡) name#0 | 0,"counter" self.counter everything/contract.py:53 app_global_get_ex // (𝕡) name#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.counter everything/contract.py:53 // virtual: store maybe_exists%1#0 to l-stack (no copy) (𝕡) name#0 | maybe_exists%1#0,{app_global_get_ex}.0 self.counter everything/contract.py:53 // virtual: store maybe_value%1#0 to l-stack (no copy) (𝕡) name#0 | maybe_value%1#0,maybe_exists%1#0 self.counter everything/contract.py:53 @@ -245,14 +245,14 @@ register_if_body@2: // virtual: load tmp%2#0 from l-stack (no copy) (𝕡) name#0 | maybe_value%1#0,tmp%2#0 self.counter += multiplicative_identity() everything/contract.py:53 + // (𝕡) name#0 | {+} self.counter += multiplicative_identity() everything/contract.py:53 // virtual: store new_state_value%0#0 to l-stack (no copy) (𝕡) name#0 | new_state_value%0#0 self.counter += multiplicative_identity() everything/contract.py:53 - byte "counter" // (𝕡) name#0 | new_state_value%0#0,"counter" self.counter everything/contract.py:45 + byte "counter" // (𝕡) name#0 | new_state_value%0#0,"counter" self.counter everything/contract.py:53 uncover 1 // load new_state_value%0#0 from l-stack (no copy) (𝕡) name#0 | "counter",new_state_value%0#0 self.counter += multiplicative_identity() everything/contract.py:53 app_global_put // (𝕡) name#0 | self.counter += multiplicative_identity() everything/contract.py:53 // Implicit fall through to register_after_if_else@4 // (𝕡) name#0 | register_after_if_else@4: int 0 // (𝕡) name#0 | 0 0 everything/contract.py:54 - byte "name" // (𝕡) name#0 | 0,"name" self.name everything/contract.py:39 + byte "name" // (𝕡) name#0 | 0,"name" self.name everything/contract.py:54 frame_dig -1 // load name#0 from parameters (𝕡) name#0 | 0,"name",name#0 self.name[0] = name everything/contract.py:54 app_local_put // (𝕡) name#0 | self.name[0] = name everything/contract.py:54 retsub // @@ -275,7 +275,7 @@ say_hello_block@0: callsub _check_ban_list // self._check_ban_list() everything/contract.py:58 int 0 // 0 0 everything/contract.py:59 int 0 // 0,0 self.name.maybe(account=0) everything/contract.py:59 - byte "name" // 0,0,"name" self.name everything/contract.py:39 + byte "name" // 0,0,"name" self.name everything/contract.py:59 app_local_get_ex // {app_local_get_ex}.0,{app_local_get_ex}.1 self.name.maybe(account=0) everything/contract.py:59 // virtual: store exists#0 to l-stack (no copy) exists#0,{app_local_get_ex}.0 self.name.maybe(account=0) everything/contract.py:59 // virtual: store name#0 to f-stack (𝕗) name#0 | exists#0 self.name.maybe(account=0) everything/contract.py:59 @@ -397,7 +397,7 @@ _remove_sender: _remove_sender_block@0: int 0 // 0 self.counter everything/contract.py:83 - byte "counter" // 0,"counter" self.counter everything/contract.py:45 + byte "counter" // 0,"counter" self.counter everything/contract.py:83 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.counter everything/contract.py:83 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.counter everything/contract.py:83 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.counter everything/contract.py:83 @@ -409,7 +409,7 @@ _remove_sender_block@0: // virtual: load tmp%0#0 from l-stack (no copy) maybe_value%0#0,tmp%0#0 self.counter -= positive_one() everything/contract.py:83 - // {-} self.counter -= positive_one() everything/contract.py:83 // virtual: store new_state_value%0#0 to l-stack (no copy) new_state_value%0#0 self.counter -= positive_one() everything/contract.py:83 - byte "counter" // new_state_value%0#0,"counter" self.counter everything/contract.py:45 + byte "counter" // new_state_value%0#0,"counter" self.counter everything/contract.py:83 uncover 1 // load new_state_value%0#0 from l-stack (no copy) "counter",new_state_value%0#0 self.counter -= positive_one() everything/contract.py:83 app_global_put // self.counter -= positive_one() everything/contract.py:83 retsub // diff --git a/test_cases/everything/out/MyContract.approval.teal b/test_cases/everything/out/MyContract.approval.teal index 2ae1b1c194..405cc949c3 100644 --- a/test_cases/everything/out/MyContract.approval.teal +++ b/test_cases/everything/out/MyContract.approval.teal @@ -195,11 +195,7 @@ register: // sender_name, sender_name_existed = self.name.maybe(account=0) int 0 dup - // everything/contract.py:39 - // self.name = LocalState(String) byte "name" - // everything/contract.py:51 - // sender_name, sender_name_existed = self.name.maybe(account=0) app_local_get_ex bury 1 // everything/contract.py:52 @@ -208,20 +204,12 @@ register: // everything/contract.py:53 // self.counter += multiplicative_identity() # has full FuncDef int 0 - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:53 - // self.counter += multiplicative_identity() # has full FuncDef app_global_get_ex assert // check self.counter exists callsub multiplicative_identity + - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:53 - // self.counter += multiplicative_identity() # has full FuncDef swap app_global_put @@ -229,11 +217,7 @@ register_after_if_else@4: // everything/contract.py:54 // self.name[0] = name int 0 - // everything/contract.py:39 - // self.name = LocalState(String) byte "name" - // everything/contract.py:54 - // self.name[0] = name frame_dig -1 app_local_put retsub @@ -264,11 +248,7 @@ say_hello: // name, exists = self.name.maybe(account=0) int 0 dup - // everything/contract.py:39 - // self.name = LocalState(String) byte "name" - // everything/contract.py:59 - // name, exists = self.name.maybe(account=0) app_local_get_ex // everything/contract.py:60 // if not exists: @@ -365,20 +345,12 @@ _remove_sender: // everything/contract.py:83 // self.counter -= positive_one() int 0 - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:83 - // self.counter -= positive_one() app_global_get_ex assert // check self.counter exists callsub positive_one - - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:83 - // self.counter -= positive_one() swap app_global_put retsub diff --git a/test_cases/everything/out/MyContract.arc32.json b/test_cases/everything/out/MyContract.arc32.json index 0c87dcdb5e..2bc6852672 100644 --- a/test_cases/everything/out/MyContract.arc32.json +++ b/test_cases/everything/out/MyContract.arc32.json @@ -28,8 +28,8 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5hcHByb3ZhbF9wcm9ncmFtOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LkV2ZXJ5dGhpbmcuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTozNwogICAgLy8gY2xhc3MgRXZlcnl0aGluZyhBUkM0Q29udHJhY3QsIE15TWlkZGxlQmFzZSwgbmFtZT0iTXlDb250cmFjdCIpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMAogICAgbWV0aG9kICJjcmVhdGUoKXZvaWQiCiAgICBtZXRob2QgInJlZ2lzdGVyKHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJzYXlfaGVsbG8oKXN0cmluZyIKICAgIG1ldGhvZCAiY2FsY3VsYXRlKHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJjbG9zZV9vdXQoKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jcmVhdGVfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19yZWdpc3Rlcl9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NheV9oZWxsb19yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NhbGN1bGF0ZV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2Nsb3NlX291dF9yb3V0ZUA2CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jcmVhdGVfcm91dGVAMjoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NDEKICAgIC8vIEBhYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgY2FsbHN1YiBjcmVhdGUKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3JlZ2lzdGVyX3JvdXRlQDM6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBAYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJOb09wIiwgIk9wdEluIl0pCiAgICBpbnQgMQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgc2hsCiAgICBpbnQgMwogICAgJgogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBvbmUgb2YgTm9PcCwgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBjbGFzcyBFdmVyeXRoaW5nKEFSQzRDb250cmFjdCwgTXlNaWRkbGVCYXNlLCBuYW1lPSJNeUNvbnRyYWN0Iik6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBAYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJOb09wIiwgIk9wdEluIl0pCiAgICBjYWxsc3ViIHJlZ2lzdGVyCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zYXlfaGVsbG9fcm91dGVANDoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NTYKICAgIC8vIEBhYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgc2F5X2hlbGxvCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jYWxjdWxhdGVfcm91dGVANToKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjQKICAgIC8vIEBhYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6MzcKICAgIC8vIGNsYXNzIEV2ZXJ5dGhpbmcoQVJDNENvbnRyYWN0LCBNeU1pZGRsZUJhc2UsIG5hbWU9Ik15Q29udHJhY3QiKToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjQKICAgIC8vIEBhYmltZXRob2QKICAgIGNhbGxzdWIgY2FsY3VsYXRlCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jbG9zZV9vdXRfcm91dGVANjoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjkKICAgIC8vIEBhYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIkNsb3NlT3V0Il0pCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBpbnQgQ2xvc2VPdXQKICAgID09CiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIENsb3NlT3V0CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBjbG9zZV9vdXQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBjbGFzcyBFdmVyeXRoaW5nKEFSQzRDb250cmFjdCwgTXlNaWRkbGVCYXNlLCBuYW1lPSJNeUNvbnRyYWN0Iik6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LkV2ZXJ5dGhpbmcuY3JlYXRlKCkgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo0MS00MgogICAgLy8gQGFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBzZWxmLl9jaGVja19iYW5fbGlzdCgpCiAgICBjYWxsc3ViIF9jaGVja19iYW5fbGlzdAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo0NAogICAgLy8gc2VsZi5yZW1lbWJlcl9jcmVhdG9yKCkKICAgIGNhbGxzdWIgcmVtZW1iZXJfY3JlYXRvcgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo0NQogICAgLy8gc2VsZi5jb3VudGVyID0gVUludDY0KFpFUk8pCiAgICBieXRlICJjb3VudGVyIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5fY2hlY2tfYmFuX2xpc3QoKSAtPiB2b2lkOgpfY2hlY2tfYmFuX2xpc3Q6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojc3LTc4CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9jaGVja19iYW5fbGlzdChzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyBhc3NlcnQgb3AuVHhuLnNlbmRlciAhPSBnZXRfYmFubmVkKCksICJZb3UgYXJlIGJhbm5lZCwgZ29vZGJ5ZSIKICAgIHR4biBTZW5kZXIKICAgIGNhbGxzdWIgZ2V0X2Jhbm5lZAogICAgIT0KICAgIGFzc2VydCAvLyBZb3UgYXJlIGJhbm5lZCwgZ29vZGJ5ZQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LmdldF9iYW5uZWQoKSAtPiBieXRlczoKZ2V0X2Jhbm5lZDoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6MjMtMjQKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgZ2V0X2Jhbm5lZCgpIC0+IEFjY291bnQ6CiAgICBwcm90byAwIDEKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6MjUKICAgIC8vIGFkZHIgPSBBY2NvdW50KEJBTk5FRCkKICAgIGFkZHIgVkNNSktXT1k1UDVQN1NLTVpGRk9DRVJPUEpDWk9USUpNTklZTlVDS0g3TFJPNDVKTUpQNlVZQklKQQogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weToyNgogICAgLy8gcmV0dXJuIGFkZHIKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5teV9iYXNlLk15QmFzZS5yZW1lbWJlcl9jcmVhdG9yKCkgLT4gdm9pZDoKcmVtZW1iZXJfY3JlYXRvcjoKICAgIC8vIGV2ZXJ5dGhpbmcvbXlfYmFzZS5weTo3LTgKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgcmVtZW1iZXJfY3JlYXRvcihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBldmVyeXRoaW5nL215X2Jhc2UucHk6OQogICAgLy8gc2VsZi5jcmVhdG9yID0gb3AuVHhuLnNlbmRlcgogICAgYnl0ZSAiY3JlYXRvciIKICAgIHR4biBTZW5kZXIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5yZWdpc3RlcihuYW1lOiBieXRlcykgLT4gdm9pZDoKcmVnaXN0ZXI6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ3LTQ4CiAgICAvLyBAYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJOb09wIiwgIk9wdEluIl0pCiAgICAvLyBkZWYgcmVnaXN0ZXIoc2VsZiwgbmFtZTogU3RyaW5nKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyBzZWxmLl9jaGVja19iYW5fbGlzdCgpCiAgICBjYWxsc3ViIF9jaGVja19iYW5fbGlzdAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1MAogICAgLy8gaWYgb3AuVHhuLm9uX2NvbXBsZXRpb24gPT0gT25Db21wbGV0ZUFjdGlvbi5PcHRJbjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBPcHRJbgogICAgPT0KICAgIGJ6IHJlZ2lzdGVyX2FmdGVyX2lmX2Vsc2VANAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1MQogICAgLy8gc2VuZGVyX25hbWUsIHNlbmRlcl9uYW1lX2V4aXN0ZWQgPSBzZWxmLm5hbWUubWF5YmUoYWNjb3VudD0wKQogICAgaW50IDAKICAgIGR1cAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTozOQogICAgLy8gc2VsZi5uYW1lID0gTG9jYWxTdGF0ZShTdHJpbmcpCiAgICBieXRlICJuYW1lIgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1MQogICAgLy8gc2VuZGVyX25hbWUsIHNlbmRlcl9uYW1lX2V4aXN0ZWQgPSBzZWxmLm5hbWUubWF5YmUoYWNjb3VudD0wKQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYnVyeSAxCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjUyCiAgICAvLyBpZiBub3Qgc2VuZGVyX25hbWVfZXhpc3RlZDoKICAgIGJueiByZWdpc3Rlcl9hZnRlcl9pZl9lbHNlQDQKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NTMKICAgIC8vIHNlbGYuY291bnRlciArPSBtdWx0aXBsaWNhdGl2ZV9pZGVudGl0eSgpICAjIGhhcyBmdWxsIEZ1bmNEZWYKICAgIGludCAwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ1CiAgICAvLyBzZWxmLmNvdW50ZXIgPSBVSW50NjQoWkVSTykKICAgIGJ5dGUgImNvdW50ZXIiCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjUzCiAgICAvLyBzZWxmLmNvdW50ZXIgKz0gbXVsdGlwbGljYXRpdmVfaWRlbnRpdHkoKSAgIyBoYXMgZnVsbCBGdW5jRGVmCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuY291bnRlciBleGlzdHMKICAgIGNhbGxzdWIgbXVsdGlwbGljYXRpdmVfaWRlbnRpdHkKICAgICsKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NDUKICAgIC8vIHNlbGYuY291bnRlciA9IFVJbnQ2NChaRVJPKQogICAgYnl0ZSAiY291bnRlciIKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NTMKICAgIC8vIHNlbGYuY291bnRlciArPSBtdWx0aXBsaWNhdGl2ZV9pZGVudGl0eSgpICAjIGhhcyBmdWxsIEZ1bmNEZWYKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CgpyZWdpc3Rlcl9hZnRlcl9pZl9lbHNlQDQ6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjU0CiAgICAvLyBzZWxmLm5hbWVbMF0gPSBuYW1lCiAgICBpbnQgMAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTozOQogICAgLy8gc2VsZi5uYW1lID0gTG9jYWxTdGF0ZShTdHJpbmcpCiAgICBieXRlICJuYW1lIgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1NAogICAgLy8gc2VsZi5uYW1lWzBdID0gbmFtZQogICAgZnJhbWVfZGlnIC0xCiAgICBhcHBfbG9jYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcubXlfYmFzZS5tdWx0aXBsaWNhdGl2ZV9pZGVudGl0eSgpIC0+IHVpbnQ2NDoKbXVsdGlwbGljYXRpdmVfaWRlbnRpdHk6CiAgICAvLyBldmVyeXRoaW5nL215X2Jhc2UucHk6MTgtMTkKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgbXVsdGlwbGljYXRpdmVfaWRlbnRpdHkoKSAtPiBVSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGV2ZXJ5dGhpbmcvbXlfYmFzZS5weToyMAogICAgLy8gcmV0dXJuIFVJbnQ2NCgxKQogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5jb250cmFjdC5FdmVyeXRoaW5nLnNheV9oZWxsbygpIC0+IGJ5dGVzOgpzYXlfaGVsbG86CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjU2LTU3CiAgICAvLyBAYWJpbWV0aG9kCiAgICAvLyBkZWYgc2F5X2hlbGxvKHNlbGYpIC0+IFN0cmluZzoKICAgIHByb3RvIDAgMQogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1OAogICAgLy8gc2VsZi5fY2hlY2tfYmFuX2xpc3QoKQogICAgY2FsbHN1YiBfY2hlY2tfYmFuX2xpc3QKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NTkKICAgIC8vIG5hbWUsIGV4aXN0cyA9IHNlbGYubmFtZS5tYXliZShhY2NvdW50PTApCiAgICBpbnQgMAogICAgZHVwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjM5CiAgICAvLyBzZWxmLm5hbWUgPSBMb2NhbFN0YXRlKFN0cmluZykKICAgIGJ5dGUgIm5hbWUiCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBuYW1lLCBleGlzdHMgPSBzZWxmLm5hbWUubWF5YmUoYWNjb3VudD0wKQogICAgYXBwX2xvY2FsX2dldF9leAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo2MAogICAgLy8gaWYgbm90IGV4aXN0czoKICAgIGJueiBzYXlfaGVsbG9fYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjYxCiAgICAvLyByZXR1cm4gU3RyaW5nKCJIb3dkeSBzdHJhbmdlciEiKQogICAgYnl0ZSAweDAwMGY0ODZmNzc2NDc5MjA3Mzc0NzI2MTZlNjc2NTcyMjEKICAgIHN3YXAKICAgIHJldHN1YgoKc2F5X2hlbGxvX2FmdGVyX2lmX2Vsc2VAMjoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjIKICAgIC8vIHJldHVybiAiSGVsbG8sICIgKyBuYW1lICsgIiEiCiAgICBmcmFtZV9kaWcgMAogICAgZXh0cmFjdCAyIDAKICAgIGJ5dGUgMHg0ODY1NmM2YzZmMmMyMAogICAgc3dhcAogICAgY29uY2F0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZXh0cmFjdCAyIDAKICAgIGJ5dGUgMHgyMQogICAgY29uY2F0CiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LkV2ZXJ5dGhpbmcuY2FsY3VsYXRlKGE6IGJ5dGVzLCBiOiBieXRlcykgLT4gYnl0ZXM6CmNhbGN1bGF0ZToKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjQtNjUKICAgIC8vIEBhYmltZXRob2QKICAgIC8vIGRlZiBjYWxjdWxhdGUoc2VsZiwgYTogYXJjNF9VSW50NjQsIGI6IGFyYzRfVUludDY0KSAtPiBhcmM0X1VJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo2NgogICAgLy8gYyA9IHN1cGVyKCkuY2FsY3VsYXRlKGEsIGIpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgY2FsbHN1YiB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcubXlfYmFzZS5NeU1pZGRsZUJhc2UuY2FsY3VsYXRlCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjY3CiAgICAvLyByZXR1cm4gYXJjNF9VSW50NjQoYy5uYXRpdmUgKiBiLm5hdGl2ZSkKICAgIGJ0b2kKICAgIGZyYW1lX2RpZyAtMQogICAgYnRvaQogICAgKgogICAgaXRvYgogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLm15X2Jhc2UuTXlNaWRkbGVCYXNlLmNhbGN1bGF0ZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgp0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcubXlfYmFzZS5NeU1pZGRsZUJhc2UuY2FsY3VsYXRlOgogICAgLy8gZXZlcnl0aGluZy9teV9iYXNlLnB5OjEzLTE0CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGNhbGN1bGF0ZShzZWxmLCBhOiBhcmM0LlVJbnQ2NCwgYjogYXJjNC5VSW50NjQpIC0+IGFyYzQuVUludDY0OgogICAgcHJvdG8gMiAxCiAgICAvLyBldmVyeXRoaW5nL215X2Jhc2UucHk6MTUKICAgIC8vIHJldHVybiBhcmM0LlVJbnQ2NChhLm5hdGl2ZSArIGIubmF0aXZlKQogICAgZnJhbWVfZGlnIC0yCiAgICBidG9pCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICsKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5jb250cmFjdC5FdmVyeXRoaW5nLmNsb3NlX291dCgpIC0+IHZvaWQ6CmNsb3NlX291dDoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjktNzAKICAgIC8vIEBhYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIkNsb3NlT3V0Il0pCiAgICAvLyBkZWYgY2xvc2Vfb3V0KHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NzEKICAgIC8vIHNlbGYuX3JlbW92ZV9zZW5kZXIoKQogICAgY2FsbHN1YiBfcmVtb3ZlX3NlbmRlcgogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LkV2ZXJ5dGhpbmcuX3JlbW92ZV9zZW5kZXIoKSAtPiB2b2lkOgpfcmVtb3ZlX3NlbmRlcjoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6ODEtODIKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgX3JlbW92ZV9zZW5kZXIoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo4MwogICAgLy8gc2VsZi5jb3VudGVyIC09IHBvc2l0aXZlX29uZSgpCiAgICBpbnQgMAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo0NQogICAgLy8gc2VsZi5jb3VudGVyID0gVUludDY0KFpFUk8pCiAgICBieXRlICJjb3VudGVyIgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo4MwogICAgLy8gc2VsZi5jb3VudGVyIC09IHBvc2l0aXZlX29uZSgpCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuY291bnRlciBleGlzdHMKICAgIGNhbGxzdWIgcG9zaXRpdmVfb25lCiAgICAtCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ1CiAgICAvLyBzZWxmLmNvdW50ZXIgPSBVSW50NjQoWkVSTykKICAgIGJ5dGUgImNvdW50ZXIiCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjgzCiAgICAvLyBzZWxmLmNvdW50ZXIgLT0gcG9zaXRpdmVfb25lKCkKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QucG9zaXRpdmVfb25lKCkgLT4gdWludDY0Ogpwb3NpdGl2ZV9vbmU6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojg2LTg3CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHBvc2l0aXZlX29uZSgpIC0+IFVJbnQ2NDoKICAgIHByb3RvIDAgMQogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo4OAogICAgLy8gcmV0dXJuIFVJbnQ2NCgxKQogICAgaW50IDEKICAgIHJldHN1Ygo=", - "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo3NAogICAgLy8gc2VsZi5fcmVtb3ZlX3NlbmRlcigpCiAgICBjYWxsc3ViIF9yZW1vdmVfc2VuZGVyCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5jb250cmFjdC5FdmVyeXRoaW5nLl9yZW1vdmVfc2VuZGVyKCkgLT4gdm9pZDoKX3JlbW92ZV9zZW5kZXI6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjgxLTgyCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9yZW1vdmVfc2VuZGVyKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6ODMKICAgIC8vIHNlbGYuY291bnRlciAtPSBwb3NpdGl2ZV9vbmUoKQogICAgaW50IDAKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NDUKICAgIC8vIHNlbGYuY291bnRlciA9IFVJbnQ2NChaRVJPKQogICAgYnl0ZSAiY291bnRlciIKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6ODMKICAgIC8vIHNlbGYuY291bnRlciAtPSBwb3NpdGl2ZV9vbmUoKQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmNvdW50ZXIgZXhpc3RzCiAgICBjYWxsc3ViIHBvc2l0aXZlX29uZQogICAgLQogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo0NQogICAgLy8gc2VsZi5jb3VudGVyID0gVUludDY0KFpFUk8pCiAgICBieXRlICJjb3VudGVyIgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo4MwogICAgLy8gc2VsZi5jb3VudGVyIC09IHBvc2l0aXZlX29uZSgpCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LnBvc2l0aXZlX29uZSgpIC0+IHVpbnQ2NDoKcG9zaXRpdmVfb25lOgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo4Ni04NwogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBwb3NpdGl2ZV9vbmUoKSAtPiBVSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6ODgKICAgIC8vIHJldHVybiBVSW50NjQoMSkKICAgIGludCAxCiAgICByZXRzdWIK" + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5hcHByb3ZhbF9wcm9ncmFtOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LkV2ZXJ5dGhpbmcuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTozNwogICAgLy8gY2xhc3MgRXZlcnl0aGluZyhBUkM0Q29udHJhY3QsIE15TWlkZGxlQmFzZSwgbmFtZT0iTXlDb250cmFjdCIpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYWZ0ZXJfaWZfZWxzZUAxMAogICAgbWV0aG9kICJjcmVhdGUoKXZvaWQiCiAgICBtZXRob2QgInJlZ2lzdGVyKHN0cmluZyl2b2lkIgogICAgbWV0aG9kICJzYXlfaGVsbG8oKXN0cmluZyIKICAgIG1ldGhvZCAiY2FsY3VsYXRlKHVpbnQ2NCx1aW50NjQpdWludDY0IgogICAgbWV0aG9kICJjbG9zZV9vdXQoKXZvaWQiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19jcmVhdGVfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19yZWdpc3Rlcl9yb3V0ZUAzIF9fcHV5YV9hcmM0X3JvdXRlcl9fX3NheV9oZWxsb19yb3V0ZUA0IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2NhbGN1bGF0ZV9yb3V0ZUA1IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2Nsb3NlX291dF9yb3V0ZUA2CiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jcmVhdGVfcm91dGVAMjoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NDEKICAgIC8vIEBhYmltZXRob2QoY3JlYXRlPSJyZXF1aXJlIikKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgY2FsbHN1YiBjcmVhdGUKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3JlZ2lzdGVyX3JvdXRlQDM6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBAYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJOb09wIiwgIk9wdEluIl0pCiAgICBpbnQgMQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgc2hsCiAgICBpbnQgMwogICAgJgogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBvbmUgb2YgTm9PcCwgT3B0SW4KICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBjbGFzcyBFdmVyeXRoaW5nKEFSQzRDb250cmFjdCwgTXlNaWRkbGVCYXNlLCBuYW1lPSJNeUNvbnRyYWN0Iik6CiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAxCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBAYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJOb09wIiwgIk9wdEluIl0pCiAgICBjYWxsc3ViIHJlZ2lzdGVyCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19zYXlfaGVsbG9fcm91dGVANDoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NTYKICAgIC8vIEBhYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgc2F5X2hlbGxvCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jYWxjdWxhdGVfcm91dGVANToKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjQKICAgIC8vIEBhYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6MzcKICAgIC8vIGNsYXNzIEV2ZXJ5dGhpbmcoQVJDNENvbnRyYWN0LCBNeU1pZGRsZUJhc2UsIG5hbWU9Ik15Q29udHJhY3QiKToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDIKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjQKICAgIC8vIEBhYmltZXRob2QKICAgIGNhbGxzdWIgY2FsY3VsYXRlCiAgICBieXRlIDB4MTUxZjdjNzUKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19jbG9zZV9vdXRfcm91dGVANjoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjkKICAgIC8vIEBhYmltZXRob2QoYWxsb3dfYWN0aW9ucz1bIkNsb3NlT3V0Il0pCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBpbnQgQ2xvc2VPdXQKICAgID09CiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIENsb3NlT3V0CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBjbG9zZV9vdXQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjM3CiAgICAvLyBjbGFzcyBFdmVyeXRoaW5nKEFSQzRDb250cmFjdCwgTXlNaWRkbGVCYXNlLCBuYW1lPSJNeUNvbnRyYWN0Iik6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LkV2ZXJ5dGhpbmcuY3JlYXRlKCkgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo0MS00MgogICAgLy8gQGFiaW1ldGhvZChjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQzCiAgICAvLyBzZWxmLl9jaGVja19iYW5fbGlzdCgpCiAgICBjYWxsc3ViIF9jaGVja19iYW5fbGlzdAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo0NAogICAgLy8gc2VsZi5yZW1lbWJlcl9jcmVhdG9yKCkKICAgIGNhbGxzdWIgcmVtZW1iZXJfY3JlYXRvcgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo0NQogICAgLy8gc2VsZi5jb3VudGVyID0gVUludDY0KFpFUk8pCiAgICBieXRlICJjb3VudGVyIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5fY2hlY2tfYmFuX2xpc3QoKSAtPiB2b2lkOgpfY2hlY2tfYmFuX2xpc3Q6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojc3LTc4CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9jaGVja19iYW5fbGlzdChzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojc5CiAgICAvLyBhc3NlcnQgb3AuVHhuLnNlbmRlciAhPSBnZXRfYmFubmVkKCksICJZb3UgYXJlIGJhbm5lZCwgZ29vZGJ5ZSIKICAgIHR4biBTZW5kZXIKICAgIGNhbGxzdWIgZ2V0X2Jhbm5lZAogICAgIT0KICAgIGFzc2VydCAvLyBZb3UgYXJlIGJhbm5lZCwgZ29vZGJ5ZQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLmNvbnRyYWN0LmdldF9iYW5uZWQoKSAtPiBieXRlczoKZ2V0X2Jhbm5lZDoKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6MjMtMjQKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgZ2V0X2Jhbm5lZCgpIC0+IEFjY291bnQ6CiAgICBwcm90byAwIDEKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6MjUKICAgIC8vIGFkZHIgPSBBY2NvdW50KEJBTk5FRCkKICAgIGFkZHIgVkNNSktXT1k1UDVQN1NLTVpGRk9DRVJPUEpDWk9USUpNTklZTlVDS0g3TFJPNDVKTUpQNlVZQklKQQogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weToyNgogICAgLy8gcmV0dXJuIGFkZHIKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5teV9iYXNlLk15QmFzZS5yZW1lbWJlcl9jcmVhdG9yKCkgLT4gdm9pZDoKcmVtZW1iZXJfY3JlYXRvcjoKICAgIC8vIGV2ZXJ5dGhpbmcvbXlfYmFzZS5weTo3LTgKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgcmVtZW1iZXJfY3JlYXRvcihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBldmVyeXRoaW5nL215X2Jhc2UucHk6OQogICAgLy8gc2VsZi5jcmVhdG9yID0gb3AuVHhuLnNlbmRlcgogICAgYnl0ZSAiY3JlYXRvciIKICAgIHR4biBTZW5kZXIKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5yZWdpc3RlcihuYW1lOiBieXRlcykgLT4gdm9pZDoKcmVnaXN0ZXI6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ3LTQ4CiAgICAvLyBAYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJOb09wIiwgIk9wdEluIl0pCiAgICAvLyBkZWYgcmVnaXN0ZXIoc2VsZiwgbmFtZTogU3RyaW5nKSAtPiBOb25lOgogICAgcHJvdG8gMSAwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyBzZWxmLl9jaGVja19iYW5fbGlzdCgpCiAgICBjYWxsc3ViIF9jaGVja19iYW5fbGlzdAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1MAogICAgLy8gaWYgb3AuVHhuLm9uX2NvbXBsZXRpb24gPT0gT25Db21wbGV0ZUFjdGlvbi5PcHRJbjoKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGludCBPcHRJbgogICAgPT0KICAgIGJ6IHJlZ2lzdGVyX2FmdGVyX2lmX2Vsc2VANAogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1MQogICAgLy8gc2VuZGVyX25hbWUsIHNlbmRlcl9uYW1lX2V4aXN0ZWQgPSBzZWxmLm5hbWUubWF5YmUoYWNjb3VudD0wKQogICAgaW50IDAKICAgIGR1cAogICAgYnl0ZSAibmFtZSIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGJ1cnkgMQogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1MgogICAgLy8gaWYgbm90IHNlbmRlcl9uYW1lX2V4aXN0ZWQ6CiAgICBibnogcmVnaXN0ZXJfYWZ0ZXJfaWZfZWxzZUA0CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjUzCiAgICAvLyBzZWxmLmNvdW50ZXIgKz0gbXVsdGlwbGljYXRpdmVfaWRlbnRpdHkoKSAgIyBoYXMgZnVsbCBGdW5jRGVmCiAgICBpbnQgMAogICAgYnl0ZSAiY291bnRlciIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5jb3VudGVyIGV4aXN0cwogICAgY2FsbHN1YiBtdWx0aXBsaWNhdGl2ZV9pZGVudGl0eQogICAgKwogICAgYnl0ZSAiY291bnRlciIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CgpyZWdpc3Rlcl9hZnRlcl9pZl9lbHNlQDQ6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjU0CiAgICAvLyBzZWxmLm5hbWVbMF0gPSBuYW1lCiAgICBpbnQgMAogICAgYnl0ZSAibmFtZSIKICAgIGZyYW1lX2RpZyAtMQogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5ldmVyeXRoaW5nLm15X2Jhc2UubXVsdGlwbGljYXRpdmVfaWRlbnRpdHkoKSAtPiB1aW50NjQ6Cm11bHRpcGxpY2F0aXZlX2lkZW50aXR5OgogICAgLy8gZXZlcnl0aGluZy9teV9iYXNlLnB5OjE4LTE5CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIG11bHRpcGxpY2F0aXZlX2lkZW50aXR5KCkgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyBldmVyeXRoaW5nL215X2Jhc2UucHk6MjAKICAgIC8vIHJldHVybiBVSW50NjQoMSkKICAgIGludCAxCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5zYXlfaGVsbG8oKSAtPiBieXRlczoKc2F5X2hlbGxvOgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo1Ni01NwogICAgLy8gQGFiaW1ldGhvZAogICAgLy8gZGVmIHNheV9oZWxsbyhzZWxmKSAtPiBTdHJpbmc6CiAgICBwcm90byAwIDEKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NTgKICAgIC8vIHNlbGYuX2NoZWNrX2Jhbl9saXN0KCkKICAgIGNhbGxzdWIgX2NoZWNrX2Jhbl9saXN0CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBuYW1lLCBleGlzdHMgPSBzZWxmLm5hbWUubWF5YmUoYWNjb3VudD0wKQogICAgaW50IDAKICAgIGR1cAogICAgYnl0ZSAibmFtZSIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjAKICAgIC8vIGlmIG5vdCBleGlzdHM6CiAgICBibnogc2F5X2hlbGxvX2FmdGVyX2lmX2Vsc2VAMgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo2MQogICAgLy8gcmV0dXJuIFN0cmluZygiSG93ZHkgc3RyYW5nZXIhIikKICAgIGJ5dGUgMHgwMDBmNDg2Zjc3NjQ3OTIwNzM3NDcyNjE2ZTY3NjU3MjIxCiAgICBzd2FwCiAgICByZXRzdWIKCnNheV9oZWxsb19hZnRlcl9pZl9lbHNlQDI6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjYyCiAgICAvLyByZXR1cm4gIkhlbGxvLCAiICsgbmFtZSArICIhIgogICAgZnJhbWVfZGlnIDAKICAgIGV4dHJhY3QgMiAwCiAgICBieXRlIDB4NDg2NTZjNmM2ZjJjMjAKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGV4dHJhY3QgMiAwCiAgICBieXRlIDB4MjEKICAgIGNvbmNhdAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHN3YXAKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5jb250cmFjdC5FdmVyeXRoaW5nLmNhbGN1bGF0ZShhOiBieXRlcywgYjogYnl0ZXMpIC0+IGJ5dGVzOgpjYWxjdWxhdGU6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjY0LTY1CiAgICAvLyBAYWJpbWV0aG9kCiAgICAvLyBkZWYgY2FsY3VsYXRlKHNlbGYsIGE6IGFyYzRfVUludDY0LCBiOiBhcmM0X1VJbnQ2NCkgLT4gYXJjNF9VSW50NjQ6CiAgICBwcm90byAyIDEKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6NjYKICAgIC8vIGMgPSBzdXBlcigpLmNhbGN1bGF0ZShhLCBiKQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIGNhbGxzdWIgdGVzdF9jYXNlcy5ldmVyeXRoaW5nLm15X2Jhc2UuTXlNaWRkbGVCYXNlLmNhbGN1bGF0ZQogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo2NwogICAgLy8gcmV0dXJuIGFyYzRfVUludDY0KGMubmF0aXZlICogYi5uYXRpdmUpCiAgICBidG9pCiAgICBmcmFtZV9kaWcgLTEKICAgIGJ0b2kKICAgICoKICAgIGl0b2IKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5teV9iYXNlLk15TWlkZGxlQmFzZS5jYWxjdWxhdGUoYTogYnl0ZXMsIGI6IGJ5dGVzKSAtPiBieXRlczoKdGVzdF9jYXNlcy5ldmVyeXRoaW5nLm15X2Jhc2UuTXlNaWRkbGVCYXNlLmNhbGN1bGF0ZToKICAgIC8vIGV2ZXJ5dGhpbmcvbXlfYmFzZS5weToxMy0xNAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBjYWxjdWxhdGUoc2VsZiwgYTogYXJjNC5VSW50NjQsIGI6IGFyYzQuVUludDY0KSAtPiBhcmM0LlVJbnQ2NDoKICAgIHByb3RvIDIgMQogICAgLy8gZXZlcnl0aGluZy9teV9iYXNlLnB5OjE1CiAgICAvLyByZXR1cm4gYXJjNC5VSW50NjQoYS5uYXRpdmUgKyBiLm5hdGl2ZSkKICAgIGZyYW1lX2RpZyAtMgogICAgYnRvaQogICAgZnJhbWVfZGlnIC0xCiAgICBidG9pCiAgICArCiAgICBpdG9iCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5jbG9zZV9vdXQoKSAtPiB2b2lkOgpjbG9zZV9vdXQ6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjY5LTcwCiAgICAvLyBAYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJDbG9zZU91dCJdKQogICAgLy8gZGVmIGNsb3NlX291dChzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjcxCiAgICAvLyBzZWxmLl9yZW1vdmVfc2VuZGVyKCkKICAgIGNhbGxzdWIgX3JlbW92ZV9zZW5kZXIKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5jb250cmFjdC5FdmVyeXRoaW5nLl9yZW1vdmVfc2VuZGVyKCkgLT4gdm9pZDoKX3JlbW92ZV9zZW5kZXI6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjgxLTgyCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9yZW1vdmVfc2VuZGVyKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6ODMKICAgIC8vIHNlbGYuY291bnRlciAtPSBwb3NpdGl2ZV9vbmUoKQogICAgaW50IDAKICAgIGJ5dGUgImNvdW50ZXIiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuY291bnRlciBleGlzdHMKICAgIGNhbGxzdWIgcG9zaXRpdmVfb25lCiAgICAtCiAgICBieXRlICJjb3VudGVyIgogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5jb250cmFjdC5wb3NpdGl2ZV9vbmUoKSAtPiB1aW50NjQ6CnBvc2l0aXZlX29uZToKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6ODYtODcKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgcG9zaXRpdmVfb25lKCkgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojg4CiAgICAvLyByZXR1cm4gVUludDY0KDEpCiAgICBpbnQgMQogICAgcmV0c3ViCg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmV2ZXJ5dGhpbmcuY29udHJhY3QuRXZlcnl0aGluZy5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgLy8gZXZlcnl0aGluZy9jb250cmFjdC5weTo3NAogICAgLy8gc2VsZi5fcmVtb3ZlX3NlbmRlcigpCiAgICBjYWxsc3ViIF9yZW1vdmVfc2VuZGVyCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojc1CiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5jb250cmFjdC5FdmVyeXRoaW5nLl9yZW1vdmVfc2VuZGVyKCkgLT4gdm9pZDoKX3JlbW92ZV9zZW5kZXI6CiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5OjgxLTgyCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIF9yZW1vdmVfc2VuZGVyKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6ODMKICAgIC8vIHNlbGYuY291bnRlciAtPSBwb3NpdGl2ZV9vbmUoKQogICAgaW50IDAKICAgIGJ5dGUgImNvdW50ZXIiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuY291bnRlciBleGlzdHMKICAgIGNhbGxzdWIgcG9zaXRpdmVfb25lCiAgICAtCiAgICBieXRlICJjb3VudGVyIgogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuZXZlcnl0aGluZy5jb250cmFjdC5wb3NpdGl2ZV9vbmUoKSAtPiB1aW50NjQ6CnBvc2l0aXZlX29uZToKICAgIC8vIGV2ZXJ5dGhpbmcvY29udHJhY3QucHk6ODYtODcKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgcG9zaXRpdmVfb25lKCkgLT4gVUludDY0OgogICAgcHJvdG8gMCAxCiAgICAvLyBldmVyeXRoaW5nL2NvbnRyYWN0LnB5Ojg4CiAgICAvLyByZXR1cm4gVUludDY0KDEpCiAgICBpbnQgMQogICAgcmV0c3ViCg==" }, "state": { "global": { diff --git a/test_cases/everything/out/MyContract.clear.mir b/test_cases/everything/out/MyContract.clear.mir index 87465ad7cf..369f006a71 100644 --- a/test_cases/everything/out/MyContract.clear.mir +++ b/test_cases/everything/out/MyContract.clear.mir @@ -15,7 +15,7 @@ _remove_sender: _remove_sender_block@0: int 0 // 0 self.counter everything/contract.py:83 - byte "counter" // 0,"counter" self.counter everything/contract.py:45 + byte "counter" // 0,"counter" self.counter everything/contract.py:83 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.counter everything/contract.py:83 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.counter everything/contract.py:83 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.counter everything/contract.py:83 @@ -27,7 +27,7 @@ _remove_sender_block@0: // virtual: load tmp%0#0 from l-stack (no copy) maybe_value%0#0,tmp%0#0 self.counter -= positive_one() everything/contract.py:83 - // {-} self.counter -= positive_one() everything/contract.py:83 // virtual: store new_state_value%0#0 to l-stack (no copy) new_state_value%0#0 self.counter -= positive_one() everything/contract.py:83 - byte "counter" // new_state_value%0#0,"counter" self.counter everything/contract.py:45 + byte "counter" // new_state_value%0#0,"counter" self.counter everything/contract.py:83 uncover 1 // load new_state_value%0#0 from l-stack (no copy) "counter",new_state_value%0#0 self.counter -= positive_one() everything/contract.py:83 app_global_put // self.counter -= positive_one() everything/contract.py:83 retsub // diff --git a/test_cases/everything/out/MyContract.clear.teal b/test_cases/everything/out/MyContract.clear.teal index 35bf41f2ad..05fa4dac10 100644 --- a/test_cases/everything/out/MyContract.clear.teal +++ b/test_cases/everything/out/MyContract.clear.teal @@ -19,20 +19,12 @@ _remove_sender: // everything/contract.py:83 // self.counter -= positive_one() int 0 - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:83 - // self.counter -= positive_one() app_global_get_ex assert // check self.counter exists callsub positive_one - - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:83 - // self.counter -= positive_one() swap app_global_put retsub diff --git a/test_cases/everything/out_unoptimized/MyContract.approval.teal b/test_cases/everything/out_unoptimized/MyContract.approval.teal index d1d8b06f40..bb52da2a79 100644 --- a/test_cases/everything/out_unoptimized/MyContract.approval.teal +++ b/test_cases/everything/out_unoptimized/MyContract.approval.teal @@ -221,11 +221,7 @@ register: // sender_name, sender_name_existed = self.name.maybe(account=0) int 0 int 0 - // everything/contract.py:39 - // self.name = LocalState(String) byte "name" - // everything/contract.py:51 - // sender_name, sender_name_existed = self.name.maybe(account=0) app_local_get_ex cover 1 pop @@ -235,20 +231,12 @@ register: // everything/contract.py:53 // self.counter += multiplicative_identity() # has full FuncDef int 0 - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:53 - // self.counter += multiplicative_identity() # has full FuncDef app_global_get_ex assert // check self.counter exists callsub multiplicative_identity + - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:53 - // self.counter += multiplicative_identity() # has full FuncDef uncover 1 app_global_put @@ -258,11 +246,7 @@ register_after_if_else@4: // everything/contract.py:54 // self.name[0] = name int 0 - // everything/contract.py:39 - // self.name = LocalState(String) byte "name" - // everything/contract.py:54 - // self.name[0] = name frame_dig -1 app_local_put retsub @@ -293,11 +277,7 @@ say_hello: // name, exists = self.name.maybe(account=0) int 0 int 0 - // everything/contract.py:39 - // self.name = LocalState(String) byte "name" - // everything/contract.py:59 - // name, exists = self.name.maybe(account=0) app_local_get_ex // everything/contract.py:60 // if not exists: @@ -410,20 +390,12 @@ _remove_sender: // everything/contract.py:83 // self.counter -= positive_one() int 0 - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:83 - // self.counter -= positive_one() app_global_get_ex assert // check self.counter exists callsub positive_one - - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:83 - // self.counter -= positive_one() uncover 1 app_global_put retsub diff --git a/test_cases/everything/out_unoptimized/MyContract.clear.teal b/test_cases/everything/out_unoptimized/MyContract.clear.teal index 7af9d4e01e..36955a4b2c 100644 --- a/test_cases/everything/out_unoptimized/MyContract.clear.teal +++ b/test_cases/everything/out_unoptimized/MyContract.clear.teal @@ -19,20 +19,12 @@ _remove_sender: // everything/contract.py:83 // self.counter -= positive_one() int 0 - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:83 - // self.counter -= positive_one() app_global_get_ex assert // check self.counter exists callsub positive_one - - // everything/contract.py:45 - // self.counter = UInt64(ZERO) byte "counter" - // everything/contract.py:83 - // self.counter -= positive_one() uncover 1 app_global_put retsub diff --git a/test_cases/inner_transactions/out/Greeter.approval.mir b/test_cases/inner_transactions/out/Greeter.approval.mir index ab448061a2..7f6da084f8 100644 --- a/test_cases/inner_transactions/out/Greeter.approval.mir +++ b/test_cases/inner_transactions/out/Greeter.approval.mir @@ -116,7 +116,7 @@ bootstrap: bootstrap_block@0: int 0 // 0 self.hello_app inner_transactions/c2c.py:12 - byte "hello_app" // 0,"hello_app" self.hello_app inner_transactions/c2c.py:8 + byte "hello_app" // 0,"hello_app" self.hello_app inner_transactions/c2c.py:12 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.hello_app inner_transactions/c2c.py:12 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.hello_app inner_transactions/c2c.py:12 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.hello_app inner_transactions/c2c.py:12 @@ -139,11 +139,11 @@ bootstrap_block@0: itxn_submit // itxn.ApplicationCall(\napproval_program=Bytes.from_hex(HELLO_WORLD_APPROVAL_HEX),\nclear_state_pr... inner_transactions/c2c.py:14-18 itxn CreatedApplicationID // {itxn} itxn.ApplicationCall(\napproval_program=Bytes.from_hex(HELLO_WORLD_APPROVAL_HEX),\nclear_state_pr... inner_transactions/c2c.py:14-19 // virtual: store new_state_value%0#0 to l-stack (no copy) new_state_value%0#0 itxn.ApplicationCall(\napproval_program=Bytes.from_hex(HELLO_WORLD_APPROVAL_HEX),\nclear_state_pr... inner_transactions/c2c.py:14-19 - byte "hello_app" // new_state_value%0#0,"hello_app" self.hello_app inner_transactions/c2c.py:8 + byte "hello_app" // new_state_value%0#0,"hello_app" self.hello_app inner_transactions/c2c.py:13 uncover 1 // load new_state_value%0#0 from l-stack (no copy) "hello_app",new_state_value%0#0 self.hello_app = (\nitxn.ApplicationCall(\napproval_program=Bytes.from_hex(HELLO_WORLD_APPROVAL_H... inner_transactions/c2c.py:13-20 app_global_put // self.hello_app = (\nitxn.ApplicationCall(\napproval_program=Bytes.from_hex(HELLO_WORLD_APPROVAL_H... inner_transactions/c2c.py:13-20 int 0 // 0 self.hello_app inner_transactions/c2c.py:21 - byte "hello_app" // 0,"hello_app" self.hello_app inner_transactions/c2c.py:8 + byte "hello_app" // 0,"hello_app" self.hello_app inner_transactions/c2c.py:21 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.hello_app inner_transactions/c2c.py:21 // virtual: store maybe_exists%1#0 to l-stack (no copy) maybe_exists%1#0,{app_global_get_ex}.0 self.hello_app inner_transactions/c2c.py:21 // virtual: store maybe_value%1#0 to l-stack (no copy) maybe_value%1#0,maybe_exists%1#0 self.hello_app inner_transactions/c2c.py:21 @@ -160,7 +160,7 @@ log_greetings: log_greetings_block@0: itxn_begin // (𝕡) name#0 | itxn.ApplicationCall(\napp_id=self.hello_app,\napp_args=(arc4.arc4_signature("hello(string)string... inner_transactions/c2c.py:25-28 int 0 // (𝕡) name#0 | 0 self.hello_app inner_transactions/c2c.py:26 - byte "hello_app" // (𝕡) name#0 | 0,"hello_app" self.hello_app inner_transactions/c2c.py:8 + byte "hello_app" // (𝕡) name#0 | 0,"hello_app" self.hello_app inner_transactions/c2c.py:26 app_global_get_ex // (𝕡) name#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.hello_app inner_transactions/c2c.py:26 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.hello_app inner_transactions/c2c.py:26 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕡) name#0 | maybe_value%0#0,maybe_exists%0#0 self.hello_app inner_transactions/c2c.py:26 diff --git a/test_cases/inner_transactions/out/Greeter.approval.teal b/test_cases/inner_transactions/out/Greeter.approval.teal index db57b910cc..7813af24f7 100644 --- a/test_cases/inner_transactions/out/Greeter.approval.teal +++ b/test_cases/inner_transactions/out/Greeter.approval.teal @@ -85,11 +85,7 @@ bootstrap: // inner_transactions/c2c.py:12 // assert not self.hello_app, "already bootstrapped" int 0 - // inner_transactions/c2c.py:8 - // self.hello_app = Application() byte "hello_app" - // inner_transactions/c2c.py:12 - // assert not self.hello_app, "already bootstrapped" app_global_get_ex assert // check self.hello_app exists ! @@ -122,8 +118,8 @@ bootstrap: // ) // .submit() itxn_submit - // inner_transactions/c2c.py:8 - // self.hello_app = Application() + // inner_transactions/c2c.py:13 + // self.hello_app = ( byte "hello_app" // inner_transactions/c2c.py:14-19 // itxn.ApplicationCall( @@ -146,11 +142,7 @@ bootstrap: // inner_transactions/c2c.py:21 // return self.hello_app.id int 0 - // inner_transactions/c2c.py:8 - // self.hello_app = Application() byte "hello_app" - // inner_transactions/c2c.py:21 - // return self.hello_app.id app_global_get_ex assert // check self.hello_app exists retsub @@ -171,11 +163,7 @@ log_greetings: // inner_transactions/c2c.py:26 // app_id=self.hello_app, int 0 - // inner_transactions/c2c.py:8 - // self.hello_app = Application() byte "hello_app" - // inner_transactions/c2c.py:26 - // app_id=self.hello_app, app_global_get_ex assert // check self.hello_app exists // inner_transactions/c2c.py:27 diff --git a/test_cases/inner_transactions/out/Greeter.arc32.json b/test_cases/inner_transactions/out/Greeter.arc32.json index 3e30fd8d41..a6c56f0611 100644 --- a/test_cases/inner_transactions/out/Greeter.arc32.json +++ b/test_cases/inner_transactions/out/Greeter.arc32.json @@ -12,7 +12,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmlubmVyX3RyYW5zYWN0aW9ucy5jMmMuR3JlZXRlci5hcHByb3ZhbF9wcm9ncmFtOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2VudHJ5cG9pbnRAMgogICAgY2FsbHN1YiBfX2luaXRfXwoKbWFpbl9lbnRyeXBvaW50QDI6CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0X2Nhc2VzLmlubmVyX3RyYW5zYWN0aW9ucy5jMmMuR3JlZXRlci5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjYKICAgIC8vIGNsYXNzIEdyZWV0ZXIoQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBtZXRob2QgImJvb3RzdHJhcCgpdWludDY0IgogICAgbWV0aG9kICJsb2dfZ3JlZXRpbmdzKHN0cmluZyl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fYm9vdHN0cmFwX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fbG9nX2dyZWV0aW5nc19yb3V0ZUAzCiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ib290c3RyYXBfcm91dGVAMjoKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJvb3RzdHJhcAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fbG9nX2dyZWV0aW5nc19yb3V0ZUAzOgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6NgogICAgLy8gY2xhc3MgR3JlZXRlcihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgbG9nX2dyZWV0aW5ncwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDY6CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjYKICAgIC8vIGNsYXNzIEdyZWV0ZXIoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwOgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weTo2CiAgICAvLyBjbGFzcyBHcmVldGVyKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5pbm5lcl90cmFuc2FjdGlvbnMuYzJjLkdyZWV0ZXIuYm9vdHN0cmFwKCkgLT4gdWludDY0Ogpib290c3RyYXA6CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjEwLTExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGJvb3RzdHJhcChzZWxmKSAtPiBVSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MTIKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5oZWxsb19hcHAsICJhbHJlYWR5IGJvb3RzdHJhcHBlZCIKICAgIGludCAwCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjgKICAgIC8vIHNlbGYuaGVsbG9fYXBwID0gQXBwbGljYXRpb24oKQogICAgYnl0ZSAiaGVsbG9fYXBwIgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToxMgogICAgLy8gYXNzZXJ0IG5vdCBzZWxmLmhlbGxvX2FwcCwgImFscmVhZHkgYm9vdHN0cmFwcGVkIgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmhlbGxvX2FwcCBleGlzdHMKICAgICEKICAgIGFzc2VydCAvLyBhbHJlYWR5IGJvb3RzdHJhcHBlZAogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToxNC0xOAogICAgLy8gaXR4bi5BcHBsaWNhdGlvbkNhbGwoCiAgICAvLyAgICAgYXBwcm92YWxfcHJvZ3JhbT1CeXRlcy5mcm9tX2hleChIRUxMT19XT1JMRF9BUFBST1ZBTF9IRVgpLAogICAgLy8gICAgIGNsZWFyX3N0YXRlX3Byb2dyYW09SEVMTE9fV09STERfQ0xFQVIsCiAgICAvLyApCiAgICAvLyAuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MTYKICAgIC8vIGNsZWFyX3N0YXRlX3Byb2dyYW09SEVMTE9fV09STERfQ0xFQVIsCiAgICBieXRlIDB4MGE4MTAxCiAgICBpdHhuX2ZpZWxkIENsZWFyU3RhdGVQcm9ncmFtUGFnZXMKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MTUKICAgIC8vIGFwcHJvdmFsX3Byb2dyYW09Qnl0ZXMuZnJvbV9oZXgoSEVMTE9fV09STERfQVBQUk9WQUxfSEVYKSwKICAgIGJ5dGUgMHgwYTIwMDEwMTMxMWI0MTAwMjY4MDA0MDJiZWNlMTEzNjFhMDA4ZTAxMDAwMTAwMzExOTE0NDQzMTE4NDQzNjFhMDE4ODAwMTU4MDA0MTUxZjdjNzU0YzUwYjAyMjQzMzExOTE0NDQzMTE4MTQ0NDIyNDM4YTAxMDE4YmZmNTcwMjAwODAwNzQ4NjU2YzZjNmYyYzIwNGM1MDQ5MTUxNjU3MDYwMDRjNTA4OQogICAgaXR4bl9maWVsZCBBcHByb3ZhbFByb2dyYW1QYWdlcwogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToxNAogICAgLy8gaXR4bi5BcHBsaWNhdGlvbkNhbGwoCiAgICBpbnQgYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjE0LTE4CiAgICAvLyBpdHhuLkFwcGxpY2F0aW9uQ2FsbCgKICAgIC8vICAgICBhcHByb3ZhbF9wcm9ncmFtPUJ5dGVzLmZyb21faGV4KEhFTExPX1dPUkxEX0FQUFJPVkFMX0hFWCksCiAgICAvLyAgICAgY2xlYXJfc3RhdGVfcHJvZ3JhbT1IRUxMT19XT1JMRF9DTEVBUiwKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgaXR4bl9zdWJtaXQKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6OAogICAgLy8gc2VsZi5oZWxsb19hcHAgPSBBcHBsaWNhdGlvbigpCiAgICBieXRlICJoZWxsb19hcHAiCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjE0LTE5CiAgICAvLyBpdHhuLkFwcGxpY2F0aW9uQ2FsbCgKICAgIC8vICAgICBhcHByb3ZhbF9wcm9ncmFtPUJ5dGVzLmZyb21faGV4KEhFTExPX1dPUkxEX0FQUFJPVkFMX0hFWCksCiAgICAvLyAgICAgY2xlYXJfc3RhdGVfcHJvZ3JhbT1IRUxMT19XT1JMRF9DTEVBUiwKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgLy8gLmNyZWF0ZWRfYXBwCiAgICBpdHhuIENyZWF0ZWRBcHBsaWNhdGlvbklECiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjEzLTIwCiAgICAvLyBzZWxmLmhlbGxvX2FwcCA9ICgKICAgIC8vICAgICBpdHhuLkFwcGxpY2F0aW9uQ2FsbCgKICAgIC8vICAgICAgICAgYXBwcm92YWxfcHJvZ3JhbT1CeXRlcy5mcm9tX2hleChIRUxMT19XT1JMRF9BUFBST1ZBTF9IRVgpLAogICAgLy8gICAgICAgICBjbGVhcl9zdGF0ZV9wcm9ncmFtPUhFTExPX1dPUkxEX0NMRUFSLAogICAgLy8gICAgICkKICAgIC8vICAgICAuc3VibWl0KCkKICAgIC8vICAgICAuY3JlYXRlZF9hcHAKICAgIC8vICkKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjIxCiAgICAvLyByZXR1cm4gc2VsZi5oZWxsb19hcHAuaWQKICAgIGludCAwCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjgKICAgIC8vIHNlbGYuaGVsbG9fYXBwID0gQXBwbGljYXRpb24oKQogICAgYnl0ZSAiaGVsbG9fYXBwIgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyMQogICAgLy8gcmV0dXJuIHNlbGYuaGVsbG9fYXBwLmlkCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaGVsbG9fYXBwIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5pbm5lcl90cmFuc2FjdGlvbnMuYzJjLkdyZWV0ZXIubG9nX2dyZWV0aW5ncyhuYW1lOiBieXRlcykgLT4gdm9pZDoKbG9nX2dyZWV0aW5nczoKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MjMtMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgbG9nX2dyZWV0aW5ncyhzZWxmLCBuYW1lOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyNS0yOAogICAgLy8gaGVsbG9fY2FsbCA9IGl0eG4uQXBwbGljYXRpb25DYWxsKAogICAgLy8gICAgIGFwcF9pZD1zZWxmLmhlbGxvX2FwcCwKICAgIC8vICAgICBhcHBfYXJncz0oYXJjNC5hcmM0X3NpZ25hdHVyZSgiaGVsbG8oc3RyaW5nKXN0cmluZyIpLCBuYW1lKSwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MjYKICAgIC8vIGFwcF9pZD1zZWxmLmhlbGxvX2FwcCwKICAgIGludCAwCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjgKICAgIC8vIHNlbGYuaGVsbG9fYXBwID0gQXBwbGljYXRpb24oKQogICAgYnl0ZSAiaGVsbG9fYXBwIgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyNgogICAgLy8gYXBwX2lkPXNlbGYuaGVsbG9fYXBwLAogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmhlbGxvX2FwcCBleGlzdHMKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MjcKICAgIC8vIGFwcF9hcmdzPShhcmM0LmFyYzRfc2lnbmF0dXJlKCJoZWxsbyhzdHJpbmcpc3RyaW5nIiksIG5hbWUpLAogICAgbWV0aG9kICJoZWxsbyhzdHJpbmcpc3RyaW5nIgogICAgaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKICAgIGZyYW1lX2RpZyAtMQogICAgaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKICAgIGl0eG5fZmllbGQgQXBwbGljYXRpb25JRAogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyNQogICAgLy8gaGVsbG9fY2FsbCA9IGl0eG4uQXBwbGljYXRpb25DYWxsKAogICAgaW50IGFwcGwKICAgIGl0eG5fZmllbGQgVHlwZUVudW0KICAgIGludCAwCiAgICBpdHhuX2ZpZWxkIEZlZQogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyNS0yOAogICAgLy8gaGVsbG9fY2FsbCA9IGl0eG4uQXBwbGljYXRpb25DYWxsKAogICAgLy8gICAgIGFwcF9pZD1zZWxmLmhlbGxvX2FwcCwKICAgIC8vICAgICBhcHBfYXJncz0oYXJjNC5hcmM0X3NpZ25hdHVyZSgiaGVsbG8oc3RyaW5nKXN0cmluZyIpLCBuYW1lKSwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fc3VibWl0CiAgICBpdHhuIExhc3RMb2cKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MjkKICAgIC8vIGdyZWV0aW5nID0gYXJjNC5TdHJpbmcuZnJvbV9sb2coaGVsbG9fY2FsbC5sYXN0X2xvZykKICAgIGR1cAogICAgZXh0cmFjdCA0IDAKICAgIHN3YXAKICAgIGV4dHJhY3QgMCA0CiAgICBieXRlIDB4MTUxZjdjNzUKICAgID09CiAgICBhc3NlcnQgLy8gQVJDNCBwcmVmaXggaXMgdmFsaWQKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MzAKICAgIC8vIGxvZygiSGVsbG9Xb3JsZCByZXR1cm5lZDogIiwgZ3JlZXRpbmcubmF0aXZlKQogICAgZXh0cmFjdCAyIDAKICAgIGJ5dGUgIkhlbGxvV29ybGQgcmV0dXJuZWQ6ICIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgbG9nCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLmlubmVyX3RyYW5zYWN0aW9ucy5jMmMuR3JlZXRlci5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weTo3CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weTo4CiAgICAvLyBzZWxmLmhlbGxvX2FwcCA9IEFwcGxpY2F0aW9uKCkKICAgIGJ5dGUgImhlbGxvX2FwcCIKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmlubmVyX3RyYW5zYWN0aW9ucy5jMmMuR3JlZXRlci5hcHByb3ZhbF9wcm9ncmFtOgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGJueiBtYWluX2VudHJ5cG9pbnRAMgogICAgY2FsbHN1YiBfX2luaXRfXwoKbWFpbl9lbnRyeXBvaW50QDI6CiAgICBjYWxsc3ViIF9fcHV5YV9hcmM0X3JvdXRlcl9fCiAgICByZXR1cm4KCgovLyB0ZXN0X2Nhc2VzLmlubmVyX3RyYW5zYWN0aW9ucy5jMmMuR3JlZXRlci5fX3B1eWFfYXJjNF9yb3V0ZXJfXygpIC0+IHVpbnQ2NDoKX19wdXlhX2FyYzRfcm91dGVyX186CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjYKICAgIC8vIGNsYXNzIEdyZWV0ZXIoQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBtZXRob2QgImJvb3RzdHJhcCgpdWludDY0IgogICAgbWV0aG9kICJsb2dfZ3JlZXRpbmdzKHN0cmluZyl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fYm9vdHN0cmFwX3JvdXRlQDIgX19wdXlhX2FyYzRfcm91dGVyX19fbG9nX2dyZWV0aW5nc19yb3V0ZUAzCiAgICBpbnQgMAogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19ib290c3RyYXBfcm91dGVAMjoKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MTAKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGJvb3RzdHJhcAogICAgaXRvYgogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fbG9nX2dyZWV0aW5nc19yb3V0ZUAzOgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6NgogICAgLy8gY2xhc3MgR3JlZXRlcihBUkM0Q29udHJhY3QpOgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyMwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIGNhbGxzdWIgbG9nX2dyZWV0aW5ncwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDY6CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjYKICAgIC8vIGNsYXNzIEdyZWV0ZXIoQVJDNENvbnRyYWN0KToKICAgIHR4biBPbkNvbXBsZXRpb24KICAgIGJueiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgIQogICAgYXNzZXJ0IC8vIGlzIGNyZWF0aW5nCiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDEwOgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weTo2CiAgICAvLyBjbGFzcyBHcmVldGVyKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5pbm5lcl90cmFuc2FjdGlvbnMuYzJjLkdyZWV0ZXIuYm9vdHN0cmFwKCkgLT4gdWludDY0Ogpib290c3RyYXA6CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjEwLTExCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIGJvb3RzdHJhcChzZWxmKSAtPiBVSW50NjQ6CiAgICBwcm90byAwIDEKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MTIKICAgIC8vIGFzc2VydCBub3Qgc2VsZi5oZWxsb19hcHAsICJhbHJlYWR5IGJvb3RzdHJhcHBlZCIKICAgIGludCAwCiAgICBieXRlICJoZWxsb19hcHAiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaGVsbG9fYXBwIGV4aXN0cwogICAgIQogICAgYXNzZXJ0IC8vIGFscmVhZHkgYm9vdHN0cmFwcGVkCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjE0LTE4CiAgICAvLyBpdHhuLkFwcGxpY2F0aW9uQ2FsbCgKICAgIC8vICAgICBhcHByb3ZhbF9wcm9ncmFtPUJ5dGVzLmZyb21faGV4KEhFTExPX1dPUkxEX0FQUFJPVkFMX0hFWCksCiAgICAvLyAgICAgY2xlYXJfc3RhdGVfcHJvZ3JhbT1IRUxMT19XT1JMRF9DTEVBUiwKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgaXR4bl9iZWdpbgogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToxNgogICAgLy8gY2xlYXJfc3RhdGVfcHJvZ3JhbT1IRUxMT19XT1JMRF9DTEVBUiwKICAgIGJ5dGUgMHgwYTgxMDEKICAgIGl0eG5fZmllbGQgQ2xlYXJTdGF0ZVByb2dyYW1QYWdlcwogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToxNQogICAgLy8gYXBwcm92YWxfcHJvZ3JhbT1CeXRlcy5mcm9tX2hleChIRUxMT19XT1JMRF9BUFBST1ZBTF9IRVgpLAogICAgYnl0ZSAweDBhMjAwMTAxMzExYjQxMDAyNjgwMDQwMmJlY2UxMTM2MWEwMDhlMDEwMDAxMDAzMTE5MTQ0NDMxMTg0NDM2MWEwMTg4MDAxNTgwMDQxNTFmN2M3NTRjNTBiMDIyNDMzMTE5MTQ0NDMxMTgxNDQ0MjI0MzhhMDEwMThiZmY1NzAyMDA4MDA3NDg2NTZjNmM2ZjJjMjA0YzUwNDkxNTE2NTcwNjAwNGM1MDg5CiAgICBpdHhuX2ZpZWxkIEFwcHJvdmFsUHJvZ3JhbVBhZ2VzCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjE0CiAgICAvLyBpdHhuLkFwcGxpY2F0aW9uQ2FsbCgKICAgIGludCBhcHBsCiAgICBpdHhuX2ZpZWxkIFR5cGVFbnVtCiAgICBpbnQgMAogICAgaXR4bl9maWVsZCBGZWUKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MTQtMTgKICAgIC8vIGl0eG4uQXBwbGljYXRpb25DYWxsKAogICAgLy8gICAgIGFwcHJvdmFsX3Byb2dyYW09Qnl0ZXMuZnJvbV9oZXgoSEVMTE9fV09STERfQVBQUk9WQUxfSEVYKSwKICAgIC8vICAgICBjbGVhcl9zdGF0ZV9wcm9ncmFtPUhFTExPX1dPUkxEX0NMRUFSLAogICAgLy8gKQogICAgLy8gLnN1Ym1pdCgpCiAgICBpdHhuX3N1Ym1pdAogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToxMwogICAgLy8gc2VsZi5oZWxsb19hcHAgPSAoCiAgICBieXRlICJoZWxsb19hcHAiCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjE0LTE5CiAgICAvLyBpdHhuLkFwcGxpY2F0aW9uQ2FsbCgKICAgIC8vICAgICBhcHByb3ZhbF9wcm9ncmFtPUJ5dGVzLmZyb21faGV4KEhFTExPX1dPUkxEX0FQUFJPVkFMX0hFWCksCiAgICAvLyAgICAgY2xlYXJfc3RhdGVfcHJvZ3JhbT1IRUxMT19XT1JMRF9DTEVBUiwKICAgIC8vICkKICAgIC8vIC5zdWJtaXQoKQogICAgLy8gLmNyZWF0ZWRfYXBwCiAgICBpdHhuIENyZWF0ZWRBcHBsaWNhdGlvbklECiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjEzLTIwCiAgICAvLyBzZWxmLmhlbGxvX2FwcCA9ICgKICAgIC8vICAgICBpdHhuLkFwcGxpY2F0aW9uQ2FsbCgKICAgIC8vICAgICAgICAgYXBwcm92YWxfcHJvZ3JhbT1CeXRlcy5mcm9tX2hleChIRUxMT19XT1JMRF9BUFBST1ZBTF9IRVgpLAogICAgLy8gICAgICAgICBjbGVhcl9zdGF0ZV9wcm9ncmFtPUhFTExPX1dPUkxEX0NMRUFSLAogICAgLy8gICAgICkKICAgIC8vICAgICAuc3VibWl0KCkKICAgIC8vICAgICAuY3JlYXRlZF9hcHAKICAgIC8vICkKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjIxCiAgICAvLyByZXR1cm4gc2VsZi5oZWxsb19hcHAuaWQKICAgIGludCAwCiAgICBieXRlICJoZWxsb19hcHAiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaGVsbG9fYXBwIGV4aXN0cwogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5pbm5lcl90cmFuc2FjdGlvbnMuYzJjLkdyZWV0ZXIubG9nX2dyZWV0aW5ncyhuYW1lOiBieXRlcykgLT4gdm9pZDoKbG9nX2dyZWV0aW5nczoKICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MjMtMjQKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICAvLyBkZWYgbG9nX2dyZWV0aW5ncyhzZWxmLCBuYW1lOiBhcmM0LlN0cmluZykgLT4gTm9uZToKICAgIHByb3RvIDEgMAogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyNS0yOAogICAgLy8gaGVsbG9fY2FsbCA9IGl0eG4uQXBwbGljYXRpb25DYWxsKAogICAgLy8gICAgIGFwcF9pZD1zZWxmLmhlbGxvX2FwcCwKICAgIC8vICAgICBhcHBfYXJncz0oYXJjNC5hcmM0X3NpZ25hdHVyZSgiaGVsbG8oc3RyaW5nKXN0cmluZyIpLCBuYW1lKSwKICAgIC8vICkuc3VibWl0KCkKICAgIGl0eG5fYmVnaW4KICAgIC8vIGlubmVyX3RyYW5zYWN0aW9ucy9jMmMucHk6MjYKICAgIC8vIGFwcF9pZD1zZWxmLmhlbGxvX2FwcCwKICAgIGludCAwCiAgICBieXRlICJoZWxsb19hcHAiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuaGVsbG9fYXBwIGV4aXN0cwogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyNwogICAgLy8gYXBwX2FyZ3M9KGFyYzQuYXJjNF9zaWduYXR1cmUoImhlbGxvKHN0cmluZylzdHJpbmciKSwgbmFtZSksCiAgICBtZXRob2QgImhlbGxvKHN0cmluZylzdHJpbmciCiAgICBpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwogICAgZnJhbWVfZGlnIC0xCiAgICBpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwogICAgaXR4bl9maWVsZCBBcHBsaWNhdGlvbklECiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjI1CiAgICAvLyBoZWxsb19jYWxsID0gaXR4bi5BcHBsaWNhdGlvbkNhbGwoCiAgICBpbnQgYXBwbAogICAgaXR4bl9maWVsZCBUeXBlRW51bQogICAgaW50IDAKICAgIGl0eG5fZmllbGQgRmVlCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjI1LTI4CiAgICAvLyBoZWxsb19jYWxsID0gaXR4bi5BcHBsaWNhdGlvbkNhbGwoCiAgICAvLyAgICAgYXBwX2lkPXNlbGYuaGVsbG9fYXBwLAogICAgLy8gICAgIGFwcF9hcmdzPShhcmM0LmFyYzRfc2lnbmF0dXJlKCJoZWxsbyhzdHJpbmcpc3RyaW5nIiksIG5hbWUpLAogICAgLy8gKS5zdWJtaXQoKQogICAgaXR4bl9zdWJtaXQKICAgIGl0eG4gTGFzdExvZwogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weToyOQogICAgLy8gZ3JlZXRpbmcgPSBhcmM0LlN0cmluZy5mcm9tX2xvZyhoZWxsb19jYWxsLmxhc3RfbG9nKQogICAgZHVwCiAgICBleHRyYWN0IDQgMAogICAgc3dhcAogICAgZXh0cmFjdCAwIDQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgPT0KICAgIGFzc2VydCAvLyBBUkM0IHByZWZpeCBpcyB2YWxpZAogICAgLy8gaW5uZXJfdHJhbnNhY3Rpb25zL2MyYy5weTozMAogICAgLy8gbG9nKCJIZWxsb1dvcmxkIHJldHVybmVkOiAiLCBncmVldGluZy5uYXRpdmUpCiAgICBleHRyYWN0IDIgMAogICAgYnl0ZSAiSGVsbG9Xb3JsZCByZXR1cm5lZDogIgogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuaW5uZXJfdHJhbnNhY3Rpb25zLmMyYy5HcmVldGVyLl9faW5pdF9fKCkgLT4gdm9pZDoKX19pbml0X186CiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjcKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBpbm5lcl90cmFuc2FjdGlvbnMvYzJjLnB5OjgKICAgIC8vIHNlbGYuaGVsbG9fYXBwID0gQXBwbGljYXRpb24oKQogICAgYnl0ZSAiaGVsbG9fYXBwIgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLmlubmVyX3RyYW5zYWN0aW9ucy5jMmMuR3JlZXRlci5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/test_cases/inner_transactions/out/MyContract.approval.mir b/test_cases/inner_transactions/out/MyContract.approval.mir index c4194b227b..4acffa00d3 100644 --- a/test_cases/inner_transactions/out/MyContract.approval.mir +++ b/test_cases/inner_transactions/out/MyContract.approval.mir @@ -59,11 +59,11 @@ test1: proto 0 0 // @subroutine\ndef test1(self) -> None: inner_transactions/contract.py:42-43 test1_block@0: - byte "name" // "name" self.name inner_transactions/contract.py:24 + byte "name" // "name" self.name inner_transactions/contract.py:44 byte 0x41535431 // "name",0x41535431 Bytes(b"AST1") inner_transactions/contract.py:44 app_global_put // self.name = Bytes(b"AST1") inner_transactions/contract.py:44 int 0 // 0 self.name inner_transactions/contract.py:47 - byte "name" // 0,"name" self.name inner_transactions/contract.py:24 + byte "name" // 0,"name" self.name inner_transactions/contract.py:47 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.name inner_transactions/contract.py:47 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.name inner_transactions/contract.py:47 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.name inner_transactions/contract.py:47 @@ -73,7 +73,7 @@ test1_block@0: // virtual: store asset_params%%param_ConfigAssetManager_idx_0#0 to l-stack (no copy) maybe_value%0#0,asset_params%%param_ConfigAssetManager_idx_0#0 op.Global.current_application_address inner_transactions/contract.py:50 global CurrentApplicationAddress // maybe_value%0#0,asset_params%%param_ConfigAssetManager_idx_0#0,{global} op.Global.current_application_address inner_transactions/contract.py:51 // virtual: store asset_params%%param_ConfigAssetReserve_idx_0#0 to l-stack (no copy) maybe_value%0#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0 op.Global.current_application_address inner_transactions/contract.py:51 - byte "name" // maybe_value%0#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,"name" self.name inner_transactions/contract.py:24 + byte "name" // maybe_value%0#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,"name" self.name inner_transactions/contract.py:53 byte 0x41535432 // maybe_value%0#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,"name",0x41535432 Bytes(b"AST2") inner_transactions/contract.py:53 app_global_put // maybe_value%0#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0 self.name = Bytes(b"AST2") inner_transactions/contract.py:53 itxn_begin // maybe_value%0#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0 asset_params.submit() inner_transactions/contract.py:54 @@ -99,7 +99,7 @@ test1_block@0: itxn CreatedAssetID // asset1_txn.ConfigAssetName#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,{itxn} asset_params inner_transactions/contract.py:54 cover 3 // store asset1_txn.CreatedAssetID#0 to l-stack (no copy) asset1_txn.CreatedAssetID#0,asset1_txn.ConfigAssetName#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0 asset_params inner_transactions/contract.py:54 int 0 // asset1_txn.CreatedAssetID#0,asset1_txn.ConfigAssetName#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,0 self.name inner_transactions/contract.py:57 - byte "name" // asset1_txn.CreatedAssetID#0,asset1_txn.ConfigAssetName#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,0,"name" self.name inner_transactions/contract.py:24 + byte "name" // asset1_txn.CreatedAssetID#0,asset1_txn.ConfigAssetName#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,0,"name" self.name inner_transactions/contract.py:57 app_global_get_ex // asset1_txn.CreatedAssetID#0,asset1_txn.ConfigAssetName#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.name inner_transactions/contract.py:57 // virtual: store maybe_exists%1#0 to l-stack (no copy) asset1_txn.CreatedAssetID#0,asset1_txn.ConfigAssetName#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,maybe_exists%1#0,{app_global_get_ex}.0 self.name inner_transactions/contract.py:57 // virtual: store maybe_value%1#0 to l-stack (no copy) asset1_txn.CreatedAssetID#0,asset1_txn.ConfigAssetName#0,asset_params%%param_ConfigAssetManager_idx_0#0,asset_params%%param_ConfigAssetReserve_idx_0#0,maybe_value%1#0,maybe_exists%1#0 self.name inner_transactions/contract.py:57 diff --git a/test_cases/inner_transactions/out/MyContract.approval.teal b/test_cases/inner_transactions/out/MyContract.approval.teal index ecaa706b0c..9e7c6a981f 100644 --- a/test_cases/inner_transactions/out/MyContract.approval.teal +++ b/test_cases/inner_transactions/out/MyContract.approval.teal @@ -77,21 +77,15 @@ test1: // @subroutine // def test1(self) -> None: proto 0 0 - // inner_transactions/contract.py:24 - // self.name = Bytes(b"") - byte "name" // inner_transactions/contract.py:44 // self.name = Bytes(b"AST1") + byte "name" byte 0x41535431 app_global_put // inner_transactions/contract.py:47 // asset_name=self.name, int 0 - // inner_transactions/contract.py:24 - // self.name = Bytes(b"") byte "name" - // inner_transactions/contract.py:47 - // asset_name=self.name, app_global_get_ex assert // check self.name exists // inner_transactions/contract.py:50 @@ -100,11 +94,9 @@ test1: // inner_transactions/contract.py:51 // reserve=op.Global.current_application_address, dup - // inner_transactions/contract.py:24 - // self.name = Bytes(b"") - byte "name" // inner_transactions/contract.py:53 // self.name = Bytes(b"AST2") + byte "name" byte 0x41535432 app_global_put // inner_transactions/contract.py:54 @@ -144,11 +136,7 @@ test1: // inner_transactions/contract.py:57 // asset_name=self.name, int 0 - // inner_transactions/contract.py:24 - // self.name = Bytes(b"") byte "name" - // inner_transactions/contract.py:57 - // asset_name=self.name, app_global_get_ex assert // check self.name exists // inner_transactions/contract.py:60 diff --git a/test_cases/inner_transactions/out_unoptimized/Greeter.approval.teal b/test_cases/inner_transactions/out_unoptimized/Greeter.approval.teal index dcdb72f04f..0e73f4d78e 100644 --- a/test_cases/inner_transactions/out_unoptimized/Greeter.approval.teal +++ b/test_cases/inner_transactions/out_unoptimized/Greeter.approval.teal @@ -107,11 +107,7 @@ bootstrap: // inner_transactions/c2c.py:12 // assert not self.hello_app, "already bootstrapped" int 0 - // inner_transactions/c2c.py:8 - // self.hello_app = Application() byte "hello_app" - // inner_transactions/c2c.py:12 - // assert not self.hello_app, "already bootstrapped" app_global_get_ex assert // check self.hello_app exists ! @@ -152,8 +148,8 @@ bootstrap: // .submit() // .created_app itxn CreatedApplicationID - // inner_transactions/c2c.py:8 - // self.hello_app = Application() + // inner_transactions/c2c.py:13 + // self.hello_app = ( byte "hello_app" // inner_transactions/c2c.py:13-20 // self.hello_app = ( @@ -169,11 +165,7 @@ bootstrap: // inner_transactions/c2c.py:21 // return self.hello_app.id int 0 - // inner_transactions/c2c.py:8 - // self.hello_app = Application() byte "hello_app" - // inner_transactions/c2c.py:21 - // return self.hello_app.id app_global_get_ex assert // check self.hello_app exists retsub @@ -194,11 +186,7 @@ log_greetings: // inner_transactions/c2c.py:26 // app_id=self.hello_app, int 0 - // inner_transactions/c2c.py:8 - // self.hello_app = Application() byte "hello_app" - // inner_transactions/c2c.py:26 - // app_id=self.hello_app, app_global_get_ex assert // check self.hello_app exists // inner_transactions/c2c.py:24 diff --git a/test_cases/inner_transactions/out_unoptimized/MyContract.approval.teal b/test_cases/inner_transactions/out_unoptimized/MyContract.approval.teal index 476669b01b..9ae2b74602 100644 --- a/test_cases/inner_transactions/out_unoptimized/MyContract.approval.teal +++ b/test_cases/inner_transactions/out_unoptimized/MyContract.approval.teal @@ -83,21 +83,15 @@ test1: // def test1(self) -> None: proto 0 0 int 0 - // inner_transactions/contract.py:24 - // self.name = Bytes(b"") - byte "name" // inner_transactions/contract.py:44 // self.name = Bytes(b"AST1") + byte "name" byte 0x41535431 app_global_put // inner_transactions/contract.py:47 // asset_name=self.name, int 0 - // inner_transactions/contract.py:24 - // self.name = Bytes(b"") byte "name" - // inner_transactions/contract.py:47 - // asset_name=self.name, app_global_get_ex assert // check self.name exists // inner_transactions/contract.py:50 @@ -110,11 +104,9 @@ test1: global CurrentApplicationAddress dup cover 3 - // inner_transactions/contract.py:24 - // self.name = Bytes(b"") - byte "name" // inner_transactions/contract.py:53 // self.name = Bytes(b"AST2") + byte "name" byte 0x41535432 app_global_put // inner_transactions/contract.py:54 @@ -150,11 +142,7 @@ test1: // inner_transactions/contract.py:57 // asset_name=self.name, int 0 - // inner_transactions/contract.py:24 - // self.name = Bytes(b"") byte "name" - // inner_transactions/contract.py:57 - // asset_name=self.name, app_global_get_ex assert // check self.name exists // inner_transactions/contract.py:60 diff --git a/test_cases/intrinsics/out/Overloaded.approval.mir b/test_cases/intrinsics/out/Overloaded.approval.mir index 4f966044ce..27491bf781 100644 --- a/test_cases/intrinsics/out/Overloaded.approval.mir +++ b/test_cases/intrinsics/out/Overloaded.approval.mir @@ -28,12 +28,12 @@ main_entrypoint@2: // virtual: load tmp%2#0 from l-stack (no copy) tmp%2#0 assert op.AppGlobal.get_uint64(b"key") == op.AppGlobal.get_uint64(b"key") intrinsics/overloaded.py:9 assert // assert op.AppGlobal.get_uint64(b"key") == op.AppGlobal.get_uint64(b"key") intrinsics/overloaded.py:9 int 0 // 0 self.key.maybe intrinsics/overloaded.py:10 - byte "key" // 0,"key" self.key intrinsics/overloaded.py:6 + byte "key" // 0,"key" self.key intrinsics/overloaded.py:10 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.key.maybe() intrinsics/overloaded.py:10 pop // {app_global_get_ex}.0 self.key.maybe() intrinsics/overloaded.py:10 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0 self.key.maybe() intrinsics/overloaded.py:10 int 0 // maybe_value%0#0,0 self.key.maybe intrinsics/overloaded.py:10 - byte "key" // maybe_value%0#0,0,"key" self.key intrinsics/overloaded.py:6 + byte "key" // maybe_value%0#0,0,"key" self.key intrinsics/overloaded.py:10 app_global_get_ex // maybe_value%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.key.maybe() intrinsics/overloaded.py:10 pop // maybe_value%0#0,{app_global_get_ex}.0 self.key.maybe() intrinsics/overloaded.py:10 // virtual: store maybe_value%1#0 to l-stack (no copy) maybe_value%0#0,maybe_value%1#0 self.key.maybe() intrinsics/overloaded.py:10 diff --git a/test_cases/intrinsics/out/Overloaded.approval.teal b/test_cases/intrinsics/out/Overloaded.approval.teal index f936234857..fffc5eeace 100644 --- a/test_cases/intrinsics/out/Overloaded.approval.teal +++ b/test_cases/intrinsics/out/Overloaded.approval.teal @@ -17,19 +17,11 @@ main_entrypoint@2: // intrinsics/overloaded.py:10 // assert self.key.maybe()[0] == self.key.maybe()[0] int 0 - // intrinsics/overloaded.py:6 - // self.key = GlobalState(UInt64(0)) byte "key" - // intrinsics/overloaded.py:10 - // assert self.key.maybe()[0] == self.key.maybe()[0] app_global_get_ex pop int 0 - // intrinsics/overloaded.py:6 - // self.key = GlobalState(UInt64(0)) byte "key" - // intrinsics/overloaded.py:10 - // assert self.key.maybe()[0] == self.key.maybe()[0] app_global_get_ex pop == diff --git a/test_cases/intrinsics/out_unoptimized/Overloaded.approval.teal b/test_cases/intrinsics/out_unoptimized/Overloaded.approval.teal index 7e15dea1ea..413cd32434 100644 --- a/test_cases/intrinsics/out_unoptimized/Overloaded.approval.teal +++ b/test_cases/intrinsics/out_unoptimized/Overloaded.approval.teal @@ -17,19 +17,11 @@ main_entrypoint@2: // intrinsics/overloaded.py:10 // assert self.key.maybe()[0] == self.key.maybe()[0] int 0 - // intrinsics/overloaded.py:6 - // self.key = GlobalState(UInt64(0)) byte "key" - // intrinsics/overloaded.py:10 - // assert self.key.maybe()[0] == self.key.maybe()[0] app_global_get_ex pop int 0 - // intrinsics/overloaded.py:6 - // self.key = GlobalState(UInt64(0)) byte "key" - // intrinsics/overloaded.py:10 - // assert self.key.maybe()[0] == self.key.maybe()[0] app_global_get_ex pop == diff --git a/test_cases/match/out/Counter.approval.mir b/test_cases/match/out/Counter.approval.mir index 5a2aa7793b..1282eb8883 100644 --- a/test_cases/match/out/Counter.approval.mir +++ b/test_cases/match/out/Counter.approval.mir @@ -37,7 +37,7 @@ increment_counter: increment_counter_block@0: int 0 // 0 self.counter match/counter.py:22 - byte "counter" // 0,"counter" self.counter match/counter.py:6 + byte "counter" // 0,"counter" self.counter match/counter.py:22 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.counter match/counter.py:22 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.counter match/counter.py:22 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.counter match/counter.py:22 @@ -47,7 +47,7 @@ increment_counter_block@0: int 1 // maybe_value%0#0,1 1 match/counter.py:22 + // {+} self.counter += 1 match/counter.py:22 // virtual: store new_state_value%0#0 to l-stack (no copy) new_state_value%0#0 self.counter += 1 match/counter.py:22 - byte "counter" // new_state_value%0#0,"counter" self.counter match/counter.py:6 + byte "counter" // new_state_value%0#0,"counter" self.counter match/counter.py:22 uncover 1 // load new_state_value%0#0 from l-stack (no copy) "counter",new_state_value%0#0 self.counter += 1 match/counter.py:22 app_global_put // self.counter += 1 match/counter.py:22 retsub // diff --git a/test_cases/match/out/Counter.approval.teal b/test_cases/match/out/Counter.approval.teal index 65104a1a91..eb118df8fd 100644 --- a/test_cases/match/out/Counter.approval.teal +++ b/test_cases/match/out/Counter.approval.teal @@ -43,20 +43,12 @@ increment_counter: // match/counter.py:22 // self.counter += 1 int 0 - // match/counter.py:6 - // self.counter = algopy.UInt64(0) byte "counter" - // match/counter.py:22 - // self.counter += 1 app_global_get_ex assert // check self.counter exists int 1 + - // match/counter.py:6 - // self.counter = algopy.UInt64(0) byte "counter" - // match/counter.py:22 - // self.counter += 1 swap app_global_put retsub diff --git a/test_cases/match/out/MyContract.approval.mir b/test_cases/match/out/MyContract.approval.mir index 42202e305f..bf8d685d40 100644 --- a/test_cases/match/out/MyContract.approval.mir +++ b/test_cases/match/out/MyContract.approval.mir @@ -143,14 +143,14 @@ match_attributes_block@0: txn NumAppArgs // {txn} algopy.op.Txn.num_app_args match/contract.py:62 // virtual: store n#0 to l-stack (no copy) n#0 n = algopy.op.Txn.num_app_args match/contract.py:62 int 0 // n#0,0 self.case_one match/contract.py:64 - byte "case_one" // n#0,0,"case_one" self.case_one match/contract.py:6 + byte "case_one" // n#0,0,"case_one" self.case_one match/contract.py:64 app_global_get_ex // n#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.case_one match/contract.py:64 // virtual: store maybe_exists%0#0 to l-stack (no copy) n#0,maybe_exists%0#0,{app_global_get_ex}.0 self.case_one match/contract.py:64 // virtual: store maybe_value%0#0 to l-stack (no copy) n#0,maybe_value%0#0,maybe_exists%0#0 self.case_one match/contract.py:64 // virtual: load maybe_exists%0#0 from l-stack (no copy) n#0,maybe_value%0#0,maybe_exists%0#0 self.case_one match/contract.py:64 assert // check self.case_one exists // n#0,maybe_value%0#0 self.case_one match/contract.py:64 int 0 // n#0,maybe_value%0#0,0 self.case_two match/contract.py:67 - byte "case_two" // n#0,maybe_value%0#0,0,"case_two" self.case_two match/contract.py:7 + byte "case_two" // n#0,maybe_value%0#0,0,"case_two" self.case_two match/contract.py:67 app_global_get_ex // n#0,maybe_value%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.case_two match/contract.py:67 // virtual: store maybe_exists%1#0 to l-stack (no copy) n#0,maybe_value%0#0,maybe_exists%1#0,{app_global_get_ex}.0 self.case_two match/contract.py:67 // virtual: store maybe_value%1#0 to l-stack (no copy) n#0,maybe_value%0#0,maybe_value%1#0,maybe_exists%1#0 self.case_two match/contract.py:67 diff --git a/test_cases/match/out/MyContract.approval.teal b/test_cases/match/out/MyContract.approval.teal index 15ff078719..c2331dffe7 100644 --- a/test_cases/match/out/MyContract.approval.teal +++ b/test_cases/match/out/MyContract.approval.teal @@ -239,21 +239,13 @@ match_attributes: // match/contract.py:64 // case self.case_one: int 0 - // match/contract.py:6 - // self.case_one = algopy.UInt64(1) byte "case_one" - // match/contract.py:64 - // case self.case_one: app_global_get_ex assert // check self.case_one exists // match/contract.py:67 // case self.case_two: int 0 - // match/contract.py:7 - // self.case_two = algopy.UInt64(2) byte "case_two" - // match/contract.py:67 - // case self.case_two: app_global_get_ex assert // check self.case_two exists // match/contract.py:63-72 diff --git a/test_cases/match/out_unoptimized/Counter.approval.teal b/test_cases/match/out_unoptimized/Counter.approval.teal index 6b6c899b61..534c0d1a3b 100644 --- a/test_cases/match/out_unoptimized/Counter.approval.teal +++ b/test_cases/match/out_unoptimized/Counter.approval.teal @@ -53,20 +53,12 @@ increment_counter: // match/counter.py:22 // self.counter += 1 int 0 - // match/counter.py:6 - // self.counter = algopy.UInt64(0) byte "counter" - // match/counter.py:22 - // self.counter += 1 app_global_get_ex assert // check self.counter exists int 1 + - // match/counter.py:6 - // self.counter = algopy.UInt64(0) byte "counter" - // match/counter.py:22 - // self.counter += 1 uncover 1 app_global_put retsub diff --git a/test_cases/match/out_unoptimized/MyContract.approval.teal b/test_cases/match/out_unoptimized/MyContract.approval.teal index 750f441679..e8de9b20a8 100644 --- a/test_cases/match/out_unoptimized/MyContract.approval.teal +++ b/test_cases/match/out_unoptimized/MyContract.approval.teal @@ -254,21 +254,13 @@ match_attributes: // match/contract.py:64 // case self.case_one: int 0 - // match/contract.py:6 - // self.case_one = algopy.UInt64(1) byte "case_one" - // match/contract.py:64 - // case self.case_one: app_global_get_ex assert // check self.case_one exists // match/contract.py:67 // case self.case_two: int 0 - // match/contract.py:7 - // self.case_two = algopy.UInt64(2) byte "case_two" - // match/contract.py:67 - // case self.case_two: app_global_get_ex assert // check self.case_two exists // match/contract.py:63-72 diff --git a/test_cases/simplish/out/Simplish.approval.mir b/test_cases/simplish/out/Simplish.approval.mir index 234684c25a..75967bc7bb 100644 --- a/test_cases/simplish/out/Simplish.approval.mir +++ b/test_cases/simplish/out/Simplish.approval.mir @@ -65,7 +65,7 @@ main_if_body@6: main_if_body@7: int 0 // (𝕗) msg#0,sender#0,asset_balance#0,num_app_args#0,oca#0 | 0 self.counter simplish/contract.py:40 - byte "counter" // (𝕗) msg#0,sender#0,asset_balance#0,num_app_args#0,oca#0 | 0,"counter" self.counter simplish/base_class.py:8 + byte "counter" // (𝕗) msg#0,sender#0,asset_balance#0,num_app_args#0,oca#0 | 0,"counter" self.counter simplish/contract.py:40 app_global_get_ex // (𝕗) msg#0,sender#0,asset_balance#0,num_app_args#0,oca#0 | {app_global_get_ex}.0,{app_global_get_ex}.1 self.counter simplish/contract.py:40 // virtual: store maybe_exists%0#0 to l-stack (no copy) (𝕗) msg#0,sender#0,asset_balance#0,num_app_args#0,oca#0 | maybe_exists%0#0,{app_global_get_ex}.0 self.counter simplish/contract.py:40 // virtual: store maybe_value%0#0 to l-stack (no copy) (𝕗) msg#0,sender#0,asset_balance#0,num_app_args#0,oca#0 | maybe_value%0#0,maybe_exists%0#0 self.counter simplish/contract.py:40 @@ -267,7 +267,7 @@ set_sender_nickname: set_sender_nickname_block@0: int 0 // (𝕡) nickname#0 | 0 0 simplish/base_class.py:17 - byte "name" // (𝕡) nickname#0 | 0,"name" self.name simplish/base_class.py:9 + byte "name" // (𝕡) nickname#0 | 0,"name" self.name simplish/base_class.py:17 frame_dig -1 // load nickname#0 from parameters (𝕡) nickname#0 | 0,"name",nickname#0 self.name[0] = nickname simplish/base_class.py:17 app_local_put // (𝕡) nickname#0 | self.name[0] = nickname simplish/base_class.py:17 retsub // @@ -448,7 +448,7 @@ test_cases.simplish.base_class.CallCounter.increment_counter: test_cases.simplish.base_class.CallCounter.increment_counter_block@0: int 0 // 0 self.counter simplish/base_class.py:13 - byte "counter" // 0,"counter" self.counter simplish/base_class.py:8 + byte "counter" // 0,"counter" self.counter simplish/base_class.py:13 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.counter simplish/base_class.py:13 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.counter simplish/base_class.py:13 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.counter simplish/base_class.py:13 @@ -458,7 +458,7 @@ test_cases.simplish.base_class.CallCounter.increment_counter_block@0: int 1 // maybe_value%0#0,1 1 simplish/base_class.py:13 + // {+} self.counter += 1 simplish/base_class.py:13 // virtual: store new_state_value%0#0 to l-stack (no copy) new_state_value%0#0 self.counter += 1 simplish/base_class.py:13 - byte "counter" // new_state_value%0#0,"counter" self.counter simplish/base_class.py:8 + byte "counter" // new_state_value%0#0,"counter" self.counter simplish/base_class.py:13 uncover 1 // load new_state_value%0#0 from l-stack (no copy) "counter",new_state_value%0#0 self.counter += 1 simplish/base_class.py:13 app_global_put // self.counter += 1 simplish/base_class.py:13 retsub // diff --git a/test_cases/simplish/out/Simplish.approval.teal b/test_cases/simplish/out/Simplish.approval.teal index cb38ebaf9e..a651712275 100644 --- a/test_cases/simplish/out/Simplish.approval.teal +++ b/test_cases/simplish/out/Simplish.approval.teal @@ -61,11 +61,7 @@ main_if_body@6: // simplish/contract.py:40 // log(Bytes(b"I was used ") + itoa(self.counter) + b" time(s) before I died") int 0 - // simplish/base_class.py:8 - // self.counter = UInt64(0) byte "counter" - // simplish/contract.py:40 - // log(Bytes(b"I was used ") + itoa(self.counter) + b" time(s) before I died") app_global_get_ex assert // check self.counter exists callsub itoa @@ -267,11 +263,7 @@ set_sender_nickname: // simplish/base_class.py:17 // self.name[0] = nickname int 0 - // simplish/base_class.py:9 - // self.name = LocalState(Bytes) byte "name" - // simplish/base_class.py:17 - // self.name[0] = nickname frame_dig -1 app_local_put retsub @@ -498,20 +490,12 @@ test_cases.simplish.base_class.CallCounter.increment_counter: // simplish/base_class.py:13 // self.counter += 1 int 0 - // simplish/base_class.py:8 - // self.counter = UInt64(0) byte "counter" - // simplish/base_class.py:13 - // self.counter += 1 app_global_get_ex assert // check self.counter exists int 1 + - // simplish/base_class.py:8 - // self.counter = UInt64(0) byte "counter" - // simplish/base_class.py:13 - // self.counter += 1 swap app_global_put retsub diff --git a/test_cases/simplish/out_unoptimized/Simplish.approval.teal b/test_cases/simplish/out_unoptimized/Simplish.approval.teal index ad374b5826..564477cb1f 100644 --- a/test_cases/simplish/out_unoptimized/Simplish.approval.teal +++ b/test_cases/simplish/out_unoptimized/Simplish.approval.teal @@ -63,11 +63,7 @@ main_if_body@6: // simplish/contract.py:40 // log(Bytes(b"I was used ") + itoa(self.counter) + b" time(s) before I died") int 0 - // simplish/base_class.py:8 - // self.counter = UInt64(0) byte "counter" - // simplish/contract.py:40 - // log(Bytes(b"I was used ") + itoa(self.counter) + b" time(s) before I died") app_global_get_ex assert // check self.counter exists callsub itoa @@ -283,11 +279,7 @@ set_sender_nickname: // simplish/base_class.py:17 // self.name[0] = nickname int 0 - // simplish/base_class.py:9 - // self.name = LocalState(Bytes) byte "name" - // simplish/base_class.py:17 - // self.name[0] = nickname frame_dig -1 app_local_put retsub @@ -517,20 +509,12 @@ test_cases.simplish.base_class.CallCounter.increment_counter: // simplish/base_class.py:13 // self.counter += 1 int 0 - // simplish/base_class.py:8 - // self.counter = UInt64(0) byte "counter" - // simplish/base_class.py:13 - // self.counter += 1 app_global_get_ex assert // check self.counter exists int 1 + - // simplish/base_class.py:8 - // self.counter = UInt64(0) byte "counter" - // simplish/base_class.py:13 - // self.counter += 1 uncover 1 app_global_put retsub diff --git a/test_cases/state_mutations/out/Contract.approval.mir b/test_cases/state_mutations/out/Contract.approval.mir index 6ffde2039c..0efc01fe33 100644 --- a/test_cases/state_mutations/out/Contract.approval.mir +++ b/test_cases/state_mutations/out/Contract.approval.mir @@ -124,7 +124,7 @@ append_block@0: callsub get_struct // {get_struct} get_struct() state_mutations/contract.py:38 // virtual: store struct#0 to l-stack (no copy) struct#0 struct = get_struct() state_mutations/contract.py:38 int 0 // struct#0,0 self.glob.value state_mutations/contract.py:39 - byte "glob" // struct#0,0,"glob" self.glob state_mutations/contract.py:24 + byte "glob" // struct#0,0,"glob" self.glob state_mutations/contract.py:39 app_global_get_ex // struct#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.glob.value state_mutations/contract.py:39 // virtual: store maybe_exists%0#0 to l-stack (no copy) struct#0,maybe_exists%0#0,{app_global_get_ex}.0 self.glob.value state_mutations/contract.py:39 // virtual: store maybe_value%0#0 to l-stack (no copy) struct#0,maybe_value%0#0,maybe_exists%0#0 self.glob.value state_mutations/contract.py:39 @@ -147,14 +147,14 @@ append_block@0: dig 3 // load result%1#0 from l-stack (copy) result%1#0,l_count%0#0,l_head_and_tail%0#0,1,result%1#0 self.glob.value.append(struct.copy()) state_mutations/contract.py:39 callsub dynamic_array_concat_dynamic_element // result%1#0,{dynamic_array_concat_dynamic_element} self.glob.value.append(struct.copy()) state_mutations/contract.py:39 // virtual: store concat_result%0#0 to l-stack (no copy) result%1#0,concat_result%0#0 self.glob.value.append(struct.copy()) state_mutations/contract.py:39 - byte "glob" // result%1#0,concat_result%0#0,"glob" self.glob state_mutations/contract.py:24 + byte "glob" // result%1#0,concat_result%0#0,"glob" self.glob state_mutations/contract.py:39 uncover 1 // load concat_result%0#0 from l-stack (no copy) result%1#0,"glob",concat_result%0#0 self.glob.value.append(struct.copy()) state_mutations/contract.py:39 app_global_put // result%1#0 self.glob.value.append(struct.copy()) state_mutations/contract.py:39 txn Sender // result%1#0,{txn} Txn.sender state_mutations/contract.py:40 // virtual: store tmp%0#0 to l-stack (no copy) result%1#0,tmp%0#0 Txn.sender state_mutations/contract.py:40 // virtual: load tmp%0#0 from l-stack (no copy) result%1#0,tmp%0#0 self.loc[Txn.sender] state_mutations/contract.py:40 int 0 // result%1#0,tmp%0#0,0 self.loc[Txn.sender] state_mutations/contract.py:40 - byte "loc" // result%1#0,tmp%0#0,0,"loc" self.loc state_mutations/contract.py:25 + byte "loc" // result%1#0,tmp%0#0,0,"loc" self.loc state_mutations/contract.py:40 app_local_get_ex // result%1#0,{app_local_get_ex}.0,{app_local_get_ex}.1 self.loc[Txn.sender] state_mutations/contract.py:40 // virtual: store maybe_exists%1#0 to l-stack (no copy) result%1#0,maybe_exists%1#0,{app_local_get_ex}.0 self.loc[Txn.sender] state_mutations/contract.py:40 // virtual: store maybe_value%1#0 to l-stack (no copy) result%1#0,maybe_value%1#0,maybe_exists%1#0 self.loc[Txn.sender] state_mutations/contract.py:40 @@ -176,10 +176,10 @@ append_block@0: txn Sender // result%1#0,concat_result%1#0,{txn} Txn.sender state_mutations/contract.py:40 // virtual: store tmp%1#0 to l-stack (no copy) result%1#0,concat_result%1#0,tmp%1#0 Txn.sender state_mutations/contract.py:40 // virtual: load tmp%1#0 from l-stack (no copy) result%1#0,concat_result%1#0,tmp%1#0 self.loc[Txn.sender].append(struct.copy()) state_mutations/contract.py:40 - byte "loc" // result%1#0,concat_result%1#0,tmp%1#0,"loc" self.loc state_mutations/contract.py:25 + byte "loc" // result%1#0,concat_result%1#0,tmp%1#0,"loc" self.loc state_mutations/contract.py:40 uncover 2 // load concat_result%1#0 from l-stack (no copy) result%1#0,tmp%1#0,"loc",concat_result%1#0 self.loc[Txn.sender].append(struct.copy()) state_mutations/contract.py:40 app_local_put // result%1#0 self.loc[Txn.sender].append(struct.copy()) state_mutations/contract.py:40 - byte "box" // result%1#0,"box" self.box state_mutations/contract.py:26 + byte "box" // result%1#0,"box" self.box state_mutations/contract.py:41 box_get // result%1#0,{box_get}.0,{box_get}.1 self.box.value state_mutations/contract.py:41 // virtual: store maybe_exists%2#0 to l-stack (no copy) result%1#0,maybe_exists%2#0,{box_get}.0 self.box.value state_mutations/contract.py:41 // virtual: store maybe_value%2#0 to l-stack (no copy) result%1#0,maybe_value%2#0,maybe_exists%2#0 self.box.value state_mutations/contract.py:41 @@ -198,15 +198,15 @@ append_block@0: dig 3 // load result%1#0 from l-stack (copy) result%1#0,l_count%2#0,l_head_and_tail%2#0,1,result%1#0 self.box.value.append(struct.copy()) state_mutations/contract.py:41 callsub dynamic_array_concat_dynamic_element // result%1#0,{dynamic_array_concat_dynamic_element} self.box.value.append(struct.copy()) state_mutations/contract.py:41 // virtual: store concat_result%2#0 to l-stack (no copy) result%1#0,concat_result%2#0 self.box.value.append(struct.copy()) state_mutations/contract.py:41 - byte "box" // result%1#0,concat_result%2#0,"box" self.box state_mutations/contract.py:26 + byte "box" // result%1#0,concat_result%2#0,"box" self.box state_mutations/contract.py:41 box_del // result%1#0,concat_result%2#0,{box_del} self.box.value.append(struct.copy()) state_mutations/contract.py:41 pop // result%1#0,concat_result%2#0 - byte "box" // result%1#0,concat_result%2#0,"box" self.box state_mutations/contract.py:26 + byte "box" // result%1#0,concat_result%2#0,"box" self.box state_mutations/contract.py:41 uncover 1 // load concat_result%2#0 from l-stack (no copy) result%1#0,"box",concat_result%2#0 self.box.value.append(struct.copy()) state_mutations/contract.py:41 box_put // result%1#0 self.box.value.append(struct.copy()) state_mutations/contract.py:41 txn Sender // result%1#0,{txn} Txn.sender state_mutations/contract.py:42 // virtual: store tmp%2#0 to l-stack (no copy) result%1#0,tmp%2#0 Txn.sender state_mutations/contract.py:42 - byte "map" // result%1#0,tmp%2#0,"map" self.map state_mutations/contract.py:27 + byte "map" // result%1#0,tmp%2#0,"map" self.map state_mutations/contract.py:42 uncover 1 // load tmp%2#0 from l-stack (no copy) result%1#0,"map",tmp%2#0 self.map[Txn.sender] state_mutations/contract.py:42 concat // result%1#0,{concat} self.map[Txn.sender] state_mutations/contract.py:42 // virtual: store tmp%3#0 to l-stack (no copy) result%1#0,tmp%3#0 self.map[Txn.sender] state_mutations/contract.py:42 @@ -231,7 +231,7 @@ append_block@0: // virtual: store concat_result%3#0 to l-stack (no copy) concat_result%3#0 self.map[Txn.sender].append(struct.copy()) state_mutations/contract.py:42 txn Sender // concat_result%3#0,{txn} Txn.sender state_mutations/contract.py:42 // virtual: store tmp%4#0 to l-stack (no copy) concat_result%3#0,tmp%4#0 Txn.sender state_mutations/contract.py:42 - byte "map" // concat_result%3#0,tmp%4#0,"map" self.map state_mutations/contract.py:27 + byte "map" // concat_result%3#0,tmp%4#0,"map" self.map state_mutations/contract.py:42 uncover 1 // load tmp%4#0 from l-stack (no copy) concat_result%3#0,"map",tmp%4#0 self.map[Txn.sender] state_mutations/contract.py:42 concat // concat_result%3#0,{concat} self.map[Txn.sender] state_mutations/contract.py:42 // virtual: store tmp%5#0 to l-stack (no copy) concat_result%3#0,tmp%5#0 self.map[Txn.sender] state_mutations/contract.py:42 @@ -259,7 +259,7 @@ modify: modify_block@0: int 0 // 0 self.glob.value state_mutations/contract.py:46 - byte "glob" // 0,"glob" self.glob state_mutations/contract.py:24 + byte "glob" // 0,"glob" self.glob state_mutations/contract.py:46 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.glob.value state_mutations/contract.py:46 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.glob.value state_mutations/contract.py:46 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.glob.value state_mutations/contract.py:46 @@ -311,7 +311,7 @@ modify_block@0: concat // {concat} self.glob.value[0].baz = arc4.String("modified") state_mutations/contract.py:46 // virtual: store updated_data%0#0 to l-stack (no copy) updated_data%0#0 self.glob.value[0].baz = arc4.String("modified") state_mutations/contract.py:46 int 0 // updated_data%0#0,0 self.glob.value state_mutations/contract.py:46 - byte "glob" // updated_data%0#0,0,"glob" self.glob state_mutations/contract.py:24 + byte "glob" // updated_data%0#0,0,"glob" self.glob state_mutations/contract.py:46 app_global_get_ex // updated_data%0#0,{app_global_get_ex}.0,{app_global_get_ex}.1 self.glob.value state_mutations/contract.py:46 // virtual: store maybe_exists%1#0 to l-stack (no copy) updated_data%0#0,maybe_exists%1#0,{app_global_get_ex}.0 self.glob.value state_mutations/contract.py:46 // virtual: store maybe_value%1#0 to l-stack (no copy) updated_data%0#0,maybe_value%1#0,maybe_exists%1#0 self.glob.value state_mutations/contract.py:46 @@ -322,14 +322,14 @@ modify_block@0: int 0 // maybe_value%1#0,updated_data%0#0,0 0 state_mutations/contract.py:46 callsub dynamic_array_replace_dynamic_element // {dynamic_array_replace_dynamic_element} self.glob.value[0].baz = arc4.String("modified") state_mutations/contract.py:46 // virtual: store updated_value%0#0 to l-stack (no copy) updated_value%0#0 self.glob.value[0].baz = arc4.String("modified") state_mutations/contract.py:46 - byte "glob" // updated_value%0#0,"glob" self.glob state_mutations/contract.py:24 + byte "glob" // updated_value%0#0,"glob" self.glob state_mutations/contract.py:46 uncover 1 // load updated_value%0#0 from l-stack (no copy) "glob",updated_value%0#0 self.glob.value[0].baz = arc4.String("modified") state_mutations/contract.py:46 app_global_put // self.glob.value[0].baz = arc4.String("modified") state_mutations/contract.py:46 txn Sender // {txn} Txn.sender state_mutations/contract.py:47 // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 Txn.sender state_mutations/contract.py:47 // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 self.loc[Txn.sender] state_mutations/contract.py:47 int 0 // tmp%1#0,0 self.loc[Txn.sender] state_mutations/contract.py:47 - byte "loc" // tmp%1#0,0,"loc" self.loc state_mutations/contract.py:25 + byte "loc" // tmp%1#0,0,"loc" self.loc state_mutations/contract.py:47 app_local_get_ex // {app_local_get_ex}.0,{app_local_get_ex}.1 self.loc[Txn.sender] state_mutations/contract.py:47 // virtual: store maybe_exists%2#0 to l-stack (no copy) maybe_exists%2#0,{app_local_get_ex}.0 self.loc[Txn.sender] state_mutations/contract.py:47 // virtual: store maybe_value%2#0 to l-stack (no copy) maybe_value%2#0,maybe_exists%2#0 self.loc[Txn.sender] state_mutations/contract.py:47 @@ -384,7 +384,7 @@ modify_block@0: // virtual: store tmp%3#0 to l-stack (no copy) updated_data%1#0,tmp%3#0 Txn.sender state_mutations/contract.py:47 // virtual: load tmp%3#0 from l-stack (no copy) updated_data%1#0,tmp%3#0 self.loc[Txn.sender] state_mutations/contract.py:47 int 0 // updated_data%1#0,tmp%3#0,0 self.loc[Txn.sender] state_mutations/contract.py:47 - byte "loc" // updated_data%1#0,tmp%3#0,0,"loc" self.loc state_mutations/contract.py:25 + byte "loc" // updated_data%1#0,tmp%3#0,0,"loc" self.loc state_mutations/contract.py:47 app_local_get_ex // updated_data%1#0,{app_local_get_ex}.0,{app_local_get_ex}.1 self.loc[Txn.sender] state_mutations/contract.py:47 // virtual: store maybe_exists%3#0 to l-stack (no copy) updated_data%1#0,maybe_exists%3#0,{app_local_get_ex}.0 self.loc[Txn.sender] state_mutations/contract.py:47 // virtual: store maybe_value%3#0 to l-stack (no copy) updated_data%1#0,maybe_value%3#0,maybe_exists%3#0 self.loc[Txn.sender] state_mutations/contract.py:47 @@ -398,10 +398,10 @@ modify_block@0: txn Sender // updated_value%1#0,{txn} Txn.sender state_mutations/contract.py:47 // virtual: store tmp%4#0 to l-stack (no copy) updated_value%1#0,tmp%4#0 Txn.sender state_mutations/contract.py:47 // virtual: load tmp%4#0 from l-stack (no copy) updated_value%1#0,tmp%4#0 self.loc[Txn.sender][0].baz = arc4.String("modified") state_mutations/contract.py:47 - byte "loc" // updated_value%1#0,tmp%4#0,"loc" self.loc state_mutations/contract.py:25 + byte "loc" // updated_value%1#0,tmp%4#0,"loc" self.loc state_mutations/contract.py:47 uncover 2 // load updated_value%1#0 from l-stack (no copy) tmp%4#0,"loc",updated_value%1#0 self.loc[Txn.sender][0].baz = arc4.String("modified") state_mutations/contract.py:47 app_local_put // self.loc[Txn.sender][0].baz = arc4.String("modified") state_mutations/contract.py:47 - byte "box" // "box" self.box state_mutations/contract.py:26 + byte "box" // "box" self.box state_mutations/contract.py:48 box_get // {box_get}.0,{box_get}.1 self.box.value state_mutations/contract.py:48 // virtual: store maybe_exists%4#0 to l-stack (no copy) maybe_exists%4#0,{box_get}.0 self.box.value state_mutations/contract.py:48 // virtual: store maybe_value%4#0 to l-stack (no copy) maybe_value%4#0,maybe_exists%4#0 self.box.value state_mutations/contract.py:48 @@ -452,7 +452,7 @@ modify_block@0: byte 0x00086d6f646966696564 // data_up_to_item%2#0,0x00086d6f646966696564 arc4.String("modified") state_mutations/contract.py:48 concat // {concat} self.box.value[0].baz = arc4.String("modified") state_mutations/contract.py:48 // virtual: store updated_data%2#0 to l-stack (no copy) updated_data%2#0 self.box.value[0].baz = arc4.String("modified") state_mutations/contract.py:48 - byte "box" // updated_data%2#0,"box" self.box state_mutations/contract.py:26 + byte "box" // updated_data%2#0,"box" self.box state_mutations/contract.py:48 box_get // updated_data%2#0,{box_get}.0,{box_get}.1 self.box.value state_mutations/contract.py:48 // virtual: store maybe_exists%5#0 to l-stack (no copy) updated_data%2#0,maybe_exists%5#0,{box_get}.0 self.box.value state_mutations/contract.py:48 // virtual: store maybe_value%5#0 to l-stack (no copy) updated_data%2#0,maybe_value%5#0,maybe_exists%5#0 self.box.value state_mutations/contract.py:48 @@ -463,15 +463,15 @@ modify_block@0: int 0 // maybe_value%5#0,updated_data%2#0,0 0 state_mutations/contract.py:48 callsub dynamic_array_replace_dynamic_element // {dynamic_array_replace_dynamic_element} self.box.value[0].baz = arc4.String("modified") state_mutations/contract.py:48 // virtual: store updated_value%2#0 to l-stack (no copy) updated_value%2#0 self.box.value[0].baz = arc4.String("modified") state_mutations/contract.py:48 - byte "box" // updated_value%2#0,"box" self.box state_mutations/contract.py:26 + byte "box" // updated_value%2#0,"box" self.box state_mutations/contract.py:48 box_del // updated_value%2#0,{box_del} self.box.value[0].baz = arc4.String("modified") state_mutations/contract.py:48 pop // updated_value%2#0 - byte "box" // updated_value%2#0,"box" self.box state_mutations/contract.py:26 + byte "box" // updated_value%2#0,"box" self.box state_mutations/contract.py:48 uncover 1 // load updated_value%2#0 from l-stack (no copy) "box",updated_value%2#0 self.box.value[0].baz = arc4.String("modified") state_mutations/contract.py:48 box_put // self.box.value[0].baz = arc4.String("modified") state_mutations/contract.py:48 txn Sender // {txn} Txn.sender state_mutations/contract.py:49 // virtual: store tmp%6#0 to l-stack (no copy) tmp%6#0 Txn.sender state_mutations/contract.py:49 - byte "map" // tmp%6#0,"map" self.map state_mutations/contract.py:27 + byte "map" // tmp%6#0,"map" self.map state_mutations/contract.py:49 uncover 1 // load tmp%6#0 from l-stack (no copy) "map",tmp%6#0 self.map[Txn.sender] state_mutations/contract.py:49 concat // {concat} self.map[Txn.sender] state_mutations/contract.py:49 // virtual: store tmp%7#0 to l-stack (no copy) tmp%7#0 self.map[Txn.sender] state_mutations/contract.py:49 @@ -528,7 +528,7 @@ modify_block@0: // virtual: store updated_data%3#0 to l-stack (no copy) updated_data%3#0 self.map[Txn.sender][0].baz = arc4.String("modified") state_mutations/contract.py:49 txn Sender // updated_data%3#0,{txn} Txn.sender state_mutations/contract.py:49 // virtual: store tmp%9#0 to l-stack (no copy) updated_data%3#0,tmp%9#0 Txn.sender state_mutations/contract.py:49 - byte "map" // updated_data%3#0,tmp%9#0,"map" self.map state_mutations/contract.py:27 + byte "map" // updated_data%3#0,tmp%9#0,"map" self.map state_mutations/contract.py:49 uncover 1 // load tmp%9#0 from l-stack (no copy) updated_data%3#0,"map",tmp%9#0 self.map[Txn.sender] state_mutations/contract.py:49 concat // updated_data%3#0,{concat} self.map[Txn.sender] state_mutations/contract.py:49 // virtual: store tmp%10#0 to l-stack (no copy) updated_data%3#0,tmp%10#0 self.map[Txn.sender] state_mutations/contract.py:49 @@ -545,7 +545,7 @@ modify_block@0: // virtual: store updated_value%3#0 to l-stack (no copy) updated_value%3#0 self.map[Txn.sender][0].baz = arc4.String("modified") state_mutations/contract.py:49 txn Sender // updated_value%3#0,{txn} Txn.sender state_mutations/contract.py:49 // virtual: store tmp%11#0 to l-stack (no copy) updated_value%3#0,tmp%11#0 Txn.sender state_mutations/contract.py:49 - byte "map" // updated_value%3#0,tmp%11#0,"map" self.map state_mutations/contract.py:27 + byte "map" // updated_value%3#0,tmp%11#0,"map" self.map state_mutations/contract.py:49 uncover 1 // load tmp%11#0 from l-stack (no copy) updated_value%3#0,"map",tmp%11#0 self.map[Txn.sender] state_mutations/contract.py:49 concat // updated_value%3#0,{concat} self.map[Txn.sender] state_mutations/contract.py:49 // virtual: store tmp%12#0 to l-stack (no copy) updated_value%3#0,tmp%12#0 self.map[Txn.sender] state_mutations/contract.py:49 @@ -564,7 +564,7 @@ get: get_block@0: int 0 // 0 self.glob.value state_mutations/contract.py:53 - byte "glob" // 0,"glob" self.glob state_mutations/contract.py:24 + byte "glob" // 0,"glob" self.glob state_mutations/contract.py:53 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.glob.value state_mutations/contract.py:53 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.glob.value state_mutations/contract.py:53 // virtual: store a1#0 to l-stack (no copy) a1#0,maybe_exists%0#0 self.glob.value state_mutations/contract.py:53 @@ -574,13 +574,13 @@ get_block@0: // virtual: store tmp%0#0 to l-stack (no copy) a1#0,tmp%0#0 Txn.sender state_mutations/contract.py:54 // virtual: load tmp%0#0 from l-stack (no copy) a1#0,tmp%0#0 self.loc[Txn.sender] state_mutations/contract.py:54 int 0 // a1#0,tmp%0#0,0 self.loc[Txn.sender] state_mutations/contract.py:54 - byte "loc" // a1#0,tmp%0#0,0,"loc" self.loc state_mutations/contract.py:25 + byte "loc" // a1#0,tmp%0#0,0,"loc" self.loc state_mutations/contract.py:54 app_local_get_ex // a1#0,{app_local_get_ex}.0,{app_local_get_ex}.1 self.loc[Txn.sender] state_mutations/contract.py:54 // virtual: store maybe_exists%1#0 to l-stack (no copy) a1#0,maybe_exists%1#0,{app_local_get_ex}.0 self.loc[Txn.sender] state_mutations/contract.py:54 // virtual: store a2#0 to l-stack (no copy) a1#0,a2#0,maybe_exists%1#0 self.loc[Txn.sender] state_mutations/contract.py:54 // virtual: load maybe_exists%1#0 from l-stack (no copy) a1#0,a2#0,maybe_exists%1#0 self.loc[Txn.sender] state_mutations/contract.py:54 assert // check self.loc exists for account // a1#0,a2#0 self.loc[Txn.sender] state_mutations/contract.py:54 - byte "box" // a1#0,a2#0,"box" self.box state_mutations/contract.py:26 + byte "box" // a1#0,a2#0,"box" self.box state_mutations/contract.py:55 box_get // a1#0,a2#0,{box_get}.0,{box_get}.1 self.box.value state_mutations/contract.py:55 cover 1 // store maybe_exists%2#0 to l-stack (no copy) a1#0,a2#0,maybe_exists%2#0,{box_get}.0 self.box.value state_mutations/contract.py:55 cover 2 // store a3#0 to l-stack (no copy) a1#0,a3#0,a2#0,maybe_exists%2#0 self.box.value state_mutations/contract.py:55 @@ -588,7 +588,7 @@ get_block@0: assert // check self.box exists // a1#0,a3#0,a2#0 self.box.value state_mutations/contract.py:55 txn Sender // a1#0,a3#0,a2#0,{txn} Txn.sender state_mutations/contract.py:56 // virtual: store tmp%1#0 to l-stack (no copy) a1#0,a3#0,a2#0,tmp%1#0 Txn.sender state_mutations/contract.py:56 - byte "map" // a1#0,a3#0,a2#0,tmp%1#0,"map" self.map state_mutations/contract.py:27 + byte "map" // a1#0,a3#0,a2#0,tmp%1#0,"map" self.map state_mutations/contract.py:56 uncover 1 // load tmp%1#0 from l-stack (no copy) a1#0,a3#0,a2#0,"map",tmp%1#0 self.map[Txn.sender] state_mutations/contract.py:56 concat // a1#0,a3#0,a2#0,{concat} self.map[Txn.sender] state_mutations/contract.py:56 // virtual: store tmp%2#0 to l-stack (no copy) a1#0,a3#0,a2#0,tmp%2#0 self.map[Txn.sender] state_mutations/contract.py:56 @@ -625,24 +625,24 @@ opt_in: proto 0 0 // @arc4.baremethod(allow_actions=["OptIn"])\ndef opt_in(self) -> None: state_mutations/contract.py:29-30 opt_in_block@0: - byte "glob" // "glob" self.glob state_mutations/contract.py:24 + byte "glob" // "glob" self.glob state_mutations/contract.py:31 byte 0x0000 // "glob",0x0000 MyArray() state_mutations/contract.py:31 app_global_put // self.glob.value = MyArray() state_mutations/contract.py:31 - byte "box" // "box" self.box state_mutations/contract.py:26 + byte "box" // "box" self.box state_mutations/contract.py:32 box_del // {box_del} self.box.value = MyArray() state_mutations/contract.py:32 pop // - byte "box" // "box" self.box state_mutations/contract.py:26 + byte "box" // "box" self.box state_mutations/contract.py:32 byte 0x0000 // "box",0x0000 MyArray() state_mutations/contract.py:32 box_put // self.box.value = MyArray() state_mutations/contract.py:32 txn Sender // {txn} Txn.sender state_mutations/contract.py:33 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Txn.sender state_mutations/contract.py:33 // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 self.loc[Txn.sender] = MyArray() state_mutations/contract.py:33 - byte "loc" // tmp%0#0,"loc" self.loc state_mutations/contract.py:25 + byte "loc" // tmp%0#0,"loc" self.loc state_mutations/contract.py:33 byte 0x0000 // tmp%0#0,"loc",0x0000 MyArray() state_mutations/contract.py:33 app_local_put // self.loc[Txn.sender] = MyArray() state_mutations/contract.py:33 txn Sender // {txn} Txn.sender state_mutations/contract.py:34 // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 Txn.sender state_mutations/contract.py:34 - byte "map" // tmp%1#0,"map" self.map state_mutations/contract.py:27 + byte "map" // tmp%1#0,"map" self.map state_mutations/contract.py:34 uncover 1 // load tmp%1#0 from l-stack (no copy) "map",tmp%1#0 self.map[Txn.sender] state_mutations/contract.py:34 concat // {concat} self.map[Txn.sender] state_mutations/contract.py:34 // virtual: store tmp%2#0 to l-stack (no copy) tmp%2#0 self.map[Txn.sender] state_mutations/contract.py:34 diff --git a/test_cases/state_mutations/out/Contract.approval.teal b/test_cases/state_mutations/out/Contract.approval.teal index 73b2f86105..f324ce6055 100644 --- a/test_cases/state_mutations/out/Contract.approval.teal +++ b/test_cases/state_mutations/out/Contract.approval.teal @@ -102,11 +102,7 @@ append: // state_mutations/contract.py:39 // self.glob.value.append(struct.copy()) int 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:39 - // self.glob.value.append(struct.copy()) app_global_get_ex assert // check self.glob exists byte 0x0002 @@ -121,22 +117,14 @@ append: int 1 dig 3 callsub dynamic_array_concat_dynamic_element - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:39 - // self.glob.value.append(struct.copy()) swap app_global_put // state_mutations/contract.py:40 // self.loc[Txn.sender].append(struct.copy()) txn Sender int 0 - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:40 - // self.loc[Txn.sender].append(struct.copy()) app_local_get_ex assert // check self.loc exists for account dup @@ -148,18 +136,12 @@ append: dig 3 callsub dynamic_array_concat_dynamic_element txn Sender - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:40 - // self.loc[Txn.sender].append(struct.copy()) uncover 2 app_local_put - // state_mutations/contract.py:26 - // self.box = Box(MyArray) - byte "box" // state_mutations/contract.py:41 // self.box.value.append(struct.copy()) + byte "box" box_get assert // check self.box exists dup @@ -170,25 +152,15 @@ append: int 1 dig 3 callsub dynamic_array_concat_dynamic_element - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:41 - // self.box.value.append(struct.copy()) box_del pop - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:41 - // self.box.value.append(struct.copy()) swap box_put - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) - byte "map" // state_mutations/contract.py:42 // self.map[Txn.sender].append(struct.copy()) + byte "map" txn Sender concat box_get @@ -201,11 +173,7 @@ append: int 1 uncover 3 callsub dynamic_array_concat_dynamic_element - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:42 - // self.map[Txn.sender].append(struct.copy()) txn Sender concat dup @@ -240,11 +208,7 @@ modify: // state_mutations/contract.py:46 // self.glob.value[0].baz = arc4.String("modified") int 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:46 - // self.glob.value[0].baz = arc4.String("modified") app_global_get_ex assert // check self.glob exists dup @@ -278,32 +242,20 @@ modify: byte 0x00086d6f646966696564 concat int 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:46 - // self.glob.value[0].baz = arc4.String("modified") app_global_get_ex assert // check self.glob exists swap int 0 callsub dynamic_array_replace_dynamic_element - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:46 - // self.glob.value[0].baz = arc4.String("modified") swap app_global_put // state_mutations/contract.py:47 // self.loc[Txn.sender][0].baz = arc4.String("modified") txn Sender int 0 - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:47 - // self.loc[Txn.sender][0].baz = arc4.String("modified") app_local_get_ex assert // check self.loc exists for account dup @@ -338,29 +290,19 @@ modify: concat txn Sender int 0 - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:47 - // self.loc[Txn.sender][0].baz = arc4.String("modified") app_local_get_ex assert // check self.loc exists for account swap int 0 callsub dynamic_array_replace_dynamic_element txn Sender - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:47 - // self.loc[Txn.sender][0].baz = arc4.String("modified") uncover 2 app_local_put - // state_mutations/contract.py:26 - // self.box = Box(MyArray) - byte "box" // state_mutations/contract.py:48 // self.box.value[0].baz = arc4.String("modified") + byte "box" box_get assert // check self.box exists dup @@ -393,35 +335,21 @@ modify: extract3 byte 0x00086d6f646966696564 concat - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:48 - // self.box.value[0].baz = arc4.String("modified") box_get assert // check self.box exists swap int 0 callsub dynamic_array_replace_dynamic_element - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:48 - // self.box.value[0].baz = arc4.String("modified") box_del pop - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:48 - // self.box.value[0].baz = arc4.String("modified") swap box_put - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) - byte "map" // state_mutations/contract.py:49 // self.map[Txn.sender][0].baz = arc4.String("modified") + byte "map" txn Sender concat box_get @@ -456,11 +384,7 @@ modify: extract3 byte 0x00086d6f646966696564 concat - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:49 - // self.map[Txn.sender][0].baz = arc4.String("modified") txn Sender concat box_get @@ -468,11 +392,7 @@ modify: swap int 0 callsub dynamic_array_replace_dynamic_element - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:49 - // self.map[Txn.sender][0].baz = arc4.String("modified") txn Sender concat dup @@ -492,38 +412,26 @@ get: // state_mutations/contract.py:53 // a1 = self.glob.value.copy() int 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:53 - // a1 = self.glob.value.copy() app_global_get_ex assert // check self.glob exists // state_mutations/contract.py:54 // a2 = self.loc[Txn.sender].copy() txn Sender int 0 - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:54 - // a2 = self.loc[Txn.sender].copy() app_local_get_ex assert // check self.loc exists for account - // state_mutations/contract.py:26 - // self.box = Box(MyArray) - byte "box" // state_mutations/contract.py:55 // a3 = self.box.value.copy() + byte "box" box_get swap cover 2 assert // check self.box exists - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) - byte "map" // state_mutations/contract.py:56 // a4 = self.map[Txn.sender].copy() + byte "map" txn Sender concat box_get @@ -556,42 +464,28 @@ opt_in: // @arc4.baremethod(allow_actions=["OptIn"]) // def opt_in(self) -> None: proto 0 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) - byte "glob" // state_mutations/contract.py:31 // self.glob.value = MyArray() + byte "glob" byte 0x0000 app_global_put - // state_mutations/contract.py:26 - // self.box = Box(MyArray) - byte "box" // state_mutations/contract.py:32 // self.box.value = MyArray() + byte "box" box_del pop - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:32 - // self.box.value = MyArray() byte 0x0000 box_put // state_mutations/contract.py:33 // self.loc[Txn.sender] = MyArray() txn Sender - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:33 - // self.loc[Txn.sender] = MyArray() byte 0x0000 app_local_put - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) - byte "map" // state_mutations/contract.py:34 // self.map[Txn.sender] = MyArray() + byte "map" txn Sender concat dup diff --git a/test_cases/state_mutations/out/Contract.arc32.json b/test_cases/state_mutations/out/Contract.arc32.json index b40beba278..9fd47ac8a2 100644 --- a/test_cases/state_mutations/out/Contract.arc32.json +++ b/test_cases/state_mutations/out/Contract.arc32.json @@ -17,7 +17,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX211dGF0aW9ucy5jb250cmFjdC5Db250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5zdGF0ZV9tdXRhdGlvbnMuY29udHJhY3QuQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDcKICAgIG1ldGhvZCAiYXBwZW5kKCl2b2lkIgogICAgbWV0aG9kICJtb2RpZnkoKXZvaWQiCiAgICBtZXRob2QgImdldCgpKHVpbnQ2NCxzdHJpbmcpW10iCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcHBlbmRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19tb2RpZnlfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfcm91dGVANAogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXBwZW5kX3JvdXRlQDI6CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBhcHBlbmQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX21vZGlmeV9yb3V0ZUAzOgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgbW9kaWZ5CiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfcm91dGVANDoKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDc6CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjIKICAgIC8vIGNsYXNzIENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBzd2l0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvcHlfZGVmYXVsdF9jcmVhdGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW5AOQogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvcHlfZGVmYXVsdF9jcmVhdGVAODoKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbkA5OgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI5CiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyOS0zMAogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIC8vIGRlZiBvcHRfaW4oc2VsZikgLT4gTm9uZToKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5zdGF0ZV9tdXRhdGlvbnMuY29udHJhY3QuQ29udHJhY3QuYXBwZW5kKCkgLT4gdm9pZDoKYXBwZW5kOgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjM2LTM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBhcHBlbmQoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjM4CiAgICAvLyBzdHJ1Y3QgPSBnZXRfc3RydWN0KCkKICAgIGNhbGxzdWIgZ2V0X3N0cnVjdAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjM5CiAgICAvLyBzZWxmLmdsb2IudmFsdWUuYXBwZW5kKHN0cnVjdC5jb3B5KCkpCiAgICBpbnQgMAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBzZWxmLmdsb2IgPSBHbG9iYWxTdGF0ZShNeUFycmF5KQogICAgYnl0ZSAiZ2xvYiIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTozOQogICAgLy8gc2VsZi5nbG9iLnZhbHVlLmFwcGVuZChzdHJ1Y3QuY29weSgpKQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmdsb2IgZXhpc3RzCiAgICBieXRlIDB4MDAwMgogICAgdW5jb3ZlciAyCiAgICBjb25jYXQKICAgIHN3YXAKICAgIGR1cAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBleHRyYWN0IDIgMAogICAgaW50IDEKICAgIGRpZyAzCiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBzZWxmLmdsb2IgPSBHbG9iYWxTdGF0ZShNeUFycmF5KQogICAgYnl0ZSAiZ2xvYiIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTozOQogICAgLy8gc2VsZi5nbG9iLnZhbHVlLmFwcGVuZChzdHJ1Y3QuY29weSgpKQogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo0MAogICAgLy8gc2VsZi5sb2NbVHhuLnNlbmRlcl0uYXBwZW5kKHN0cnVjdC5jb3B5KCkpCiAgICB0eG4gU2VuZGVyCiAgICBpbnQgMAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBzZWxmLmxvYyA9IExvY2FsU3RhdGUoTXlBcnJheSkKICAgIGJ5dGUgImxvYyIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo0MAogICAgLy8gc2VsZi5sb2NbVHhuLnNlbmRlcl0uYXBwZW5kKHN0cnVjdC5jb3B5KCkpCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2MgZXhpc3RzIGZvciBhY2NvdW50CiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgZXh0cmFjdCAyIDAKICAgIGludCAxCiAgICBkaWcgMwogICAgY2FsbHN1YiBkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnQKICAgIHR4biBTZW5kZXIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyNQogICAgLy8gc2VsZi5sb2MgPSBMb2NhbFN0YXRlKE15QXJyYXkpCiAgICBieXRlICJsb2MiCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDAKICAgIC8vIHNlbGYubG9jW1R4bi5zZW5kZXJdLmFwcGVuZChzdHJ1Y3QuY29weSgpKQogICAgdW5jb3ZlciAyCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjYKICAgIC8vIHNlbGYuYm94ID0gQm94KE15QXJyYXkpCiAgICBieXRlICJib3giCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDEKICAgIC8vIHNlbGYuYm94LnZhbHVlLmFwcGVuZChzdHJ1Y3QuY29weSgpKQogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94IGV4aXN0cwogICAgZHVwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIGV4dHJhY3QgMiAwCiAgICBpbnQgMQogICAgZGlnIDMKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9jb25jYXRfZHluYW1pY19lbGVtZW50CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjYKICAgIC8vIHNlbGYuYm94ID0gQm94KE15QXJyYXkpCiAgICBieXRlICJib3giCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDEKICAgIC8vIHNlbGYuYm94LnZhbHVlLmFwcGVuZChzdHJ1Y3QuY29weSgpKQogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjYKICAgIC8vIHNlbGYuYm94ID0gQm94KE15QXJyYXkpCiAgICBieXRlICJib3giCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDEKICAgIC8vIHNlbGYuYm94LnZhbHVlLmFwcGVuZChzdHJ1Y3QuY29weSgpKQogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBzZWxmLm1hcCA9IEJveE1hcChBY2NvdW50LCBNeUFycmF5KQogICAgYnl0ZSAibWFwIgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQyCiAgICAvLyBzZWxmLm1hcFtUeG4uc2VuZGVyXS5hcHBlbmQoc3RydWN0LmNvcHkoKSkKICAgIHR4biBTZW5kZXIKICAgIGNvbmNhdAogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubWFwIGVudHJ5IGV4aXN0cwogICAgZHVwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIGV4dHJhY3QgMiAwCiAgICBpbnQgMQogICAgdW5jb3ZlciAzCiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBzZWxmLm1hcCA9IEJveE1hcChBY2NvdW50LCBNeUFycmF5KQogICAgYnl0ZSAibWFwIgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQyCiAgICAvLyBzZWxmLm1hcFtUeG4uc2VuZGVyXS5hcHBlbmQoc3RydWN0LmNvcHkoKSkKICAgIHR4biBTZW5kZXIKICAgIGNvbmNhdAogICAgZHVwCiAgICBib3hfZGVsCiAgICBwb3AKICAgIHN3YXAKICAgIGJveF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfbXV0YXRpb25zLmNvbnRyYWN0LmdldF9zdHJ1Y3QoKSAtPiBieXRlczoKZ2V0X3N0cnVjdDoKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo2NC02NQogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiBnZXRfc3RydWN0KCkgLT4gTXlTdHJ1Y3Q6CiAgICBwcm90byAwIDEKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo2Ni02OQogICAgLy8gcmV0dXJuIE15U3RydWN0KAogICAgLy8gICAgIGJhcj1hcmM0LlVJbnQ2NCgxKSwKICAgIC8vICAgICBiYXo9YXJjNC5TdHJpbmcoImJheiIpLAogICAgLy8gKQogICAgYnl0ZSAweDAwMDAwMDAwMDAwMDAwMDEwMDBhMDAwMzYyNjE3YQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5zdGF0ZV9tdXRhdGlvbnMuY29udHJhY3QuQ29udHJhY3QubW9kaWZ5KCkgLT4gdm9pZDoKbW9kaWZ5OgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ0LTQ1CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBtb2RpZnkoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ2CiAgICAvLyBzZWxmLmdsb2IudmFsdWVbMF0uYmF6ID0gYXJjNC5TdHJpbmcoIm1vZGlmaWVkIikKICAgIGludCAwCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjQKICAgIC8vIHNlbGYuZ2xvYiA9IEdsb2JhbFN0YXRlKE15QXJyYXkpCiAgICBieXRlICJnbG9iIgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ2CiAgICAvLyBzZWxmLmdsb2IudmFsdWVbMF0uYmF6ID0gYXJjNC5TdHJpbmcoIm1vZGlmaWVkIikKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nbG9iIGV4aXN0cwogICAgZHVwCiAgICBleHRyYWN0IDIgMAogICAgZHVwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGNvdmVyIDIKICAgIHN3YXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDEKICAgIC0gLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkaWcgMQogICAgbGVuCiAgICBzd2FwCiAgICBkaWcgMgogICAgaW50IDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBzZWxlY3QKICAgIHN3YXAKICAgIGNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGR1cAogICAgaW50IDgKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMAogICAgc3dhcAogICAgZXh0cmFjdDMKICAgIGJ5dGUgMHgwMDA4NmQ2ZjY0Njk2NjY5NjU2NAogICAgY29uY2F0CiAgICBpbnQgMAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBzZWxmLmdsb2IgPSBHbG9iYWxTdGF0ZShNeUFycmF5KQogICAgYnl0ZSAiZ2xvYiIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo0NgogICAgLy8gc2VsZi5nbG9iLnZhbHVlWzBdLmJheiA9IGFyYzQuU3RyaW5nKCJtb2RpZmllZCIpCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuZ2xvYiBleGlzdHMKICAgIHN3YXAKICAgIGludCAwCiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfcmVwbGFjZV9keW5hbWljX2VsZW1lbnQKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyNAogICAgLy8gc2VsZi5nbG9iID0gR2xvYmFsU3RhdGUoTXlBcnJheSkKICAgIGJ5dGUgImdsb2IiCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDYKICAgIC8vIHNlbGYuZ2xvYi52YWx1ZVswXS5iYXogPSBhcmM0LlN0cmluZygibW9kaWZpZWQiKQogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo0NwogICAgLy8gc2VsZi5sb2NbVHhuLnNlbmRlcl1bMF0uYmF6ID0gYXJjNC5TdHJpbmcoIm1vZGlmaWVkIikKICAgIHR4biBTZW5kZXIKICAgIGludCAwCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjUKICAgIC8vIHNlbGYubG9jID0gTG9jYWxTdGF0ZShNeUFycmF5KQogICAgYnl0ZSAibG9jIgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ3CiAgICAvLyBzZWxmLmxvY1tUeG4uc2VuZGVyXVswXS5iYXogPSBhcmM0LlN0cmluZygibW9kaWZpZWQiKQogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jIGV4aXN0cyBmb3IgYWNjb3VudAogICAgZHVwCiAgICBleHRyYWN0IDIgMAogICAgZHVwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGNvdmVyIDIKICAgIHN3YXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDEKICAgIC0gLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkaWcgMQogICAgbGVuCiAgICBzd2FwCiAgICBkaWcgMgogICAgaW50IDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBzZWxlY3QKICAgIHN3YXAKICAgIGNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGR1cAogICAgaW50IDgKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMAogICAgc3dhcAogICAgZXh0cmFjdDMKICAgIGJ5dGUgMHgwMDA4NmQ2ZjY0Njk2NjY5NjU2NAogICAgY29uY2F0CiAgICB0eG4gU2VuZGVyCiAgICBpbnQgMAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI1CiAgICAvLyBzZWxmLmxvYyA9IExvY2FsU3RhdGUoTXlBcnJheSkKICAgIGJ5dGUgImxvYyIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo0NwogICAgLy8gc2VsZi5sb2NbVHhuLnNlbmRlcl1bMF0uYmF6ID0gYXJjNC5TdHJpbmcoIm1vZGlmaWVkIikKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmxvYyBleGlzdHMgZm9yIGFjY291bnQKICAgIHN3YXAKICAgIGludCAwCiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfcmVwbGFjZV9keW5hbWljX2VsZW1lbnQKICAgIHR4biBTZW5kZXIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyNQogICAgLy8gc2VsZi5sb2MgPSBMb2NhbFN0YXRlKE15QXJyYXkpCiAgICBieXRlICJsb2MiCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDcKICAgIC8vIHNlbGYubG9jW1R4bi5zZW5kZXJdWzBdLmJheiA9IGFyYzQuU3RyaW5nKCJtb2RpZmllZCIpCiAgICB1bmNvdmVyIDIKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyNgogICAgLy8gc2VsZi5ib3ggPSBCb3goTXlBcnJheSkKICAgIGJ5dGUgImJveCIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo0OAogICAgLy8gc2VsZi5ib3gudmFsdWVbMF0uYmF6ID0gYXJjNC5TdHJpbmcoIm1vZGlmaWVkIikKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveCBleGlzdHMKICAgIGR1cAogICAgZXh0cmFjdCAyIDAKICAgIGR1cAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGludCAxCiAgICAtIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZGlnIDEKICAgIGxlbgogICAgc3dhcAogICAgZGlnIDIKICAgIGludCAyCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgc2VsZWN0CiAgICBzd2FwCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICBkdXAKICAgIGludCA4CiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDAKICAgIHN3YXAKICAgIGV4dHJhY3QzCiAgICBieXRlIDB4MDAwODZkNmY2NDY5NjY2OTY1NjQKICAgIGNvbmNhdAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI2CiAgICAvLyBzZWxmLmJveCA9IEJveChNeUFycmF5KQogICAgYnl0ZSAiYm94IgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ4CiAgICAvLyBzZWxmLmJveC52YWx1ZVswXS5iYXogPSBhcmM0LlN0cmluZygibW9kaWZpZWQiKQogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYm94IGV4aXN0cwogICAgc3dhcAogICAgaW50IDAKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI2CiAgICAvLyBzZWxmLmJveCA9IEJveChNeUFycmF5KQogICAgYnl0ZSAiYm94IgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ4CiAgICAvLyBzZWxmLmJveC52YWx1ZVswXS5iYXogPSBhcmM0LlN0cmluZygibW9kaWZpZWQiKQogICAgYm94X2RlbAogICAgcG9wCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjYKICAgIC8vIHNlbGYuYm94ID0gQm94KE15QXJyYXkpCiAgICBieXRlICJib3giCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDgKICAgIC8vIHNlbGYuYm94LnZhbHVlWzBdLmJheiA9IGFyYzQuU3RyaW5nKCJtb2RpZmllZCIpCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjcKICAgIC8vIHNlbGYubWFwID0gQm94TWFwKEFjY291bnQsIE15QXJyYXkpCiAgICBieXRlICJtYXAiCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDkKICAgIC8vIHNlbGYubWFwW1R4bi5zZW5kZXJdWzBdLmJheiA9IGFyYzQuU3RyaW5nKCJtb2RpZmllZCIpCiAgICB0eG4gU2VuZGVyCiAgICBjb25jYXQKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLm1hcCBlbnRyeSBleGlzdHMKICAgIGR1cAogICAgZXh0cmFjdCAyIDAKICAgIGR1cAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGludCAxCiAgICAtIC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgZGlnIDEKICAgIGxlbgogICAgc3dhcAogICAgZGlnIDIKICAgIGludCAyCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgc2VsZWN0CiAgICBzd2FwCiAgICBjb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICBkdXAKICAgIGludCA4CiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDAKICAgIHN3YXAKICAgIGV4dHJhY3QzCiAgICBieXRlIDB4MDAwODZkNmY2NDY5NjY2OTY1NjQKICAgIGNvbmNhdAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBzZWxmLm1hcCA9IEJveE1hcChBY2NvdW50LCBNeUFycmF5KQogICAgYnl0ZSAibWFwIgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyBzZWxmLm1hcFtUeG4uc2VuZGVyXVswXS5iYXogPSBhcmM0LlN0cmluZygibW9kaWZpZWQiKQogICAgdHhuIFNlbmRlcgogICAgY29uY2F0CiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5tYXAgZW50cnkgZXhpc3RzCiAgICBzd2FwCiAgICBpbnQgMAogICAgY2FsbHN1YiBkeW5hbWljX2FycmF5X3JlcGxhY2VfZHluYW1pY19lbGVtZW50CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjcKICAgIC8vIHNlbGYubWFwID0gQm94TWFwKEFjY291bnQsIE15QXJyYXkpCiAgICBieXRlICJtYXAiCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDkKICAgIC8vIHNlbGYubWFwW1R4bi5zZW5kZXJdWzBdLmJheiA9IGFyYzQuU3RyaW5nKCJtb2RpZmllZCIpCiAgICB0eG4gU2VuZGVyCiAgICBjb25jYXQKICAgIGR1cAogICAgYm94X2RlbAogICAgcG9wCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnN0YXRlX211dGF0aW9ucy5jb250cmFjdC5Db250cmFjdC5nZXQoKSAtPiBieXRlczoKZ2V0OgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjUxLTUyCiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBnZXQoc2VsZikgLT4gTXlBcnJheToKICAgIHByb3RvIDAgMQogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjUzCiAgICAvLyBhMSA9IHNlbGYuZ2xvYi52YWx1ZS5jb3B5KCkKICAgIGludCAwCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjQKICAgIC8vIHNlbGYuZ2xvYiA9IEdsb2JhbFN0YXRlKE15QXJyYXkpCiAgICBieXRlICJnbG9iIgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjUzCiAgICAvLyBhMSA9IHNlbGYuZ2xvYi52YWx1ZS5jb3B5KCkKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nbG9iIGV4aXN0cwogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjU0CiAgICAvLyBhMiA9IHNlbGYubG9jW1R4bi5zZW5kZXJdLmNvcHkoKQogICAgdHhuIFNlbmRlcgogICAgaW50IDAKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyNQogICAgLy8gc2VsZi5sb2MgPSBMb2NhbFN0YXRlKE15QXJyYXkpCiAgICBieXRlICJsb2MiCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NTQKICAgIC8vIGEyID0gc2VsZi5sb2NbVHhuLnNlbmRlcl0uY29weSgpCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2MgZXhpc3RzIGZvciBhY2NvdW50CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjYKICAgIC8vIHNlbGYuYm94ID0gQm94KE15QXJyYXkpCiAgICBieXRlICJib3giCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NTUKICAgIC8vIGEzID0gc2VsZi5ib3gudmFsdWUuY29weSgpCiAgICBib3hfZ2V0CiAgICBzd2FwCiAgICBjb3ZlciAyCiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ib3ggZXhpc3RzCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjcKICAgIC8vIHNlbGYubWFwID0gQm94TWFwKEFjY291bnQsIE15QXJyYXkpCiAgICBieXRlICJtYXAiCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NTYKICAgIC8vIGE0ID0gc2VsZi5tYXBbVHhuLnNlbmRlcl0uY29weSgpCiAgICB0eG4gU2VuZGVyCiAgICBjb25jYXQKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLm1hcCBlbnRyeSBleGlzdHMKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo1OAogICAgLy8gYXNzZXJ0IGExID09IGEyLCAiZXhwZWN0ZWQgbG9jYWwgPT0gZ2xvYmFsIgogICAgZGlnIDMKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBsb2NhbCA9PSBnbG9iYWwKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo1OQogICAgLy8gYXNzZXJ0IGExID09IGEzLCAiZXhwZWN0ZWQgYm94ID09IGdsb2JhbCIKICAgIGRpZyAyCiAgICB1bmNvdmVyIDIKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgYm94ID09IGdsb2JhbAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjYwCiAgICAvLyBhc3NlcnQgYTEgPT0gYTQsICJleHBlY3RlZCBtYXAgPT0gZ2xvYmFsIgogICAgZGlnIDEKICAgID09CiAgICBhc3NlcnQgLy8gZXhwZWN0ZWQgbWFwID09IGdsb2JhbAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjYxCiAgICAvLyByZXR1cm4gYTEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfbXV0YXRpb25zLmNvbnRyYWN0LkNvbnRyYWN0Lm9wdF9pbigpIC0+IHZvaWQ6Cm9wdF9pbjoKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyOS0zMAogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIC8vIGRlZiBvcHRfaW4oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI0CiAgICAvLyBzZWxmLmdsb2IgPSBHbG9iYWxTdGF0ZShNeUFycmF5KQogICAgYnl0ZSAiZ2xvYiIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTozMQogICAgLy8gc2VsZi5nbG9iLnZhbHVlID0gTXlBcnJheSgpCiAgICBieXRlIDB4MDAwMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyNgogICAgLy8gc2VsZi5ib3ggPSBCb3goTXlBcnJheSkKICAgIGJ5dGUgImJveCIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTozMgogICAgLy8gc2VsZi5ib3gudmFsdWUgPSBNeUFycmF5KCkKICAgIGJveF9kZWwKICAgIHBvcAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI2CiAgICAvLyBzZWxmLmJveCA9IEJveChNeUFycmF5KQogICAgYnl0ZSAiYm94IgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjMyCiAgICAvLyBzZWxmLmJveC52YWx1ZSA9IE15QXJyYXkoKQogICAgYnl0ZSAweDAwMDAKICAgIGJveF9wdXQKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTozMwogICAgLy8gc2VsZi5sb2NbVHhuLnNlbmRlcl0gPSBNeUFycmF5KCkKICAgIHR4biBTZW5kZXIKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyNQogICAgLy8gc2VsZi5sb2MgPSBMb2NhbFN0YXRlKE15QXJyYXkpCiAgICBieXRlICJsb2MiCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MzMKICAgIC8vIHNlbGYubG9jW1R4bi5zZW5kZXJdID0gTXlBcnJheSgpCiAgICBieXRlIDB4MDAwMAogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBzZWxmLm1hcCA9IEJveE1hcChBY2NvdW50LCBNeUFycmF5KQogICAgYnl0ZSAibWFwIgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjM0CiAgICAvLyBzZWxmLm1hcFtUeG4uc2VuZGVyXSA9IE15QXJyYXkoKQogICAgdHhuIFNlbmRlcgogICAgY29uY2F0CiAgICBkdXAKICAgIGJveF9kZWwKICAgIHBvcAogICAgYnl0ZSAweDAwMDAKICAgIGJveF9wdXQKICAgIHJldHN1YgoKCi8vIF9wdXlhX2xpYi5hcmM0LmR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudChhcnJheV9pdGVtc19jb3VudDogdWludDY0LCBhcnJheV9oZWFkX2FuZF90YWlsOiBieXRlcywgbmV3X2l0ZW1zX2NvdW50OiB1aW50NjQsIG5ld19oZWFkX2FuZF90YWlsOiBieXRlcykgLT4gYnl0ZXM6CmR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudDoKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjE4OS0xOTYKICAgIHByb3RvIDQgMQogICAgYnl0ZSAiIgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MTk3CiAgICBieXRlIDB4CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToxOTgKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDIKICAgICoKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjE5OQogICAgZnJhbWVfZGlnIC00CiAgICBpbnQgMgogICAgKgogICAgaW50IDAKCmR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudF9mb3JfaGVhZGVyQDE6CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToxOTkKICAgIGZyYW1lX2RpZyA0CiAgICBmcmFtZV9kaWcgMwogICAgPAogICAgYnogZHluYW1pY19hcnJheV9jb25jYXRfZHluYW1pY19lbGVtZW50X2FmdGVyX2ZvckA0CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDAKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIDQKICAgIGR1cAogICAgY292ZXIgMgogICAgZXh0cmFjdF91aW50MTYKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwMQogICAgZnJhbWVfZGlnIDIKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgMQogICAgc3dhcAogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IDEKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjE5OQogICAgaW50IDIKICAgICsKICAgIGZyYW1lX2J1cnkgNAogICAgYiBkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnRfZm9yX2hlYWRlckAxCgpkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnRfYWZ0ZXJfZm9yQDQ6CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDMKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwNAogICAgaW50IDAKICAgIGZyYW1lX2J1cnkgNAoKZHluYW1pY19hcnJheV9jb25jYXRfZHluYW1pY19lbGVtZW50X2Zvcl9oZWFkZXJANToKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwNAogICAgZnJhbWVfZGlnIDQKICAgIGZyYW1lX2RpZyAyCiAgICA8CiAgICBieiBkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnRfYWZ0ZXJfZm9yQDgKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwNQogICAgZnJhbWVfZGlnIC0xCiAgICBmcmFtZV9kaWcgNAogICAgZHVwCiAgICBjb3ZlciAyCiAgICBleHRyYWN0X3VpbnQxNgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjA2CiAgICBmcmFtZV9kaWcgMAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGZyYW1lX2RpZyAxCiAgICBzd2FwCiAgICBjb25jYXQKICAgIGZyYW1lX2J1cnkgMQogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjA0CiAgICBpbnQgMgogICAgKwogICAgZnJhbWVfYnVyeSA0CiAgICBiIGR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudF9mb3JfaGVhZGVyQDUKCmR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudF9hZnRlcl9mb3JAODoKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwOAogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTIKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDgtMjA5CiAgICBmcmFtZV9kaWcgMQogICAgY29uY2F0CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMTAtMjEyCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyAzCiAgICBmcmFtZV9kaWcgMAogICAgc3Vic3RyaW5nMwogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjA4LTIxMgogICAgY29uY2F0CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMTMKICAgIGZyYW1lX2RpZyAtMQogICAgbGVuCiAgICBmcmFtZV9kaWcgLTEKICAgIGZyYW1lX2RpZyAyCiAgICB1bmNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwOC0yMTMKICAgIGNvbmNhdAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjA3LTIxNAogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIKCgovLyBfcHV5YV9saWIuYXJjNC5keW5hbWljX2FycmF5X3JlcGxhY2VfZHluYW1pY19lbGVtZW50KHNvdXJjZTogYnl0ZXMsIG5ld19pdGVtOiBieXRlcywgaW5kZXg6IHVpbnQ2NCkgLT4gYnl0ZXM6CmR5bmFtaWNfYXJyYXlfcmVwbGFjZV9keW5hbWljX2VsZW1lbnQ6CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNDAtMjQxCiAgICBwcm90byAzIDEKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI0MgogICAgZnJhbWVfZGlnIC0zCiAgICBzdWJzdHJpbmcgMCAyCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNDMKICAgIGR1cAogICAgYnRvaQogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjQ1CiAgICBmcmFtZV9kaWcgLTMKICAgIGV4dHJhY3QgMiAwCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNDQtMjQ5CiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgdW5jb3ZlciAzCiAgICBjYWxsc3ViIHN0YXRpY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudAogICAgY29uY2F0CiAgICByZXRzdWIKCgovLyBfcHV5YV9saWIuYXJjNC5zdGF0aWNfYXJyYXlfcmVwbGFjZV9keW5hbWljX2VsZW1lbnQoYXJyYXlfaGVhZF9hbmRfdGFpbDogYnl0ZXMsIG5ld19pdGVtOiBieXRlcywgaW5kZXg6IHVpbnQ2NCwgYXJyYXlfbGVuZ3RoOiB1aW50NjQpIC0+IGJ5dGVzOgpzdGF0aWNfYXJyYXlfcmVwbGFjZV9keW5hbWljX2VsZW1lbnQ6CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNTItMjU1CiAgICBwcm90byA0IDEKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI1NgogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMgogICAgKgogICAgZnJhbWVfZGlnIC00CiAgICBzd2FwCiAgICBleHRyYWN0X3VpbnQxNgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjU3CiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAxCiAgICArCiAgICBpbnQgMgogICAgKgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBmcmFtZV9kaWcgLTQKICAgIHN3YXAKICAgIGV4dHJhY3RfdWludDE2CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNTgKICAgIGZyYW1lX2RpZyAtNAogICAgbGVuCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNTkKICAgIGZyYW1lX2RpZyAtMQogICAgZnJhbWVfZGlnIC0yCiAgICAtCiAgICBpbnQgMQogICAgLQogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjYwCiAgICBkaWcgMQogICAgdW5jb3ZlciAzCiAgICB1bmNvdmVyIDIKICAgIHNlbGVjdAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjYyCiAgICBkdXAKICAgIGRpZyAzCiAgICAtCiAgICBjb3ZlciAzCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNjMKICAgIGZyYW1lX2RpZyAtMwogICAgbGVuCiAgICBjb3ZlciAzCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNjUKICAgIGZyYW1lX2RpZyAtNAogICAgaW50IDAKICAgIHVuY292ZXIgNAogICAgc3Vic3RyaW5nMwogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjY1LTI2NgogICAgZnJhbWVfZGlnIC0zCiAgICBjb25jYXQKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI2NwogICAgZnJhbWVfZGlnIC00CiAgICB1bmNvdmVyIDIKICAgIHVuY292ZXIgMwogICAgc3Vic3RyaW5nMwogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjY1LTI2NwogICAgY29uY2F0CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNjkKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDIKICAgICoKCnN0YXRpY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudF9mb3JfaGVhZGVyQDE6CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNjkKICAgIGZyYW1lX2RpZyAwCiAgICBmcmFtZV9kaWcgNAogICAgPAogICAgYnogc3RhdGljX2FycmF5X3JlcGxhY2VfZHluYW1pY19lbGVtZW50X2FmdGVyX2ZvckA0CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNzAKICAgIGZyYW1lX2RpZyAzCiAgICBkdXAKICAgIGZyYW1lX2RpZyAwCiAgICBkdXAKICAgIGNvdmVyIDMKICAgIGV4dHJhY3RfdWludDE2CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNzEKICAgIGZyYW1lX2RpZyAyCiAgICArCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNzIKICAgIGZyYW1lX2RpZyAxCiAgICAtCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNzMKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNzQKICAgIGRpZyAyCiAgICBzd2FwCiAgICByZXBsYWNlMwogICAgZnJhbWVfYnVyeSAzCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNjkKICAgIGludCAyCiAgICArCiAgICBmcmFtZV9idXJ5IDAKICAgIGIgc3RhdGljX2FycmF5X3JlcGxhY2VfZHluYW1pY19lbGVtZW50X2Zvcl9oZWFkZXJAMQoKc3RhdGljX2FycmF5X3JlcGxhY2VfZHluYW1pY19lbGVtZW50X2FmdGVyX2ZvckA0OgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6Mjc1CiAgICBmcmFtZV9kaWcgMwogICAgZnJhbWVfYnVyeSAwCiAgICByZXRzdWIK", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX211dGF0aW9ucy5jb250cmFjdC5Db250cmFjdC5hcHByb3ZhbF9wcm9ncmFtOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy5zdGF0ZV9tdXRhdGlvbnMuY29udHJhY3QuQ29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjIyCiAgICAvLyBjbGFzcyBDb250cmFjdChBUkM0Q29udHJhY3QpOgogICAgcHJvdG8gMCAxCiAgICB0eG4gTnVtQXBwQXJncwogICAgYnogX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDcKICAgIG1ldGhvZCAiYXBwZW5kKCl2b2lkIgogICAgbWV0aG9kICJtb2RpZnkoKXZvaWQiCiAgICBtZXRob2QgImdldCgpKHVpbnQ2NCxzdHJpbmcpW10iCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hcHBlbmRfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19tb2RpZnlfcm91dGVAMyBfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfcm91dGVANAogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYXBwZW5kX3JvdXRlQDI6CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MzYKICAgIC8vIEBhcmM0LmFiaW1ldGhvZAogICAgdHhuIE9uQ29tcGxldGlvbgogICAgIQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBOb09wCiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYXNzZXJ0IC8vIGlzIG5vdCBjcmVhdGluZwogICAgY2FsbHN1YiBhcHBlbmQKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX21vZGlmeV9yb3V0ZUAzOgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ0CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIGNhbGxzdWIgbW9kaWZ5CiAgICBpbnQgMQogICAgcmV0c3ViCgpfX3B1eWFfYXJjNF9yb3V0ZXJfX19nZXRfcm91dGVANDoKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo1MQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIGdldAogICAgYnl0ZSAweDE1MWY3Yzc1CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGxvZwogICAgaW50IDEKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fYmFyZV9yb3V0aW5nQDc6CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MjIKICAgIC8vIGNsYXNzIENvbnRyYWN0KEFSQzRDb250cmFjdCk6CiAgICB0eG4gT25Db21wbGV0aW9uCiAgICBzd2l0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvcHlfZGVmYXVsdF9jcmVhdGVAOCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19vcHRfaW5AOQogICAgaW50IDAKICAgIHJldHN1YgoKX19wdXlhX2FyYzRfcm91dGVyX19fX19hbGdvcHlfZGVmYXVsdF9jcmVhdGVAODoKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyMgogICAgLy8gY2xhc3MgQ29udHJhY3QoQVJDNENvbnRyYWN0KToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX29wdF9pbkA5OgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI5CiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weToyOS0zMAogICAgLy8gQGFyYzQuYmFyZW1ldGhvZChhbGxvd19hY3Rpb25zPVsiT3B0SW4iXSkKICAgIC8vIGRlZiBvcHRfaW4oc2VsZikgLT4gTm9uZToKICAgIGNhbGxzdWIgb3B0X2luCiAgICBpbnQgMQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5zdGF0ZV9tdXRhdGlvbnMuY29udHJhY3QuQ29udHJhY3QuYXBwZW5kKCkgLT4gdm9pZDoKYXBwZW5kOgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjM2LTM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QKICAgIC8vIGRlZiBhcHBlbmQoc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjM4CiAgICAvLyBzdHJ1Y3QgPSBnZXRfc3RydWN0KCkKICAgIGNhbGxzdWIgZ2V0X3N0cnVjdAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjM5CiAgICAvLyBzZWxmLmdsb2IudmFsdWUuYXBwZW5kKHN0cnVjdC5jb3B5KCkpCiAgICBpbnQgMAogICAgYnl0ZSAiZ2xvYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nbG9iIGV4aXN0cwogICAgYnl0ZSAweDAwMDIKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgZXh0cmFjdCAyIDAKICAgIGludCAxCiAgICBkaWcgMwogICAgY2FsbHN1YiBkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnQKICAgIGJ5dGUgImdsb2IiCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQwCiAgICAvLyBzZWxmLmxvY1tUeG4uc2VuZGVyXS5hcHBlbmQoc3RydWN0LmNvcHkoKSkKICAgIHR4biBTZW5kZXIKICAgIGludCAwCiAgICBieXRlICJsb2MiCiAgICBhcHBfbG9jYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5sb2MgZXhpc3RzIGZvciBhY2NvdW50CiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgZXh0cmFjdCAyIDAKICAgIGludCAxCiAgICBkaWcgMwogICAgY2FsbHN1YiBkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnQKICAgIHR4biBTZW5kZXIKICAgIGJ5dGUgImxvYyIKICAgIHVuY292ZXIgMgogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQxCiAgICAvLyBzZWxmLmJveC52YWx1ZS5hcHBlbmQoc3RydWN0LmNvcHkoKSkKICAgIGJ5dGUgImJveCIKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveCBleGlzdHMKICAgIGR1cAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBleHRyYWN0IDIgMAogICAgaW50IDEKICAgIGRpZyAzCiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudAogICAgYnl0ZSAiYm94IgogICAgYm94X2RlbAogICAgcG9wCiAgICBieXRlICJib3giCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDIKICAgIC8vIHNlbGYubWFwW1R4bi5zZW5kZXJdLmFwcGVuZChzdHJ1Y3QuY29weSgpKQogICAgYnl0ZSAibWFwIgogICAgdHhuIFNlbmRlcgogICAgY29uY2F0CiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5tYXAgZW50cnkgZXhpc3RzCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgZXh0cmFjdCAyIDAKICAgIGludCAxCiAgICB1bmNvdmVyIDMKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9jb25jYXRfZHluYW1pY19lbGVtZW50CiAgICBieXRlICJtYXAiCiAgICB0eG4gU2VuZGVyCiAgICBjb25jYXQKICAgIGR1cAogICAgYm94X2RlbAogICAgcG9wCiAgICBzd2FwCiAgICBib3hfcHV0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnN0YXRlX211dGF0aW9ucy5jb250cmFjdC5nZXRfc3RydWN0KCkgLT4gYnl0ZXM6CmdldF9zdHJ1Y3Q6CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NjQtNjUKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgZ2V0X3N0cnVjdCgpIC0+IE15U3RydWN0OgogICAgcHJvdG8gMCAxCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NjYtNjkKICAgIC8vIHJldHVybiBNeVN0cnVjdCgKICAgIC8vICAgICBiYXI9YXJjNC5VSW50NjQoMSksCiAgICAvLyAgICAgYmF6PWFyYzQuU3RyaW5nKCJiYXoiKSwKICAgIC8vICkKICAgIGJ5dGUgMHgwMDAwMDAwMDAwMDAwMDAxMDAwYTAwMDM2MjYxN2EKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfbXV0YXRpb25zLmNvbnRyYWN0LkNvbnRyYWN0Lm1vZGlmeSgpIC0+IHZvaWQ6Cm1vZGlmeToKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo0NC00NQogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgbW9kaWZ5KHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo0NgogICAgLy8gc2VsZi5nbG9iLnZhbHVlWzBdLmJheiA9IGFyYzQuU3RyaW5nKCJtb2RpZmllZCIpCiAgICBpbnQgMAogICAgYnl0ZSAiZ2xvYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nbG9iIGV4aXN0cwogICAgZHVwCiAgICBleHRyYWN0IDIgMAogICAgZHVwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGNvdmVyIDIKICAgIHN3YXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDEKICAgIC0gLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkaWcgMQogICAgbGVuCiAgICBzd2FwCiAgICBkaWcgMgogICAgaW50IDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBzZWxlY3QKICAgIHN3YXAKICAgIGNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGR1cAogICAgaW50IDgKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMAogICAgc3dhcAogICAgZXh0cmFjdDMKICAgIGJ5dGUgMHgwMDA4NmQ2ZjY0Njk2NjY5NjU2NAogICAgY29uY2F0CiAgICBpbnQgMAogICAgYnl0ZSAiZ2xvYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nbG9iIGV4aXN0cwogICAgc3dhcAogICAgaW50IDAKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudAogICAgYnl0ZSAiZ2xvYiIKICAgIHN3YXAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDcKICAgIC8vIHNlbGYubG9jW1R4bi5zZW5kZXJdWzBdLmJheiA9IGFyYzQuU3RyaW5nKCJtb2RpZmllZCIpCiAgICB0eG4gU2VuZGVyCiAgICBpbnQgMAogICAgYnl0ZSAibG9jIgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jIGV4aXN0cyBmb3IgYWNjb3VudAogICAgZHVwCiAgICBleHRyYWN0IDIgMAogICAgZHVwCiAgICBpbnQgMAogICAgZXh0cmFjdF91aW50MTYKICAgIGNvdmVyIDIKICAgIHN3YXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgaW50IDEKICAgIC0gLy8gb24gZXJyb3I6IEluZGV4IGFjY2VzcyBpcyBvdXQgb2YgYm91bmRzCiAgICBkaWcgMQogICAgbGVuCiAgICBzd2FwCiAgICBkaWcgMgogICAgaW50IDIKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBzZWxlY3QKICAgIHN3YXAKICAgIGNvdmVyIDIKICAgIHN1YnN0cmluZzMKICAgIGR1cAogICAgaW50IDgKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMAogICAgc3dhcAogICAgZXh0cmFjdDMKICAgIGJ5dGUgMHgwMDA4NmQ2ZjY0Njk2NjY5NjU2NAogICAgY29uY2F0CiAgICB0eG4gU2VuZGVyCiAgICBpbnQgMAogICAgYnl0ZSAibG9jIgogICAgYXBwX2xvY2FsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubG9jIGV4aXN0cyBmb3IgYWNjb3VudAogICAgc3dhcAogICAgaW50IDAKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudAogICAgdHhuIFNlbmRlcgogICAgYnl0ZSAibG9jIgogICAgdW5jb3ZlciAyCiAgICBhcHBfbG9jYWxfcHV0CiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NDgKICAgIC8vIHNlbGYuYm94LnZhbHVlWzBdLmJheiA9IGFyYzQuU3RyaW5nKCJtb2RpZmllZCIpCiAgICBieXRlICJib3giCiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5ib3ggZXhpc3RzCiAgICBkdXAKICAgIGV4dHJhY3QgMiAwCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgY292ZXIgMgogICAgc3dhcAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMQogICAgLSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGRpZyAxCiAgICBsZW4KICAgIHN3YXAKICAgIGRpZyAyCiAgICBpbnQgMgogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIHNlbGVjdAogICAgc3dhcAogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBpbnQgOAogICAgZXh0cmFjdF91aW50MTYKICAgIGludCAwCiAgICBzd2FwCiAgICBleHRyYWN0MwogICAgYnl0ZSAweDAwMDg2ZDZmNjQ2OTY2Njk2NTY0CiAgICBjb25jYXQKICAgIGJ5dGUgImJveCIKICAgIGJveF9nZXQKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveCBleGlzdHMKICAgIHN3YXAKICAgIGludCAwCiAgICBjYWxsc3ViIGR5bmFtaWNfYXJyYXlfcmVwbGFjZV9keW5hbWljX2VsZW1lbnQKICAgIGJ5dGUgImJveCIKICAgIGJveF9kZWwKICAgIHBvcAogICAgYnl0ZSAiYm94IgogICAgc3dhcAogICAgYm94X3B1dAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjQ5CiAgICAvLyBzZWxmLm1hcFtUeG4uc2VuZGVyXVswXS5iYXogPSBhcmM0LlN0cmluZygibW9kaWZpZWQiKQogICAgYnl0ZSAibWFwIgogICAgdHhuIFNlbmRlcgogICAgY29uY2F0CiAgICBib3hfZ2V0CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5tYXAgZW50cnkgZXhpc3RzCiAgICBkdXAKICAgIGV4dHJhY3QgMiAwCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgY292ZXIgMgogICAgc3dhcAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBpbnQgMQogICAgLSAvLyBvbiBlcnJvcjogSW5kZXggYWNjZXNzIGlzIG91dCBvZiBib3VuZHMKICAgIGRpZyAxCiAgICBsZW4KICAgIHN3YXAKICAgIGRpZyAyCiAgICBpbnQgMgogICAgZXh0cmFjdF91aW50MTYKICAgIHN3YXAKICAgIHNlbGVjdAogICAgc3dhcAogICAgY292ZXIgMgogICAgc3Vic3RyaW5nMwogICAgZHVwCiAgICBpbnQgOAogICAgZXh0cmFjdF91aW50MTYKICAgIGludCAwCiAgICBzd2FwCiAgICBleHRyYWN0MwogICAgYnl0ZSAweDAwMDg2ZDZmNjQ2OTY2Njk2NTY0CiAgICBjb25jYXQKICAgIGJ5dGUgIm1hcCIKICAgIHR4biBTZW5kZXIKICAgIGNvbmNhdAogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubWFwIGVudHJ5IGV4aXN0cwogICAgc3dhcAogICAgaW50IDAKICAgIGNhbGxzdWIgZHluYW1pY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudAogICAgYnl0ZSAibWFwIgogICAgdHhuIFNlbmRlcgogICAgY29uY2F0CiAgICBkdXAKICAgIGJveF9kZWwKICAgIHBvcAogICAgc3dhcAogICAgYm94X3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5zdGF0ZV9tdXRhdGlvbnMuY29udHJhY3QuQ29udHJhY3QuZ2V0KCkgLT4gYnl0ZXM6CmdldDoKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo1MS01MgogICAgLy8gQGFyYzQuYWJpbWV0aG9kCiAgICAvLyBkZWYgZ2V0KHNlbGYpIC0+IE15QXJyYXk6CiAgICBwcm90byAwIDEKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo1MwogICAgLy8gYTEgPSBzZWxmLmdsb2IudmFsdWUuY29weSgpCiAgICBpbnQgMAogICAgYnl0ZSAiZ2xvYiIKICAgIGFwcF9nbG9iYWxfZ2V0X2V4CiAgICBhc3NlcnQgLy8gY2hlY2sgc2VsZi5nbG9iIGV4aXN0cwogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjU0CiAgICAvLyBhMiA9IHNlbGYubG9jW1R4bi5zZW5kZXJdLmNvcHkoKQogICAgdHhuIFNlbmRlcgogICAgaW50IDAKICAgIGJ5dGUgImxvYyIKICAgIGFwcF9sb2NhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmxvYyBleGlzdHMgZm9yIGFjY291bnQKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo1NQogICAgLy8gYTMgPSBzZWxmLmJveC52YWx1ZS5jb3B5KCkKICAgIGJ5dGUgImJveCIKICAgIGJveF9nZXQKICAgIHN3YXAKICAgIGNvdmVyIDIKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJveCBleGlzdHMKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTo1NgogICAgLy8gYTQgPSBzZWxmLm1hcFtUeG4uc2VuZGVyXS5jb3B5KCkKICAgIGJ5dGUgIm1hcCIKICAgIHR4biBTZW5kZXIKICAgIGNvbmNhdAogICAgYm94X2dldAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYubWFwIGVudHJ5IGV4aXN0cwogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjU4CiAgICAvLyBhc3NlcnQgYTEgPT0gYTIsICJleHBlY3RlZCBsb2NhbCA9PSBnbG9iYWwiCiAgICBkaWcgMwogICAgdW5jb3ZlciAyCiAgICA9PQogICAgYXNzZXJ0IC8vIGV4cGVjdGVkIGxvY2FsID09IGdsb2JhbAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjU5CiAgICAvLyBhc3NlcnQgYTEgPT0gYTMsICJleHBlY3RlZCBib3ggPT0gZ2xvYmFsIgogICAgZGlnIDIKICAgIHVuY292ZXIgMgogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBib3ggPT0gZ2xvYmFsCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NjAKICAgIC8vIGFzc2VydCBhMSA9PSBhNCwgImV4cGVjdGVkIG1hcCA9PSBnbG9iYWwiCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydCAvLyBleHBlY3RlZCBtYXAgPT0gZ2xvYmFsCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6NjEKICAgIC8vIHJldHVybiBhMQogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5zdGF0ZV9tdXRhdGlvbnMuY29udHJhY3QuQ29udHJhY3Qub3B0X2luKCkgLT4gdm9pZDoKb3B0X2luOgogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjI5LTMwCiAgICAvLyBAYXJjNC5iYXJlbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdKQogICAgLy8gZGVmIG9wdF9pbihzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBzdGF0ZV9tdXRhdGlvbnMvY29udHJhY3QucHk6MzEKICAgIC8vIHNlbGYuZ2xvYi52YWx1ZSA9IE15QXJyYXkoKQogICAgYnl0ZSAiZ2xvYiIKICAgIGJ5dGUgMHgwMDAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjMyCiAgICAvLyBzZWxmLmJveC52YWx1ZSA9IE15QXJyYXkoKQogICAgYnl0ZSAiYm94IgogICAgYm94X2RlbAogICAgcG9wCiAgICBieXRlICJib3giCiAgICBieXRlIDB4MDAwMAogICAgYm94X3B1dAogICAgLy8gc3RhdGVfbXV0YXRpb25zL2NvbnRyYWN0LnB5OjMzCiAgICAvLyBzZWxmLmxvY1tUeG4uc2VuZGVyXSA9IE15QXJyYXkoKQogICAgdHhuIFNlbmRlcgogICAgYnl0ZSAibG9jIgogICAgYnl0ZSAweDAwMDAKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHN0YXRlX211dGF0aW9ucy9jb250cmFjdC5weTozNAogICAgLy8gc2VsZi5tYXBbVHhuLnNlbmRlcl0gPSBNeUFycmF5KCkKICAgIGJ5dGUgIm1hcCIKICAgIHR4biBTZW5kZXIKICAgIGNvbmNhdAogICAgZHVwCiAgICBib3hfZGVsCiAgICBwb3AKICAgIGJ5dGUgMHgwMDAwCiAgICBib3hfcHV0CiAgICByZXRzdWIKCgovLyBfcHV5YV9saWIuYXJjNC5keW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnQoYXJyYXlfaXRlbXNfY291bnQ6IHVpbnQ2NCwgYXJyYXlfaGVhZF9hbmRfdGFpbDogYnl0ZXMsIG5ld19pdGVtc19jb3VudDogdWludDY0LCBuZXdfaGVhZF9hbmRfdGFpbDogYnl0ZXMpIC0+IGJ5dGVzOgpkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnQ6CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToxODktMTk2CiAgICBwcm90byA0IDEKICAgIGJ5dGUgIiIKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjE5NwogICAgYnl0ZSAweAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MTk4CiAgICBmcmFtZV9kaWcgLTIKICAgIGludCAyCiAgICAqCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToxOTkKICAgIGZyYW1lX2RpZyAtNAogICAgaW50IDIKICAgICoKICAgIGludCAwCgpkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnRfZm9yX2hlYWRlckAxOgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MTk5CiAgICBmcmFtZV9kaWcgNAogICAgZnJhbWVfZGlnIDMKICAgIDwKICAgIGJ6IGR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudF9hZnRlcl9mb3JANAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjAwCiAgICBmcmFtZV9kaWcgLTMKICAgIGZyYW1lX2RpZyA0CiAgICBkdXAKICAgIGNvdmVyIDIKICAgIGV4dHJhY3RfdWludDE2CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDEKICAgIGZyYW1lX2RpZyAyCiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgZnJhbWVfZGlnIDEKICAgIHN3YXAKICAgIGNvbmNhdAogICAgZnJhbWVfYnVyeSAxCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToxOTkKICAgIGludCAyCiAgICArCiAgICBmcmFtZV9idXJ5IDQKICAgIGIgZHluYW1pY19hcnJheV9jb25jYXRfZHluYW1pY19lbGVtZW50X2Zvcl9oZWFkZXJAMQoKZHluYW1pY19hcnJheV9jb25jYXRfZHluYW1pY19lbGVtZW50X2FmdGVyX2ZvckA0OgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjAzCiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgZnJhbWVfYnVyeSAwCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDQKICAgIGludCAwCiAgICBmcmFtZV9idXJ5IDQKCmR5bmFtaWNfYXJyYXlfY29uY2F0X2R5bmFtaWNfZWxlbWVudF9mb3JfaGVhZGVyQDU6CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDQKICAgIGZyYW1lX2RpZyA0CiAgICBmcmFtZV9kaWcgMgogICAgPAogICAgYnogZHluYW1pY19hcnJheV9jb25jYXRfZHluYW1pY19lbGVtZW50X2FmdGVyX2ZvckA4CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDUKICAgIGZyYW1lX2RpZyAtMQogICAgZnJhbWVfZGlnIDQKICAgIGR1cAogICAgY292ZXIgMgogICAgZXh0cmFjdF91aW50MTYKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwNgogICAgZnJhbWVfZGlnIDAKICAgICsKICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBmcmFtZV9kaWcgMQogICAgc3dhcAogICAgY29uY2F0CiAgICBmcmFtZV9idXJ5IDEKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwNAogICAgaW50IDIKICAgICsKICAgIGZyYW1lX2J1cnkgNAogICAgYiBkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnRfZm9yX2hlYWRlckA1CgpkeW5hbWljX2FycmF5X2NvbmNhdF9keW5hbWljX2VsZW1lbnRfYWZ0ZXJfZm9yQDg6CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDgKICAgIGZyYW1lX2RpZyAtNAogICAgZnJhbWVfZGlnIC0yCiAgICArCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjA4LTIwOQogICAgZnJhbWVfZGlnIDEKICAgIGNvbmNhdAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjEwLTIxMgogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgMwogICAgZnJhbWVfZGlnIDAKICAgIHN1YnN0cmluZzMKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwOC0yMTIKICAgIGNvbmNhdAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjEzCiAgICBmcmFtZV9kaWcgLTEKICAgIGxlbgogICAgZnJhbWVfZGlnIC0xCiAgICBmcmFtZV9kaWcgMgogICAgdW5jb3ZlciAyCiAgICBzdWJzdHJpbmczCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyMDgtMjEzCiAgICBjb25jYXQKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjIwNy0yMTQKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCgoKLy8gX3B1eWFfbGliLmFyYzQuZHluYW1pY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudChzb3VyY2U6IGJ5dGVzLCBuZXdfaXRlbTogYnl0ZXMsIGluZGV4OiB1aW50NjQpIC0+IGJ5dGVzOgpkeW5hbWljX2FycmF5X3JlcGxhY2VfZHluYW1pY19lbGVtZW50OgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjQwLTI0MQogICAgcHJvdG8gMyAxCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNDIKICAgIGZyYW1lX2RpZyAtMwogICAgc3Vic3RyaW5nIDAgMgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjQzCiAgICBkdXAKICAgIGJ0b2kKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI0NQogICAgZnJhbWVfZGlnIC0zCiAgICBleHRyYWN0IDIgMAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjQ0LTI0OQogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgIHVuY292ZXIgMwogICAgY2FsbHN1YiBzdGF0aWNfYXJyYXlfcmVwbGFjZV9keW5hbWljX2VsZW1lbnQKICAgIGNvbmNhdAogICAgcmV0c3ViCgoKLy8gX3B1eWFfbGliLmFyYzQuc3RhdGljX2FycmF5X3JlcGxhY2VfZHluYW1pY19lbGVtZW50KGFycmF5X2hlYWRfYW5kX3RhaWw6IGJ5dGVzLCBuZXdfaXRlbTogYnl0ZXMsIGluZGV4OiB1aW50NjQsIGFycmF5X2xlbmd0aDogdWludDY0KSAtPiBieXRlczoKc3RhdGljX2FycmF5X3JlcGxhY2VfZHluYW1pY19lbGVtZW50OgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjUyLTI1NQogICAgcHJvdG8gNCAxCiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNTYKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDIKICAgICoKICAgIGZyYW1lX2RpZyAtNAogICAgc3dhcAogICAgZXh0cmFjdF91aW50MTYKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI1NwogICAgZnJhbWVfZGlnIC0yCiAgICBpbnQgMQogICAgKwogICAgaW50IDIKICAgICoKICAgIGR1cAogICAgY292ZXIgMgogICAgZnJhbWVfZGlnIC00CiAgICBzd2FwCiAgICBleHRyYWN0X3VpbnQxNgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjU4CiAgICBmcmFtZV9kaWcgLTQKICAgIGxlbgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjU5CiAgICBmcmFtZV9kaWcgLTEKICAgIGZyYW1lX2RpZyAtMgogICAgLQogICAgaW50IDEKICAgIC0KICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI2MAogICAgZGlnIDEKICAgIHVuY292ZXIgMwogICAgdW5jb3ZlciAyCiAgICBzZWxlY3QKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI2MgogICAgZHVwCiAgICBkaWcgMwogICAgLQogICAgY292ZXIgMwogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjYzCiAgICBmcmFtZV9kaWcgLTMKICAgIGxlbgogICAgY292ZXIgMwogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjY1CiAgICBmcmFtZV9kaWcgLTQKICAgIGludCAwCiAgICB1bmNvdmVyIDQKICAgIHN1YnN0cmluZzMKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI2NS0yNjYKICAgIGZyYW1lX2RpZyAtMwogICAgY29uY2F0CiAgICAvLyBfcHV5YV9saWIvYXJjNC5weToyNjcKICAgIGZyYW1lX2RpZyAtNAogICAgdW5jb3ZlciAyCiAgICB1bmNvdmVyIDMKICAgIHN1YnN0cmluZzMKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI2NS0yNjcKICAgIGNvbmNhdAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjY5CiAgICBmcmFtZV9kaWcgLTEKICAgIGludCAyCiAgICAqCgpzdGF0aWNfYXJyYXlfcmVwbGFjZV9keW5hbWljX2VsZW1lbnRfZm9yX2hlYWRlckAxOgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjY5CiAgICBmcmFtZV9kaWcgMAogICAgZnJhbWVfZGlnIDQKICAgIDwKICAgIGJ6IHN0YXRpY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudF9hZnRlcl9mb3JANAogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjcwCiAgICBmcmFtZV9kaWcgMwogICAgZHVwCiAgICBmcmFtZV9kaWcgMAogICAgZHVwCiAgICBjb3ZlciAzCiAgICBleHRyYWN0X3VpbnQxNgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjcxCiAgICBmcmFtZV9kaWcgMgogICAgKwogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjcyCiAgICBmcmFtZV9kaWcgMQogICAgLQogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjczCiAgICBpdG9iCiAgICBleHRyYWN0IDYgMgogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6Mjc0CiAgICBkaWcgMgogICAgc3dhcAogICAgcmVwbGFjZTMKICAgIGZyYW1lX2J1cnkgMwogICAgLy8gX3B1eWFfbGliL2FyYzQucHk6MjY5CiAgICBpbnQgMgogICAgKwogICAgZnJhbWVfYnVyeSAwCiAgICBiIHN0YXRpY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudF9mb3JfaGVhZGVyQDEKCnN0YXRpY19hcnJheV9yZXBsYWNlX2R5bmFtaWNfZWxlbWVudF9hZnRlcl9mb3JANDoKICAgIC8vIF9wdXlhX2xpYi9hcmM0LnB5OjI3NQogICAgZnJhbWVfZGlnIDMKICAgIGZyYW1lX2J1cnkgMAogICAgcmV0c3ViCg==", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX211dGF0aW9ucy5jb250cmFjdC5Db250cmFjdC5jbGVhcl9zdGF0ZV9wcm9ncmFtOgogICAgaW50IDEKICAgIHJldHVybgo=" }, "state": { diff --git a/test_cases/state_mutations/out_unoptimized/Contract.approval.teal b/test_cases/state_mutations/out_unoptimized/Contract.approval.teal index 2b1e09eaf6..b090ac5c62 100644 --- a/test_cases/state_mutations/out_unoptimized/Contract.approval.teal +++ b/test_cases/state_mutations/out_unoptimized/Contract.approval.teal @@ -135,11 +135,7 @@ append: // state_mutations/contract.py:39 // self.glob.value.append(struct.copy()) int 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:39 - // self.glob.value.append(struct.copy()) app_global_get_ex cover 1 cover 2 @@ -164,22 +160,14 @@ append: int 1 uncover 3 callsub dynamic_array_concat_dynamic_element - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:39 - // self.glob.value.append(struct.copy()) uncover 1 app_global_put // state_mutations/contract.py:40 // self.loc[Txn.sender].append(struct.copy()) txn Sender int 0 - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:40 - // self.loc[Txn.sender].append(struct.copy()) app_local_get_ex assert // check self.loc exists for account dig 1 @@ -203,18 +191,12 @@ append: uncover 3 callsub dynamic_array_concat_dynamic_element txn Sender - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:40 - // self.loc[Txn.sender].append(struct.copy()) uncover 2 app_local_put - // state_mutations/contract.py:26 - // self.box = Box(MyArray) - byte "box" // state_mutations/contract.py:41 // self.box.value.append(struct.copy()) + byte "box" box_get assert // check self.box exists dig 1 @@ -237,28 +219,16 @@ append: int 1 uncover 3 callsub dynamic_array_concat_dynamic_element - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:41 - // self.box.value.append(struct.copy()) box_del pop - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:41 - // self.box.value.append(struct.copy()) uncover 1 box_put // state_mutations/contract.py:42 // self.map[Txn.sender].append(struct.copy()) txn Sender - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:42 - // self.map[Txn.sender].append(struct.copy()) uncover 1 concat box_get @@ -284,11 +254,7 @@ append: uncover 3 callsub dynamic_array_concat_dynamic_element txn Sender - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:42 - // self.map[Txn.sender].append(struct.copy()) uncover 1 concat dup @@ -352,11 +318,7 @@ modify: byte "modified" concat int 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:46 - // self.glob.value[0].baz = arc4.String("modified") app_global_get_ex assert // check self.glob exists dup @@ -404,21 +366,13 @@ modify: uncover 1 concat int 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:46 - // self.glob.value[0].baz = arc4.String("modified") app_global_get_ex assert // check self.glob exists uncover 1 int 0 callsub dynamic_array_replace_dynamic_element - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:46 - // self.glob.value[0].baz = arc4.String("modified") uncover 1 app_global_put // state_mutations/contract.py:47 @@ -431,11 +385,7 @@ modify: concat txn Sender int 0 - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:47 - // self.loc[Txn.sender][0].baz = arc4.String("modified") app_local_get_ex assert // check self.loc exists for account dup @@ -484,22 +434,14 @@ modify: concat txn Sender int 0 - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:47 - // self.loc[Txn.sender][0].baz = arc4.String("modified") app_local_get_ex assert // check self.loc exists for account uncover 1 int 0 callsub dynamic_array_replace_dynamic_element txn Sender - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:47 - // self.loc[Txn.sender][0].baz = arc4.String("modified") uncover 2 app_local_put // state_mutations/contract.py:48 @@ -510,11 +452,7 @@ modify: extract 6 2 byte "modified" concat - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:48 - // self.box.value[0].baz = arc4.String("modified") box_get assert // check self.box exists dup @@ -561,28 +499,16 @@ modify: extract3 uncover 1 concat - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:48 - // self.box.value[0].baz = arc4.String("modified") box_get assert // check self.box exists uncover 1 int 0 callsub dynamic_array_replace_dynamic_element - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:48 - // self.box.value[0].baz = arc4.String("modified") box_del pop - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:48 - // self.box.value[0].baz = arc4.String("modified") uncover 1 box_put // state_mutations/contract.py:49 @@ -594,11 +520,7 @@ modify: byte "modified" concat txn Sender - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:49 - // self.map[Txn.sender][0].baz = arc4.String("modified") uncover 1 concat box_get @@ -648,11 +570,7 @@ modify: uncover 1 concat txn Sender - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:49 - // self.map[Txn.sender][0].baz = arc4.String("modified") uncover 1 concat box_get @@ -661,11 +579,7 @@ modify: int 0 callsub dynamic_array_replace_dynamic_element txn Sender - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:49 - // self.map[Txn.sender][0].baz = arc4.String("modified") uncover 1 concat dup @@ -685,39 +599,25 @@ get: // state_mutations/contract.py:53 // a1 = self.glob.value.copy() int 0 - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:53 - // a1 = self.glob.value.copy() app_global_get_ex assert // check self.glob exists // state_mutations/contract.py:54 // a2 = self.loc[Txn.sender].copy() txn Sender int 0 - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:54 - // a2 = self.loc[Txn.sender].copy() app_local_get_ex assert // check self.loc exists for account - // state_mutations/contract.py:26 - // self.box = Box(MyArray) - byte "box" // state_mutations/contract.py:55 // a3 = self.box.value.copy() + byte "box" box_get assert // check self.box exists // state_mutations/contract.py:56 // a4 = self.map[Txn.sender].copy() txn Sender - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:56 - // a4 = self.map[Txn.sender].copy() uncover 1 concat box_get @@ -764,11 +664,7 @@ opt_in: byte 0x0000 byte 0x concat - // state_mutations/contract.py:24 - // self.glob = GlobalState(MyArray) byte "glob" - // state_mutations/contract.py:31 - // self.glob.value = MyArray() uncover 1 app_global_put // state_mutations/contract.py:32 @@ -776,18 +672,10 @@ opt_in: byte 0x0000 byte 0x concat - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:32 - // self.box.value = MyArray() box_del pop - // state_mutations/contract.py:26 - // self.box = Box(MyArray) byte "box" - // state_mutations/contract.py:32 - // self.box.value = MyArray() uncover 1 box_put // state_mutations/contract.py:33 @@ -796,11 +684,7 @@ opt_in: byte 0x concat txn Sender - // state_mutations/contract.py:25 - // self.loc = LocalState(MyArray) byte "loc" - // state_mutations/contract.py:33 - // self.loc[Txn.sender] = MyArray() uncover 2 app_local_put // state_mutations/contract.py:34 @@ -809,11 +693,7 @@ opt_in: byte 0x concat txn Sender - // state_mutations/contract.py:27 - // self.map = BoxMap(Account, MyArray) byte "map" - // state_mutations/contract.py:34 - // self.map[Txn.sender] = MyArray() uncover 1 concat dup diff --git a/test_cases/state_proxies/out/StateProxyContract.approval.mir b/test_cases/state_proxies/out/StateProxyContract.approval.mir index 31ba9090be..16bbfa1315 100644 --- a/test_cases/state_proxies/out/StateProxyContract.approval.mir +++ b/test_cases/state_proxies/out/StateProxyContract.approval.mir @@ -71,19 +71,19 @@ create: proto 0 0 // @arc4.abimethod(allow_actions=["OptIn"], create="require")\ndef create(self) -> None: state_proxies/contract.py:25-26 create_block@0: - byte "g1" // "g1" "g1" state_proxies/contract.py:16 + byte "g1" // "g1" self.global1 state_proxies/contract.py:27 int 1 // "g1",1 UInt64(1) state_proxies/contract.py:27 app_global_put // self.global1.value = UInt64(1) state_proxies/contract.py:27 txn Sender // {txn} Txn.sender state_proxies/contract.py:28 // virtual: store tmp%0#0 to l-stack (no copy) tmp%0#0 Txn.sender state_proxies/contract.py:28 // virtual: load tmp%0#0 from l-stack (no copy) tmp%0#0 self.local1[Txn.sender] = UInt64(2) state_proxies/contract.py:28 - byte "l1" // tmp%0#0,"l1" "l1" state_proxies/contract.py:14 + byte "l1" // tmp%0#0,"l1" self.local1 state_proxies/contract.py:28 int 2 // tmp%0#0,"l1",2 UInt64(2) state_proxies/contract.py:28 app_local_put // self.local1[Txn.sender] = UInt64(2) state_proxies/contract.py:28 txn Sender // {txn} Txn.sender state_proxies/contract.py:29 // virtual: store tmp%1#0 to l-stack (no copy) tmp%1#0 Txn.sender state_proxies/contract.py:29 // virtual: load tmp%1#0 from l-stack (no copy) tmp%1#0 self.local2[Txn.sender] = UInt64(3) state_proxies/contract.py:29 - byte 0x6c32 // tmp%1#0,0x6c32 b"l2" state_proxies/contract.py:15 + byte 0x6c32 // tmp%1#0,0x6c32 self.local2 state_proxies/contract.py:29 int 3 // tmp%1#0,0x6c32,3 UInt64(3) state_proxies/contract.py:29 app_local_put // self.local2[Txn.sender] = UInt64(3) state_proxies/contract.py:29 retsub // diff --git a/test_cases/state_proxies/out/StateProxyContract.approval.teal b/test_cases/state_proxies/out/StateProxyContract.approval.teal index 343a4d1c85..f9f8ada126 100644 --- a/test_cases/state_proxies/out/StateProxyContract.approval.teal +++ b/test_cases/state_proxies/out/StateProxyContract.approval.teal @@ -50,31 +50,21 @@ create: // @arc4.abimethod(allow_actions=["OptIn"], create="require") // def create(self) -> None: proto 0 0 - // state_proxies/contract.py:16 - // self.global1 = GlobalState(UInt64, key="g1", description="g1 description") - byte "g1" // state_proxies/contract.py:27 // self.global1.value = UInt64(1) + byte "g1" int 1 app_global_put // state_proxies/contract.py:28 // self.local1[Txn.sender] = UInt64(2) txn Sender - // state_proxies/contract.py:14 - // self.local1 = LocalState(UInt64, key="l1", description="l1 description") byte "l1" - // state_proxies/contract.py:28 - // self.local1[Txn.sender] = UInt64(2) int 2 app_local_put // state_proxies/contract.py:29 // self.local2[Txn.sender] = UInt64(3) txn Sender - // state_proxies/contract.py:15 - // self.local2 = LocalState[UInt64](UInt64, key=b"l2", description="l2 description") byte 0x6c32 - // state_proxies/contract.py:29 - // self.local2[Txn.sender] = UInt64(3) int 3 app_local_put retsub diff --git a/test_cases/state_proxies/out/StateProxyContract.arc32.json b/test_cases/state_proxies/out/StateProxyContract.arc32.json index 5b219e3afb..25f2bd16f3 100644 --- a/test_cases/state_proxies/out/StateProxyContract.arc32.json +++ b/test_cases/state_proxies/out/StateProxyContract.arc32.json @@ -7,7 +7,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX3Byb3hpZXMuY29udHJhY3QuU3RhdGVQcm94eUNvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfcHJveGllcy5jb250cmFjdC5TdGF0ZVByb3h5Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxMgogICAgLy8gY2xhc3MgU3RhdGVQcm94eUNvbnRyYWN0KEFSQzRDb250cmFjdCwgc3RhdGVfdG90YWxzPVN0YXRlVG90YWxzKGdsb2JhbF91aW50cz0zKSk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYKICAgIG1ldGhvZCAiY3JlYXRlKCl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fY3JlYXRlX3JvdXRlQDIKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdLCBjcmVhdGU9InJlcXVpcmUiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgY2FsbHN1YiBjcmVhdGUKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MTIKICAgIC8vIGNsYXNzIFN0YXRlUHJveHlDb250cmFjdChBUkM0Q29udHJhY3QsIHN0YXRlX3RvdGFscz1TdGF0ZVRvdGFscyhnbG9iYWxfdWludHM9MykpOgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfcHJveGllcy5jb250cmFjdC5TdGF0ZVByb3h5Q29udHJhY3QuY3JlYXRlKCkgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyNS0yNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdLCBjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE2CiAgICAvLyBzZWxmLmdsb2JhbDEgPSBHbG9iYWxTdGF0ZShVSW50NjQsIGtleT0iZzEiLCBkZXNjcmlwdGlvbj0iZzEgZGVzY3JpcHRpb24iKQogICAgYnl0ZSAiZzEiCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBzZWxmLmdsb2JhbDEudmFsdWUgPSBVSW50NjQoMSkKICAgIGludCAxCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyOAogICAgLy8gc2VsZi5sb2NhbDFbVHhuLnNlbmRlcl0gPSBVSW50NjQoMikKICAgIHR4biBTZW5kZXIKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MTQKICAgIC8vIHNlbGYubG9jYWwxID0gTG9jYWxTdGF0ZShVSW50NjQsIGtleT0ibDEiLCBkZXNjcmlwdGlvbj0ibDEgZGVzY3JpcHRpb24iKQogICAgYnl0ZSAibDEiCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjI4CiAgICAvLyBzZWxmLmxvY2FsMVtUeG4uc2VuZGVyXSA9IFVJbnQ2NCgyKQogICAgaW50IDIKICAgIGFwcF9sb2NhbF9wdXQKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MjkKICAgIC8vIHNlbGYubG9jYWwyW1R4bi5zZW5kZXJdID0gVUludDY0KDMpCiAgICB0eG4gU2VuZGVyCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE1CiAgICAvLyBzZWxmLmxvY2FsMiA9IExvY2FsU3RhdGVbVUludDY0XShVSW50NjQsIGtleT1iImwyIiwgZGVzY3JpcHRpb249ImwyIGRlc2NyaXB0aW9uIikKICAgIGJ5dGUgMHg2YzMyCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjI5CiAgICAvLyBzZWxmLmxvY2FsMltUeG4uc2VuZGVyXSA9IFVJbnQ2NCgzKQogICAgaW50IDMKICAgIGFwcF9sb2NhbF9wdXQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfcHJveGllcy5jb250cmFjdC5TdGF0ZVByb3h5Q29udHJhY3QuX19pbml0X18oKSAtPiB2b2lkOgpfX2luaXRfXzoKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MTMKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE3CiAgICAvLyBzZWxmLmdsb2JhbDIgPSBHbG9iYWxTdGF0ZVtVSW50NjRdKFVJbnQ2NCgwKSwga2V5PWIiZzIiLCBkZXNjcmlwdGlvbj0iZzIgZGVzY3JpcHRpb24iKQogICAgYnl0ZSAweDY3MzIKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyMQogICAgLy8gZWxzZSBHbG9iYWxTdGF0ZShVSW50NjQsIGtleT0idG93biIpCiAgICBieXRlICJ0b3duIgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxOQogICAgLy8gR2xvYmFsU3RhdGUoVUludDY0LCBrZXk9ImZ1bmt5IikKICAgIGJ5dGUgImZ1bmt5IgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyMAogICAgLy8gaWYgVHhuLm51bV9hcHBfYXJncwogICAgdHhuIE51bUFwcEFyZ3MKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MTktMjEKICAgIC8vIEdsb2JhbFN0YXRlKFVJbnQ2NCwga2V5PSJmdW5reSIpCiAgICAvLyBpZiBUeG4ubnVtX2FwcF9hcmdzCiAgICAvLyBlbHNlIEdsb2JhbFN0YXRlKFVJbnQ2NCwga2V5PSJ0b3duIikKICAgIHNlbGVjdAogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyMwogICAgLy8gZnVua3lfdG93bi52YWx1ZSA9IFVJbnQ2NCgxMjMpCiAgICBpbnQgMTIzCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgcmV0c3ViCg==", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX3Byb3hpZXMuY29udHJhY3QuU3RhdGVQcm94eUNvbnRyYWN0LmFwcHJvdmFsX3Byb2dyYW06CiAgICB0eG4gQXBwbGljYXRpb25JRAogICAgYm56IG1haW5fZW50cnlwb2ludEAyCiAgICBjYWxsc3ViIF9faW5pdF9fCgptYWluX2VudHJ5cG9pbnRAMjoKICAgIGNhbGxzdWIgX19wdXlhX2FyYzRfcm91dGVyX18KICAgIHJldHVybgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfcHJveGllcy5jb250cmFjdC5TdGF0ZVByb3h5Q29udHJhY3QuX19wdXlhX2FyYzRfcm91dGVyX18oKSAtPiB1aW50NjQ6Cl9fcHV5YV9hcmM0X3JvdXRlcl9fOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxMgogICAgLy8gY2xhc3MgU3RhdGVQcm94eUNvbnRyYWN0KEFSQzRDb250cmFjdCwgc3RhdGVfdG90YWxzPVN0YXRlVG90YWxzKGdsb2JhbF91aW50cz0zKSk6CiAgICBwcm90byAwIDEKICAgIHR4biBOdW1BcHBBcmdzCiAgICBieiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19hZnRlcl9pZl9lbHNlQDYKICAgIG1ldGhvZCAiY3JlYXRlKCl2b2lkIgogICAgdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAogICAgbWF0Y2ggX19wdXlhX2FyYzRfcm91dGVyX19fY3JlYXRlX3JvdXRlQDIKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2NyZWF0ZV9yb3V0ZUAyOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyNQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdLCBjcmVhdGU9InJlcXVpcmUiKQogICAgdHhuIE9uQ29tcGxldGlvbgogICAgaW50IE9wdEluCiAgICA9PQogICAgYXNzZXJ0IC8vIE9uQ29tcGxldGlvbiBpcyBPcHRJbgogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgICEKICAgIGFzc2VydCAvLyBpcyBjcmVhdGluZwogICAgY2FsbHN1YiBjcmVhdGUKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VANjoKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MTIKICAgIC8vIGNsYXNzIFN0YXRlUHJveHlDb250cmFjdChBUkM0Q29udHJhY3QsIHN0YXRlX3RvdGFscz1TdGF0ZVRvdGFscyhnbG9iYWxfdWludHM9MykpOgogICAgaW50IDAKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMuc3RhdGVfcHJveGllcy5jb250cmFjdC5TdGF0ZVByb3h5Q29udHJhY3QuY3JlYXRlKCkgLT4gdm9pZDoKY3JlYXRlOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyNS0yNgogICAgLy8gQGFyYzQuYWJpbWV0aG9kKGFsbG93X2FjdGlvbnM9WyJPcHRJbiJdLCBjcmVhdGU9InJlcXVpcmUiKQogICAgLy8gZGVmIGNyZWF0ZShzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjI3CiAgICAvLyBzZWxmLmdsb2JhbDEudmFsdWUgPSBVSW50NjQoMSkKICAgIGJ5dGUgImcxIgogICAgaW50IDEKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjI4CiAgICAvLyBzZWxmLmxvY2FsMVtUeG4uc2VuZGVyXSA9IFVJbnQ2NCgyKQogICAgdHhuIFNlbmRlcgogICAgYnl0ZSAibDEiCiAgICBpbnQgMgogICAgYXBwX2xvY2FsX3B1dAogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToyOQogICAgLy8gc2VsZi5sb2NhbDJbVHhuLnNlbmRlcl0gPSBVSW50NjQoMykKICAgIHR4biBTZW5kZXIKICAgIGJ5dGUgMHg2YzMyCiAgICBpbnQgMwogICAgYXBwX2xvY2FsX3B1dAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy5zdGF0ZV9wcm94aWVzLmNvbnRyYWN0LlN0YXRlUHJveHlDb250cmFjdC5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxMwogICAgLy8gZGVmIF9faW5pdF9fKHNlbGYpIC0+IE5vbmU6CiAgICBwcm90byAwIDAKICAgIC8vIHN0YXRlX3Byb3hpZXMvY29udHJhY3QucHk6MTcKICAgIC8vIHNlbGYuZ2xvYmFsMiA9IEdsb2JhbFN0YXRlW1VJbnQ2NF0oVUludDY0KDApLCBrZXk9YiJnMiIsIGRlc2NyaXB0aW9uPSJnMiBkZXNjcmlwdGlvbiIpCiAgICBieXRlIDB4NjczMgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjIxCiAgICAvLyBlbHNlIEdsb2JhbFN0YXRlKFVJbnQ2NCwga2V5PSJ0b3duIikKICAgIGJ5dGUgInRvd24iCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjE5CiAgICAvLyBHbG9iYWxTdGF0ZShVSW50NjQsIGtleT0iZnVua3kiKQogICAgYnl0ZSAiZnVua3kiCiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjIwCiAgICAvLyBpZiBUeG4ubnVtX2FwcF9hcmdzCiAgICB0eG4gTnVtQXBwQXJncwogICAgLy8gc3RhdGVfcHJveGllcy9jb250cmFjdC5weToxOS0yMQogICAgLy8gR2xvYmFsU3RhdGUoVUludDY0LCBrZXk9ImZ1bmt5IikKICAgIC8vIGlmIFR4bi5udW1fYXBwX2FyZ3MKICAgIC8vIGVsc2UgR2xvYmFsU3RhdGUoVUludDY0LCBrZXk9InRvd24iKQogICAgc2VsZWN0CiAgICAvLyBzdGF0ZV9wcm94aWVzL2NvbnRyYWN0LnB5OjIzCiAgICAvLyBmdW5reV90b3duLnZhbHVlID0gVUludDY0KDEyMykKICAgIGludCAxMjMKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnN0YXRlX3Byb3hpZXMuY29udHJhY3QuU3RhdGVQcm94eUNvbnRyYWN0LmNsZWFyX3N0YXRlX3Byb2dyYW06CiAgICBpbnQgMQogICAgcmV0dXJuCg==" }, "state": { diff --git a/test_cases/state_proxies/out_unoptimized/StateProxyContract.approval.teal b/test_cases/state_proxies/out_unoptimized/StateProxyContract.approval.teal index 5e46210678..7ea3be8d74 100644 --- a/test_cases/state_proxies/out_unoptimized/StateProxyContract.approval.teal +++ b/test_cases/state_proxies/out_unoptimized/StateProxyContract.approval.teal @@ -58,31 +58,21 @@ create: // @arc4.abimethod(allow_actions=["OptIn"], create="require") // def create(self) -> None: proto 0 0 - // state_proxies/contract.py:16 - // self.global1 = GlobalState(UInt64, key="g1", description="g1 description") - byte "g1" // state_proxies/contract.py:27 // self.global1.value = UInt64(1) + byte "g1" int 1 app_global_put // state_proxies/contract.py:28 // self.local1[Txn.sender] = UInt64(2) txn Sender - // state_proxies/contract.py:14 - // self.local1 = LocalState(UInt64, key="l1", description="l1 description") byte "l1" - // state_proxies/contract.py:28 - // self.local1[Txn.sender] = UInt64(2) int 2 app_local_put // state_proxies/contract.py:29 // self.local2[Txn.sender] = UInt64(3) txn Sender - // state_proxies/contract.py:15 - // self.local2 = LocalState[UInt64](UInt64, key=b"l2", description="l2 description") byte 0x6c32 - // state_proxies/contract.py:29 - // self.local2[Txn.sender] = UInt64(3) int 3 app_local_put retsub diff --git a/test_cases/tuple_support/out/NestedTuples.approval.mir b/test_cases/tuple_support/out/NestedTuples.approval.mir index f63507b15a..1b0edc5720 100644 --- a/test_cases/tuple_support/out/NestedTuples.approval.mir +++ b/test_cases/tuple_support/out/NestedTuples.approval.mir @@ -577,7 +577,7 @@ test_single_evaluation_nested: proto 0 0 // @subroutine\ndef test_single_evaluation_nested(self) -> None: tuple_support/nested_tuples.py:49-50 test_single_evaluation_nested_block@0: - byte "build_nested_call_count" // "build_nested_call_count" self.build_nested_call_count tuple_support/nested_tuples.py:6 + byte "build_nested_call_count" // "build_nested_call_count" self.build_nested_call_count tuple_support/nested_tuples.py:51 int 0 // "build_nested_call_count",0 UInt64(0) tuple_support/nested_tuples.py:51 app_global_put // self.build_nested_call_count = UInt64(0) tuple_support/nested_tuples.py:51 callsub build_nested // {build_nested}.0,{build_nested}.1,{build_nested}.2 self.build_nested() tuple_support/nested_tuples.py:52 @@ -591,7 +591,7 @@ test_single_evaluation_nested_block@0: // virtual: load tmp%5#0 from l-stack (no copy) tmp%5#0 assert result[0][0] == "hi" tuple_support/nested_tuples.py:53 assert // assert result[0][0] == "hi" tuple_support/nested_tuples.py:53 int 0 // 0 self.build_nested_call_count tuple_support/nested_tuples.py:54 - byte "build_nested_call_count" // 0,"build_nested_call_count" self.build_nested_call_count tuple_support/nested_tuples.py:6 + byte "build_nested_call_count" // 0,"build_nested_call_count" self.build_nested_call_count tuple_support/nested_tuples.py:54 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.build_nested_call_count tuple_support/nested_tuples.py:54 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.build_nested_call_count tuple_support/nested_tuples.py:54 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.build_nested_call_count tuple_support/nested_tuples.py:54 @@ -612,7 +612,7 @@ build_nested: build_nested_block@0: int 0 // 0 self.build_nested_call_count tuple_support/nested_tuples.py:46 - byte "build_nested_call_count" // 0,"build_nested_call_count" self.build_nested_call_count tuple_support/nested_tuples.py:6 + byte "build_nested_call_count" // 0,"build_nested_call_count" self.build_nested_call_count tuple_support/nested_tuples.py:46 app_global_get_ex // {app_global_get_ex}.0,{app_global_get_ex}.1 self.build_nested_call_count tuple_support/nested_tuples.py:46 // virtual: store maybe_exists%0#0 to l-stack (no copy) maybe_exists%0#0,{app_global_get_ex}.0 self.build_nested_call_count tuple_support/nested_tuples.py:46 // virtual: store maybe_value%0#0 to l-stack (no copy) maybe_value%0#0,maybe_exists%0#0 self.build_nested_call_count tuple_support/nested_tuples.py:46 @@ -622,7 +622,7 @@ build_nested_block@0: int 1 // maybe_value%0#0,1 1 tuple_support/nested_tuples.py:46 + // {+} self.build_nested_call_count += 1 tuple_support/nested_tuples.py:46 // virtual: store new_state_value%0#0 to l-stack (no copy) new_state_value%0#0 self.build_nested_call_count += 1 tuple_support/nested_tuples.py:46 - byte "build_nested_call_count" // new_state_value%0#0,"build_nested_call_count" self.build_nested_call_count tuple_support/nested_tuples.py:6 + byte "build_nested_call_count" // new_state_value%0#0,"build_nested_call_count" self.build_nested_call_count tuple_support/nested_tuples.py:46 uncover 1 // load new_state_value%0#0 from l-stack (no copy) "build_nested_call_count",new_state_value%0#0 self.build_nested_call_count += 1 tuple_support/nested_tuples.py:46 app_global_put // self.build_nested_call_count += 1 tuple_support/nested_tuples.py:46 byte "hi" // "hi" String("hi") tuple_support/nested_tuples.py:47 diff --git a/test_cases/tuple_support/out/NestedTuples.approval.teal b/test_cases/tuple_support/out/NestedTuples.approval.teal index 88051ee4ce..b60521eda4 100644 --- a/test_cases/tuple_support/out/NestedTuples.approval.teal +++ b/test_cases/tuple_support/out/NestedTuples.approval.teal @@ -580,11 +580,9 @@ test_single_evaluation_nested: // @subroutine // def test_single_evaluation_nested(self) -> None: proto 0 0 - // tuple_support/nested_tuples.py:6 - // self.build_nested_call_count = UInt64(0) - byte "build_nested_call_count" // tuple_support/nested_tuples.py:51 // self.build_nested_call_count = UInt64(0) + byte "build_nested_call_count" int 0 app_global_put // tuple_support/nested_tuples.py:52 @@ -599,11 +597,7 @@ test_single_evaluation_nested: // tuple_support/nested_tuples.py:54 // assert self.build_nested_call_count == 1 int 0 - // tuple_support/nested_tuples.py:6 - // self.build_nested_call_count = UInt64(0) byte "build_nested_call_count" - // tuple_support/nested_tuples.py:54 - // assert self.build_nested_call_count == 1 app_global_get_ex assert // check self.build_nested_call_count exists int 1 @@ -621,20 +615,12 @@ build_nested: // tuple_support/nested_tuples.py:46 // self.build_nested_call_count += 1 int 0 - // tuple_support/nested_tuples.py:6 - // self.build_nested_call_count = UInt64(0) byte "build_nested_call_count" - // tuple_support/nested_tuples.py:46 - // self.build_nested_call_count += 1 app_global_get_ex assert // check self.build_nested_call_count exists int 1 + - // tuple_support/nested_tuples.py:6 - // self.build_nested_call_count = UInt64(0) byte "build_nested_call_count" - // tuple_support/nested_tuples.py:46 - // self.build_nested_call_count += 1 swap app_global_put // tuple_support/nested_tuples.py:47 diff --git a/test_cases/tuple_support/out/NestedTuples.arc32.json b/test_cases/tuple_support/out/NestedTuples.arc32.json index c4926b0caa..5db1141ab7 100644 --- a/test_cases/tuple_support/out/NestedTuples.arc32.json +++ b/test_cases/tuple_support/out/NestedTuples.arc32.json @@ -12,7 +12,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy5OZXN0ZWRUdXBsZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy50dXBsZV9zdXBwb3J0Lm5lc3RlZF90dXBsZXMuTmVzdGVkVHVwbGVzLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo0CiAgICAvLyBjbGFzcyBOZXN0ZWRUdXBsZXMoQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBtZXRob2QgInJ1bl90ZXN0cygpYm9vbCIKICAgIG1ldGhvZCAibmVzdGVkX3R1cGxlX3BhcmFtcygoc3RyaW5nLChieXRlW10sKHVpbnQ2NCkpKSkoYnl0ZVtdLChzdHJpbmcsdWludDY0KSkiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19ydW5fdGVzdHNfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19uZXN0ZWRfdHVwbGVfcGFyYW1zX3JvdXRlQDMKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3J1bl90ZXN0c19yb3V0ZUAyOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHJ1bl90ZXN0cwogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX25lc3RlZF90dXBsZV9wYXJhbXNfcm91dGVAMzoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo0CiAgICAvLyBjbGFzcyBOZXN0ZWRUdXBsZXMoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGR1cAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGludCAyCiAgICBleHRyYWN0X3VpbnQxNgogICAgZGlnIDEKICAgIHVuY292ZXIgMwogICAgZGlnIDIKICAgIHN1YnN0cmluZzMKICAgIGNvdmVyIDIKICAgIGRpZyAxCiAgICBsZW4KICAgIHN1YnN0cmluZzMKICAgIHN3YXAKICAgIGV4dHJhY3QgMiAwCiAgICBzd2FwCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIHN3YXAKICAgIGR1cAogICAgdW5jb3ZlciAzCiAgICB1bmNvdmVyIDMKICAgIHN1YnN0cmluZzMKICAgIHN3YXAKICAgIGV4dHJhY3QgMiA4IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgc3dhcAogICAgZXh0cmFjdCAyIDAKICAgIHN3YXAKICAgIGV4dHJhY3QgMCA4IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnRvaQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBuZXN0ZWRfdHVwbGVfcGFyYW1zCiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgaXRvYgogICAgYnl0ZSAweDAwMGEKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpbnQgNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGUgMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2OgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjQKICAgIC8vIGNsYXNzIE5lc3RlZFR1cGxlcyhBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTAKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NAogICAgLy8gY2xhc3MgTmVzdGVkVHVwbGVzKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy50dXBsZV9zdXBwb3J0Lm5lc3RlZF90dXBsZXMuTmVzdGVkVHVwbGVzLnJ1bl90ZXN0cygpIC0+IHVpbnQ2NDoKcnVuX3Rlc3RzOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjgtOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBydW5fdGVzdHMoc2VsZikgLT4gYm9vbDoKICAgIHByb3RvIDAgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEwCiAgICAvLyB4ID0gKFN0cmluZygiSGkiKSwgU3RyaW5nKCJUaGVyZSIpKQogICAgYnl0ZSAiSGkiCiAgICBieXRlICJUaGVyZSIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMQogICAgLy8gYXNzZXJ0IHRlc3Rfc3dhcCh4KSA9PSAoU3RyaW5nKCJUaGVyZSIpLCBTdHJpbmcoIkhpIikpCiAgICBjYWxsc3ViIHRlc3Rfc3dhcAogICAgc3dhcAogICAgYnl0ZSAiVGhlcmUiCiAgICA9PQogICAgc3dhcAogICAgYnl0ZSAiSGkiCiAgICA9PQogICAgJiYKICAgIGFzc2VydAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEwCiAgICAvLyB4ID0gKFN0cmluZygiSGkiKSwgU3RyaW5nKCJUaGVyZSIpKQogICAgYnl0ZSAiSGkiCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTMKICAgIC8vIHogPSAoVUludDY0KDApLCBVSW50NjQoMiksIHkpCiAgICBpbnQgMAogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMgogICAgLy8geSA9IChVSW50NjQoMSksIHgpCiAgICBpbnQgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEwCiAgICAvLyB4ID0gKFN0cmluZygiSGkiKSwgU3RyaW5nKCJUaGVyZSIpKQogICAgYnl0ZSAiSGkiCiAgICBieXRlICJUaGVyZSIKICAgIGR1cAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE5CiAgICAvLyAoYSwgYiwgKGMsIGQsIChlLCkpKSA9IHRlc3RfcmVhcnJhbmdlKHhbMF0sIHosIHhbMV0pCiAgICBjYWxsc3ViIHRlc3RfcmVhcnJhbmdlCiAgICBjb3ZlciA0CiAgICBjb3ZlciAzCiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MjAKICAgIC8vIGFzc2VydCAoYSwgYikgPT0gKFN0cmluZygiSGkiKSwgVUludDY0KDApKQogICAgYnl0ZSAiSGkiCiAgICA9PQogICAgc3dhcAogICAgIQogICAgJiYKICAgIGFzc2VydAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjIxCiAgICAvLyBhc3NlcnQgKGMsIGQpID09IChVSW50NjQoMiksIFVJbnQ2NCgxKSkKICAgIGludCAyCiAgICA9PQogICAgc3dhcAogICAgaW50IDEKICAgID09CiAgICAmJgogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MjIKICAgIC8vIGFzc2VydCBlID09IFN0cmluZygiVGhlcmUiKQogICAgYnl0ZSAiVGhlcmUiCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MjQKICAgIC8vIHRlc3RfaW50cmluc2ljcyhVSW50NjQoMSksIFVJbnQ2NCgyKSkKICAgIGludCAxCiAgICBpbnQgMgogICAgY2FsbHN1YiB0ZXN0X2ludHJpbnNpY3MKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToyNgogICAgLy8gdGVzdF9uZXN0ZWRfc2luZ2xlcyhVSW50NjQoMSksIHJlYXNzaWduPVRydWUpCiAgICBpbnQgMQogICAgZHVwCiAgICBjYWxsc3ViIHRlc3RfbmVzdGVkX3NpbmdsZXMKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToyNwogICAgLy8gdGVzdF9uZXN0ZWRfc2luZ2xlcyhVSW50NjQoMSksIHJlYXNzaWduPUZhbHNlKQogICAgaW50IDEKICAgIGludCAwCiAgICBjYWxsc3ViIHRlc3RfbmVzdGVkX3NpbmdsZXMKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTozMgogICAgLy8gdGVzdF9uZXN0ZWRfaXRlcmF0aW9uKCkKICAgIGNhbGxzdWIgdGVzdF9uZXN0ZWRfaXRlcmF0aW9uCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MzQKICAgIC8vIHNlbGYudGVzdF9zaW5nbGVfZXZhbHVhdGlvbl9uZXN0ZWQoKQogICAgY2FsbHN1YiB0ZXN0X3NpbmdsZV9ldmFsdWF0aW9uX25lc3RlZAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjM1CiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudHVwbGVfc3VwcG9ydC5uZXN0ZWRfdHVwbGVzLnRlc3Rfc3dhcChhcmdzLjA6IGJ5dGVzLCBhcmdzLjE6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CnRlc3Rfc3dhcDoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo2Ni02NwogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiB0ZXN0X3N3YXAoYXJnczogdHVwbGVbU3RyaW5nLCBTdHJpbmddKSAtPiB0dXBsZVtTdHJpbmcsIFN0cmluZ106CiAgICBwcm90byAyIDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo2OQogICAgLy8gcmV0dXJuIGIsIGEKICAgIGZyYW1lX2RpZyAtMQogICAgZnJhbWVfZGlnIC0yCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy50ZXN0X3JlYXJyYW5nZShfYTogYnl0ZXMsIGFyZ3MuMDogdWludDY0LCBhcmdzLjE6IHVpbnQ2NCwgYXJncy4yLjA6IHVpbnQ2NCwgYXJncy4yLjEuMDogYnl0ZXMsIGFyZ3MuMi4xLjE6IGJ5dGVzLCBfYjogYnl0ZXMpIC0+IGJ5dGVzLCB1aW50NjQsIHVpbnQ2NCwgdWludDY0LCBieXRlczoKdGVzdF9yZWFycmFuZ2U6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NTctNjAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgdGVzdF9yZWFycmFuZ2UoCiAgICAvLyAgICAgX2E6IFN0cmluZywgYXJnczogdHVwbGVbVUludDY0LCBVSW50NjQsIHR1cGxlW1VJbnQ2NCwgdHVwbGVbU3RyaW5nLCBTdHJpbmddXV0sIF9iOiBTdHJpbmcKICAgIC8vICkgLT4gdHVwbGVbU3RyaW5nLCBVSW50NjQsIHR1cGxlW1VJbnQ2NCwgVUludDY0LCB0dXBsZVtTdHJpbmddXV06CiAgICBwcm90byA3IDUKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo2MwogICAgLy8gcmV0dXJuIGQsIGEsIChiLCBjLCAoZSwpKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTYKICAgIGZyYW1lX2RpZyAtNQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTIKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudHVwbGVfc3VwcG9ydC5uZXN0ZWRfdHVwbGVzLnRlc3RfaW50cmluc2ljcyhudW0xOiB1aW50NjQsIG51bTI6IHVpbnQ2NCkgLT4gdm9pZDoKdGVzdF9pbnRyaW5zaWNzOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjcyLTczCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHRlc3RfaW50cmluc2ljcyhudW0xOiBVSW50NjQsIG51bTI6IFVJbnQ2NCkgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5Ojc0CiAgICAvLyBudCA9IChVSW50NjQoMSksIG9wLmFkZHcobnVtMSwgbnVtMiksIFVJbnQ2NCg0MikpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYWRkdwogICAgc3dhcAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5Ojc3CiAgICAvLyBhc3NlcnQgbnRbMV0gPT0gKDAsIG51bTEgKyBudW0yKSAgIyB0eXBlOiBpZ25vcmVbY29tcGFyaXNvbi1vdmVybGFwXQogICAgIQogICAgc3dhcAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICsKICAgID09CiAgICBkdXAyCiAgICAmJgogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NzgKICAgIC8vIGFzc2VydCBudFsxXVs6MV0gPT0gKDAsKSAgIyB0eXBlOiBpZ25vcmVbY29tcGFyaXNvbi1vdmVybGFwXQogICAgc3dhcAogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NzkKICAgIC8vIGFzc2VydCBudFsxXVsxOl0gPT0gKG51bTEgKyBudW0yLCkKICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy50dXBsZV9zdXBwb3J0Lm5lc3RlZF90dXBsZXMudGVzdF9uZXN0ZWRfc2luZ2xlcyhvbmU6IHVpbnQ2NCwgcmVhc3NpZ246IHVpbnQ2NCkgLT4gdm9pZDoKdGVzdF9uZXN0ZWRfc2luZ2xlczoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMDctMTA4CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHRlc3RfbmVzdGVkX3NpbmdsZXMob25lOiBVSW50NjQsICosIHJlYXNzaWduOiBib29sKSAtPiBOb25lOgogICAgcHJvdG8gMiAwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTEwCiAgICAvLyAoVUludDY0KDApLCksCiAgICBpbnQgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjExMgogICAgLy8gKFVJbnQ2NCgyKSwpLAogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMTYKICAgIC8vIGFzc2VydCBzWzFdWzBdID09IDEKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDEKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEyMQogICAgLy8gaWYgcmVhc3NpZ246CiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6IHRlc3RfbmVzdGVkX3NpbmdsZXNfYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTIzCiAgICAvLyAoVUludDY0KDMpLCksCiAgICBpbnQgMwogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEyMi0xMjYKICAgIC8vIHMgPSAoCiAgICAvLyAgICAgKFVJbnQ2NCgzKSwpLAogICAgLy8gICAgIChVSW50NjQoNCksKSwKICAgIC8vICAgICAoVUludDY0KDUpLCksCiAgICAvLyApCiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMjQKICAgIC8vIChVSW50NjQoNCksKSwKICAgIGludCA0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTIyLTEyNgogICAgLy8gcyA9ICgKICAgIC8vICAgICAoVUludDY0KDMpLCksCiAgICAvLyAgICAgKFVJbnQ2NCg0KSwpLAogICAgLy8gICAgIChVSW50NjQoNSksKSwKICAgIC8vICkKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEyNQogICAgLy8gKFVJbnQ2NCg1KSwpLAogICAgaW50IDUKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMjItMTI2CiAgICAvLyBzID0gKAogICAgLy8gICAgIChVSW50NjQoMyksKSwKICAgIC8vICAgICAoVUludDY0KDQpLCksCiAgICAvLyAgICAgKFVJbnQ2NCg1KSwpLAogICAgLy8gKQogICAgZnJhbWVfYnVyeSAxCgp0ZXN0X25lc3RlZF9zaW5nbGVzX2FmdGVyX2lmX2Vsc2VAMjoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMjcKICAgIC8vIGFzc2VydCBzWzBdWzBdID09ICgzIGlmIHJlYXNzaWduIGVsc2UgMCkKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgICoKICAgIGZyYW1lX2RpZyAwCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTI5CiAgICAvLyBhc3NlcnQgdG1wID09ICg1IGlmIHJlYXNzaWduIGVsc2UgMikKICAgIGludCAyCiAgICBpbnQgNQogICAgZnJhbWVfZGlnIC0xCiAgICBzZWxlY3QKICAgIGZyYW1lX2RpZyAxCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEzMwogICAgLy8gczEgKz0gb25lCiAgICBmcmFtZV9kaWcgMgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBmcmFtZV9kaWcgLTIKICAgICsKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMzQKICAgIC8vIGFzc2VydCBzMSA9PSAoNSBpZiByZWFzc2lnbiBlbHNlIDIpCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTM1CiAgICAvLyBhc3NlcnQgc1sxXVswXSA9PSAoNCBpZiByZWFzc2lnbiBlbHNlIDEpCiAgICBpbnQgMQogICAgaW50IDQKICAgIGZyYW1lX2RpZyAtMQogICAgc2VsZWN0CiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy50ZXN0X25lc3RlZF9pdGVyYXRpb24oKSAtPiB2b2lkOgp0ZXN0X25lc3RlZF9pdGVyYXRpb246CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTUxLTE1MgogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiB0ZXN0X25lc3RlZF9pdGVyYXRpb24oKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICBieXRlICIiCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU1CiAgICAvLyB0b3RhbCA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTMKICAgIC8vIHggPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU0CiAgICAvLyB5ID0gVUludDY0KDIpCiAgICBpbnQgMgogICAgaW50IDAKCnRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9mb3JfYm9keUAxOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1OQogICAgLy8gdG90YWwgKz0gYSArIGIKICAgIGZyYW1lX2RpZyAyCiAgICB1bmNvdmVyIDIKICAgICsKICAgIGZyYW1lX2RpZyAxCiAgICArCiAgICBmcmFtZV9idXJ5IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTcKICAgIC8vIGZvciB0IGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dpdGNoIHRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9mb3JfaGVhZGVyXzFAMyB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2hlYWRlcl8yQDQgdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfM0A1CiAgICBiIHRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9hZnRlcl9mb3JANgoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfMUAzOgogICAgaW50IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTQKICAgIC8vIHkgPSBVSW50NjQoMikKICAgIGludCAyCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU3CiAgICAvLyBmb3IgdCBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1MwogICAgLy8geCA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTcKICAgIC8vIGZvciB0IGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2JvZHlAMQoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfMkA0OgogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTMKICAgIC8vIHggPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU3CiAgICAvLyBmb3IgdCBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1MwogICAgLy8geCA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTcKICAgIC8vIGZvciB0IGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2JvZHlAMQoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfM0A1OgogICAgaW50IDMKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTQKICAgIC8vIHkgPSBVSW50NjQoMikKICAgIGludCAyCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU3CiAgICAvLyBmb3IgdCBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1NAogICAgLy8geSA9IFVJbnQ2NCgyKQogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTcKICAgIC8vIGZvciB0IGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2JvZHlAMQoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2FmdGVyX2ZvckA2OgogICAgaW50IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTMKICAgIC8vIHggPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTYxCiAgICAvLyBmb3IgYSwgYiBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1NAogICAgLy8geSA9IFVJbnQ2NCgyKQogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNjEKICAgIC8vIGZvciBhLCBiIGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9ib2R5QDc6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTYyCiAgICAvLyB0b3RhbCArPSBhICsgYgogICAgZnJhbWVfZGlnIDAKICAgIHVuY292ZXIgMgogICAgKwogICAgZnJhbWVfZGlnIDEKICAgICsKICAgIGZyYW1lX2J1cnkgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE2MQogICAgLy8gZm9yIGEsIGIgaW4gKCh4LCB5KSwgKHksIHgpLCAoeCwgeCksICh5LCB5KSk6CiAgICBzd2l0Y2ggdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfMUA5IHRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9mb3JfaGVhZGVyXzJAMTAgdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfM0AxMQogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fYWZ0ZXJfZm9yQDEyCgp0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2hlYWRlcl8xQDk6CiAgICBpbnQgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1NAogICAgLy8geSA9IFVJbnQ2NCgyKQogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNjEKICAgIC8vIGZvciBhLCBiIGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgZnJhbWVfYnVyeSAwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTUzCiAgICAvLyB4ID0gVUludDY0KDEpCiAgICBpbnQgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE2MQogICAgLy8gZm9yIGEsIGIgaW4gKCh4LCB5KSwgKHksIHgpLCAoeCwgeCksICh5LCB5KSk6CiAgICBzd2FwCiAgICBiIHRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9mb3JfYm9keUA3Cgp0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2hlYWRlcl8yQDEwOgogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTMKICAgIC8vIHggPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTYxCiAgICAvLyBmb3IgYSwgYiBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1MwogICAgLy8geCA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNjEKICAgIC8vIGZvciBhLCBiIGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2JvZHlANwoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfM0AxMToKICAgIGludCAzCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU0CiAgICAvLyB5ID0gVUludDY0KDIpCiAgICBpbnQgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE2MQogICAgLy8gZm9yIGEsIGIgaW4gKCh4LCB5KSwgKHksIHgpLCAoeCwgeCksICh5LCB5KSk6CiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTQKICAgIC8vIHkgPSBVSW50NjQoMikKICAgIGludCAyCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTYxCiAgICAvLyBmb3IgYSwgYiBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIHN3YXAKICAgIGIgdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9ib2R5QDcKCnRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9hZnRlcl9mb3JAMTI6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTY0CiAgICAvLyBhc3NlcnQgdG90YWwgLy8gOCA9PSAzCiAgICBmcmFtZV9kaWcgMQogICAgaW50IDgKICAgIC8KICAgIGludCAzCiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy5OZXN0ZWRUdXBsZXMudGVzdF9zaW5nbGVfZXZhbHVhdGlvbl9uZXN0ZWQoKSAtPiB2b2lkOgp0ZXN0X3NpbmdsZV9ldmFsdWF0aW9uX25lc3RlZDoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo0OS01MAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiB0ZXN0X3NpbmdsZV9ldmFsdWF0aW9uX25lc3RlZChzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NgogICAgLy8gc2VsZi5idWlsZF9uZXN0ZWRfY2FsbF9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYnVpbGRfbmVzdGVkX2NhbGxfY291bnQiCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NTEKICAgIC8vIHNlbGYuYnVpbGRfbmVzdGVkX2NhbGxfY291bnQgPSBVSW50NjQoMCkKICAgIGludCAwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjUyCiAgICAvLyByZXN1bHQgPSBzZWxmLmJ1aWxkX25lc3RlZCgpIG9yIHNlbGYuYnVpbGRfbmVzdGVkKCkKICAgIGNhbGxzdWIgYnVpbGRfbmVzdGVkCiAgICBwb3BuIDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo1MwogICAgLy8gYXNzZXJ0IHJlc3VsdFswXVswXSA9PSAiaGkiCiAgICBieXRlICJoaSIKICAgID09CiAgICBhc3NlcnQKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo1NAogICAgLy8gYXNzZXJ0IHNlbGYuYnVpbGRfbmVzdGVkX2NhbGxfY291bnQgPT0gMQogICAgaW50IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo2CiAgICAvLyBzZWxmLmJ1aWxkX25lc3RlZF9jYWxsX2NvdW50ID0gVUludDY0KDApCiAgICBieXRlICJidWlsZF9uZXN0ZWRfY2FsbF9jb3VudCIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo1NAogICAgLy8gYXNzZXJ0IHNlbGYuYnVpbGRfbmVzdGVkX2NhbGxfY291bnQgPT0gMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJ1aWxkX25lc3RlZF9jYWxsX2NvdW50IGV4aXN0cwogICAgaW50IDEKICAgID09CiAgICBhc3NlcnQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudHVwbGVfc3VwcG9ydC5uZXN0ZWRfdHVwbGVzLk5lc3RlZFR1cGxlcy5idWlsZF9uZXN0ZWQoKSAtPiBieXRlcywgdWludDY0LCBieXRlczoKYnVpbGRfbmVzdGVkOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjQ0LTQ1CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIGJ1aWxkX25lc3RlZChzZWxmKSAtPiB0dXBsZVt0dXBsZVtTdHJpbmcsIFVJbnQ2NF0sIEJ5dGVzXToKICAgIHByb3RvIDAgMwogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjQ2CiAgICAvLyBzZWxmLmJ1aWxkX25lc3RlZF9jYWxsX2NvdW50ICs9IDEKICAgIGludCAwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NgogICAgLy8gc2VsZi5idWlsZF9uZXN0ZWRfY2FsbF9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYnVpbGRfbmVzdGVkX2NhbGxfY291bnQiCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NDYKICAgIC8vIHNlbGYuYnVpbGRfbmVzdGVkX2NhbGxfY291bnQgKz0gMQogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJ1aWxkX25lc3RlZF9jYWxsX2NvdW50IGV4aXN0cwogICAgaW50IDEKICAgICsKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo2CiAgICAvLyBzZWxmLmJ1aWxkX25lc3RlZF9jYWxsX2NvdW50ID0gVUludDY0KDApCiAgICBieXRlICJidWlsZF9uZXN0ZWRfY2FsbF9jb3VudCIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo0NgogICAgLy8gc2VsZi5idWlsZF9uZXN0ZWRfY2FsbF9jb3VudCArPSAxCiAgICBzd2FwCiAgICBhcHBfZ2xvYmFsX3B1dAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjQ3CiAgICAvLyByZXR1cm4gKFN0cmluZygiaGkiKSwgVUludDY0KDEpKSwgQnl0ZXMoYiJobW1tIikKICAgIGJ5dGUgImhpIgogICAgaW50IDEKICAgIGJ5dGUgMHg2ODZkNmQ2ZAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy50dXBsZV9zdXBwb3J0Lm5lc3RlZF90dXBsZXMuTmVzdGVkVHVwbGVzLm5lc3RlZF90dXBsZV9wYXJhbXMoYXJncy4wOiBieXRlcywgYXJncy4xLjA6IGJ5dGVzLCBhcmdzLjEuMS4wOiB1aW50NjQpIC0+IGJ5dGVzLCBieXRlcywgdWludDY0OgpuZXN0ZWRfdHVwbGVfcGFyYW1zOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjM3LTQwCiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgLy8gZGVmIG5lc3RlZF90dXBsZV9wYXJhbXMoCiAgICAvLyAgICAgc2VsZiwgYXJnczogdHVwbGVbU3RyaW5nLCB0dXBsZVtCeXRlcywgdHVwbGVbVUludDY0XV1dCiAgICAvLyApIC0+IHR1cGxlW0J5dGVzLCB0dXBsZVtTdHJpbmcsIFVJbnQ2NF1dOgogICAgcHJvdG8gMyAzCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NDIKICAgIC8vIHJldHVybiBiLCAocywgdSkKICAgIGZyYW1lX2RpZyAtMgogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudHVwbGVfc3VwcG9ydC5uZXN0ZWRfdHVwbGVzLk5lc3RlZFR1cGxlcy5fX2luaXRfXygpIC0+IHZvaWQ6Cl9faW5pdF9fOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjUKICAgIC8vIGRlZiBfX2luaXRfXyhzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NgogICAgLy8gc2VsZi5idWlsZF9uZXN0ZWRfY2FsbF9jb3VudCA9IFVJbnQ2NCgwKQogICAgYnl0ZSAiYnVpbGRfbmVzdGVkX2NhbGxfY291bnQiCiAgICBpbnQgMAogICAgYXBwX2dsb2JhbF9wdXQKICAgIHJldHN1Ygo=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy5OZXN0ZWRUdXBsZXMuYXBwcm92YWxfcHJvZ3JhbToKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBibnogbWFpbl9lbnRyeXBvaW50QDIKICAgIGNhbGxzdWIgX19pbml0X18KCm1haW5fZW50cnlwb2ludEAyOgogICAgY2FsbHN1YiBfX3B1eWFfYXJjNF9yb3V0ZXJfXwogICAgcmV0dXJuCgoKLy8gdGVzdF9jYXNlcy50dXBsZV9zdXBwb3J0Lm5lc3RlZF90dXBsZXMuTmVzdGVkVHVwbGVzLl9fcHV5YV9hcmM0X3JvdXRlcl9fKCkgLT4gdWludDY0OgpfX3B1eWFfYXJjNF9yb3V0ZXJfXzoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo0CiAgICAvLyBjbGFzcyBOZXN0ZWRUdXBsZXMoQVJDNENvbnRyYWN0KToKICAgIHByb3RvIDAgMQogICAgdHhuIE51bUFwcEFyZ3MKICAgIGJ6IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2CiAgICBtZXRob2QgInJ1bl90ZXN0cygpYm9vbCIKICAgIG1ldGhvZCAibmVzdGVkX3R1cGxlX3BhcmFtcygoc3RyaW5nLChieXRlW10sKHVpbnQ2NCkpKSkoYnl0ZVtdLChzdHJpbmcsdWludDY0KSkiCiAgICB0eG5hIEFwcGxpY2F0aW9uQXJncyAwCiAgICBtYXRjaCBfX3B1eWFfYXJjNF9yb3V0ZXJfX19ydW5fdGVzdHNfcm91dGVAMiBfX3B1eWFfYXJjNF9yb3V0ZXJfX19uZXN0ZWRfdHVwbGVfcGFyYW1zX3JvdXRlQDMKICAgIGludCAwCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX3J1bl90ZXN0c19yb3V0ZUAyOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjgKICAgIC8vIEBhcmM0LmFiaW1ldGhvZCgpCiAgICB0eG4gT25Db21wbGV0aW9uCiAgICAhCiAgICBhc3NlcnQgLy8gT25Db21wbGV0aW9uIGlzIE5vT3AKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICBhc3NlcnQgLy8gaXMgbm90IGNyZWF0aW5nCiAgICBjYWxsc3ViIHJ1bl90ZXN0cwogICAgYnl0ZSAweDAwCiAgICBpbnQgMAogICAgdW5jb3ZlciAyCiAgICBzZXRiaXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX25lc3RlZF90dXBsZV9wYXJhbXNfcm91dGVAMzoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTozNwogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIHR4biBPbkNvbXBsZXRpb24KICAgICEKICAgIGFzc2VydCAvLyBPbkNvbXBsZXRpb24gaXMgTm9PcAogICAgdHhuIEFwcGxpY2F0aW9uSUQKICAgIGFzc2VydCAvLyBpcyBub3QgY3JlYXRpbmcKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo0CiAgICAvLyBjbGFzcyBOZXN0ZWRUdXBsZXMoQVJDNENvbnRyYWN0KToKICAgIHR4bmEgQXBwbGljYXRpb25BcmdzIDEKICAgIGR1cAogICAgaW50IDAKICAgIGV4dHJhY3RfdWludDE2CiAgICBzd2FwCiAgICBkdXAKICAgIGludCAyCiAgICBleHRyYWN0X3VpbnQxNgogICAgZGlnIDEKICAgIHVuY292ZXIgMwogICAgZGlnIDIKICAgIHN1YnN0cmluZzMKICAgIGNvdmVyIDIKICAgIGRpZyAxCiAgICBsZW4KICAgIHN1YnN0cmluZzMKICAgIHN3YXAKICAgIGV4dHJhY3QgMiAwCiAgICBzd2FwCiAgICBkdXAKICAgIGludCAwCiAgICBleHRyYWN0X3VpbnQxNgogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIHN3YXAKICAgIGR1cAogICAgdW5jb3ZlciAzCiAgICB1bmNvdmVyIDMKICAgIHN1YnN0cmluZzMKICAgIHN3YXAKICAgIGV4dHJhY3QgMiA4IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgc3dhcAogICAgZXh0cmFjdCAyIDAKICAgIHN3YXAKICAgIGV4dHJhY3QgMCA4IC8vIG9uIGVycm9yOiBJbmRleCBhY2Nlc3MgaXMgb3V0IG9mIGJvdW5kcwogICAgYnRvaQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjM3CiAgICAvLyBAYXJjNC5hYmltZXRob2QoKQogICAgY2FsbHN1YiBuZXN0ZWRfdHVwbGVfcGFyYW1zCiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICBkdXAKICAgIGxlbgogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgZHVwCiAgICBsZW4KICAgIGl0b2IKICAgIGV4dHJhY3QgNiAyCiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgaXRvYgogICAgYnl0ZSAweDAwMGEKICAgIHN3YXAKICAgIGNvbmNhdAogICAgc3dhcAogICAgY29uY2F0CiAgICBkaWcgMQogICAgbGVuCiAgICBpbnQgNAogICAgKwogICAgaXRvYgogICAgZXh0cmFjdCA2IDIKICAgIGJ5dGUgMHgwMDA0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIHVuY292ZXIgMgogICAgY29uY2F0CiAgICBzd2FwCiAgICBjb25jYXQKICAgIGJ5dGUgMHgxNTFmN2M3NQogICAgc3dhcAogICAgY29uY2F0CiAgICBsb2cKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2JhcmVfcm91dGluZ0A2OgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjQKICAgIC8vIGNsYXNzIE5lc3RlZFR1cGxlcyhBUkM0Q29udHJhY3QpOgogICAgdHhuIE9uQ29tcGxldGlvbgogICAgYm56IF9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTAKICAgIHR4biBBcHBsaWNhdGlvbklECiAgICAhCiAgICBhc3NlcnQgLy8gaXMgY3JlYXRpbmcKICAgIGludCAxCiAgICByZXRzdWIKCl9fcHV5YV9hcmM0X3JvdXRlcl9fX2FmdGVyX2lmX2Vsc2VAMTA6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NAogICAgLy8gY2xhc3MgTmVzdGVkVHVwbGVzKEFSQzRDb250cmFjdCk6CiAgICBpbnQgMAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy50dXBsZV9zdXBwb3J0Lm5lc3RlZF90dXBsZXMuTmVzdGVkVHVwbGVzLnJ1bl90ZXN0cygpIC0+IHVpbnQ2NDoKcnVuX3Rlc3RzOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjgtOQogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBydW5fdGVzdHMoc2VsZikgLT4gYm9vbDoKICAgIHByb3RvIDAgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEwCiAgICAvLyB4ID0gKFN0cmluZygiSGkiKSwgU3RyaW5nKCJUaGVyZSIpKQogICAgYnl0ZSAiSGkiCiAgICBieXRlICJUaGVyZSIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMQogICAgLy8gYXNzZXJ0IHRlc3Rfc3dhcCh4KSA9PSAoU3RyaW5nKCJUaGVyZSIpLCBTdHJpbmcoIkhpIikpCiAgICBjYWxsc3ViIHRlc3Rfc3dhcAogICAgc3dhcAogICAgYnl0ZSAiVGhlcmUiCiAgICA9PQogICAgc3dhcAogICAgYnl0ZSAiSGkiCiAgICA9PQogICAgJiYKICAgIGFzc2VydAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEwCiAgICAvLyB4ID0gKFN0cmluZygiSGkiKSwgU3RyaW5nKCJUaGVyZSIpKQogICAgYnl0ZSAiSGkiCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTMKICAgIC8vIHogPSAoVUludDY0KDApLCBVSW50NjQoMiksIHkpCiAgICBpbnQgMAogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMgogICAgLy8geSA9IChVSW50NjQoMSksIHgpCiAgICBpbnQgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEwCiAgICAvLyB4ID0gKFN0cmluZygiSGkiKSwgU3RyaW5nKCJUaGVyZSIpKQogICAgYnl0ZSAiSGkiCiAgICBieXRlICJUaGVyZSIKICAgIGR1cAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE5CiAgICAvLyAoYSwgYiwgKGMsIGQsIChlLCkpKSA9IHRlc3RfcmVhcnJhbmdlKHhbMF0sIHosIHhbMV0pCiAgICBjYWxsc3ViIHRlc3RfcmVhcnJhbmdlCiAgICBjb3ZlciA0CiAgICBjb3ZlciAzCiAgICBjb3ZlciAyCiAgICBzd2FwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MjAKICAgIC8vIGFzc2VydCAoYSwgYikgPT0gKFN0cmluZygiSGkiKSwgVUludDY0KDApKQogICAgYnl0ZSAiSGkiCiAgICA9PQogICAgc3dhcAogICAgIQogICAgJiYKICAgIGFzc2VydAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjIxCiAgICAvLyBhc3NlcnQgKGMsIGQpID09IChVSW50NjQoMiksIFVJbnQ2NCgxKSkKICAgIGludCAyCiAgICA9PQogICAgc3dhcAogICAgaW50IDEKICAgID09CiAgICAmJgogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MjIKICAgIC8vIGFzc2VydCBlID09IFN0cmluZygiVGhlcmUiKQogICAgYnl0ZSAiVGhlcmUiCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MjQKICAgIC8vIHRlc3RfaW50cmluc2ljcyhVSW50NjQoMSksIFVJbnQ2NCgyKSkKICAgIGludCAxCiAgICBpbnQgMgogICAgY2FsbHN1YiB0ZXN0X2ludHJpbnNpY3MKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToyNgogICAgLy8gdGVzdF9uZXN0ZWRfc2luZ2xlcyhVSW50NjQoMSksIHJlYXNzaWduPVRydWUpCiAgICBpbnQgMQogICAgZHVwCiAgICBjYWxsc3ViIHRlc3RfbmVzdGVkX3NpbmdsZXMKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToyNwogICAgLy8gdGVzdF9uZXN0ZWRfc2luZ2xlcyhVSW50NjQoMSksIHJlYXNzaWduPUZhbHNlKQogICAgaW50IDEKICAgIGludCAwCiAgICBjYWxsc3ViIHRlc3RfbmVzdGVkX3NpbmdsZXMKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTozMgogICAgLy8gdGVzdF9uZXN0ZWRfaXRlcmF0aW9uKCkKICAgIGNhbGxzdWIgdGVzdF9uZXN0ZWRfaXRlcmF0aW9uCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MzQKICAgIC8vIHNlbGYudGVzdF9zaW5nbGVfZXZhbHVhdGlvbl9uZXN0ZWQoKQogICAgY2FsbHN1YiB0ZXN0X3NpbmdsZV9ldmFsdWF0aW9uX25lc3RlZAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjM1CiAgICAvLyByZXR1cm4gVHJ1ZQogICAgaW50IDEKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudHVwbGVfc3VwcG9ydC5uZXN0ZWRfdHVwbGVzLnRlc3Rfc3dhcChhcmdzLjA6IGJ5dGVzLCBhcmdzLjE6IGJ5dGVzKSAtPiBieXRlcywgYnl0ZXM6CnRlc3Rfc3dhcDoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo2Ni02NwogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiB0ZXN0X3N3YXAoYXJnczogdHVwbGVbU3RyaW5nLCBTdHJpbmddKSAtPiB0dXBsZVtTdHJpbmcsIFN0cmluZ106CiAgICBwcm90byAyIDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo2OQogICAgLy8gcmV0dXJuIGIsIGEKICAgIGZyYW1lX2RpZyAtMQogICAgZnJhbWVfZGlnIC0yCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy50ZXN0X3JlYXJyYW5nZShfYTogYnl0ZXMsIGFyZ3MuMDogdWludDY0LCBhcmdzLjE6IHVpbnQ2NCwgYXJncy4yLjA6IHVpbnQ2NCwgYXJncy4yLjEuMDogYnl0ZXMsIGFyZ3MuMi4xLjE6IGJ5dGVzLCBfYjogYnl0ZXMpIC0+IGJ5dGVzLCB1aW50NjQsIHVpbnQ2NCwgdWludDY0LCBieXRlczoKdGVzdF9yZWFycmFuZ2U6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NTctNjAKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgdGVzdF9yZWFycmFuZ2UoCiAgICAvLyAgICAgX2E6IFN0cmluZywgYXJnczogdHVwbGVbVUludDY0LCBVSW50NjQsIHR1cGxlW1VJbnQ2NCwgdHVwbGVbU3RyaW5nLCBTdHJpbmddXV0sIF9iOiBTdHJpbmcKICAgIC8vICkgLT4gdHVwbGVbU3RyaW5nLCBVSW50NjQsIHR1cGxlW1VJbnQ2NCwgVUludDY0LCB0dXBsZVtTdHJpbmddXV06CiAgICBwcm90byA3IDUKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo2MwogICAgLy8gcmV0dXJuIGQsIGEsIChiLCBjLCAoZSwpKQogICAgZnJhbWVfZGlnIC0zCiAgICBmcmFtZV9kaWcgLTYKICAgIGZyYW1lX2RpZyAtNQogICAgZnJhbWVfZGlnIC00CiAgICBmcmFtZV9kaWcgLTIKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudHVwbGVfc3VwcG9ydC5uZXN0ZWRfdHVwbGVzLnRlc3RfaW50cmluc2ljcyhudW0xOiB1aW50NjQsIG51bTI6IHVpbnQ2NCkgLT4gdm9pZDoKdGVzdF9pbnRyaW5zaWNzOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjcyLTczCiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHRlc3RfaW50cmluc2ljcyhudW0xOiBVSW50NjQsIG51bTI6IFVJbnQ2NCkgLT4gTm9uZToKICAgIHByb3RvIDIgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5Ojc0CiAgICAvLyBudCA9IChVSW50NjQoMSksIG9wLmFkZHcobnVtMSwgbnVtMiksIFVJbnQ2NCg0MikpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMQogICAgYWRkdwogICAgc3dhcAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5Ojc3CiAgICAvLyBhc3NlcnQgbnRbMV0gPT0gKDAsIG51bTEgKyBudW0yKSAgIyB0eXBlOiBpZ25vcmVbY29tcGFyaXNvbi1vdmVybGFwXQogICAgIQogICAgc3dhcAogICAgZnJhbWVfZGlnIC0yCiAgICBmcmFtZV9kaWcgLTEKICAgICsKICAgID09CiAgICBkdXAyCiAgICAmJgogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NzgKICAgIC8vIGFzc2VydCBudFsxXVs6MV0gPT0gKDAsKSAgIyB0eXBlOiBpZ25vcmVbY29tcGFyaXNvbi1vdmVybGFwXQogICAgc3dhcAogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NzkKICAgIC8vIGFzc2VydCBudFsxXVsxOl0gPT0gKG51bTEgKyBudW0yLCkKICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy50dXBsZV9zdXBwb3J0Lm5lc3RlZF90dXBsZXMudGVzdF9uZXN0ZWRfc2luZ2xlcyhvbmU6IHVpbnQ2NCwgcmVhc3NpZ246IHVpbnQ2NCkgLT4gdm9pZDoKdGVzdF9uZXN0ZWRfc2luZ2xlczoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMDctMTA4CiAgICAvLyBAc3Vicm91dGluZQogICAgLy8gZGVmIHRlc3RfbmVzdGVkX3NpbmdsZXMob25lOiBVSW50NjQsICosIHJlYXNzaWduOiBib29sKSAtPiBOb25lOgogICAgcHJvdG8gMiAwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTEwCiAgICAvLyAoVUludDY0KDApLCksCiAgICBpbnQgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjExMgogICAgLy8gKFVJbnQ2NCgyKSwpLAogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMTYKICAgIC8vIGFzc2VydCBzWzFdWzBdID09IDEKICAgIGZyYW1lX2RpZyAtMgogICAgaW50IDEKICAgID09CiAgICBhc3NlcnQKICAgIGZyYW1lX2RpZyAtMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEyMQogICAgLy8gaWYgcmVhc3NpZ246CiAgICBmcmFtZV9kaWcgLTEKICAgIGJ6IHRlc3RfbmVzdGVkX3NpbmdsZXNfYWZ0ZXJfaWZfZWxzZUAyCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTIzCiAgICAvLyAoVUludDY0KDMpLCksCiAgICBpbnQgMwogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEyMi0xMjYKICAgIC8vIHMgPSAoCiAgICAvLyAgICAgKFVJbnQ2NCgzKSwpLAogICAgLy8gICAgIChVSW50NjQoNCksKSwKICAgIC8vICAgICAoVUludDY0KDUpLCksCiAgICAvLyApCiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMjQKICAgIC8vIChVSW50NjQoNCksKSwKICAgIGludCA0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTIyLTEyNgogICAgLy8gcyA9ICgKICAgIC8vICAgICAoVUludDY0KDMpLCksCiAgICAvLyAgICAgKFVJbnQ2NCg0KSwpLAogICAgLy8gICAgIChVSW50NjQoNSksKSwKICAgIC8vICkKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEyNQogICAgLy8gKFVJbnQ2NCg1KSwpLAogICAgaW50IDUKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMjItMTI2CiAgICAvLyBzID0gKAogICAgLy8gICAgIChVSW50NjQoMyksKSwKICAgIC8vICAgICAoVUludDY0KDQpLCksCiAgICAvLyAgICAgKFVJbnQ2NCg1KSwpLAogICAgLy8gKQogICAgZnJhbWVfYnVyeSAxCgp0ZXN0X25lc3RlZF9zaW5nbGVzX2FmdGVyX2lmX2Vsc2VAMjoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMjcKICAgIC8vIGFzc2VydCBzWzBdWzBdID09ICgzIGlmIHJlYXNzaWduIGVsc2UgMCkKICAgIGZyYW1lX2RpZyAtMQogICAgaW50IDMKICAgICoKICAgIGZyYW1lX2RpZyAwCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTI5CiAgICAvLyBhc3NlcnQgdG1wID09ICg1IGlmIHJlYXNzaWduIGVsc2UgMikKICAgIGludCAyCiAgICBpbnQgNQogICAgZnJhbWVfZGlnIC0xCiAgICBzZWxlY3QKICAgIGZyYW1lX2RpZyAxCiAgICBkaWcgMQogICAgPT0KICAgIGFzc2VydAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjEzMwogICAgLy8gczEgKz0gb25lCiAgICBmcmFtZV9kaWcgMgogICAgZHVwCiAgICBjb3ZlciAyCiAgICBmcmFtZV9kaWcgLTIKICAgICsKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxMzQKICAgIC8vIGFzc2VydCBzMSA9PSAoNSBpZiByZWFzc2lnbiBlbHNlIDIpCiAgICA9PQogICAgYXNzZXJ0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTM1CiAgICAvLyBhc3NlcnQgc1sxXVswXSA9PSAoNCBpZiByZWFzc2lnbiBlbHNlIDEpCiAgICBpbnQgMQogICAgaW50IDQKICAgIGZyYW1lX2RpZyAtMQogICAgc2VsZWN0CiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy50ZXN0X25lc3RlZF9pdGVyYXRpb24oKSAtPiB2b2lkOgp0ZXN0X25lc3RlZF9pdGVyYXRpb246CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTUxLTE1MgogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiB0ZXN0X25lc3RlZF9pdGVyYXRpb24oKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICBieXRlICIiCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU1CiAgICAvLyB0b3RhbCA9IFVJbnQ2NCgwKQogICAgaW50IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTMKICAgIC8vIHggPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU0CiAgICAvLyB5ID0gVUludDY0KDIpCiAgICBpbnQgMgogICAgaW50IDAKCnRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9mb3JfYm9keUAxOgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1OQogICAgLy8gdG90YWwgKz0gYSArIGIKICAgIGZyYW1lX2RpZyAyCiAgICB1bmNvdmVyIDIKICAgICsKICAgIGZyYW1lX2RpZyAxCiAgICArCiAgICBmcmFtZV9idXJ5IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTcKICAgIC8vIGZvciB0IGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dpdGNoIHRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9mb3JfaGVhZGVyXzFAMyB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2hlYWRlcl8yQDQgdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfM0A1CiAgICBiIHRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9hZnRlcl9mb3JANgoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfMUAzOgogICAgaW50IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTQKICAgIC8vIHkgPSBVSW50NjQoMikKICAgIGludCAyCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU3CiAgICAvLyBmb3IgdCBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1MwogICAgLy8geCA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTcKICAgIC8vIGZvciB0IGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2JvZHlAMQoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfMkA0OgogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTMKICAgIC8vIHggPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU3CiAgICAvLyBmb3IgdCBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1MwogICAgLy8geCA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTcKICAgIC8vIGZvciB0IGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2JvZHlAMQoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfM0A1OgogICAgaW50IDMKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTQKICAgIC8vIHkgPSBVSW50NjQoMikKICAgIGludCAyCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU3CiAgICAvLyBmb3IgdCBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1NAogICAgLy8geSA9IFVJbnQ2NCgyKQogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTcKICAgIC8vIGZvciB0IGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2JvZHlAMQoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2FmdGVyX2ZvckA2OgogICAgaW50IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTMKICAgIC8vIHggPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTYxCiAgICAvLyBmb3IgYSwgYiBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1NAogICAgLy8geSA9IFVJbnQ2NCgyKQogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNjEKICAgIC8vIGZvciBhLCBiIGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9ib2R5QDc6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTYyCiAgICAvLyB0b3RhbCArPSBhICsgYgogICAgZnJhbWVfZGlnIDAKICAgIHVuY292ZXIgMgogICAgKwogICAgZnJhbWVfZGlnIDEKICAgICsKICAgIGZyYW1lX2J1cnkgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE2MQogICAgLy8gZm9yIGEsIGIgaW4gKCh4LCB5KSwgKHksIHgpLCAoeCwgeCksICh5LCB5KSk6CiAgICBzd2l0Y2ggdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfMUA5IHRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9mb3JfaGVhZGVyXzJAMTAgdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfM0AxMQogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fYWZ0ZXJfZm9yQDEyCgp0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2hlYWRlcl8xQDk6CiAgICBpbnQgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1NAogICAgLy8geSA9IFVJbnQ2NCgyKQogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNjEKICAgIC8vIGZvciBhLCBiIGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgZnJhbWVfYnVyeSAwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTUzCiAgICAvLyB4ID0gVUludDY0KDEpCiAgICBpbnQgMQogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE2MQogICAgLy8gZm9yIGEsIGIgaW4gKCh4LCB5KSwgKHksIHgpLCAoeCwgeCksICh5LCB5KSk6CiAgICBzd2FwCiAgICBiIHRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9mb3JfYm9keUA3Cgp0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2hlYWRlcl8yQDEwOgogICAgaW50IDIKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTMKICAgIC8vIHggPSBVSW50NjQoMSkKICAgIGludCAxCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTYxCiAgICAvLyBmb3IgYSwgYiBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIGZyYW1lX2J1cnkgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE1MwogICAgLy8geCA9IFVJbnQ2NCgxKQogICAgaW50IDEKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNjEKICAgIC8vIGZvciBhLCBiIGluICgoeCwgeSksICh5LCB4KSwgKHgsIHgpLCAoeSwgeSkpOgogICAgc3dhcAogICAgYiB0ZXN0X25lc3RlZF9pdGVyYXRpb25fZm9yX2JvZHlANwoKdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9oZWFkZXJfM0AxMToKICAgIGludCAzCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTU0CiAgICAvLyB5ID0gVUludDY0KDIpCiAgICBpbnQgMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjE2MQogICAgLy8gZm9yIGEsIGIgaW4gKCh4LCB5KSwgKHksIHgpLCAoeCwgeCksICh5LCB5KSk6CiAgICBmcmFtZV9idXJ5IDAKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weToxNTQKICAgIC8vIHkgPSBVSW50NjQoMikKICAgIGludCAyCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTYxCiAgICAvLyBmb3IgYSwgYiBpbiAoKHgsIHkpLCAoeSwgeCksICh4LCB4KSwgKHksIHkpKToKICAgIHN3YXAKICAgIGIgdGVzdF9uZXN0ZWRfaXRlcmF0aW9uX2Zvcl9ib2R5QDcKCnRlc3RfbmVzdGVkX2l0ZXJhdGlvbl9hZnRlcl9mb3JAMTI6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6MTY0CiAgICAvLyBhc3NlcnQgdG90YWwgLy8gOCA9PSAzCiAgICBmcmFtZV9kaWcgMQogICAgaW50IDgKICAgIC8KICAgIGludCAzCiAgICA9PQogICAgYXNzZXJ0CiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy5OZXN0ZWRUdXBsZXMudGVzdF9zaW5nbGVfZXZhbHVhdGlvbl9uZXN0ZWQoKSAtPiB2b2lkOgp0ZXN0X3NpbmdsZV9ldmFsdWF0aW9uX25lc3RlZDoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo0OS01MAogICAgLy8gQHN1YnJvdXRpbmUKICAgIC8vIGRlZiB0ZXN0X3NpbmdsZV9ldmFsdWF0aW9uX25lc3RlZChzZWxmKSAtPiBOb25lOgogICAgcHJvdG8gMCAwCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NTEKICAgIC8vIHNlbGYuYnVpbGRfbmVzdGVkX2NhbGxfY291bnQgPSBVSW50NjQoMCkKICAgIGJ5dGUgImJ1aWxkX25lc3RlZF9jYWxsX2NvdW50IgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NTIKICAgIC8vIHJlc3VsdCA9IHNlbGYuYnVpbGRfbmVzdGVkKCkgb3Igc2VsZi5idWlsZF9uZXN0ZWQoKQogICAgY2FsbHN1YiBidWlsZF9uZXN0ZWQKICAgIHBvcG4gMgogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjUzCiAgICAvLyBhc3NlcnQgcmVzdWx0WzBdWzBdID09ICJoaSIKICAgIGJ5dGUgImhpIgogICAgPT0KICAgIGFzc2VydAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjU0CiAgICAvLyBhc3NlcnQgc2VsZi5idWlsZF9uZXN0ZWRfY2FsbF9jb3VudCA9PSAxCiAgICBpbnQgMAogICAgYnl0ZSAiYnVpbGRfbmVzdGVkX2NhbGxfY291bnQiCiAgICBhcHBfZ2xvYmFsX2dldF9leAogICAgYXNzZXJ0IC8vIGNoZWNrIHNlbGYuYnVpbGRfbmVzdGVkX2NhbGxfY291bnQgZXhpc3RzCiAgICBpbnQgMQogICAgPT0KICAgIGFzc2VydAogICAgcmV0c3ViCgoKLy8gdGVzdF9jYXNlcy50dXBsZV9zdXBwb3J0Lm5lc3RlZF90dXBsZXMuTmVzdGVkVHVwbGVzLmJ1aWxkX25lc3RlZCgpIC0+IGJ5dGVzLCB1aW50NjQsIGJ5dGVzOgpidWlsZF9uZXN0ZWQ6CiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NDQtNDUKICAgIC8vIEBzdWJyb3V0aW5lCiAgICAvLyBkZWYgYnVpbGRfbmVzdGVkKHNlbGYpIC0+IHR1cGxlW3R1cGxlW1N0cmluZywgVUludDY0XSwgQnl0ZXNdOgogICAgcHJvdG8gMCAzCiAgICAvLyB0dXBsZV9zdXBwb3J0L25lc3RlZF90dXBsZXMucHk6NDYKICAgIC8vIHNlbGYuYnVpbGRfbmVzdGVkX2NhbGxfY291bnQgKz0gMQogICAgaW50IDAKICAgIGJ5dGUgImJ1aWxkX25lc3RlZF9jYWxsX2NvdW50IgogICAgYXBwX2dsb2JhbF9nZXRfZXgKICAgIGFzc2VydCAvLyBjaGVjayBzZWxmLmJ1aWxkX25lc3RlZF9jYWxsX2NvdW50IGV4aXN0cwogICAgaW50IDEKICAgICsKICAgIGJ5dGUgImJ1aWxkX25lc3RlZF9jYWxsX2NvdW50IgogICAgc3dhcAogICAgYXBwX2dsb2JhbF9wdXQKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo0NwogICAgLy8gcmV0dXJuIChTdHJpbmcoImhpIiksIFVJbnQ2NCgxKSksIEJ5dGVzKGIiaG1tbSIpCiAgICBieXRlICJoaSIKICAgIGludCAxCiAgICBieXRlIDB4Njg2ZDZkNmQKICAgIHJldHN1YgoKCi8vIHRlc3RfY2FzZXMudHVwbGVfc3VwcG9ydC5uZXN0ZWRfdHVwbGVzLk5lc3RlZFR1cGxlcy5uZXN0ZWRfdHVwbGVfcGFyYW1zKGFyZ3MuMDogYnl0ZXMsIGFyZ3MuMS4wOiBieXRlcywgYXJncy4xLjEuMDogdWludDY0KSAtPiBieXRlcywgYnl0ZXMsIHVpbnQ2NDoKbmVzdGVkX3R1cGxlX3BhcmFtczoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTozNy00MAogICAgLy8gQGFyYzQuYWJpbWV0aG9kKCkKICAgIC8vIGRlZiBuZXN0ZWRfdHVwbGVfcGFyYW1zKAogICAgLy8gICAgIHNlbGYsIGFyZ3M6IHR1cGxlW1N0cmluZywgdHVwbGVbQnl0ZXMsIHR1cGxlW1VJbnQ2NF1dXQogICAgLy8gKSAtPiB0dXBsZVtCeXRlcywgdHVwbGVbU3RyaW5nLCBVSW50NjRdXToKICAgIHByb3RvIDMgMwogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjQyCiAgICAvLyByZXR1cm4gYiwgKHMsIHUpCiAgICBmcmFtZV9kaWcgLTIKICAgIGZyYW1lX2RpZyAtMwogICAgZnJhbWVfZGlnIC0xCiAgICByZXRzdWIKCgovLyB0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy5OZXN0ZWRUdXBsZXMuX19pbml0X18oKSAtPiB2b2lkOgpfX2luaXRfXzoKICAgIC8vIHR1cGxlX3N1cHBvcnQvbmVzdGVkX3R1cGxlcy5weTo1CiAgICAvLyBkZWYgX19pbml0X18oc2VsZikgLT4gTm9uZToKICAgIHByb3RvIDAgMAogICAgLy8gdHVwbGVfc3VwcG9ydC9uZXN0ZWRfdHVwbGVzLnB5OjYKICAgIC8vIHNlbGYuYnVpbGRfbmVzdGVkX2NhbGxfY291bnQgPSBVSW50NjQoMCkKICAgIGJ5dGUgImJ1aWxkX25lc3RlZF9jYWxsX2NvdW50IgogICAgaW50IDAKICAgIGFwcF9nbG9iYWxfcHV0CiAgICByZXRzdWIK", "clear": "I3ByYWdtYSB2ZXJzaW9uIDEwCgp0ZXN0X2Nhc2VzLnR1cGxlX3N1cHBvcnQubmVzdGVkX3R1cGxlcy5OZXN0ZWRUdXBsZXMuY2xlYXJfc3RhdGVfcHJvZ3JhbToKICAgIGludCAxCiAgICByZXR1cm4K" }, "state": { diff --git a/test_cases/tuple_support/out/TupleSupport.approval.mir b/test_cases/tuple_support/out/TupleSupport.approval.mir index 55320fd084..8f30bdbf68 100644 --- a/test_cases/tuple_support/out/TupleSupport.approval.mir +++ b/test_cases/tuple_support/out/TupleSupport.approval.mir @@ -30,7 +30,7 @@ main_entrypoint@2: addw // {addw}.0,{addw}.1 op.addw(a, b) tuple_support/tuple_support.py:12 // virtual: store result.1#0 to l-stack (no copy) result.1#0,{addw}.0 op.addw(a, b) tuple_support/tuple_support.py:12 // virtual: store did_overflow#0 to l-stack (no copy) did_overflow#0,result.1#0 op.addw(a, b) tuple_support/tuple_support.py:12 - byte "state" // did_overflow#0,result.1#0,"state" self.state tuple_support/tuple_support.py:6 + byte "state" // did_overflow#0,result.1#0,"state" self.state tuple_support/tuple_support.py:12 dig 1 // load result.1#0 from l-stack (copy) did_overflow#0,result.1#0,"state",result.1#0 (did_overflow, self.state) = op.addw(a, b) tuple_support/tuple_support.py:12 app_global_put // did_overflow#0,result.1#0 (did_overflow, self.state) = op.addw(a, b) tuple_support/tuple_support.py:12 dig 1 // load did_overflow#0 from l-stack (copy) did_overflow#0,result.1#0,did_overflow#0 not did_overflow tuple_support/tuple_support.py:13 diff --git a/test_cases/tuple_support/out/TupleSupport.approval.teal b/test_cases/tuple_support/out/TupleSupport.approval.teal index 52056a1f0d..167a705f63 100644 --- a/test_cases/tuple_support/out/TupleSupport.approval.teal +++ b/test_cases/tuple_support/out/TupleSupport.approval.teal @@ -23,11 +23,7 @@ main_entrypoint@2: // tuple_support/tuple_support.py:12 // (did_overflow, self.state) = op.addw(a, b) addw - // tuple_support/tuple_support.py:6 - // self.state = UInt64(0) byte "state" - // tuple_support/tuple_support.py:12 - // (did_overflow, self.state) = op.addw(a, b) dig 1 app_global_put // tuple_support/tuple_support.py:13 diff --git a/test_cases/tuple_support/out_unoptimized/NestedTuples.approval.teal b/test_cases/tuple_support/out_unoptimized/NestedTuples.approval.teal index 3a3d782732..ec4194b31c 100644 --- a/test_cases/tuple_support/out_unoptimized/NestedTuples.approval.teal +++ b/test_cases/tuple_support/out_unoptimized/NestedTuples.approval.teal @@ -874,11 +874,9 @@ test_single_evaluation_nested: // @subroutine // def test_single_evaluation_nested(self) -> None: proto 0 0 - // tuple_support/nested_tuples.py:6 - // self.build_nested_call_count = UInt64(0) - byte "build_nested_call_count" // tuple_support/nested_tuples.py:51 // self.build_nested_call_count = UInt64(0) + byte "build_nested_call_count" int 0 app_global_put // tuple_support/nested_tuples.py:52 @@ -919,11 +917,7 @@ test_single_evaluation_nested_ternary_merge@3: // tuple_support/nested_tuples.py:54 // assert self.build_nested_call_count == 1 int 0 - // tuple_support/nested_tuples.py:6 - // self.build_nested_call_count = UInt64(0) byte "build_nested_call_count" - // tuple_support/nested_tuples.py:54 - // assert self.build_nested_call_count == 1 app_global_get_ex assert // check self.build_nested_call_count exists int 1 @@ -941,20 +935,12 @@ build_nested: // tuple_support/nested_tuples.py:46 // self.build_nested_call_count += 1 int 0 - // tuple_support/nested_tuples.py:6 - // self.build_nested_call_count = UInt64(0) byte "build_nested_call_count" - // tuple_support/nested_tuples.py:46 - // self.build_nested_call_count += 1 app_global_get_ex assert // check self.build_nested_call_count exists int 1 + - // tuple_support/nested_tuples.py:6 - // self.build_nested_call_count = UInt64(0) byte "build_nested_call_count" - // tuple_support/nested_tuples.py:46 - // self.build_nested_call_count += 1 uncover 1 app_global_put // tuple_support/nested_tuples.py:47 diff --git a/test_cases/tuple_support/out_unoptimized/TupleSupport.approval.teal b/test_cases/tuple_support/out_unoptimized/TupleSupport.approval.teal index 2569b23756..b579d4e2d5 100644 --- a/test_cases/tuple_support/out_unoptimized/TupleSupport.approval.teal +++ b/test_cases/tuple_support/out_unoptimized/TupleSupport.approval.teal @@ -26,11 +26,7 @@ main_entrypoint@2: // (did_overflow, self.state) = op.addw(a, b) addw cover 1 - // tuple_support/tuple_support.py:6 - // self.state = UInt64(0) byte "state" - // tuple_support/tuple_support.py:12 - // (did_overflow, self.state) = op.addw(a, b) uncover 2 app_global_put // tuple_support/tuple_support.py:13