From 7122dfa87df99e1c66f7f0f6d6232c3d802adbb3 Mon Sep 17 00:00:00 2001 From: Joe Polny Date: Thu, 3 Aug 2023 15:42:30 -0400 Subject: [PATCH 1/4] raffle example --- examples/raffle/artifacts/NFTRaffle.abi.json | 108 ++++ .../raffle/artifacts/NFTRaffle.approval.teal | 529 ++++++++++++++++++ .../raffle/artifacts/NFTRaffle.clear.teal | 2 + examples/raffle/artifacts/NFTRaffle.json | 207 +++++++ .../raffle/artifacts/NFTRaffle.src_map.json | 22 + examples/raffle/raffle.algo.ts | 184 ++++++ examples/raffle/tsconfig.json | 103 ++++ package.json | 3 +- 8 files changed, 1157 insertions(+), 1 deletion(-) create mode 100644 examples/raffle/artifacts/NFTRaffle.abi.json create mode 100644 examples/raffle/artifacts/NFTRaffle.approval.teal create mode 100644 examples/raffle/artifacts/NFTRaffle.clear.teal create mode 100644 examples/raffle/artifacts/NFTRaffle.json create mode 100644 examples/raffle/artifacts/NFTRaffle.src_map.json create mode 100644 examples/raffle/raffle.algo.ts create mode 100644 examples/raffle/tsconfig.json diff --git a/examples/raffle/artifacts/NFTRaffle.abi.json b/examples/raffle/artifacts/NFTRaffle.abi.json new file mode 100644 index 000000000..cc4204984 --- /dev/null +++ b/examples/raffle/artifacts/NFTRaffle.abi.json @@ -0,0 +1,108 @@ +{ + "name": "NFTRaffle", + "desc": "", + "methods": [ + { + "name": "createApplication", + "args": [ + { + "name": "ticketPrice", + "type": "uint64", + "desc": "The price of a single ticket (uALGO)" + }, + { + "name": "randomnessOracle", + "type": "uint64", + "desc": "The app ID of the randomness oracle" + } + ], + "desc": "Create the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "setAsset", + "args": [ + { + "name": "asset", + "type": "asset", + "desc": "The asset to be raffled" + } + ], + "desc": "Set the asset to be raffled", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "startRaffle", + "args": [ + { + "name": "end", + "type": "uint64", + "desc": "The round number when the raffle ends" + }, + { + "name": "draw", + "type": "uint64", + "desc": "The round number when the raffle is drawn" + } + ], + "desc": "Start the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "buyTickets", + "args": [ + { + "name": "payment", + "type": "pay", + "desc": "The payment for the tickets" + }, + { + "name": "quanity", + "type": "uint64", + "desc": "The number of tickets to buy" + } + ], + "desc": "Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed.", + "returns": { + "type": "void", + "desc": "The total number of tickets owned by the sender" + } + }, + { + "name": "draw", + "args": [], + "desc": "Draw the winning ticket", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "claim", + "args": [], + "desc": "Send the asset to the the sender if they have the winning ticket", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "getRefund", + "args": [], + "desc": "Allows purchasers to get a refund if the winning ticket has not been drawnand 1512 rounds have passed since the draw round, meaning the oracle nolonger has the data for the draw round", + "returns": { + "type": "void", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/examples/raffle/artifacts/NFTRaffle.approval.teal b/examples/raffle/artifacts/NFTRaffle.approval.teal new file mode 100644 index 000000000..c1eb841ef --- /dev/null +++ b/examples/raffle/artifacts/NFTRaffle.approval.teal @@ -0,0 +1,529 @@ +#pragma version 9 + +txn ApplicationID +int 0 +> +int 6 +* +txn OnCompletion ++ +switch create_NoOp NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED call_NoOp + +NOT_IMPLEMENTED: + err + +abi_route_createApplication: + // no dupn needed + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 1 + btoi + callsub createApplication + int 1 + return + +createApplication: + proto 2 0 + + // examples/raffle/raffle.algo.ts:39 + // this.randomnessOracle.value = randomnessOracle + byte "randomnessOracle" + frame_dig -2 // randomnessOracle: uint64 + app_global_put + + // examples/raffle/raffle.algo.ts:40 + // this.ticketPrice.value = ticketPrice + byte "ticketPrice" + frame_dig -1 // ticketPrice: uint64 + app_global_put + retsub + +abi_route_setAsset: + // no dupn needed + txna ApplicationArgs 1 + btoi + txnas Assets + callsub setAsset + int 1 + return + +setAsset: + proto 1 0 + + // examples/raffle/raffle.algo.ts:50 + // assert(!this.asset.exists) + txna Applications 0 + byte "asset" + app_global_get_ex + swap + pop + ! + assert + + // examples/raffle/raffle.algo.ts:52 + // sendAssetTransfer({ + itxn_begin + int axfer + itxn_field TypeEnum + + // examples/raffle/raffle.algo.ts:53 + // assetReceiver: this.app.address + txna Applications 0 + app_params_get AppAddress + assert + itxn_field AssetReceiver + + // examples/raffle/raffle.algo.ts:54 + // xferAsset: asset + frame_dig -1 // asset: asset + itxn_field XferAsset + + // examples/raffle/raffle.algo.ts:55 + // assetAmount: 0 + int 0 + itxn_field AssetAmount + + // examples/raffle/raffle.algo.ts:56 + // fee: 0 + int 0 + itxn_field Fee + itxn_submit + + // examples/raffle/raffle.algo.ts:59 + // this.asset.value = asset + byte "asset" + frame_dig -1 // asset: asset + app_global_put + retsub + +abi_route_startRaffle: + // no dupn needed + txna ApplicationArgs 2 + btoi + txna ApplicationArgs 1 + btoi + callsub startRaffle + int 1 + return + +startRaffle: + proto 2 0 + + // examples/raffle/raffle.algo.ts:70 + // assert(this.app.address.assetBalance(this.asset.value) > 0) + txna Applications 0 + app_params_get AppAddress + assert + byte "asset" + app_global_get + asset_holding_get AssetBalance + assert + int 0 + > + assert + + // examples/raffle/raffle.algo.ts:72 + // assert(draw > end) + frame_dig -2 // draw: uint64 + frame_dig -1 // end: uint64 + > + assert + + // examples/raffle/raffle.algo.ts:73 + // this.endRound.value = end + byte "endRound" + frame_dig -1 // end: uint64 + app_global_put + + // examples/raffle/raffle.algo.ts:74 + // this.drawRound.value = draw + byte "drawRound" + frame_dig -2 // draw: uint64 + app_global_put + retsub + +abi_route_buyTickets: + byte 0x + txna ApplicationArgs 1 + btoi + txn GroupIndex + int 1 + - + dup + gtxns TypeEnum + int pay + == + assert + callsub buyTickets + int 1 + return + +buyTickets: + proto 3 0 + + // examples/raffle/raffle.algo.ts:88 + // assert(globals.round < this.endRound.value) + global Round + byte "endRound" + app_global_get + < + assert + + // examples/raffle/raffle.algo.ts:89 + // assert(quanity > 0) + frame_dig -2 // quanity: uint64 + int 0 + > + assert + + // examples/raffle/raffle.algo.ts:91 + // assert(payment.amount === this.ticketPrice.value * quanity) + frame_dig -1 // payment: pay + gtxns Amount + byte "ticketPrice" + app_global_get + frame_dig -2 // quanity: uint64 + * + == + assert + + // examples/raffle/raffle.algo.ts:92 + // assert(payment.sender === this.txn.sender) + frame_dig -1 // payment: pay + gtxns Sender + txn Sender + == + assert + + // examples/raffle/raffle.algo.ts:93 + // assert(payment.receiver === this.app.address) + frame_dig -1 // payment: pay + gtxns Receiver + txna Applications 0 + app_params_get AppAddress + assert + == + assert + + // examples/raffle/raffle.algo.ts:95 + // assert(!this.tickets(payment.sender).exists) + frame_dig -1 // payment: pay + gtxns Sender + box_len + swap + pop + ! + assert + + // examples/raffle/raffle.algo.ts:97 + // newTotal = this.totalTickets.value + quanity + 1 + byte "totalTickets" + app_global_get + frame_dig -2 // quanity: uint64 + + + int 1 + + + frame_bury -3 // newTotal: uint64 + + // examples/raffle/raffle.algo.ts:99 + // this.tickets(payment.sender).value = { start: this.totalTickets.value, end: newTotal - 1 } + frame_dig -1 // payment: pay + gtxns Sender + byte "totalTickets" + app_global_get + itob + frame_dig -3 // newTotal: uint64 + int 1 + - + itob + concat + box_put + + // examples/raffle/raffle.algo.ts:100 + // this.totalTickets.value = newTotal + byte "totalTickets" + frame_dig -3 // newTotal: uint64 + app_global_put + retsub + +abi_route_draw: + byte 0x + callsub draw + int 1 + return + +draw: + proto 1 0 + + // examples/raffle/raffle.algo.ts:105 + // assert(!this.winningTicket.exists) + txna Applications 0 + byte "winningTicket" + app_global_get_ex + swap + pop + ! + assert + + // examples/raffle/raffle.algo.ts:107 + // output = sendMethodCall<[uint64, bytes], bytes>({ + itxn_begin + int appl + itxn_field TypeEnum + method "must_get(uint64,byte[])byte[]" + itxn_field ApplicationArgs + + // examples/raffle/raffle.algo.ts:109 + // methodArgs: [this.drawRound.value, ''] + byte "drawRound" + app_global_get + itob + itxn_field ApplicationArgs + byte "" + dup + len + itob + extract 6 2 + swap + concat + itxn_field ApplicationArgs + + // examples/raffle/raffle.algo.ts:110 + // applicationID: Application.fromIndex(this.randomnessOracle.value) + byte "randomnessOracle" + app_global_get + itxn_field ApplicationID + + // examples/raffle/raffle.algo.ts:111 + // fee: 0 + int 0 + itxn_field Fee + + // examples/raffle/raffle.algo.ts:112 + // onCompletion: 'NoOp' + int NoOp + itxn_field OnCompletion + itxn_submit + itxn NumLogs + int 1 + - + itxnas Logs + extract 4 0 + frame_bury -1 // output: bytes + + // examples/raffle/raffle.algo.ts:119 + // this.winningTicket.value = btobigint(output) % this.totalTickets.value + byte "winningTicket" + frame_dig -1 // output: bytes + byte "totalTickets" + app_global_get + itob + b% + btoi + app_global_put + retsub + +abi_route_claim: + byte 0x + callsub claim + int 1 + return + +claim: + proto 1 0 + + // examples/raffle/raffle.algo.ts:124 + // ticketRange = this.tickets(this.txn.sender).value + txn Sender + frame_bury -1 // storage key//ticketRange + + // examples/raffle/raffle.algo.ts:126 + // assert(ticketRange.start <= this.winningTicket.value) + frame_dig -1 // storage key//ticketRange + box_get + assert + store 0 // full array + int 0 // initial offset + int 0 // headOffset + + + load 0 // full array + swap + int 8 + extract3 + btoi + byte "winningTicket" + app_global_get + <= + assert + + // examples/raffle/raffle.algo.ts:127 + // assert(ticketRange.end >= this.winningTicket.value) + frame_dig -1 // storage key//ticketRange + box_get + assert + store 0 // full array + int 0 // initial offset + int 8 // headOffset + + + load 0 // full array + swap + int 8 + extract3 + btoi + byte "winningTicket" + app_global_get + >= + assert + + // examples/raffle/raffle.algo.ts:129 + // sendAssetTransfer({ + itxn_begin + int axfer + itxn_field TypeEnum + + // examples/raffle/raffle.algo.ts:130 + // assetReceiver: this.txn.sender + txn Sender + itxn_field AssetReceiver + + // examples/raffle/raffle.algo.ts:131 + // xferAsset: this.asset.value + byte "asset" + app_global_get + itxn_field XferAsset + + // examples/raffle/raffle.algo.ts:132 + // assetAmount: this.app.address.assetBalance(this.asset.value) + txna Applications 0 + app_params_get AppAddress + assert + byte "asset" + app_global_get + asset_holding_get AssetBalance + assert + itxn_field AssetAmount + + // examples/raffle/raffle.algo.ts:133 + // assetCloseTo: this.txn.sender + txn Sender + itxn_field AssetCloseTo + + // examples/raffle/raffle.algo.ts:134 + // fee: 0 + int 0 + itxn_field Fee + itxn_submit + retsub + +abi_route_getRefund: + byte 0x; dup + callsub getRefund + int 1 + return + +getRefund: + proto 2 0 + + // examples/raffle/raffle.algo.ts:144 + // assert(!this.winningTicket.exists) + txna Applications 0 + byte "winningTicket" + app_global_get_ex + swap + pop + ! + assert + + // examples/raffle/raffle.algo.ts:145 + // assert(globals.round > this.drawRound.value + 1512) + global Round + byte "drawRound" + app_global_get + int 1512 + + + > + assert + + // examples/raffle/raffle.algo.ts:147 + // ticketRange = this.tickets(this.txn.sender).value + txn Sender + frame_bury -1 // storage key//ticketRange + + // examples/raffle/raffle.algo.ts:148 + // ticketCount = ticketRange.end - ticketRange.start + 1 + frame_dig -1 // storage key//ticketRange + box_get + assert + store 0 // full array + int 0 // initial offset + int 8 // headOffset + + + load 0 // full array + swap + int 8 + extract3 + btoi + frame_dig -1 // storage key//ticketRange + box_get + assert + store 0 // full array + int 0 // initial offset + int 0 // headOffset + + + load 0 // full array + swap + int 8 + extract3 + btoi + - + int 1 + + + frame_bury -2 // ticketCount: uint64 + + // examples/raffle/raffle.algo.ts:150 + // this.tickets(this.txn.sender).delete() + txn Sender + box_del + + // examples/raffle/raffle.algo.ts:152 + // sendPayment({ + itxn_begin + int pay + itxn_field TypeEnum + + // examples/raffle/raffle.algo.ts:153 + // amount: this.ticketPrice.value * ticketCount + byte "ticketPrice" + app_global_get + frame_dig -2 // ticketCount: uint64 + * + itxn_field Amount + + // examples/raffle/raffle.algo.ts:154 + // receiver: this.txn.sender + txn Sender + itxn_field Receiver + + // examples/raffle/raffle.algo.ts:155 + // fee: 0 + int 0 + itxn_field Fee + itxn_submit + retsub + +create_NoOp: + method "createApplication(uint64,uint64)void" + txna ApplicationArgs 0 + match abi_route_createApplication + err + +call_NoOp: + method "setAsset(asset)void" + method "startRaffle(uint64,uint64)void" + method "buyTickets(pay,uint64)void" + method "draw()void" + method "claim()void" + method "getRefund()void" + txna ApplicationArgs 0 + match abi_route_setAsset abi_route_startRaffle abi_route_buyTickets abi_route_draw abi_route_claim abi_route_getRefund + err \ No newline at end of file diff --git a/examples/raffle/artifacts/NFTRaffle.clear.teal b/examples/raffle/artifacts/NFTRaffle.clear.teal new file mode 100644 index 000000000..6bbec507a --- /dev/null +++ b/examples/raffle/artifacts/NFTRaffle.clear.teal @@ -0,0 +1,2 @@ +#pragma version 9 +int 1 \ No newline at end of file diff --git a/examples/raffle/artifacts/NFTRaffle.json b/examples/raffle/artifacts/NFTRaffle.json new file mode 100644 index 000000000..5eacbbd4b --- /dev/null +++ b/examples/raffle/artifacts/NFTRaffle.json @@ -0,0 +1,207 @@ +{ + "hints": { + "createApplication(uint64,uint64)void": { + "call_config": { + "no_op": "CREATE" + } + }, + "setAsset(asset)void": { + "call_config": { + "no_op": "CALL" + } + }, + "startRaffle(uint64,uint64)void": { + "call_config": { + "no_op": "CALL" + } + }, + "buyTickets(pay,uint64)void": { + "call_config": { + "no_op": "CALL" + } + }, + "draw()void": { + "call_config": { + "no_op": "CALL" + } + }, + "claim()void": { + "call_config": { + "no_op": "CALL" + } + }, + "getRefund()void": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "NEVER", + "opt_in": "NEVER", + "close_out": "NEVER", + "update_application": "NEVER", + "delete_application": "NEVER" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": { + "randomnessOracle": { + "type": "uint64", + "key": "randomnessOracle" + }, + "ticketPrice": { + "type": "uint64", + "key": "ticketPrice" + }, + "asset": { + "type": "uint64", + "key": "asset" + }, + "endRound": { + "type": "uint64", + "key": "endRound" + }, + "drawRound": { + "type": "uint64", + "key": "drawRound" + }, + "totalTickets": { + "type": "uint64", + "key": "totalTickets" + }, + "winningTicket": { + "type": "uint64", + "key": "winningTicket" + } + }, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 7 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIG5vIGR1cG4gbmVlZGVkCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgljYWxsc3ViIGNyZWF0ZUFwcGxpY2F0aW9uCglpbnQgMQoJcmV0dXJuCgpjcmVhdGVBcHBsaWNhdGlvbjoKCXByb3RvIDIgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czozOQoJLy8gdGhpcy5yYW5kb21uZXNzT3JhY2xlLnZhbHVlID0gcmFuZG9tbmVzc09yYWNsZQoJYnl0ZSAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQwCgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgInRpY2tldFByaWNlIgoJZnJhbWVfZGlnIC0xIC8vIHRpY2tldFByaWNlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CglyZXRzdWIKCmFiaV9yb3V0ZV9zZXRBc3NldDoKCS8vIG5vIGR1cG4gbmVlZGVkCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjUwCgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTIKCS8vIHNlbmRBc3NldFRyYW5zZmVyKHsKCWl0eG5fYmVnaW4KCWludCBheGZlcgoJaXR4bl9maWVsZCBUeXBlRW51bQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo1MwoJLy8gYXNzZXRSZWNlaXZlcjogdGhpcy5hcHAuYWRkcmVzcwoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYXBwX3BhcmFtc19nZXQgQXBwQWRkcmVzcwoJYXNzZXJ0CglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTQKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU1CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTYKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo1OQoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlICJhc3NldCIKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWFwcF9nbG9iYWxfcHV0CglyZXRzdWIKCmFiaV9yb3V0ZV9zdGFydFJhZmZsZToKCS8vIG5vIGR1cG4gbmVlZGVkCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgljYWxsc3ViIHN0YXJ0UmFmZmxlCglpbnQgMQoJcmV0dXJuCgpzdGFydFJhZmZsZToKCXByb3RvIDIgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo3MAoJLy8gYXNzZXJ0KHRoaXMuYXBwLmFkZHJlc3MuYXNzZXRCYWxhbmNlKHRoaXMuYXNzZXQudmFsdWUpID4gMCkKCXR4bmEgQXBwbGljYXRpb25zIDAKCWFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKCWFzc2VydAoJYnl0ZSAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRCYWxhbmNlCglhc3NlcnQKCWludCAwCgk+Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NzIKCS8vIGFzc2VydChkcmF3ID4gZW5kKQoJZnJhbWVfZGlnIC0yIC8vIGRyYXc6IHVpbnQ2NAoJZnJhbWVfZGlnIC0xIC8vIGVuZDogdWludDY0Cgk+Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NzMKCS8vIHRoaXMuZW5kUm91bmQudmFsdWUgPSBlbmQKCWJ5dGUgImVuZFJvdW5kIgoJZnJhbWVfZGlnIC0xIC8vIGVuZDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo3NAoJLy8gdGhpcy5kcmF3Um91bmQudmFsdWUgPSBkcmF3CglieXRlICJkcmF3Um91bmQiCglmcmFtZV9kaWcgLTIgLy8gZHJhdzogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgphYmlfcm91dGVfYnV5VGlja2V0czoKCWJ5dGUgMHgKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCXR4biBHcm91cEluZGV4CglpbnQgMQoJLQoJZHVwCglndHhucyBUeXBlRW51bQoJaW50IHBheQoJPT0KCWFzc2VydAoJY2FsbHN1YiBidXlUaWNrZXRzCglpbnQgMQoJcmV0dXJuCgpidXlUaWNrZXRzOgoJcHJvdG8gMyAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjg4CgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA8IHRoaXMuZW5kUm91bmQudmFsdWUpCglnbG9iYWwgUm91bmQKCWJ5dGUgImVuZFJvdW5kIgoJYXBwX2dsb2JhbF9nZXQKCTwKCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4OQoJLy8gYXNzZXJ0KHF1YW5pdHkgPiAwKQoJZnJhbWVfZGlnIC0yIC8vIHF1YW5pdHk6IHVpbnQ2NAoJaW50IDAKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5MQoJLy8gYXNzZXJ0KHBheW1lbnQuYW1vdW50ID09PSB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogcXVhbml0eSkKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIEFtb3VudAoJYnl0ZSAidGlja2V0UHJpY2UiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW5pdHk6IHVpbnQ2NAoJKgoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5MgoJLy8gYXNzZXJ0KHBheW1lbnQuc2VuZGVyID09PSB0aGlzLnR4bi5zZW5kZXIpCglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBTZW5kZXIKCXR4biBTZW5kZXIKCT09Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTMKCS8vIGFzc2VydChwYXltZW50LnJlY2VpdmVyID09PSB0aGlzLmFwcC5hZGRyZXNzKQoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgUmVjZWl2ZXIKCXR4bmEgQXBwbGljYXRpb25zIDAKCWFwcF9wYXJhbXNfZ2V0IEFwcEFkZHJlc3MKCWFzc2VydAoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5NQoJLy8gYXNzZXJ0KCF0aGlzLnRpY2tldHMocGF5bWVudC5zZW5kZXIpLmV4aXN0cykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJYm94X2xlbgoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTcKCS8vIG5ld1RvdGFsID0gdGhpcy50b3RhbFRpY2tldHMudmFsdWUgKyBxdWFuaXR5ICsgMQoJYnl0ZSAidG90YWxUaWNrZXRzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtMiAvLyBxdWFuaXR5OiB1aW50NjQKCSsKCWludCAxCgkrCglmcmFtZV9idXJ5IC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTkKCS8vIHRoaXMudGlja2V0cyhwYXltZW50LnNlbmRlcikudmFsdWUgPSB7IHN0YXJ0OiB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSwgZW5kOiBuZXdUb3RhbCAtIDEgfQoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCglieXRlICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJZnJhbWVfZGlnIC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCWludCAxCgktCglpdG9iCgljb25jYXQKCWJveF9wdXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAwCgkvLyB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSA9IG5ld1RvdGFsCglieXRlICJ0b3RhbFRpY2tldHMiCglmcmFtZV9kaWcgLTMgLy8gbmV3VG90YWw6IHVpbnQ2NAoJYXBwX2dsb2JhbF9wdXQKCXJldHN1YgoKYWJpX3JvdXRlX2RyYXc6CglieXRlIDB4CgljYWxsc3ViIGRyYXcKCWludCAxCglyZXR1cm4KCmRyYXc6Cglwcm90byAxIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTA1CgkvLyBhc3NlcnQoIXRoaXMud2lubmluZ1RpY2tldC5leGlzdHMpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwNwoJLy8gb3V0cHV0ID0gc2VuZE1ldGhvZENhbGw8W3VpbnQ2NCwgYnl0ZXNdLCBieXRlcz4oewoJaXR4bl9iZWdpbgoJaW50IGFwcGwKCWl0eG5fZmllbGQgVHlwZUVudW0KCW1ldGhvZCAibXVzdF9nZXQodWludDY0LGJ5dGVbXSlieXRlW10iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDkKCS8vIG1ldGhvZEFyZ3M6IFt0aGlzLmRyYXdSb3VuZC52YWx1ZSwgJyddCglieXRlICJkcmF3Um91bmQiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKCWJ5dGUgIiIKCWR1cAoJbGVuCglpdG9iCglleHRyYWN0IDYgMgoJc3dhcAoJY29uY2F0CglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMTAKCS8vIGFwcGxpY2F0aW9uSUQ6IEFwcGxpY2F0aW9uLmZyb21JbmRleCh0aGlzLnJhbmRvbW5lc3NPcmFjbGUudmFsdWUpCglieXRlICJyYW5kb21uZXNzT3JhY2xlIgoJYXBwX2dsb2JhbF9nZXQKCWl0eG5fZmllbGQgQXBwbGljYXRpb25JRAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMTEKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExMgoJLy8gb25Db21wbGV0aW9uOiAnTm9PcCcKCWludCBOb09wCglpdHhuX2ZpZWxkIE9uQ29tcGxldGlvbgoJaXR4bl9zdWJtaXQKCWl0eG4gTnVtTG9ncwoJaW50IDEKCS0KCWl0eG5hcyBMb2dzCglleHRyYWN0IDQgMAoJZnJhbWVfYnVyeSAtMSAvLyBvdXRwdXQ6IGJ5dGVzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExOQoJLy8gdGhpcy53aW5uaW5nVGlja2V0LnZhbHVlID0gYnRvYmlnaW50KG91dHB1dCkgJSB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZQoJYnl0ZSAid2lubmluZ1RpY2tldCIKCWZyYW1lX2RpZyAtMSAvLyBvdXRwdXQ6IGJ5dGVzCglieXRlICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJYiUKCWJ0b2kKCWFwcF9nbG9iYWxfcHV0CglyZXRzdWIKCmFiaV9yb3V0ZV9jbGFpbToKCWJ5dGUgMHgKCWNhbGxzdWIgY2xhaW0KCWludCAxCglyZXR1cm4KCmNsYWltOgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNAoJLy8gdGlja2V0UmFuZ2UgPSB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS52YWx1ZQoJdHhuIFNlbmRlcgoJZnJhbWVfYnVyeSAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTI2CgkvLyBhc3NlcnQodGlja2V0UmFuZ2Uuc3RhcnQgPD0gdGhpcy53aW5uaW5nVGlja2V0LnZhbHVlKQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglzdG9yZSAwIC8vIGZ1bGwgYXJyYXkKCWludCAwIC8vIGluaXRpYWwgb2Zmc2V0CglpbnQgMCAvLyBoZWFkT2Zmc2V0CgkrCglsb2FkIDAgLy8gZnVsbCBhcnJheQoJc3dhcAoJaW50IDgKCWV4dHJhY3QzCglidG9pCglieXRlICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXQKCTw9Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTI3CgkvLyBhc3NlcnQodGlja2V0UmFuZ2UuZW5kID49IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCWJveF9nZXQKCWFzc2VydAoJc3RvcmUgMCAvLyBmdWxsIGFycmF5CglpbnQgMCAvLyBpbml0aWFsIG9mZnNldAoJaW50IDggLy8gaGVhZE9mZnNldAoJKwoJbG9hZCAwIC8vIGZ1bGwgYXJyYXkKCXN3YXAKCWludCA4CglleHRyYWN0MwoJYnRvaQoJYnl0ZSAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0Cgk+PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyOQoJLy8gc2VuZEFzc2V0VHJhbnNmZXIoewoJaXR4bl9iZWdpbgoJaW50IGF4ZmVyCglpdHhuX2ZpZWxkIFR5cGVFbnVtCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEzMAoJLy8gYXNzZXRSZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTMxCgkvLyB4ZmVyQXNzZXQ6IHRoaXMuYXNzZXQudmFsdWUKCWJ5dGUgImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEzMgoJLy8gYXNzZXRBbW91bnQ6IHRoaXMuYXBwLmFkZHJlc3MuYXNzZXRCYWxhbmNlKHRoaXMuYXNzZXQudmFsdWUpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglhcHBfcGFyYW1zX2dldCBBcHBBZGRyZXNzCglhc3NlcnQKCWJ5dGUgImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQoJYXNzZXJ0CglpdHhuX2ZpZWxkIEFzc2V0QW1vdW50CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEzMwoJLy8gYXNzZXRDbG9zZVRvOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRDbG9zZVRvCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEzNAoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCWl0eG5fc3VibWl0CglyZXRzdWIKCmFiaV9yb3V0ZV9nZXRSZWZ1bmQ6CglieXRlIDB4OyBkdXAKCWNhbGxzdWIgZ2V0UmVmdW5kCglpbnQgMQoJcmV0dXJuCgpnZXRSZWZ1bmQ6Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTQ0CgkvLyBhc3NlcnQoIXRoaXMud2lubmluZ1RpY2tldC5leGlzdHMpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0NQoJLy8gYXNzZXJ0KGdsb2JhbHMucm91bmQgPiB0aGlzLmRyYXdSb3VuZC52YWx1ZSArIDE1MTIpCglnbG9iYWwgUm91bmQKCWJ5dGUgImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpbnQgMTUxMgoJKwoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0NwoJLy8gdGlja2V0UmFuZ2UgPSB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS52YWx1ZQoJdHhuIFNlbmRlcgoJZnJhbWVfYnVyeSAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTQ4CgkvLyB0aWNrZXRDb3VudCA9IHRpY2tldFJhbmdlLmVuZCAtIHRpY2tldFJhbmdlLnN0YXJ0ICsgMQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglzdG9yZSAwIC8vIGZ1bGwgYXJyYXkKCWludCAwIC8vIGluaXRpYWwgb2Zmc2V0CglpbnQgOCAvLyBoZWFkT2Zmc2V0CgkrCglsb2FkIDAgLy8gZnVsbCBhcnJheQoJc3dhcAoJaW50IDgKCWV4dHJhY3QzCglidG9pCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCXN0b3JlIDAgLy8gZnVsbCBhcnJheQoJaW50IDAgLy8gaW5pdGlhbCBvZmZzZXQKCWludCAwIC8vIGhlYWRPZmZzZXQKCSsKCWxvYWQgMCAvLyBmdWxsIGFycmF5Cglzd2FwCglpbnQgOAoJZXh0cmFjdDMKCWJ0b2kKCS0KCWludCAxCgkrCglmcmFtZV9idXJ5IC0yIC8vIHRpY2tldENvdW50OiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUwCgkvLyB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS5kZWxldGUoKQoJdHhuIFNlbmRlcgoJYm94X2RlbAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTIKCS8vIHNlbmRQYXltZW50KHsKCWl0eG5fYmVnaW4KCWludCBwYXkKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiB0aWNrZXRDb3VudAoJYnl0ZSAidGlja2V0UHJpY2UiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHRpY2tldENvdW50OiB1aW50NjQKCSoKCWl0eG5fZmllbGQgQW1vdW50CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE1NAoJLy8gcmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlcgoJdHhuIFNlbmRlcgoJaXR4bl9maWVsZCBSZWNlaXZlcgoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTUKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCglpdHhuX3N1Ym1pdAoJcmV0c3ViCgpjcmVhdGVfTm9PcDoKCW1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24odWludDY0LHVpbnQ2NCl2b2lkIgoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAoJbWF0Y2ggYWJpX3JvdXRlX2NyZWF0ZUFwcGxpY2F0aW9uCgllcnIKCmNhbGxfTm9PcDoKCW1ldGhvZCAic2V0QXNzZXQoYXNzZXQpdm9pZCIKCW1ldGhvZCAic3RhcnRSYWZmbGUodWludDY0LHVpbnQ2NCl2b2lkIgoJbWV0aG9kICJidXlUaWNrZXRzKHBheSx1aW50NjQpdm9pZCIKCW1ldGhvZCAiZHJhdygpdm9pZCIKCW1ldGhvZCAiY2xhaW0oKXZvaWQiCgltZXRob2QgImdldFJlZnVuZCgpdm9pZCIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9zZXRBc3NldCBhYmlfcm91dGVfc3RhcnRSYWZmbGUgYWJpX3JvdXRlX2J1eVRpY2tldHMgYWJpX3JvdXRlX2RyYXcgYWJpX3JvdXRlX2NsYWltIGFiaV9yb3V0ZV9nZXRSZWZ1bmQKCWVycg==", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDkKaW50IDE=" + }, + "contract": { + "name": "NFTRaffle", + "desc": "", + "methods": [ + { + "name": "createApplication", + "args": [ + { + "name": "ticketPrice", + "type": "uint64", + "desc": "The price of a single ticket (uALGO)" + }, + { + "name": "randomnessOracle", + "type": "uint64", + "desc": "The app ID of the randomness oracle" + } + ], + "desc": "Create the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "setAsset", + "args": [ + { + "name": "asset", + "type": "asset", + "desc": "The asset to be raffled" + } + ], + "desc": "Set the asset to be raffled", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "startRaffle", + "args": [ + { + "name": "end", + "type": "uint64", + "desc": "The round number when the raffle ends" + }, + { + "name": "draw", + "type": "uint64", + "desc": "The round number when the raffle is drawn" + } + ], + "desc": "Start the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "buyTickets", + "args": [ + { + "name": "payment", + "type": "pay", + "desc": "The payment for the tickets" + }, + { + "name": "quanity", + "type": "uint64", + "desc": "The number of tickets to buy" + } + ], + "desc": "Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed.", + "returns": { + "type": "void", + "desc": "The total number of tickets owned by the sender" + } + }, + { + "name": "draw", + "args": [], + "desc": "Draw the winning ticket", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "claim", + "args": [], + "desc": "Send the asset to the the sender if they have the winning ticket", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "getRefund", + "args": [], + "desc": "Allows purchasers to get a refund if the winning ticket has not been drawnand 1512 rounds have passed since the draw round, meaning the oracle nolonger has the data for the draw round", + "returns": { + "type": "void", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/examples/raffle/artifacts/NFTRaffle.src_map.json b/examples/raffle/artifacts/NFTRaffle.src_map.json new file mode 100644 index 000000000..1ec452ccf --- /dev/null +++ b/examples/raffle/artifacts/NFTRaffle.src_map.json @@ -0,0 +1,22 @@ +{ + "pc": { + "version": 3, + "sources": [ + "raffle.algo.ts" + ], + "names": [], + "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCoB;;;AAAlB;AAAA;;;AAAA;AAAA;AAAA;;;AACE;;AACA;;AAAA;AAAA;;AASF;;AAAS;AAAA;AAAA;;;;AAAT;;AAXkB;;;AAChB;AAWQ;AAAA;;;AAAA;;;AAER;AAAA;AAAA;AAAA;AAFQ;AADV;AAImB;AACf;;AAhBJ;;AAgBe;;;;;AACX;AALK;;AAGmB;;AAM1B;;AAVF;;;AAoBA;;;AAAY;AAAZ;;;AApBA;AAUE;AAWO;;;;AAAA;;;AAAA;AAAkD;;;AAAF;AAAhD;AAlBP;;;AAoBc;;;AACd;;AAAA;AAAA;AAAA;AAlBe;;AAesB;AAIrC;AAAA;AAAA;AALF;;;;AAkBW;AAAA;AAAA;;;;AAAA;AAAX;;;;AAlByB;AAAA;AAmBhB;AAAc;;;AAAd;AADmB;;AAAA;AAEnB;AAAU;AAAF;;AAAR;AAFE;AAAA;AAIF;;;AAAQ;AAAW;AAAA;;;AAAJ;;AACf;;AAAQ;AAAoB;AAAb;AAAf;;;AACqB;AAAA;AAAS;;AAErC;;AAAqB;;AAAQ;AAArB;;AAAA;AAAA;AAAA;AAAD;;AAEU;;AAAoC;;AAAF;AAAE;AAAF;;AAEtC;;AAAQ;;;AAArB;;AAAA;AAA8C;AAA8B;AAAW;;;;AAZ9E;AA5BT;AAyCA;AAAA;AAAA;AAbF;;AAiBA;;AAAA;AAAA;AAnCY;AAhBR;;AAoDM;;;;AAAA;AAAD;AAZQ;AArBR;;AAmCQ;AAAA;AAAA;AACb;AAAA;AATmC;AAUtB;;AAAA;AAAsB;AAAA;AAAA;;;AAAA;AAAA;AAAA;;;AACE;;;AACrC;AAAK;AAAL;AANM;AAAA;AAOQ;AAAd;AALa;AAAA;;AAAA;;;;;;AAAT;;AAdC;;;AA0BwC;AAAA;;AAAF;AAAA;AAA7C;AAfF;AAmBA;;;AAAA;AAAA;AAAA;;AAAA;;AACsB;AAAA;;AAAa;AAAb;;AAAA;;;AAEb;AAAA;;AAAA;AAAA;AAAA;;AAAqB;;;AAAA;;AAAH;AAFL;;AAAA;AAAA;AAGb;AAAA;;;AAAA;AAAA;AAAA;;;AAAmB;AAAA;AAAH;;;AAvBzB;;AA0BI;;AAjCuC;;AAkCvC;AAAW;AAAA;;AAAX;AA3EA;AAsEK;AAMQ;;AAAA;AAAS;AAAqB;AAAA;AAA9B;AAAA;AAAb;AA/DJ;AAAA;;AAiEI;AAAK;AAAL;;AALF;AANF;AAoBA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AApDmD;AAkBZ;AAmC7B;AAAA;;;AAAD;;AAfP;;;;AAgB8C;AAEJ;AAvBtB;;AAuBA;;;AAAA;;AACA;AAAA;;;;AAAA;AAAA;;AAAA;;AADA;;AAAA;AACkB;;AAAA;AAAA;AAAA;;AAAF;;;AAAsB;AAAF;AAAE;;;AA7D5D;;;AAiEE;AAjEF;AAiEE;AAAA;AAAA;AARQ;AAAA;;;;AASN;AARqB;;;AAAA;AASF;AAAnB;AATmB;;;;AAFvB;;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAIsB;AA3Eb;AA6DL;;AAeoC;;;AAxBlB;;AALpB;AAAA;AAA+C;AA6BT;AAvCvB;AAAA;AAAA;AA5DjB;;AAqBkB;;;AAgFM;;AA9CxB;;AAAA;;;AAmBA;;AA8BY;AAAyB;;AAAF;;;;AA7D1B;;;AA+DA;AAAL;AAHF;;;;;;AAhEuB;;;AAuDzB;;;;AAAA;AAAA;;;;;;;;;;;;;;;;;;AAtCU;;;;;;AANK;;;;;;AANN;;;;;;AAcQ;;;AAAA;;;;;;;;;;;;;;AAAA;AAyCK", + "file": "NFTRaffle.approval.teal", + "sourceRoot": "" + }, + "teal": { + "version": 3, + "sources": [ + "raffle.algo.ts" + ], + "names": [], + "mappings": ";;;;;;;;;;;;;;;;AAoCoB;AAAlB;AAAA;AAAA;AAAA;AAAA;;;AACE;;;;AACA;AAAA;AAAA;;;;AASF;AAAS;AAAA;AAAA;;;;;AAAT;AAXkB;AAChB;AAWQ;AAAA;;;AAAA;;;;AAER;AAAA;AAAA;AAAA;AAFQ;AADV;AAImB;;;;AACf;AAhBJ;AAgBe;;;;;AACX;AALK;AAGmB;;;;AAM1B;AAVF;;;;;AAoBA;;;;;AAAY;AAAZ;;;;;AApBA;AAUE;AAWO;;;;;AAAA;AAAA;AAAkD;AAAF;AAAhD;AAlBP;;;AAoBc;;;;AACd;AAAA;AAAA;AAAA;AAlBe;AAesB;AAIrC;AAAA;AAAA;AALF;;;;;AAkBW;AAAA;AAAA;;;;;AAAA;AAAX;;;;;AAlByB;AAAA;AAmBhB;;;AAAc;AAAd;AADmB;AAAA;AAEnB;AAAU;AAAF;AAAR;AAFE;AAAA;AAIF;AAAQ;AAAW;AAAA;;;AAAJ;;;;AACf;AAAQ;AAAoB;AAAb;AAAf;;;;;AACqB;AAAA;AAAS;;;;AAErC;AAAqB;AAAQ;AAArB;AAAA;AAAA;AAAA;AAAD;;;;AAEU;AAAoC;AAAF;AAAE;AAAF;;;;AAEtC;AAAQ;AAArB;AAAA;AAA8C;AAA8B;AAAW;;;;;AAZ9E;AA5BT;AAyCA;AAAA;AAAA;AAbF;;;;;AAiBA;AAAA;AAAA;AAnCY;AAhBR;AAoDM;;;;;AAAA;AAAD;AAZQ;AArBR;AAmCQ;AAAA;AAAA;AACb;AAAA;AATmC;;;;AAUtB;AAAA;AAAsB;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;AACE;;;;AACrC;AAAK;AAAL;AANM;AAAA;AAOQ;AAAd;;;;AALa;AAAA;AAAA;AAAT;AAdC;;;;;AA0BwC;AAAA;AAAF;AAAA;AAA7C;AAfF;AAmBA;AAAA;AAAA;AAAA;AAAA;;;;AACsB;AAAA;AAAa;;;;AAAb;AAAA;;;;;AAEb;AAAA;AAAA;AAAA;AAAA;AAAqB;AAAA;AAAH;;;;AAFL;AAAA;AAAA;AAGb;AAAA;;;AAAA;AAAA;;;AAAA;AAAmB;AAAA;AAAH;;;AAvBzB;;;;AA0BI;AAjCuC;;;;AAkCvC;AAAW;AAAA;AAAX;AA3EA;AAsEK;AAMQ;AAAA;AAAS;AAAqB;AAAA;AAA9B;AAAA;AAAb;AA/DJ;AAAA;;;;AAiEI;AAAK;AAAL;AALF;AANF;AAoBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AApDmD;AAkBZ;AAmC7B;AAAA;;;;;AAAD;AAfP;;;;;AAgB8C;;;;AAEJ;AAvBtB;AAuBA;;;;AAAA;AACA;AAAA;;;AAAA;AAAA;AAAA;;;;AADA;AAAA;;;;AACkB;AAAA;AAAA;AAAA;;;AAAF;AAAsB;AAAF;AAAE;;;AA7D5D;;;;AAiEE;AAjEF;AAiEE;AAAA;AAAA;AARQ;AAAA;;;;;AASN;AARqB;AAAA;AASF;AAAnB;AATmB;;;;;AAFvB;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIsB;AA3Eb;AA6DL;AAeoC;;;AAxBlB;AALpB;AAAA;AAA+C;AA6BT;AAvCvB;AAAA;AAAA;AA5DjB;AAqBkB;;;;;AAgFM;;;;;AA9CxB;AAAA;;;;;AAmBA;AA8BY;AAAyB;AAAF;;;;;AA7D1B;;;;;AA+DA;AAAL;AAHF;;;AAhEuB;AAuDzB;AAAA;AAAA;;;;;AAtCU;AANK;AANN;AAcQ;AAAA;AAAA;AAyCK", + "file": "NFTRaffle.approval.teal", + "sourceRoot": "" + } +} \ No newline at end of file diff --git a/examples/raffle/raffle.algo.ts b/examples/raffle/raffle.algo.ts new file mode 100644 index 000000000..5315f6e1b --- /dev/null +++ b/examples/raffle/raffle.algo.ts @@ -0,0 +1,184 @@ +import { Contract } from '../../src/lib/index'; + +type TicketRange = {start: number, end: number}; +// eslint-disable-next-line no-loss-of-precision +const RAND_MAX = 18_446_744_073_709_551_615; + +// eslint-disable-next-line no-unused-vars +class NFTRaffle extends Contract { + /** The app ID of the randomness oracle */ + randomnessOracle = GlobalStateKey(); + + /** The price of a single ticket (uALGO) */ + ticketPrice = GlobalStateKey(); + + /** The asset to be raffled */ + asset = GlobalStateKey(); + + /** After this round, tickets can no longer be purchased */ + endRound = GlobalStateKey(); + + /** The randomness oracle round commitment */ + drawRound = GlobalStateKey(); + + /** The range of tickets owned by each purchaser */ + tickets = BoxMap(); + + /** The total number of tickets purchased */ + totalTickets = GlobalStateKey(); + + /** The winning ticket number */ + winningTicket = GlobalStateKey(); + + randomBytes = GlobalStateKey(); + + /** + * Create the raffle + * + * @param ticketPrice The price of a single ticket (uALGO) + * @param randomnessOracle The app ID of the randomness oracle + * + */ + createApplication(ticketPrice: number, randomnessOracle: number): void { + this.randomnessOracle.value = randomnessOracle; + this.ticketPrice.value = ticketPrice; + } + + /** + * Set the asset to be raffled + * + * @param asset The asset to be raffled + * + */ + setAsset(asset: Asset): void { + assert(!this.asset.exists); + + sendAssetTransfer({ + assetReceiver: this.app.address, + xferAsset: asset, + assetAmount: 0, + fee: 0, + }); + + this.asset.value = asset; + } + + /** + * Start the raffle + * + * @param end The round number when the raffle ends + * @param draw The round number when the raffle is drawn + * + */ + startRaffle(end: number, draw: number): void { + assert(this.app.address.assetBalance(this.asset.value) > 0); + + assert(draw > end); + this.endRound.value = end; + this.drawRound.value = draw; + } + + /** + * Buy tickets. Note this can only be called once! + * It would be possible to allow multiple purchases, but + * for simplicity, only one purchase is allowed. + * + * @param payment The payment for the tickets + * @param quanity The number of tickets to buy + * + * @returns The total number of tickets owned by the sender + */ + buyTickets(payment: PayTxn, quanity: number): void { + assert(globals.round < this.endRound.value); + assert(quanity > 0); + + assert(payment.amount === this.ticketPrice.value * quanity); + assert(payment.sender === this.txn.sender); + assert(payment.receiver === this.app.address); + + assert(!this.tickets(payment.sender).exists); + + const newTotal = this.totalTickets.value + quanity + 1; + + this.tickets(payment.sender).value = { start: this.totalTickets.value, end: newTotal - 1 }; + this.totalTickets.value = newTotal; + } + + /** Get randomness from the oracle or by hashing existing randomness */ + private getRandomBytes(): void { + if (this.randomBytes.exists) { + this.randomBytes.value = sha256(this.randomBytes.value) as bytes; + } else { + this.randomBytes.value = sendMethodCall<[uint64, bytes], bytes>({ + name: 'must_get', + methodArgs: [this.drawRound.value, ''], + applicationID: Application.fromID(this.randomnessOracle.value), + fee: 0, + onCompletion: 'NoOp', + }); + } + } + + /** Draw the winning ticket */ + draw(): boolean { + assert(!this.winningTicket.exists); + this.getRandomBytes(); + + // Continue to sample a uint64 from randomBytes until we get one that avoids modulo bias + // See https://stackoverflow.com/a/46991999/12513465 + const n = this.totalTickets.value; + let x: uint64; + let offset = 0; + let maxCondition: boolean; + + do { + x = extract_uint64(this.randomBytes.value, offset); + + offset += 8; + + maxCondition = x > (RAND_MAX - (((RAND_MAX % n) + 1) % n)); + } while (maxCondition && offset < 32); + + if (maxCondition) return false; + + this.winningTicket.value = x % n; + return true; + } + + /** Send the asset to the the sender if they have the winning ticket */ + claim(): void { + const ticketRange = this.tickets(this.txn.sender).value; + + assert(ticketRange.start <= this.winningTicket.value); + assert(ticketRange.end >= this.winningTicket.value); + + sendAssetTransfer({ + assetReceiver: this.txn.sender, + xferAsset: this.asset.value, + assetAmount: this.app.address.assetBalance(this.asset.value), + assetCloseTo: this.txn.sender, + fee: 0, + }); + } + + /** + * Allows purchasers to get a refund if the winning ticket has not been drawn + * and 1512 rounds have passed since the draw round, meaning the oracle no + * longer has the data for the draw round + */ + getRefund(): void { + assert(!this.winningTicket.exists); + assert(globals.round > this.drawRound.value + 1512); + + const ticketRange = this.tickets(this.txn.sender).value; + const ticketCount = ticketRange.end - ticketRange.start + 1; + + this.tickets(this.txn.sender).delete(); + + sendPayment({ + amount: this.ticketPrice.value * ticketCount, + receiver: this.txn.sender, + fee: 0, + }); + } +} diff --git a/examples/raffle/tsconfig.json b/examples/raffle/tsconfig.json new file mode 100644 index 000000000..5e3106d17 --- /dev/null +++ b/examples/raffle/tsconfig.json @@ -0,0 +1,103 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/package.json b/package.json index 23fb5ce0a..1416008a2 100644 --- a/package.json +++ b/package.json @@ -42,12 +42,13 @@ "compile-non_abi": "bun ./src/bin/tealscript.ts --unsafe-disable-typescript examples/non_abi/non_abi.algo.ts examples/non_abi/artifacts", "compile-optin-lsig": "bun ./src/bin/tealscript.ts --unsafe-disable-typescript examples/optin-lsig/lsig.algo.ts examples/optin-lsig/artifacts", "compile-lsig_with_app": "bun ./src/bin/tealscript.ts --unsafe-disable-typescript examples/lsig_with_app/lsig_with_app.algo.ts examples/lsig_with_app/artifacts", + "compile-raffle": "bun ./src/bin/tealscript.ts examples/raffle/raffle.algo.ts examples/raffle/artifacts", "run-merkle": "bun examples/merkle/demo.ts", "run-tuple_in_box": "bun ./examples/tuple_in_box/client.ts", "run-itxns": "bun examples/itxns/demo.ts", "run-examples": "conc \"bun run-merkle\" \"bun run-tuple_in_box\" \"bun run-itxns\"", "run-simple": "bun examples/simple/index.ts", - "compile-examples": "conc \"bun compile-amm\" \"bun compile-arc75\" \"bun compile-auction\" \"bun compile-itxns\" \"bun compile-simple\" \"bun compile-tuple_in_box\" \"bun compile-calculator\" \"bun compile-merkle\" \"bun compile-big_box\" \"bun compile-arc72\" \"bun compile-non_abi\" \"bun compile-optin-lsig\" \"bun compile-lsig_with_app\"", + "compile-examples": "conc \"bun compile-amm\" \"bun compile-arc75\" \"bun compile-auction\" \"bun compile-itxns\" \"bun compile-simple\" \"bun compile-tuple_in_box\" \"bun compile-calculator\" \"bun compile-merkle\" \"bun compile-big_box\" \"bun compile-arc72\" \"bun compile-non_abi\" \"bun compile-optin-lsig\" \"bun compile-lsig_with_app\" \"bun compile-raffle\"", "webpack-smoketest": "webpack --config tests/web/webpack.config.js", "pre-commit": "conc \"bun lint\" \"bun test\" \"bun test examples/\" \"bun run-examples\" \"bun webpack-smoketest\" \"bun scripts/compile_all_smoketest.ts\"", "compile-all": "conc \"bun compile-tests\" \"bun compile-examples\"" From 13d334a82bd8a7b3dbb2de8ee8d0c6fcd6a9cb46 Mon Sep 17 00:00:00 2001 From: Joe Polny Date: Thu, 23 Nov 2023 07:28:43 -0500 Subject: [PATCH 2/4] compile raffle --- .../raffle/artifacts/NFTRaffle.approval.teal | 467 ++- .../raffle/artifacts/NFTRaffle.arc32.json | 211 ++ examples/raffle/artifacts/NFTRaffle.arc4.json | 108 + .../raffle/artifacts/NFTRaffle.clear.teal | 3 +- .../raffle/artifacts/NFTRaffle.src_map.json | 3043 ++++++++++++++++- examples/raffle/raffle.algo.ts | 6 +- 6 files changed, 3664 insertions(+), 174 deletions(-) create mode 100644 examples/raffle/artifacts/NFTRaffle.arc32.json create mode 100644 examples/raffle/artifacts/NFTRaffle.arc4.json diff --git a/examples/raffle/artifacts/NFTRaffle.approval.teal b/examples/raffle/artifacts/NFTRaffle.approval.teal index c1eb841ef..778fce7a1 100644 --- a/examples/raffle/artifacts/NFTRaffle.approval.teal +++ b/examples/raffle/artifacts/NFTRaffle.approval.teal @@ -1,5 +1,15 @@ #pragma version 9 +// This TEAL was generated by TEALScript v0.63.0 +// https://github.com/algorandfoundation/TEALScript + +// This contract is compliant with and/or implements the following ARCs: [ ARC4 ] + +// The following ten lines of TEAL handle initial program flow +// This pattern is used to make it easy for anyone to parse the start of the program and determine if a specific action is allowed +// Here, action refers to the OnComplete in combination with whether the app is being created or called +// Every possible action for this contract is represented in the switch statement +// If the action is not implmented in the contract, its repsective branch will be "NOT_IMPLMENTED" which just contains "err" txn ApplicationID int 0 > @@ -12,12 +22,22 @@ switch create_NoOp NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENT NOT_IMPLEMENTED: err +// createApplication(uint64,uint64)void +// +// Create the raffle +// +// @param ticketPrice The price of a single ticket (uALGO) +// @param randomnessOracle The app ID of the randomness oracle abi_route_createApplication: - // no dupn needed + // randomnessOracle: uint64 txna ApplicationArgs 2 btoi + + // ticketPrice: uint64 txna ApplicationArgs 1 btoi + + // execute createApplication(uint64,uint64)void callsub createApplication int 1 return @@ -25,24 +45,31 @@ abi_route_createApplication: createApplication: proto 2 0 - // examples/raffle/raffle.algo.ts:39 + // examples/raffle/raffle.algo.ts:43 // this.randomnessOracle.value = randomnessOracle - byte "randomnessOracle" + byte 0x72616e646f6d6e6573734f7261636c65 // "randomnessOracle" frame_dig -2 // randomnessOracle: uint64 app_global_put - // examples/raffle/raffle.algo.ts:40 + // examples/raffle/raffle.algo.ts:44 // this.ticketPrice.value = ticketPrice - byte "ticketPrice" + byte 0x7469636b65745072696365 // "ticketPrice" frame_dig -1 // ticketPrice: uint64 app_global_put retsub +// setAsset(asset)void +// +// Set the asset to be raffled +// +// @param asset The asset to be raffled abi_route_setAsset: - // no dupn needed + // asset: asset txna ApplicationArgs 1 btoi txnas Assets + + // execute setAsset(asset)void callsub setAsset int 1 return @@ -50,58 +77,73 @@ abi_route_setAsset: setAsset: proto 1 0 - // examples/raffle/raffle.algo.ts:50 + // examples/raffle/raffle.algo.ts:54 // assert(!this.asset.exists) txna Applications 0 - byte "asset" + byte 0x6173736574 // "asset" app_global_get_ex swap pop ! assert - // examples/raffle/raffle.algo.ts:52 + // examples/raffle/raffle.algo.ts:56 // sendAssetTransfer({ + // assetReceiver: this.app.address, + // xferAsset: asset, + // assetAmount: 0, + // fee: 0, + // }) itxn_begin int axfer itxn_field TypeEnum - // examples/raffle/raffle.algo.ts:53 + // examples/raffle/raffle.algo.ts:57 // assetReceiver: this.app.address - txna Applications 0 - app_params_get AppAddress - assert + global CurrentApplicationAddress itxn_field AssetReceiver - // examples/raffle/raffle.algo.ts:54 + // examples/raffle/raffle.algo.ts:58 // xferAsset: asset frame_dig -1 // asset: asset itxn_field XferAsset - // examples/raffle/raffle.algo.ts:55 + // examples/raffle/raffle.algo.ts:59 // assetAmount: 0 int 0 itxn_field AssetAmount - // examples/raffle/raffle.algo.ts:56 + // examples/raffle/raffle.algo.ts:60 // fee: 0 int 0 itxn_field Fee + + // Submit inner transaction itxn_submit - // examples/raffle/raffle.algo.ts:59 + // examples/raffle/raffle.algo.ts:63 // this.asset.value = asset - byte "asset" + byte 0x6173736574 // "asset" frame_dig -1 // asset: asset app_global_put retsub +// startRaffle(uint64,uint64)void +// +// Start the raffle +// +// @param end The round number when the raffle ends +// @param draw The round number when the raffle is drawn abi_route_startRaffle: - // no dupn needed + // draw: uint64 txna ApplicationArgs 2 btoi + + // end: uint64 txna ApplicationArgs 1 btoi + + // execute startRaffle(uint64,uint64)void callsub startRaffle int 1 return @@ -109,12 +151,10 @@ abi_route_startRaffle: startRaffle: proto 2 0 - // examples/raffle/raffle.algo.ts:70 + // examples/raffle/raffle.algo.ts:74 // assert(this.app.address.assetBalance(this.asset.value) > 0) - txna Applications 0 - app_params_get AppAddress - assert - byte "asset" + global CurrentApplicationAddress + byte 0x6173736574 // "asset" app_global_get asset_holding_get AssetBalance assert @@ -122,30 +162,44 @@ startRaffle: > assert - // examples/raffle/raffle.algo.ts:72 + // examples/raffle/raffle.algo.ts:76 // assert(draw > end) frame_dig -2 // draw: uint64 frame_dig -1 // end: uint64 > assert - // examples/raffle/raffle.algo.ts:73 + // examples/raffle/raffle.algo.ts:77 // this.endRound.value = end - byte "endRound" + byte 0x656e64526f756e64 // "endRound" frame_dig -1 // end: uint64 app_global_put - // examples/raffle/raffle.algo.ts:74 + // examples/raffle/raffle.algo.ts:78 // this.drawRound.value = draw - byte "drawRound" + byte 0x64726177526f756e64 // "drawRound" frame_dig -2 // draw: uint64 app_global_put retsub +// buyTickets(uint64,pay)void +// +// Buy tickets. Note this can only be called once! +// It would be possible to allow multiple purchases, but +// for simplicity, only one purchase is allowed. +// +// @param payment The payment for the tickets +// @param quanity The number of tickets to buy +// +// @returns The total number of tickets owned by the sender abi_route_buyTickets: - byte 0x + byte 0x // push empty bytes to fill the stack frame for this subroutine's local variables + + // quanity: uint64 txna ApplicationArgs 1 btoi + + // payment: pay txn GroupIndex int 1 - @@ -154,6 +208,8 @@ abi_route_buyTickets: int pay == assert + + // execute buyTickets(uint64,pay)void callsub buyTickets int 1 return @@ -161,33 +217,33 @@ abi_route_buyTickets: buyTickets: proto 3 0 - // examples/raffle/raffle.algo.ts:88 + // examples/raffle/raffle.algo.ts:92 // assert(globals.round < this.endRound.value) global Round - byte "endRound" + byte 0x656e64526f756e64 // "endRound" app_global_get < assert - // examples/raffle/raffle.algo.ts:89 + // examples/raffle/raffle.algo.ts:93 // assert(quanity > 0) frame_dig -2 // quanity: uint64 int 0 > assert - // examples/raffle/raffle.algo.ts:91 + // examples/raffle/raffle.algo.ts:95 // assert(payment.amount === this.ticketPrice.value * quanity) frame_dig -1 // payment: pay gtxns Amount - byte "ticketPrice" + byte 0x7469636b65745072696365 // "ticketPrice" app_global_get frame_dig -2 // quanity: uint64 * == assert - // examples/raffle/raffle.algo.ts:92 + // examples/raffle/raffle.algo.ts:96 // assert(payment.sender === this.txn.sender) frame_dig -1 // payment: pay gtxns Sender @@ -195,17 +251,15 @@ buyTickets: == assert - // examples/raffle/raffle.algo.ts:93 + // examples/raffle/raffle.algo.ts:97 // assert(payment.receiver === this.app.address) frame_dig -1 // payment: pay gtxns Receiver - txna Applications 0 - app_params_get AppAddress - assert + global CurrentApplicationAddress == assert - // examples/raffle/raffle.algo.ts:95 + // examples/raffle/raffle.algo.ts:99 // assert(!this.tickets(payment.sender).exists) frame_dig -1 // payment: pay gtxns Sender @@ -215,9 +269,9 @@ buyTickets: ! assert - // examples/raffle/raffle.algo.ts:97 + // examples/raffle/raffle.algo.ts:101 // newTotal = this.totalTickets.value + quanity + 1 - byte "totalTickets" + byte 0x746f74616c5469636b657473 // "totalTickets" app_global_get frame_dig -2 // quanity: uint64 + @@ -225,11 +279,11 @@ buyTickets: + frame_bury -3 // newTotal: uint64 - // examples/raffle/raffle.algo.ts:99 + // examples/raffle/raffle.algo.ts:103 // this.tickets(payment.sender).value = { start: this.totalTickets.value, end: newTotal - 1 } frame_dig -1 // payment: pay gtxns Sender - byte "totalTickets" + byte 0x746f74616c5469636b657473 // "totalTickets" app_global_get itob frame_dig -3 // newTotal: uint64 @@ -239,92 +293,218 @@ buyTickets: concat box_put - // examples/raffle/raffle.algo.ts:100 + // examples/raffle/raffle.algo.ts:104 // this.totalTickets.value = newTotal - byte "totalTickets" + byte 0x746f74616c5469636b657473 // "totalTickets" frame_dig -3 // newTotal: uint64 app_global_put retsub -abi_route_draw: - byte 0x - callsub draw - int 1 - return - -draw: - proto 1 0 +getRandomBytes: + proto 0 0 - // examples/raffle/raffle.algo.ts:105 - // assert(!this.winningTicket.exists) + // if0_condition + // examples/raffle/raffle.algo.ts:109 + // this.randomBytes.exists txna Applications 0 - byte "winningTicket" + byte 0x72616e646f6d4279746573 // "randomBytes" app_global_get_ex swap pop - ! - assert + bz if0_else + + // if0_consequent + // examples/raffle/raffle.algo.ts:110 + // this.randomBytes.value = sha256(this.randomBytes.value) as bytes + byte 0x72616e646f6d4279746573 // "randomBytes" + byte 0x72616e646f6d4279746573 // "randomBytes" + app_global_get + sha256 + app_global_put + b if0_end - // examples/raffle/raffle.algo.ts:107 - // output = sendMethodCall<[uint64, bytes], bytes>({ +if0_else: + // examples/raffle/raffle.algo.ts:112 + // this.randomBytes.value = sendMethodCall<[uint64, bytes], bytes>({ + // name: 'must_get', + // methodArgs: [this.drawRound.value, ''], + // applicationID: Application.fromID(this.randomnessOracle.value), + // fee: 0, + // onCompletion: 'NoOp', + // }) + byte 0x72616e646f6d4279746573 // "randomBytes" itxn_begin int appl itxn_field TypeEnum method "must_get(uint64,byte[])byte[]" itxn_field ApplicationArgs - // examples/raffle/raffle.algo.ts:109 + // examples/raffle/raffle.algo.ts:114 // methodArgs: [this.drawRound.value, ''] - byte "drawRound" + byte 0x64726177526f756e64 // "drawRound" app_global_get itob itxn_field ApplicationArgs - byte "" - dup - len - itob - extract 6 2 - swap - concat + byte 0x0000 itxn_field ApplicationArgs - // examples/raffle/raffle.algo.ts:110 - // applicationID: Application.fromIndex(this.randomnessOracle.value) - byte "randomnessOracle" + // examples/raffle/raffle.algo.ts:115 + // applicationID: Application.fromID(this.randomnessOracle.value) + byte 0x72616e646f6d6e6573734f7261636c65 // "randomnessOracle" app_global_get itxn_field ApplicationID - // examples/raffle/raffle.algo.ts:111 + // examples/raffle/raffle.algo.ts:116 // fee: 0 int 0 itxn_field Fee - // examples/raffle/raffle.algo.ts:112 + // examples/raffle/raffle.algo.ts:117 // onCompletion: 'NoOp' int NoOp itxn_field OnCompletion + + // Submit inner transaction itxn_submit itxn NumLogs int 1 - itxnas Logs extract 4 0 - frame_bury -1 // output: bytes + app_global_put + +if0_end: + retsub + +// draw()bool +// +// Draw the winning ticket +abi_route_draw: + byte 0x; dupn 3 // push empty bytes to fill the stack frame for this subroutine's local variables + + // execute draw()bool + callsub draw + int 1 + return + +draw: + proto 4 0 + + // examples/raffle/raffle.algo.ts:124 + // assert(!this.winningTicket.exists) + txna Applications 0 + byte 0x77696e6e696e675469636b6574 // "winningTicket" + app_global_get_ex + swap + pop + ! + assert + + // examples/raffle/raffle.algo.ts:125 + // this.getRandomBytes() + callsub getRandomBytes + + // examples/raffle/raffle.algo.ts:129 + // n = this.totalTickets.value + byte 0x746f74616c5469636b657473 // "totalTickets" + app_global_get + frame_bury -1 // n: uint64 + + // examples/raffle/raffle.algo.ts:131 + // offset = 0 + int 0 + frame_bury -3 // offset: uint64 - // examples/raffle/raffle.algo.ts:119 - // this.winningTicket.value = btobigint(output) % this.totalTickets.value - byte "winningTicket" - frame_dig -1 // output: bytes - byte "totalTickets" +do_while_0: + // examples/raffle/raffle.algo.ts:135 + // x = extract_uint64(this.randomBytes.value, offset) + byte 0x72616e646f6d4279746573 // "randomBytes" app_global_get - itob - b% - btoi + frame_dig -3 // offset: uint64 + extract_uint64 + frame_bury -2 // x: uint64 + + // examples/raffle/raffle.algo.ts:137 + // offset = offset + 8 + frame_dig -3 // offset: uint64 + int 8 + + + frame_bury -3 // offset: uint64 + + // examples/raffle/raffle.algo.ts:139 + // maxCondition = x > RAND_MAX - (((RAND_MAX % n) + 1) % n) + frame_dig -2 // x: uint64 + int 18_446_744_073_709_551_615 + int 18_446_744_073_709_551_615 + frame_dig -1 // n: uint64 + % + int 1 + + + frame_dig -1 // n: uint64 + % + - + > + frame_bury -4 // maxCondition: bool + frame_dig -4 // maxCondition: bool + dup + bz skip_and0 + frame_dig -3 // offset: uint64 + int 32 + < + && + +skip_and0: + bnz do_while_0 + + // if1_condition + // examples/raffle/raffle.algo.ts:142 + // maxCondition + frame_dig -4 // maxCondition: bool + bz if1_end + + // if1_consequent + // examples/raffle/raffle.algo.ts:142 + // return false; + int 0 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log + retsub + +if1_end: + // examples/raffle/raffle.algo.ts:144 + // this.winningTicket.value = x % n + byte 0x77696e6e696e675469636b6574 // "winningTicket" + frame_dig -2 // x: uint64 + frame_dig -1 // n: uint64 + % app_global_put + + // examples/raffle/raffle.algo.ts:145 + // return true; + int 1 + byte 0x00 + int 0 + uncover 2 + setbit + byte 0x151f7c75 + swap + concat + log retsub +// claim()void +// +// Send the asset to the the sender if they have the winning ticket abi_route_claim: - byte 0x + byte 0x // push empty bytes to fill the stack frame for this subroutine's local variables + + // execute claim()void callsub claim int 1 return @@ -332,91 +512,90 @@ abi_route_claim: claim: proto 1 0 - // examples/raffle/raffle.algo.ts:124 + // examples/raffle/raffle.algo.ts:150 // ticketRange = this.tickets(this.txn.sender).value txn Sender frame_bury -1 // storage key//ticketRange - // examples/raffle/raffle.algo.ts:126 + // examples/raffle/raffle.algo.ts:152 // assert(ticketRange.start <= this.winningTicket.value) frame_dig -1 // storage key//ticketRange box_get assert - store 0 // full array - int 0 // initial offset - int 0 // headOffset - + - load 0 // full array - swap - int 8 - extract3 + extract 0 8 btoi - byte "winningTicket" + byte 0x77696e6e696e675469636b6574 // "winningTicket" app_global_get <= assert - // examples/raffle/raffle.algo.ts:127 + // examples/raffle/raffle.algo.ts:153 // assert(ticketRange.end >= this.winningTicket.value) frame_dig -1 // storage key//ticketRange box_get assert - store 0 // full array - int 0 // initial offset - int 8 // headOffset - + - load 0 // full array - swap - int 8 - extract3 + extract 8 8 btoi - byte "winningTicket" + byte 0x77696e6e696e675469636b6574 // "winningTicket" app_global_get >= assert - // examples/raffle/raffle.algo.ts:129 + // examples/raffle/raffle.algo.ts:155 // sendAssetTransfer({ + // assetReceiver: this.txn.sender, + // xferAsset: this.asset.value, + // assetAmount: this.app.address.assetBalance(this.asset.value), + // assetCloseTo: this.txn.sender, + // fee: 0, + // }) itxn_begin int axfer itxn_field TypeEnum - // examples/raffle/raffle.algo.ts:130 + // examples/raffle/raffle.algo.ts:156 // assetReceiver: this.txn.sender txn Sender itxn_field AssetReceiver - // examples/raffle/raffle.algo.ts:131 + // examples/raffle/raffle.algo.ts:157 // xferAsset: this.asset.value - byte "asset" + byte 0x6173736574 // "asset" app_global_get itxn_field XferAsset - // examples/raffle/raffle.algo.ts:132 + // examples/raffle/raffle.algo.ts:158 // assetAmount: this.app.address.assetBalance(this.asset.value) - txna Applications 0 - app_params_get AppAddress - assert - byte "asset" + global CurrentApplicationAddress + byte 0x6173736574 // "asset" app_global_get asset_holding_get AssetBalance assert itxn_field AssetAmount - // examples/raffle/raffle.algo.ts:133 + // examples/raffle/raffle.algo.ts:159 // assetCloseTo: this.txn.sender txn Sender itxn_field AssetCloseTo - // examples/raffle/raffle.algo.ts:134 + // examples/raffle/raffle.algo.ts:160 // fee: 0 int 0 itxn_field Fee + + // Submit inner transaction itxn_submit retsub +// getRefund()void +// +// Allows purchasers to get a refund if the winning ticket has not been drawn +// and 1512 rounds have passed since the draw round, meaning the oracle no +// longer has the data for the draw round abi_route_getRefund: - byte 0x; dup + byte 0x; dup // push empty bytes to fill the stack frame for this subroutine's local variables + + // execute getRefund()void callsub getRefund int 1 return @@ -424,90 +603,82 @@ abi_route_getRefund: getRefund: proto 2 0 - // examples/raffle/raffle.algo.ts:144 + // examples/raffle/raffle.algo.ts:170 // assert(!this.winningTicket.exists) txna Applications 0 - byte "winningTicket" + byte 0x77696e6e696e675469636b6574 // "winningTicket" app_global_get_ex swap pop ! assert - // examples/raffle/raffle.algo.ts:145 + // examples/raffle/raffle.algo.ts:171 // assert(globals.round > this.drawRound.value + 1512) global Round - byte "drawRound" + byte 0x64726177526f756e64 // "drawRound" app_global_get int 1512 + > assert - // examples/raffle/raffle.algo.ts:147 + // examples/raffle/raffle.algo.ts:173 // ticketRange = this.tickets(this.txn.sender).value txn Sender frame_bury -1 // storage key//ticketRange - // examples/raffle/raffle.algo.ts:148 + // examples/raffle/raffle.algo.ts:174 // ticketCount = ticketRange.end - ticketRange.start + 1 frame_dig -1 // storage key//ticketRange box_get assert - store 0 // full array - int 0 // initial offset - int 8 // headOffset - + - load 0 // full array - swap - int 8 - extract3 + extract 8 8 btoi frame_dig -1 // storage key//ticketRange box_get assert - store 0 // full array - int 0 // initial offset - int 0 // headOffset - + - load 0 // full array - swap - int 8 - extract3 + extract 0 8 btoi - int 1 + frame_bury -2 // ticketCount: uint64 - // examples/raffle/raffle.algo.ts:150 + // examples/raffle/raffle.algo.ts:176 // this.tickets(this.txn.sender).delete() txn Sender box_del - // examples/raffle/raffle.algo.ts:152 + // examples/raffle/raffle.algo.ts:178 // sendPayment({ + // amount: this.ticketPrice.value * ticketCount, + // receiver: this.txn.sender, + // fee: 0, + // }) itxn_begin int pay itxn_field TypeEnum - // examples/raffle/raffle.algo.ts:153 + // examples/raffle/raffle.algo.ts:179 // amount: this.ticketPrice.value * ticketCount - byte "ticketPrice" + byte 0x7469636b65745072696365 // "ticketPrice" app_global_get frame_dig -2 // ticketCount: uint64 * itxn_field Amount - // examples/raffle/raffle.algo.ts:154 + // examples/raffle/raffle.algo.ts:180 // receiver: this.txn.sender txn Sender itxn_field Receiver - // examples/raffle/raffle.algo.ts:155 + // examples/raffle/raffle.algo.ts:181 // fee: 0 int 0 itxn_field Fee + + // Submit inner transaction itxn_submit retsub @@ -521,7 +692,7 @@ call_NoOp: method "setAsset(asset)void" method "startRaffle(uint64,uint64)void" method "buyTickets(pay,uint64)void" - method "draw()void" + method "draw()bool" method "claim()void" method "getRefund()void" txna ApplicationArgs 0 diff --git a/examples/raffle/artifacts/NFTRaffle.arc32.json b/examples/raffle/artifacts/NFTRaffle.arc32.json new file mode 100644 index 000000000..5702c4915 --- /dev/null +++ b/examples/raffle/artifacts/NFTRaffle.arc32.json @@ -0,0 +1,211 @@ +{ + "hints": { + "createApplication(uint64,uint64)void": { + "call_config": { + "no_op": "CREATE" + } + }, + "setAsset(asset)void": { + "call_config": { + "no_op": "CALL" + } + }, + "startRaffle(uint64,uint64)void": { + "call_config": { + "no_op": "CALL" + } + }, + "buyTickets(pay,uint64)void": { + "call_config": { + "no_op": "CALL" + } + }, + "draw()bool": { + "call_config": { + "no_op": "CALL" + } + }, + "claim()void": { + "call_config": { + "no_op": "CALL" + } + }, + "getRefund()void": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "NEVER", + "opt_in": "NEVER", + "close_out": "NEVER", + "update_application": "NEVER", + "delete_application": "NEVER" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": { + "randomnessOracle": { + "type": "uint64", + "key": "randomnessOracle" + }, + "ticketPrice": { + "type": "uint64", + "key": "ticketPrice" + }, + "asset": { + "type": "uint64", + "key": "asset" + }, + "endRound": { + "type": "uint64", + "key": "endRound" + }, + "drawRound": { + "type": "uint64", + "key": "drawRound" + }, + "totalTickets": { + "type": "uint64", + "key": "totalTickets" + }, + "winningTicket": { + "type": "uint64", + "key": "winningTicket" + }, + "randomBytes": { + "type": "bytes", + "key": "randomBytes" + } + }, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 1, + "num_uints": 7 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAovLwovLyBDcmVhdGUgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gdGlja2V0UHJpY2UgVGhlIHByaWNlIG9mIGEgc2luZ2xlIHRpY2tldCAodUFMR08pCi8vIEBwYXJhbSByYW5kb21uZXNzT3JhY2xlIFRoZSBhcHAgSUQgb2YgdGhlIHJhbmRvbW5lc3Mgb3JhY2xlCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIHJhbmRvbW5lc3NPcmFjbGU6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIHRpY2tldFByaWNlOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBjcmVhdGVBcHBsaWNhdGlvbgoJaW50IDEKCXJldHVybgoKY3JlYXRlQXBwbGljYXRpb246Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NDMKCS8vIHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSA9IHJhbmRvbW5lc3NPcmFjbGUKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQ0CgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWZyYW1lX2RpZyAtMSAvLyB0aWNrZXRQcmljZTogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzZXRBc3NldChhc3NldCl2b2lkCi8vCi8vIFNldCB0aGUgYXNzZXQgdG8gYmUgcmFmZmxlZAovLwovLyBAcGFyYW0gYXNzZXQgVGhlIGFzc2V0IHRvIGJlIHJhZmZsZWQKYWJpX3JvdXRlX3NldEFzc2V0OgoJLy8gYXNzZXQ6IGFzc2V0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCgkvLyBleGVjdXRlIHNldEFzc2V0KGFzc2V0KXZvaWQKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU0CgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiBhc3NldCwKCS8vICAgICAgIGFzc2V0QW1vdW50OiAwLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTcKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMuYXBwLmFkZHJlc3MKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTgKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU5CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NjAKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo2MwoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglmcmFtZV9kaWcgLTEgLy8gYXNzZXQ6IGFzc2V0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0KXZvaWQKLy8KLy8gU3RhcnQgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gZW5kIFRoZSByb3VuZCBudW1iZXIgd2hlbiB0aGUgcmFmZmxlIGVuZHMKLy8gQHBhcmFtIGRyYXcgVGhlIHJvdW5kIG51bWJlciB3aGVuIHRoZSByYWZmbGUgaXMgZHJhd24KYWJpX3JvdXRlX3N0YXJ0UmFmZmxlOgoJLy8gZHJhdzogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgoJLy8gZW5kOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIHN0YXJ0UmFmZmxlKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBzdGFydFJhZmZsZQoJaW50IDEKCXJldHVybgoKc3RhcnRSYWZmbGU6Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NzQKCS8vIGFzc2VydCh0aGlzLmFwcC5hZGRyZXNzLmFzc2V0QmFsYW5jZSh0aGlzLmFzc2V0LnZhbHVlKSA+IDApCglnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQoJYXNzZXJ0CglpbnQgMAoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc2CgkvLyBhc3NlcnQoZHJhdyA+IGVuZCkKCWZyYW1lX2RpZyAtMiAvLyBkcmF3OiB1aW50NjQKCWZyYW1lX2RpZyAtMSAvLyBlbmQ6IHVpbnQ2NAoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc3CgkvLyB0aGlzLmVuZFJvdW5kLnZhbHVlID0gZW5kCglieXRlIDB4NjU2ZTY0NTI2Zjc1NmU2NCAvLyAiZW5kUm91bmQiCglmcmFtZV9kaWcgLTEgLy8gZW5kOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc4CgkvLyB0aGlzLmRyYXdSb3VuZC52YWx1ZSA9IGRyYXcKCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWZyYW1lX2RpZyAtMiAvLyBkcmF3OiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CglyZXRzdWIKCi8vIGJ1eVRpY2tldHModWludDY0LHBheSl2b2lkCi8vCi8vIEJ1eSB0aWNrZXRzLiBOb3RlIHRoaXMgY2FuIG9ubHkgYmUgY2FsbGVkIG9uY2UhCi8vIEl0IHdvdWxkIGJlIHBvc3NpYmxlIHRvIGFsbG93IG11bHRpcGxlIHB1cmNoYXNlcywgYnV0Ci8vIGZvciBzaW1wbGljaXR5LCBvbmx5IG9uZSBwdXJjaGFzZSBpcyBhbGxvd2VkLgovLwovLyBAcGFyYW0gcGF5bWVudCBUaGUgcGF5bWVudCBmb3IgdGhlIHRpY2tldHMKLy8gQHBhcmFtIHF1YW5pdHkgVGhlIG51bWJlciBvZiB0aWNrZXRzIHRvIGJ1eQovLwovLyBAcmV0dXJucyBUaGUgdG90YWwgbnVtYmVyIG9mIHRpY2tldHMgb3duZWQgYnkgdGhlIHNlbmRlcgphYmlfcm91dGVfYnV5VGlja2V0czoKCWJ5dGUgMHggLy8gcHVzaCBlbXB0eSBieXRlcyB0byBmaWxsIHRoZSBzdGFjayBmcmFtZSBmb3IgdGhpcyBzdWJyb3V0aW5lJ3MgbG9jYWwgdmFyaWFibGVzCgoJLy8gcXVhbml0eTogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gcGF5bWVudDogcGF5Cgl0eG4gR3JvdXBJbmRleAoJaW50IDEKCS0KCWR1cAoJZ3R4bnMgVHlwZUVudW0KCWludCBwYXkKCT09Cglhc3NlcnQKCgkvLyBleGVjdXRlIGJ1eVRpY2tldHModWludDY0LHBheSl2b2lkCgljYWxsc3ViIGJ1eVRpY2tldHMKCWludCAxCglyZXR1cm4KCmJ1eVRpY2tldHM6Cglwcm90byAzIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTIKCS8vIGFzc2VydChnbG9iYWxzLnJvdW5kIDwgdGhpcy5lbmRSb3VuZC52YWx1ZSkKCWdsb2JhbCBSb3VuZAoJYnl0ZSAweDY1NmU2NDUyNmY3NTZlNjQgLy8gImVuZFJvdW5kIgoJYXBwX2dsb2JhbF9nZXQKCTwKCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5MwoJLy8gYXNzZXJ0KHF1YW5pdHkgPiAwKQoJZnJhbWVfZGlnIC0yIC8vIHF1YW5pdHk6IHVpbnQ2NAoJaW50IDAKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5NQoJLy8gYXNzZXJ0KHBheW1lbnQuYW1vdW50ID09PSB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogcXVhbml0eSkKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIEFtb3VudAoJYnl0ZSAweDc0Njk2MzZiNjU3NDUwNzI2OTYzNjUgLy8gInRpY2tldFByaWNlIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtMiAvLyBxdWFuaXR5OiB1aW50NjQKCSoKCT09Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTYKCS8vIGFzc2VydChwYXltZW50LnNlbmRlciA9PT0gdGhpcy50eG4uc2VuZGVyKQoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCgl0eG4gU2VuZGVyCgk9PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjk3CgkvLyBhc3NlcnQocGF5bWVudC5yZWNlaXZlciA9PT0gdGhpcy5hcHAuYWRkcmVzcykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFJlY2VpdmVyCglnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5OQoJLy8gYXNzZXJ0KCF0aGlzLnRpY2tldHMocGF5bWVudC5zZW5kZXIpLmV4aXN0cykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJYm94X2xlbgoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAxCgkvLyBuZXdUb3RhbCA9IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlICsgcXVhbml0eSArIDEKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9kaWcgLTIgLy8gcXVhbml0eTogdWludDY0CgkrCglpbnQgMQoJKwoJZnJhbWVfYnVyeSAtMyAvLyBuZXdUb3RhbDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwMwoJLy8gdGhpcy50aWNrZXRzKHBheW1lbnQuc2VuZGVyKS52YWx1ZSA9IHsgc3RhcnQ6IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlLCBlbmQ6IG5ld1RvdGFsIC0gMSB9CglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBTZW5kZXIKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWFwcF9nbG9iYWxfZ2V0CglpdG9iCglmcmFtZV9kaWcgLTMgLy8gbmV3VG90YWw6IHVpbnQ2NAoJaW50IDEKCS0KCWl0b2IKCWNvbmNhdAoJYm94X3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDQKCS8vIHRoaXMudG90YWxUaWNrZXRzLnZhbHVlID0gbmV3VG90YWwKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWZyYW1lX2RpZyAtMyAvLyBuZXdUb3RhbDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgpnZXRSYW5kb21CeXRlczoKCXByb3RvIDAgMAoKCS8vIGlmMF9jb25kaXRpb24KCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDkKCS8vIHRoaXMucmFuZG9tQnl0ZXMuZXhpc3RzCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCglieiBpZjBfZWxzZQoKCS8vIGlmMF9jb25zZXF1ZW50CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTEwCgkvLyB0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlID0gc2hhMjU2KHRoaXMucmFuZG9tQnl0ZXMudmFsdWUpIGFzIGJ5dGVzCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglhcHBfZ2xvYmFsX2dldAoJc2hhMjU2CglhcHBfZ2xvYmFsX3B1dAoJYiBpZjBfZW5kCgppZjBfZWxzZToKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMTIKCS8vIHRoaXMucmFuZG9tQnl0ZXMudmFsdWUgPSBzZW5kTWV0aG9kQ2FsbDxbdWludDY0LCBieXRlc10sIGJ5dGVzPih7CgkvLyAgICAgICAgIG5hbWU6ICdtdXN0X2dldCcsCgkvLyAgICAgICAgIG1ldGhvZEFyZ3M6IFt0aGlzLmRyYXdSb3VuZC52YWx1ZSwgJyddLAoJLy8gICAgICAgICBhcHBsaWNhdGlvbklEOiBBcHBsaWNhdGlvbi5mcm9tSUQodGhpcy5yYW5kb21uZXNzT3JhY2xlLnZhbHVlKSwKCS8vICAgICAgICAgZmVlOiAwLAoJLy8gICAgICAgICBvbkNvbXBsZXRpb246ICdOb09wJywKCS8vICAgICAgIH0pCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglpdHhuX2JlZ2luCglpbnQgYXBwbAoJaXR4bl9maWVsZCBUeXBlRW51bQoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCWl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExNAoJLy8gbWV0aG9kQXJnczogW3RoaXMuZHJhd1JvdW5kLnZhbHVlLCAnJ10KCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpdG9iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoJYnl0ZSAweDAwMDAKCWl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExNQoJLy8gYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSkKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWFwcF9nbG9iYWxfZ2V0CglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uSUQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTE2CgkvLyBmZWU6IDAKCWludCAwCglpdHhuX2ZpZWxkIEZlZQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMTcKCS8vIG9uQ29tcGxldGlvbjogJ05vT3AnCglpbnQgTm9PcAoJaXR4bl9maWVsZCBPbkNvbXBsZXRpb24KCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglpdHhuIE51bUxvZ3MKCWludCAxCgktCglpdHhuYXMgTG9ncwoJZXh0cmFjdCA0IDAKCWFwcF9nbG9iYWxfcHV0CgppZjBfZW5kOgoJcmV0c3ViCgovLyBkcmF3KClib29sCi8vCi8vIERyYXcgdGhlIHdpbm5pbmcgdGlja2V0CmFiaV9yb3V0ZV9kcmF3OgoJYnl0ZSAweDsgZHVwbiAzIC8vIHB1c2ggZW1wdHkgYnl0ZXMgdG8gZmlsbCB0aGUgc3RhY2sgZnJhbWUgZm9yIHRoaXMgc3Vicm91dGluZSdzIGxvY2FsIHZhcmlhYmxlcwoKCS8vIGV4ZWN1dGUgZHJhdygpYm9vbAoJY2FsbHN1YiBkcmF3CglpbnQgMQoJcmV0dXJuCgpkcmF3OgoJcHJvdG8gNCAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNAoJLy8gYXNzZXJ0KCF0aGlzLndpbm5pbmdUaWNrZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNQoJLy8gdGhpcy5nZXRSYW5kb21CeXRlcygpCgljYWxsc3ViIGdldFJhbmRvbUJ5dGVzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyOQoJLy8gbiA9IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfYnVyeSAtMSAvLyBuOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTMxCgkvLyBvZmZzZXQgPSAwCglpbnQgMAoJZnJhbWVfYnVyeSAtMyAvLyBvZmZzZXQ6IHVpbnQ2NAoKZG9fd2hpbGVfMDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzUKCS8vIHggPSBleHRyYWN0X3VpbnQ2NCh0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlLCBvZmZzZXQpCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0zIC8vIG9mZnNldDogdWludDY0CglleHRyYWN0X3VpbnQ2NAoJZnJhbWVfYnVyeSAtMiAvLyB4OiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTM3CgkvLyBvZmZzZXQgPSBvZmZzZXQgKyA4CglmcmFtZV9kaWcgLTMgLy8gb2Zmc2V0OiB1aW50NjQKCWludCA4CgkrCglmcmFtZV9idXJ5IC0zIC8vIG9mZnNldDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEzOQoJLy8gbWF4Q29uZGl0aW9uID0geCA+IFJBTkRfTUFYIC0gKCgoUkFORF9NQVggJSBuKSArIDEpICUgbikKCWZyYW1lX2RpZyAtMiAvLyB4OiB1aW50NjQKCWludCAxOF80NDZfNzQ0XzA3M183MDlfNTUxXzYxNQoJaW50IDE4XzQ0Nl83NDRfMDczXzcwOV81NTFfNjE1CglmcmFtZV9kaWcgLTEgLy8gbjogdWludDY0CgklCglpbnQgMQoJKwoJZnJhbWVfZGlnIC0xIC8vIG46IHVpbnQ2NAoJJQoJLQoJPgoJZnJhbWVfYnVyeSAtNCAvLyBtYXhDb25kaXRpb246IGJvb2wKCWZyYW1lX2RpZyAtNCAvLyBtYXhDb25kaXRpb246IGJvb2wKCWR1cAoJYnogc2tpcF9hbmQwCglmcmFtZV9kaWcgLTMgLy8gb2Zmc2V0OiB1aW50NjQKCWludCAzMgoJPAoJJiYKCnNraXBfYW5kMDoKCWJueiBkb193aGlsZV8wCgoJLy8gaWYxX2NvbmRpdGlvbgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0MgoJLy8gbWF4Q29uZGl0aW9uCglmcmFtZV9kaWcgLTQgLy8gbWF4Q29uZGl0aW9uOiBib29sCglieiBpZjFfZW5kCgoJLy8gaWYxX2NvbnNlcXVlbnQKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNDIKCS8vIHJldHVybiBmYWxzZTsKCWludCAwCglieXRlIDB4MDAKCWludCAwCgl1bmNvdmVyIDIKCXNldGJpdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgppZjFfZW5kOgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0NAoJLy8gdGhpcy53aW5uaW5nVGlja2V0LnZhbHVlID0geCAlIG4KCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWZyYW1lX2RpZyAtMiAvLyB4OiB1aW50NjQKCWZyYW1lX2RpZyAtMSAvLyBuOiB1aW50NjQKCSUKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0NQoJLy8gcmV0dXJuIHRydWU7CglpbnQgMQoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKLy8gY2xhaW0oKXZvaWQKLy8KLy8gU2VuZCB0aGUgYXNzZXQgdG8gdGhlIHRoZSBzZW5kZXIgaWYgdGhleSBoYXZlIHRoZSB3aW5uaW5nIHRpY2tldAphYmlfcm91dGVfY2xhaW06CglieXRlIDB4IC8vIHB1c2ggZW1wdHkgYnl0ZXMgdG8gZmlsbCB0aGUgc3RhY2sgZnJhbWUgZm9yIHRoaXMgc3Vicm91dGluZSdzIGxvY2FsIHZhcmlhYmxlcwoKCS8vIGV4ZWN1dGUgY2xhaW0oKXZvaWQKCWNhbGxzdWIgY2xhaW0KCWludCAxCglyZXR1cm4KCmNsYWltOgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE1MAoJLy8gdGlja2V0UmFuZ2UgPSB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS52YWx1ZQoJdHhuIFNlbmRlcgoJZnJhbWVfYnVyeSAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUyCgkvLyBhc3NlcnQodGlja2V0UmFuZ2Uuc3RhcnQgPD0gdGhpcy53aW5uaW5nVGlja2V0LnZhbHVlKQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDAgOAoJYnRvaQoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXQKCTw9Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyBhc3NlcnQodGlja2V0UmFuZ2UuZW5kID49IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCWJveF9nZXQKCWFzc2VydAoJZXh0cmFjdCA4IDgKCWJ0b2kKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0Cgk+PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE1NQoJLy8gc2VuZEFzc2V0VHJhbnNmZXIoewoJLy8gICAgICAgYXNzZXRSZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgeGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlLAoJLy8gICAgICAgYXNzZXRBbW91bnQ6IHRoaXMuYXBwLmFkZHJlc3MuYXNzZXRCYWxhbmNlKHRoaXMuYXNzZXQudmFsdWUpLAoJLy8gICAgICAgYXNzZXRDbG9zZVRvOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICBmZWU6IDAsCgkvLyAgICAgfSkKCWl0eG5fYmVnaW4KCWludCBheGZlcgoJaXR4bl9maWVsZCBUeXBlRW51bQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTYKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlcgoJdHhuIFNlbmRlcgoJaXR4bl9maWVsZCBBc3NldFJlY2VpdmVyCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE1NwoJLy8geGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlCglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJaXR4bl9maWVsZCBYZmVyQXNzZXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTU4CgkvLyBhc3NldEFtb3VudDogdGhpcy5hcHAuYWRkcmVzcy5hc3NldEJhbGFuY2UodGhpcy5hc3NldC52YWx1ZSkKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRCYWxhbmNlCglhc3NlcnQKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTU5CgkvLyBhc3NldENsb3NlVG86IHRoaXMudHhuLnNlbmRlcgoJdHhuIFNlbmRlcgoJaXR4bl9maWVsZCBBc3NldENsb3NlVG8KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTYwCgkvLyBmZWU6IDAKCWludCAwCglpdHhuX2ZpZWxkIEZlZQoKCS8vIFN1Ym1pdCBpbm5lciB0cmFuc2FjdGlvbgoJaXR4bl9zdWJtaXQKCXJldHN1YgoKLy8gZ2V0UmVmdW5kKCl2b2lkCi8vCi8vIEFsbG93cyBwdXJjaGFzZXJzIHRvIGdldCBhIHJlZnVuZCBpZiB0aGUgd2lubmluZyB0aWNrZXQgaGFzIG5vdCBiZWVuIGRyYXduCi8vIGFuZCAxNTEyIHJvdW5kcyBoYXZlIHBhc3NlZCBzaW5jZSB0aGUgZHJhdyByb3VuZCwgbWVhbmluZyB0aGUgb3JhY2xlIG5vCi8vIGxvbmdlciBoYXMgdGhlIGRhdGEgZm9yIHRoZSBkcmF3IHJvdW5kCmFiaV9yb3V0ZV9nZXRSZWZ1bmQ6CglieXRlIDB4OyBkdXAgLy8gcHVzaCBlbXB0eSBieXRlcyB0byBmaWxsIHRoZSBzdGFjayBmcmFtZSBmb3IgdGhpcyBzdWJyb3V0aW5lJ3MgbG9jYWwgdmFyaWFibGVzCgoJLy8gZXhlY3V0ZSBnZXRSZWZ1bmQoKXZvaWQKCWNhbGxzdWIgZ2V0UmVmdW5kCglpbnQgMQoJcmV0dXJuCgpnZXRSZWZ1bmQ6Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTcwCgkvLyBhc3NlcnQoIXRoaXMud2lubmluZ1RpY2tldC5leGlzdHMpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTcxCgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA+IHRoaXMuZHJhd1JvdW5kLnZhbHVlICsgMTUxMikKCWdsb2JhbCBSb3VuZAoJYnl0ZSAweDY0NzI2MTc3NTI2Zjc1NmU2NCAvLyAiZHJhd1JvdW5kIgoJYXBwX2dsb2JhbF9nZXQKCWludCAxNTEyCgkrCgk+Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTczCgkvLyB0aWNrZXRSYW5nZSA9IHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLnZhbHVlCgl0eG4gU2VuZGVyCglmcmFtZV9idXJ5IC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNzQKCS8vIHRpY2tldENvdW50ID0gdGlja2V0UmFuZ2UuZW5kIC0gdGlja2V0UmFuZ2Uuc3RhcnQgKyAxCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgOCA4CglidG9pCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgMCA4CglidG9pCgktCglpbnQgMQoJKwoJZnJhbWVfYnVyeSAtMiAvLyB0aWNrZXRDb3VudDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3NgoJLy8gdGhpcy50aWNrZXRzKHRoaXMudHhuLnNlbmRlcikuZGVsZXRlKCkKCXR4biBTZW5kZXIKCWJveF9kZWwKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTc4CgkvLyBzZW5kUGF5bWVudCh7CgkvLyAgICAgICBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiB0aWNrZXRDb3VudCwKCS8vICAgICAgIHJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICBmZWU6IDAsCgkvLyAgICAgfSkKCWl0eG5fYmVnaW4KCWludCBwYXkKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTc5CgkvLyBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiB0aWNrZXRDb3VudAoJYnl0ZSAweDc0Njk2MzZiNjU3NDUwNzI2OTYzNjUgLy8gInRpY2tldFByaWNlIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtMiAvLyB0aWNrZXRDb3VudDogdWludDY0CgkqCglpdHhuX2ZpZWxkIEFtb3VudAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxODAKCS8vIHJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgUmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTgxCgkvLyBmZWU6IDAKCWludCAwCglpdHhuX2ZpZWxkIEZlZQoKCS8vIFN1Ym1pdCBpbm5lciB0cmFuc2FjdGlvbgoJaXR4bl9zdWJtaXQKCXJldHN1YgoKY3JlYXRlX05vT3A6CgltZXRob2QgImNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZCIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbgoJZXJyCgpjYWxsX05vT3A6CgltZXRob2QgInNldEFzc2V0KGFzc2V0KXZvaWQiCgltZXRob2QgInN0YXJ0UmFmZmxlKHVpbnQ2NCx1aW50NjQpdm9pZCIKCW1ldGhvZCAiYnV5VGlja2V0cyhwYXksdWludDY0KXZvaWQiCgltZXRob2QgImRyYXcoKWJvb2wiCgltZXRob2QgImNsYWltKCl2b2lkIgoJbWV0aG9kICJnZXRSZWZ1bmQoKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc2V0QXNzZXQgYWJpX3JvdXRlX3N0YXJ0UmFmZmxlIGFiaV9yb3V0ZV9idXlUaWNrZXRzIGFiaV9yb3V0ZV9kcmF3IGFiaV9yb3V0ZV9jbGFpbSBhYmlfcm91dGVfZ2V0UmVmdW5kCgllcnI=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" + }, + "contract": { + "name": "NFTRaffle", + "desc": "", + "methods": [ + { + "name": "createApplication", + "args": [ + { + "name": "ticketPrice", + "type": "uint64", + "desc": "The price of a single ticket (uALGO)" + }, + { + "name": "randomnessOracle", + "type": "uint64", + "desc": "The app ID of the randomness oracle" + } + ], + "desc": "Create the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "setAsset", + "args": [ + { + "name": "asset", + "type": "asset", + "desc": "The asset to be raffled" + } + ], + "desc": "Set the asset to be raffled", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "startRaffle", + "args": [ + { + "name": "end", + "type": "uint64", + "desc": "The round number when the raffle ends" + }, + { + "name": "draw", + "type": "uint64", + "desc": "The round number when the raffle is drawn" + } + ], + "desc": "Start the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "buyTickets", + "args": [ + { + "name": "payment", + "type": "pay", + "desc": "The payment for the tickets" + }, + { + "name": "quanity", + "type": "uint64", + "desc": "The number of tickets to buy" + } + ], + "desc": "Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed.", + "returns": { + "type": "void", + "desc": "The total number of tickets owned by the sender" + } + }, + { + "name": "draw", + "args": [], + "desc": "Draw the winning ticket", + "returns": { + "type": "bool", + "desc": "" + } + }, + { + "name": "claim", + "args": [], + "desc": "Send the asset to the the sender if they have the winning ticket", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "getRefund", + "args": [], + "desc": "Allows purchasers to get a refund if the winning ticket has not been drawnand 1512 rounds have passed since the draw round, meaning the oracle nolonger has the data for the draw round", + "returns": { + "type": "void", + "desc": "" + } + } + ] + } +} \ No newline at end of file diff --git a/examples/raffle/artifacts/NFTRaffle.arc4.json b/examples/raffle/artifacts/NFTRaffle.arc4.json new file mode 100644 index 000000000..06a4af2c1 --- /dev/null +++ b/examples/raffle/artifacts/NFTRaffle.arc4.json @@ -0,0 +1,108 @@ +{ + "name": "NFTRaffle", + "desc": "", + "methods": [ + { + "name": "createApplication", + "args": [ + { + "name": "ticketPrice", + "type": "uint64", + "desc": "The price of a single ticket (uALGO)" + }, + { + "name": "randomnessOracle", + "type": "uint64", + "desc": "The app ID of the randomness oracle" + } + ], + "desc": "Create the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "setAsset", + "args": [ + { + "name": "asset", + "type": "asset", + "desc": "The asset to be raffled" + } + ], + "desc": "Set the asset to be raffled", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "startRaffle", + "args": [ + { + "name": "end", + "type": "uint64", + "desc": "The round number when the raffle ends" + }, + { + "name": "draw", + "type": "uint64", + "desc": "The round number when the raffle is drawn" + } + ], + "desc": "Start the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "buyTickets", + "args": [ + { + "name": "payment", + "type": "pay", + "desc": "The payment for the tickets" + }, + { + "name": "quanity", + "type": "uint64", + "desc": "The number of tickets to buy" + } + ], + "desc": "Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed.", + "returns": { + "type": "void", + "desc": "The total number of tickets owned by the sender" + } + }, + { + "name": "draw", + "args": [], + "desc": "Draw the winning ticket", + "returns": { + "type": "bool", + "desc": "" + } + }, + { + "name": "claim", + "args": [], + "desc": "Send the asset to the the sender if they have the winning ticket", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "getRefund", + "args": [], + "desc": "Allows purchasers to get a refund if the winning ticket has not been drawnand 1512 rounds have passed since the draw round, meaning the oracle nolonger has the data for the draw round", + "returns": { + "type": "void", + "desc": "" + } + } + ] +} \ No newline at end of file diff --git a/examples/raffle/artifacts/NFTRaffle.clear.teal b/examples/raffle/artifacts/NFTRaffle.clear.teal index 6bbec507a..858e5674c 100644 --- a/examples/raffle/artifacts/NFTRaffle.clear.teal +++ b/examples/raffle/artifacts/NFTRaffle.clear.teal @@ -1,2 +1 @@ -#pragma version 9 -int 1 \ No newline at end of file +#pragma version 9 \ No newline at end of file diff --git a/examples/raffle/artifacts/NFTRaffle.src_map.json b/examples/raffle/artifacts/NFTRaffle.src_map.json index 1ec452ccf..d235eaeb6 100644 --- a/examples/raffle/artifacts/NFTRaffle.src_map.json +++ b/examples/raffle/artifacts/NFTRaffle.src_map.json @@ -1,22 +1,3023 @@ -{ - "pc": { - "version": 3, - "sources": [ - "raffle.algo.ts" - ], - "names": [], - "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCoB;;;AAAlB;AAAA;;;AAAA;AAAA;AAAA;;;AACE;;AACA;;AAAA;AAAA;;AASF;;AAAS;AAAA;AAAA;;;;AAAT;;AAXkB;;;AAChB;AAWQ;AAAA;;;AAAA;;;AAER;AAAA;AAAA;AAAA;AAFQ;AADV;AAImB;AACf;;AAhBJ;;AAgBe;;;;;AACX;AALK;;AAGmB;;AAM1B;;AAVF;;;AAoBA;;;AAAY;AAAZ;;;AApBA;AAUE;AAWO;;;;AAAA;;;AAAA;AAAkD;;;AAAF;AAAhD;AAlBP;;;AAoBc;;;AACd;;AAAA;AAAA;AAAA;AAlBe;;AAesB;AAIrC;AAAA;AAAA;AALF;;;;AAkBW;AAAA;AAAA;;;;AAAA;AAAX;;;;AAlByB;AAAA;AAmBhB;AAAc;;;AAAd;AADmB;;AAAA;AAEnB;AAAU;AAAF;;AAAR;AAFE;AAAA;AAIF;;;AAAQ;AAAW;AAAA;;;AAAJ;;AACf;;AAAQ;AAAoB;AAAb;AAAf;;;AACqB;AAAA;AAAS;;AAErC;;AAAqB;;AAAQ;AAArB;;AAAA;AAAA;AAAA;AAAD;;AAEU;;AAAoC;;AAAF;AAAE;AAAF;;AAEtC;;AAAQ;;;AAArB;;AAAA;AAA8C;AAA8B;AAAW;;;;AAZ9E;AA5BT;AAyCA;AAAA;AAAA;AAbF;;AAiBA;;AAAA;AAAA;AAnCY;AAhBR;;AAoDM;;;;AAAA;AAAD;AAZQ;AArBR;;AAmCQ;AAAA;AAAA;AACb;AAAA;AATmC;AAUtB;;AAAA;AAAsB;AAAA;AAAA;;;AAAA;AAAA;AAAA;;;AACE;;;AACrC;AAAK;AAAL;AANM;AAAA;AAOQ;AAAd;AALa;AAAA;;AAAA;;;;;;AAAT;;AAdC;;;AA0BwC;AAAA;;AAAF;AAAA;AAA7C;AAfF;AAmBA;;;AAAA;AAAA;AAAA;;AAAA;;AACsB;AAAA;;AAAa;AAAb;;AAAA;;;AAEb;AAAA;;AAAA;AAAA;AAAA;;AAAqB;;;AAAA;;AAAH;AAFL;;AAAA;AAAA;AAGb;AAAA;;;AAAA;AAAA;AAAA;;;AAAmB;AAAA;AAAH;;;AAvBzB;;AA0BI;;AAjCuC;;AAkCvC;AAAW;AAAA;;AAAX;AA3EA;AAsEK;AAMQ;;AAAA;AAAS;AAAqB;AAAA;AAA9B;AAAA;AAAb;AA/DJ;AAAA;;AAiEI;AAAK;AAAL;;AALF;AANF;AAoBA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AApDmD;AAkBZ;AAmC7B;AAAA;;;AAAD;;AAfP;;;;AAgB8C;AAEJ;AAvBtB;;AAuBA;;;AAAA;;AACA;AAAA;;;;AAAA;AAAA;;AAAA;;AADA;;AAAA;AACkB;;AAAA;AAAA;AAAA;;AAAF;;;AAAsB;AAAF;AAAE;;;AA7D5D;;;AAiEE;AAjEF;AAiEE;AAAA;AAAA;AARQ;AAAA;;;;AASN;AARqB;;;AAAA;AASF;AAAnB;AATmB;;;;AAFvB;;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAIsB;AA3Eb;AA6DL;;AAeoC;;;AAxBlB;;AALpB;AAAA;AAA+C;AA6BT;AAvCvB;AAAA;AAAA;AA5DjB;;AAqBkB;;;AAgFM;;AA9CxB;;AAAA;;;AAmBA;;AA8BY;AAAyB;;AAAF;;;;AA7D1B;;;AA+DA;AAAL;AAHF;;;;;;AAhEuB;;;AAuDzB;;;;AAAA;AAAA;;;;;;;;;;;;;;;;;;AAtCU;;;;;;AANK;;;;;;AANN;;;;;;AAcQ;;;AAAA;;;;;;;;;;;;;;AAAA;AAyCK", - "file": "NFTRaffle.approval.teal", - "sourceRoot": "" - }, - "teal": { - "version": 3, - "sources": [ - "raffle.algo.ts" - ], - "names": [], - "mappings": ";;;;;;;;;;;;;;;;AAoCoB;AAAlB;AAAA;AAAA;AAAA;AAAA;;;AACE;;;;AACA;AAAA;AAAA;;;;AASF;AAAS;AAAA;AAAA;;;;;AAAT;AAXkB;AAChB;AAWQ;AAAA;;;AAAA;;;;AAER;AAAA;AAAA;AAAA;AAFQ;AADV;AAImB;;;;AACf;AAhBJ;AAgBe;;;;;AACX;AALK;AAGmB;;;;AAM1B;AAVF;;;;;AAoBA;;;;;AAAY;AAAZ;;;;;AApBA;AAUE;AAWO;;;;;AAAA;AAAA;AAAkD;AAAF;AAAhD;AAlBP;;;AAoBc;;;;AACd;AAAA;AAAA;AAAA;AAlBe;AAesB;AAIrC;AAAA;AAAA;AALF;;;;;AAkBW;AAAA;AAAA;;;;;AAAA;AAAX;;;;;AAlByB;AAAA;AAmBhB;;;AAAc;AAAd;AADmB;AAAA;AAEnB;AAAU;AAAF;AAAR;AAFE;AAAA;AAIF;AAAQ;AAAW;AAAA;;;AAAJ;;;;AACf;AAAQ;AAAoB;AAAb;AAAf;;;;;AACqB;AAAA;AAAS;;;;AAErC;AAAqB;AAAQ;AAArB;AAAA;AAAA;AAAA;AAAD;;;;AAEU;AAAoC;AAAF;AAAE;AAAF;;;;AAEtC;AAAQ;AAArB;AAAA;AAA8C;AAA8B;AAAW;;;;;AAZ9E;AA5BT;AAyCA;AAAA;AAAA;AAbF;;;;;AAiBA;AAAA;AAAA;AAnCY;AAhBR;AAoDM;;;;;AAAA;AAAD;AAZQ;AArBR;AAmCQ;AAAA;AAAA;AACb;AAAA;AATmC;;;;AAUtB;AAAA;AAAsB;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;AACE;;;;AACrC;AAAK;AAAL;AANM;AAAA;AAOQ;AAAd;;;;AALa;AAAA;AAAA;AAAT;AAdC;;;;;AA0BwC;AAAA;AAAF;AAAA;AAA7C;AAfF;AAmBA;AAAA;AAAA;AAAA;AAAA;;;;AACsB;AAAA;AAAa;;;;AAAb;AAAA;;;;;AAEb;AAAA;AAAA;AAAA;AAAA;AAAqB;AAAA;AAAH;;;;AAFL;AAAA;AAAA;AAGb;AAAA;;;AAAA;AAAA;;;AAAA;AAAmB;AAAA;AAAH;;;AAvBzB;;;;AA0BI;AAjCuC;;;;AAkCvC;AAAW;AAAA;AAAX;AA3EA;AAsEK;AAMQ;AAAA;AAAS;AAAqB;AAAA;AAA9B;AAAA;AAAb;AA/DJ;AAAA;;;;AAiEI;AAAK;AAAL;AALF;AANF;AAoBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AApDmD;AAkBZ;AAmC7B;AAAA;;;;;AAAD;AAfP;;;;;AAgB8C;;;;AAEJ;AAvBtB;AAuBA;;;;AAAA;AACA;AAAA;;;AAAA;AAAA;AAAA;;;;AADA;AAAA;;;;AACkB;AAAA;AAAA;AAAA;;;AAAF;AAAsB;AAAF;AAAE;;;AA7D5D;;;;AAiEE;AAjEF;AAiEE;AAAA;AAAA;AARQ;AAAA;;;;;AASN;AARqB;AAAA;AASF;AAAnB;AATmB;;;;;AAFvB;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIsB;AA3Eb;AA6DL;AAeoC;;;AAxBlB;AALpB;AAAA;AAA+C;AA6BT;AAvCvB;AAAA;AAAA;AA5DjB;AAqBkB;;;;;AAgFM;;;;;AA9CxB;AAAA;;;;;AAmBA;AA8BY;AAAyB;AAAF;;;;;AA7D1B;;;;;AA+DA;AAAL;AAHF;;;AAhEuB;AAuDzB;AAAA;AAAA;;;;;AAtCU;AANK;AANN;AAcQ;AAAA;AAAA;AAyCK", - "file": "NFTRaffle.approval.teal", - "sourceRoot": "" +[ + { + "teal": 1, + "source": 8, + "pc": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119 + ] + }, + { + "teal": 13, + "source": 8, + "pc": [ + 120, + 121 + ] + }, + { + "teal": 14, + "source": 8, + "pc": [ + 122 + ] + }, + { + "teal": 15, + "source": 8, + "pc": [ + 123 + ] + }, + { + "teal": 16, + "source": 8, + "pc": [ + 124 + ] + }, + { + "teal": 17, + "source": 8, + "pc": [ + 125 + ] + }, + { + "teal": 18, + "source": 8, + "pc": [ + 126, + 127 + ] + }, + { + "teal": 19, + "source": 8, + "pc": [ + 128 + ] + }, + { + "teal": 20, + "source": 8, + "pc": [ + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144 + ] + }, + { + "teal": 23, + "source": 8, + "pc": [ + 145 + ] + }, + { + "teal": 33, + "source": 42, + "pc": [ + 146, + 147, + 148 + ] + }, + { + "teal": 34, + "source": 42, + "pc": [ + 149 + ] + }, + { + "teal": 37, + "source": 42, + "pc": [ + 150, + 151, + 152 + ] + }, + { + "teal": 38, + "source": 42, + "pc": [ + 153 + ] + }, + { + "teal": 41, + "source": 42, + "pc": [ + 154, + 155, + 156 + ] + }, + { + "teal": 42, + "source": 42, + "pc": [ + 157 + ] + }, + { + "teal": 43, + "source": 42, + "pc": [ + 158 + ] + }, + { + "teal": 46, + "source": 42, + "pc": [ + 159, + 160, + 161 + ] + }, + { + "teal": 50, + "source": 43, + "pc": [ + 162, + 163 + ] + }, + { + "teal": 51, + "source": 43, + "pc": [ + 164, + 165 + ] + }, + { + "teal": 52, + "source": 43, + "pc": [ + 166 + ] + }, + { + "teal": 56, + "source": 44, + "pc": [ + 167, + 168 + ] + }, + { + "teal": 57, + "source": 44, + "pc": [ + 169, + 170 + ] + }, + { + "teal": 58, + "source": 44, + "pc": [ + 171 + ] + }, + { + "teal": 59, + "source": 42, + "pc": [ + 172 + ] + }, + { + "teal": 68, + "source": 53, + "pc": [ + 173, + 174, + 175 + ] + }, + { + "teal": 69, + "source": 53, + "pc": [ + 176 + ] + }, + { + "teal": 70, + "source": 53, + "pc": [ + 177, + 178 + ] + }, + { + "teal": 73, + "source": 53, + "pc": [ + 179, + 180, + 181 + ] + }, + { + "teal": 74, + "source": 53, + "pc": [ + 182 + ] + }, + { + "teal": 75, + "source": 53, + "pc": [ + 183 + ] + }, + { + "teal": 78, + "source": 53, + "pc": [ + 184, + 185, + 186 + ] + }, + { + "teal": 82, + "source": 54, + "pc": [ + 187, + 188, + 189 + ] + }, + { + "teal": 83, + "source": 54, + "pc": [ + 190 + ] + }, + { + "teal": 84, + "source": 54, + "pc": [ + 191 + ] + }, + { + "teal": 85, + "source": 54, + "pc": [ + 192 + ] + }, + { + "teal": 86, + "source": 54, + "pc": [ + 193 + ] + }, + { + "teal": 87, + "source": 54, + "pc": [ + 194 + ] + }, + { + "teal": 88, + "source": 54, + "pc": [ + 195 + ] + }, + { + "teal": 97, + "source": 56, + "pc": [ + 196 + ] + }, + { + "teal": 98, + "source": 56, + "pc": [ + 197 + ] + }, + { + "teal": 99, + "source": 56, + "pc": [ + 198, + 199 + ] + }, + { + "teal": 103, + "source": 57, + "pc": [ + 200, + 201 + ] + }, + { + "teal": 104, + "source": 57, + "pc": [ + 202, + 203 + ] + }, + { + "teal": 108, + "source": 58, + "pc": [ + 204, + 205 + ] + }, + { + "teal": 109, + "source": 58, + "pc": [ + 206, + 207 + ] + }, + { + "teal": 113, + "source": 59, + "pc": [ + 208 + ] + }, + { + "teal": 114, + "source": 59, + "pc": [ + 209, + 210 + ] + }, + { + "teal": 118, + "source": 60, + "pc": [ + 211 + ] + }, + { + "teal": 119, + "source": 60, + "pc": [ + 212, + 213 + ] + }, + { + "teal": 122, + "source": 56, + "pc": [ + 214 + ] + }, + { + "teal": 126, + "source": 63, + "pc": [ + 215 + ] + }, + { + "teal": 127, + "source": 63, + "pc": [ + 216, + 217 + ] + }, + { + "teal": 128, + "source": 63, + "pc": [ + 218 + ] + }, + { + "teal": 129, + "source": 53, + "pc": [ + 219 + ] + }, + { + "teal": 139, + "source": 73, + "pc": [ + 220, + 221, + 222 + ] + }, + { + "teal": 140, + "source": 73, + "pc": [ + 223 + ] + }, + { + "teal": 143, + "source": 73, + "pc": [ + 224, + 225, + 226 + ] + }, + { + "teal": 144, + "source": 73, + "pc": [ + 227 + ] + }, + { + "teal": 147, + "source": 73, + "pc": [ + 228, + 229, + 230 + ] + }, + { + "teal": 148, + "source": 73, + "pc": [ + 231 + ] + }, + { + "teal": 149, + "source": 73, + "pc": [ + 232 + ] + }, + { + "teal": 152, + "source": 73, + "pc": [ + 233, + 234, + 235 + ] + }, + { + "teal": 156, + "source": 74, + "pc": [ + 236, + 237 + ] + }, + { + "teal": 157, + "source": 74, + "pc": [ + 238 + ] + }, + { + "teal": 158, + "source": 74, + "pc": [ + 239 + ] + }, + { + "teal": 159, + "source": 74, + "pc": [ + 240, + 241 + ] + }, + { + "teal": 160, + "source": 74, + "pc": [ + 242 + ] + }, + { + "teal": 161, + "source": 74, + "pc": [ + 243 + ] + }, + { + "teal": 162, + "source": 74, + "pc": [ + 244 + ] + }, + { + "teal": 163, + "source": 74, + "pc": [ + 245 + ] + }, + { + "teal": 167, + "source": 76, + "pc": [ + 246, + 247 + ] + }, + { + "teal": 168, + "source": 76, + "pc": [ + 248, + 249 + ] + }, + { + "teal": 169, + "source": 76, + "pc": [ + 250 + ] + }, + { + "teal": 170, + "source": 76, + "pc": [ + 251 + ] + }, + { + "teal": 174, + "source": 77, + "pc": [ + 252, + 253 + ] + }, + { + "teal": 175, + "source": 77, + "pc": [ + 254, + 255 + ] + }, + { + "teal": 176, + "source": 77, + "pc": [ + 256 + ] + }, + { + "teal": 180, + "source": 78, + "pc": [ + 257, + 258 + ] + }, + { + "teal": 181, + "source": 78, + "pc": [ + 259, + 260 + ] + }, + { + "teal": 182, + "source": 78, + "pc": [ + 261 + ] + }, + { + "teal": 183, + "source": 73, + "pc": [ + 262 + ] + }, + { + "teal": 196, + "source": 91, + "pc": [ + 263 + ] + }, + { + "teal": 199, + "source": 91, + "pc": [ + 264, + 265, + 266 + ] + }, + { + "teal": 200, + "source": 91, + "pc": [ + 267 + ] + }, + { + "teal": 203, + "source": 91, + "pc": [ + 268, + 269 + ] + }, + { + "teal": 204, + "source": 91, + "pc": [ + 270 + ] + }, + { + "teal": 205, + "source": 91, + "pc": [ + 271 + ] + }, + { + "teal": 206, + "source": 91, + "pc": [ + 272 + ] + }, + { + "teal": 207, + "source": 91, + "pc": [ + 273, + 274 + ] + }, + { + "teal": 208, + "source": 91, + "pc": [ + 275 + ] + }, + { + "teal": 209, + "source": 91, + "pc": [ + 276 + ] + }, + { + "teal": 210, + "source": 91, + "pc": [ + 277 + ] + }, + { + "teal": 213, + "source": 91, + "pc": [ + 278, + 279, + 280 + ] + }, + { + "teal": 214, + "source": 91, + "pc": [ + 281 + ] + }, + { + "teal": 215, + "source": 91, + "pc": [ + 282 + ] + }, + { + "teal": 218, + "source": 91, + "pc": [ + 283, + 284, + 285 + ] + }, + { + "teal": 222, + "source": 92, + "pc": [ + 286, + 287 + ] + }, + { + "teal": 223, + "source": 92, + "pc": [ + 288, + 289 + ] + }, + { + "teal": 224, + "source": 92, + "pc": [ + 290 + ] + }, + { + "teal": 225, + "source": 92, + "pc": [ + 291 + ] + }, + { + "teal": 226, + "source": 92, + "pc": [ + 292 + ] + }, + { + "teal": 230, + "source": 93, + "pc": [ + 293, + 294 + ] + }, + { + "teal": 231, + "source": 93, + "pc": [ + 295 + ] + }, + { + "teal": 232, + "source": 93, + "pc": [ + 296 + ] + }, + { + "teal": 233, + "source": 93, + "pc": [ + 297 + ] + }, + { + "teal": 237, + "source": 95, + "pc": [ + 298, + 299 + ] + }, + { + "teal": 238, + "source": 95, + "pc": [ + 300, + 301 + ] + }, + { + "teal": 239, + "source": 95, + "pc": [ + 302, + 303 + ] + }, + { + "teal": 240, + "source": 95, + "pc": [ + 304 + ] + }, + { + "teal": 241, + "source": 95, + "pc": [ + 305, + 306 + ] + }, + { + "teal": 242, + "source": 95, + "pc": [ + 307 + ] + }, + { + "teal": 243, + "source": 95, + "pc": [ + 308 + ] + }, + { + "teal": 244, + "source": 95, + "pc": [ + 309 + ] + }, + { + "teal": 248, + "source": 96, + "pc": [ + 310, + 311 + ] + }, + { + "teal": 249, + "source": 96, + "pc": [ + 312, + 313 + ] + }, + { + "teal": 250, + "source": 96, + "pc": [ + 314, + 315 + ] + }, + { + "teal": 251, + "source": 96, + "pc": [ + 316 + ] + }, + { + "teal": 252, + "source": 96, + "pc": [ + 317 + ] + }, + { + "teal": 256, + "source": 97, + "pc": [ + 318, + 319 + ] + }, + { + "teal": 257, + "source": 97, + "pc": [ + 320, + 321 + ] + }, + { + "teal": 258, + "source": 97, + "pc": [ + 322, + 323 + ] + }, + { + "teal": 259, + "source": 97, + "pc": [ + 324 + ] + }, + { + "teal": 260, + "source": 97, + "pc": [ + 325 + ] + }, + { + "teal": 264, + "source": 99, + "pc": [ + 326, + 327 + ] + }, + { + "teal": 265, + "source": 99, + "pc": [ + 328, + 329 + ] + }, + { + "teal": 266, + "source": 99, + "pc": [ + 330 + ] + }, + { + "teal": 267, + "source": 99, + "pc": [ + 331 + ] + }, + { + "teal": 268, + "source": 99, + "pc": [ + 332 + ] + }, + { + "teal": 269, + "source": 99, + "pc": [ + 333 + ] + }, + { + "teal": 270, + "source": 99, + "pc": [ + 334 + ] + }, + { + "teal": 274, + "source": 101, + "pc": [ + 335, + 336 + ] + }, + { + "teal": 275, + "source": 101, + "pc": [ + 337 + ] + }, + { + "teal": 276, + "source": 101, + "pc": [ + 338, + 339 + ] + }, + { + "teal": 277, + "source": 101, + "pc": [ + 340 + ] + }, + { + "teal": 278, + "source": 101, + "pc": [ + 341 + ] + }, + { + "teal": 279, + "source": 101, + "pc": [ + 342 + ] + }, + { + "teal": 280, + "source": 101, + "pc": [ + 343, + 344 + ] + }, + { + "teal": 284, + "source": 103, + "pc": [ + 345, + 346 + ] + }, + { + "teal": 285, + "source": 103, + "pc": [ + 347, + 348 + ] + }, + { + "teal": 286, + "source": 103, + "pc": [ + 349, + 350 + ] + }, + { + "teal": 287, + "source": 103, + "pc": [ + 351 + ] + }, + { + "teal": 288, + "source": 103, + "pc": [ + 352 + ] + }, + { + "teal": 289, + "source": 103, + "pc": [ + 353, + 354 + ] + }, + { + "teal": 290, + "source": 103, + "pc": [ + 355 + ] + }, + { + "teal": 291, + "source": 103, + "pc": [ + 356 + ] + }, + { + "teal": 292, + "source": 103, + "pc": [ + 357 + ] + }, + { + "teal": 293, + "source": 103, + "pc": [ + 358 + ] + }, + { + "teal": 294, + "source": 103, + "pc": [ + 359 + ] + }, + { + "teal": 298, + "source": 104, + "pc": [ + 360, + 361 + ] + }, + { + "teal": 299, + "source": 104, + "pc": [ + 362, + 363 + ] + }, + { + "teal": 300, + "source": 104, + "pc": [ + 364 + ] + }, + { + "teal": 301, + "source": 91, + "pc": [ + 365 + ] + }, + { + "teal": 304, + "source": 108, + "pc": [ + 366, + 367, + 368 + ] + }, + { + "teal": 309, + "source": 109, + "pc": [ + 369, + 370, + 371 + ] + }, + { + "teal": 310, + "source": 109, + "pc": [ + 372 + ] + }, + { + "teal": 311, + "source": 109, + "pc": [ + 373 + ] + }, + { + "teal": 312, + "source": 109, + "pc": [ + 374 + ] + }, + { + "teal": 313, + "source": 109, + "pc": [ + 375 + ] + }, + { + "teal": 314, + "source": 109, + "pc": [ + 376, + 377, + 378 + ] + }, + { + "teal": 319, + "source": 110, + "pc": [ + 379 + ] + }, + { + "teal": 320, + "source": 110, + "pc": [ + 380 + ] + }, + { + "teal": 321, + "source": 110, + "pc": [ + 381 + ] + }, + { + "teal": 322, + "source": 110, + "pc": [ + 382 + ] + }, + { + "teal": 323, + "source": 110, + "pc": [ + 383 + ] + }, + { + "teal": 324, + "source": 109, + "pc": [ + 384, + 385, + 386 + ] + }, + { + "teal": 335, + "source": 112, + "pc": [ + 387 + ] + }, + { + "teal": 336, + "source": 112, + "pc": [ + 388 + ] + }, + { + "teal": 337, + "source": 112, + "pc": [ + 389 + ] + }, + { + "teal": 338, + "source": 112, + "pc": [ + 390, + 391 + ] + }, + { + "teal": 339, + "source": 113, + "pc": [ + 392, + 393, + 394, + 395, + 396, + 397 + ] + }, + { + "teal": 340, + "source": 113, + "pc": [ + 398, + 399 + ] + }, + { + "teal": 344, + "source": 114, + "pc": [ + 400, + 401 + ] + }, + { + "teal": 345, + "source": 114, + "pc": [ + 402 + ] + }, + { + "teal": 346, + "source": 114, + "pc": [ + 403 + ] + }, + { + "teal": 347, + "source": 114, + "pc": [ + 404, + 405 + ] + }, + { + "teal": 348, + "source": 114, + "pc": [ + 406, + 407, + 408, + 409 + ] + }, + { + "teal": 349, + "source": 114, + "pc": [ + 410, + 411 + ] + }, + { + "teal": 353, + "source": 115, + "pc": [ + 412, + 413 + ] + }, + { + "teal": 354, + "source": 115, + "pc": [ + 414 + ] + }, + { + "teal": 355, + "source": 115, + "pc": [ + 415, + 416 + ] + }, + { + "teal": 359, + "source": 116, + "pc": [ + 417 + ] + }, + { + "teal": 360, + "source": 116, + "pc": [ + 418, + 419 + ] + }, + { + "teal": 364, + "source": 117, + "pc": [ + 420 + ] + }, + { + "teal": 365, + "source": 117, + "pc": [ + 421, + 422 + ] + }, + { + "teal": 368, + "source": 112, + "pc": [ + 423 + ] + }, + { + "teal": 369, + "source": 112, + "pc": [ + 424, + 425 + ] + }, + { + "teal": 370, + "source": 112, + "pc": [ + 426 + ] + }, + { + "teal": 371, + "source": 112, + "pc": [ + 427 + ] + }, + { + "teal": 372, + "source": 112, + "pc": [ + 428, + 429 + ] + }, + { + "teal": 373, + "source": 112, + "pc": [ + 430, + 431, + 432 + ] + }, + { + "teal": 374, + "source": 112, + "pc": [ + 433 + ] + }, + { + "teal": 377, + "source": 108, + "pc": [ + 434 + ] + }, + { + "teal": 383, + "source": 123, + "pc": [ + 435, + 436, + 437 + ] + }, + { + "teal": 386, + "source": 123, + "pc": [ + 438, + 439, + 440 + ] + }, + { + "teal": 387, + "source": 123, + "pc": [ + 441 + ] + }, + { + "teal": 388, + "source": 123, + "pc": [ + 442 + ] + }, + { + "teal": 391, + "source": 123, + "pc": [ + 443, + 444, + 445 + ] + }, + { + "teal": 395, + "source": 124, + "pc": [ + 446, + 447, + 448 + ] + }, + { + "teal": 396, + "source": 124, + "pc": [ + 449 + ] + }, + { + "teal": 397, + "source": 124, + "pc": [ + 450 + ] + }, + { + "teal": 398, + "source": 124, + "pc": [ + 451 + ] + }, + { + "teal": 399, + "source": 124, + "pc": [ + 452 + ] + }, + { + "teal": 400, + "source": 124, + "pc": [ + 453 + ] + }, + { + "teal": 401, + "source": 124, + "pc": [ + 454 + ] + }, + { + "teal": 405, + "source": 125, + "pc": [ + 455, + 456, + 457 + ] + }, + { + "teal": 409, + "source": 129, + "pc": [ + 458, + 459 + ] + }, + { + "teal": 410, + "source": 129, + "pc": [ + 460 + ] + }, + { + "teal": 411, + "source": 129, + "pc": [ + 461, + 462 + ] + }, + { + "teal": 415, + "source": 131, + "pc": [ + 463 + ] + }, + { + "teal": 416, + "source": 131, + "pc": [ + 464, + 465 + ] + }, + { + "teal": 421, + "source": 135, + "pc": [ + 466 + ] + }, + { + "teal": 422, + "source": 135, + "pc": [ + 467 + ] + }, + { + "teal": 423, + "source": 135, + "pc": [ + 468, + 469 + ] + }, + { + "teal": 424, + "source": 135, + "pc": [ + 470 + ] + }, + { + "teal": 425, + "source": 135, + "pc": [ + 471, + 472 + ] + }, + { + "teal": 429, + "source": 137, + "pc": [ + 473, + 474 + ] + }, + { + "teal": 430, + "source": 137, + "pc": [ + 475, + 476 + ] + }, + { + "teal": 431, + "source": 137, + "pc": [ + 477 + ] + }, + { + "teal": 432, + "source": 137, + "pc": [ + 478, + 479 + ] + }, + { + "teal": 436, + "source": 139, + "pc": [ + 480, + 481 + ] + }, + { + "teal": 437, + "source": 5, + "pc": [ + 482, + 483 + ] + }, + { + "teal": 438, + "source": 5, + "pc": [ + 484, + 485 + ] + }, + { + "teal": 439, + "source": 139, + "pc": [ + 486, + 487 + ] + }, + { + "teal": 440, + "source": 139, + "pc": [ + 488 + ] + }, + { + "teal": 441, + "source": 139, + "pc": [ + 489 + ] + }, + { + "teal": 442, + "source": 139, + "pc": [ + 490 + ] + }, + { + "teal": 443, + "source": 139, + "pc": [ + 491, + 492 + ] + }, + { + "teal": 444, + "source": 139, + "pc": [ + 493 + ] + }, + { + "teal": 445, + "source": 139, + "pc": [ + 494 + ] + }, + { + "teal": 446, + "source": 139, + "pc": [ + 495 + ] + }, + { + "teal": 447, + "source": 139, + "pc": [ + 496, + 497 + ] + }, + { + "teal": 448, + "source": 140, + "pc": [ + 498, + 499 + ] + }, + { + "teal": 449, + "source": 140, + "pc": [ + 500 + ] + }, + { + "teal": 450, + "source": 140, + "pc": [ + 501, + 502, + 503 + ] + }, + { + "teal": 451, + "source": 140, + "pc": [ + 504, + 505 + ] + }, + { + "teal": 452, + "source": 140, + "pc": [ + 506, + 507 + ] + }, + { + "teal": 453, + "source": 140, + "pc": [ + 508 + ] + }, + { + "teal": 454, + "source": 140, + "pc": [ + 509 + ] + }, + { + "teal": 457, + "source": 134, + "pc": [ + 510, + 511, + 512 + ] + }, + { + "teal": 462, + "source": 142, + "pc": [ + 513, + 514 + ] + }, + { + "teal": 463, + "source": 142, + "pc": [ + 515, + 516, + 517 + ] + }, + { + "teal": 468, + "source": 142, + "pc": [ + 518 + ] + }, + { + "teal": 469, + "source": 142, + "pc": [ + 519, + 520 + ] + }, + { + "teal": 470, + "source": 142, + "pc": [ + 521 + ] + }, + { + "teal": 471, + "source": 142, + "pc": [ + 522, + 523 + ] + }, + { + "teal": 472, + "source": 142, + "pc": [ + 524 + ] + }, + { + "teal": 473, + "source": 142, + "pc": [ + 525, + 526 + ] + }, + { + "teal": 474, + "source": 142, + "pc": [ + 527 + ] + }, + { + "teal": 475, + "source": 142, + "pc": [ + 528 + ] + }, + { + "teal": 476, + "source": 142, + "pc": [ + 529 + ] + }, + { + "teal": 477, + "source": 142, + "pc": [ + 530 + ] + }, + { + "teal": 482, + "source": 144, + "pc": [ + 531 + ] + }, + { + "teal": 483, + "source": 144, + "pc": [ + 532, + 533 + ] + }, + { + "teal": 484, + "source": 144, + "pc": [ + 534, + 535 + ] + }, + { + "teal": 485, + "source": 144, + "pc": [ + 536 + ] + }, + { + "teal": 486, + "source": 144, + "pc": [ + 537 + ] + }, + { + "teal": 490, + "source": 145, + "pc": [ + 538 + ] + }, + { + "teal": 491, + "source": 145, + "pc": [ + 539, + 540 + ] + }, + { + "teal": 492, + "source": 145, + "pc": [ + 541 + ] + }, + { + "teal": 493, + "source": 145, + "pc": [ + 542, + 543 + ] + }, + { + "teal": 494, + "source": 145, + "pc": [ + 544 + ] + }, + { + "teal": 495, + "source": 145, + "pc": [ + 545, + 546 + ] + }, + { + "teal": 496, + "source": 145, + "pc": [ + 547 + ] + }, + { + "teal": 497, + "source": 145, + "pc": [ + 548 + ] + }, + { + "teal": 498, + "source": 145, + "pc": [ + 549 + ] + }, + { + "teal": 499, + "source": 145, + "pc": [ + 550 + ] + }, + { + "teal": 505, + "source": 149, + "pc": [ + 551 + ] + }, + { + "teal": 508, + "source": 149, + "pc": [ + 552, + 553, + 554 + ] + }, + { + "teal": 509, + "source": 149, + "pc": [ + 555 + ] + }, + { + "teal": 510, + "source": 149, + "pc": [ + 556 + ] + }, + { + "teal": 513, + "source": 149, + "pc": [ + 557, + 558, + 559 + ] + }, + { + "teal": 517, + "source": 150, + "pc": [ + 560, + 561 + ] + }, + { + "teal": 518, + "source": 150, + "pc": [ + 562, + 563 + ] + }, + { + "teal": 522, + "source": 150, + "pc": [ + 564, + 565 + ] + }, + { + "teal": 523, + "source": 150, + "pc": [ + 566 + ] + }, + { + "teal": 524, + "source": 150, + "pc": [ + 567 + ] + }, + { + "teal": 525, + "source": 152, + "pc": [ + 568, + 569, + 570 + ] + }, + { + "teal": 526, + "source": 152, + "pc": [ + 571 + ] + }, + { + "teal": 527, + "source": 152, + "pc": [ + 572 + ] + }, + { + "teal": 528, + "source": 152, + "pc": [ + 573 + ] + }, + { + "teal": 529, + "source": 152, + "pc": [ + 574 + ] + }, + { + "teal": 530, + "source": 152, + "pc": [ + 575 + ] + }, + { + "teal": 534, + "source": 150, + "pc": [ + 576, + 577 + ] + }, + { + "teal": 535, + "source": 150, + "pc": [ + 578 + ] + }, + { + "teal": 536, + "source": 150, + "pc": [ + 579 + ] + }, + { + "teal": 537, + "source": 153, + "pc": [ + 580, + 581, + 582 + ] + }, + { + "teal": 538, + "source": 153, + "pc": [ + 583 + ] + }, + { + "teal": 539, + "source": 153, + "pc": [ + 584 + ] + }, + { + "teal": 540, + "source": 153, + "pc": [ + 585 + ] + }, + { + "teal": 541, + "source": 153, + "pc": [ + 586 + ] + }, + { + "teal": 542, + "source": 153, + "pc": [ + 587 + ] + }, + { + "teal": 552, + "source": 155, + "pc": [ + 588 + ] + }, + { + "teal": 553, + "source": 155, + "pc": [ + 589 + ] + }, + { + "teal": 554, + "source": 155, + "pc": [ + 590, + 591 + ] + }, + { + "teal": 558, + "source": 156, + "pc": [ + 592, + 593 + ] + }, + { + "teal": 559, + "source": 156, + "pc": [ + 594, + 595 + ] + }, + { + "teal": 563, + "source": 157, + "pc": [ + 596 + ] + }, + { + "teal": 564, + "source": 157, + "pc": [ + 597 + ] + }, + { + "teal": 565, + "source": 157, + "pc": [ + 598, + 599 + ] + }, + { + "teal": 569, + "source": 158, + "pc": [ + 600, + 601 + ] + }, + { + "teal": 570, + "source": 158, + "pc": [ + 602 + ] + }, + { + "teal": 571, + "source": 158, + "pc": [ + 603 + ] + }, + { + "teal": 572, + "source": 158, + "pc": [ + 604, + 605 + ] + }, + { + "teal": 573, + "source": 158, + "pc": [ + 606 + ] + }, + { + "teal": 574, + "source": 158, + "pc": [ + 607, + 608 + ] + }, + { + "teal": 578, + "source": 159, + "pc": [ + 609, + 610 + ] + }, + { + "teal": 579, + "source": 159, + "pc": [ + 611, + 612 + ] + }, + { + "teal": 583, + "source": 160, + "pc": [ + 613 + ] + }, + { + "teal": 584, + "source": 160, + "pc": [ + 614, + 615 + ] + }, + { + "teal": 587, + "source": 155, + "pc": [ + 616 + ] + }, + { + "teal": 588, + "source": 149, + "pc": [ + 617 + ] + }, + { + "teal": 596, + "source": 169, + "pc": [ + 618, + 619 + ] + }, + { + "teal": 599, + "source": 169, + "pc": [ + 620, + 621, + 622 + ] + }, + { + "teal": 600, + "source": 169, + "pc": [ + 623 + ] + }, + { + "teal": 601, + "source": 169, + "pc": [ + 624 + ] + }, + { + "teal": 604, + "source": 169, + "pc": [ + 625, + 626, + 627 + ] + }, + { + "teal": 608, + "source": 170, + "pc": [ + 628, + 629, + 630 + ] + }, + { + "teal": 609, + "source": 170, + "pc": [ + 631 + ] + }, + { + "teal": 610, + "source": 170, + "pc": [ + 632 + ] + }, + { + "teal": 611, + "source": 170, + "pc": [ + 633 + ] + }, + { + "teal": 612, + "source": 170, + "pc": [ + 634 + ] + }, + { + "teal": 613, + "source": 170, + "pc": [ + 635 + ] + }, + { + "teal": 614, + "source": 170, + "pc": [ + 636 + ] + }, + { + "teal": 618, + "source": 171, + "pc": [ + 637, + 638 + ] + }, + { + "teal": 619, + "source": 171, + "pc": [ + 639, + 640 + ] + }, + { + "teal": 620, + "source": 171, + "pc": [ + 641 + ] + }, + { + "teal": 621, + "source": 171, + "pc": [ + 642, + 643, + 644 + ] + }, + { + "teal": 622, + "source": 171, + "pc": [ + 645 + ] + }, + { + "teal": 623, + "source": 171, + "pc": [ + 646 + ] + }, + { + "teal": 624, + "source": 171, + "pc": [ + 647 + ] + }, + { + "teal": 628, + "source": 173, + "pc": [ + 648, + 649 + ] + }, + { + "teal": 629, + "source": 173, + "pc": [ + 650, + 651 + ] + }, + { + "teal": 633, + "source": 173, + "pc": [ + 652, + 653 + ] + }, + { + "teal": 634, + "source": 173, + "pc": [ + 654 + ] + }, + { + "teal": 635, + "source": 173, + "pc": [ + 655 + ] + }, + { + "teal": 636, + "source": 174, + "pc": [ + 656, + 657, + 658 + ] + }, + { + "teal": 637, + "source": 174, + "pc": [ + 659 + ] + }, + { + "teal": 638, + "source": 173, + "pc": [ + 660, + 661 + ] + }, + { + "teal": 639, + "source": 173, + "pc": [ + 662 + ] + }, + { + "teal": 640, + "source": 173, + "pc": [ + 663 + ] + }, + { + "teal": 641, + "source": 174, + "pc": [ + 664, + 665, + 666 + ] + }, + { + "teal": 642, + "source": 174, + "pc": [ + 667 + ] + }, + { + "teal": 643, + "source": 174, + "pc": [ + 668 + ] + }, + { + "teal": 644, + "source": 174, + "pc": [ + 669 + ] + }, + { + "teal": 645, + "source": 174, + "pc": [ + 670 + ] + }, + { + "teal": 646, + "source": 174, + "pc": [ + 671, + 672 + ] + }, + { + "teal": 650, + "source": 176, + "pc": [ + 673, + 674 + ] + }, + { + "teal": 651, + "source": 176, + "pc": [ + 675 + ] + }, + { + "teal": 659, + "source": 178, + "pc": [ + 676 + ] + }, + { + "teal": 660, + "source": 178, + "pc": [ + 677 + ] + }, + { + "teal": 661, + "source": 178, + "pc": [ + 678, + 679 + ] + }, + { + "teal": 665, + "source": 179, + "pc": [ + 680, + 681 + ] + }, + { + "teal": 666, + "source": 179, + "pc": [ + 682 + ] + }, + { + "teal": 667, + "source": 179, + "pc": [ + 683, + 684 + ] + }, + { + "teal": 668, + "source": 179, + "pc": [ + 685 + ] + }, + { + "teal": 669, + "source": 179, + "pc": [ + 686, + 687 + ] + }, + { + "teal": 673, + "source": 180, + "pc": [ + 688, + 689 + ] + }, + { + "teal": 674, + "source": 180, + "pc": [ + 690, + 691 + ] + }, + { + "teal": 678, + "source": 181, + "pc": [ + 692 + ] + }, + { + "teal": 679, + "source": 181, + "pc": [ + 693, + 694 + ] + }, + { + "teal": 682, + "source": 178, + "pc": [ + 695 + ] + }, + { + "teal": 683, + "source": 169, + "pc": [ + 696 + ] + }, + { + "teal": 686, + "source": 8, + "pc": [ + 697, + 698, + 699, + 700, + 701, + 702 + ] + }, + { + "teal": 687, + "source": 8, + "pc": [ + 703, + 704, + 705 + ] + }, + { + "teal": 688, + "source": 8, + "pc": [ + 706, + 707, + 708, + 709 + ] + }, + { + "teal": 689, + "source": 8, + "pc": [ + 710 + ] + }, + { + "teal": 692, + "source": 8, + "pc": [ + 711, + 712, + 713, + 714, + 715, + 716 + ] + }, + { + "teal": 693, + "source": 8, + "pc": [ + 717, + 718, + 719, + 720, + 721, + 722 + ] + }, + { + "teal": 694, + "source": 8, + "pc": [ + 723, + 724, + 725, + 726, + 727, + 728 + ] + }, + { + "teal": 695, + "source": 8, + "pc": [ + 729, + 730, + 731, + 732, + 733, + 734 + ] + }, + { + "teal": 696, + "source": 8, + "pc": [ + 735, + 736, + 737, + 738, + 739, + 740 + ] + }, + { + "teal": 697, + "source": 8, + "pc": [ + 741, + 742, + 743, + 744, + 745, + 746 + ] + }, + { + "teal": 698, + "source": 8, + "pc": [ + 747, + 748, + 749 + ] + }, + { + "teal": 699, + "source": 8, + "pc": [ + 750, + 751, + 752, + 753, + 754, + 755, + 756, + 757, + 758, + 759, + 760, + 761, + 762, + 763 + ] + }, + { + "teal": 700, + "source": 8, + "pc": [ + 764 + ] } -} \ No newline at end of file +] \ No newline at end of file diff --git a/examples/raffle/raffle.algo.ts b/examples/raffle/raffle.algo.ts index 5315f6e1b..79f429c7c 100644 --- a/examples/raffle/raffle.algo.ts +++ b/examples/raffle/raffle.algo.ts @@ -1,6 +1,6 @@ import { Contract } from '../../src/lib/index'; -type TicketRange = {start: number, end: number}; +type TicketRange = { start: number; end: number }; // eslint-disable-next-line no-loss-of-precision const RAND_MAX = 18_446_744_073_709_551_615; @@ -134,9 +134,9 @@ class NFTRaffle extends Contract { do { x = extract_uint64(this.randomBytes.value, offset); - offset += 8; + offset = offset + 8; - maxCondition = x > (RAND_MAX - (((RAND_MAX % n) + 1) % n)); + maxCondition = x > RAND_MAX - (((RAND_MAX % n) + 1) % n); } while (maxCondition && offset < 32); if (maxCondition) return false; From 6d5df2a1f072fb32f677360ab4129a21be8d752c Mon Sep 17 00:00:00 2001 From: Joe Polny Date: Thu, 23 Nov 2023 08:56:56 -0500 Subject: [PATCH 3/4] functional raffle test --- examples/raffle/MockVRFBeaconClient.ts | 448 ++++ examples/raffle/NFTRaffleClient.ts | 962 ++++++++ .../artifacts/MockVRFBeacon.approval.teal | 76 + .../raffle/artifacts/MockVRFBeacon.arc32.json | 80 + .../raffle/artifacts/MockVRFBeacon.arc4.json | 35 + .../raffle/artifacts/MockVRFBeacon.clear.teal | 1 + .../artifacts/MockVRFBeacon.src_map.json | 371 +++ .../raffle/artifacts/NFTRaffle.approval.teal | 271 ++- .../raffle/artifacts/NFTRaffle.arc32.json | 27 +- examples/raffle/artifacts/NFTRaffle.arc4.json | 21 +- .../raffle/artifacts/NFTRaffle.src_map.json | 2109 +++++++++-------- examples/raffle/raffle.algo.ts | 38 +- examples/raffle/raffle.test.ts | 137 ++ package.json | 2 +- 14 files changed, 3509 insertions(+), 1069 deletions(-) create mode 100644 examples/raffle/MockVRFBeaconClient.ts create mode 100644 examples/raffle/NFTRaffleClient.ts create mode 100644 examples/raffle/artifacts/MockVRFBeacon.approval.teal create mode 100644 examples/raffle/artifacts/MockVRFBeacon.arc32.json create mode 100644 examples/raffle/artifacts/MockVRFBeacon.arc4.json create mode 100644 examples/raffle/artifacts/MockVRFBeacon.clear.teal create mode 100644 examples/raffle/artifacts/MockVRFBeacon.src_map.json create mode 100644 examples/raffle/raffle.test.ts diff --git a/examples/raffle/MockVRFBeaconClient.ts b/examples/raffle/MockVRFBeaconClient.ts new file mode 100644 index 000000000..ff271af32 --- /dev/null +++ b/examples/raffle/MockVRFBeaconClient.ts @@ -0,0 +1,448 @@ +/* eslint-disable */ +/** + * This file was automatically generated by @algorandfoundation/algokit-client-generator. + * DO NOT MODIFY IT BY HAND. + * requires: @algorandfoundation/algokit-utils: ^2 + */ +import * as algokit from '@algorandfoundation/algokit-utils' +import type { + AppCallTransactionResult, + AppCallTransactionResultOfType, + CoreAppCallArgs, + RawAppCallArgs, + AppState, + TealTemplateParams, + ABIAppCallArg, +} from '@algorandfoundation/algokit-utils/types/app' +import type { + AppClientCallCoreParams, + AppClientCompilationParams, + AppClientDeployCoreParams, + AppDetails, + ApplicationClient, +} from '@algorandfoundation/algokit-utils/types/app-client' +import type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import type { SendTransactionResult, TransactionToSign, SendTransactionFrom } from '@algorandfoundation/algokit-utils/types/transaction' +import type { TransactionWithSigner } from 'algosdk' +import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer } from 'algosdk' +export const APP_SPEC: AppSpec = { + "hints": { + "must_get(uint64,byte[])byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "createApplication()void": { + "call_config": { + "no_op": "CREATE" + } + } + }, + "bare_call_config": { + "no_op": "NEVER", + "opt_in": "NEVER", + "close_out": "NEVER", + "update_application": "NEVER", + "delete_application": "NEVER" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIG11c3RfZ2V0KGJ5dGVzLHVpbnQ2NClieXRlW10KYWJpX3JvdXRlX211c3RfZ2V0OgoJLy8gZGF0YTogYnl0ZVtdCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglleHRyYWN0IDIgMAoKCS8vIF9yb3VuZDogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gZXhlY3V0ZSBtdXN0X2dldChieXRlcyx1aW50NjQpYnl0ZVtdCgljYWxsc3ViIG11c3RfZ2V0CglpbnQgMQoJcmV0dXJuCgptdXN0X2dldDoKCXByb3RvIDIgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoyMDAKCS8vIHJldHVybiBzaGEyNTYoZGF0YSArIGl0b2IoZ2xvYmFscy5yb3VuZCkpIGFzIGJ5dGVzOwoJZnJhbWVfZGlnIC0yIC8vIGRhdGE6IGJ5dGVzCglnbG9iYWwgUm91bmQKCWl0b2IKCWNvbmNhdAoJc2hhMjU2CglkdXAKCWxlbgoJaXRvYgoJZXh0cmFjdCA2IDIKCXN3YXAKCWNvbmNhdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgphYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb246CglpbnQgMQoJcmV0dXJuCgpjcmVhdGVfTm9PcDoKCW1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24oKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9tdXN0X2dldAoJZXJy", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" + }, + "contract": { + "name": "MockVRFBeacon", + "desc": "", + "methods": [ + { + "name": "must_get", + "args": [ + { + "name": "_round", + "type": "uint64", + "desc": "" + }, + { + "name": "data", + "type": "byte[]", + "desc": "" + } + ], + "desc": "", + "returns": { + "type": "byte[]", + "desc": "" + } + }, + { + "name": "createApplication", + "desc": "", + "returns": { + "type": "void", + "desc": "" + }, + "args": [] + } + ] + } +} + +/** + * Defines an onCompletionAction of 'no_op' + */ +export type OnCompleteNoOp = { onCompleteAction?: 'no_op' | OnApplicationComplete.NoOpOC } +/** + * Defines an onCompletionAction of 'opt_in' + */ +export type OnCompleteOptIn = { onCompleteAction: 'opt_in' | OnApplicationComplete.OptInOC } +/** + * Defines an onCompletionAction of 'close_out' + */ +export type OnCompleteCloseOut = { onCompleteAction: 'close_out' | OnApplicationComplete.CloseOutOC } +/** + * Defines an onCompletionAction of 'delete_application' + */ +export type OnCompleteDelApp = { onCompleteAction: 'delete_application' | OnApplicationComplete.DeleteApplicationOC } +/** + * Defines an onCompletionAction of 'update_application' + */ +export type OnCompleteUpdApp = { onCompleteAction: 'update_application' | OnApplicationComplete.UpdateApplicationOC } +/** + * A state record containing a single unsigned integer + */ +export type IntegerState = { + /** + * Gets the state value as a BigInt + */ + asBigInt(): bigint + /** + * Gets the state value as a number. + */ + asNumber(): number +} +/** + * A state record containing binary data + */ +export type BinaryState = { + /** + * Gets the state value as a Uint8Array + */ + asByteArray(): Uint8Array + /** + * Gets the state value as a string + */ + asString(): string +} + +/** + * Defines the types of available calls and state of the MockVrfBeacon smart contract. + */ +export type MockVrfBeacon = { + /** + * Maps method signatures / names to their argument and return types. + */ + methods: + & Record<'must_get(uint64,byte[])byte[]' | 'must_get', { + argsObj: { + _round: bigint | number + data: Uint8Array + } + argsTuple: [_round: bigint | number, data: Uint8Array] + returns: Uint8Array + }> + & Record<'createApplication()void' | 'createApplication', { + argsObj: { + } + argsTuple: [] + returns: void + }> +} +/** + * Defines the possible abi call signatures + */ +export type MockVrfBeaconSig = keyof MockVrfBeacon['methods'] +/** + * Defines an object containing all relevant parameters for a single call to the contract. Where TSignature is undefined, a bare call is made + */ +export type TypedCallParams = { + method: TSignature + methodArgs: TSignature extends undefined ? undefined : Array +} & AppClientCallCoreParams & CoreAppCallArgs +/** + * Defines the arguments required for a bare call + */ +export type BareCallArgs = Omit +/** + * Maps a method signature from the MockVrfBeacon smart contract to the method's arguments in either tuple of struct form + */ +export type MethodArgs = MockVrfBeacon['methods'][TSignature]['argsObj' | 'argsTuple'] +/** + * Maps a method signature from the MockVrfBeacon smart contract to the method's return type + */ +export type MethodReturn = MockVrfBeacon['methods'][TSignature]['returns'] + +/** + * A factory for available 'create' calls + */ +export type MockVrfBeaconCreateCalls = (typeof MockVrfBeaconCallFactory)['create'] +/** + * Defines supported create methods for this smart contract + */ +export type MockVrfBeaconCreateCallParams = + | (TypedCallParams<'createApplication()void'> & (OnCompleteNoOp)) +/** + * Defines arguments required for the deploy method. + */ +export type MockVrfBeaconDeployArgs = { + deployTimeParams?: TealTemplateParams + /** + * A delegate which takes a create call factory and returns the create call params for this smart contract + */ + createCall?: (callFactory: MockVrfBeaconCreateCalls) => MockVrfBeaconCreateCallParams +} + + +/** + * Exposes methods for constructing all available smart contract calls + */ +export abstract class MockVrfBeaconCallFactory { + /** + * Gets available create call factories + */ + static get create() { + return { + /** + * Constructs a create call for the MockVRFBeacon smart contract using the createApplication()void ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + createApplication(args: MethodArgs<'createApplication()void'>, params: AppClientCallCoreParams & CoreAppCallArgs & AppClientCompilationParams & (OnCompleteNoOp) = {}) { + return { + method: 'createApplication()void' as const, + methodArgs: Array.isArray(args) ? args : [], + ...params, + } + }, + } + } + + /** + * Constructs a no op call for the must_get(uint64,byte[])byte[] ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static mustGet(args: MethodArgs<'must_get(uint64,byte[])byte[]'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'must_get(uint64,byte[])byte[]' as const, + methodArgs: Array.isArray(args) ? args : [args._round, args.data], + ...params, + } + } +} + +/** + * A client to make calls to the MockVRFBeacon smart contract + */ +export class MockVrfBeaconClient { + /** + * The underlying `ApplicationClient` for when you want to have more flexibility + */ + public readonly appClient: ApplicationClient + + private readonly sender: SendTransactionFrom | undefined + + /** + * Creates a new instance of `MockVrfBeaconClient` + * + * @param appDetails appDetails The details to identify the app to deploy + * @param algod An algod client instance + */ + constructor(appDetails: AppDetails, private algod: Algodv2) { + this.sender = appDetails.sender + this.appClient = algokit.getAppClient({ + ...appDetails, + app: APP_SPEC + }, algod) + } + + /** + * Checks for decode errors on the AppCallTransactionResult and maps the return value to the specified generic type + * + * @param result The AppCallTransactionResult to be mapped + * @param returnValueFormatter An optional delegate to format the return value if required + * @returns The smart contract response with an updated return value + */ + protected mapReturnValue(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType { + if(result.return?.decodeError) { + throw result.return.decodeError + } + const returnValue = result.return?.returnValue !== undefined && returnValueFormatter !== undefined + ? returnValueFormatter(result.return.returnValue) + : result.return?.returnValue as TReturn | undefined + return { ...result, return: returnValue } + } + + /** + * Calls the ABI method with the matching signature using an onCompletion code of NO_OP + * + * @param typedCallParams An object containing the method signature, args, and any other relevant parameters + * @param returnValueFormatter An optional delegate which when provided will be used to map non-undefined return values to the target type + * @returns The result of the smart contract call + */ + public async call(typedCallParams: TypedCallParams, returnValueFormatter?: (value: any) => MethodReturn) { + return this.mapReturnValue>(await this.appClient.call(typedCallParams), returnValueFormatter) + } + + /** + * Idempotently deploys the MockVRFBeacon smart contract. + * + * @param params The arguments for the contract calls and any additional parameters for the call + * @returns The deployment result + */ + public deploy(params: MockVrfBeaconDeployArgs & AppClientDeployCoreParams = {}): ReturnType { + const createArgs = params.createCall?.(MockVrfBeaconCallFactory.create) + return this.appClient.deploy({ + ...params, + createArgs, + createOnCompleteAction: createArgs?.onCompleteAction, + }) + } + + /** + * Gets available create methods + */ + public get create() { + const $this = this + return { + /** + * Creates a new instance of the MockVRFBeacon smart contract using the createApplication()void ABI method. + * + * @param args The arguments for the smart contract call + * @param params Any additional parameters for the call + * @returns The create result + */ + async createApplication(args: MethodArgs<'createApplication()void'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}): Promise>> { + return $this.mapReturnValue(await $this.appClient.create(MockVrfBeaconCallFactory.create.createApplication(args, params))) + }, + } + } + + /** + * Makes a clear_state call to an existing instance of the MockVRFBeacon smart contract. + * + * @param args The arguments for the bare call + * @returns The clear_state result + */ + public clearState(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.appClient.clearState(args) + } + + /** + * Calls the must_get(uint64,byte[])byte[] ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public mustGet(args: MethodArgs<'must_get(uint64,byte[])byte[]'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(MockVrfBeaconCallFactory.mustGet(args, params)) + } + + public compose(): MockVrfBeaconComposer { + const client = this + const atc = new AtomicTransactionComposer() + let promiseChain:Promise = Promise.resolve() + const resultMappers: Array any)> = [] + return { + mustGet(args: MethodArgs<'must_get(uint64,byte[])byte[]'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.mustGet(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + clearState(args?: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.clearState({...args, sendParams: {...args?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + addTransaction(txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, defaultSender?: SendTransactionFrom) { + promiseChain = promiseChain.then(async () => atc.addTransaction(await algokit.getTransactionWithSigner(txn, defaultSender ?? client.sender))) + return this + }, + async atc() { + await promiseChain + return atc + }, + async execute() { + await promiseChain + const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams: {} }, client.algod) + return { + ...result, + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val.returnValue) : val.returnValue) + } + } + } as unknown as MockVrfBeaconComposer + } +} +export type MockVrfBeaconComposer = { + /** + * Calls the must_get(uint64,byte[])byte[] ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + mustGet(args: MethodArgs<'must_get(uint64,byte[])byte[]'>, params?: AppClientCallCoreParams & CoreAppCallArgs): MockVrfBeaconComposer<[...TReturns, MethodReturn<'must_get(uint64,byte[])byte[]'>]> + + /** + * Makes a clear_state call to an existing instance of the MockVRFBeacon smart contract. + * + * @param args The arguments for the bare call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + clearState(args?: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs): MockVrfBeaconComposer<[...TReturns, undefined]> + + /** + * Adds a transaction to the composer + * + * @param txn One of: A TransactionWithSigner object (returned as is), a TransactionToSign object (signer is obtained from the signer property), a Transaction object (signer is extracted from the defaultSender parameter), an async SendTransactionResult returned by one of algokit utils helpers (signer is obtained from the defaultSender parameter) + * @param defaultSender The default sender to be used to obtain a signer where the object provided to the transaction parameter does not include a signer. + */ + addTransaction(txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, defaultSender?: SendTransactionFrom): MockVrfBeaconComposer + /** + * Returns the underlying AtomicTransactionComposer instance + */ + atc(): Promise + /** + * Executes the transaction group and returns an array of results + */ + execute(): Promise> +} +export type MockVrfBeaconComposerResults = { + returns: TReturns + groupId: string + txIds: string[] + transactions: Transaction[] +} diff --git a/examples/raffle/NFTRaffleClient.ts b/examples/raffle/NFTRaffleClient.ts new file mode 100644 index 000000000..8018d3cb0 --- /dev/null +++ b/examples/raffle/NFTRaffleClient.ts @@ -0,0 +1,962 @@ +/* eslint-disable */ +/** + * This file was automatically generated by @algorandfoundation/algokit-client-generator. + * DO NOT MODIFY IT BY HAND. + * requires: @algorandfoundation/algokit-utils: ^2 + */ +import * as algokit from '@algorandfoundation/algokit-utils' +import type { + AppCallTransactionResult, + AppCallTransactionResultOfType, + CoreAppCallArgs, + RawAppCallArgs, + AppState, + TealTemplateParams, + ABIAppCallArg, +} from '@algorandfoundation/algokit-utils/types/app' +import type { + AppClientCallCoreParams, + AppClientCompilationParams, + AppClientDeployCoreParams, + AppDetails, + ApplicationClient, +} from '@algorandfoundation/algokit-utils/types/app-client' +import type { AppSpec } from '@algorandfoundation/algokit-utils/types/app-spec' +import type { SendTransactionResult, TransactionToSign, SendTransactionFrom } from '@algorandfoundation/algokit-utils/types/transaction' +import type { TransactionWithSigner } from 'algosdk' +import { Algodv2, OnApplicationComplete, Transaction, AtomicTransactionComposer } from 'algosdk' +export const APP_SPEC: AppSpec = { + "hints": { + "createApplication(uint64,uint64)void": { + "call_config": { + "no_op": "CREATE" + } + }, + "setAsset(asset)void": { + "call_config": { + "no_op": "CALL" + } + }, + "startRaffle(axfer,uint64,uint64)void": { + "call_config": { + "no_op": "CALL" + } + }, + "buyTickets(pay,uint64)void": { + "call_config": { + "no_op": "CALL" + } + }, + "draw(application)bool": { + "call_config": { + "no_op": "CALL" + } + }, + "claim()void": { + "call_config": { + "no_op": "CALL" + } + }, + "getRefund()void": { + "call_config": { + "no_op": "CALL" + } + } + }, + "bare_call_config": { + "no_op": "NEVER", + "opt_in": "NEVER", + "close_out": "NEVER", + "update_application": "NEVER", + "delete_application": "NEVER" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": { + "randomnessOracle": { + "type": "uint64", + "key": "randomnessOracle" + }, + "ticketPrice": { + "type": "uint64", + "key": "ticketPrice" + }, + "asset": { + "type": "uint64", + "key": "asset" + }, + "endRound": { + "type": "uint64", + "key": "endRound" + }, + "drawRound": { + "type": "uint64", + "key": "drawRound" + }, + "totalTickets": { + "type": "uint64", + "key": "totalTickets" + }, + "winningTicket": { + "type": "uint64", + "key": "winningTicket" + }, + "randomBytes": { + "type": "bytes", + "key": "randomBytes" + } + }, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 1, + "num_uints": 7 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAovLwovLyBDcmVhdGUgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gdGlja2V0UHJpY2UgVGhlIHByaWNlIG9mIGEgc2luZ2xlIHRpY2tldCAodUFMR08pCi8vIEBwYXJhbSByYW5kb21uZXNzT3JhY2xlIFRoZSBhcHAgSUQgb2YgdGhlIHJhbmRvbW5lc3Mgb3JhY2xlCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIHJhbmRvbW5lc3NPcmFjbGU6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIHRpY2tldFByaWNlOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBjcmVhdGVBcHBsaWNhdGlvbgoJaW50IDEKCXJldHVybgoKY3JlYXRlQXBwbGljYXRpb246Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NDMKCS8vIHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSA9IHJhbmRvbW5lc3NPcmFjbGUKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQ0CgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWZyYW1lX2RpZyAtMSAvLyB0aWNrZXRQcmljZTogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzZXRBc3NldChhc3NldCl2b2lkCi8vCi8vIFNldCB0aGUgYXNzZXQgdG8gYmUgcmFmZmxlZAovLwovLyBAcGFyYW0gYXNzZXQgVGhlIGFzc2V0IHRvIGJlIHJhZmZsZWQKYWJpX3JvdXRlX3NldEFzc2V0OgoJLy8gYXNzZXQ6IGFzc2V0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCgkvLyBleGVjdXRlIHNldEFzc2V0KGFzc2V0KXZvaWQKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU0CgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiBhc3NldCwKCS8vICAgICAgIGFzc2V0QW1vdW50OiAwLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTcKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMuYXBwLmFkZHJlc3MKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTgKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU5CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NjAKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo2MwoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglmcmFtZV9kaWcgLTEgLy8gYXNzZXQ6IGFzc2V0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKLy8KLy8gU3RhcnQgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gZW5kIFRoZSByb3VuZCBudW1iZXIgd2hlbiB0aGUgcmFmZmxlIGVuZHMKLy8gQHBhcmFtIGRyYXcgVGhlIHJvdW5kIG51bWJlciB3aGVuIHRoZSByYWZmbGUgaXMgZHJhd24KYWJpX3JvdXRlX3N0YXJ0UmFmZmxlOgoJLy8gZHJhdzogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgoJLy8gZW5kOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBheGZlcjogYXhmZXIKCXR4biBHcm91cEluZGV4CglpbnQgMQoJLQoJZHVwCglndHhucyBUeXBlRW51bQoJaW50IGF4ZmVyCgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKCWNhbGxzdWIgc3RhcnRSYWZmbGUKCWludCAxCglyZXR1cm4KCnN0YXJ0UmFmZmxlOgoJcHJvdG8gMyAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc0CgkvLyB2ZXJpZnlUeG4oYXhmZXIsIHsKCS8vICAgICAgIGFzc2V0QW1vdW50OiB7IGdyZWF0ZXJUaGFuOiAwIH0sCgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlLAoJLy8gICAgIH0pCgkvLyB2ZXJpZnkgYXNzZXRBbW91bnQKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0QW1vdW50CglpbnQgMAoJPgoJYXNzZXJ0CgoJLy8gdmVyaWZ5IGFzc2V0UmVjZWl2ZXIKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0UmVjZWl2ZXIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHhmZXJBc3NldAoJZnJhbWVfZGlnIC0xIC8vIGF4ZmVyOiBheGZlcgoJZ3R4bnMgWGZlckFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MAoJLy8gYXNzZXJ0KGRyYXcgPiBlbmQpCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gZW5kOiB1aW50NjQKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MQoJLy8gdGhpcy5lbmRSb3VuZC52YWx1ZSA9IGVuZAoJYnl0ZSAweDY1NmU2NDUyNmY3NTZlNjQgLy8gImVuZFJvdW5kIgoJZnJhbWVfZGlnIC0yIC8vIGVuZDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MgoJLy8gdGhpcy5kcmF3Um91bmQudmFsdWUgPSBkcmF3CglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAovLwovLyBCdXkgdGlja2V0cy4gTm90ZSB0aGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlIQovLyBJdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBhbGxvdyBtdWx0aXBsZSBwdXJjaGFzZXMsIGJ1dAovLyBmb3Igc2ltcGxpY2l0eSwgb25seSBvbmUgcHVyY2hhc2UgaXMgYWxsb3dlZC4KLy8KLy8gQHBhcmFtIHBheW1lbnQgVGhlIHBheW1lbnQgZm9yIHRoZSB0aWNrZXRzCi8vIEBwYXJhbSBxdWFuaXR5IFRoZSBudW1iZXIgb2YgdGlja2V0cyB0byBidXkKLy8KLy8gQHJldHVybnMgVGhlIHRvdGFsIG51bWJlciBvZiB0aWNrZXRzIG93bmVkIGJ5IHRoZSBzZW5kZXIKYWJpX3JvdXRlX2J1eVRpY2tldHM6CglieXRlIDB4OyBkdXBuIDIgLy8gcHVzaCBlbXB0eSBieXRlcyB0byBmaWxsIHRoZSBzdGFjayBmcmFtZSBmb3IgdGhpcyBzdWJyb3V0aW5lJ3MgbG9jYWwgdmFyaWFibGVzCgoJLy8gcXVhbnRpdHk6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoKCS8vIHBheW1lbnQ6IHBheQoJdHhuIEdyb3VwSW5kZXgKCWludCAxCgktCglkdXAKCWd0eG5zIFR5cGVFbnVtCglpbnQgcGF5Cgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAoJY2FsbHN1YiBidXlUaWNrZXRzCglpbnQgMQoJcmV0dXJuCgpidXlUaWNrZXRzOgoJcHJvdG8gNSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjk2CgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA8IHRoaXMuZW5kUm91bmQudmFsdWUpCglnbG9iYWwgUm91bmQKCWJ5dGUgMHg2NTZlNjQ1MjZmNzU2ZTY0IC8vICJlbmRSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0Cgk8Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTcKCS8vIGFzc2VydChxdWFudGl0eSA+IDApCglmcmFtZV9kaWcgLTIgLy8gcXVhbnRpdHk6IHVpbnQ2NAoJaW50IDAKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5OQoJLy8gYXNzZXJ0KCF0aGlzLnRpY2tldHMocGF5bWVudC5zZW5kZXIpLmV4aXN0cykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJYm94X2xlbgoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAxCgkvLyBuZXdUb3RhbCA9IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlICsgcXVhbnRpdHkgKyAxCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCSsKCWludCAxCgkrCglmcmFtZV9idXJ5IC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAzCgkvLyBwcmVNQlIgPSB0aGlzLmFwcC5hZGRyZXNzLm1pbkJhbGFuY2UKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKCWFzc2VydAoJZnJhbWVfYnVyeSAtNCAvLyBwcmVNQlI6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDQKCS8vIHRoaXMudGlja2V0cyhwYXltZW50LnNlbmRlcikudmFsdWUgPSB7IHN0YXJ0OiB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSwgZW5kOiBuZXdUb3RhbCAtIDEgfQoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJZnJhbWVfZGlnIC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCWludCAxCgktCglpdG9iCgljb25jYXQKCWJveF9wdXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTA1CgkvLyBtYnJEZWx0YSA9IHRoaXMuYXBwLmFkZHJlc3MubWluQmFsYW5jZSAtIHByZU1CUgoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCWFjY3RfcGFyYW1zX2dldCBBY2N0TWluQmFsYW5jZQoJYXNzZXJ0CglmcmFtZV9kaWcgLTQgLy8gcHJlTUJSOiB1aW50NjQKCS0KCWZyYW1lX2J1cnkgLTUgLy8gbWJyRGVsdGE6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDcKCS8vIHZlcmlmeVR4bihwYXltZW50LCB7CgkvLyAgICAgICBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiBxdWFudGl0eSArIG1ickRlbHRhLAoJLy8gICAgICAgc2VuZGVyOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICByZWNlaXZlcjogdGhpcy5hcHAuYWRkcmVzcywKCS8vICAgICB9KQoJLy8gdmVyaWZ5IGFtb3VudAoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgQW1vdW50CglieXRlIDB4NzQ2OTYzNmI2NTc0NTA3MjY5NjM2NSAvLyAidGlja2V0UHJpY2UiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCSoKCWZyYW1lX2RpZyAtNSAvLyBtYnJEZWx0YTogdWludDY0CgkrCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHNlbmRlcgoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCgl0eG4gU2VuZGVyCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHJlY2VpdmVyCglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBSZWNlaXZlcgoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCT09Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTEzCgkvLyB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSA9IG5ld1RvdGFsCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglmcmFtZV9kaWcgLTMgLy8gbmV3VG90YWw6IHVpbnQ2NAoJYXBwX2dsb2JhbF9wdXQKCXJldHN1YgoKZ2V0UmFuZG9tQnl0ZXM6Cglwcm90byAwIDAKCgkvLyBpZjBfY29uZGl0aW9uCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTE4CgkvLyB0aGlzLnJhbmRvbUJ5dGVzLmV4aXN0cwoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJYnogaWYwX2Vsc2UKCgkvLyBpZjBfY29uc2VxdWVudAoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExOQoJLy8gdGhpcy5yYW5kb21CeXRlcy52YWx1ZSA9IHNoYTI1Nih0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlKSBhcyBieXRlcwoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCXNoYTI1NgoJYXBwX2dsb2JhbF9wdXQKCWIgaWYwX2VuZAoKaWYwX2Vsc2U6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTIxCgkvLyB0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlID0gc2VuZE1ldGhvZENhbGw8W3VpbnQ2NCwgYnl0ZXNdLCBieXRlcz4oewoJLy8gICAgICAgICBuYW1lOiAnbXVzdF9nZXQnLAoJLy8gICAgICAgICBtZXRob2RBcmdzOiBbdGhpcy5kcmF3Um91bmQudmFsdWUsICcnXSwKCS8vICAgICAgICAgYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSksCgkvLyAgICAgICAgIGZlZTogMCwKCS8vICAgICAgICAgb25Db21wbGV0aW9uOiAnTm9PcCcsCgkvLyAgICAgICB9KQoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJaXR4bl9iZWdpbgoJaW50IGFwcGwKCWl0eG5fZmllbGQgVHlwZUVudW0KCW1ldGhvZCAibXVzdF9nZXQodWludDY0LGJ5dGVbXSlieXRlW10iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjMKCS8vIG1ldGhvZEFyZ3M6IFt0aGlzLmRyYXdSb3VuZC52YWx1ZSwgJyddCglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKCWJ5dGUgMHgwMDAwCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjQKCS8vIGFwcGxpY2F0aW9uSUQ6IEFwcGxpY2F0aW9uLmZyb21JRCh0aGlzLnJhbmRvbW5lc3NPcmFjbGUudmFsdWUpCglieXRlIDB4NzI2MTZlNjQ2ZjZkNmU2NTczNzM0ZjcyNjE2MzZjNjUgLy8gInJhbmRvbW5lc3NPcmFjbGUiCglhcHBfZ2xvYmFsX2dldAoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbklECgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNQoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTI2CgkvLyBvbkNvbXBsZXRpb246ICdOb09wJwoJaW50IE5vT3AKCWl0eG5fZmllbGQgT25Db21wbGV0aW9uCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoJaXR4biBOdW1Mb2dzCglpbnQgMQoJLQoJaXR4bmFzIExvZ3MKCWV4dHJhY3QgNCAwCglhcHBfZ2xvYmFsX3B1dAoKaWYwX2VuZDoKCXJldHN1YgoKLy8gZHJhdyhhcHBsaWNhdGlvbilib29sCi8vCi8vIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFycwphYmlfcm91dGVfZHJhdzoKCWJ5dGUgMHg7IGR1cG4gMyAvLyBwdXNoIGVtcHR5IGJ5dGVzIHRvIGZpbGwgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIHN1YnJvdXRpbmUncyBsb2NhbCB2YXJpYWJsZXMKCgkvLyBfb3JhY2xlUmVmZXJlbmNlOiBhcHBsaWNhdGlvbgoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoJdHhuYXMgQXBwbGljYXRpb25zCgoJLy8gZXhlY3V0ZSBkcmF3KGFwcGxpY2F0aW9uKWJvb2wKCWNhbGxzdWIgZHJhdwoJaW50IDEKCXJldHVybgoKZHJhdzoKCXByb3RvIDUgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzUKCS8vIGFzc2VydCghdGhpcy53aW5uaW5nVGlja2V0LmV4aXN0cykKCXR4bmEgQXBwbGljYXRpb25zIDAKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0X2V4Cglzd2FwCglwb3AKCSEKCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzYKCS8vIHRoaXMuZ2V0UmFuZG9tQnl0ZXMoKQoJY2FsbHN1YiBnZXRSYW5kb21CeXRlcwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNDAKCS8vIG4gPSB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZQoJYnl0ZSAweDc0NmY3NDYxNmM1NDY5NjM2YjY1NzQ3MyAvLyAidG90YWxUaWNrZXRzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2J1cnkgLTIgLy8gbjogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0MgoJLy8gb2Zmc2V0ID0gMAoJaW50IDAKCWZyYW1lX2J1cnkgLTQgLy8gb2Zmc2V0OiB1aW50NjQKCmRvX3doaWxlXzA6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTQ2CgkvLyB4ID0gZXh0cmFjdF91aW50NjQodGhpcy5yYW5kb21CeXRlcy52YWx1ZSwgb2Zmc2V0KQoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtNCAvLyBvZmZzZXQ6IHVpbnQ2NAoJZXh0cmFjdF91aW50NjQKCWZyYW1lX2J1cnkgLTMgLy8geDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0OAoJLy8gb2Zmc2V0ID0gb2Zmc2V0ICsgOAoJZnJhbWVfZGlnIC00IC8vIG9mZnNldDogdWludDY0CglpbnQgOAoJKwoJZnJhbWVfYnVyeSAtNCAvLyBvZmZzZXQ6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTAKCS8vIG1heENvbmRpdGlvbiA9IHggPiBSQU5EX01BWCAtICgoKFJBTkRfTUFYICUgbikgKyAxKSAlIG4pCglmcmFtZV9kaWcgLTMgLy8geDogdWludDY0CglpbnQgMThfNDQ2Xzc0NF8wNzNfNzA5XzU1MV82MTUKCWludCAxOF80NDZfNzQ0XzA3M183MDlfNTUxXzYxNQoJZnJhbWVfZGlnIC0yIC8vIG46IHVpbnQ2NAoJJQoJaW50IDEKCSsKCWZyYW1lX2RpZyAtMiAvLyBuOiB1aW50NjQKCSUKCS0KCT4KCWZyYW1lX2J1cnkgLTUgLy8gbWF4Q29uZGl0aW9uOiBib29sCglmcmFtZV9kaWcgLTUgLy8gbWF4Q29uZGl0aW9uOiBib29sCglkdXAKCWJ6IHNraXBfYW5kMAoJZnJhbWVfZGlnIC00IC8vIG9mZnNldDogdWludDY0CglpbnQgMzIKCTwKCSYmCgpza2lwX2FuZDA6CglibnogZG9fd2hpbGVfMAoKCS8vIGlmMV9jb25kaXRpb24KCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTMKCS8vIG1heENvbmRpdGlvbgoJZnJhbWVfZGlnIC01IC8vIG1heENvbmRpdGlvbjogYm9vbAoJYnogaWYxX2VuZAoKCS8vIGlmMV9jb25zZXF1ZW50CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyByZXR1cm4gZmFsc2U7CglpbnQgMAoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKaWYxX2VuZDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTUKCS8vIHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSA9IHggJSBuCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglmcmFtZV9kaWcgLTMgLy8geDogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gbjogdWludDY0CgklCglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTYKCS8vIHJldHVybiB0cnVlOwoJaW50IDEKCWJ5dGUgMHgwMAoJaW50IDAKCXVuY292ZXIgMgoJc2V0Yml0CglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCi8vIGNsYWltKCl2b2lkCi8vCi8vIFNlbmQgdGhlIGFzc2V0IHRvIHRoZSB0aGUgc2VuZGVyIGlmIHRoZXkgaGF2ZSB0aGUgd2lubmluZyB0aWNrZXQKYWJpX3JvdXRlX2NsYWltOgoJYnl0ZSAweCAvLyBwdXNoIGVtcHR5IGJ5dGVzIHRvIGZpbGwgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIHN1YnJvdXRpbmUncyBsb2NhbCB2YXJpYWJsZXMKCgkvLyBleGVjdXRlIGNsYWltKCl2b2lkCgljYWxsc3ViIGNsYWltCglpbnQgMQoJcmV0dXJuCgpjbGFpbToKCXByb3RvIDEgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjEKCS8vIHRpY2tldFJhbmdlID0gdGhpcy50aWNrZXRzKHRoaXMudHhuLnNlbmRlcikudmFsdWUKCXR4biBTZW5kZXIKCWZyYW1lX2J1cnkgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2MwoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLnN0YXJ0IDw9IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCWJveF9nZXQKCWFzc2VydAoJZXh0cmFjdCAwIDgKCWJ0b2kKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0Cgk8PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2NAoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLmVuZCA+PSB0aGlzLndpbm5pbmdUaWNrZXQudmFsdWUpCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgOCA4CglidG9pCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldAoJPj0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjYKCS8vIHNlbmRBc3NldFRyYW5zZmVyKHsKCS8vICAgICAgIGFzc2V0UmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIHhmZXJBc3NldDogdGhpcy5hc3NldC52YWx1ZSwKCS8vICAgICAgIGFzc2V0QW1vdW50OiB0aGlzLmFwcC5hZGRyZXNzLmFzc2V0QmFsYW5jZSh0aGlzLmFzc2V0LnZhbHVlKSwKCS8vICAgICAgIGFzc2V0Q2xvc2VUbzogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY3CgkvLyBhc3NldFJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRSZWNlaXZlcgoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjgKCS8vIHhmZXJBc3NldDogdGhpcy5hc3NldC52YWx1ZQoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2OQoJLy8gYXNzZXRBbW91bnQ6IHRoaXMuYXBwLmFkZHJlc3MuYXNzZXRCYWxhbmNlKHRoaXMuYXNzZXQudmFsdWUpCglnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQoJYXNzZXJ0CglpdHhuX2ZpZWxkIEFzc2V0QW1vdW50CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3MAoJLy8gYXNzZXRDbG9zZVRvOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRDbG9zZVRvCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3MQoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCi8vIGdldFJlZnVuZCgpdm9pZAovLwovLyBBbGxvd3MgcHVyY2hhc2VycyB0byBnZXQgYSByZWZ1bmQgaWYgdGhlIHdpbm5pbmcgdGlja2V0IGhhcyBub3QgYmVlbiBkcmF3bgovLyBhbmQgMTUxMiByb3VuZHMgaGF2ZSBwYXNzZWQgc2luY2UgdGhlIGRyYXcgcm91bmQsIG1lYW5pbmcgdGhlIG9yYWNsZSBubwovLyBsb25nZXIgaGFzIHRoZSBkYXRhIGZvciB0aGUgZHJhdyByb3VuZAphYmlfcm91dGVfZ2V0UmVmdW5kOgoJYnl0ZSAweDsgZHVwIC8vIHB1c2ggZW1wdHkgYnl0ZXMgdG8gZmlsbCB0aGUgc3RhY2sgZnJhbWUgZm9yIHRoaXMgc3Vicm91dGluZSdzIGxvY2FsIHZhcmlhYmxlcwoKCS8vIGV4ZWN1dGUgZ2V0UmVmdW5kKCl2b2lkCgljYWxsc3ViIGdldFJlZnVuZAoJaW50IDEKCXJldHVybgoKZ2V0UmVmdW5kOgoJcHJvdG8gMiAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4MQoJLy8gYXNzZXJ0KCF0aGlzLndpbm5pbmdUaWNrZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4MgoJLy8gYXNzZXJ0KGdsb2JhbHMucm91bmQgPiB0aGlzLmRyYXdSb3VuZC52YWx1ZSArIDE1MTIpCglnbG9iYWwgUm91bmQKCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpbnQgMTUxMgoJKwoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4NAoJLy8gdGlja2V0UmFuZ2UgPSB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS52YWx1ZQoJdHhuIFNlbmRlcgoJZnJhbWVfYnVyeSAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTg1CgkvLyB0aWNrZXRDb3VudCA9IHRpY2tldFJhbmdlLmVuZCAtIHRpY2tldFJhbmdlLnN0YXJ0ICsgMQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDggOAoJYnRvaQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDAgOAoJYnRvaQoJLQoJaW50IDEKCSsKCWZyYW1lX2J1cnkgLTIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxODcKCS8vIHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLmRlbGV0ZSgpCgl0eG4gU2VuZGVyCglib3hfZGVsCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4OQoJLy8gc2VuZFBheW1lbnQoewoJLy8gICAgICAgYW1vdW50OiB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogdGlja2V0Q291bnQsCgkvLyAgICAgICByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgcGF5CglpdHhuX2ZpZWxkIFR5cGVFbnVtCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MAoJLy8gYW1vdW50OiB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogdGlja2V0Q291bnQKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9kaWcgLTIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoJKgoJaXR4bl9maWVsZCBBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTkxCgkvLyByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIFJlY2VpdmVyCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MgoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCmNyZWF0ZV9Ob09wOgoJbWV0aG9kICJjcmVhdGVBcHBsaWNhdGlvbih1aW50NjQsdWludDY0KXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJzZXRBc3NldChhc3NldCl2b2lkIgoJbWV0aG9kICJzdGFydFJhZmZsZShheGZlcix1aW50NjQsdWludDY0KXZvaWQiCgltZXRob2QgImJ1eVRpY2tldHMocGF5LHVpbnQ2NCl2b2lkIgoJbWV0aG9kICJkcmF3KGFwcGxpY2F0aW9uKWJvb2wiCgltZXRob2QgImNsYWltKCl2b2lkIgoJbWV0aG9kICJnZXRSZWZ1bmQoKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc2V0QXNzZXQgYWJpX3JvdXRlX3N0YXJ0UmFmZmxlIGFiaV9yb3V0ZV9idXlUaWNrZXRzIGFiaV9yb3V0ZV9kcmF3IGFiaV9yb3V0ZV9jbGFpbSBhYmlfcm91dGVfZ2V0UmVmdW5kCgllcnI=", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" + }, + "contract": { + "name": "NFTRaffle", + "desc": "", + "methods": [ + { + "name": "createApplication", + "args": [ + { + "name": "ticketPrice", + "type": "uint64", + "desc": "The price of a single ticket (uALGO)" + }, + { + "name": "randomnessOracle", + "type": "uint64", + "desc": "The app ID of the randomness oracle" + } + ], + "desc": "Create the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "setAsset", + "args": [ + { + "name": "asset", + "type": "asset", + "desc": "The asset to be raffled" + } + ], + "desc": "Set the asset to be raffled", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "startRaffle", + "args": [ + { + "name": "axfer", + "type": "axfer", + "desc": "" + }, + { + "name": "end", + "type": "uint64", + "desc": "The round number when the raffle ends" + }, + { + "name": "draw", + "type": "uint64", + "desc": "The round number when the raffle is drawn" + } + ], + "desc": "Start the raffle", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "buyTickets", + "args": [ + { + "name": "payment", + "type": "pay", + "desc": "The payment for the tickets" + }, + { + "name": "quantity", + "type": "uint64", + "desc": "" + } + ], + "desc": "Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed.", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "draw", + "args": [ + { + "name": "_oracleReference", + "type": "application", + "desc": "" + } + ], + "desc": "", + "returns": { + "type": "bool", + "desc": "" + } + }, + { + "name": "claim", + "args": [], + "desc": "Send the asset to the the sender if they have the winning ticket", + "returns": { + "type": "void", + "desc": "" + } + }, + { + "name": "getRefund", + "args": [], + "desc": "Allows purchasers to get a refund if the winning ticket has not been drawnand 1512 rounds have passed since the draw round, meaning the oracle nolonger has the data for the draw round", + "returns": { + "type": "void", + "desc": "" + } + } + ] + } +} + +/** + * Defines an onCompletionAction of 'no_op' + */ +export type OnCompleteNoOp = { onCompleteAction?: 'no_op' | OnApplicationComplete.NoOpOC } +/** + * Defines an onCompletionAction of 'opt_in' + */ +export type OnCompleteOptIn = { onCompleteAction: 'opt_in' | OnApplicationComplete.OptInOC } +/** + * Defines an onCompletionAction of 'close_out' + */ +export type OnCompleteCloseOut = { onCompleteAction: 'close_out' | OnApplicationComplete.CloseOutOC } +/** + * Defines an onCompletionAction of 'delete_application' + */ +export type OnCompleteDelApp = { onCompleteAction: 'delete_application' | OnApplicationComplete.DeleteApplicationOC } +/** + * Defines an onCompletionAction of 'update_application' + */ +export type OnCompleteUpdApp = { onCompleteAction: 'update_application' | OnApplicationComplete.UpdateApplicationOC } +/** + * A state record containing a single unsigned integer + */ +export type IntegerState = { + /** + * Gets the state value as a BigInt + */ + asBigInt(): bigint + /** + * Gets the state value as a number. + */ + asNumber(): number +} +/** + * A state record containing binary data + */ +export type BinaryState = { + /** + * Gets the state value as a Uint8Array + */ + asByteArray(): Uint8Array + /** + * Gets the state value as a string + */ + asString(): string +} + +/** + * Defines the types of available calls and state of the NftRaffle smart contract. + */ +export type NftRaffle = { + /** + * Maps method signatures / names to their argument and return types. + */ + methods: + & Record<'createApplication(uint64,uint64)void' | 'createApplication', { + argsObj: { + /** + * The price of a single ticket (uALGO) + */ + ticketPrice: bigint | number + /** + * The app ID of the randomness oracle + */ + randomnessOracle: bigint | number + } + argsTuple: [ticketPrice: bigint | number, randomnessOracle: bigint | number] + returns: void + }> + & Record<'setAsset(asset)void' | 'setAsset', { + argsObj: { + /** + * The asset to be raffled + */ + asset: number | bigint + } + argsTuple: [asset: number | bigint] + returns: void + }> + & Record<'startRaffle(axfer,uint64,uint64)void' | 'startRaffle', { + argsObj: { + axfer: TransactionToSign | Transaction | Promise + /** + * The round number when the raffle ends + */ + end: bigint | number + /** + * The round number when the raffle is drawn + */ + draw: bigint | number + } + argsTuple: [axfer: TransactionToSign | Transaction | Promise, end: bigint | number, draw: bigint | number] + returns: void + }> + & Record<'buyTickets(pay,uint64)void' | 'buyTickets', { + argsObj: { + /** + * The payment for the tickets + */ + payment: TransactionToSign | Transaction | Promise + quantity: bigint | number + } + argsTuple: [payment: TransactionToSign | Transaction | Promise, quantity: bigint | number] + returns: void + }> + & Record<'draw(application)bool' | 'draw', { + argsObj: { + _oracleReference: number | bigint + } + argsTuple: [_oracleReference: number | bigint] + returns: boolean + }> + & Record<'claim()void' | 'claim', { + argsObj: { + } + argsTuple: [] + returns: void + }> + & Record<'getRefund()void' | 'getRefund', { + argsObj: { + } + argsTuple: [] + returns: void + }> + /** + * Defines the shape of the global and local state of the application. + */ + state: { + global: { + 'randomnessOracle'?: IntegerState + 'ticketPrice'?: IntegerState + 'asset'?: IntegerState + 'endRound'?: IntegerState + 'drawRound'?: IntegerState + 'totalTickets'?: IntegerState + 'winningTicket'?: IntegerState + 'randomBytes'?: BinaryState + } + } +} +/** + * Defines the possible abi call signatures + */ +export type NftRaffleSig = keyof NftRaffle['methods'] +/** + * Defines an object containing all relevant parameters for a single call to the contract. Where TSignature is undefined, a bare call is made + */ +export type TypedCallParams = { + method: TSignature + methodArgs: TSignature extends undefined ? undefined : Array +} & AppClientCallCoreParams & CoreAppCallArgs +/** + * Defines the arguments required for a bare call + */ +export type BareCallArgs = Omit +/** + * Maps a method signature from the NftRaffle smart contract to the method's arguments in either tuple of struct form + */ +export type MethodArgs = NftRaffle['methods'][TSignature]['argsObj' | 'argsTuple'] +/** + * Maps a method signature from the NftRaffle smart contract to the method's return type + */ +export type MethodReturn = NftRaffle['methods'][TSignature]['returns'] + +/** + * A factory for available 'create' calls + */ +export type NftRaffleCreateCalls = (typeof NftRaffleCallFactory)['create'] +/** + * Defines supported create methods for this smart contract + */ +export type NftRaffleCreateCallParams = + | (TypedCallParams<'createApplication(uint64,uint64)void'> & (OnCompleteNoOp)) +/** + * Defines arguments required for the deploy method. + */ +export type NftRaffleDeployArgs = { + deployTimeParams?: TealTemplateParams + /** + * A delegate which takes a create call factory and returns the create call params for this smart contract + */ + createCall?: (callFactory: NftRaffleCreateCalls) => NftRaffleCreateCallParams +} + + +/** + * Exposes methods for constructing all available smart contract calls + */ +export abstract class NftRaffleCallFactory { + /** + * Gets available create call factories + */ + static get create() { + return { + /** + * Constructs a create call for the NFTRaffle smart contract using the createApplication(uint64,uint64)void ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + createApplication(args: MethodArgs<'createApplication(uint64,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs & AppClientCompilationParams & (OnCompleteNoOp) = {}) { + return { + method: 'createApplication(uint64,uint64)void' as const, + methodArgs: Array.isArray(args) ? args : [args.ticketPrice, args.randomnessOracle], + ...params, + } + }, + } + } + + /** + * Constructs a no op call for the setAsset(asset)void ABI method + * + * Set the asset to be raffled + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static setAsset(args: MethodArgs<'setAsset(asset)void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'setAsset(asset)void' as const, + methodArgs: Array.isArray(args) ? args : [args.asset], + ...params, + } + } + /** + * Constructs a no op call for the startRaffle(axfer,uint64,uint64)void ABI method + * + * Start the raffle + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static startRaffle(args: MethodArgs<'startRaffle(axfer,uint64,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'startRaffle(axfer,uint64,uint64)void' as const, + methodArgs: Array.isArray(args) ? args : [args.axfer, args.end, args.draw], + ...params, + } + } + /** + * Constructs a no op call for the buyTickets(pay,uint64)void ABI method + * + * Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed. + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static buyTickets(args: MethodArgs<'buyTickets(pay,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'buyTickets(pay,uint64)void' as const, + methodArgs: Array.isArray(args) ? args : [args.payment, args.quantity], + ...params, + } + } + /** + * Constructs a no op call for the draw(application)bool ABI method + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static draw(args: MethodArgs<'draw(application)bool'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'draw(application)bool' as const, + methodArgs: Array.isArray(args) ? args : [args._oracleReference], + ...params, + } + } + /** + * Constructs a no op call for the claim()void ABI method + * + * Send the asset to the the sender if they have the winning ticket + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static claim(args: MethodArgs<'claim()void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'claim()void' as const, + methodArgs: Array.isArray(args) ? args : [], + ...params, + } + } + /** + * Constructs a no op call for the getRefund()void ABI method + * + * Allows purchasers to get a refund if the winning ticket has not been drawnand 1512 rounds have passed since the draw round, meaning the oracle nolonger has the data for the draw round + * + * @param args Any args for the contract call + * @param params Any additional parameters for the call + * @returns A TypedCallParams object for the call + */ + static getRefund(args: MethodArgs<'getRefund()void'>, params: AppClientCallCoreParams & CoreAppCallArgs) { + return { + method: 'getRefund()void' as const, + methodArgs: Array.isArray(args) ? args : [], + ...params, + } + } +} + +/** + * A client to make calls to the NFTRaffle smart contract + */ +export class NftRaffleClient { + /** + * The underlying `ApplicationClient` for when you want to have more flexibility + */ + public readonly appClient: ApplicationClient + + private readonly sender: SendTransactionFrom | undefined + + /** + * Creates a new instance of `NftRaffleClient` + * + * @param appDetails appDetails The details to identify the app to deploy + * @param algod An algod client instance + */ + constructor(appDetails: AppDetails, private algod: Algodv2) { + this.sender = appDetails.sender + this.appClient = algokit.getAppClient({ + ...appDetails, + app: APP_SPEC + }, algod) + } + + /** + * Checks for decode errors on the AppCallTransactionResult and maps the return value to the specified generic type + * + * @param result The AppCallTransactionResult to be mapped + * @param returnValueFormatter An optional delegate to format the return value if required + * @returns The smart contract response with an updated return value + */ + protected mapReturnValue(result: AppCallTransactionResult, returnValueFormatter?: (value: any) => TReturn): AppCallTransactionResultOfType { + if(result.return?.decodeError) { + throw result.return.decodeError + } + const returnValue = result.return?.returnValue !== undefined && returnValueFormatter !== undefined + ? returnValueFormatter(result.return.returnValue) + : result.return?.returnValue as TReturn | undefined + return { ...result, return: returnValue } + } + + /** + * Calls the ABI method with the matching signature using an onCompletion code of NO_OP + * + * @param typedCallParams An object containing the method signature, args, and any other relevant parameters + * @param returnValueFormatter An optional delegate which when provided will be used to map non-undefined return values to the target type + * @returns The result of the smart contract call + */ + public async call(typedCallParams: TypedCallParams, returnValueFormatter?: (value: any) => MethodReturn) { + return this.mapReturnValue>(await this.appClient.call(typedCallParams), returnValueFormatter) + } + + /** + * Idempotently deploys the NFTRaffle smart contract. + * + * @param params The arguments for the contract calls and any additional parameters for the call + * @returns The deployment result + */ + public deploy(params: NftRaffleDeployArgs & AppClientDeployCoreParams = {}): ReturnType { + const createArgs = params.createCall?.(NftRaffleCallFactory.create) + return this.appClient.deploy({ + ...params, + createArgs, + createOnCompleteAction: createArgs?.onCompleteAction, + }) + } + + /** + * Gets available create methods + */ + public get create() { + const $this = this + return { + /** + * Creates a new instance of the NFTRaffle smart contract using the createApplication(uint64,uint64)void ABI method. + * + * @param args The arguments for the smart contract call + * @param params Any additional parameters for the call + * @returns The create result + */ + async createApplication(args: MethodArgs<'createApplication(uint64,uint64)void'>, params: AppClientCallCoreParams & AppClientCompilationParams & (OnCompleteNoOp) = {}): Promise>> { + return $this.mapReturnValue(await $this.appClient.create(NftRaffleCallFactory.create.createApplication(args, params))) + }, + } + } + + /** + * Makes a clear_state call to an existing instance of the NFTRaffle smart contract. + * + * @param args The arguments for the bare call + * @returns The clear_state result + */ + public clearState(args: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.appClient.clearState(args) + } + + /** + * Calls the setAsset(asset)void ABI method. + * + * Set the asset to be raffled + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public setAsset(args: MethodArgs<'setAsset(asset)void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(NftRaffleCallFactory.setAsset(args, params)) + } + + /** + * Calls the startRaffle(axfer,uint64,uint64)void ABI method. + * + * Start the raffle + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public startRaffle(args: MethodArgs<'startRaffle(axfer,uint64,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(NftRaffleCallFactory.startRaffle(args, params)) + } + + /** + * Calls the buyTickets(pay,uint64)void ABI method. + * + * Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public buyTickets(args: MethodArgs<'buyTickets(pay,uint64)void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(NftRaffleCallFactory.buyTickets(args, params)) + } + + /** + * Calls the draw(application)bool ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public draw(args: MethodArgs<'draw(application)bool'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(NftRaffleCallFactory.draw(args, params)) + } + + /** + * Calls the claim()void ABI method. + * + * Send the asset to the the sender if they have the winning ticket + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public claim(args: MethodArgs<'claim()void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(NftRaffleCallFactory.claim(args, params)) + } + + /** + * Calls the getRefund()void ABI method. + * + * Allows purchasers to get a refund if the winning ticket has not been drawnand 1512 rounds have passed since the draw round, meaning the oracle nolonger has the data for the draw round + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The result of the call + */ + public getRefund(args: MethodArgs<'getRefund()void'>, params: AppClientCallCoreParams & CoreAppCallArgs = {}) { + return this.call(NftRaffleCallFactory.getRefund(args, params)) + } + + /** + * Extracts a binary state value out of an AppState dictionary + * + * @param state The state dictionary containing the state value + * @param key The key of the state value + * @returns A BinaryState instance containing the state value, or undefined if the key was not found + */ + private static getBinaryState(state: AppState, key: string): BinaryState | undefined { + const value = state[key] + if (!value) return undefined + if (!('valueRaw' in value)) + throw new Error(`Failed to parse state value for ${key}; received an int when expected a byte array`) + return { + asString(): string { + return value.value + }, + asByteArray(): Uint8Array { + return value.valueRaw + } + } + } + + /** + * Extracts a integer state value out of an AppState dictionary + * + * @param state The state dictionary containing the state value + * @param key The key of the state value + * @returns An IntegerState instance containing the state value, or undefined if the key was not found + */ + private static getIntegerState(state: AppState, key: string): IntegerState | undefined { + const value = state[key] + if (!value) return undefined + if ('valueRaw' in value) + throw new Error(`Failed to parse state value for ${key}; received a byte array when expected a number`) + return { + asBigInt() { + return typeof value.value === 'bigint' ? value.value : BigInt(value.value) + }, + asNumber(): number { + return typeof value.value === 'bigint' ? Number(value.value) : value.value + }, + } + } + + /** + * Returns the smart contract's global state wrapped in a strongly typed accessor with options to format the stored value + */ + public async getGlobalState(): Promise { + const state = await this.appClient.getGlobalState() + return { + get randomnessOracle() { + return NftRaffleClient.getIntegerState(state, 'randomnessOracle') + }, + get ticketPrice() { + return NftRaffleClient.getIntegerState(state, 'ticketPrice') + }, + get asset() { + return NftRaffleClient.getIntegerState(state, 'asset') + }, + get endRound() { + return NftRaffleClient.getIntegerState(state, 'endRound') + }, + get drawRound() { + return NftRaffleClient.getIntegerState(state, 'drawRound') + }, + get totalTickets() { + return NftRaffleClient.getIntegerState(state, 'totalTickets') + }, + get winningTicket() { + return NftRaffleClient.getIntegerState(state, 'winningTicket') + }, + get randomBytes() { + return NftRaffleClient.getBinaryState(state, 'randomBytes') + }, + } + } + + public compose(): NftRaffleComposer { + const client = this + const atc = new AtomicTransactionComposer() + let promiseChain:Promise = Promise.resolve() + const resultMappers: Array any)> = [] + return { + setAsset(args: MethodArgs<'setAsset(asset)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.setAsset(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + startRaffle(args: MethodArgs<'startRaffle(axfer,uint64,uint64)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.startRaffle(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + buyTickets(args: MethodArgs<'buyTickets(pay,uint64)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.buyTickets(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + draw(args: MethodArgs<'draw(application)bool'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.draw(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + claim(args: MethodArgs<'claim()void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.claim(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + getRefund(args: MethodArgs<'getRefund()void'>, params?: AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.getRefund(args, {...params, sendParams: {...params?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + clearState(args?: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs) { + promiseChain = promiseChain.then(() => client.clearState({...args, sendParams: {...args?.sendParams, skipSending: true, atc}})) + resultMappers.push(undefined) + return this + }, + addTransaction(txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, defaultSender?: SendTransactionFrom) { + promiseChain = promiseChain.then(async () => atc.addTransaction(await algokit.getTransactionWithSigner(txn, defaultSender ?? client.sender))) + return this + }, + async atc() { + await promiseChain + return atc + }, + async execute() { + await promiseChain + const result = await algokit.sendAtomicTransactionComposer({ atc, sendParams: {} }, client.algod) + return { + ...result, + returns: result.returns?.map((val, i) => resultMappers[i] !== undefined ? resultMappers[i]!(val.returnValue) : val.returnValue) + } + } + } as unknown as NftRaffleComposer + } +} +export type NftRaffleComposer = { + /** + * Calls the setAsset(asset)void ABI method. + * + * Set the asset to be raffled + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + setAsset(args: MethodArgs<'setAsset(asset)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs): NftRaffleComposer<[...TReturns, MethodReturn<'setAsset(asset)void'>]> + + /** + * Calls the startRaffle(axfer,uint64,uint64)void ABI method. + * + * Start the raffle + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + startRaffle(args: MethodArgs<'startRaffle(axfer,uint64,uint64)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs): NftRaffleComposer<[...TReturns, MethodReturn<'startRaffle(axfer,uint64,uint64)void'>]> + + /** + * Calls the buyTickets(pay,uint64)void ABI method. + * + * Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + buyTickets(args: MethodArgs<'buyTickets(pay,uint64)void'>, params?: AppClientCallCoreParams & CoreAppCallArgs): NftRaffleComposer<[...TReturns, MethodReturn<'buyTickets(pay,uint64)void'>]> + + /** + * Calls the draw(application)bool ABI method. + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + draw(args: MethodArgs<'draw(application)bool'>, params?: AppClientCallCoreParams & CoreAppCallArgs): NftRaffleComposer<[...TReturns, MethodReturn<'draw(application)bool'>]> + + /** + * Calls the claim()void ABI method. + * + * Send the asset to the the sender if they have the winning ticket + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + claim(args: MethodArgs<'claim()void'>, params?: AppClientCallCoreParams & CoreAppCallArgs): NftRaffleComposer<[...TReturns, MethodReturn<'claim()void'>]> + + /** + * Calls the getRefund()void ABI method. + * + * Allows purchasers to get a refund if the winning ticket has not been drawnand 1512 rounds have passed since the draw round, meaning the oracle nolonger has the data for the draw round + * + * @param args The arguments for the contract call + * @param params Any additional parameters for the call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + getRefund(args: MethodArgs<'getRefund()void'>, params?: AppClientCallCoreParams & CoreAppCallArgs): NftRaffleComposer<[...TReturns, MethodReturn<'getRefund()void'>]> + + /** + * Makes a clear_state call to an existing instance of the NFTRaffle smart contract. + * + * @param args The arguments for the bare call + * @returns The typed transaction composer so you can fluently chain multiple calls or call execute to execute all queued up transactions + */ + clearState(args?: BareCallArgs & AppClientCallCoreParams & CoreAppCallArgs): NftRaffleComposer<[...TReturns, undefined]> + + /** + * Adds a transaction to the composer + * + * @param txn One of: A TransactionWithSigner object (returned as is), a TransactionToSign object (signer is obtained from the signer property), a Transaction object (signer is extracted from the defaultSender parameter), an async SendTransactionResult returned by one of algokit utils helpers (signer is obtained from the defaultSender parameter) + * @param defaultSender The default sender to be used to obtain a signer where the object provided to the transaction parameter does not include a signer. + */ + addTransaction(txn: TransactionWithSigner | TransactionToSign | Transaction | Promise, defaultSender?: SendTransactionFrom): NftRaffleComposer + /** + * Returns the underlying AtomicTransactionComposer instance + */ + atc(): Promise + /** + * Executes the transaction group and returns an array of results + */ + execute(): Promise> +} +export type NftRaffleComposerResults = { + returns: TReturns + groupId: string + txIds: string[] + transactions: Transaction[] +} diff --git a/examples/raffle/artifacts/MockVRFBeacon.approval.teal b/examples/raffle/artifacts/MockVRFBeacon.approval.teal new file mode 100644 index 000000000..a6e93f8f1 --- /dev/null +++ b/examples/raffle/artifacts/MockVRFBeacon.approval.teal @@ -0,0 +1,76 @@ +#pragma version 9 + +// This TEAL was generated by TEALScript v0.63.0 +// https://github.com/algorandfoundation/TEALScript + +// This contract is compliant with and/or implements the following ARCs: [ ARC4 ] + +// The following ten lines of TEAL handle initial program flow +// This pattern is used to make it easy for anyone to parse the start of the program and determine if a specific action is allowed +// Here, action refers to the OnComplete in combination with whether the app is being created or called +// Every possible action for this contract is represented in the switch statement +// If the action is not implmented in the contract, its repsective branch will be "NOT_IMPLMENTED" which just contains "err" +txn ApplicationID +int 0 +> +int 6 +* +txn OnCompletion ++ +switch create_NoOp NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED NOT_IMPLEMENTED call_NoOp + +NOT_IMPLEMENTED: + err + +// must_get(bytes,uint64)byte[] +abi_route_must_get: + // data: byte[] + txna ApplicationArgs 2 + extract 2 0 + + // _round: uint64 + txna ApplicationArgs 1 + btoi + + // execute must_get(bytes,uint64)byte[] + callsub must_get + int 1 + return + +must_get: + proto 2 0 + + // examples/raffle/raffle.algo.ts:200 + // return sha256(data + itob(globals.round)) as bytes; + frame_dig -2 // data: bytes + global Round + itob + concat + sha256 + dup + len + itob + extract 6 2 + swap + concat + byte 0x151f7c75 + swap + concat + log + retsub + +abi_route_createApplication: + int 1 + return + +create_NoOp: + method "createApplication()void" + txna ApplicationArgs 0 + match abi_route_createApplication + err + +call_NoOp: + method "must_get(uint64,byte[])byte[]" + txna ApplicationArgs 0 + match abi_route_must_get + err \ No newline at end of file diff --git a/examples/raffle/artifacts/MockVRFBeacon.arc32.json b/examples/raffle/artifacts/MockVRFBeacon.arc32.json new file mode 100644 index 000000000..c618a05f8 --- /dev/null +++ b/examples/raffle/artifacts/MockVRFBeacon.arc32.json @@ -0,0 +1,80 @@ +{ + "hints": { + "must_get(uint64,byte[])byte[]": { + "call_config": { + "no_op": "CALL" + } + }, + "createApplication()void": { + "call_config": { + "no_op": "CREATE" + } + } + }, + "bare_call_config": { + "no_op": "NEVER", + "opt_in": "NEVER", + "close_out": "NEVER", + "update_application": "NEVER", + "delete_application": "NEVER" + }, + "schema": { + "local": { + "declared": {}, + "reserved": {} + }, + "global": { + "declared": {}, + "reserved": {} + } + }, + "state": { + "global": { + "num_byte_slices": 0, + "num_uints": 0 + }, + "local": { + "num_byte_slices": 0, + "num_uints": 0 + } + }, + "source": { + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIG11c3RfZ2V0KGJ5dGVzLHVpbnQ2NClieXRlW10KYWJpX3JvdXRlX211c3RfZ2V0OgoJLy8gZGF0YTogYnl0ZVtdCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglleHRyYWN0IDIgMAoKCS8vIF9yb3VuZDogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gZXhlY3V0ZSBtdXN0X2dldChieXRlcyx1aW50NjQpYnl0ZVtdCgljYWxsc3ViIG11c3RfZ2V0CglpbnQgMQoJcmV0dXJuCgptdXN0X2dldDoKCXByb3RvIDIgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoyMDAKCS8vIHJldHVybiBzaGEyNTYoZGF0YSArIGl0b2IoZ2xvYmFscy5yb3VuZCkpIGFzIGJ5dGVzOwoJZnJhbWVfZGlnIC0yIC8vIGRhdGE6IGJ5dGVzCglnbG9iYWwgUm91bmQKCWl0b2IKCWNvbmNhdAoJc2hhMjU2CglkdXAKCWxlbgoJaXRvYgoJZXh0cmFjdCA2IDIKCXN3YXAKCWNvbmNhdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgphYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb246CglpbnQgMQoJcmV0dXJuCgpjcmVhdGVfTm9PcDoKCW1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24oKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9tdXN0X2dldAoJZXJy", + "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" + }, + "contract": { + "name": "MockVRFBeacon", + "desc": "", + "methods": [ + { + "name": "must_get", + "args": [ + { + "name": "_round", + "type": "uint64", + "desc": "" + }, + { + "name": "data", + "type": "byte[]", + "desc": "" + } + ], + "desc": "", + "returns": { + "type": "byte[]", + "desc": "" + } + }, + { + "name": "createApplication", + "desc": "", + "returns": { + "type": "void", + "desc": "" + }, + "args": [] + } + ] + } +} \ No newline at end of file diff --git a/examples/raffle/artifacts/MockVRFBeacon.arc4.json b/examples/raffle/artifacts/MockVRFBeacon.arc4.json new file mode 100644 index 000000000..f1d48170a --- /dev/null +++ b/examples/raffle/artifacts/MockVRFBeacon.arc4.json @@ -0,0 +1,35 @@ +{ + "name": "MockVRFBeacon", + "desc": "", + "methods": [ + { + "name": "must_get", + "args": [ + { + "name": "_round", + "type": "uint64", + "desc": "" + }, + { + "name": "data", + "type": "byte[]", + "desc": "" + } + ], + "desc": "", + "returns": { + "type": "byte[]", + "desc": "" + } + }, + { + "name": "createApplication", + "desc": "", + "returns": { + "type": "void", + "desc": "" + }, + "args": [] + } + ] +} \ No newline at end of file diff --git a/examples/raffle/artifacts/MockVRFBeacon.clear.teal b/examples/raffle/artifacts/MockVRFBeacon.clear.teal new file mode 100644 index 000000000..858e5674c --- /dev/null +++ b/examples/raffle/artifacts/MockVRFBeacon.clear.teal @@ -0,0 +1 @@ +#pragma version 9 \ No newline at end of file diff --git a/examples/raffle/artifacts/MockVRFBeacon.src_map.json b/examples/raffle/artifacts/MockVRFBeacon.src_map.json new file mode 100644 index 000000000..134a0b463 --- /dev/null +++ b/examples/raffle/artifacts/MockVRFBeacon.src_map.json @@ -0,0 +1,371 @@ +[ + { + "teal": 1, + "source": 198, + "pc": [ + 0, + 1, + 2, + 3 + ] + }, + { + "teal": 13, + "source": 198, + "pc": [ + 4, + 5 + ] + }, + { + "teal": 14, + "source": 198, + "pc": [ + 6, + 7 + ] + }, + { + "teal": 15, + "source": 198, + "pc": [ + 8 + ] + }, + { + "teal": 16, + "source": 198, + "pc": [ + 9, + 10 + ] + }, + { + "teal": 17, + "source": 198, + "pc": [ + 11 + ] + }, + { + "teal": 18, + "source": 198, + "pc": [ + 12, + 13 + ] + }, + { + "teal": 19, + "source": 198, + "pc": [ + 14 + ] + }, + { + "teal": 20, + "source": 198, + "pc": [ + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ] + }, + { + "teal": 23, + "source": 198, + "pc": [ + 31 + ] + }, + { + "teal": 28, + "source": 199, + "pc": [ + 32, + 33, + 34 + ] + }, + { + "teal": 29, + "source": 199, + "pc": [ + 35, + 36, + 37 + ] + }, + { + "teal": 32, + "source": 199, + "pc": [ + 38, + 39, + 40 + ] + }, + { + "teal": 33, + "source": 199, + "pc": [ + 41 + ] + }, + { + "teal": 36, + "source": 199, + "pc": [ + 42, + 43, + 44 + ] + }, + { + "teal": 37, + "source": 199, + "pc": [ + 45 + ] + }, + { + "teal": 38, + "source": 199, + "pc": [ + 46 + ] + }, + { + "teal": 41, + "source": 199, + "pc": [ + 47, + 48, + 49 + ] + }, + { + "teal": 45, + "source": 200, + "pc": [ + 50, + 51 + ] + }, + { + "teal": 46, + "source": 200, + "pc": [ + 52, + 53 + ] + }, + { + "teal": 47, + "source": 200, + "pc": [ + 54 + ] + }, + { + "teal": 48, + "source": 200, + "pc": [ + 55 + ] + }, + { + "teal": 49, + "source": 200, + "pc": [ + 56 + ] + }, + { + "teal": 50, + "source": 200, + "pc": [ + 57 + ] + }, + { + "teal": 51, + "source": 200, + "pc": [ + 58 + ] + }, + { + "teal": 52, + "source": 200, + "pc": [ + 59 + ] + }, + { + "teal": 53, + "source": 200, + "pc": [ + 60, + 61, + 62 + ] + }, + { + "teal": 54, + "source": 200, + "pc": [ + 63 + ] + }, + { + "teal": 55, + "source": 200, + "pc": [ + 64 + ] + }, + { + "teal": 56, + "source": 200, + "pc": [ + 65, + 66, + 67, + 68, + 69, + 70 + ] + }, + { + "teal": 57, + "source": 200, + "pc": [ + 71 + ] + }, + { + "teal": 58, + "source": 200, + "pc": [ + 72 + ] + }, + { + "teal": 59, + "source": 200, + "pc": [ + 73 + ] + }, + { + "teal": 60, + "source": 200, + "pc": [ + 74 + ] + }, + { + "teal": 63, + "source": 198, + "pc": [ + 75 + ] + }, + { + "teal": 64, + "source": 198, + "pc": [ + 76 + ] + }, + { + "teal": 67, + "source": 198, + "pc": [ + 77, + 78, + 79, + 80, + 81, + 82 + ] + }, + { + "teal": 68, + "source": 198, + "pc": [ + 83, + 84, + 85 + ] + }, + { + "teal": 69, + "source": 198, + "pc": [ + 86, + 87, + 88, + 89 + ] + }, + { + "teal": 70, + "source": 198, + "pc": [ + 90 + ] + }, + { + "teal": 73, + "source": 198, + "pc": [ + 91, + 92, + 93, + 94, + 95, + 96 + ] + }, + { + "teal": 74, + "source": 198, + "pc": [ + 97, + 98, + 99 + ] + }, + { + "teal": 75, + "source": 198, + "pc": [ + 100, + 101, + 102, + 103 + ] + }, + { + "teal": 76, + "source": 198, + "pc": [ + 104 + ] + } +] \ No newline at end of file diff --git a/examples/raffle/artifacts/NFTRaffle.approval.teal b/examples/raffle/artifacts/NFTRaffle.approval.teal index 778fce7a1..023f90de4 100644 --- a/examples/raffle/artifacts/NFTRaffle.approval.teal +++ b/examples/raffle/artifacts/NFTRaffle.approval.teal @@ -128,7 +128,7 @@ setAsset: app_global_put retsub -// startRaffle(uint64,uint64)void +// startRaffle(uint64,uint64,axfer)void // // Start the raffle // @@ -143,42 +143,69 @@ abi_route_startRaffle: txna ApplicationArgs 1 btoi - // execute startRaffle(uint64,uint64)void + // axfer: axfer + txn GroupIndex + int 1 + - + dup + gtxns TypeEnum + int axfer + == + assert + + // execute startRaffle(uint64,uint64,axfer)void callsub startRaffle int 1 return startRaffle: - proto 2 0 + proto 3 0 // examples/raffle/raffle.algo.ts:74 - // assert(this.app.address.assetBalance(this.asset.value) > 0) + // verifyTxn(axfer, { + // assetAmount: { greaterThan: 0 }, + // assetReceiver: this.app.address, + // xferAsset: this.asset.value, + // }) + // verify assetAmount + frame_dig -1 // axfer: axfer + gtxns AssetAmount + int 0 + > + assert + + // verify assetReceiver + frame_dig -1 // axfer: axfer + gtxns AssetReceiver global CurrentApplicationAddress + == + assert + + // verify xferAsset + frame_dig -1 // axfer: axfer + gtxns XferAsset byte 0x6173736574 // "asset" app_global_get - asset_holding_get AssetBalance - assert - int 0 - > + == assert - // examples/raffle/raffle.algo.ts:76 + // examples/raffle/raffle.algo.ts:80 // assert(draw > end) - frame_dig -2 // draw: uint64 - frame_dig -1 // end: uint64 + frame_dig -3 // draw: uint64 + frame_dig -2 // end: uint64 > assert - // examples/raffle/raffle.algo.ts:77 + // examples/raffle/raffle.algo.ts:81 // this.endRound.value = end byte 0x656e64526f756e64 // "endRound" - frame_dig -1 // end: uint64 + frame_dig -2 // end: uint64 app_global_put - // examples/raffle/raffle.algo.ts:78 + // examples/raffle/raffle.algo.ts:82 // this.drawRound.value = draw byte 0x64726177526f756e64 // "drawRound" - frame_dig -2 // draw: uint64 + frame_dig -3 // draw: uint64 app_global_put retsub @@ -193,9 +220,9 @@ startRaffle: // // @returns The total number of tickets owned by the sender abi_route_buyTickets: - byte 0x // push empty bytes to fill the stack frame for this subroutine's local variables + byte 0x; dupn 2 // push empty bytes to fill the stack frame for this subroutine's local variables - // quanity: uint64 + // quantity: uint64 txna ApplicationArgs 1 btoi @@ -215,9 +242,9 @@ abi_route_buyTickets: return buyTickets: - proto 3 0 + proto 5 0 - // examples/raffle/raffle.algo.ts:92 + // examples/raffle/raffle.algo.ts:96 // assert(globals.round < this.endRound.value) global Round byte 0x656e64526f756e64 // "endRound" @@ -225,40 +252,13 @@ buyTickets: < assert - // examples/raffle/raffle.algo.ts:93 - // assert(quanity > 0) - frame_dig -2 // quanity: uint64 + // examples/raffle/raffle.algo.ts:97 + // assert(quantity > 0) + frame_dig -2 // quantity: uint64 int 0 > assert - // examples/raffle/raffle.algo.ts:95 - // assert(payment.amount === this.ticketPrice.value * quanity) - frame_dig -1 // payment: pay - gtxns Amount - byte 0x7469636b65745072696365 // "ticketPrice" - app_global_get - frame_dig -2 // quanity: uint64 - * - == - assert - - // examples/raffle/raffle.algo.ts:96 - // assert(payment.sender === this.txn.sender) - frame_dig -1 // payment: pay - gtxns Sender - txn Sender - == - assert - - // examples/raffle/raffle.algo.ts:97 - // assert(payment.receiver === this.app.address) - frame_dig -1 // payment: pay - gtxns Receiver - global CurrentApplicationAddress - == - assert - // examples/raffle/raffle.algo.ts:99 // assert(!this.tickets(payment.sender).exists) frame_dig -1 // payment: pay @@ -270,16 +270,23 @@ buyTickets: assert // examples/raffle/raffle.algo.ts:101 - // newTotal = this.totalTickets.value + quanity + 1 + // newTotal = this.totalTickets.value + quantity + 1 byte 0x746f74616c5469636b657473 // "totalTickets" app_global_get - frame_dig -2 // quanity: uint64 + frame_dig -2 // quantity: uint64 + int 1 + frame_bury -3 // newTotal: uint64 // examples/raffle/raffle.algo.ts:103 + // preMBR = this.app.address.minBalance + global CurrentApplicationAddress + acct_params_get AcctMinBalance + assert + frame_bury -4 // preMBR: uint64 + + // examples/raffle/raffle.algo.ts:104 // this.tickets(payment.sender).value = { start: this.totalTickets.value, end: newTotal - 1 } frame_dig -1 // payment: pay gtxns Sender @@ -293,7 +300,48 @@ buyTickets: concat box_put - // examples/raffle/raffle.algo.ts:104 + // examples/raffle/raffle.algo.ts:105 + // mbrDelta = this.app.address.minBalance - preMBR + global CurrentApplicationAddress + acct_params_get AcctMinBalance + assert + frame_dig -4 // preMBR: uint64 + - + frame_bury -5 // mbrDelta: uint64 + + // examples/raffle/raffle.algo.ts:107 + // verifyTxn(payment, { + // amount: this.ticketPrice.value * quantity + mbrDelta, + // sender: this.txn.sender, + // receiver: this.app.address, + // }) + // verify amount + frame_dig -1 // payment: pay + gtxns Amount + byte 0x7469636b65745072696365 // "ticketPrice" + app_global_get + frame_dig -2 // quantity: uint64 + * + frame_dig -5 // mbrDelta: uint64 + + + == + assert + + // verify sender + frame_dig -1 // payment: pay + gtxns Sender + txn Sender + == + assert + + // verify receiver + frame_dig -1 // payment: pay + gtxns Receiver + global CurrentApplicationAddress + == + assert + + // examples/raffle/raffle.algo.ts:113 // this.totalTickets.value = newTotal byte 0x746f74616c5469636b657473 // "totalTickets" frame_dig -3 // newTotal: uint64 @@ -304,7 +352,7 @@ getRandomBytes: proto 0 0 // if0_condition - // examples/raffle/raffle.algo.ts:109 + // examples/raffle/raffle.algo.ts:118 // this.randomBytes.exists txna Applications 0 byte 0x72616e646f6d4279746573 // "randomBytes" @@ -314,7 +362,7 @@ getRandomBytes: bz if0_else // if0_consequent - // examples/raffle/raffle.algo.ts:110 + // examples/raffle/raffle.algo.ts:119 // this.randomBytes.value = sha256(this.randomBytes.value) as bytes byte 0x72616e646f6d4279746573 // "randomBytes" byte 0x72616e646f6d4279746573 // "randomBytes" @@ -324,7 +372,7 @@ getRandomBytes: b if0_end if0_else: - // examples/raffle/raffle.algo.ts:112 + // examples/raffle/raffle.algo.ts:121 // this.randomBytes.value = sendMethodCall<[uint64, bytes], bytes>({ // name: 'must_get', // methodArgs: [this.drawRound.value, ''], @@ -339,7 +387,7 @@ if0_else: method "must_get(uint64,byte[])byte[]" itxn_field ApplicationArgs - // examples/raffle/raffle.algo.ts:114 + // examples/raffle/raffle.algo.ts:123 // methodArgs: [this.drawRound.value, ''] byte 0x64726177526f756e64 // "drawRound" app_global_get @@ -348,18 +396,18 @@ if0_else: byte 0x0000 itxn_field ApplicationArgs - // examples/raffle/raffle.algo.ts:115 + // examples/raffle/raffle.algo.ts:124 // applicationID: Application.fromID(this.randomnessOracle.value) byte 0x72616e646f6d6e6573734f7261636c65 // "randomnessOracle" app_global_get itxn_field ApplicationID - // examples/raffle/raffle.algo.ts:116 + // examples/raffle/raffle.algo.ts:125 // fee: 0 int 0 itxn_field Fee - // examples/raffle/raffle.algo.ts:117 + // examples/raffle/raffle.algo.ts:126 // onCompletion: 'NoOp' int NoOp itxn_field OnCompletion @@ -376,21 +424,26 @@ if0_else: if0_end: retsub -// draw()bool +// draw(application)bool // -// Draw the winning ticket +// // eslint-disable-next-line no-unused-vars abi_route_draw: byte 0x; dupn 3 // push empty bytes to fill the stack frame for this subroutine's local variables - // execute draw()bool + // _oracleReference: application + txna ApplicationArgs 1 + btoi + txnas Applications + + // execute draw(application)bool callsub draw int 1 return draw: - proto 4 0 + proto 5 0 - // examples/raffle/raffle.algo.ts:124 + // examples/raffle/raffle.algo.ts:135 // assert(!this.winningTicket.exists) txna Applications 0 byte 0x77696e6e696e675469636b6574 // "winningTicket" @@ -400,55 +453,55 @@ draw: ! assert - // examples/raffle/raffle.algo.ts:125 + // examples/raffle/raffle.algo.ts:136 // this.getRandomBytes() callsub getRandomBytes - // examples/raffle/raffle.algo.ts:129 + // examples/raffle/raffle.algo.ts:140 // n = this.totalTickets.value byte 0x746f74616c5469636b657473 // "totalTickets" app_global_get - frame_bury -1 // n: uint64 + frame_bury -2 // n: uint64 - // examples/raffle/raffle.algo.ts:131 + // examples/raffle/raffle.algo.ts:142 // offset = 0 int 0 - frame_bury -3 // offset: uint64 + frame_bury -4 // offset: uint64 do_while_0: - // examples/raffle/raffle.algo.ts:135 + // examples/raffle/raffle.algo.ts:146 // x = extract_uint64(this.randomBytes.value, offset) byte 0x72616e646f6d4279746573 // "randomBytes" app_global_get - frame_dig -3 // offset: uint64 + frame_dig -4 // offset: uint64 extract_uint64 - frame_bury -2 // x: uint64 + frame_bury -3 // x: uint64 - // examples/raffle/raffle.algo.ts:137 + // examples/raffle/raffle.algo.ts:148 // offset = offset + 8 - frame_dig -3 // offset: uint64 + frame_dig -4 // offset: uint64 int 8 + - frame_bury -3 // offset: uint64 + frame_bury -4 // offset: uint64 - // examples/raffle/raffle.algo.ts:139 + // examples/raffle/raffle.algo.ts:150 // maxCondition = x > RAND_MAX - (((RAND_MAX % n) + 1) % n) - frame_dig -2 // x: uint64 + frame_dig -3 // x: uint64 int 18_446_744_073_709_551_615 int 18_446_744_073_709_551_615 - frame_dig -1 // n: uint64 + frame_dig -2 // n: uint64 % int 1 + - frame_dig -1 // n: uint64 + frame_dig -2 // n: uint64 % - > - frame_bury -4 // maxCondition: bool - frame_dig -4 // maxCondition: bool + frame_bury -5 // maxCondition: bool + frame_dig -5 // maxCondition: bool dup bz skip_and0 - frame_dig -3 // offset: uint64 + frame_dig -4 // offset: uint64 int 32 < && @@ -457,13 +510,13 @@ skip_and0: bnz do_while_0 // if1_condition - // examples/raffle/raffle.algo.ts:142 + // examples/raffle/raffle.algo.ts:153 // maxCondition - frame_dig -4 // maxCondition: bool + frame_dig -5 // maxCondition: bool bz if1_end // if1_consequent - // examples/raffle/raffle.algo.ts:142 + // examples/raffle/raffle.algo.ts:153 // return false; int 0 byte 0x00 @@ -477,15 +530,15 @@ skip_and0: retsub if1_end: - // examples/raffle/raffle.algo.ts:144 + // examples/raffle/raffle.algo.ts:155 // this.winningTicket.value = x % n byte 0x77696e6e696e675469636b6574 // "winningTicket" - frame_dig -2 // x: uint64 - frame_dig -1 // n: uint64 + frame_dig -3 // x: uint64 + frame_dig -2 // n: uint64 % app_global_put - // examples/raffle/raffle.algo.ts:145 + // examples/raffle/raffle.algo.ts:156 // return true; int 1 byte 0x00 @@ -512,12 +565,12 @@ abi_route_claim: claim: proto 1 0 - // examples/raffle/raffle.algo.ts:150 + // examples/raffle/raffle.algo.ts:161 // ticketRange = this.tickets(this.txn.sender).value txn Sender frame_bury -1 // storage key//ticketRange - // examples/raffle/raffle.algo.ts:152 + // examples/raffle/raffle.algo.ts:163 // assert(ticketRange.start <= this.winningTicket.value) frame_dig -1 // storage key//ticketRange box_get @@ -529,7 +582,7 @@ claim: <= assert - // examples/raffle/raffle.algo.ts:153 + // examples/raffle/raffle.algo.ts:164 // assert(ticketRange.end >= this.winningTicket.value) frame_dig -1 // storage key//ticketRange box_get @@ -541,7 +594,7 @@ claim: >= assert - // examples/raffle/raffle.algo.ts:155 + // examples/raffle/raffle.algo.ts:166 // sendAssetTransfer({ // assetReceiver: this.txn.sender, // xferAsset: this.asset.value, @@ -553,18 +606,18 @@ claim: int axfer itxn_field TypeEnum - // examples/raffle/raffle.algo.ts:156 + // examples/raffle/raffle.algo.ts:167 // assetReceiver: this.txn.sender txn Sender itxn_field AssetReceiver - // examples/raffle/raffle.algo.ts:157 + // examples/raffle/raffle.algo.ts:168 // xferAsset: this.asset.value byte 0x6173736574 // "asset" app_global_get itxn_field XferAsset - // examples/raffle/raffle.algo.ts:158 + // examples/raffle/raffle.algo.ts:169 // assetAmount: this.app.address.assetBalance(this.asset.value) global CurrentApplicationAddress byte 0x6173736574 // "asset" @@ -573,12 +626,12 @@ claim: assert itxn_field AssetAmount - // examples/raffle/raffle.algo.ts:159 + // examples/raffle/raffle.algo.ts:170 // assetCloseTo: this.txn.sender txn Sender itxn_field AssetCloseTo - // examples/raffle/raffle.algo.ts:160 + // examples/raffle/raffle.algo.ts:171 // fee: 0 int 0 itxn_field Fee @@ -603,7 +656,7 @@ abi_route_getRefund: getRefund: proto 2 0 - // examples/raffle/raffle.algo.ts:170 + // examples/raffle/raffle.algo.ts:181 // assert(!this.winningTicket.exists) txna Applications 0 byte 0x77696e6e696e675469636b6574 // "winningTicket" @@ -613,7 +666,7 @@ getRefund: ! assert - // examples/raffle/raffle.algo.ts:171 + // examples/raffle/raffle.algo.ts:182 // assert(globals.round > this.drawRound.value + 1512) global Round byte 0x64726177526f756e64 // "drawRound" @@ -623,12 +676,12 @@ getRefund: > assert - // examples/raffle/raffle.algo.ts:173 + // examples/raffle/raffle.algo.ts:184 // ticketRange = this.tickets(this.txn.sender).value txn Sender frame_bury -1 // storage key//ticketRange - // examples/raffle/raffle.algo.ts:174 + // examples/raffle/raffle.algo.ts:185 // ticketCount = ticketRange.end - ticketRange.start + 1 frame_dig -1 // storage key//ticketRange box_get @@ -645,12 +698,12 @@ getRefund: + frame_bury -2 // ticketCount: uint64 - // examples/raffle/raffle.algo.ts:176 + // examples/raffle/raffle.algo.ts:187 // this.tickets(this.txn.sender).delete() txn Sender box_del - // examples/raffle/raffle.algo.ts:178 + // examples/raffle/raffle.algo.ts:189 // sendPayment({ // amount: this.ticketPrice.value * ticketCount, // receiver: this.txn.sender, @@ -660,7 +713,7 @@ getRefund: int pay itxn_field TypeEnum - // examples/raffle/raffle.algo.ts:179 + // examples/raffle/raffle.algo.ts:190 // amount: this.ticketPrice.value * ticketCount byte 0x7469636b65745072696365 // "ticketPrice" app_global_get @@ -668,12 +721,12 @@ getRefund: * itxn_field Amount - // examples/raffle/raffle.algo.ts:180 + // examples/raffle/raffle.algo.ts:191 // receiver: this.txn.sender txn Sender itxn_field Receiver - // examples/raffle/raffle.algo.ts:181 + // examples/raffle/raffle.algo.ts:192 // fee: 0 int 0 itxn_field Fee @@ -690,9 +743,9 @@ create_NoOp: call_NoOp: method "setAsset(asset)void" - method "startRaffle(uint64,uint64)void" + method "startRaffle(axfer,uint64,uint64)void" method "buyTickets(pay,uint64)void" - method "draw()bool" + method "draw(application)bool" method "claim()void" method "getRefund()void" txna ApplicationArgs 0 diff --git a/examples/raffle/artifacts/NFTRaffle.arc32.json b/examples/raffle/artifacts/NFTRaffle.arc32.json index 5702c4915..cdef78233 100644 --- a/examples/raffle/artifacts/NFTRaffle.arc32.json +++ b/examples/raffle/artifacts/NFTRaffle.arc32.json @@ -10,7 +10,7 @@ "no_op": "CALL" } }, - "startRaffle(uint64,uint64)void": { + "startRaffle(axfer,uint64,uint64)void": { "call_config": { "no_op": "CALL" } @@ -20,7 +20,7 @@ "no_op": "CALL" } }, - "draw()bool": { + "draw(application)bool": { "call_config": { "no_op": "CALL" } @@ -97,7 +97,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAovLwovLyBDcmVhdGUgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gdGlja2V0UHJpY2UgVGhlIHByaWNlIG9mIGEgc2luZ2xlIHRpY2tldCAodUFMR08pCi8vIEBwYXJhbSByYW5kb21uZXNzT3JhY2xlIFRoZSBhcHAgSUQgb2YgdGhlIHJhbmRvbW5lc3Mgb3JhY2xlCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIHJhbmRvbW5lc3NPcmFjbGU6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIHRpY2tldFByaWNlOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBjcmVhdGVBcHBsaWNhdGlvbgoJaW50IDEKCXJldHVybgoKY3JlYXRlQXBwbGljYXRpb246Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NDMKCS8vIHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSA9IHJhbmRvbW5lc3NPcmFjbGUKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQ0CgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWZyYW1lX2RpZyAtMSAvLyB0aWNrZXRQcmljZTogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzZXRBc3NldChhc3NldCl2b2lkCi8vCi8vIFNldCB0aGUgYXNzZXQgdG8gYmUgcmFmZmxlZAovLwovLyBAcGFyYW0gYXNzZXQgVGhlIGFzc2V0IHRvIGJlIHJhZmZsZWQKYWJpX3JvdXRlX3NldEFzc2V0OgoJLy8gYXNzZXQ6IGFzc2V0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCgkvLyBleGVjdXRlIHNldEFzc2V0KGFzc2V0KXZvaWQKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU0CgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiBhc3NldCwKCS8vICAgICAgIGFzc2V0QW1vdW50OiAwLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTcKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMuYXBwLmFkZHJlc3MKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTgKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU5CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NjAKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo2MwoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglmcmFtZV9kaWcgLTEgLy8gYXNzZXQ6IGFzc2V0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0KXZvaWQKLy8KLy8gU3RhcnQgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gZW5kIFRoZSByb3VuZCBudW1iZXIgd2hlbiB0aGUgcmFmZmxlIGVuZHMKLy8gQHBhcmFtIGRyYXcgVGhlIHJvdW5kIG51bWJlciB3aGVuIHRoZSByYWZmbGUgaXMgZHJhd24KYWJpX3JvdXRlX3N0YXJ0UmFmZmxlOgoJLy8gZHJhdzogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgoJLy8gZW5kOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIHN0YXJ0UmFmZmxlKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBzdGFydFJhZmZsZQoJaW50IDEKCXJldHVybgoKc3RhcnRSYWZmbGU6Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NzQKCS8vIGFzc2VydCh0aGlzLmFwcC5hZGRyZXNzLmFzc2V0QmFsYW5jZSh0aGlzLmFzc2V0LnZhbHVlKSA+IDApCglnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQoJYXNzZXJ0CglpbnQgMAoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc2CgkvLyBhc3NlcnQoZHJhdyA+IGVuZCkKCWZyYW1lX2RpZyAtMiAvLyBkcmF3OiB1aW50NjQKCWZyYW1lX2RpZyAtMSAvLyBlbmQ6IHVpbnQ2NAoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc3CgkvLyB0aGlzLmVuZFJvdW5kLnZhbHVlID0gZW5kCglieXRlIDB4NjU2ZTY0NTI2Zjc1NmU2NCAvLyAiZW5kUm91bmQiCglmcmFtZV9kaWcgLTEgLy8gZW5kOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc4CgkvLyB0aGlzLmRyYXdSb3VuZC52YWx1ZSA9IGRyYXcKCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWZyYW1lX2RpZyAtMiAvLyBkcmF3OiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CglyZXRzdWIKCi8vIGJ1eVRpY2tldHModWludDY0LHBheSl2b2lkCi8vCi8vIEJ1eSB0aWNrZXRzLiBOb3RlIHRoaXMgY2FuIG9ubHkgYmUgY2FsbGVkIG9uY2UhCi8vIEl0IHdvdWxkIGJlIHBvc3NpYmxlIHRvIGFsbG93IG11bHRpcGxlIHB1cmNoYXNlcywgYnV0Ci8vIGZvciBzaW1wbGljaXR5LCBvbmx5IG9uZSBwdXJjaGFzZSBpcyBhbGxvd2VkLgovLwovLyBAcGFyYW0gcGF5bWVudCBUaGUgcGF5bWVudCBmb3IgdGhlIHRpY2tldHMKLy8gQHBhcmFtIHF1YW5pdHkgVGhlIG51bWJlciBvZiB0aWNrZXRzIHRvIGJ1eQovLwovLyBAcmV0dXJucyBUaGUgdG90YWwgbnVtYmVyIG9mIHRpY2tldHMgb3duZWQgYnkgdGhlIHNlbmRlcgphYmlfcm91dGVfYnV5VGlja2V0czoKCWJ5dGUgMHggLy8gcHVzaCBlbXB0eSBieXRlcyB0byBmaWxsIHRoZSBzdGFjayBmcmFtZSBmb3IgdGhpcyBzdWJyb3V0aW5lJ3MgbG9jYWwgdmFyaWFibGVzCgoJLy8gcXVhbml0eTogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gcGF5bWVudDogcGF5Cgl0eG4gR3JvdXBJbmRleAoJaW50IDEKCS0KCWR1cAoJZ3R4bnMgVHlwZUVudW0KCWludCBwYXkKCT09Cglhc3NlcnQKCgkvLyBleGVjdXRlIGJ1eVRpY2tldHModWludDY0LHBheSl2b2lkCgljYWxsc3ViIGJ1eVRpY2tldHMKCWludCAxCglyZXR1cm4KCmJ1eVRpY2tldHM6Cglwcm90byAzIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTIKCS8vIGFzc2VydChnbG9iYWxzLnJvdW5kIDwgdGhpcy5lbmRSb3VuZC52YWx1ZSkKCWdsb2JhbCBSb3VuZAoJYnl0ZSAweDY1NmU2NDUyNmY3NTZlNjQgLy8gImVuZFJvdW5kIgoJYXBwX2dsb2JhbF9nZXQKCTwKCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5MwoJLy8gYXNzZXJ0KHF1YW5pdHkgPiAwKQoJZnJhbWVfZGlnIC0yIC8vIHF1YW5pdHk6IHVpbnQ2NAoJaW50IDAKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5NQoJLy8gYXNzZXJ0KHBheW1lbnQuYW1vdW50ID09PSB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogcXVhbml0eSkKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIEFtb3VudAoJYnl0ZSAweDc0Njk2MzZiNjU3NDUwNzI2OTYzNjUgLy8gInRpY2tldFByaWNlIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtMiAvLyBxdWFuaXR5OiB1aW50NjQKCSoKCT09Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTYKCS8vIGFzc2VydChwYXltZW50LnNlbmRlciA9PT0gdGhpcy50eG4uc2VuZGVyKQoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCgl0eG4gU2VuZGVyCgk9PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjk3CgkvLyBhc3NlcnQocGF5bWVudC5yZWNlaXZlciA9PT0gdGhpcy5hcHAuYWRkcmVzcykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFJlY2VpdmVyCglnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5OQoJLy8gYXNzZXJ0KCF0aGlzLnRpY2tldHMocGF5bWVudC5zZW5kZXIpLmV4aXN0cykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJYm94X2xlbgoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAxCgkvLyBuZXdUb3RhbCA9IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlICsgcXVhbml0eSArIDEKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9kaWcgLTIgLy8gcXVhbml0eTogdWludDY0CgkrCglpbnQgMQoJKwoJZnJhbWVfYnVyeSAtMyAvLyBuZXdUb3RhbDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwMwoJLy8gdGhpcy50aWNrZXRzKHBheW1lbnQuc2VuZGVyKS52YWx1ZSA9IHsgc3RhcnQ6IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlLCBlbmQ6IG5ld1RvdGFsIC0gMSB9CglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBTZW5kZXIKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWFwcF9nbG9iYWxfZ2V0CglpdG9iCglmcmFtZV9kaWcgLTMgLy8gbmV3VG90YWw6IHVpbnQ2NAoJaW50IDEKCS0KCWl0b2IKCWNvbmNhdAoJYm94X3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDQKCS8vIHRoaXMudG90YWxUaWNrZXRzLnZhbHVlID0gbmV3VG90YWwKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWZyYW1lX2RpZyAtMyAvLyBuZXdUb3RhbDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgpnZXRSYW5kb21CeXRlczoKCXByb3RvIDAgMAoKCS8vIGlmMF9jb25kaXRpb24KCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDkKCS8vIHRoaXMucmFuZG9tQnl0ZXMuZXhpc3RzCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCglieiBpZjBfZWxzZQoKCS8vIGlmMF9jb25zZXF1ZW50CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTEwCgkvLyB0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlID0gc2hhMjU2KHRoaXMucmFuZG9tQnl0ZXMudmFsdWUpIGFzIGJ5dGVzCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglhcHBfZ2xvYmFsX2dldAoJc2hhMjU2CglhcHBfZ2xvYmFsX3B1dAoJYiBpZjBfZW5kCgppZjBfZWxzZToKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMTIKCS8vIHRoaXMucmFuZG9tQnl0ZXMudmFsdWUgPSBzZW5kTWV0aG9kQ2FsbDxbdWludDY0LCBieXRlc10sIGJ5dGVzPih7CgkvLyAgICAgICAgIG5hbWU6ICdtdXN0X2dldCcsCgkvLyAgICAgICAgIG1ldGhvZEFyZ3M6IFt0aGlzLmRyYXdSb3VuZC52YWx1ZSwgJyddLAoJLy8gICAgICAgICBhcHBsaWNhdGlvbklEOiBBcHBsaWNhdGlvbi5mcm9tSUQodGhpcy5yYW5kb21uZXNzT3JhY2xlLnZhbHVlKSwKCS8vICAgICAgICAgZmVlOiAwLAoJLy8gICAgICAgICBvbkNvbXBsZXRpb246ICdOb09wJywKCS8vICAgICAgIH0pCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglpdHhuX2JlZ2luCglpbnQgYXBwbAoJaXR4bl9maWVsZCBUeXBlRW51bQoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCWl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExNAoJLy8gbWV0aG9kQXJnczogW3RoaXMuZHJhd1JvdW5kLnZhbHVlLCAnJ10KCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpdG9iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoJYnl0ZSAweDAwMDAKCWl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExNQoJLy8gYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSkKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWFwcF9nbG9iYWxfZ2V0CglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uSUQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTE2CgkvLyBmZWU6IDAKCWludCAwCglpdHhuX2ZpZWxkIEZlZQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMTcKCS8vIG9uQ29tcGxldGlvbjogJ05vT3AnCglpbnQgTm9PcAoJaXR4bl9maWVsZCBPbkNvbXBsZXRpb24KCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglpdHhuIE51bUxvZ3MKCWludCAxCgktCglpdHhuYXMgTG9ncwoJZXh0cmFjdCA0IDAKCWFwcF9nbG9iYWxfcHV0CgppZjBfZW5kOgoJcmV0c3ViCgovLyBkcmF3KClib29sCi8vCi8vIERyYXcgdGhlIHdpbm5pbmcgdGlja2V0CmFiaV9yb3V0ZV9kcmF3OgoJYnl0ZSAweDsgZHVwbiAzIC8vIHB1c2ggZW1wdHkgYnl0ZXMgdG8gZmlsbCB0aGUgc3RhY2sgZnJhbWUgZm9yIHRoaXMgc3Vicm91dGluZSdzIGxvY2FsIHZhcmlhYmxlcwoKCS8vIGV4ZWN1dGUgZHJhdygpYm9vbAoJY2FsbHN1YiBkcmF3CglpbnQgMQoJcmV0dXJuCgpkcmF3OgoJcHJvdG8gNCAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNAoJLy8gYXNzZXJ0KCF0aGlzLndpbm5pbmdUaWNrZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNQoJLy8gdGhpcy5nZXRSYW5kb21CeXRlcygpCgljYWxsc3ViIGdldFJhbmRvbUJ5dGVzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyOQoJLy8gbiA9IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfYnVyeSAtMSAvLyBuOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTMxCgkvLyBvZmZzZXQgPSAwCglpbnQgMAoJZnJhbWVfYnVyeSAtMyAvLyBvZmZzZXQ6IHVpbnQ2NAoKZG9fd2hpbGVfMDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzUKCS8vIHggPSBleHRyYWN0X3VpbnQ2NCh0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlLCBvZmZzZXQpCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0zIC8vIG9mZnNldDogdWludDY0CglleHRyYWN0X3VpbnQ2NAoJZnJhbWVfYnVyeSAtMiAvLyB4OiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTM3CgkvLyBvZmZzZXQgPSBvZmZzZXQgKyA4CglmcmFtZV9kaWcgLTMgLy8gb2Zmc2V0OiB1aW50NjQKCWludCA4CgkrCglmcmFtZV9idXJ5IC0zIC8vIG9mZnNldDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEzOQoJLy8gbWF4Q29uZGl0aW9uID0geCA+IFJBTkRfTUFYIC0gKCgoUkFORF9NQVggJSBuKSArIDEpICUgbikKCWZyYW1lX2RpZyAtMiAvLyB4OiB1aW50NjQKCWludCAxOF80NDZfNzQ0XzA3M183MDlfNTUxXzYxNQoJaW50IDE4XzQ0Nl83NDRfMDczXzcwOV81NTFfNjE1CglmcmFtZV9kaWcgLTEgLy8gbjogdWludDY0CgklCglpbnQgMQoJKwoJZnJhbWVfZGlnIC0xIC8vIG46IHVpbnQ2NAoJJQoJLQoJPgoJZnJhbWVfYnVyeSAtNCAvLyBtYXhDb25kaXRpb246IGJvb2wKCWZyYW1lX2RpZyAtNCAvLyBtYXhDb25kaXRpb246IGJvb2wKCWR1cAoJYnogc2tpcF9hbmQwCglmcmFtZV9kaWcgLTMgLy8gb2Zmc2V0OiB1aW50NjQKCWludCAzMgoJPAoJJiYKCnNraXBfYW5kMDoKCWJueiBkb193aGlsZV8wCgoJLy8gaWYxX2NvbmRpdGlvbgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0MgoJLy8gbWF4Q29uZGl0aW9uCglmcmFtZV9kaWcgLTQgLy8gbWF4Q29uZGl0aW9uOiBib29sCglieiBpZjFfZW5kCgoJLy8gaWYxX2NvbnNlcXVlbnQKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNDIKCS8vIHJldHVybiBmYWxzZTsKCWludCAwCglieXRlIDB4MDAKCWludCAwCgl1bmNvdmVyIDIKCXNldGJpdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgppZjFfZW5kOgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0NAoJLy8gdGhpcy53aW5uaW5nVGlja2V0LnZhbHVlID0geCAlIG4KCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWZyYW1lX2RpZyAtMiAvLyB4OiB1aW50NjQKCWZyYW1lX2RpZyAtMSAvLyBuOiB1aW50NjQKCSUKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0NQoJLy8gcmV0dXJuIHRydWU7CglpbnQgMQoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKLy8gY2xhaW0oKXZvaWQKLy8KLy8gU2VuZCB0aGUgYXNzZXQgdG8gdGhlIHRoZSBzZW5kZXIgaWYgdGhleSBoYXZlIHRoZSB3aW5uaW5nIHRpY2tldAphYmlfcm91dGVfY2xhaW06CglieXRlIDB4IC8vIHB1c2ggZW1wdHkgYnl0ZXMgdG8gZmlsbCB0aGUgc3RhY2sgZnJhbWUgZm9yIHRoaXMgc3Vicm91dGluZSdzIGxvY2FsIHZhcmlhYmxlcwoKCS8vIGV4ZWN1dGUgY2xhaW0oKXZvaWQKCWNhbGxzdWIgY2xhaW0KCWludCAxCglyZXR1cm4KCmNsYWltOgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE1MAoJLy8gdGlja2V0UmFuZ2UgPSB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS52YWx1ZQoJdHhuIFNlbmRlcgoJZnJhbWVfYnVyeSAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUyCgkvLyBhc3NlcnQodGlja2V0UmFuZ2Uuc3RhcnQgPD0gdGhpcy53aW5uaW5nVGlja2V0LnZhbHVlKQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDAgOAoJYnRvaQoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXQKCTw9Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyBhc3NlcnQodGlja2V0UmFuZ2UuZW5kID49IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCWJveF9nZXQKCWFzc2VydAoJZXh0cmFjdCA4IDgKCWJ0b2kKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0Cgk+PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE1NQoJLy8gc2VuZEFzc2V0VHJhbnNmZXIoewoJLy8gICAgICAgYXNzZXRSZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgeGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlLAoJLy8gICAgICAgYXNzZXRBbW91bnQ6IHRoaXMuYXBwLmFkZHJlc3MuYXNzZXRCYWxhbmNlKHRoaXMuYXNzZXQudmFsdWUpLAoJLy8gICAgICAgYXNzZXRDbG9zZVRvOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICBmZWU6IDAsCgkvLyAgICAgfSkKCWl0eG5fYmVnaW4KCWludCBheGZlcgoJaXR4bl9maWVsZCBUeXBlRW51bQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTYKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlcgoJdHhuIFNlbmRlcgoJaXR4bl9maWVsZCBBc3NldFJlY2VpdmVyCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE1NwoJLy8geGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlCglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJaXR4bl9maWVsZCBYZmVyQXNzZXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTU4CgkvLyBhc3NldEFtb3VudDogdGhpcy5hcHAuYWRkcmVzcy5hc3NldEJhbGFuY2UodGhpcy5hc3NldC52YWx1ZSkKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJYXNzZXRfaG9sZGluZ19nZXQgQXNzZXRCYWxhbmNlCglhc3NlcnQKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTU5CgkvLyBhc3NldENsb3NlVG86IHRoaXMudHhuLnNlbmRlcgoJdHhuIFNlbmRlcgoJaXR4bl9maWVsZCBBc3NldENsb3NlVG8KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTYwCgkvLyBmZWU6IDAKCWludCAwCglpdHhuX2ZpZWxkIEZlZQoKCS8vIFN1Ym1pdCBpbm5lciB0cmFuc2FjdGlvbgoJaXR4bl9zdWJtaXQKCXJldHN1YgoKLy8gZ2V0UmVmdW5kKCl2b2lkCi8vCi8vIEFsbG93cyBwdXJjaGFzZXJzIHRvIGdldCBhIHJlZnVuZCBpZiB0aGUgd2lubmluZyB0aWNrZXQgaGFzIG5vdCBiZWVuIGRyYXduCi8vIGFuZCAxNTEyIHJvdW5kcyBoYXZlIHBhc3NlZCBzaW5jZSB0aGUgZHJhdyByb3VuZCwgbWVhbmluZyB0aGUgb3JhY2xlIG5vCi8vIGxvbmdlciBoYXMgdGhlIGRhdGEgZm9yIHRoZSBkcmF3IHJvdW5kCmFiaV9yb3V0ZV9nZXRSZWZ1bmQ6CglieXRlIDB4OyBkdXAgLy8gcHVzaCBlbXB0eSBieXRlcyB0byBmaWxsIHRoZSBzdGFjayBmcmFtZSBmb3IgdGhpcyBzdWJyb3V0aW5lJ3MgbG9jYWwgdmFyaWFibGVzCgoJLy8gZXhlY3V0ZSBnZXRSZWZ1bmQoKXZvaWQKCWNhbGxzdWIgZ2V0UmVmdW5kCglpbnQgMQoJcmV0dXJuCgpnZXRSZWZ1bmQ6Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTcwCgkvLyBhc3NlcnQoIXRoaXMud2lubmluZ1RpY2tldC5leGlzdHMpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTcxCgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA+IHRoaXMuZHJhd1JvdW5kLnZhbHVlICsgMTUxMikKCWdsb2JhbCBSb3VuZAoJYnl0ZSAweDY0NzI2MTc3NTI2Zjc1NmU2NCAvLyAiZHJhd1JvdW5kIgoJYXBwX2dsb2JhbF9nZXQKCWludCAxNTEyCgkrCgk+Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTczCgkvLyB0aWNrZXRSYW5nZSA9IHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLnZhbHVlCgl0eG4gU2VuZGVyCglmcmFtZV9idXJ5IC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNzQKCS8vIHRpY2tldENvdW50ID0gdGlja2V0UmFuZ2UuZW5kIC0gdGlja2V0UmFuZ2Uuc3RhcnQgKyAxCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgOCA4CglidG9pCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgMCA4CglidG9pCgktCglpbnQgMQoJKwoJZnJhbWVfYnVyeSAtMiAvLyB0aWNrZXRDb3VudDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3NgoJLy8gdGhpcy50aWNrZXRzKHRoaXMudHhuLnNlbmRlcikuZGVsZXRlKCkKCXR4biBTZW5kZXIKCWJveF9kZWwKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTc4CgkvLyBzZW5kUGF5bWVudCh7CgkvLyAgICAgICBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiB0aWNrZXRDb3VudCwKCS8vICAgICAgIHJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICBmZWU6IDAsCgkvLyAgICAgfSkKCWl0eG5fYmVnaW4KCWludCBwYXkKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTc5CgkvLyBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiB0aWNrZXRDb3VudAoJYnl0ZSAweDc0Njk2MzZiNjU3NDUwNzI2OTYzNjUgLy8gInRpY2tldFByaWNlIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtMiAvLyB0aWNrZXRDb3VudDogdWludDY0CgkqCglpdHhuX2ZpZWxkIEFtb3VudAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxODAKCS8vIHJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgUmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTgxCgkvLyBmZWU6IDAKCWludCAwCglpdHhuX2ZpZWxkIEZlZQoKCS8vIFN1Ym1pdCBpbm5lciB0cmFuc2FjdGlvbgoJaXR4bl9zdWJtaXQKCXJldHN1YgoKY3JlYXRlX05vT3A6CgltZXRob2QgImNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZCIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbgoJZXJyCgpjYWxsX05vT3A6CgltZXRob2QgInNldEFzc2V0KGFzc2V0KXZvaWQiCgltZXRob2QgInN0YXJ0UmFmZmxlKHVpbnQ2NCx1aW50NjQpdm9pZCIKCW1ldGhvZCAiYnV5VGlja2V0cyhwYXksdWludDY0KXZvaWQiCgltZXRob2QgImRyYXcoKWJvb2wiCgltZXRob2QgImNsYWltKCl2b2lkIgoJbWV0aG9kICJnZXRSZWZ1bmQoKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc2V0QXNzZXQgYWJpX3JvdXRlX3N0YXJ0UmFmZmxlIGFiaV9yb3V0ZV9idXlUaWNrZXRzIGFiaV9yb3V0ZV9kcmF3IGFiaV9yb3V0ZV9jbGFpbSBhYmlfcm91dGVfZ2V0UmVmdW5kCgllcnI=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAovLwovLyBDcmVhdGUgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gdGlja2V0UHJpY2UgVGhlIHByaWNlIG9mIGEgc2luZ2xlIHRpY2tldCAodUFMR08pCi8vIEBwYXJhbSByYW5kb21uZXNzT3JhY2xlIFRoZSBhcHAgSUQgb2YgdGhlIHJhbmRvbW5lc3Mgb3JhY2xlCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIHJhbmRvbW5lc3NPcmFjbGU6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIHRpY2tldFByaWNlOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBjcmVhdGVBcHBsaWNhdGlvbgoJaW50IDEKCXJldHVybgoKY3JlYXRlQXBwbGljYXRpb246Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NDMKCS8vIHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSA9IHJhbmRvbW5lc3NPcmFjbGUKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQ0CgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWZyYW1lX2RpZyAtMSAvLyB0aWNrZXRQcmljZTogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzZXRBc3NldChhc3NldCl2b2lkCi8vCi8vIFNldCB0aGUgYXNzZXQgdG8gYmUgcmFmZmxlZAovLwovLyBAcGFyYW0gYXNzZXQgVGhlIGFzc2V0IHRvIGJlIHJhZmZsZWQKYWJpX3JvdXRlX3NldEFzc2V0OgoJLy8gYXNzZXQ6IGFzc2V0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCgkvLyBleGVjdXRlIHNldEFzc2V0KGFzc2V0KXZvaWQKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU0CgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiBhc3NldCwKCS8vICAgICAgIGFzc2V0QW1vdW50OiAwLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTcKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMuYXBwLmFkZHJlc3MKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTgKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU5CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NjAKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo2MwoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglmcmFtZV9kaWcgLTEgLy8gYXNzZXQ6IGFzc2V0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKLy8KLy8gU3RhcnQgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gZW5kIFRoZSByb3VuZCBudW1iZXIgd2hlbiB0aGUgcmFmZmxlIGVuZHMKLy8gQHBhcmFtIGRyYXcgVGhlIHJvdW5kIG51bWJlciB3aGVuIHRoZSByYWZmbGUgaXMgZHJhd24KYWJpX3JvdXRlX3N0YXJ0UmFmZmxlOgoJLy8gZHJhdzogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgoJLy8gZW5kOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBheGZlcjogYXhmZXIKCXR4biBHcm91cEluZGV4CglpbnQgMQoJLQoJZHVwCglndHhucyBUeXBlRW51bQoJaW50IGF4ZmVyCgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKCWNhbGxzdWIgc3RhcnRSYWZmbGUKCWludCAxCglyZXR1cm4KCnN0YXJ0UmFmZmxlOgoJcHJvdG8gMyAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc0CgkvLyB2ZXJpZnlUeG4oYXhmZXIsIHsKCS8vICAgICAgIGFzc2V0QW1vdW50OiB7IGdyZWF0ZXJUaGFuOiAwIH0sCgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlLAoJLy8gICAgIH0pCgkvLyB2ZXJpZnkgYXNzZXRBbW91bnQKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0QW1vdW50CglpbnQgMAoJPgoJYXNzZXJ0CgoJLy8gdmVyaWZ5IGFzc2V0UmVjZWl2ZXIKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0UmVjZWl2ZXIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHhmZXJBc3NldAoJZnJhbWVfZGlnIC0xIC8vIGF4ZmVyOiBheGZlcgoJZ3R4bnMgWGZlckFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MAoJLy8gYXNzZXJ0KGRyYXcgPiBlbmQpCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gZW5kOiB1aW50NjQKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MQoJLy8gdGhpcy5lbmRSb3VuZC52YWx1ZSA9IGVuZAoJYnl0ZSAweDY1NmU2NDUyNmY3NTZlNjQgLy8gImVuZFJvdW5kIgoJZnJhbWVfZGlnIC0yIC8vIGVuZDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MgoJLy8gdGhpcy5kcmF3Um91bmQudmFsdWUgPSBkcmF3CglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAovLwovLyBCdXkgdGlja2V0cy4gTm90ZSB0aGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlIQovLyBJdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBhbGxvdyBtdWx0aXBsZSBwdXJjaGFzZXMsIGJ1dAovLyBmb3Igc2ltcGxpY2l0eSwgb25seSBvbmUgcHVyY2hhc2UgaXMgYWxsb3dlZC4KLy8KLy8gQHBhcmFtIHBheW1lbnQgVGhlIHBheW1lbnQgZm9yIHRoZSB0aWNrZXRzCi8vIEBwYXJhbSBxdWFuaXR5IFRoZSBudW1iZXIgb2YgdGlja2V0cyB0byBidXkKLy8KLy8gQHJldHVybnMgVGhlIHRvdGFsIG51bWJlciBvZiB0aWNrZXRzIG93bmVkIGJ5IHRoZSBzZW5kZXIKYWJpX3JvdXRlX2J1eVRpY2tldHM6CglieXRlIDB4OyBkdXBuIDIgLy8gcHVzaCBlbXB0eSBieXRlcyB0byBmaWxsIHRoZSBzdGFjayBmcmFtZSBmb3IgdGhpcyBzdWJyb3V0aW5lJ3MgbG9jYWwgdmFyaWFibGVzCgoJLy8gcXVhbnRpdHk6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoKCS8vIHBheW1lbnQ6IHBheQoJdHhuIEdyb3VwSW5kZXgKCWludCAxCgktCglkdXAKCWd0eG5zIFR5cGVFbnVtCglpbnQgcGF5Cgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAoJY2FsbHN1YiBidXlUaWNrZXRzCglpbnQgMQoJcmV0dXJuCgpidXlUaWNrZXRzOgoJcHJvdG8gNSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjk2CgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA8IHRoaXMuZW5kUm91bmQudmFsdWUpCglnbG9iYWwgUm91bmQKCWJ5dGUgMHg2NTZlNjQ1MjZmNzU2ZTY0IC8vICJlbmRSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0Cgk8Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTcKCS8vIGFzc2VydChxdWFudGl0eSA+IDApCglmcmFtZV9kaWcgLTIgLy8gcXVhbnRpdHk6IHVpbnQ2NAoJaW50IDAKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5OQoJLy8gYXNzZXJ0KCF0aGlzLnRpY2tldHMocGF5bWVudC5zZW5kZXIpLmV4aXN0cykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJYm94X2xlbgoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAxCgkvLyBuZXdUb3RhbCA9IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlICsgcXVhbnRpdHkgKyAxCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCSsKCWludCAxCgkrCglmcmFtZV9idXJ5IC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAzCgkvLyBwcmVNQlIgPSB0aGlzLmFwcC5hZGRyZXNzLm1pbkJhbGFuY2UKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKCWFzc2VydAoJZnJhbWVfYnVyeSAtNCAvLyBwcmVNQlI6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDQKCS8vIHRoaXMudGlja2V0cyhwYXltZW50LnNlbmRlcikudmFsdWUgPSB7IHN0YXJ0OiB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSwgZW5kOiBuZXdUb3RhbCAtIDEgfQoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJZnJhbWVfZGlnIC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCWludCAxCgktCglpdG9iCgljb25jYXQKCWJveF9wdXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTA1CgkvLyBtYnJEZWx0YSA9IHRoaXMuYXBwLmFkZHJlc3MubWluQmFsYW5jZSAtIHByZU1CUgoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCWFjY3RfcGFyYW1zX2dldCBBY2N0TWluQmFsYW5jZQoJYXNzZXJ0CglmcmFtZV9kaWcgLTQgLy8gcHJlTUJSOiB1aW50NjQKCS0KCWZyYW1lX2J1cnkgLTUgLy8gbWJyRGVsdGE6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDcKCS8vIHZlcmlmeVR4bihwYXltZW50LCB7CgkvLyAgICAgICBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiBxdWFudGl0eSArIG1ickRlbHRhLAoJLy8gICAgICAgc2VuZGVyOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICByZWNlaXZlcjogdGhpcy5hcHAuYWRkcmVzcywKCS8vICAgICB9KQoJLy8gdmVyaWZ5IGFtb3VudAoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgQW1vdW50CglieXRlIDB4NzQ2OTYzNmI2NTc0NTA3MjY5NjM2NSAvLyAidGlja2V0UHJpY2UiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCSoKCWZyYW1lX2RpZyAtNSAvLyBtYnJEZWx0YTogdWludDY0CgkrCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHNlbmRlcgoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCgl0eG4gU2VuZGVyCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHJlY2VpdmVyCglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBSZWNlaXZlcgoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCT09Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTEzCgkvLyB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSA9IG5ld1RvdGFsCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglmcmFtZV9kaWcgLTMgLy8gbmV3VG90YWw6IHVpbnQ2NAoJYXBwX2dsb2JhbF9wdXQKCXJldHN1YgoKZ2V0UmFuZG9tQnl0ZXM6Cglwcm90byAwIDAKCgkvLyBpZjBfY29uZGl0aW9uCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTE4CgkvLyB0aGlzLnJhbmRvbUJ5dGVzLmV4aXN0cwoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJYnogaWYwX2Vsc2UKCgkvLyBpZjBfY29uc2VxdWVudAoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExOQoJLy8gdGhpcy5yYW5kb21CeXRlcy52YWx1ZSA9IHNoYTI1Nih0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlKSBhcyBieXRlcwoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCXNoYTI1NgoJYXBwX2dsb2JhbF9wdXQKCWIgaWYwX2VuZAoKaWYwX2Vsc2U6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTIxCgkvLyB0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlID0gc2VuZE1ldGhvZENhbGw8W3VpbnQ2NCwgYnl0ZXNdLCBieXRlcz4oewoJLy8gICAgICAgICBuYW1lOiAnbXVzdF9nZXQnLAoJLy8gICAgICAgICBtZXRob2RBcmdzOiBbdGhpcy5kcmF3Um91bmQudmFsdWUsICcnXSwKCS8vICAgICAgICAgYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSksCgkvLyAgICAgICAgIGZlZTogMCwKCS8vICAgICAgICAgb25Db21wbGV0aW9uOiAnTm9PcCcsCgkvLyAgICAgICB9KQoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJaXR4bl9iZWdpbgoJaW50IGFwcGwKCWl0eG5fZmllbGQgVHlwZUVudW0KCW1ldGhvZCAibXVzdF9nZXQodWludDY0LGJ5dGVbXSlieXRlW10iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjMKCS8vIG1ldGhvZEFyZ3M6IFt0aGlzLmRyYXdSb3VuZC52YWx1ZSwgJyddCglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKCWJ5dGUgMHgwMDAwCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjQKCS8vIGFwcGxpY2F0aW9uSUQ6IEFwcGxpY2F0aW9uLmZyb21JRCh0aGlzLnJhbmRvbW5lc3NPcmFjbGUudmFsdWUpCglieXRlIDB4NzI2MTZlNjQ2ZjZkNmU2NTczNzM0ZjcyNjE2MzZjNjUgLy8gInJhbmRvbW5lc3NPcmFjbGUiCglhcHBfZ2xvYmFsX2dldAoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbklECgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNQoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTI2CgkvLyBvbkNvbXBsZXRpb246ICdOb09wJwoJaW50IE5vT3AKCWl0eG5fZmllbGQgT25Db21wbGV0aW9uCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoJaXR4biBOdW1Mb2dzCglpbnQgMQoJLQoJaXR4bmFzIExvZ3MKCWV4dHJhY3QgNCAwCglhcHBfZ2xvYmFsX3B1dAoKaWYwX2VuZDoKCXJldHN1YgoKLy8gZHJhdyhhcHBsaWNhdGlvbilib29sCi8vCi8vIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFycwphYmlfcm91dGVfZHJhdzoKCWJ5dGUgMHg7IGR1cG4gMyAvLyBwdXNoIGVtcHR5IGJ5dGVzIHRvIGZpbGwgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIHN1YnJvdXRpbmUncyBsb2NhbCB2YXJpYWJsZXMKCgkvLyBfb3JhY2xlUmVmZXJlbmNlOiBhcHBsaWNhdGlvbgoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoJdHhuYXMgQXBwbGljYXRpb25zCgoJLy8gZXhlY3V0ZSBkcmF3KGFwcGxpY2F0aW9uKWJvb2wKCWNhbGxzdWIgZHJhdwoJaW50IDEKCXJldHVybgoKZHJhdzoKCXByb3RvIDUgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzUKCS8vIGFzc2VydCghdGhpcy53aW5uaW5nVGlja2V0LmV4aXN0cykKCXR4bmEgQXBwbGljYXRpb25zIDAKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0X2V4Cglzd2FwCglwb3AKCSEKCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzYKCS8vIHRoaXMuZ2V0UmFuZG9tQnl0ZXMoKQoJY2FsbHN1YiBnZXRSYW5kb21CeXRlcwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNDAKCS8vIG4gPSB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZQoJYnl0ZSAweDc0NmY3NDYxNmM1NDY5NjM2YjY1NzQ3MyAvLyAidG90YWxUaWNrZXRzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2J1cnkgLTIgLy8gbjogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0MgoJLy8gb2Zmc2V0ID0gMAoJaW50IDAKCWZyYW1lX2J1cnkgLTQgLy8gb2Zmc2V0OiB1aW50NjQKCmRvX3doaWxlXzA6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTQ2CgkvLyB4ID0gZXh0cmFjdF91aW50NjQodGhpcy5yYW5kb21CeXRlcy52YWx1ZSwgb2Zmc2V0KQoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtNCAvLyBvZmZzZXQ6IHVpbnQ2NAoJZXh0cmFjdF91aW50NjQKCWZyYW1lX2J1cnkgLTMgLy8geDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0OAoJLy8gb2Zmc2V0ID0gb2Zmc2V0ICsgOAoJZnJhbWVfZGlnIC00IC8vIG9mZnNldDogdWludDY0CglpbnQgOAoJKwoJZnJhbWVfYnVyeSAtNCAvLyBvZmZzZXQ6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTAKCS8vIG1heENvbmRpdGlvbiA9IHggPiBSQU5EX01BWCAtICgoKFJBTkRfTUFYICUgbikgKyAxKSAlIG4pCglmcmFtZV9kaWcgLTMgLy8geDogdWludDY0CglpbnQgMThfNDQ2Xzc0NF8wNzNfNzA5XzU1MV82MTUKCWludCAxOF80NDZfNzQ0XzA3M183MDlfNTUxXzYxNQoJZnJhbWVfZGlnIC0yIC8vIG46IHVpbnQ2NAoJJQoJaW50IDEKCSsKCWZyYW1lX2RpZyAtMiAvLyBuOiB1aW50NjQKCSUKCS0KCT4KCWZyYW1lX2J1cnkgLTUgLy8gbWF4Q29uZGl0aW9uOiBib29sCglmcmFtZV9kaWcgLTUgLy8gbWF4Q29uZGl0aW9uOiBib29sCglkdXAKCWJ6IHNraXBfYW5kMAoJZnJhbWVfZGlnIC00IC8vIG9mZnNldDogdWludDY0CglpbnQgMzIKCTwKCSYmCgpza2lwX2FuZDA6CglibnogZG9fd2hpbGVfMAoKCS8vIGlmMV9jb25kaXRpb24KCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTMKCS8vIG1heENvbmRpdGlvbgoJZnJhbWVfZGlnIC01IC8vIG1heENvbmRpdGlvbjogYm9vbAoJYnogaWYxX2VuZAoKCS8vIGlmMV9jb25zZXF1ZW50CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyByZXR1cm4gZmFsc2U7CglpbnQgMAoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKaWYxX2VuZDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTUKCS8vIHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSA9IHggJSBuCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglmcmFtZV9kaWcgLTMgLy8geDogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gbjogdWludDY0CgklCglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTYKCS8vIHJldHVybiB0cnVlOwoJaW50IDEKCWJ5dGUgMHgwMAoJaW50IDAKCXVuY292ZXIgMgoJc2V0Yml0CglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCi8vIGNsYWltKCl2b2lkCi8vCi8vIFNlbmQgdGhlIGFzc2V0IHRvIHRoZSB0aGUgc2VuZGVyIGlmIHRoZXkgaGF2ZSB0aGUgd2lubmluZyB0aWNrZXQKYWJpX3JvdXRlX2NsYWltOgoJYnl0ZSAweCAvLyBwdXNoIGVtcHR5IGJ5dGVzIHRvIGZpbGwgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIHN1YnJvdXRpbmUncyBsb2NhbCB2YXJpYWJsZXMKCgkvLyBleGVjdXRlIGNsYWltKCl2b2lkCgljYWxsc3ViIGNsYWltCglpbnQgMQoJcmV0dXJuCgpjbGFpbToKCXByb3RvIDEgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjEKCS8vIHRpY2tldFJhbmdlID0gdGhpcy50aWNrZXRzKHRoaXMudHhuLnNlbmRlcikudmFsdWUKCXR4biBTZW5kZXIKCWZyYW1lX2J1cnkgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2MwoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLnN0YXJ0IDw9IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCWJveF9nZXQKCWFzc2VydAoJZXh0cmFjdCAwIDgKCWJ0b2kKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0Cgk8PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2NAoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLmVuZCA+PSB0aGlzLndpbm5pbmdUaWNrZXQudmFsdWUpCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgOCA4CglidG9pCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldAoJPj0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjYKCS8vIHNlbmRBc3NldFRyYW5zZmVyKHsKCS8vICAgICAgIGFzc2V0UmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIHhmZXJBc3NldDogdGhpcy5hc3NldC52YWx1ZSwKCS8vICAgICAgIGFzc2V0QW1vdW50OiB0aGlzLmFwcC5hZGRyZXNzLmFzc2V0QmFsYW5jZSh0aGlzLmFzc2V0LnZhbHVlKSwKCS8vICAgICAgIGFzc2V0Q2xvc2VUbzogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY3CgkvLyBhc3NldFJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRSZWNlaXZlcgoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjgKCS8vIHhmZXJBc3NldDogdGhpcy5hc3NldC52YWx1ZQoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2OQoJLy8gYXNzZXRBbW91bnQ6IHRoaXMuYXBwLmFkZHJlc3MuYXNzZXRCYWxhbmNlKHRoaXMuYXNzZXQudmFsdWUpCglnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQoJYXNzZXJ0CglpdHhuX2ZpZWxkIEFzc2V0QW1vdW50CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3MAoJLy8gYXNzZXRDbG9zZVRvOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRDbG9zZVRvCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3MQoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCi8vIGdldFJlZnVuZCgpdm9pZAovLwovLyBBbGxvd3MgcHVyY2hhc2VycyB0byBnZXQgYSByZWZ1bmQgaWYgdGhlIHdpbm5pbmcgdGlja2V0IGhhcyBub3QgYmVlbiBkcmF3bgovLyBhbmQgMTUxMiByb3VuZHMgaGF2ZSBwYXNzZWQgc2luY2UgdGhlIGRyYXcgcm91bmQsIG1lYW5pbmcgdGhlIG9yYWNsZSBubwovLyBsb25nZXIgaGFzIHRoZSBkYXRhIGZvciB0aGUgZHJhdyByb3VuZAphYmlfcm91dGVfZ2V0UmVmdW5kOgoJYnl0ZSAweDsgZHVwIC8vIHB1c2ggZW1wdHkgYnl0ZXMgdG8gZmlsbCB0aGUgc3RhY2sgZnJhbWUgZm9yIHRoaXMgc3Vicm91dGluZSdzIGxvY2FsIHZhcmlhYmxlcwoKCS8vIGV4ZWN1dGUgZ2V0UmVmdW5kKCl2b2lkCgljYWxsc3ViIGdldFJlZnVuZAoJaW50IDEKCXJldHVybgoKZ2V0UmVmdW5kOgoJcHJvdG8gMiAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4MQoJLy8gYXNzZXJ0KCF0aGlzLndpbm5pbmdUaWNrZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4MgoJLy8gYXNzZXJ0KGdsb2JhbHMucm91bmQgPiB0aGlzLmRyYXdSb3VuZC52YWx1ZSArIDE1MTIpCglnbG9iYWwgUm91bmQKCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpbnQgMTUxMgoJKwoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4NAoJLy8gdGlja2V0UmFuZ2UgPSB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS52YWx1ZQoJdHhuIFNlbmRlcgoJZnJhbWVfYnVyeSAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTg1CgkvLyB0aWNrZXRDb3VudCA9IHRpY2tldFJhbmdlLmVuZCAtIHRpY2tldFJhbmdlLnN0YXJ0ICsgMQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDggOAoJYnRvaQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDAgOAoJYnRvaQoJLQoJaW50IDEKCSsKCWZyYW1lX2J1cnkgLTIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxODcKCS8vIHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLmRlbGV0ZSgpCgl0eG4gU2VuZGVyCglib3hfZGVsCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4OQoJLy8gc2VuZFBheW1lbnQoewoJLy8gICAgICAgYW1vdW50OiB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogdGlja2V0Q291bnQsCgkvLyAgICAgICByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgcGF5CglpdHhuX2ZpZWxkIFR5cGVFbnVtCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MAoJLy8gYW1vdW50OiB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogdGlja2V0Q291bnQKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9kaWcgLTIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoJKgoJaXR4bl9maWVsZCBBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTkxCgkvLyByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIFJlY2VpdmVyCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MgoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCmNyZWF0ZV9Ob09wOgoJbWV0aG9kICJjcmVhdGVBcHBsaWNhdGlvbih1aW50NjQsdWludDY0KXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJzZXRBc3NldChhc3NldCl2b2lkIgoJbWV0aG9kICJzdGFydFJhZmZsZShheGZlcix1aW50NjQsdWludDY0KXZvaWQiCgltZXRob2QgImJ1eVRpY2tldHMocGF5LHVpbnQ2NCl2b2lkIgoJbWV0aG9kICJkcmF3KGFwcGxpY2F0aW9uKWJvb2wiCgltZXRob2QgImNsYWltKCl2b2lkIgoJbWV0aG9kICJnZXRSZWZ1bmQoKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc2V0QXNzZXQgYWJpX3JvdXRlX3N0YXJ0UmFmZmxlIGFiaV9yb3V0ZV9idXlUaWNrZXRzIGFiaV9yb3V0ZV9kcmF3IGFiaV9yb3V0ZV9jbGFpbSBhYmlfcm91dGVfZ2V0UmVmdW5kCgllcnI=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" }, "contract": { @@ -142,6 +142,11 @@ { "name": "startRaffle", "args": [ + { + "name": "axfer", + "type": "axfer", + "desc": "" + }, { "name": "end", "type": "uint64", @@ -168,21 +173,27 @@ "desc": "The payment for the tickets" }, { - "name": "quanity", + "name": "quantity", "type": "uint64", - "desc": "The number of tickets to buy" + "desc": "" } ], "desc": "Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed.", "returns": { "type": "void", - "desc": "The total number of tickets owned by the sender" + "desc": "" } }, { "name": "draw", - "args": [], - "desc": "Draw the winning ticket", + "args": [ + { + "name": "_oracleReference", + "type": "application", + "desc": "" + } + ], + "desc": "", "returns": { "type": "bool", "desc": "" diff --git a/examples/raffle/artifacts/NFTRaffle.arc4.json b/examples/raffle/artifacts/NFTRaffle.arc4.json index 06a4af2c1..773f52fad 100644 --- a/examples/raffle/artifacts/NFTRaffle.arc4.json +++ b/examples/raffle/artifacts/NFTRaffle.arc4.json @@ -40,6 +40,11 @@ { "name": "startRaffle", "args": [ + { + "name": "axfer", + "type": "axfer", + "desc": "" + }, { "name": "end", "type": "uint64", @@ -66,21 +71,27 @@ "desc": "The payment for the tickets" }, { - "name": "quanity", + "name": "quantity", "type": "uint64", - "desc": "The number of tickets to buy" + "desc": "" } ], "desc": "Buy tickets. Note this can only be called once!It would be possible to allow multiple purchases, butfor simplicity, only one purchase is allowed.", "returns": { "type": "void", - "desc": "The total number of tickets owned by the sender" + "desc": "" } }, { "name": "draw", - "args": [], - "desc": "Draw the winning ticket", + "args": [ + { + "name": "_oracleReference", + "type": "application", + "desc": "" + } + ], + "desc": "", "returns": { "type": "bool", "desc": "" diff --git a/examples/raffle/artifacts/NFTRaffle.src_map.json b/examples/raffle/artifacts/NFTRaffle.src_map.json index d235eaeb6..deaf752ed 100644 --- a/examples/raffle/artifacts/NFTRaffle.src_map.json +++ b/examples/raffle/artifacts/NFTRaffle.src_map.json @@ -586,147 +586,147 @@ "source": 73, "pc": [ 228, - 229, - 230 + 229 ] }, { "teal": 148, "source": 73, "pc": [ - 231 + 230 ] }, { "teal": 149, "source": 73, "pc": [ - 232 + 231 ] }, { - "teal": 152, + "teal": 150, "source": 73, "pc": [ - 233, - 234, - 235 + 232 ] }, { - "teal": 156, - "source": 74, + "teal": 151, + "source": 73, "pc": [ - 236, - 237 + 233, + 234 ] }, { - "teal": 157, - "source": 74, + "teal": 152, + "source": 73, "pc": [ - 238 + 235 ] }, { - "teal": 158, - "source": 74, + "teal": 153, + "source": 73, "pc": [ - 239 + 236 ] }, { - "teal": 159, - "source": 74, + "teal": 154, + "source": 73, "pc": [ - 240, - 241 + 237 ] }, { - "teal": 160, - "source": 74, + "teal": 157, + "source": 73, "pc": [ - 242 + 238, + 239, + 240 ] }, { - "teal": 161, - "source": 74, + "teal": 158, + "source": 73, "pc": [ - 243 + 241 ] }, { - "teal": 162, - "source": 74, + "teal": 159, + "source": 73, "pc": [ - 244 + 242 ] }, { - "teal": 163, - "source": 74, + "teal": 162, + "source": 73, "pc": [ + 243, + 244, 245 ] }, { - "teal": 167, - "source": 76, + "teal": 171, + "source": 74, "pc": [ 246, 247 ] }, { - "teal": 168, - "source": 76, + "teal": 172, + "source": 75, "pc": [ 248, 249 ] }, { - "teal": 169, - "source": 76, + "teal": 173, + "source": 75, "pc": [ 250 ] }, { - "teal": 170, - "source": 76, + "teal": 174, + "source": 75, "pc": [ 251 ] }, { - "teal": 174, - "source": 77, + "teal": 175, + "source": 75, "pc": [ - 252, - 253 + 252 ] }, { - "teal": 175, - "source": 77, + "teal": 178, + "source": 74, "pc": [ - 254, - 255 + 253, + 254 ] }, { - "teal": 176, - "source": 77, + "teal": 179, + "source": 76, "pc": [ + 255, 256 ] }, { "teal": 180, - "source": 78, + "source": 76, "pc": [ 257, 258 @@ -734,179 +734,173 @@ }, { "teal": 181, - "source": 78, + "source": 76, "pc": [ - 259, - 260 + 259 ] }, { "teal": 182, - "source": 78, + "source": 76, "pc": [ - 261 + 260 ] }, { - "teal": 183, - "source": 73, + "teal": 185, + "source": 74, "pc": [ + 261, 262 ] }, { - "teal": 196, - "source": 91, + "teal": 186, + "source": 77, "pc": [ - 263 + 263, + 264 ] }, { - "teal": 199, - "source": 91, + "teal": 187, + "source": 77, "pc": [ - 264, - 265, - 266 + 265 ] }, { - "teal": 200, - "source": 91, + "teal": 188, + "source": 77, "pc": [ - 267 + 266 ] }, { - "teal": 203, - "source": 91, + "teal": 189, + "source": 77, "pc": [ - 268, - 269 + 267 ] }, { - "teal": 204, - "source": 91, + "teal": 190, + "source": 77, "pc": [ - 270 + 268 ] }, { - "teal": 205, - "source": 91, + "teal": 194, + "source": 80, "pc": [ - 271 + 269, + 270 ] }, { - "teal": 206, - "source": 91, + "teal": 195, + "source": 80, "pc": [ + 271, 272 ] }, { - "teal": 207, - "source": 91, + "teal": 196, + "source": 80, "pc": [ - 273, - 274 + 273 ] }, { - "teal": 208, - "source": 91, + "teal": 197, + "source": 80, "pc": [ - 275 + 274 ] }, { - "teal": 209, - "source": 91, + "teal": 201, + "source": 81, "pc": [ + 275, 276 ] }, { - "teal": 210, - "source": 91, + "teal": 202, + "source": 81, "pc": [ - 277 + 277, + 278 ] }, { - "teal": 213, - "source": 91, + "teal": 203, + "source": 81, "pc": [ - 278, - 279, - 280 + 279 ] }, { - "teal": 214, - "source": 91, + "teal": 207, + "source": 82, "pc": [ + 280, 281 ] }, { - "teal": 215, - "source": 91, + "teal": 208, + "source": 82, "pc": [ - 282 + 282, + 283 ] }, { - "teal": 218, - "source": 91, + "teal": 209, + "source": 82, "pc": [ - 283, - 284, - 285 + 284 ] }, { - "teal": 222, - "source": 92, + "teal": 210, + "source": 73, "pc": [ - 286, - 287 + 285 ] }, { "teal": 223, - "source": 92, - "pc": [ - 288, - 289 - ] - }, - { - "teal": 224, - "source": 92, + "source": 95, "pc": [ - 290 + 286, + 287, + 288 ] }, { - "teal": 225, - "source": 92, + "teal": 226, + "source": 95, "pc": [ + 289, + 290, 291 ] }, { - "teal": 226, - "source": 92, + "teal": 227, + "source": 95, "pc": [ 292 ] }, { "teal": 230, - "source": 93, + "source": 95, "pc": [ 293, 294 @@ -914,27 +908,27 @@ }, { "teal": 231, - "source": 93, + "source": 95, "pc": [ 295 ] }, { "teal": 232, - "source": 93, + "source": 95, "pc": [ 296 ] }, { "teal": 233, - "source": 93, + "source": 95, "pc": [ 297 ] }, { - "teal": 237, + "teal": 234, "source": 95, "pc": [ 298, @@ -942,33 +936,39 @@ ] }, { - "teal": 238, + "teal": 235, + "source": 95, + "pc": [ + 300 + ] + }, + { + "teal": 236, "source": 95, "pc": [ - 300, 301 ] }, { - "teal": 239, + "teal": 237, "source": 95, "pc": [ - 302, - 303 + 302 ] }, { "teal": 240, "source": 95, "pc": [ - 304 + 303, + 304, + 305 ] }, { "teal": 241, "source": 95, "pc": [ - 305, 306 ] }, @@ -980,275 +980,263 @@ ] }, { - "teal": 243, - "source": 95, - "pc": [ - 308 - ] - }, - { - "teal": 244, + "teal": 245, "source": 95, "pc": [ - 309 + 308, + 309, + 310 ] }, { - "teal": 248, + "teal": 249, "source": 96, "pc": [ - 310, - 311 + 311, + 312 ] }, { - "teal": 249, + "teal": 250, "source": 96, "pc": [ - 312, - 313 + 313, + 314 ] }, { - "teal": 250, + "teal": 251, "source": 96, "pc": [ - 314, 315 ] }, { - "teal": 251, + "teal": 252, "source": 96, "pc": [ 316 ] }, { - "teal": 252, + "teal": 253, "source": 96, "pc": [ 317 ] }, { - "teal": 256, + "teal": 257, "source": 97, "pc": [ 318, 319 ] }, - { - "teal": 257, - "source": 97, - "pc": [ - 320, - 321 - ] - }, { "teal": 258, "source": 97, "pc": [ - 322, - 323 + 320 ] }, { "teal": 259, "source": 97, "pc": [ - 324 + 321 ] }, { "teal": 260, "source": 97, "pc": [ - 325 + 322 ] }, { "teal": 264, "source": 99, "pc": [ - 326, - 327 + 323, + 324 ] }, { "teal": 265, "source": 99, "pc": [ - 328, - 329 + 325, + 326 ] }, { "teal": 266, "source": 99, "pc": [ - 330 + 327 ] }, { "teal": 267, "source": 99, "pc": [ - 331 + 328 ] }, { "teal": 268, "source": 99, "pc": [ - 332 + 329 ] }, { "teal": 269, "source": 99, "pc": [ - 333 + 330 ] }, { "teal": 270, "source": 99, "pc": [ - 334 + 331 ] }, { "teal": 274, "source": 101, "pc": [ - 335, - 336 + 332, + 333 ] }, { "teal": 275, "source": 101, "pc": [ - 337 + 334 ] }, { "teal": 276, "source": 101, "pc": [ - 338, - 339 + 335, + 336 ] }, { "teal": 277, "source": 101, "pc": [ - 340 + 337 ] }, { "teal": 278, "source": 101, "pc": [ - 341 + 338 ] }, { "teal": 279, "source": 101, "pc": [ - 342 + 339 ] }, { "teal": 280, "source": 101, "pc": [ - 343, - 344 + 340, + 341 ] }, { "teal": 284, "source": 103, "pc": [ - 345, - 346 + 342, + 343 ] }, { "teal": 285, "source": 103, "pc": [ - 347, - 348 + 344, + 345 ] }, { "teal": 286, "source": 103, "pc": [ - 349, - 350 + 346 ] }, { "teal": 287, "source": 103, "pc": [ - 351 + 347, + 348 ] }, { - "teal": 288, - "source": 103, + "teal": 291, + "source": 104, + "pc": [ + 349, + 350 + ] + }, + { + "teal": 292, + "source": 104, "pc": [ + 351, 352 ] }, { - "teal": 289, - "source": 103, + "teal": 293, + "source": 104, "pc": [ 353, 354 ] }, { - "teal": 290, - "source": 103, + "teal": 294, + "source": 104, "pc": [ 355 ] }, { - "teal": 291, - "source": 103, + "teal": 295, + "source": 104, "pc": [ 356 ] }, { - "teal": 292, - "source": 103, - "pc": [ - 357 - ] - }, - { - "teal": 293, - "source": 103, + "teal": 296, + "source": 104, "pc": [ + 357, 358 ] }, { - "teal": 294, - "source": 103, + "teal": 297, + "source": 104, "pc": [ 359 ] @@ -1257,911 +1245,905 @@ "teal": 298, "source": 104, "pc": [ - 360, - 361 + 360 ] }, { "teal": 299, "source": 104, "pc": [ - 362, - 363 + 361 ] }, { "teal": 300, "source": 104, "pc": [ - 364 + 362 ] }, { "teal": 301, - "source": 91, + "source": 104, + "pc": [ + 363 + ] + }, + { + "teal": 305, + "source": 105, "pc": [ + 364, 365 ] }, { - "teal": 304, - "source": 108, + "teal": 306, + "source": 105, "pc": [ 366, - 367, - 368 + 367 ] }, { - "teal": 309, - "source": 109, + "teal": 307, + "source": 105, "pc": [ - 369, - 370, - 371 + 368 ] }, { - "teal": 310, - "source": 109, + "teal": 308, + "source": 105, "pc": [ - 372 + 369, + 370 ] }, { - "teal": 311, - "source": 109, + "teal": 309, + "source": 105, "pc": [ - 373 + 371 ] }, { - "teal": 312, - "source": 109, + "teal": 310, + "source": 105, "pc": [ - 374 + 372, + 373 ] }, { - "teal": 313, - "source": 109, + "teal": 319, + "source": 107, "pc": [ + 374, 375 ] }, { - "teal": 314, - "source": 109, + "teal": 320, + "source": 108, "pc": [ 376, - 377, - 378 + 377 ] }, { - "teal": 319, - "source": 110, + "teal": 321, + "source": 108, "pc": [ + 378, 379 ] }, { - "teal": 320, - "source": 110, + "teal": 322, + "source": 108, "pc": [ 380 ] }, { - "teal": 321, - "source": 110, - "pc": [ - 381 - ] - }, - { - "teal": 322, - "source": 110, + "teal": 323, + "source": 108, "pc": [ + 381, 382 ] }, { - "teal": 323, - "source": 110, + "teal": 324, + "source": 108, "pc": [ 383 ] }, { - "teal": 324, - "source": 109, + "teal": 325, + "source": 108, "pc": [ 384, - 385, - 386 + 385 ] }, { - "teal": 335, - "source": 112, + "teal": 326, + "source": 108, + "pc": [ + 386 + ] + }, + { + "teal": 327, + "source": 108, "pc": [ 387 ] }, { - "teal": 336, - "source": 112, + "teal": 328, + "source": 108, "pc": [ 388 ] }, { - "teal": 337, - "source": 112, + "teal": 331, + "source": 107, + "pc": [ + 389, + 390 + ] + }, + { + "teal": 332, + "source": 109, + "pc": [ + 391, + 392 + ] + }, + { + "teal": 333, + "source": 109, + "pc": [ + 393, + 394 + ] + }, + { + "teal": 334, + "source": 109, + "pc": [ + 395 + ] + }, + { + "teal": 335, + "source": 109, "pc": [ - 389 + 396 ] }, { "teal": 338, - "source": 112, + "source": 107, "pc": [ - 390, - 391 + 397, + 398 ] }, { "teal": 339, - "source": 113, + "source": 110, "pc": [ - 392, - 393, - 394, - 395, - 396, - 397 + 399, + 400 ] }, { "teal": 340, - "source": 113, + "source": 110, "pc": [ - 398, - 399 + 401, + 402 ] }, { - "teal": 344, - "source": 114, + "teal": 341, + "source": 110, "pc": [ - 400, - 401 + 403 ] }, { - "teal": 345, - "source": 114, + "teal": 342, + "source": 110, "pc": [ - 402 + 404 ] }, { "teal": 346, - "source": 114, + "source": 113, "pc": [ - 403 + 405, + 406 ] }, { "teal": 347, - "source": 114, + "source": 113, "pc": [ - 404, - 405 + 407, + 408 ] }, { "teal": 348, - "source": 114, + "source": 113, "pc": [ - 406, - 407, - 408, 409 ] }, { "teal": 349, - "source": 114, + "source": 95, "pc": [ - 410, - 411 + 410 ] }, { - "teal": 353, - "source": 115, + "teal": 352, + "source": 117, "pc": [ + 411, 412, 413 ] }, { - "teal": 354, - "source": 115, + "teal": 357, + "source": 118, "pc": [ - 414 + 414, + 415, + 416 ] }, { - "teal": 355, - "source": 115, + "teal": 358, + "source": 118, "pc": [ - 415, - 416 + 417 ] }, { "teal": 359, - "source": 116, + "source": 118, "pc": [ - 417 + 418 ] }, { "teal": 360, - "source": 116, + "source": 118, "pc": [ - 418, 419 ] }, { - "teal": 364, - "source": 117, + "teal": 361, + "source": 118, "pc": [ 420 ] }, { - "teal": 365, - "source": 117, + "teal": 362, + "source": 118, "pc": [ 421, - 422 + 422, + 423 + ] + }, + { + "teal": 367, + "source": 119, + "pc": [ + 424 ] }, { "teal": 368, - "source": 112, + "source": 119, "pc": [ - 423 + 425 ] }, { "teal": 369, - "source": 112, + "source": 119, "pc": [ - 424, - 425 + 426 ] }, { "teal": 370, - "source": 112, + "source": 119, "pc": [ - 426 + 427 ] }, { "teal": 371, - "source": 112, + "source": 119, "pc": [ - 427 + 428 ] }, { "teal": 372, - "source": 112, + "source": 118, "pc": [ - 428, - 429 + 429, + 430, + 431 ] }, { - "teal": 373, - "source": 112, + "teal": 383, + "source": 121, "pc": [ - 430, - 431, 432 ] }, { - "teal": 374, - "source": 112, + "teal": 384, + "source": 121, "pc": [ 433 ] }, { - "teal": 377, - "source": 108, + "teal": 385, + "source": 121, "pc": [ 434 ] }, { - "teal": 383, - "source": 123, + "teal": 386, + "source": 121, "pc": [ 435, - 436, - 437 + 436 ] }, { - "teal": 386, - "source": 123, + "teal": 387, + "source": 122, "pc": [ + 437, 438, 439, - 440 + 440, + 441, + 442 ] }, { - "teal": 387, - "source": 123, + "teal": 388, + "source": 122, "pc": [ - 441 + 443, + 444 ] }, { - "teal": 388, + "teal": 392, "source": 123, "pc": [ - 442 + 445, + 446 ] }, { - "teal": 391, + "teal": 393, "source": 123, "pc": [ - 443, - 444, - 445 + 447 ] }, { - "teal": 395, - "source": 124, + "teal": 394, + "source": 123, "pc": [ - 446, - 447, 448 ] }, { - "teal": 396, - "source": 124, - "pc": [ - 449 - ] - }, - { - "teal": 397, - "source": 124, + "teal": 395, + "source": 123, "pc": [ + 449, 450 ] }, { - "teal": 398, - "source": 124, - "pc": [ - 451 - ] - }, - { - "teal": 399, - "source": 124, + "teal": 396, + "source": 123, "pc": [ - 452 + 451, + 452, + 453, + 454 ] }, { - "teal": 400, - "source": 124, + "teal": 397, + "source": 123, "pc": [ - 453 + 455, + 456 ] }, { "teal": 401, "source": 124, "pc": [ - 454 - ] - }, - { - "teal": 405, - "source": 125, - "pc": [ - 455, - 456, - 457 + 457, + 458 ] }, { - "teal": 409, - "source": 129, + "teal": 402, + "source": 124, "pc": [ - 458, 459 ] }, { - "teal": 410, - "source": 129, + "teal": 403, + "source": 124, "pc": [ - 460 + 460, + 461 ] }, { - "teal": 411, - "source": 129, + "teal": 407, + "source": 125, "pc": [ - 461, 462 ] }, { - "teal": 415, - "source": 131, + "teal": 408, + "source": 125, "pc": [ - 463 + 463, + 464 ] }, { - "teal": 416, - "source": 131, + "teal": 412, + "source": 126, "pc": [ - 464, 465 ] }, { - "teal": 421, - "source": 135, + "teal": 413, + "source": 126, "pc": [ - 466 + 466, + 467 ] }, { - "teal": 422, - "source": 135, + "teal": 416, + "source": 121, "pc": [ - 467 + 468 ] }, { - "teal": 423, - "source": 135, + "teal": 417, + "source": 121, "pc": [ - 468, - 469 + 469, + 470 ] }, { - "teal": 424, - "source": 135, + "teal": 418, + "source": 121, "pc": [ - 470 + 471 ] }, { - "teal": 425, - "source": 135, + "teal": 419, + "source": 121, "pc": [ - 471, 472 ] }, { - "teal": 429, - "source": 137, + "teal": 420, + "source": 121, "pc": [ 473, 474 ] }, { - "teal": 430, - "source": 137, + "teal": 421, + "source": 121, "pc": [ 475, - 476 + 476, + 477 ] }, { - "teal": 431, - "source": 137, + "teal": 422, + "source": 121, "pc": [ - 477 + 478 ] }, { - "teal": 432, - "source": 137, + "teal": 425, + "source": 117, "pc": [ - 478, 479 ] }, { - "teal": 436, - "source": 139, + "teal": 431, + "source": 133, "pc": [ 480, - 481 - ] - }, - { - "teal": 437, - "source": 5, - "pc": [ - 482, - 483 + 481, + 482 ] }, { - "teal": 438, - "source": 5, + "teal": 434, + "source": 133, "pc": [ + 483, 484, 485 ] }, { - "teal": 439, - "source": 139, + "teal": 435, + "source": 133, "pc": [ - 486, - 487 + 486 ] }, { - "teal": 440, - "source": 139, + "teal": 436, + "source": 133, "pc": [ + 487, 488 ] }, { - "teal": 441, - "source": 139, + "teal": 439, + "source": 133, "pc": [ - 489 + 489, + 490, + 491 ] }, { - "teal": 442, - "source": 139, + "teal": 440, + "source": 133, "pc": [ - 490 + 492 ] }, { - "teal": 443, - "source": 139, + "teal": 441, + "source": 133, "pc": [ - 491, - 492 + 493 ] }, { "teal": 444, - "source": 139, + "source": 133, "pc": [ - 493 + 494, + 495, + 496 ] }, { - "teal": 445, - "source": 139, + "teal": 448, + "source": 135, "pc": [ - 494 + 497, + 498, + 499 ] }, { - "teal": 446, - "source": 139, + "teal": 449, + "source": 135, "pc": [ - 495 + 500 ] }, { - "teal": 447, - "source": 139, + "teal": 450, + "source": 135, "pc": [ - 496, - 497 + 501 ] }, { - "teal": 448, - "source": 140, + "teal": 451, + "source": 135, "pc": [ - 498, - 499 + 502 ] }, { - "teal": 449, - "source": 140, + "teal": 452, + "source": 135, "pc": [ - 500 + 503 ] }, { - "teal": 450, - "source": 140, + "teal": 453, + "source": 135, "pc": [ - 501, - 502, - 503 + 504 ] }, { - "teal": 451, - "source": 140, + "teal": 454, + "source": 135, "pc": [ - 504, 505 ] }, { - "teal": 452, - "source": 140, + "teal": 458, + "source": 136, "pc": [ 506, - 507 + 507, + 508 ] }, { - "teal": 453, + "teal": 462, "source": 140, "pc": [ - 508 + 509, + 510 ] }, { - "teal": 454, + "teal": 463, "source": 140, "pc": [ - 509 + 511 ] }, { - "teal": 457, - "source": 134, + "teal": 464, + "source": 140, "pc": [ - 510, - 511, - 512 + 512, + 513 ] }, { - "teal": 462, + "teal": 468, "source": 142, "pc": [ - 513, 514 ] }, { - "teal": 463, + "teal": 469, "source": 142, "pc": [ 515, - 516, + 516 + ] + }, + { + "teal": 474, + "source": 146, + "pc": [ 517 ] }, { - "teal": 468, - "source": 142, + "teal": 475, + "source": 146, "pc": [ 518 ] }, { - "teal": 469, - "source": 142, + "teal": 476, + "source": 146, "pc": [ 519, 520 ] }, { - "teal": 470, - "source": 142, + "teal": 477, + "source": 146, "pc": [ 521 ] }, { - "teal": 471, - "source": 142, + "teal": 478, + "source": 146, "pc": [ 522, 523 ] }, { - "teal": 472, - "source": 142, + "teal": 482, + "source": 148, "pc": [ - 524 + 524, + 525 ] }, { - "teal": 473, - "source": 142, + "teal": 483, + "source": 148, "pc": [ - 525, - 526 + 526, + 527 ] }, { - "teal": 474, - "source": 142, + "teal": 484, + "source": 148, "pc": [ - 527 + 528 ] }, { - "teal": 475, - "source": 142, + "teal": 485, + "source": 148, "pc": [ - 528 + 529, + 530 ] }, { - "teal": 476, - "source": 142, + "teal": 489, + "source": 150, "pc": [ - 529 + 531, + 532 ] }, { - "teal": 477, - "source": 142, + "teal": 490, + "source": 5, "pc": [ - 530 + 533, + 534 ] }, { - "teal": 482, - "source": 144, + "teal": 491, + "source": 5, "pc": [ - 531 + 535, + 536 ] }, { - "teal": 483, - "source": 144, + "teal": 492, + "source": 150, "pc": [ - 532, - 533 + 537, + 538 ] }, { - "teal": 484, - "source": 144, + "teal": 493, + "source": 150, "pc": [ - 534, - 535 + 539 ] }, { - "teal": 485, - "source": 144, - "pc": [ - 536 - ] - }, - { - "teal": 486, - "source": 144, - "pc": [ - 537 - ] - }, - { - "teal": 490, - "source": 145, - "pc": [ - 538 - ] - }, - { - "teal": 491, - "source": 145, + "teal": 494, + "source": 150, "pc": [ - 539, 540 ] }, { - "teal": 492, - "source": 145, + "teal": 495, + "source": 150, "pc": [ 541 ] }, { - "teal": 493, - "source": 145, + "teal": 496, + "source": 150, "pc": [ 542, 543 ] }, { - "teal": 494, - "source": 145, + "teal": 497, + "source": 150, "pc": [ 544 ] }, { - "teal": 495, - "source": 145, + "teal": 498, + "source": 150, "pc": [ - 545, - 546 + 545 ] }, { - "teal": 496, - "source": 145, + "teal": 499, + "source": 150, "pc": [ - 547 + 546 ] }, { - "teal": 497, - "source": 145, + "teal": 500, + "source": 150, "pc": [ + 547, 548 ] }, { - "teal": 498, - "source": 145, - "pc": [ - 549 - ] - }, - { - "teal": 499, - "source": 145, + "teal": 501, + "source": 151, "pc": [ + 549, 550 ] }, { - "teal": 505, - "source": 149, + "teal": 502, + "source": 151, "pc": [ 551 ] }, { - "teal": 508, - "source": 149, + "teal": 503, + "source": 151, "pc": [ 552, 553, @@ -2169,855 +2151,1110 @@ ] }, { - "teal": 509, - "source": 149, + "teal": 504, + "source": 151, "pc": [ - 555 + 555, + 556 ] }, { - "teal": 510, - "source": 149, + "teal": 505, + "source": 151, "pc": [ - 556 + 557, + 558 ] }, { - "teal": 513, - "source": 149, + "teal": 506, + "source": 151, "pc": [ - 557, - 558, 559 ] }, { - "teal": 517, - "source": 150, + "teal": 507, + "source": 151, "pc": [ - 560, - 561 + 560 ] }, { - "teal": 518, - "source": 150, + "teal": 510, + "source": 145, "pc": [ + 561, 562, 563 ] }, { - "teal": 522, - "source": 150, + "teal": 515, + "source": 153, "pc": [ 564, 565 ] }, { - "teal": 523, - "source": 150, - "pc": [ - 566 - ] - }, - { - "teal": 524, - "source": 150, + "teal": 516, + "source": 153, "pc": [ - 567 + 566, + 567, + 568 ] }, { - "teal": 525, - "source": 152, + "teal": 521, + "source": 153, "pc": [ - 568, - 569, - 570 + 569 ] }, { - "teal": 526, - "source": 152, + "teal": 522, + "source": 153, "pc": [ + 570, 571 ] }, { - "teal": 527, - "source": 152, + "teal": 523, + "source": 153, "pc": [ 572 ] }, { - "teal": 528, - "source": 152, - "pc": [ - 573 - ] - }, - { - "teal": 529, - "source": 152, + "teal": 524, + "source": 153, "pc": [ + 573, 574 ] }, { - "teal": 530, - "source": 152, + "teal": 525, + "source": 153, "pc": [ 575 ] }, { - "teal": 534, - "source": 150, + "teal": 526, + "source": 153, "pc": [ 576, 577 ] }, { - "teal": 535, - "source": 150, + "teal": 527, + "source": 153, "pc": [ 578 ] }, { - "teal": 536, - "source": 150, + "teal": 528, + "source": 153, "pc": [ 579 ] }, { - "teal": 537, + "teal": 529, "source": 153, "pc": [ - 580, - 581, - 582 + 580 ] }, { - "teal": 538, + "teal": 530, "source": 153, "pc": [ - 583 + 581 ] }, { - "teal": 539, - "source": 153, + "teal": 535, + "source": 155, "pc": [ - 584 + 582 ] }, { - "teal": 540, - "source": 153, + "teal": 536, + "source": 155, "pc": [ - 585 + 583, + 584 ] }, { - "teal": 541, - "source": 153, + "teal": 537, + "source": 155, "pc": [ + 585, 586 ] }, { - "teal": 542, - "source": 153, + "teal": 538, + "source": 155, "pc": [ 587 ] }, { - "teal": 552, + "teal": 539, "source": 155, "pc": [ 588 ] }, { - "teal": 553, - "source": 155, + "teal": 543, + "source": 156, "pc": [ 589 ] }, { - "teal": 554, - "source": 155, + "teal": 544, + "source": 156, "pc": [ 590, 591 ] }, { - "teal": 558, + "teal": 545, "source": 156, "pc": [ - 592, - 593 + 592 ] }, { - "teal": 559, + "teal": 546, "source": 156, "pc": [ - 594, - 595 + 593, + 594 ] }, { - "teal": 563, - "source": 157, + "teal": 547, + "source": 156, "pc": [ - 596 + 595 ] }, { - "teal": 564, - "source": 157, + "teal": 548, + "source": 156, "pc": [ + 596, 597 ] }, { - "teal": 565, - "source": 157, + "teal": 549, + "source": 156, + "pc": [ + 598 + ] + }, + { + "teal": 550, + "source": 156, "pc": [ - 598, 599 ] }, { - "teal": 569, - "source": 158, + "teal": 551, + "source": 156, "pc": [ - 600, - 601 + 600 ] }, { - "teal": 570, - "source": 158, + "teal": 552, + "source": 156, "pc": [ - 602 + 601 ] }, { - "teal": 571, - "source": 158, + "teal": 558, + "source": 160, "pc": [ - 603 + 602 ] }, { - "teal": 572, - "source": 158, + "teal": 561, + "source": 160, "pc": [ + 603, 604, 605 ] }, { - "teal": 573, - "source": 158, + "teal": 562, + "source": 160, "pc": [ 606 ] }, { - "teal": 574, - "source": 158, + "teal": 563, + "source": 160, "pc": [ - 607, - 608 + 607 ] }, { - "teal": 578, - "source": 159, + "teal": 566, + "source": 160, "pc": [ + 608, 609, 610 ] }, { - "teal": 579, - "source": 159, + "teal": 570, + "source": 161, "pc": [ 611, 612 ] }, { - "teal": 583, - "source": 160, + "teal": 571, + "source": 161, "pc": [ - 613 + 613, + 614 ] }, { - "teal": 584, - "source": 160, + "teal": 575, + "source": 161, "pc": [ - 614, - 615 + 615, + 616 ] }, { - "teal": 587, - "source": 155, + "teal": 576, + "source": 161, "pc": [ - 616 + 617 ] }, { - "teal": 588, - "source": 149, + "teal": 577, + "source": 161, "pc": [ - 617 + 618 ] }, { - "teal": 596, - "source": 169, + "teal": 578, + "source": 163, "pc": [ - 618, - 619 + 619, + 620, + 621 ] }, { - "teal": 599, - "source": 169, + "teal": 579, + "source": 163, "pc": [ - 620, - 621, 622 ] }, { - "teal": 600, - "source": 169, + "teal": 580, + "source": 163, "pc": [ 623 ] }, { - "teal": 601, - "source": 169, + "teal": 581, + "source": 163, "pc": [ 624 ] }, { - "teal": 604, - "source": 169, + "teal": 582, + "source": 163, "pc": [ - 625, - 626, - 627 + 625 ] }, { - "teal": 608, - "source": 170, + "teal": 583, + "source": 163, "pc": [ - 628, - 629, - 630 + 626 ] }, { - "teal": 609, - "source": 170, + "teal": 587, + "source": 161, "pc": [ - 631 + 627, + 628 ] }, { - "teal": 610, - "source": 170, + "teal": 588, + "source": 161, "pc": [ - 632 + 629 ] }, { - "teal": 611, - "source": 170, + "teal": 589, + "source": 161, + "pc": [ + 630 + ] + }, + { + "teal": 590, + "source": 164, "pc": [ + 631, + 632, 633 ] }, { - "teal": 612, - "source": 170, + "teal": 591, + "source": 164, "pc": [ 634 ] }, { - "teal": 613, - "source": 170, + "teal": 592, + "source": 164, "pc": [ 635 ] }, { - "teal": 614, - "source": 170, + "teal": 593, + "source": 164, "pc": [ 636 ] }, { - "teal": 618, - "source": 171, + "teal": 594, + "source": 164, + "pc": [ + 637 + ] + }, + { + "teal": 595, + "source": 164, "pc": [ - 637, 638 ] }, { - "teal": 619, - "source": 171, + "teal": 605, + "source": 166, + "pc": [ + 639 + ] + }, + { + "teal": 606, + "source": 166, "pc": [ - 639, 640 ] }, { - "teal": 620, - "source": 171, + "teal": 607, + "source": 166, "pc": [ - 641 + 641, + 642 ] }, { - "teal": 621, - "source": 171, + "teal": 611, + "source": 167, "pc": [ - 642, 643, 644 ] }, { - "teal": 622, - "source": 171, + "teal": 612, + "source": 167, "pc": [ - 645 + 645, + 646 ] }, { - "teal": 623, - "source": 171, + "teal": 616, + "source": 168, "pc": [ - 646 + 647 ] }, { - "teal": 624, - "source": 171, + "teal": 617, + "source": 168, "pc": [ - 647 + 648 ] }, { - "teal": 628, - "source": 173, + "teal": 618, + "source": 168, "pc": [ - 648, - 649 + 649, + 650 ] }, { - "teal": 629, - "source": 173, + "teal": 622, + "source": 169, "pc": [ - 650, - 651 + 651, + 652 ] }, { - "teal": 633, - "source": 173, + "teal": 623, + "source": 169, "pc": [ - 652, 653 ] }, { - "teal": 634, - "source": 173, + "teal": 624, + "source": 169, "pc": [ 654 ] }, { - "teal": 635, - "source": 173, + "teal": 625, + "source": 169, "pc": [ - 655 + 655, + 656 ] }, { - "teal": 636, - "source": 174, + "teal": 626, + "source": 169, "pc": [ - 656, - 657, - 658 + 657 ] }, { - "teal": 637, - "source": 174, + "teal": 627, + "source": 169, "pc": [ + 658, 659 ] }, { - "teal": 638, - "source": 173, + "teal": 631, + "source": 170, "pc": [ 660, 661 ] }, { - "teal": 639, - "source": 173, + "teal": 632, + "source": 170, "pc": [ - 662 + 662, + 663 ] }, { - "teal": 640, - "source": 173, + "teal": 636, + "source": 171, "pc": [ - 663 + 664 ] }, { - "teal": 641, - "source": 174, + "teal": 637, + "source": 171, "pc": [ - 664, 665, 666 ] }, { - "teal": 642, - "source": 174, + "teal": 640, + "source": 166, "pc": [ 667 ] }, { - "teal": 643, - "source": 174, + "teal": 641, + "source": 160, "pc": [ 668 ] }, { - "teal": 644, - "source": 174, - "pc": [ - 669 - ] - }, - { - "teal": 645, - "source": 174, + "teal": 649, + "source": 180, "pc": [ + 669, 670 ] }, { - "teal": 646, - "source": 174, + "teal": 652, + "source": 180, "pc": [ 671, - 672 + 672, + 673 ] }, { - "teal": 650, - "source": 176, + "teal": 653, + "source": 180, "pc": [ - 673, 674 ] }, { - "teal": 651, - "source": 176, + "teal": 654, + "source": 180, "pc": [ 675 ] }, { - "teal": 659, - "source": 178, + "teal": 657, + "source": 180, "pc": [ - 676 + 676, + 677, + 678 ] }, { - "teal": 660, - "source": 178, + "teal": 661, + "source": 181, "pc": [ - 677 + 679, + 680, + 681 ] }, { - "teal": 661, - "source": 178, + "teal": 662, + "source": 181, "pc": [ - 678, - 679 + 682 ] }, { - "teal": 665, - "source": 179, + "teal": 663, + "source": 181, "pc": [ - 680, - 681 + 683 ] }, { - "teal": 666, - "source": 179, + "teal": 664, + "source": 181, "pc": [ - 682 + 684 ] }, { - "teal": 667, - "source": 179, + "teal": 665, + "source": 181, "pc": [ - 683, - 684 + 685 ] }, { - "teal": 668, - "source": 179, + "teal": 666, + "source": 181, "pc": [ - 685 + 686 ] }, { - "teal": 669, - "source": 179, + "teal": 667, + "source": 181, "pc": [ - 686, 687 ] }, { - "teal": 673, - "source": 180, + "teal": 671, + "source": 182, "pc": [ 688, 689 ] }, { - "teal": 674, - "source": 180, + "teal": 672, + "source": 182, "pc": [ 690, 691 ] }, { - "teal": 678, - "source": 181, + "teal": 673, + "source": 182, "pc": [ 692 ] }, { - "teal": 679, - "source": 181, + "teal": 674, + "source": 182, "pc": [ 693, - 694 + 694, + 695 ] }, { - "teal": 682, - "source": 178, + "teal": 675, + "source": 182, "pc": [ - 695 + 696 ] }, { - "teal": 683, - "source": 169, + "teal": 676, + "source": 182, "pc": [ - 696 + 697 ] }, { - "teal": 686, - "source": 8, + "teal": 677, + "source": 182, + "pc": [ + 698 + ] + }, + { + "teal": 681, + "source": 184, "pc": [ - 697, - 698, 699, - 700, + 700 + ] + }, + { + "teal": 682, + "source": 184, + "pc": [ 701, 702 ] }, { - "teal": 687, - "source": 8, + "teal": 686, + "source": 184, "pc": [ 703, - 704, + 704 + ] + }, + { + "teal": 687, + "source": 184, + "pc": [ 705 ] }, { "teal": 688, - "source": 8, + "source": 184, + "pc": [ + 706 + ] + }, + { + "teal": 689, + "source": 185, "pc": [ - 706, 707, 708, 709 ] }, { - "teal": 689, - "source": 8, + "teal": 690, + "source": 185, "pc": [ 710 ] }, { - "teal": 692, - "source": 8, + "teal": 691, + "source": 184, "pc": [ 711, - 712, - 713, - 714, - 715, - 716 + 712 + ] + }, + { + "teal": 692, + "source": 184, + "pc": [ + 713 ] }, { "teal": 693, - "source": 8, + "source": 184, "pc": [ - 717, - 718, - 719, - 720, - 721, - 722 + 714 ] }, { "teal": 694, - "source": 8, + "source": 185, + "pc": [ + 715, + 716, + 717 + ] + }, + { + "teal": 695, + "source": 185, + "pc": [ + 718 + ] + }, + { + "teal": 696, + "source": 185, + "pc": [ + 719 + ] + }, + { + "teal": 697, + "source": 185, + "pc": [ + 720 + ] + }, + { + "teal": 698, + "source": 185, + "pc": [ + 721 + ] + }, + { + "teal": 699, + "source": 185, + "pc": [ + 722, + 723 + ] + }, + { + "teal": 703, + "source": 187, "pc": [ - 723, 724, - 725, - 726, - 727, + 725 + ] + }, + { + "teal": 704, + "source": 187, + "pc": [ + 726 + ] + }, + { + "teal": 712, + "source": 189, + "pc": [ + 727 + ] + }, + { + "teal": 713, + "source": 189, + "pc": [ 728 ] }, { - "teal": 695, - "source": 8, + "teal": 714, + "source": 189, "pc": [ 729, - 730, + 730 + ] + }, + { + "teal": 718, + "source": 190, + "pc": [ 731, - 732, - 733, - 734 + 732 ] }, { - "teal": 696, - "source": 8, + "teal": 719, + "source": 190, + "pc": [ + 733 + ] + }, + { + "teal": 720, + "source": 190, + "pc": [ + 734, + 735 + ] + }, + { + "teal": 721, + "source": 190, + "pc": [ + 736 + ] + }, + { + "teal": 722, + "source": 190, "pc": [ - 735, - 736, 737, - 738, + 738 + ] + }, + { + "teal": 726, + "source": 191, + "pc": [ 739, 740 ] }, { - "teal": 697, - "source": 8, + "teal": 727, + "source": 191, "pc": [ 741, - 742, - 743, + 742 + ] + }, + { + "teal": 731, + "source": 192, + "pc": [ + 743 + ] + }, + { + "teal": 732, + "source": 192, + "pc": [ 744, - 745, + 745 + ] + }, + { + "teal": 735, + "source": 189, + "pc": [ 746 ] }, { - "teal": 698, - "source": 8, + "teal": 736, + "source": 180, "pc": [ - 747, - 748, - 749 + 747 ] }, { - "teal": 699, + "teal": 739, "source": 8, "pc": [ + 748, + 749, 750, 751, 752, - 753, + 753 + ] + }, + { + "teal": 740, + "source": 8, + "pc": [ 754, 755, - 756, + 756 + ] + }, + { + "teal": 741, + "source": 8, + "pc": [ 757, 758, 759, - 760, - 761, + 760 + ] + }, + { + "teal": 742, + "source": 8, + "pc": [ + 761 + ] + }, + { + "teal": 745, + "source": 8, + "pc": [ 762, - 763 + 763, + 764, + 765, + 766, + 767 + ] + }, + { + "teal": 746, + "source": 8, + "pc": [ + 768, + 769, + 770, + 771, + 772, + 773 + ] + }, + { + "teal": 747, + "source": 8, + "pc": [ + 774, + 775, + 776, + 777, + 778, + 779 + ] + }, + { + "teal": 748, + "source": 8, + "pc": [ + 780, + 781, + 782, + 783, + 784, + 785 + ] + }, + { + "teal": 749, + "source": 8, + "pc": [ + 786, + 787, + 788, + 789, + 790, + 791 + ] + }, + { + "teal": 750, + "source": 8, + "pc": [ + 792, + 793, + 794, + 795, + 796, + 797 + ] + }, + { + "teal": 751, + "source": 8, + "pc": [ + 798, + 799, + 800 + ] + }, + { + "teal": 752, + "source": 8, + "pc": [ + 801, + 802, + 803, + 804, + 805, + 806, + 807, + 808, + 809, + 810, + 811, + 812, + 813, + 814 ] }, { - "teal": 700, + "teal": 753, "source": 8, "pc": [ - 764 + 815 ] } ] \ No newline at end of file diff --git a/examples/raffle/raffle.algo.ts b/examples/raffle/raffle.algo.ts index 79f429c7c..f56c98fdb 100644 --- a/examples/raffle/raffle.algo.ts +++ b/examples/raffle/raffle.algo.ts @@ -70,8 +70,12 @@ class NFTRaffle extends Contract { * @param draw The round number when the raffle is drawn * */ - startRaffle(end: number, draw: number): void { - assert(this.app.address.assetBalance(this.asset.value) > 0); + startRaffle(axfer: AssetTransferTxn, end: number, draw: number): void { + verifyTxn(axfer, { + assetAmount: { greaterThan: 0 }, + assetReceiver: this.app.address, + xferAsset: this.asset.value, + }); assert(draw > end); this.endRound.value = end; @@ -88,19 +92,24 @@ class NFTRaffle extends Contract { * * @returns The total number of tickets owned by the sender */ - buyTickets(payment: PayTxn, quanity: number): void { + buyTickets(payment: PayTxn, quantity: number): void { assert(globals.round < this.endRound.value); - assert(quanity > 0); - - assert(payment.amount === this.ticketPrice.value * quanity); - assert(payment.sender === this.txn.sender); - assert(payment.receiver === this.app.address); + assert(quantity > 0); assert(!this.tickets(payment.sender).exists); - const newTotal = this.totalTickets.value + quanity + 1; + const newTotal = this.totalTickets.value + quantity + 1; + const preMBR = this.app.address.minBalance; this.tickets(payment.sender).value = { start: this.totalTickets.value, end: newTotal - 1 }; + const mbrDelta = this.app.address.minBalance - preMBR; + + verifyTxn(payment, { + amount: this.ticketPrice.value * quantity + mbrDelta, + sender: this.txn.sender, + receiver: this.app.address, + }); + this.totalTickets.value = newTotal; } @@ -120,7 +129,9 @@ class NFTRaffle extends Contract { } /** Draw the winning ticket */ - draw(): boolean { + // eslint-disable-next-line no-unused-vars + draw(_oracleReference: Application): boolean { + // assert(this.endRound.value < globals.round); assert(!this.winningTicket.exists); this.getRandomBytes(); @@ -182,3 +193,10 @@ class NFTRaffle extends Contract { }); } } + +// eslint-disable-next-line no-unused-vars +class MockVRFBeacon extends Contract { + must_get(_round: uint64, data: bytes): bytes { + return sha256(data + itob(globals.round)) as bytes; + } +} diff --git a/examples/raffle/raffle.test.ts b/examples/raffle/raffle.test.ts new file mode 100644 index 000000000..a665b41ff --- /dev/null +++ b/examples/raffle/raffle.test.ts @@ -0,0 +1,137 @@ +import { describe, test, beforeAll, beforeEach, expect } from '@jest/globals'; +// eslint-disable-next-line import/no-unresolved +import { algorandFixture } from '@algorandfoundation/algokit-utils/testing'; +import * as algokit from '@algorandfoundation/algokit-utils'; +import algosdk from 'algosdk'; +import { MockVrfBeaconClient } from './MockVRFBeaconClient'; +import { NftRaffleClient } from './NFTRaffleClient'; + +const BOX_COST = 21_700; + +describe('Raffle', () => { + const fixture = algorandFixture(); + + let appClient: NftRaffleClient; + + let asa: bigint; + + let alice: algosdk.Account; + + let bob: algosdk.Account; + + let randomnessOracle: bigint; + + beforeEach(fixture.beforeEach); + + beforeAll(async () => { + await fixture.beforeEach(); + const { algod, testAccount } = fixture.context; + + const beaconClient = new MockVrfBeaconClient( + { + sender: testAccount, + resolveBy: 'id', + id: 0, + }, + algod + ); + + await beaconClient.create.createApplication({}); + + randomnessOracle = BigInt((await beaconClient.appClient.getAppReference()).appId); + + alice = testAccount; + + appClient = new NftRaffleClient( + { + sender: testAccount, + resolveBy: 'id', + id: 0, + }, + algod + ); + + await appClient.create.createApplication({ + ticketPrice: 100, + randomnessOracle, + }); + + const asaCreateTxn = algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({ + suggestedParams: await algod.getTransactionParams().do(), + from: testAccount.addr, + total: 1, + decimals: 0, + defaultFrozen: false, + }); + + const { confirmation } = await algokit.sendTransaction({ transaction: asaCreateTxn, from: testAccount }, algod); + + asa = BigInt(confirmation!.assetIndex!); + + await appClient.appClient.fundAppAccount(algokit.microAlgos(200_000)); + }); + + test('setAsset', async () => { + await appClient.setAsset({ asset: asa }, { sendParams: { fee: algokit.microAlgos(2_000) } }); + }); + + test('startRaffle', async () => { + const { algod } = fixture.context; + + const lastRound = BigInt((await algod.status().do())['last-round']); + + const axfer = algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject({ + from: alice.addr, + assetIndex: Number(asa), + to: (await appClient.appClient.getAppReference()).appAddress, + suggestedParams: await algod.getTransactionParams().do(), + amount: 1, + }); + + await appClient.startRaffle({ axfer, end: lastRound + BigInt(100), draw: lastRound + BigInt(101) }); + }); + + test('buyTickets', async () => { + const { algod, testAccount } = fixture.context; + + bob = testAccount; + + const ticketPrice = (await appClient.getGlobalState()).ticketPrice!.asNumber(); + const quantity = 50; + + const to = (await appClient.appClient.getAppReference()).appAddress; + + const alicePayment = algosdk.makePaymentTxnWithSuggestedParamsFromObject({ + from: alice.addr, + to, + suggestedParams: await algod.getTransactionParams().do(), + amount: ticketPrice * quantity + BOX_COST, + }); + + await appClient.buyTickets( + { payment: alicePayment, quantity: 50 }, + { boxes: [algosdk.decodeAddress(alice.addr).publicKey] } + ); + + const bobPayment = algosdk.makePaymentTxnWithSuggestedParamsFromObject({ + from: bob.addr, + to, + suggestedParams: await algod.getTransactionParams().do(), + amount: ticketPrice * quantity + BOX_COST, + }); + + await appClient.buyTickets( + { payment: bobPayment, quantity: 50 }, + { sender: bob, boxes: [algosdk.decodeAddress(bob.addr).publicKey] } + ); + }); + + test('draw', async () => { + const result = await appClient.draw( + { _oracleReference: randomnessOracle }, + { sendParams: { fee: algokit.microAlgos(2_000) } } + ); + + expect(result.return?.valueOf()).toBe(true); + }); +}); diff --git a/package.json b/package.json index 1416008a2..f3cdc5f3a 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "compile-non_abi": "bun ./src/bin/tealscript.ts --unsafe-disable-typescript examples/non_abi/non_abi.algo.ts examples/non_abi/artifacts", "compile-optin-lsig": "bun ./src/bin/tealscript.ts --unsafe-disable-typescript examples/optin-lsig/lsig.algo.ts examples/optin-lsig/artifacts", "compile-lsig_with_app": "bun ./src/bin/tealscript.ts --unsafe-disable-typescript examples/lsig_with_app/lsig_with_app.algo.ts examples/lsig_with_app/artifacts", - "compile-raffle": "bun ./src/bin/tealscript.ts examples/raffle/raffle.algo.ts examples/raffle/artifacts", + "compile-raffle": "bun ./src/bin/tealscript.ts examples/raffle/raffle.algo.ts examples/raffle/artifacts && algokitgen generate -a examples/raffle/artifacts/NFTRaffle.arc32.json -o examples/raffle/NFTRaffleClient.ts && algokitgen generate -a examples/raffle/artifacts/MockVRFBeacon.arc32.json -o examples/raffle/MockVRFBeaconClient.ts", "run-merkle": "bun examples/merkle/demo.ts", "run-tuple_in_box": "bun ./examples/tuple_in_box/client.ts", "run-itxns": "bun examples/itxns/demo.ts", From 8e95850b13d5f1eae7e94853893210c39bd104cd Mon Sep 17 00:00:00 2001 From: Joe Polny Date: Wed, 6 Dec 2023 08:57:14 -0500 Subject: [PATCH 4/4] compile raffle with latest compiler --- examples/raffle/MockVRFBeaconClient.ts | 2 +- examples/raffle/NFTRaffleClient.ts | 2 +- .../artifacts/MockVRFBeacon.approval.teal | 2 +- .../raffle/artifacts/MockVRFBeacon.arc32.json | 2 +- .../raffle/artifacts/NFTRaffle.approval.teal | 84 +- .../raffle/artifacts/NFTRaffle.arc32.json | 2 +- .../raffle/artifacts/NFTRaffle.src_map.json | 1005 ++++++++--------- examples/raffle/raffle.algo.ts | 2 +- src/lib/compiler.ts | 9 +- 9 files changed, 542 insertions(+), 568 deletions(-) diff --git a/examples/raffle/MockVRFBeaconClient.ts b/examples/raffle/MockVRFBeaconClient.ts index ff271af32..e027d6176 100644 --- a/examples/raffle/MockVRFBeaconClient.ts +++ b/examples/raffle/MockVRFBeaconClient.ts @@ -66,7 +66,7 @@ export const APP_SPEC: AppSpec = { } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIG11c3RfZ2V0KGJ5dGVzLHVpbnQ2NClieXRlW10KYWJpX3JvdXRlX211c3RfZ2V0OgoJLy8gZGF0YTogYnl0ZVtdCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglleHRyYWN0IDIgMAoKCS8vIF9yb3VuZDogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gZXhlY3V0ZSBtdXN0X2dldChieXRlcyx1aW50NjQpYnl0ZVtdCgljYWxsc3ViIG11c3RfZ2V0CglpbnQgMQoJcmV0dXJuCgptdXN0X2dldDoKCXByb3RvIDIgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoyMDAKCS8vIHJldHVybiBzaGEyNTYoZGF0YSArIGl0b2IoZ2xvYmFscy5yb3VuZCkpIGFzIGJ5dGVzOwoJZnJhbWVfZGlnIC0yIC8vIGRhdGE6IGJ5dGVzCglnbG9iYWwgUm91bmQKCWl0b2IKCWNvbmNhdAoJc2hhMjU2CglkdXAKCWxlbgoJaXRvYgoJZXh0cmFjdCA2IDIKCXN3YXAKCWNvbmNhdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgphYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb246CglpbnQgMQoJcmV0dXJuCgpjcmVhdGVfTm9PcDoKCW1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24oKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9tdXN0X2dldAoJZXJy", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjUuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIG11c3RfZ2V0KGJ5dGVzLHVpbnQ2NClieXRlW10KYWJpX3JvdXRlX211c3RfZ2V0OgoJLy8gZGF0YTogYnl0ZVtdCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglleHRyYWN0IDIgMAoKCS8vIF9yb3VuZDogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gZXhlY3V0ZSBtdXN0X2dldChieXRlcyx1aW50NjQpYnl0ZVtdCgljYWxsc3ViIG11c3RfZ2V0CglpbnQgMQoJcmV0dXJuCgptdXN0X2dldDoKCXByb3RvIDIgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoyMDAKCS8vIHJldHVybiBzaGEyNTYoZGF0YSArIGl0b2IoZ2xvYmFscy5yb3VuZCkpIGFzIGJ5dGVzOwoJZnJhbWVfZGlnIC0yIC8vIGRhdGE6IGJ5dGVzCglnbG9iYWwgUm91bmQKCWl0b2IKCWNvbmNhdAoJc2hhMjU2CglkdXAKCWxlbgoJaXRvYgoJZXh0cmFjdCA2IDIKCXN3YXAKCWNvbmNhdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgphYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb246CglpbnQgMQoJcmV0dXJuCgpjcmVhdGVfTm9PcDoKCW1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24oKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9tdXN0X2dldAoJZXJy", "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" }, "contract": { diff --git a/examples/raffle/NFTRaffleClient.ts b/examples/raffle/NFTRaffleClient.ts index 8018d3cb0..01fe94155 100644 --- a/examples/raffle/NFTRaffleClient.ts +++ b/examples/raffle/NFTRaffleClient.ts @@ -124,7 +124,7 @@ export const APP_SPEC: AppSpec = { } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAovLwovLyBDcmVhdGUgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gdGlja2V0UHJpY2UgVGhlIHByaWNlIG9mIGEgc2luZ2xlIHRpY2tldCAodUFMR08pCi8vIEBwYXJhbSByYW5kb21uZXNzT3JhY2xlIFRoZSBhcHAgSUQgb2YgdGhlIHJhbmRvbW5lc3Mgb3JhY2xlCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIHJhbmRvbW5lc3NPcmFjbGU6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIHRpY2tldFByaWNlOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBjcmVhdGVBcHBsaWNhdGlvbgoJaW50IDEKCXJldHVybgoKY3JlYXRlQXBwbGljYXRpb246Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NDMKCS8vIHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSA9IHJhbmRvbW5lc3NPcmFjbGUKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQ0CgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWZyYW1lX2RpZyAtMSAvLyB0aWNrZXRQcmljZTogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzZXRBc3NldChhc3NldCl2b2lkCi8vCi8vIFNldCB0aGUgYXNzZXQgdG8gYmUgcmFmZmxlZAovLwovLyBAcGFyYW0gYXNzZXQgVGhlIGFzc2V0IHRvIGJlIHJhZmZsZWQKYWJpX3JvdXRlX3NldEFzc2V0OgoJLy8gYXNzZXQ6IGFzc2V0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCgkvLyBleGVjdXRlIHNldEFzc2V0KGFzc2V0KXZvaWQKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU0CgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiBhc3NldCwKCS8vICAgICAgIGFzc2V0QW1vdW50OiAwLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTcKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMuYXBwLmFkZHJlc3MKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTgKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU5CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NjAKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo2MwoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglmcmFtZV9kaWcgLTEgLy8gYXNzZXQ6IGFzc2V0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKLy8KLy8gU3RhcnQgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gZW5kIFRoZSByb3VuZCBudW1iZXIgd2hlbiB0aGUgcmFmZmxlIGVuZHMKLy8gQHBhcmFtIGRyYXcgVGhlIHJvdW5kIG51bWJlciB3aGVuIHRoZSByYWZmbGUgaXMgZHJhd24KYWJpX3JvdXRlX3N0YXJ0UmFmZmxlOgoJLy8gZHJhdzogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgoJLy8gZW5kOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBheGZlcjogYXhmZXIKCXR4biBHcm91cEluZGV4CglpbnQgMQoJLQoJZHVwCglndHhucyBUeXBlRW51bQoJaW50IGF4ZmVyCgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKCWNhbGxzdWIgc3RhcnRSYWZmbGUKCWludCAxCglyZXR1cm4KCnN0YXJ0UmFmZmxlOgoJcHJvdG8gMyAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc0CgkvLyB2ZXJpZnlUeG4oYXhmZXIsIHsKCS8vICAgICAgIGFzc2V0QW1vdW50OiB7IGdyZWF0ZXJUaGFuOiAwIH0sCgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlLAoJLy8gICAgIH0pCgkvLyB2ZXJpZnkgYXNzZXRBbW91bnQKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0QW1vdW50CglpbnQgMAoJPgoJYXNzZXJ0CgoJLy8gdmVyaWZ5IGFzc2V0UmVjZWl2ZXIKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0UmVjZWl2ZXIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHhmZXJBc3NldAoJZnJhbWVfZGlnIC0xIC8vIGF4ZmVyOiBheGZlcgoJZ3R4bnMgWGZlckFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MAoJLy8gYXNzZXJ0KGRyYXcgPiBlbmQpCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gZW5kOiB1aW50NjQKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MQoJLy8gdGhpcy5lbmRSb3VuZC52YWx1ZSA9IGVuZAoJYnl0ZSAweDY1NmU2NDUyNmY3NTZlNjQgLy8gImVuZFJvdW5kIgoJZnJhbWVfZGlnIC0yIC8vIGVuZDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MgoJLy8gdGhpcy5kcmF3Um91bmQudmFsdWUgPSBkcmF3CglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAovLwovLyBCdXkgdGlja2V0cy4gTm90ZSB0aGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlIQovLyBJdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBhbGxvdyBtdWx0aXBsZSBwdXJjaGFzZXMsIGJ1dAovLyBmb3Igc2ltcGxpY2l0eSwgb25seSBvbmUgcHVyY2hhc2UgaXMgYWxsb3dlZC4KLy8KLy8gQHBhcmFtIHBheW1lbnQgVGhlIHBheW1lbnQgZm9yIHRoZSB0aWNrZXRzCi8vIEBwYXJhbSBxdWFuaXR5IFRoZSBudW1iZXIgb2YgdGlja2V0cyB0byBidXkKLy8KLy8gQHJldHVybnMgVGhlIHRvdGFsIG51bWJlciBvZiB0aWNrZXRzIG93bmVkIGJ5IHRoZSBzZW5kZXIKYWJpX3JvdXRlX2J1eVRpY2tldHM6CglieXRlIDB4OyBkdXBuIDIgLy8gcHVzaCBlbXB0eSBieXRlcyB0byBmaWxsIHRoZSBzdGFjayBmcmFtZSBmb3IgdGhpcyBzdWJyb3V0aW5lJ3MgbG9jYWwgdmFyaWFibGVzCgoJLy8gcXVhbnRpdHk6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoKCS8vIHBheW1lbnQ6IHBheQoJdHhuIEdyb3VwSW5kZXgKCWludCAxCgktCglkdXAKCWd0eG5zIFR5cGVFbnVtCglpbnQgcGF5Cgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAoJY2FsbHN1YiBidXlUaWNrZXRzCglpbnQgMQoJcmV0dXJuCgpidXlUaWNrZXRzOgoJcHJvdG8gNSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjk2CgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA8IHRoaXMuZW5kUm91bmQudmFsdWUpCglnbG9iYWwgUm91bmQKCWJ5dGUgMHg2NTZlNjQ1MjZmNzU2ZTY0IC8vICJlbmRSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0Cgk8Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTcKCS8vIGFzc2VydChxdWFudGl0eSA+IDApCglmcmFtZV9kaWcgLTIgLy8gcXVhbnRpdHk6IHVpbnQ2NAoJaW50IDAKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5OQoJLy8gYXNzZXJ0KCF0aGlzLnRpY2tldHMocGF5bWVudC5zZW5kZXIpLmV4aXN0cykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJYm94X2xlbgoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAxCgkvLyBuZXdUb3RhbCA9IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlICsgcXVhbnRpdHkgKyAxCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCSsKCWludCAxCgkrCglmcmFtZV9idXJ5IC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAzCgkvLyBwcmVNQlIgPSB0aGlzLmFwcC5hZGRyZXNzLm1pbkJhbGFuY2UKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKCWFzc2VydAoJZnJhbWVfYnVyeSAtNCAvLyBwcmVNQlI6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDQKCS8vIHRoaXMudGlja2V0cyhwYXltZW50LnNlbmRlcikudmFsdWUgPSB7IHN0YXJ0OiB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSwgZW5kOiBuZXdUb3RhbCAtIDEgfQoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJZnJhbWVfZGlnIC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCWludCAxCgktCglpdG9iCgljb25jYXQKCWJveF9wdXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTA1CgkvLyBtYnJEZWx0YSA9IHRoaXMuYXBwLmFkZHJlc3MubWluQmFsYW5jZSAtIHByZU1CUgoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCWFjY3RfcGFyYW1zX2dldCBBY2N0TWluQmFsYW5jZQoJYXNzZXJ0CglmcmFtZV9kaWcgLTQgLy8gcHJlTUJSOiB1aW50NjQKCS0KCWZyYW1lX2J1cnkgLTUgLy8gbWJyRGVsdGE6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDcKCS8vIHZlcmlmeVR4bihwYXltZW50LCB7CgkvLyAgICAgICBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiBxdWFudGl0eSArIG1ickRlbHRhLAoJLy8gICAgICAgc2VuZGVyOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICByZWNlaXZlcjogdGhpcy5hcHAuYWRkcmVzcywKCS8vICAgICB9KQoJLy8gdmVyaWZ5IGFtb3VudAoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgQW1vdW50CglieXRlIDB4NzQ2OTYzNmI2NTc0NTA3MjY5NjM2NSAvLyAidGlja2V0UHJpY2UiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCSoKCWZyYW1lX2RpZyAtNSAvLyBtYnJEZWx0YTogdWludDY0CgkrCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHNlbmRlcgoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCgl0eG4gU2VuZGVyCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHJlY2VpdmVyCglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBSZWNlaXZlcgoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCT09Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTEzCgkvLyB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSA9IG5ld1RvdGFsCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglmcmFtZV9kaWcgLTMgLy8gbmV3VG90YWw6IHVpbnQ2NAoJYXBwX2dsb2JhbF9wdXQKCXJldHN1YgoKZ2V0UmFuZG9tQnl0ZXM6Cglwcm90byAwIDAKCgkvLyBpZjBfY29uZGl0aW9uCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTE4CgkvLyB0aGlzLnJhbmRvbUJ5dGVzLmV4aXN0cwoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJYnogaWYwX2Vsc2UKCgkvLyBpZjBfY29uc2VxdWVudAoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExOQoJLy8gdGhpcy5yYW5kb21CeXRlcy52YWx1ZSA9IHNoYTI1Nih0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlKSBhcyBieXRlcwoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCXNoYTI1NgoJYXBwX2dsb2JhbF9wdXQKCWIgaWYwX2VuZAoKaWYwX2Vsc2U6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTIxCgkvLyB0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlID0gc2VuZE1ldGhvZENhbGw8W3VpbnQ2NCwgYnl0ZXNdLCBieXRlcz4oewoJLy8gICAgICAgICBuYW1lOiAnbXVzdF9nZXQnLAoJLy8gICAgICAgICBtZXRob2RBcmdzOiBbdGhpcy5kcmF3Um91bmQudmFsdWUsICcnXSwKCS8vICAgICAgICAgYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSksCgkvLyAgICAgICAgIGZlZTogMCwKCS8vICAgICAgICAgb25Db21wbGV0aW9uOiAnTm9PcCcsCgkvLyAgICAgICB9KQoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJaXR4bl9iZWdpbgoJaW50IGFwcGwKCWl0eG5fZmllbGQgVHlwZUVudW0KCW1ldGhvZCAibXVzdF9nZXQodWludDY0LGJ5dGVbXSlieXRlW10iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjMKCS8vIG1ldGhvZEFyZ3M6IFt0aGlzLmRyYXdSb3VuZC52YWx1ZSwgJyddCglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKCWJ5dGUgMHgwMDAwCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjQKCS8vIGFwcGxpY2F0aW9uSUQ6IEFwcGxpY2F0aW9uLmZyb21JRCh0aGlzLnJhbmRvbW5lc3NPcmFjbGUudmFsdWUpCglieXRlIDB4NzI2MTZlNjQ2ZjZkNmU2NTczNzM0ZjcyNjE2MzZjNjUgLy8gInJhbmRvbW5lc3NPcmFjbGUiCglhcHBfZ2xvYmFsX2dldAoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbklECgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNQoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTI2CgkvLyBvbkNvbXBsZXRpb246ICdOb09wJwoJaW50IE5vT3AKCWl0eG5fZmllbGQgT25Db21wbGV0aW9uCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoJaXR4biBOdW1Mb2dzCglpbnQgMQoJLQoJaXR4bmFzIExvZ3MKCWV4dHJhY3QgNCAwCglhcHBfZ2xvYmFsX3B1dAoKaWYwX2VuZDoKCXJldHN1YgoKLy8gZHJhdyhhcHBsaWNhdGlvbilib29sCi8vCi8vIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFycwphYmlfcm91dGVfZHJhdzoKCWJ5dGUgMHg7IGR1cG4gMyAvLyBwdXNoIGVtcHR5IGJ5dGVzIHRvIGZpbGwgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIHN1YnJvdXRpbmUncyBsb2NhbCB2YXJpYWJsZXMKCgkvLyBfb3JhY2xlUmVmZXJlbmNlOiBhcHBsaWNhdGlvbgoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoJdHhuYXMgQXBwbGljYXRpb25zCgoJLy8gZXhlY3V0ZSBkcmF3KGFwcGxpY2F0aW9uKWJvb2wKCWNhbGxzdWIgZHJhdwoJaW50IDEKCXJldHVybgoKZHJhdzoKCXByb3RvIDUgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzUKCS8vIGFzc2VydCghdGhpcy53aW5uaW5nVGlja2V0LmV4aXN0cykKCXR4bmEgQXBwbGljYXRpb25zIDAKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0X2V4Cglzd2FwCglwb3AKCSEKCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzYKCS8vIHRoaXMuZ2V0UmFuZG9tQnl0ZXMoKQoJY2FsbHN1YiBnZXRSYW5kb21CeXRlcwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNDAKCS8vIG4gPSB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZQoJYnl0ZSAweDc0NmY3NDYxNmM1NDY5NjM2YjY1NzQ3MyAvLyAidG90YWxUaWNrZXRzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2J1cnkgLTIgLy8gbjogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0MgoJLy8gb2Zmc2V0ID0gMAoJaW50IDAKCWZyYW1lX2J1cnkgLTQgLy8gb2Zmc2V0OiB1aW50NjQKCmRvX3doaWxlXzA6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTQ2CgkvLyB4ID0gZXh0cmFjdF91aW50NjQodGhpcy5yYW5kb21CeXRlcy52YWx1ZSwgb2Zmc2V0KQoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtNCAvLyBvZmZzZXQ6IHVpbnQ2NAoJZXh0cmFjdF91aW50NjQKCWZyYW1lX2J1cnkgLTMgLy8geDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0OAoJLy8gb2Zmc2V0ID0gb2Zmc2V0ICsgOAoJZnJhbWVfZGlnIC00IC8vIG9mZnNldDogdWludDY0CglpbnQgOAoJKwoJZnJhbWVfYnVyeSAtNCAvLyBvZmZzZXQ6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTAKCS8vIG1heENvbmRpdGlvbiA9IHggPiBSQU5EX01BWCAtICgoKFJBTkRfTUFYICUgbikgKyAxKSAlIG4pCglmcmFtZV9kaWcgLTMgLy8geDogdWludDY0CglpbnQgMThfNDQ2Xzc0NF8wNzNfNzA5XzU1MV82MTUKCWludCAxOF80NDZfNzQ0XzA3M183MDlfNTUxXzYxNQoJZnJhbWVfZGlnIC0yIC8vIG46IHVpbnQ2NAoJJQoJaW50IDEKCSsKCWZyYW1lX2RpZyAtMiAvLyBuOiB1aW50NjQKCSUKCS0KCT4KCWZyYW1lX2J1cnkgLTUgLy8gbWF4Q29uZGl0aW9uOiBib29sCglmcmFtZV9kaWcgLTUgLy8gbWF4Q29uZGl0aW9uOiBib29sCglkdXAKCWJ6IHNraXBfYW5kMAoJZnJhbWVfZGlnIC00IC8vIG9mZnNldDogdWludDY0CglpbnQgMzIKCTwKCSYmCgpza2lwX2FuZDA6CglibnogZG9fd2hpbGVfMAoKCS8vIGlmMV9jb25kaXRpb24KCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTMKCS8vIG1heENvbmRpdGlvbgoJZnJhbWVfZGlnIC01IC8vIG1heENvbmRpdGlvbjogYm9vbAoJYnogaWYxX2VuZAoKCS8vIGlmMV9jb25zZXF1ZW50CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyByZXR1cm4gZmFsc2U7CglpbnQgMAoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKaWYxX2VuZDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTUKCS8vIHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSA9IHggJSBuCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglmcmFtZV9kaWcgLTMgLy8geDogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gbjogdWludDY0CgklCglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTYKCS8vIHJldHVybiB0cnVlOwoJaW50IDEKCWJ5dGUgMHgwMAoJaW50IDAKCXVuY292ZXIgMgoJc2V0Yml0CglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCi8vIGNsYWltKCl2b2lkCi8vCi8vIFNlbmQgdGhlIGFzc2V0IHRvIHRoZSB0aGUgc2VuZGVyIGlmIHRoZXkgaGF2ZSB0aGUgd2lubmluZyB0aWNrZXQKYWJpX3JvdXRlX2NsYWltOgoJYnl0ZSAweCAvLyBwdXNoIGVtcHR5IGJ5dGVzIHRvIGZpbGwgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIHN1YnJvdXRpbmUncyBsb2NhbCB2YXJpYWJsZXMKCgkvLyBleGVjdXRlIGNsYWltKCl2b2lkCgljYWxsc3ViIGNsYWltCglpbnQgMQoJcmV0dXJuCgpjbGFpbToKCXByb3RvIDEgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjEKCS8vIHRpY2tldFJhbmdlID0gdGhpcy50aWNrZXRzKHRoaXMudHhuLnNlbmRlcikudmFsdWUKCXR4biBTZW5kZXIKCWZyYW1lX2J1cnkgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2MwoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLnN0YXJ0IDw9IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCWJveF9nZXQKCWFzc2VydAoJZXh0cmFjdCAwIDgKCWJ0b2kKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0Cgk8PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2NAoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLmVuZCA+PSB0aGlzLndpbm5pbmdUaWNrZXQudmFsdWUpCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgOCA4CglidG9pCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldAoJPj0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjYKCS8vIHNlbmRBc3NldFRyYW5zZmVyKHsKCS8vICAgICAgIGFzc2V0UmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIHhmZXJBc3NldDogdGhpcy5hc3NldC52YWx1ZSwKCS8vICAgICAgIGFzc2V0QW1vdW50OiB0aGlzLmFwcC5hZGRyZXNzLmFzc2V0QmFsYW5jZSh0aGlzLmFzc2V0LnZhbHVlKSwKCS8vICAgICAgIGFzc2V0Q2xvc2VUbzogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY3CgkvLyBhc3NldFJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRSZWNlaXZlcgoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjgKCS8vIHhmZXJBc3NldDogdGhpcy5hc3NldC52YWx1ZQoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2OQoJLy8gYXNzZXRBbW91bnQ6IHRoaXMuYXBwLmFkZHJlc3MuYXNzZXRCYWxhbmNlKHRoaXMuYXNzZXQudmFsdWUpCglnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQoJYXNzZXJ0CglpdHhuX2ZpZWxkIEFzc2V0QW1vdW50CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3MAoJLy8gYXNzZXRDbG9zZVRvOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRDbG9zZVRvCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3MQoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCi8vIGdldFJlZnVuZCgpdm9pZAovLwovLyBBbGxvd3MgcHVyY2hhc2VycyB0byBnZXQgYSByZWZ1bmQgaWYgdGhlIHdpbm5pbmcgdGlja2V0IGhhcyBub3QgYmVlbiBkcmF3bgovLyBhbmQgMTUxMiByb3VuZHMgaGF2ZSBwYXNzZWQgc2luY2UgdGhlIGRyYXcgcm91bmQsIG1lYW5pbmcgdGhlIG9yYWNsZSBubwovLyBsb25nZXIgaGFzIHRoZSBkYXRhIGZvciB0aGUgZHJhdyByb3VuZAphYmlfcm91dGVfZ2V0UmVmdW5kOgoJYnl0ZSAweDsgZHVwIC8vIHB1c2ggZW1wdHkgYnl0ZXMgdG8gZmlsbCB0aGUgc3RhY2sgZnJhbWUgZm9yIHRoaXMgc3Vicm91dGluZSdzIGxvY2FsIHZhcmlhYmxlcwoKCS8vIGV4ZWN1dGUgZ2V0UmVmdW5kKCl2b2lkCgljYWxsc3ViIGdldFJlZnVuZAoJaW50IDEKCXJldHVybgoKZ2V0UmVmdW5kOgoJcHJvdG8gMiAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4MQoJLy8gYXNzZXJ0KCF0aGlzLndpbm5pbmdUaWNrZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4MgoJLy8gYXNzZXJ0KGdsb2JhbHMucm91bmQgPiB0aGlzLmRyYXdSb3VuZC52YWx1ZSArIDE1MTIpCglnbG9iYWwgUm91bmQKCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpbnQgMTUxMgoJKwoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4NAoJLy8gdGlja2V0UmFuZ2UgPSB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS52YWx1ZQoJdHhuIFNlbmRlcgoJZnJhbWVfYnVyeSAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTg1CgkvLyB0aWNrZXRDb3VudCA9IHRpY2tldFJhbmdlLmVuZCAtIHRpY2tldFJhbmdlLnN0YXJ0ICsgMQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDggOAoJYnRvaQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDAgOAoJYnRvaQoJLQoJaW50IDEKCSsKCWZyYW1lX2J1cnkgLTIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxODcKCS8vIHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLmRlbGV0ZSgpCgl0eG4gU2VuZGVyCglib3hfZGVsCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4OQoJLy8gc2VuZFBheW1lbnQoewoJLy8gICAgICAgYW1vdW50OiB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogdGlja2V0Q291bnQsCgkvLyAgICAgICByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgcGF5CglpdHhuX2ZpZWxkIFR5cGVFbnVtCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MAoJLy8gYW1vdW50OiB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogdGlja2V0Q291bnQKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9kaWcgLTIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoJKgoJaXR4bl9maWVsZCBBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTkxCgkvLyByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIFJlY2VpdmVyCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MgoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCmNyZWF0ZV9Ob09wOgoJbWV0aG9kICJjcmVhdGVBcHBsaWNhdGlvbih1aW50NjQsdWludDY0KXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJzZXRBc3NldChhc3NldCl2b2lkIgoJbWV0aG9kICJzdGFydFJhZmZsZShheGZlcix1aW50NjQsdWludDY0KXZvaWQiCgltZXRob2QgImJ1eVRpY2tldHMocGF5LHVpbnQ2NCl2b2lkIgoJbWV0aG9kICJkcmF3KGFwcGxpY2F0aW9uKWJvb2wiCgltZXRob2QgImNsYWltKCl2b2lkIgoJbWV0aG9kICJnZXRSZWZ1bmQoKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc2V0QXNzZXQgYWJpX3JvdXRlX3N0YXJ0UmFmZmxlIGFiaV9yb3V0ZV9idXlUaWNrZXRzIGFiaV9yb3V0ZV9kcmF3IGFiaV9yb3V0ZV9jbGFpbSBhYmlfcm91dGVfZ2V0UmVmdW5kCgllcnI=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjUuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAovLwovLyBDcmVhdGUgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gdGlja2V0UHJpY2UgVGhlIHByaWNlIG9mIGEgc2luZ2xlIHRpY2tldCAodUFMR08pCi8vIEBwYXJhbSByYW5kb21uZXNzT3JhY2xlIFRoZSBhcHAgSUQgb2YgdGhlIHJhbmRvbW5lc3Mgb3JhY2xlCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIHJhbmRvbW5lc3NPcmFjbGU6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIHRpY2tldFByaWNlOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBjcmVhdGVBcHBsaWNhdGlvbgoJaW50IDEKCXJldHVybgoKY3JlYXRlQXBwbGljYXRpb246Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NDMKCS8vIHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSA9IHJhbmRvbW5lc3NPcmFjbGUKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQ0CgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWZyYW1lX2RpZyAtMSAvLyB0aWNrZXRQcmljZTogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzZXRBc3NldChhc3NldCl2b2lkCi8vCi8vIFNldCB0aGUgYXNzZXQgdG8gYmUgcmFmZmxlZAovLwovLyBAcGFyYW0gYXNzZXQgVGhlIGFzc2V0IHRvIGJlIHJhZmZsZWQKYWJpX3JvdXRlX3NldEFzc2V0OgoJLy8gYXNzZXQ6IGFzc2V0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCgkvLyBleGVjdXRlIHNldEFzc2V0KGFzc2V0KXZvaWQKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU0CgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiBhc3NldCwKCS8vICAgICAgIGFzc2V0QW1vdW50OiAwLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTcKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMuYXBwLmFkZHJlc3MKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTgKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU5CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NjAKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo2MwoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglmcmFtZV9kaWcgLTEgLy8gYXNzZXQ6IGFzc2V0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKLy8KLy8gU3RhcnQgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gZW5kIFRoZSByb3VuZCBudW1iZXIgd2hlbiB0aGUgcmFmZmxlIGVuZHMKLy8gQHBhcmFtIGRyYXcgVGhlIHJvdW5kIG51bWJlciB3aGVuIHRoZSByYWZmbGUgaXMgZHJhd24KYWJpX3JvdXRlX3N0YXJ0UmFmZmxlOgoJLy8gZHJhdzogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgoJLy8gZW5kOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBheGZlcjogYXhmZXIKCXR4biBHcm91cEluZGV4CglpbnQgMQoJLQoJZHVwCglndHhucyBUeXBlRW51bQoJaW50IGF4ZmVyCgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKCWNhbGxzdWIgc3RhcnRSYWZmbGUKCWludCAxCglyZXR1cm4KCnN0YXJ0UmFmZmxlOgoJcHJvdG8gMyAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc0CgkvLyB2ZXJpZnlUeG4oYXhmZXIsIHsKCS8vICAgICAgIGFzc2V0QW1vdW50OiB7IGdyZWF0ZXJUaGFuOiAwIH0sCgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlLAoJLy8gICAgIH0pCgkvLyB2ZXJpZnkgYXNzZXRBbW91bnQKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0QW1vdW50CglpbnQgMAoJPgoJYXNzZXJ0CgoJLy8gdmVyaWZ5IGFzc2V0UmVjZWl2ZXIKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0UmVjZWl2ZXIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHhmZXJBc3NldAoJZnJhbWVfZGlnIC0xIC8vIGF4ZmVyOiBheGZlcgoJZ3R4bnMgWGZlckFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MAoJLy8gYXNzZXJ0KGRyYXcgPiBlbmQpCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gZW5kOiB1aW50NjQKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MQoJLy8gdGhpcy5lbmRSb3VuZC52YWx1ZSA9IGVuZAoJYnl0ZSAweDY1NmU2NDUyNmY3NTZlNjQgLy8gImVuZFJvdW5kIgoJZnJhbWVfZGlnIC0yIC8vIGVuZDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MgoJLy8gdGhpcy5kcmF3Um91bmQudmFsdWUgPSBkcmF3CglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAovLwovLyBCdXkgdGlja2V0cy4gTm90ZSB0aGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlIQovLyBJdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBhbGxvdyBtdWx0aXBsZSBwdXJjaGFzZXMsIGJ1dAovLyBmb3Igc2ltcGxpY2l0eSwgb25seSBvbmUgcHVyY2hhc2UgaXMgYWxsb3dlZC4KLy8KLy8gQHBhcmFtIHBheW1lbnQgVGhlIHBheW1lbnQgZm9yIHRoZSB0aWNrZXRzCi8vIEBwYXJhbSBxdWFuaXR5IFRoZSBudW1iZXIgb2YgdGlja2V0cyB0byBidXkKLy8KLy8gQHJldHVybnMgVGhlIHRvdGFsIG51bWJlciBvZiB0aWNrZXRzIG93bmVkIGJ5IHRoZSBzZW5kZXIKYWJpX3JvdXRlX2J1eVRpY2tldHM6CgkvLyBxdWFudGl0eTogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gcGF5bWVudDogcGF5Cgl0eG4gR3JvdXBJbmRleAoJaW50IDEKCS0KCWR1cAoJZ3R4bnMgVHlwZUVudW0KCWludCBwYXkKCT09Cglhc3NlcnQKCgkvLyBleGVjdXRlIGJ1eVRpY2tldHModWludDY0LHBheSl2b2lkCgljYWxsc3ViIGJ1eVRpY2tldHMKCWludCAxCglyZXR1cm4KCmJ1eVRpY2tldHM6Cglwcm90byAyIDA7IGJ5dGUgMHg7IGR1cG4gMwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5NgoJLy8gYXNzZXJ0KGdsb2JhbHMucm91bmQgPCB0aGlzLmVuZFJvdW5kLnZhbHVlKQoJZ2xvYmFsIFJvdW5kCglieXRlIDB4NjU2ZTY0NTI2Zjc1NmU2NCAvLyAiZW5kUm91bmQiCglhcHBfZ2xvYmFsX2dldAoJPAoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjk3CgkvLyBhc3NlcnQocXVhbnRpdHkgPiAwKQoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCWludCAwCgk+Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTkKCS8vIGFzc2VydCghdGhpcy50aWNrZXRzKHBheW1lbnQuc2VuZGVyKS5leGlzdHMpCglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBTZW5kZXIKCWJveF9sZW4KCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwMQoJLy8gbmV3VG90YWwgPSB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSArIHF1YW50aXR5ICsgMQoJYnl0ZSAweDc0NmY3NDYxNmM1NDY5NjM2YjY1NzQ3MyAvLyAidG90YWxUaWNrZXRzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtMiAvLyBxdWFudGl0eTogdWludDY0CgkrCglpbnQgMQoJKwoJZnJhbWVfYnVyeSAxIC8vIG5ld1RvdGFsOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAzCgkvLyBwcmVNQlIgPSB0aGlzLmFwcC5hZGRyZXNzLm1pbkJhbGFuY2UKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKCWFzc2VydAoJZnJhbWVfYnVyeSAyIC8vIHByZU1CUjogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwNAoJLy8gdGhpcy50aWNrZXRzKHBheW1lbnQuc2VuZGVyKS52YWx1ZSA9IHsgc3RhcnQ6IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlLCBlbmQ6IG5ld1RvdGFsIC0gMSB9CglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBTZW5kZXIKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWFwcF9nbG9iYWxfZ2V0CglpdG9iCglmcmFtZV9kaWcgMSAvLyBuZXdUb3RhbDogdWludDY0CglpbnQgMQoJLQoJaXRvYgoJY29uY2F0Cglib3hfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwNQoJLy8gbWJyRGVsdGEgPSB0aGlzLmFwcC5hZGRyZXNzLm1pbkJhbGFuY2UgLSBwcmVNQlIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKCWFzc2VydAoJZnJhbWVfZGlnIDIgLy8gcHJlTUJSOiB1aW50NjQKCS0KCWZyYW1lX2J1cnkgMyAvLyBtYnJEZWx0YTogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwNwoJLy8gdmVyaWZ5VHhuKHBheW1lbnQsIHsKCS8vICAgICAgIGFtb3VudDogdGhpcy50aWNrZXRQcmljZS52YWx1ZSAqIHF1YW50aXR5ICsgbWJyRGVsdGEsCgkvLyAgICAgICBzZW5kZXI6IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIHJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgIH0pCgkvLyB2ZXJpZnkgYW1vdW50CglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBBbW91bnQKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9kaWcgLTIgLy8gcXVhbnRpdHk6IHVpbnQ2NAoJKgoJZnJhbWVfZGlnIDMgLy8gbWJyRGVsdGE6IHVpbnQ2NAoJKwoJPT0KCWFzc2VydAoKCS8vIHZlcmlmeSBzZW5kZXIKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJdHhuIFNlbmRlcgoJPT0KCWFzc2VydAoKCS8vIHZlcmlmeSByZWNlaXZlcgoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgUmVjZWl2ZXIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCgk9PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExMwoJLy8gdGhpcy50b3RhbFRpY2tldHMudmFsdWUgPSBuZXdUb3RhbAoJYnl0ZSAweDc0NmY3NDYxNmM1NDY5NjM2YjY1NzQ3MyAvLyAidG90YWxUaWNrZXRzIgoJZnJhbWVfZGlnIDEgLy8gbmV3VG90YWw6IHVpbnQ2NAoJYXBwX2dsb2JhbF9wdXQKCXJldHN1YgoKZ2V0UmFuZG9tQnl0ZXM6Cglwcm90byAwIDAKCgkvLyBpZjBfY29uZGl0aW9uCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTE4CgkvLyB0aGlzLnJhbmRvbUJ5dGVzLmV4aXN0cwoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJYnogaWYwX2Vsc2UKCgkvLyBpZjBfY29uc2VxdWVudAoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExOQoJLy8gdGhpcy5yYW5kb21CeXRlcy52YWx1ZSA9IHNoYTI1Nih0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlKSBhcyBieXRlcwoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCXNoYTI1NgoJYXBwX2dsb2JhbF9wdXQKCWIgaWYwX2VuZAoKaWYwX2Vsc2U6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTIxCgkvLyB0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlID0gc2VuZE1ldGhvZENhbGw8W3VpbnQ2NCwgYnl0ZXNdLCBieXRlcz4oewoJLy8gICAgICAgICBuYW1lOiAnbXVzdF9nZXQnLAoJLy8gICAgICAgICBtZXRob2RBcmdzOiBbdGhpcy5kcmF3Um91bmQudmFsdWUsICcnXSwKCS8vICAgICAgICAgYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSksCgkvLyAgICAgICAgIGZlZTogMCwKCS8vICAgICAgICAgb25Db21wbGV0aW9uOiBPbkNvbXBsZXRpb24uTm9PcCwKCS8vICAgICAgIH0pCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglpdHhuX2JlZ2luCglpbnQgYXBwbAoJaXR4bl9maWVsZCBUeXBlRW51bQoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCWl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyMwoJLy8gbWV0aG9kQXJnczogW3RoaXMuZHJhd1JvdW5kLnZhbHVlLCAnJ10KCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpdG9iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoJYnl0ZSAweDAwMDAKCWl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNAoJLy8gYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSkKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWFwcF9nbG9iYWxfZ2V0CglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uSUQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTI1CgkvLyBmZWU6IDAKCWludCAwCglpdHhuX2ZpZWxkIEZlZQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjYKCS8vIG9uQ29tcGxldGlvbjogT25Db21wbGV0aW9uLk5vT3AKCWludCAwIC8vIE5vT3AKCWl0eG5fZmllbGQgT25Db21wbGV0aW9uCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoJaXR4biBOdW1Mb2dzCglpbnQgMQoJLQoJaXR4bmFzIExvZ3MKCWV4dHJhY3QgNCAwCglhcHBfZ2xvYmFsX3B1dAoKaWYwX2VuZDoKCXJldHN1YgoKLy8gZHJhdyhhcHBsaWNhdGlvbilib29sCi8vCi8vIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFycwphYmlfcm91dGVfZHJhdzoKCS8vIF9vcmFjbGVSZWZlcmVuY2U6IGFwcGxpY2F0aW9uCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBcHBsaWNhdGlvbnMKCgkvLyBleGVjdXRlIGRyYXcoYXBwbGljYXRpb24pYm9vbAoJY2FsbHN1YiBkcmF3CglpbnQgMQoJcmV0dXJuCgpkcmF3OgoJcHJvdG8gMSAwOyBieXRlIDB4OyBkdXBuIDQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTM1CgkvLyBhc3NlcnQoIXRoaXMud2lubmluZ1RpY2tldC5leGlzdHMpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTM2CgkvLyB0aGlzLmdldFJhbmRvbUJ5dGVzKCkKCWNhbGxzdWIgZ2V0UmFuZG9tQnl0ZXMKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTQwCgkvLyBuID0gdGhpcy50b3RhbFRpY2tldHMudmFsdWUKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9idXJ5IDEgLy8gbjogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0MgoJLy8gb2Zmc2V0ID0gMAoJaW50IDAKCWZyYW1lX2J1cnkgMyAvLyBvZmZzZXQ6IHVpbnQ2NAoKZG9fd2hpbGVfMDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNDYKCS8vIHggPSBleHRyYWN0X3VpbnQ2NCh0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlLCBvZmZzZXQpCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIDMgLy8gb2Zmc2V0OiB1aW50NjQKCWV4dHJhY3RfdWludDY0CglmcmFtZV9idXJ5IDIgLy8geDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0OAoJLy8gb2Zmc2V0ID0gb2Zmc2V0ICsgOAoJZnJhbWVfZGlnIDMgLy8gb2Zmc2V0OiB1aW50NjQKCWludCA4CgkrCglmcmFtZV9idXJ5IDMgLy8gb2Zmc2V0OiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUwCgkvLyBtYXhDb25kaXRpb24gPSB4ID4gUkFORF9NQVggLSAoKChSQU5EX01BWCAlIG4pICsgMSkgJSBuKQoJZnJhbWVfZGlnIDIgLy8geDogdWludDY0CglpbnQgMThfNDQ2Xzc0NF8wNzNfNzA5XzU1MV82MTUKCWludCAxOF80NDZfNzQ0XzA3M183MDlfNTUxXzYxNQoJZnJhbWVfZGlnIDEgLy8gbjogdWludDY0CgklCglpbnQgMQoJKwoJZnJhbWVfZGlnIDEgLy8gbjogdWludDY0CgklCgktCgk+CglmcmFtZV9idXJ5IDQgLy8gbWF4Q29uZGl0aW9uOiBib29sCglmcmFtZV9kaWcgNCAvLyBtYXhDb25kaXRpb246IGJvb2wKCWR1cAoJYnogc2tpcF9hbmQwCglmcmFtZV9kaWcgMyAvLyBvZmZzZXQ6IHVpbnQ2NAoJaW50IDMyCgk8CgkmJgoKc2tpcF9hbmQwOgoJYm56IGRvX3doaWxlXzAKCgkvLyBpZjFfY29uZGl0aW9uCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyBtYXhDb25kaXRpb24KCWZyYW1lX2RpZyA0IC8vIG1heENvbmRpdGlvbjogYm9vbAoJYnogaWYxX2VuZAoKCS8vIGlmMV9jb25zZXF1ZW50CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyByZXR1cm4gZmFsc2U7CglpbnQgMAoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKaWYxX2VuZDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTUKCS8vIHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSA9IHggJSBuCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglmcmFtZV9kaWcgMiAvLyB4OiB1aW50NjQKCWZyYW1lX2RpZyAxIC8vIG46IHVpbnQ2NAoJJQoJYXBwX2dsb2JhbF9wdXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTU2CgkvLyByZXR1cm4gdHJ1ZTsKCWludCAxCglieXRlIDB4MDAKCWludCAwCgl1bmNvdmVyIDIKCXNldGJpdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgovLyBjbGFpbSgpdm9pZAovLwovLyBTZW5kIHRoZSBhc3NldCB0byB0aGUgdGhlIHNlbmRlciBpZiB0aGV5IGhhdmUgdGhlIHdpbm5pbmcgdGlja2V0CmFiaV9yb3V0ZV9jbGFpbToKCS8vIGV4ZWN1dGUgY2xhaW0oKXZvaWQKCWNhbGxzdWIgY2xhaW0KCWludCAxCglyZXR1cm4KCmNsYWltOgoJcHJvdG8gMCAwOyBieXRlIDB4OyBkdXBuIDEKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTYxCgkvLyB0aWNrZXRSYW5nZSA9IHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLnZhbHVlCgl0eG4gU2VuZGVyCglmcmFtZV9idXJ5IDEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2MwoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLnN0YXJ0IDw9IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAxIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDAgOAoJYnRvaQoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXQKCTw9Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY0CgkvLyBhc3NlcnQodGlja2V0UmFuZ2UuZW5kID49IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAxIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDggOAoJYnRvaQoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXQKCT49Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICB4ZmVyQXNzZXQ6IHRoaXMuYXNzZXQudmFsdWUsCgkvLyAgICAgICBhc3NldEFtb3VudDogdGhpcy5hcHAuYWRkcmVzcy5hc3NldEJhbGFuY2UodGhpcy5hc3NldC52YWx1ZSksCgkvLyAgICAgICBhc3NldENsb3NlVG86IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIGZlZTogMCwKCS8vICAgICB9KQoJaXR4bl9iZWdpbgoJaW50IGF4ZmVyCglpdHhuX2ZpZWxkIFR5cGVFbnVtCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2NwoJLy8gYXNzZXRSZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY4CgkvLyB4ZmVyQXNzZXQ6IHRoaXMuYXNzZXQudmFsdWUKCWJ5dGUgMHg2MTczNzM2NTc0IC8vICJhc3NldCIKCWFwcF9nbG9iYWxfZ2V0CglpdHhuX2ZpZWxkIFhmZXJBc3NldAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjkKCS8vIGFzc2V0QW1vdW50OiB0aGlzLmFwcC5hZGRyZXNzLmFzc2V0QmFsYW5jZSh0aGlzLmFzc2V0LnZhbHVlKQoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCWJ5dGUgMHg2MTczNzM2NTc0IC8vICJhc3NldCIKCWFwcF9nbG9iYWxfZ2V0Cglhc3NldF9ob2xkaW5nX2dldCBBc3NldEJhbGFuY2UKCWFzc2VydAoJaXR4bl9maWVsZCBBc3NldEFtb3VudAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNzAKCS8vIGFzc2V0Q2xvc2VUbzogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIEFzc2V0Q2xvc2VUbwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNzEKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoJcmV0c3ViCgovLyBnZXRSZWZ1bmQoKXZvaWQKLy8KLy8gQWxsb3dzIHB1cmNoYXNlcnMgdG8gZ2V0IGEgcmVmdW5kIGlmIHRoZSB3aW5uaW5nIHRpY2tldCBoYXMgbm90IGJlZW4gZHJhd24KLy8gYW5kIDE1MTIgcm91bmRzIGhhdmUgcGFzc2VkIHNpbmNlIHRoZSBkcmF3IHJvdW5kLCBtZWFuaW5nIHRoZSBvcmFjbGUgbm8KLy8gbG9uZ2VyIGhhcyB0aGUgZGF0YSBmb3IgdGhlIGRyYXcgcm91bmQKYWJpX3JvdXRlX2dldFJlZnVuZDoKCS8vIGV4ZWN1dGUgZ2V0UmVmdW5kKCl2b2lkCgljYWxsc3ViIGdldFJlZnVuZAoJaW50IDEKCXJldHVybgoKZ2V0UmVmdW5kOgoJcHJvdG8gMCAwOyBieXRlIDB4OyBkdXBuIDIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTgxCgkvLyBhc3NlcnQoIXRoaXMud2lubmluZ1RpY2tldC5leGlzdHMpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTgyCgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA+IHRoaXMuZHJhd1JvdW5kLnZhbHVlICsgMTUxMikKCWdsb2JhbCBSb3VuZAoJYnl0ZSAweDY0NzI2MTc3NTI2Zjc1NmU2NCAvLyAiZHJhd1JvdW5kIgoJYXBwX2dsb2JhbF9nZXQKCWludCAxNTEyCgkrCgk+Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTg0CgkvLyB0aWNrZXRSYW5nZSA9IHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLnZhbHVlCgl0eG4gU2VuZGVyCglmcmFtZV9idXJ5IDEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4NQoJLy8gdGlja2V0Q291bnQgPSB0aWNrZXRSYW5nZS5lbmQgLSB0aWNrZXRSYW5nZS5zdGFydCArIDEKCWZyYW1lX2RpZyAxIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDggOAoJYnRvaQoJZnJhbWVfZGlnIDEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgMCA4CglidG9pCgktCglpbnQgMQoJKwoJZnJhbWVfYnVyeSAyIC8vIHRpY2tldENvdW50OiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTg3CgkvLyB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS5kZWxldGUoKQoJdHhuIFNlbmRlcgoJYm94X2RlbAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxODkKCS8vIHNlbmRQYXltZW50KHsKCS8vICAgICAgIGFtb3VudDogdGhpcy50aWNrZXRQcmljZS52YWx1ZSAqIHRpY2tldENvdW50LAoJLy8gICAgICAgcmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIGZlZTogMCwKCS8vICAgICB9KQoJaXR4bl9iZWdpbgoJaW50IHBheQoJaXR4bl9maWVsZCBUeXBlRW51bQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxOTAKCS8vIGFtb3VudDogdGhpcy50aWNrZXRQcmljZS52YWx1ZSAqIHRpY2tldENvdW50CglieXRlIDB4NzQ2OTYzNmI2NTc0NTA3MjY5NjM2NSAvLyAidGlja2V0UHJpY2UiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIDIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoJKgoJaXR4bl9maWVsZCBBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTkxCgkvLyByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIFJlY2VpdmVyCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MgoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCmNyZWF0ZV9Ob09wOgoJbWV0aG9kICJjcmVhdGVBcHBsaWNhdGlvbih1aW50NjQsdWludDY0KXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJzZXRBc3NldChhc3NldCl2b2lkIgoJbWV0aG9kICJzdGFydFJhZmZsZShheGZlcix1aW50NjQsdWludDY0KXZvaWQiCgltZXRob2QgImJ1eVRpY2tldHMocGF5LHVpbnQ2NCl2b2lkIgoJbWV0aG9kICJkcmF3KGFwcGxpY2F0aW9uKWJvb2wiCgltZXRob2QgImNsYWltKCl2b2lkIgoJbWV0aG9kICJnZXRSZWZ1bmQoKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc2V0QXNzZXQgYWJpX3JvdXRlX3N0YXJ0UmFmZmxlIGFiaV9yb3V0ZV9idXlUaWNrZXRzIGFiaV9yb3V0ZV9kcmF3IGFiaV9yb3V0ZV9jbGFpbSBhYmlfcm91dGVfZ2V0UmVmdW5kCgllcnI=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" }, "contract": { diff --git a/examples/raffle/artifacts/MockVRFBeacon.approval.teal b/examples/raffle/artifacts/MockVRFBeacon.approval.teal index a6e93f8f1..b4c4be579 100644 --- a/examples/raffle/artifacts/MockVRFBeacon.approval.teal +++ b/examples/raffle/artifacts/MockVRFBeacon.approval.teal @@ -1,6 +1,6 @@ #pragma version 9 -// This TEAL was generated by TEALScript v0.63.0 +// This TEAL was generated by TEALScript v0.65.0 // https://github.com/algorandfoundation/TEALScript // This contract is compliant with and/or implements the following ARCs: [ ARC4 ] diff --git a/examples/raffle/artifacts/MockVRFBeacon.arc32.json b/examples/raffle/artifacts/MockVRFBeacon.arc32.json index c618a05f8..16cebda37 100644 --- a/examples/raffle/artifacts/MockVRFBeacon.arc32.json +++ b/examples/raffle/artifacts/MockVRFBeacon.arc32.json @@ -39,7 +39,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIG11c3RfZ2V0KGJ5dGVzLHVpbnQ2NClieXRlW10KYWJpX3JvdXRlX211c3RfZ2V0OgoJLy8gZGF0YTogYnl0ZVtdCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglleHRyYWN0IDIgMAoKCS8vIF9yb3VuZDogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gZXhlY3V0ZSBtdXN0X2dldChieXRlcyx1aW50NjQpYnl0ZVtdCgljYWxsc3ViIG11c3RfZ2V0CglpbnQgMQoJcmV0dXJuCgptdXN0X2dldDoKCXByb3RvIDIgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoyMDAKCS8vIHJldHVybiBzaGEyNTYoZGF0YSArIGl0b2IoZ2xvYmFscy5yb3VuZCkpIGFzIGJ5dGVzOwoJZnJhbWVfZGlnIC0yIC8vIGRhdGE6IGJ5dGVzCglnbG9iYWwgUm91bmQKCWl0b2IKCWNvbmNhdAoJc2hhMjU2CglkdXAKCWxlbgoJaXRvYgoJZXh0cmFjdCA2IDIKCXN3YXAKCWNvbmNhdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgphYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb246CglpbnQgMQoJcmV0dXJuCgpjcmVhdGVfTm9PcDoKCW1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24oKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9tdXN0X2dldAoJZXJy", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjUuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIG11c3RfZ2V0KGJ5dGVzLHVpbnQ2NClieXRlW10KYWJpX3JvdXRlX211c3RfZ2V0OgoJLy8gZGF0YTogYnl0ZVtdCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglleHRyYWN0IDIgMAoKCS8vIF9yb3VuZDogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gZXhlY3V0ZSBtdXN0X2dldChieXRlcyx1aW50NjQpYnl0ZVtdCgljYWxsc3ViIG11c3RfZ2V0CglpbnQgMQoJcmV0dXJuCgptdXN0X2dldDoKCXByb3RvIDIgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoyMDAKCS8vIHJldHVybiBzaGEyNTYoZGF0YSArIGl0b2IoZ2xvYmFscy5yb3VuZCkpIGFzIGJ5dGVzOwoJZnJhbWVfZGlnIC0yIC8vIGRhdGE6IGJ5dGVzCglnbG9iYWwgUm91bmQKCWl0b2IKCWNvbmNhdAoJc2hhMjU2CglkdXAKCWxlbgoJaXRvYgoJZXh0cmFjdCA2IDIKCXN3YXAKCWNvbmNhdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgphYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb246CglpbnQgMQoJcmV0dXJuCgpjcmVhdGVfTm9PcDoKCW1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24oKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoIGFiaV9yb3V0ZV9tdXN0X2dldAoJZXJy", "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" }, "contract": { diff --git a/examples/raffle/artifacts/NFTRaffle.approval.teal b/examples/raffle/artifacts/NFTRaffle.approval.teal index 023f90de4..f1fda33d7 100644 --- a/examples/raffle/artifacts/NFTRaffle.approval.teal +++ b/examples/raffle/artifacts/NFTRaffle.approval.teal @@ -1,6 +1,6 @@ #pragma version 9 -// This TEAL was generated by TEALScript v0.63.0 +// This TEAL was generated by TEALScript v0.65.0 // https://github.com/algorandfoundation/TEALScript // This contract is compliant with and/or implements the following ARCs: [ ARC4 ] @@ -220,8 +220,6 @@ startRaffle: // // @returns The total number of tickets owned by the sender abi_route_buyTickets: - byte 0x; dupn 2 // push empty bytes to fill the stack frame for this subroutine's local variables - // quantity: uint64 txna ApplicationArgs 1 btoi @@ -242,7 +240,7 @@ abi_route_buyTickets: return buyTickets: - proto 5 0 + proto 2 0; byte 0x; dupn 3 // examples/raffle/raffle.algo.ts:96 // assert(globals.round < this.endRound.value) @@ -277,14 +275,14 @@ buyTickets: + int 1 + - frame_bury -3 // newTotal: uint64 + frame_bury 1 // newTotal: uint64 // examples/raffle/raffle.algo.ts:103 // preMBR = this.app.address.minBalance global CurrentApplicationAddress acct_params_get AcctMinBalance assert - frame_bury -4 // preMBR: uint64 + frame_bury 2 // preMBR: uint64 // examples/raffle/raffle.algo.ts:104 // this.tickets(payment.sender).value = { start: this.totalTickets.value, end: newTotal - 1 } @@ -293,7 +291,7 @@ buyTickets: byte 0x746f74616c5469636b657473 // "totalTickets" app_global_get itob - frame_dig -3 // newTotal: uint64 + frame_dig 1 // newTotal: uint64 int 1 - itob @@ -305,9 +303,9 @@ buyTickets: global CurrentApplicationAddress acct_params_get AcctMinBalance assert - frame_dig -4 // preMBR: uint64 + frame_dig 2 // preMBR: uint64 - - frame_bury -5 // mbrDelta: uint64 + frame_bury 3 // mbrDelta: uint64 // examples/raffle/raffle.algo.ts:107 // verifyTxn(payment, { @@ -322,7 +320,7 @@ buyTickets: app_global_get frame_dig -2 // quantity: uint64 * - frame_dig -5 // mbrDelta: uint64 + frame_dig 3 // mbrDelta: uint64 + == assert @@ -344,7 +342,7 @@ buyTickets: // examples/raffle/raffle.algo.ts:113 // this.totalTickets.value = newTotal byte 0x746f74616c5469636b657473 // "totalTickets" - frame_dig -3 // newTotal: uint64 + frame_dig 1 // newTotal: uint64 app_global_put retsub @@ -378,7 +376,7 @@ if0_else: // methodArgs: [this.drawRound.value, ''], // applicationID: Application.fromID(this.randomnessOracle.value), // fee: 0, - // onCompletion: 'NoOp', + // onCompletion: OnCompletion.NoOp, // }) byte 0x72616e646f6d4279746573 // "randomBytes" itxn_begin @@ -408,8 +406,8 @@ if0_else: itxn_field Fee // examples/raffle/raffle.algo.ts:126 - // onCompletion: 'NoOp' - int NoOp + // onCompletion: OnCompletion.NoOp + int 0 // NoOp itxn_field OnCompletion // Submit inner transaction @@ -428,8 +426,6 @@ if0_end: // // // eslint-disable-next-line no-unused-vars abi_route_draw: - byte 0x; dupn 3 // push empty bytes to fill the stack frame for this subroutine's local variables - // _oracleReference: application txna ApplicationArgs 1 btoi @@ -441,7 +437,7 @@ abi_route_draw: return draw: - proto 5 0 + proto 1 0; byte 0x; dupn 4 // examples/raffle/raffle.algo.ts:135 // assert(!this.winningTicket.exists) @@ -461,47 +457,47 @@ draw: // n = this.totalTickets.value byte 0x746f74616c5469636b657473 // "totalTickets" app_global_get - frame_bury -2 // n: uint64 + frame_bury 1 // n: uint64 // examples/raffle/raffle.algo.ts:142 // offset = 0 int 0 - frame_bury -4 // offset: uint64 + frame_bury 3 // offset: uint64 do_while_0: // examples/raffle/raffle.algo.ts:146 // x = extract_uint64(this.randomBytes.value, offset) byte 0x72616e646f6d4279746573 // "randomBytes" app_global_get - frame_dig -4 // offset: uint64 + frame_dig 3 // offset: uint64 extract_uint64 - frame_bury -3 // x: uint64 + frame_bury 2 // x: uint64 // examples/raffle/raffle.algo.ts:148 // offset = offset + 8 - frame_dig -4 // offset: uint64 + frame_dig 3 // offset: uint64 int 8 + - frame_bury -4 // offset: uint64 + frame_bury 3 // offset: uint64 // examples/raffle/raffle.algo.ts:150 // maxCondition = x > RAND_MAX - (((RAND_MAX % n) + 1) % n) - frame_dig -3 // x: uint64 + frame_dig 2 // x: uint64 int 18_446_744_073_709_551_615 int 18_446_744_073_709_551_615 - frame_dig -2 // n: uint64 + frame_dig 1 // n: uint64 % int 1 + - frame_dig -2 // n: uint64 + frame_dig 1 // n: uint64 % - > - frame_bury -5 // maxCondition: bool - frame_dig -5 // maxCondition: bool + frame_bury 4 // maxCondition: bool + frame_dig 4 // maxCondition: bool dup bz skip_and0 - frame_dig -4 // offset: uint64 + frame_dig 3 // offset: uint64 int 32 < && @@ -512,7 +508,7 @@ skip_and0: // if1_condition // examples/raffle/raffle.algo.ts:153 // maxCondition - frame_dig -5 // maxCondition: bool + frame_dig 4 // maxCondition: bool bz if1_end // if1_consequent @@ -533,8 +529,8 @@ if1_end: // examples/raffle/raffle.algo.ts:155 // this.winningTicket.value = x % n byte 0x77696e6e696e675469636b6574 // "winningTicket" - frame_dig -3 // x: uint64 - frame_dig -2 // n: uint64 + frame_dig 2 // x: uint64 + frame_dig 1 // n: uint64 % app_global_put @@ -555,24 +551,22 @@ if1_end: // // Send the asset to the the sender if they have the winning ticket abi_route_claim: - byte 0x // push empty bytes to fill the stack frame for this subroutine's local variables - // execute claim()void callsub claim int 1 return claim: - proto 1 0 + proto 0 0; byte 0x; dupn 1 // examples/raffle/raffle.algo.ts:161 // ticketRange = this.tickets(this.txn.sender).value txn Sender - frame_bury -1 // storage key//ticketRange + frame_bury 1 // storage key//ticketRange // examples/raffle/raffle.algo.ts:163 // assert(ticketRange.start <= this.winningTicket.value) - frame_dig -1 // storage key//ticketRange + frame_dig 1 // storage key//ticketRange box_get assert extract 0 8 @@ -584,7 +578,7 @@ claim: // examples/raffle/raffle.algo.ts:164 // assert(ticketRange.end >= this.winningTicket.value) - frame_dig -1 // storage key//ticketRange + frame_dig 1 // storage key//ticketRange box_get assert extract 8 8 @@ -646,15 +640,13 @@ claim: // and 1512 rounds have passed since the draw round, meaning the oracle no // longer has the data for the draw round abi_route_getRefund: - byte 0x; dup // push empty bytes to fill the stack frame for this subroutine's local variables - // execute getRefund()void callsub getRefund int 1 return getRefund: - proto 2 0 + proto 0 0; byte 0x; dupn 2 // examples/raffle/raffle.algo.ts:181 // assert(!this.winningTicket.exists) @@ -679,16 +671,16 @@ getRefund: // examples/raffle/raffle.algo.ts:184 // ticketRange = this.tickets(this.txn.sender).value txn Sender - frame_bury -1 // storage key//ticketRange + frame_bury 1 // storage key//ticketRange // examples/raffle/raffle.algo.ts:185 // ticketCount = ticketRange.end - ticketRange.start + 1 - frame_dig -1 // storage key//ticketRange + frame_dig 1 // storage key//ticketRange box_get assert extract 8 8 btoi - frame_dig -1 // storage key//ticketRange + frame_dig 1 // storage key//ticketRange box_get assert extract 0 8 @@ -696,7 +688,7 @@ getRefund: - int 1 + - frame_bury -2 // ticketCount: uint64 + frame_bury 2 // ticketCount: uint64 // examples/raffle/raffle.algo.ts:187 // this.tickets(this.txn.sender).delete() @@ -717,7 +709,7 @@ getRefund: // amount: this.ticketPrice.value * ticketCount byte 0x7469636b65745072696365 // "ticketPrice" app_global_get - frame_dig -2 // ticketCount: uint64 + frame_dig 2 // ticketCount: uint64 * itxn_field Amount diff --git a/examples/raffle/artifacts/NFTRaffle.arc32.json b/examples/raffle/artifacts/NFTRaffle.arc32.json index cdef78233..3fd1cc85d 100644 --- a/examples/raffle/artifacts/NFTRaffle.arc32.json +++ b/examples/raffle/artifacts/NFTRaffle.arc32.json @@ -97,7 +97,7 @@ } }, "source": { - "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjMuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAovLwovLyBDcmVhdGUgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gdGlja2V0UHJpY2UgVGhlIHByaWNlIG9mIGEgc2luZ2xlIHRpY2tldCAodUFMR08pCi8vIEBwYXJhbSByYW5kb21uZXNzT3JhY2xlIFRoZSBhcHAgSUQgb2YgdGhlIHJhbmRvbW5lc3Mgb3JhY2xlCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIHJhbmRvbW5lc3NPcmFjbGU6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIHRpY2tldFByaWNlOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBjcmVhdGVBcHBsaWNhdGlvbgoJaW50IDEKCXJldHVybgoKY3JlYXRlQXBwbGljYXRpb246Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NDMKCS8vIHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSA9IHJhbmRvbW5lc3NPcmFjbGUKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQ0CgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWZyYW1lX2RpZyAtMSAvLyB0aWNrZXRQcmljZTogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzZXRBc3NldChhc3NldCl2b2lkCi8vCi8vIFNldCB0aGUgYXNzZXQgdG8gYmUgcmFmZmxlZAovLwovLyBAcGFyYW0gYXNzZXQgVGhlIGFzc2V0IHRvIGJlIHJhZmZsZWQKYWJpX3JvdXRlX3NldEFzc2V0OgoJLy8gYXNzZXQ6IGFzc2V0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCgkvLyBleGVjdXRlIHNldEFzc2V0KGFzc2V0KXZvaWQKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU0CgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiBhc3NldCwKCS8vICAgICAgIGFzc2V0QW1vdW50OiAwLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTcKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMuYXBwLmFkZHJlc3MKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTgKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU5CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NjAKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo2MwoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglmcmFtZV9kaWcgLTEgLy8gYXNzZXQ6IGFzc2V0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKLy8KLy8gU3RhcnQgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gZW5kIFRoZSByb3VuZCBudW1iZXIgd2hlbiB0aGUgcmFmZmxlIGVuZHMKLy8gQHBhcmFtIGRyYXcgVGhlIHJvdW5kIG51bWJlciB3aGVuIHRoZSByYWZmbGUgaXMgZHJhd24KYWJpX3JvdXRlX3N0YXJ0UmFmZmxlOgoJLy8gZHJhdzogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgoJLy8gZW5kOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBheGZlcjogYXhmZXIKCXR4biBHcm91cEluZGV4CglpbnQgMQoJLQoJZHVwCglndHhucyBUeXBlRW51bQoJaW50IGF4ZmVyCgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKCWNhbGxzdWIgc3RhcnRSYWZmbGUKCWludCAxCglyZXR1cm4KCnN0YXJ0UmFmZmxlOgoJcHJvdG8gMyAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc0CgkvLyB2ZXJpZnlUeG4oYXhmZXIsIHsKCS8vICAgICAgIGFzc2V0QW1vdW50OiB7IGdyZWF0ZXJUaGFuOiAwIH0sCgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlLAoJLy8gICAgIH0pCgkvLyB2ZXJpZnkgYXNzZXRBbW91bnQKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0QW1vdW50CglpbnQgMAoJPgoJYXNzZXJ0CgoJLy8gdmVyaWZ5IGFzc2V0UmVjZWl2ZXIKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0UmVjZWl2ZXIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHhmZXJBc3NldAoJZnJhbWVfZGlnIC0xIC8vIGF4ZmVyOiBheGZlcgoJZ3R4bnMgWGZlckFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MAoJLy8gYXNzZXJ0KGRyYXcgPiBlbmQpCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gZW5kOiB1aW50NjQKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MQoJLy8gdGhpcy5lbmRSb3VuZC52YWx1ZSA9IGVuZAoJYnl0ZSAweDY1NmU2NDUyNmY3NTZlNjQgLy8gImVuZFJvdW5kIgoJZnJhbWVfZGlnIC0yIC8vIGVuZDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MgoJLy8gdGhpcy5kcmF3Um91bmQudmFsdWUgPSBkcmF3CglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAovLwovLyBCdXkgdGlja2V0cy4gTm90ZSB0aGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlIQovLyBJdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBhbGxvdyBtdWx0aXBsZSBwdXJjaGFzZXMsIGJ1dAovLyBmb3Igc2ltcGxpY2l0eSwgb25seSBvbmUgcHVyY2hhc2UgaXMgYWxsb3dlZC4KLy8KLy8gQHBhcmFtIHBheW1lbnQgVGhlIHBheW1lbnQgZm9yIHRoZSB0aWNrZXRzCi8vIEBwYXJhbSBxdWFuaXR5IFRoZSBudW1iZXIgb2YgdGlja2V0cyB0byBidXkKLy8KLy8gQHJldHVybnMgVGhlIHRvdGFsIG51bWJlciBvZiB0aWNrZXRzIG93bmVkIGJ5IHRoZSBzZW5kZXIKYWJpX3JvdXRlX2J1eVRpY2tldHM6CglieXRlIDB4OyBkdXBuIDIgLy8gcHVzaCBlbXB0eSBieXRlcyB0byBmaWxsIHRoZSBzdGFjayBmcmFtZSBmb3IgdGhpcyBzdWJyb3V0aW5lJ3MgbG9jYWwgdmFyaWFibGVzCgoJLy8gcXVhbnRpdHk6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoKCS8vIHBheW1lbnQ6IHBheQoJdHhuIEdyb3VwSW5kZXgKCWludCAxCgktCglkdXAKCWd0eG5zIFR5cGVFbnVtCglpbnQgcGF5Cgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAoJY2FsbHN1YiBidXlUaWNrZXRzCglpbnQgMQoJcmV0dXJuCgpidXlUaWNrZXRzOgoJcHJvdG8gNSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjk2CgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA8IHRoaXMuZW5kUm91bmQudmFsdWUpCglnbG9iYWwgUm91bmQKCWJ5dGUgMHg2NTZlNjQ1MjZmNzU2ZTY0IC8vICJlbmRSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0Cgk8Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTcKCS8vIGFzc2VydChxdWFudGl0eSA+IDApCglmcmFtZV9kaWcgLTIgLy8gcXVhbnRpdHk6IHVpbnQ2NAoJaW50IDAKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5OQoJLy8gYXNzZXJ0KCF0aGlzLnRpY2tldHMocGF5bWVudC5zZW5kZXIpLmV4aXN0cykKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJYm94X2xlbgoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAxCgkvLyBuZXdUb3RhbCA9IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlICsgcXVhbnRpdHkgKyAxCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCSsKCWludCAxCgkrCglmcmFtZV9idXJ5IC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAzCgkvLyBwcmVNQlIgPSB0aGlzLmFwcC5hZGRyZXNzLm1pbkJhbGFuY2UKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKCWFzc2VydAoJZnJhbWVfYnVyeSAtNCAvLyBwcmVNQlI6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDQKCS8vIHRoaXMudGlja2V0cyhwYXltZW50LnNlbmRlcikudmFsdWUgPSB7IHN0YXJ0OiB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSwgZW5kOiBuZXdUb3RhbCAtIDEgfQoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJZnJhbWVfZGlnIC0zIC8vIG5ld1RvdGFsOiB1aW50NjQKCWludCAxCgktCglpdG9iCgljb25jYXQKCWJveF9wdXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTA1CgkvLyBtYnJEZWx0YSA9IHRoaXMuYXBwLmFkZHJlc3MubWluQmFsYW5jZSAtIHByZU1CUgoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCWFjY3RfcGFyYW1zX2dldCBBY2N0TWluQmFsYW5jZQoJYXNzZXJ0CglmcmFtZV9kaWcgLTQgLy8gcHJlTUJSOiB1aW50NjQKCS0KCWZyYW1lX2J1cnkgLTUgLy8gbWJyRGVsdGE6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMDcKCS8vIHZlcmlmeVR4bihwYXltZW50LCB7CgkvLyAgICAgICBhbW91bnQ6IHRoaXMudGlja2V0UHJpY2UudmFsdWUgKiBxdWFudGl0eSArIG1ickRlbHRhLAoJLy8gICAgICAgc2VuZGVyOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICByZWNlaXZlcjogdGhpcy5hcHAuYWRkcmVzcywKCS8vICAgICB9KQoJLy8gdmVyaWZ5IGFtb3VudAoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgQW1vdW50CglieXRlIDB4NzQ2OTYzNmI2NTc0NTA3MjY5NjM2NSAvLyAidGlja2V0UHJpY2UiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCSoKCWZyYW1lX2RpZyAtNSAvLyBtYnJEZWx0YTogdWludDY0CgkrCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHNlbmRlcgoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgU2VuZGVyCgl0eG4gU2VuZGVyCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHJlY2VpdmVyCglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBSZWNlaXZlcgoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCT09Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTEzCgkvLyB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSA9IG5ld1RvdGFsCglieXRlIDB4NzQ2Zjc0NjE2YzU0Njk2MzZiNjU3NDczIC8vICJ0b3RhbFRpY2tldHMiCglmcmFtZV9kaWcgLTMgLy8gbmV3VG90YWw6IHVpbnQ2NAoJYXBwX2dsb2JhbF9wdXQKCXJldHN1YgoKZ2V0UmFuZG9tQnl0ZXM6Cglwcm90byAwIDAKCgkvLyBpZjBfY29uZGl0aW9uCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTE4CgkvLyB0aGlzLnJhbmRvbUJ5dGVzLmV4aXN0cwoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJYnogaWYwX2Vsc2UKCgkvLyBpZjBfY29uc2VxdWVudAoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExOQoJLy8gdGhpcy5yYW5kb21CeXRlcy52YWx1ZSA9IHNoYTI1Nih0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlKSBhcyBieXRlcwoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCXNoYTI1NgoJYXBwX2dsb2JhbF9wdXQKCWIgaWYwX2VuZAoKaWYwX2Vsc2U6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTIxCgkvLyB0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlID0gc2VuZE1ldGhvZENhbGw8W3VpbnQ2NCwgYnl0ZXNdLCBieXRlcz4oewoJLy8gICAgICAgICBuYW1lOiAnbXVzdF9nZXQnLAoJLy8gICAgICAgICBtZXRob2RBcmdzOiBbdGhpcy5kcmF3Um91bmQudmFsdWUsICcnXSwKCS8vICAgICAgICAgYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSksCgkvLyAgICAgICAgIGZlZTogMCwKCS8vICAgICAgICAgb25Db21wbGV0aW9uOiAnTm9PcCcsCgkvLyAgICAgICB9KQoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJaXR4bl9iZWdpbgoJaW50IGFwcGwKCWl0eG5fZmllbGQgVHlwZUVudW0KCW1ldGhvZCAibXVzdF9nZXQodWludDY0LGJ5dGVbXSlieXRlW10iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjMKCS8vIG1ldGhvZEFyZ3M6IFt0aGlzLmRyYXdSb3VuZC52YWx1ZSwgJyddCglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglhcHBfZ2xvYmFsX2dldAoJaXRvYgoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbkFyZ3MKCWJ5dGUgMHgwMDAwCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjQKCS8vIGFwcGxpY2F0aW9uSUQ6IEFwcGxpY2F0aW9uLmZyb21JRCh0aGlzLnJhbmRvbW5lc3NPcmFjbGUudmFsdWUpCglieXRlIDB4NzI2MTZlNjQ2ZjZkNmU2NTczNzM0ZjcyNjE2MzZjNjUgLy8gInJhbmRvbW5lc3NPcmFjbGUiCglhcHBfZ2xvYmFsX2dldAoJaXR4bl9maWVsZCBBcHBsaWNhdGlvbklECgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNQoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTI2CgkvLyBvbkNvbXBsZXRpb246ICdOb09wJwoJaW50IE5vT3AKCWl0eG5fZmllbGQgT25Db21wbGV0aW9uCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoJaXR4biBOdW1Mb2dzCglpbnQgMQoJLQoJaXR4bmFzIExvZ3MKCWV4dHJhY3QgNCAwCglhcHBfZ2xvYmFsX3B1dAoKaWYwX2VuZDoKCXJldHN1YgoKLy8gZHJhdyhhcHBsaWNhdGlvbilib29sCi8vCi8vIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFycwphYmlfcm91dGVfZHJhdzoKCWJ5dGUgMHg7IGR1cG4gMyAvLyBwdXNoIGVtcHR5IGJ5dGVzIHRvIGZpbGwgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIHN1YnJvdXRpbmUncyBsb2NhbCB2YXJpYWJsZXMKCgkvLyBfb3JhY2xlUmVmZXJlbmNlOiBhcHBsaWNhdGlvbgoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMQoJYnRvaQoJdHhuYXMgQXBwbGljYXRpb25zCgoJLy8gZXhlY3V0ZSBkcmF3KGFwcGxpY2F0aW9uKWJvb2wKCWNhbGxzdWIgZHJhdwoJaW50IDEKCXJldHVybgoKZHJhdzoKCXByb3RvIDUgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzUKCS8vIGFzc2VydCghdGhpcy53aW5uaW5nVGlja2V0LmV4aXN0cykKCXR4bmEgQXBwbGljYXRpb25zIDAKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0X2V4Cglzd2FwCglwb3AKCSEKCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMzYKCS8vIHRoaXMuZ2V0UmFuZG9tQnl0ZXMoKQoJY2FsbHN1YiBnZXRSYW5kb21CeXRlcwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNDAKCS8vIG4gPSB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZQoJYnl0ZSAweDc0NmY3NDYxNmM1NDY5NjM2YjY1NzQ3MyAvLyAidG90YWxUaWNrZXRzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2J1cnkgLTIgLy8gbjogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0MgoJLy8gb2Zmc2V0ID0gMAoJaW50IDAKCWZyYW1lX2J1cnkgLTQgLy8gb2Zmc2V0OiB1aW50NjQKCmRvX3doaWxlXzA6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTQ2CgkvLyB4ID0gZXh0cmFjdF91aW50NjQodGhpcy5yYW5kb21CeXRlcy52YWx1ZSwgb2Zmc2V0KQoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtNCAvLyBvZmZzZXQ6IHVpbnQ2NAoJZXh0cmFjdF91aW50NjQKCWZyYW1lX2J1cnkgLTMgLy8geDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0OAoJLy8gb2Zmc2V0ID0gb2Zmc2V0ICsgOAoJZnJhbWVfZGlnIC00IC8vIG9mZnNldDogdWludDY0CglpbnQgOAoJKwoJZnJhbWVfYnVyeSAtNCAvLyBvZmZzZXQ6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTAKCS8vIG1heENvbmRpdGlvbiA9IHggPiBSQU5EX01BWCAtICgoKFJBTkRfTUFYICUgbikgKyAxKSAlIG4pCglmcmFtZV9kaWcgLTMgLy8geDogdWludDY0CglpbnQgMThfNDQ2Xzc0NF8wNzNfNzA5XzU1MV82MTUKCWludCAxOF80NDZfNzQ0XzA3M183MDlfNTUxXzYxNQoJZnJhbWVfZGlnIC0yIC8vIG46IHVpbnQ2NAoJJQoJaW50IDEKCSsKCWZyYW1lX2RpZyAtMiAvLyBuOiB1aW50NjQKCSUKCS0KCT4KCWZyYW1lX2J1cnkgLTUgLy8gbWF4Q29uZGl0aW9uOiBib29sCglmcmFtZV9kaWcgLTUgLy8gbWF4Q29uZGl0aW9uOiBib29sCglkdXAKCWJ6IHNraXBfYW5kMAoJZnJhbWVfZGlnIC00IC8vIG9mZnNldDogdWludDY0CglpbnQgMzIKCTwKCSYmCgpza2lwX2FuZDA6CglibnogZG9fd2hpbGVfMAoKCS8vIGlmMV9jb25kaXRpb24KCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTMKCS8vIG1heENvbmRpdGlvbgoJZnJhbWVfZGlnIC01IC8vIG1heENvbmRpdGlvbjogYm9vbAoJYnogaWYxX2VuZAoKCS8vIGlmMV9jb25zZXF1ZW50CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyByZXR1cm4gZmFsc2U7CglpbnQgMAoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKaWYxX2VuZDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTUKCS8vIHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSA9IHggJSBuCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglmcmFtZV9kaWcgLTMgLy8geDogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gbjogdWludDY0CgklCglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTYKCS8vIHJldHVybiB0cnVlOwoJaW50IDEKCWJ5dGUgMHgwMAoJaW50IDAKCXVuY292ZXIgMgoJc2V0Yml0CglieXRlIDB4MTUxZjdjNzUKCXN3YXAKCWNvbmNhdAoJbG9nCglyZXRzdWIKCi8vIGNsYWltKCl2b2lkCi8vCi8vIFNlbmQgdGhlIGFzc2V0IHRvIHRoZSB0aGUgc2VuZGVyIGlmIHRoZXkgaGF2ZSB0aGUgd2lubmluZyB0aWNrZXQKYWJpX3JvdXRlX2NsYWltOgoJYnl0ZSAweCAvLyBwdXNoIGVtcHR5IGJ5dGVzIHRvIGZpbGwgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIHN1YnJvdXRpbmUncyBsb2NhbCB2YXJpYWJsZXMKCgkvLyBleGVjdXRlIGNsYWltKCl2b2lkCgljYWxsc3ViIGNsYWltCglpbnQgMQoJcmV0dXJuCgpjbGFpbToKCXByb3RvIDEgMAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjEKCS8vIHRpY2tldFJhbmdlID0gdGhpcy50aWNrZXRzKHRoaXMudHhuLnNlbmRlcikudmFsdWUKCXR4biBTZW5kZXIKCWZyYW1lX2J1cnkgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2MwoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLnN0YXJ0IDw9IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCWJveF9nZXQKCWFzc2VydAoJZXh0cmFjdCAwIDgKCWJ0b2kKCWJ5dGUgMHg3NzY5NmU2ZTY5NmU2NzU0Njk2MzZiNjU3NCAvLyAid2lubmluZ1RpY2tldCIKCWFwcF9nbG9iYWxfZ2V0Cgk8PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2NAoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLmVuZCA+PSB0aGlzLndpbm5pbmdUaWNrZXQudmFsdWUpCglmcmFtZV9kaWcgLTEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgOCA4CglidG9pCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldAoJPj0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjYKCS8vIHNlbmRBc3NldFRyYW5zZmVyKHsKCS8vICAgICAgIGFzc2V0UmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIHhmZXJBc3NldDogdGhpcy5hc3NldC52YWx1ZSwKCS8vICAgICAgIGFzc2V0QW1vdW50OiB0aGlzLmFwcC5hZGRyZXNzLmFzc2V0QmFsYW5jZSh0aGlzLmFzc2V0LnZhbHVlKSwKCS8vICAgICAgIGFzc2V0Q2xvc2VUbzogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY3CgkvLyBhc3NldFJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRSZWNlaXZlcgoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjgKCS8vIHhmZXJBc3NldDogdGhpcy5hc3NldC52YWx1ZQoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2OQoJLy8gYXNzZXRBbW91bnQ6IHRoaXMuYXBwLmFkZHJlc3MuYXNzZXRCYWxhbmNlKHRoaXMuYXNzZXQudmFsdWUpCglnbG9iYWwgQ3VycmVudEFwcGxpY2F0aW9uQWRkcmVzcwoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXQKCWFzc2V0X2hvbGRpbmdfZ2V0IEFzc2V0QmFsYW5jZQoJYXNzZXJ0CglpdHhuX2ZpZWxkIEFzc2V0QW1vdW50CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3MAoJLy8gYXNzZXRDbG9zZVRvOiB0aGlzLnR4bi5zZW5kZXIKCXR4biBTZW5kZXIKCWl0eG5fZmllbGQgQXNzZXRDbG9zZVRvCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE3MQoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCi8vIGdldFJlZnVuZCgpdm9pZAovLwovLyBBbGxvd3MgcHVyY2hhc2VycyB0byBnZXQgYSByZWZ1bmQgaWYgdGhlIHdpbm5pbmcgdGlja2V0IGhhcyBub3QgYmVlbiBkcmF3bgovLyBhbmQgMTUxMiByb3VuZHMgaGF2ZSBwYXNzZWQgc2luY2UgdGhlIGRyYXcgcm91bmQsIG1lYW5pbmcgdGhlIG9yYWNsZSBubwovLyBsb25nZXIgaGFzIHRoZSBkYXRhIGZvciB0aGUgZHJhdyByb3VuZAphYmlfcm91dGVfZ2V0UmVmdW5kOgoJYnl0ZSAweDsgZHVwIC8vIHB1c2ggZW1wdHkgYnl0ZXMgdG8gZmlsbCB0aGUgc3RhY2sgZnJhbWUgZm9yIHRoaXMgc3Vicm91dGluZSdzIGxvY2FsIHZhcmlhYmxlcwoKCS8vIGV4ZWN1dGUgZ2V0UmVmdW5kKCl2b2lkCgljYWxsc3ViIGdldFJlZnVuZAoJaW50IDEKCXJldHVybgoKZ2V0UmVmdW5kOgoJcHJvdG8gMiAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4MQoJLy8gYXNzZXJ0KCF0aGlzLndpbm5pbmdUaWNrZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4MgoJLy8gYXNzZXJ0KGdsb2JhbHMucm91bmQgPiB0aGlzLmRyYXdSb3VuZC52YWx1ZSArIDE1MTIpCglnbG9iYWwgUm91bmQKCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpbnQgMTUxMgoJKwoJPgoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4NAoJLy8gdGlja2V0UmFuZ2UgPSB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS52YWx1ZQoJdHhuIFNlbmRlcgoJZnJhbWVfYnVyeSAtMSAvLyBzdG9yYWdlIGtleS8vdGlja2V0UmFuZ2UKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTg1CgkvLyB0aWNrZXRDb3VudCA9IHRpY2tldFJhbmdlLmVuZCAtIHRpY2tldFJhbmdlLnN0YXJ0ICsgMQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDggOAoJYnRvaQoJZnJhbWVfZGlnIC0xIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDAgOAoJYnRvaQoJLQoJaW50IDEKCSsKCWZyYW1lX2J1cnkgLTIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxODcKCS8vIHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLmRlbGV0ZSgpCgl0eG4gU2VuZGVyCglib3hfZGVsCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4OQoJLy8gc2VuZFBheW1lbnQoewoJLy8gICAgICAgYW1vdW50OiB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogdGlja2V0Q291bnQsCgkvLyAgICAgICByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgcGF5CglpdHhuX2ZpZWxkIFR5cGVFbnVtCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MAoJLy8gYW1vdW50OiB0aGlzLnRpY2tldFByaWNlLnZhbHVlICogdGlja2V0Q291bnQKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9kaWcgLTIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoJKgoJaXR4bl9maWVsZCBBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTkxCgkvLyByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIFJlY2VpdmVyCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MgoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCmNyZWF0ZV9Ob09wOgoJbWV0aG9kICJjcmVhdGVBcHBsaWNhdGlvbih1aW50NjQsdWludDY0KXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJzZXRBc3NldChhc3NldCl2b2lkIgoJbWV0aG9kICJzdGFydFJhZmZsZShheGZlcix1aW50NjQsdWludDY0KXZvaWQiCgltZXRob2QgImJ1eVRpY2tldHMocGF5LHVpbnQ2NCl2b2lkIgoJbWV0aG9kICJkcmF3KGFwcGxpY2F0aW9uKWJvb2wiCgltZXRob2QgImNsYWltKCl2b2lkIgoJbWV0aG9kICJnZXRSZWZ1bmQoKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc2V0QXNzZXQgYWJpX3JvdXRlX3N0YXJ0UmFmZmxlIGFiaV9yb3V0ZV9idXlUaWNrZXRzIGFiaV9yb3V0ZV9kcmF3IGFiaV9yb3V0ZV9jbGFpbSBhYmlfcm91dGVfZ2V0UmVmdW5kCgllcnI=", + "approval": "I3ByYWdtYSB2ZXJzaW9uIDkKCi8vIFRoaXMgVEVBTCB3YXMgZ2VuZXJhdGVkIGJ5IFRFQUxTY3JpcHQgdjAuNjUuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsbWVudGVkIGluIHRoZSBjb250cmFjdCwgaXRzIHJlcHNlY3RpdmUgYnJhbmNoIHdpbGwgYmUgIk5PVF9JTVBMTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECmludCAwCj4KaW50IDYKKgp0eG4gT25Db21wbGV0aW9uCisKc3dpdGNoIGNyZWF0ZV9Ob09wIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgTk9UX0lNUExFTUVOVEVEIE5PVF9JTVBMRU1FTlRFRCBOT1RfSU1QTEVNRU5URUQgY2FsbF9Ob09wCgpOT1RfSU1QTEVNRU5URUQ6CgllcnIKCi8vIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAovLwovLyBDcmVhdGUgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gdGlja2V0UHJpY2UgVGhlIHByaWNlIG9mIGEgc2luZ2xlIHRpY2tldCAodUFMR08pCi8vIEBwYXJhbSByYW5kb21uZXNzT3JhY2xlIFRoZSBhcHAgSUQgb2YgdGhlIHJhbmRvbW5lc3Mgb3JhY2xlCmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCS8vIHJhbmRvbW5lc3NPcmFjbGU6IHVpbnQ2NAoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMgoJYnRvaQoKCS8vIHRpY2tldFByaWNlOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBleGVjdXRlIGNyZWF0ZUFwcGxpY2F0aW9uKHVpbnQ2NCx1aW50NjQpdm9pZAoJY2FsbHN1YiBjcmVhdGVBcHBsaWNhdGlvbgoJaW50IDEKCXJldHVybgoKY3JlYXRlQXBwbGljYXRpb246Cglwcm90byAyIDAKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NDMKCS8vIHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSA9IHJhbmRvbW5lc3NPcmFjbGUKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWZyYW1lX2RpZyAtMiAvLyByYW5kb21uZXNzT3JhY2xlOiB1aW50NjQKCWFwcF9nbG9iYWxfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjQ0CgkvLyB0aGlzLnRpY2tldFByaWNlLnZhbHVlID0gdGlja2V0UHJpY2UKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWZyYW1lX2RpZyAtMSAvLyB0aWNrZXRQcmljZTogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzZXRBc3NldChhc3NldCl2b2lkCi8vCi8vIFNldCB0aGUgYXNzZXQgdG8gYmUgcmFmZmxlZAovLwovLyBAcGFyYW0gYXNzZXQgVGhlIGFzc2V0IHRvIGJlIHJhZmZsZWQKYWJpX3JvdXRlX3NldEFzc2V0OgoJLy8gYXNzZXQ6IGFzc2V0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBc3NldHMKCgkvLyBleGVjdXRlIHNldEFzc2V0KGFzc2V0KXZvaWQKCWNhbGxzdWIgc2V0QXNzZXQKCWludCAxCglyZXR1cm4KCnNldEFzc2V0OgoJcHJvdG8gMSAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU0CgkvLyBhc3NlcnQoIXRoaXMuYXNzZXQuZXhpc3RzKQoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDYxNzM3MzY1NzQgLy8gImFzc2V0IgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiBhc3NldCwKCS8vICAgICAgIGFzc2V0QW1vdW50OiAwLAoJLy8gICAgICAgZmVlOiAwLAoJLy8gICAgIH0pCglpdHhuX2JlZ2luCglpbnQgYXhmZXIKCWl0eG5fZmllbGQgVHlwZUVudW0KCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTcKCS8vIGFzc2V0UmVjZWl2ZXI6IHRoaXMuYXBwLmFkZHJlc3MKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NTgKCS8vIHhmZXJBc3NldDogYXNzZXQKCWZyYW1lX2RpZyAtMSAvLyBhc3NldDogYXNzZXQKCWl0eG5fZmllbGQgWGZlckFzc2V0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjU5CgkvLyBhc3NldEFtb3VudDogMAoJaW50IDAKCWl0eG5fZmllbGQgQXNzZXRBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6NjAKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo2MwoJLy8gdGhpcy5hc3NldC52YWx1ZSA9IGFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglmcmFtZV9kaWcgLTEgLy8gYXNzZXQ6IGFzc2V0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKLy8KLy8gU3RhcnQgdGhlIHJhZmZsZQovLwovLyBAcGFyYW0gZW5kIFRoZSByb3VuZCBudW1iZXIgd2hlbiB0aGUgcmFmZmxlIGVuZHMKLy8gQHBhcmFtIGRyYXcgVGhlIHJvdW5kIG51bWJlciB3aGVuIHRoZSByYWZmbGUgaXMgZHJhd24KYWJpX3JvdXRlX3N0YXJ0UmFmZmxlOgoJLy8gZHJhdzogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAyCglidG9pCgoJLy8gZW5kOiB1aW50NjQKCXR4bmEgQXBwbGljYXRpb25BcmdzIDEKCWJ0b2kKCgkvLyBheGZlcjogYXhmZXIKCXR4biBHcm91cEluZGV4CglpbnQgMQoJLQoJZHVwCglndHhucyBUeXBlRW51bQoJaW50IGF4ZmVyCgk9PQoJYXNzZXJ0CgoJLy8gZXhlY3V0ZSBzdGFydFJhZmZsZSh1aW50NjQsdWludDY0LGF4ZmVyKXZvaWQKCWNhbGxzdWIgc3RhcnRSYWZmbGUKCWludCAxCglyZXR1cm4KCnN0YXJ0UmFmZmxlOgoJcHJvdG8gMyAwCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjc0CgkvLyB2ZXJpZnlUeG4oYXhmZXIsIHsKCS8vICAgICAgIGFzc2V0QW1vdW50OiB7IGdyZWF0ZXJUaGFuOiAwIH0sCgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgICAgeGZlckFzc2V0OiB0aGlzLmFzc2V0LnZhbHVlLAoJLy8gICAgIH0pCgkvLyB2ZXJpZnkgYXNzZXRBbW91bnQKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0QW1vdW50CglpbnQgMAoJPgoJYXNzZXJ0CgoJLy8gdmVyaWZ5IGFzc2V0UmVjZWl2ZXIKCWZyYW1lX2RpZyAtMSAvLyBheGZlcjogYXhmZXIKCWd0eG5zIEFzc2V0UmVjZWl2ZXIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCgk9PQoJYXNzZXJ0CgoJLy8gdmVyaWZ5IHhmZXJBc3NldAoJZnJhbWVfZGlnIC0xIC8vIGF4ZmVyOiBheGZlcgoJZ3R4bnMgWGZlckFzc2V0CglieXRlIDB4NjE3MzczNjU3NCAvLyAiYXNzZXQiCglhcHBfZ2xvYmFsX2dldAoJPT0KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MAoJLy8gYXNzZXJ0KGRyYXcgPiBlbmQpCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglmcmFtZV9kaWcgLTIgLy8gZW5kOiB1aW50NjQKCT4KCWFzc2VydAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MQoJLy8gdGhpcy5lbmRSb3VuZC52YWx1ZSA9IGVuZAoJYnl0ZSAweDY1NmU2NDUyNmY3NTZlNjQgLy8gImVuZFJvdW5kIgoJZnJhbWVfZGlnIC0yIC8vIGVuZDogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo4MgoJLy8gdGhpcy5kcmF3Um91bmQudmFsdWUgPSBkcmF3CglieXRlIDB4NjQ3MjYxNzc1MjZmNzU2ZTY0IC8vICJkcmF3Um91bmQiCglmcmFtZV9kaWcgLTMgLy8gZHJhdzogdWludDY0CglhcHBfZ2xvYmFsX3B1dAoJcmV0c3ViCgovLyBidXlUaWNrZXRzKHVpbnQ2NCxwYXkpdm9pZAovLwovLyBCdXkgdGlja2V0cy4gTm90ZSB0aGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBvbmNlIQovLyBJdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBhbGxvdyBtdWx0aXBsZSBwdXJjaGFzZXMsIGJ1dAovLyBmb3Igc2ltcGxpY2l0eSwgb25seSBvbmUgcHVyY2hhc2UgaXMgYWxsb3dlZC4KLy8KLy8gQHBhcmFtIHBheW1lbnQgVGhlIHBheW1lbnQgZm9yIHRoZSB0aWNrZXRzCi8vIEBwYXJhbSBxdWFuaXR5IFRoZSBudW1iZXIgb2YgdGlja2V0cyB0byBidXkKLy8KLy8gQHJldHVybnMgVGhlIHRvdGFsIG51bWJlciBvZiB0aWNrZXRzIG93bmVkIGJ5IHRoZSBzZW5kZXIKYWJpX3JvdXRlX2J1eVRpY2tldHM6CgkvLyBxdWFudGl0eTogdWludDY0Cgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgoJLy8gcGF5bWVudDogcGF5Cgl0eG4gR3JvdXBJbmRleAoJaW50IDEKCS0KCWR1cAoJZ3R4bnMgVHlwZUVudW0KCWludCBwYXkKCT09Cglhc3NlcnQKCgkvLyBleGVjdXRlIGJ1eVRpY2tldHModWludDY0LHBheSl2b2lkCgljYWxsc3ViIGJ1eVRpY2tldHMKCWludCAxCglyZXR1cm4KCmJ1eVRpY2tldHM6Cglwcm90byAyIDA7IGJ5dGUgMHg7IGR1cG4gMwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czo5NgoJLy8gYXNzZXJ0KGdsb2JhbHMucm91bmQgPCB0aGlzLmVuZFJvdW5kLnZhbHVlKQoJZ2xvYmFsIFJvdW5kCglieXRlIDB4NjU2ZTY0NTI2Zjc1NmU2NCAvLyAiZW5kUm91bmQiCglhcHBfZ2xvYmFsX2dldAoJPAoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjk3CgkvLyBhc3NlcnQocXVhbnRpdHkgPiAwKQoJZnJhbWVfZGlnIC0yIC8vIHF1YW50aXR5OiB1aW50NjQKCWludCAwCgk+Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6OTkKCS8vIGFzc2VydCghdGhpcy50aWNrZXRzKHBheW1lbnQuc2VuZGVyKS5leGlzdHMpCglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBTZW5kZXIKCWJveF9sZW4KCXN3YXAKCXBvcAoJIQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwMQoJLy8gbmV3VG90YWwgPSB0aGlzLnRvdGFsVGlja2V0cy52YWx1ZSArIHF1YW50aXR5ICsgMQoJYnl0ZSAweDc0NmY3NDYxNmM1NDY5NjM2YjY1NzQ3MyAvLyAidG90YWxUaWNrZXRzIgoJYXBwX2dsb2JhbF9nZXQKCWZyYW1lX2RpZyAtMiAvLyBxdWFudGl0eTogdWludDY0CgkrCglpbnQgMQoJKwoJZnJhbWVfYnVyeSAxIC8vIG5ld1RvdGFsOiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTAzCgkvLyBwcmVNQlIgPSB0aGlzLmFwcC5hZGRyZXNzLm1pbkJhbGFuY2UKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKCWFzc2VydAoJZnJhbWVfYnVyeSAyIC8vIHByZU1CUjogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwNAoJLy8gdGhpcy50aWNrZXRzKHBheW1lbnQuc2VuZGVyKS52YWx1ZSA9IHsgc3RhcnQ6IHRoaXMudG90YWxUaWNrZXRzLnZhbHVlLCBlbmQ6IG5ld1RvdGFsIC0gMSB9CglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBTZW5kZXIKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWFwcF9nbG9iYWxfZ2V0CglpdG9iCglmcmFtZV9kaWcgMSAvLyBuZXdUb3RhbDogdWludDY0CglpbnQgMQoJLQoJaXRvYgoJY29uY2F0Cglib3hfcHV0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwNQoJLy8gbWJyRGVsdGEgPSB0aGlzLmFwcC5hZGRyZXNzLm1pbkJhbGFuY2UgLSBwcmVNQlIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCglhY2N0X3BhcmFtc19nZXQgQWNjdE1pbkJhbGFuY2UKCWFzc2VydAoJZnJhbWVfZGlnIDIgLy8gcHJlTUJSOiB1aW50NjQKCS0KCWZyYW1lX2J1cnkgMyAvLyBtYnJEZWx0YTogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEwNwoJLy8gdmVyaWZ5VHhuKHBheW1lbnQsIHsKCS8vICAgICAgIGFtb3VudDogdGhpcy50aWNrZXRQcmljZS52YWx1ZSAqIHF1YW50aXR5ICsgbWJyRGVsdGEsCgkvLyAgICAgICBzZW5kZXI6IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIHJlY2VpdmVyOiB0aGlzLmFwcC5hZGRyZXNzLAoJLy8gICAgIH0pCgkvLyB2ZXJpZnkgYW1vdW50CglmcmFtZV9kaWcgLTEgLy8gcGF5bWVudDogcGF5CglndHhucyBBbW91bnQKCWJ5dGUgMHg3NDY5NjM2YjY1NzQ1MDcyNjk2MzY1IC8vICJ0aWNrZXRQcmljZSIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9kaWcgLTIgLy8gcXVhbnRpdHk6IHVpbnQ2NAoJKgoJZnJhbWVfZGlnIDMgLy8gbWJyRGVsdGE6IHVpbnQ2NAoJKwoJPT0KCWFzc2VydAoKCS8vIHZlcmlmeSBzZW5kZXIKCWZyYW1lX2RpZyAtMSAvLyBwYXltZW50OiBwYXkKCWd0eG5zIFNlbmRlcgoJdHhuIFNlbmRlcgoJPT0KCWFzc2VydAoKCS8vIHZlcmlmeSByZWNlaXZlcgoJZnJhbWVfZGlnIC0xIC8vIHBheW1lbnQ6IHBheQoJZ3R4bnMgUmVjZWl2ZXIKCWdsb2JhbCBDdXJyZW50QXBwbGljYXRpb25BZGRyZXNzCgk9PQoJYXNzZXJ0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExMwoJLy8gdGhpcy50b3RhbFRpY2tldHMudmFsdWUgPSBuZXdUb3RhbAoJYnl0ZSAweDc0NmY3NDYxNmM1NDY5NjM2YjY1NzQ3MyAvLyAidG90YWxUaWNrZXRzIgoJZnJhbWVfZGlnIDEgLy8gbmV3VG90YWw6IHVpbnQ2NAoJYXBwX2dsb2JhbF9wdXQKCXJldHN1YgoKZ2V0UmFuZG9tQnl0ZXM6Cglwcm90byAwIDAKCgkvLyBpZjBfY29uZGl0aW9uCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTE4CgkvLyB0aGlzLnJhbmRvbUJ5dGVzLmV4aXN0cwoJdHhuYSBBcHBsaWNhdGlvbnMgMAoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXRfZXgKCXN3YXAKCXBvcAoJYnogaWYwX2Vsc2UKCgkvLyBpZjBfY29uc2VxdWVudAoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjExOQoJLy8gdGhpcy5yYW5kb21CeXRlcy52YWx1ZSA9IHNoYTI1Nih0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlKSBhcyBieXRlcwoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYnl0ZSAweDcyNjE2ZTY0NmY2ZDQyNzk3NDY1NzMgLy8gInJhbmRvbUJ5dGVzIgoJYXBwX2dsb2JhbF9nZXQKCXNoYTI1NgoJYXBwX2dsb2JhbF9wdXQKCWIgaWYwX2VuZAoKaWYwX2Vsc2U6CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTIxCgkvLyB0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlID0gc2VuZE1ldGhvZENhbGw8W3VpbnQ2NCwgYnl0ZXNdLCBieXRlcz4oewoJLy8gICAgICAgICBuYW1lOiAnbXVzdF9nZXQnLAoJLy8gICAgICAgICBtZXRob2RBcmdzOiBbdGhpcy5kcmF3Um91bmQudmFsdWUsICcnXSwKCS8vICAgICAgICAgYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSksCgkvLyAgICAgICAgIGZlZTogMCwKCS8vICAgICAgICAgb25Db21wbGV0aW9uOiBPbkNvbXBsZXRpb24uTm9PcCwKCS8vICAgICAgIH0pCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglpdHhuX2JlZ2luCglpbnQgYXBwbAoJaXR4bl9maWVsZCBUeXBlRW51bQoJbWV0aG9kICJtdXN0X2dldCh1aW50NjQsYnl0ZVtdKWJ5dGVbXSIKCWl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyMwoJLy8gbWV0aG9kQXJnczogW3RoaXMuZHJhd1JvdW5kLnZhbHVlLCAnJ10KCWJ5dGUgMHg2NDcyNjE3NzUyNmY3NTZlNjQgLy8gImRyYXdSb3VuZCIKCWFwcF9nbG9iYWxfZ2V0CglpdG9iCglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uQXJncwoJYnl0ZSAweDAwMDAKCWl0eG5fZmllbGQgQXBwbGljYXRpb25BcmdzCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjEyNAoJLy8gYXBwbGljYXRpb25JRDogQXBwbGljYXRpb24uZnJvbUlEKHRoaXMucmFuZG9tbmVzc09yYWNsZS52YWx1ZSkKCWJ5dGUgMHg3MjYxNmU2NDZmNmQ2ZTY1NzM3MzRmNzI2MTYzNmM2NSAvLyAicmFuZG9tbmVzc09yYWNsZSIKCWFwcF9nbG9iYWxfZ2V0CglpdHhuX2ZpZWxkIEFwcGxpY2F0aW9uSUQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTI1CgkvLyBmZWU6IDAKCWludCAwCglpdHhuX2ZpZWxkIEZlZQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxMjYKCS8vIG9uQ29tcGxldGlvbjogT25Db21wbGV0aW9uLk5vT3AKCWludCAwIC8vIE5vT3AKCWl0eG5fZmllbGQgT25Db21wbGV0aW9uCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoJaXR4biBOdW1Mb2dzCglpbnQgMQoJLQoJaXR4bmFzIExvZ3MKCWV4dHJhY3QgNCAwCglhcHBfZ2xvYmFsX3B1dAoKaWYwX2VuZDoKCXJldHN1YgoKLy8gZHJhdyhhcHBsaWNhdGlvbilib29sCi8vCi8vIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFycwphYmlfcm91dGVfZHJhdzoKCS8vIF9vcmFjbGVSZWZlcmVuY2U6IGFwcGxpY2F0aW9uCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAxCglidG9pCgl0eG5hcyBBcHBsaWNhdGlvbnMKCgkvLyBleGVjdXRlIGRyYXcoYXBwbGljYXRpb24pYm9vbAoJY2FsbHN1YiBkcmF3CglpbnQgMQoJcmV0dXJuCgpkcmF3OgoJcHJvdG8gMSAwOyBieXRlIDB4OyBkdXBuIDQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTM1CgkvLyBhc3NlcnQoIXRoaXMud2lubmluZ1RpY2tldC5leGlzdHMpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTM2CgkvLyB0aGlzLmdldFJhbmRvbUJ5dGVzKCkKCWNhbGxzdWIgZ2V0UmFuZG9tQnl0ZXMKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTQwCgkvLyBuID0gdGhpcy50b3RhbFRpY2tldHMudmFsdWUKCWJ5dGUgMHg3NDZmNzQ2MTZjNTQ2OTYzNmI2NTc0NzMgLy8gInRvdGFsVGlja2V0cyIKCWFwcF9nbG9iYWxfZ2V0CglmcmFtZV9idXJ5IDEgLy8gbjogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0MgoJLy8gb2Zmc2V0ID0gMAoJaW50IDAKCWZyYW1lX2J1cnkgMyAvLyBvZmZzZXQ6IHVpbnQ2NAoKZG9fd2hpbGVfMDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNDYKCS8vIHggPSBleHRyYWN0X3VpbnQ2NCh0aGlzLnJhbmRvbUJ5dGVzLnZhbHVlLCBvZmZzZXQpCglieXRlIDB4NzI2MTZlNjQ2ZjZkNDI3OTc0NjU3MyAvLyAicmFuZG9tQnl0ZXMiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIDMgLy8gb2Zmc2V0OiB1aW50NjQKCWV4dHJhY3RfdWludDY0CglmcmFtZV9idXJ5IDIgLy8geDogdWludDY0CgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE0OAoJLy8gb2Zmc2V0ID0gb2Zmc2V0ICsgOAoJZnJhbWVfZGlnIDMgLy8gb2Zmc2V0OiB1aW50NjQKCWludCA4CgkrCglmcmFtZV9idXJ5IDMgLy8gb2Zmc2V0OiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUwCgkvLyBtYXhDb25kaXRpb24gPSB4ID4gUkFORF9NQVggLSAoKChSQU5EX01BWCAlIG4pICsgMSkgJSBuKQoJZnJhbWVfZGlnIDIgLy8geDogdWludDY0CglpbnQgMThfNDQ2Xzc0NF8wNzNfNzA5XzU1MV82MTUKCWludCAxOF80NDZfNzQ0XzA3M183MDlfNTUxXzYxNQoJZnJhbWVfZGlnIDEgLy8gbjogdWludDY0CgklCglpbnQgMQoJKwoJZnJhbWVfZGlnIDEgLy8gbjogdWludDY0CgklCgktCgk+CglmcmFtZV9idXJ5IDQgLy8gbWF4Q29uZGl0aW9uOiBib29sCglmcmFtZV9kaWcgNCAvLyBtYXhDb25kaXRpb246IGJvb2wKCWR1cAoJYnogc2tpcF9hbmQwCglmcmFtZV9kaWcgMyAvLyBvZmZzZXQ6IHVpbnQ2NAoJaW50IDMyCgk8CgkmJgoKc2tpcF9hbmQwOgoJYm56IGRvX3doaWxlXzAKCgkvLyBpZjFfY29uZGl0aW9uCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyBtYXhDb25kaXRpb24KCWZyYW1lX2RpZyA0IC8vIG1heENvbmRpdGlvbjogYm9vbAoJYnogaWYxX2VuZAoKCS8vIGlmMV9jb25zZXF1ZW50CgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTUzCgkvLyByZXR1cm4gZmFsc2U7CglpbnQgMAoJYnl0ZSAweDAwCglpbnQgMAoJdW5jb3ZlciAyCglzZXRiaXQKCWJ5dGUgMHgxNTFmN2M3NQoJc3dhcAoJY29uY2F0Cglsb2cKCXJldHN1YgoKaWYxX2VuZDoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNTUKCS8vIHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSA9IHggJSBuCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglmcmFtZV9kaWcgMiAvLyB4OiB1aW50NjQKCWZyYW1lX2RpZyAxIC8vIG46IHVpbnQ2NAoJJQoJYXBwX2dsb2JhbF9wdXQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTU2CgkvLyByZXR1cm4gdHJ1ZTsKCWludCAxCglieXRlIDB4MDAKCWludCAwCgl1bmNvdmVyIDIKCXNldGJpdAoJYnl0ZSAweDE1MWY3Yzc1Cglzd2FwCgljb25jYXQKCWxvZwoJcmV0c3ViCgovLyBjbGFpbSgpdm9pZAovLwovLyBTZW5kIHRoZSBhc3NldCB0byB0aGUgdGhlIHNlbmRlciBpZiB0aGV5IGhhdmUgdGhlIHdpbm5pbmcgdGlja2V0CmFiaV9yb3V0ZV9jbGFpbToKCS8vIGV4ZWN1dGUgY2xhaW0oKXZvaWQKCWNhbGxzdWIgY2xhaW0KCWludCAxCglyZXR1cm4KCmNsYWltOgoJcHJvdG8gMCAwOyBieXRlIDB4OyBkdXBuIDEKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTYxCgkvLyB0aWNrZXRSYW5nZSA9IHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLnZhbHVlCgl0eG4gU2VuZGVyCglmcmFtZV9idXJ5IDEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2MwoJLy8gYXNzZXJ0KHRpY2tldFJhbmdlLnN0YXJ0IDw9IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAxIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDAgOAoJYnRvaQoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXQKCTw9Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY0CgkvLyBhc3NlcnQodGlja2V0UmFuZ2UuZW5kID49IHRoaXMud2lubmluZ1RpY2tldC52YWx1ZSkKCWZyYW1lX2RpZyAxIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDggOAoJYnRvaQoJYnl0ZSAweDc3Njk2ZTZlNjk2ZTY3NTQ2OTYzNmI2NTc0IC8vICJ3aW5uaW5nVGlja2V0IgoJYXBwX2dsb2JhbF9nZXQKCT49Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY2CgkvLyBzZW5kQXNzZXRUcmFuc2Zlcih7CgkvLyAgICAgICBhc3NldFJlY2VpdmVyOiB0aGlzLnR4bi5zZW5kZXIsCgkvLyAgICAgICB4ZmVyQXNzZXQ6IHRoaXMuYXNzZXQudmFsdWUsCgkvLyAgICAgICBhc3NldEFtb3VudDogdGhpcy5hcHAuYWRkcmVzcy5hc3NldEJhbGFuY2UodGhpcy5hc3NldC52YWx1ZSksCgkvLyAgICAgICBhc3NldENsb3NlVG86IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIGZlZTogMCwKCS8vICAgICB9KQoJaXR4bl9iZWdpbgoJaW50IGF4ZmVyCglpdHhuX2ZpZWxkIFR5cGVFbnVtCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE2NwoJLy8gYXNzZXRSZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIEFzc2V0UmVjZWl2ZXIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTY4CgkvLyB4ZmVyQXNzZXQ6IHRoaXMuYXNzZXQudmFsdWUKCWJ5dGUgMHg2MTczNzM2NTc0IC8vICJhc3NldCIKCWFwcF9nbG9iYWxfZ2V0CglpdHhuX2ZpZWxkIFhmZXJBc3NldAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNjkKCS8vIGFzc2V0QW1vdW50OiB0aGlzLmFwcC5hZGRyZXNzLmFzc2V0QmFsYW5jZSh0aGlzLmFzc2V0LnZhbHVlKQoJZ2xvYmFsIEN1cnJlbnRBcHBsaWNhdGlvbkFkZHJlc3MKCWJ5dGUgMHg2MTczNzM2NTc0IC8vICJhc3NldCIKCWFwcF9nbG9iYWxfZ2V0Cglhc3NldF9ob2xkaW5nX2dldCBBc3NldEJhbGFuY2UKCWFzc2VydAoJaXR4bl9maWVsZCBBc3NldEFtb3VudAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNzAKCS8vIGFzc2V0Q2xvc2VUbzogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIEFzc2V0Q2xvc2VUbwoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxNzEKCS8vIGZlZTogMAoJaW50IDAKCWl0eG5fZmllbGQgRmVlCgoJLy8gU3VibWl0IGlubmVyIHRyYW5zYWN0aW9uCglpdHhuX3N1Ym1pdAoJcmV0c3ViCgovLyBnZXRSZWZ1bmQoKXZvaWQKLy8KLy8gQWxsb3dzIHB1cmNoYXNlcnMgdG8gZ2V0IGEgcmVmdW5kIGlmIHRoZSB3aW5uaW5nIHRpY2tldCBoYXMgbm90IGJlZW4gZHJhd24KLy8gYW5kIDE1MTIgcm91bmRzIGhhdmUgcGFzc2VkIHNpbmNlIHRoZSBkcmF3IHJvdW5kLCBtZWFuaW5nIHRoZSBvcmFjbGUgbm8KLy8gbG9uZ2VyIGhhcyB0aGUgZGF0YSBmb3IgdGhlIGRyYXcgcm91bmQKYWJpX3JvdXRlX2dldFJlZnVuZDoKCS8vIGV4ZWN1dGUgZ2V0UmVmdW5kKCl2b2lkCgljYWxsc3ViIGdldFJlZnVuZAoJaW50IDEKCXJldHVybgoKZ2V0UmVmdW5kOgoJcHJvdG8gMCAwOyBieXRlIDB4OyBkdXBuIDIKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTgxCgkvLyBhc3NlcnQoIXRoaXMud2lubmluZ1RpY2tldC5leGlzdHMpCgl0eG5hIEFwcGxpY2F0aW9ucyAwCglieXRlIDB4Nzc2OTZlNmU2OTZlNjc1NDY5NjM2YjY1NzQgLy8gIndpbm5pbmdUaWNrZXQiCglhcHBfZ2xvYmFsX2dldF9leAoJc3dhcAoJcG9wCgkhCglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTgyCgkvLyBhc3NlcnQoZ2xvYmFscy5yb3VuZCA+IHRoaXMuZHJhd1JvdW5kLnZhbHVlICsgMTUxMikKCWdsb2JhbCBSb3VuZAoJYnl0ZSAweDY0NzI2MTc3NTI2Zjc1NmU2NCAvLyAiZHJhd1JvdW5kIgoJYXBwX2dsb2JhbF9nZXQKCWludCAxNTEyCgkrCgk+Cglhc3NlcnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTg0CgkvLyB0aWNrZXRSYW5nZSA9IHRoaXMudGlja2V0cyh0aGlzLnR4bi5zZW5kZXIpLnZhbHVlCgl0eG4gU2VuZGVyCglmcmFtZV9idXJ5IDEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE4NQoJLy8gdGlja2V0Q291bnQgPSB0aWNrZXRSYW5nZS5lbmQgLSB0aWNrZXRSYW5nZS5zdGFydCArIDEKCWZyYW1lX2RpZyAxIC8vIHN0b3JhZ2Uga2V5Ly90aWNrZXRSYW5nZQoJYm94X2dldAoJYXNzZXJ0CglleHRyYWN0IDggOAoJYnRvaQoJZnJhbWVfZGlnIDEgLy8gc3RvcmFnZSBrZXkvL3RpY2tldFJhbmdlCglib3hfZ2V0Cglhc3NlcnQKCWV4dHJhY3QgMCA4CglidG9pCgktCglpbnQgMQoJKwoJZnJhbWVfYnVyeSAyIC8vIHRpY2tldENvdW50OiB1aW50NjQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTg3CgkvLyB0aGlzLnRpY2tldHModGhpcy50eG4uc2VuZGVyKS5kZWxldGUoKQoJdHhuIFNlbmRlcgoJYm94X2RlbAoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxODkKCS8vIHNlbmRQYXltZW50KHsKCS8vICAgICAgIGFtb3VudDogdGhpcy50aWNrZXRQcmljZS52YWx1ZSAqIHRpY2tldENvdW50LAoJLy8gICAgICAgcmVjZWl2ZXI6IHRoaXMudHhuLnNlbmRlciwKCS8vICAgICAgIGZlZTogMCwKCS8vICAgICB9KQoJaXR4bl9iZWdpbgoJaW50IHBheQoJaXR4bl9maWVsZCBUeXBlRW51bQoKCS8vIGV4YW1wbGVzL3JhZmZsZS9yYWZmbGUuYWxnby50czoxOTAKCS8vIGFtb3VudDogdGhpcy50aWNrZXRQcmljZS52YWx1ZSAqIHRpY2tldENvdW50CglieXRlIDB4NzQ2OTYzNmI2NTc0NTA3MjY5NjM2NSAvLyAidGlja2V0UHJpY2UiCglhcHBfZ2xvYmFsX2dldAoJZnJhbWVfZGlnIDIgLy8gdGlja2V0Q291bnQ6IHVpbnQ2NAoJKgoJaXR4bl9maWVsZCBBbW91bnQKCgkvLyBleGFtcGxlcy9yYWZmbGUvcmFmZmxlLmFsZ28udHM6MTkxCgkvLyByZWNlaXZlcjogdGhpcy50eG4uc2VuZGVyCgl0eG4gU2VuZGVyCglpdHhuX2ZpZWxkIFJlY2VpdmVyCgoJLy8gZXhhbXBsZXMvcmFmZmxlL3JhZmZsZS5hbGdvLnRzOjE5MgoJLy8gZmVlOiAwCglpbnQgMAoJaXR4bl9maWVsZCBGZWUKCgkvLyBTdWJtaXQgaW5uZXIgdHJhbnNhY3Rpb24KCWl0eG5fc3VibWl0CglyZXRzdWIKCmNyZWF0ZV9Ob09wOgoJbWV0aG9kICJjcmVhdGVBcHBsaWNhdGlvbih1aW50NjQsdWludDY0KXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCWVycgoKY2FsbF9Ob09wOgoJbWV0aG9kICJzZXRBc3NldChhc3NldCl2b2lkIgoJbWV0aG9kICJzdGFydFJhZmZsZShheGZlcix1aW50NjQsdWludDY0KXZvaWQiCgltZXRob2QgImJ1eVRpY2tldHMocGF5LHVpbnQ2NCl2b2lkIgoJbWV0aG9kICJkcmF3KGFwcGxpY2F0aW9uKWJvb2wiCgltZXRob2QgImNsYWltKCl2b2lkIgoJbWV0aG9kICJnZXRSZWZ1bmQoKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCBhYmlfcm91dGVfc2V0QXNzZXQgYWJpX3JvdXRlX3N0YXJ0UmFmZmxlIGFiaV9yb3V0ZV9idXlUaWNrZXRzIGFiaV9yb3V0ZV9kcmF3IGFiaV9yb3V0ZV9jbGFpbSBhYmlfcm91dGVfZ2V0UmVmdW5kCgllcnI=", "clear": "I3ByYWdtYSB2ZXJzaW9uIDk=" }, "contract": { diff --git a/examples/raffle/artifacts/NFTRaffle.src_map.json b/examples/raffle/artifacts/NFTRaffle.src_map.json index deaf752ed..7f8ed8181 100644 --- a/examples/raffle/artifacts/NFTRaffle.src_map.json +++ b/examples/raffle/artifacts/NFTRaffle.src_map.json @@ -874,7 +874,7 @@ ] }, { - "teal": 223, + "teal": 224, "source": 95, "pc": [ 286, @@ -883,16 +883,22 @@ ] }, { - "teal": 226, + "teal": 225, + "source": 95, + "pc": [ + 289 + ] + }, + { + "teal": 228, "source": 95, "pc": [ - 289, 290, 291 ] }, { - "teal": 227, + "teal": 229, "source": 95, "pc": [ 292 @@ -902,21 +908,21 @@ "teal": 230, "source": 95, "pc": [ - 293, - 294 + 293 ] }, { "teal": 231, "source": 95, "pc": [ - 295 + 294 ] }, { "teal": 232, "source": 95, "pc": [ + 295, 296 ] }, @@ -931,65 +937,53 @@ "teal": 234, "source": 95, "pc": [ - 298, - 299 + 298 ] }, { "teal": 235, "source": 95, "pc": [ - 300 - ] - }, - { - "teal": 236, - "source": 95, - "pc": [ - 301 + 299 ] }, { - "teal": 237, + "teal": 238, "source": 95, "pc": [ + 300, + 301, 302 ] }, { - "teal": 240, - "source": 95, - "pc": [ - 303, - 304, - 305 - ] - }, - { - "teal": 241, + "teal": 239, "source": 95, "pc": [ - 306 + 303 ] }, { - "teal": 242, + "teal": 240, "source": 95, "pc": [ - 307 + 304 ] }, { - "teal": 245, + "teal": 243, "source": 95, "pc": [ + 305, + 306, + 307, 308, 309, 310 ] }, { - "teal": 249, + "teal": 247, "source": 96, "pc": [ 311, @@ -997,7 +991,7 @@ ] }, { - "teal": 250, + "teal": 248, "source": 96, "pc": [ 313, @@ -1005,28 +999,28 @@ ] }, { - "teal": 251, + "teal": 249, "source": 96, "pc": [ 315 ] }, { - "teal": 252, + "teal": 250, "source": 96, "pc": [ 316 ] }, { - "teal": 253, + "teal": 251, "source": 96, "pc": [ 317 ] }, { - "teal": 257, + "teal": 255, "source": 97, "pc": [ 318, @@ -1034,28 +1028,28 @@ ] }, { - "teal": 258, + "teal": 256, "source": 97, "pc": [ 320 ] }, { - "teal": 259, + "teal": 257, "source": 97, "pc": [ 321 ] }, { - "teal": 260, + "teal": 258, "source": 97, "pc": [ 322 ] }, { - "teal": 264, + "teal": 262, "source": 99, "pc": [ 323, @@ -1063,7 +1057,7 @@ ] }, { - "teal": 265, + "teal": 263, "source": 99, "pc": [ 325, @@ -1071,42 +1065,42 @@ ] }, { - "teal": 266, + "teal": 264, "source": 99, "pc": [ 327 ] }, { - "teal": 267, + "teal": 265, "source": 99, "pc": [ 328 ] }, { - "teal": 268, + "teal": 266, "source": 99, "pc": [ 329 ] }, { - "teal": 269, + "teal": 267, "source": 99, "pc": [ 330 ] }, { - "teal": 270, + "teal": 268, "source": 99, "pc": [ 331 ] }, { - "teal": 274, + "teal": 272, "source": 101, "pc": [ 332, @@ -1114,14 +1108,14 @@ ] }, { - "teal": 275, + "teal": 273, "source": 101, "pc": [ 334 ] }, { - "teal": 276, + "teal": 274, "source": 101, "pc": [ 335, @@ -1129,28 +1123,28 @@ ] }, { - "teal": 277, + "teal": 275, "source": 101, "pc": [ 337 ] }, { - "teal": 278, + "teal": 276, "source": 101, "pc": [ 338 ] }, { - "teal": 279, + "teal": 277, "source": 101, "pc": [ 339 ] }, { - "teal": 280, + "teal": 278, "source": 101, "pc": [ 340, @@ -1158,7 +1152,7 @@ ] }, { - "teal": 284, + "teal": 282, "source": 103, "pc": [ 342, @@ -1166,7 +1160,7 @@ ] }, { - "teal": 285, + "teal": 283, "source": 103, "pc": [ 344, @@ -1174,14 +1168,14 @@ ] }, { - "teal": 286, + "teal": 284, "source": 103, "pc": [ 346 ] }, { - "teal": 287, + "teal": 285, "source": 103, "pc": [ 347, @@ -1189,7 +1183,7 @@ ] }, { - "teal": 291, + "teal": 289, "source": 104, "pc": [ 349, @@ -1197,7 +1191,7 @@ ] }, { - "teal": 292, + "teal": 290, "source": 104, "pc": [ 351, @@ -1205,7 +1199,7 @@ ] }, { - "teal": 293, + "teal": 291, "source": 104, "pc": [ 353, @@ -1213,21 +1207,21 @@ ] }, { - "teal": 294, + "teal": 292, "source": 104, "pc": [ 355 ] }, { - "teal": 295, + "teal": 293, "source": 104, "pc": [ 356 ] }, { - "teal": 296, + "teal": 294, "source": 104, "pc": [ 357, @@ -1235,42 +1229,42 @@ ] }, { - "teal": 297, + "teal": 295, "source": 104, "pc": [ 359 ] }, { - "teal": 298, + "teal": 296, "source": 104, "pc": [ 360 ] }, { - "teal": 299, + "teal": 297, "source": 104, "pc": [ 361 ] }, { - "teal": 300, + "teal": 298, "source": 104, "pc": [ 362 ] }, { - "teal": 301, + "teal": 299, "source": 104, "pc": [ 363 ] }, { - "teal": 305, + "teal": 303, "source": 105, "pc": [ 364, @@ -1278,7 +1272,7 @@ ] }, { - "teal": 306, + "teal": 304, "source": 105, "pc": [ 366, @@ -1286,14 +1280,14 @@ ] }, { - "teal": 307, + "teal": 305, "source": 105, "pc": [ 368 ] }, { - "teal": 308, + "teal": 306, "source": 105, "pc": [ 369, @@ -1301,14 +1295,14 @@ ] }, { - "teal": 309, + "teal": 307, "source": 105, "pc": [ 371 ] }, { - "teal": 310, + "teal": 308, "source": 105, "pc": [ 372, @@ -1316,7 +1310,7 @@ ] }, { - "teal": 319, + "teal": 317, "source": 107, "pc": [ 374, @@ -1324,7 +1318,7 @@ ] }, { - "teal": 320, + "teal": 318, "source": 108, "pc": [ 376, @@ -1332,7 +1326,7 @@ ] }, { - "teal": 321, + "teal": 319, "source": 108, "pc": [ 378, @@ -1340,14 +1334,14 @@ ] }, { - "teal": 322, + "teal": 320, "source": 108, "pc": [ 380 ] }, { - "teal": 323, + "teal": 321, "source": 108, "pc": [ 381, @@ -1355,14 +1349,14 @@ ] }, { - "teal": 324, + "teal": 322, "source": 108, "pc": [ 383 ] }, { - "teal": 325, + "teal": 323, "source": 108, "pc": [ 384, @@ -1370,28 +1364,28 @@ ] }, { - "teal": 326, + "teal": 324, "source": 108, "pc": [ 386 ] }, { - "teal": 327, + "teal": 325, "source": 108, "pc": [ 387 ] }, { - "teal": 328, + "teal": 326, "source": 108, "pc": [ 388 ] }, { - "teal": 331, + "teal": 329, "source": 107, "pc": [ 389, @@ -1399,7 +1393,7 @@ ] }, { - "teal": 332, + "teal": 330, "source": 109, "pc": [ 391, @@ -1407,7 +1401,7 @@ ] }, { - "teal": 333, + "teal": 331, "source": 109, "pc": [ 393, @@ -1415,21 +1409,21 @@ ] }, { - "teal": 334, + "teal": 332, "source": 109, "pc": [ 395 ] }, { - "teal": 335, + "teal": 333, "source": 109, "pc": [ 396 ] }, { - "teal": 338, + "teal": 336, "source": 107, "pc": [ 397, @@ -1437,7 +1431,7 @@ ] }, { - "teal": 339, + "teal": 337, "source": 110, "pc": [ 399, @@ -1445,7 +1439,7 @@ ] }, { - "teal": 340, + "teal": 338, "source": 110, "pc": [ 401, @@ -1453,21 +1447,21 @@ ] }, { - "teal": 341, + "teal": 339, "source": 110, "pc": [ 403 ] }, { - "teal": 342, + "teal": 340, "source": 110, "pc": [ 404 ] }, { - "teal": 346, + "teal": 344, "source": 113, "pc": [ 405, @@ -1475,7 +1469,7 @@ ] }, { - "teal": 347, + "teal": 345, "source": 113, "pc": [ 407, @@ -1483,21 +1477,21 @@ ] }, { - "teal": 348, + "teal": 346, "source": 113, "pc": [ 409 ] }, { - "teal": 349, + "teal": 347, "source": 95, "pc": [ 410 ] }, { - "teal": 352, + "teal": 350, "source": 117, "pc": [ 411, @@ -1506,7 +1500,7 @@ ] }, { - "teal": 357, + "teal": 355, "source": 118, "pc": [ 414, @@ -1515,35 +1509,35 @@ ] }, { - "teal": 358, + "teal": 356, "source": 118, "pc": [ 417 ] }, { - "teal": 359, + "teal": 357, "source": 118, "pc": [ 418 ] }, { - "teal": 360, + "teal": 358, "source": 118, "pc": [ 419 ] }, { - "teal": 361, + "teal": 359, "source": 118, "pc": [ 420 ] }, { - "teal": 362, + "teal": 360, "source": 118, "pc": [ 421, @@ -1552,42 +1546,42 @@ ] }, { - "teal": 367, + "teal": 365, "source": 119, "pc": [ 424 ] }, { - "teal": 368, + "teal": 366, "source": 119, "pc": [ 425 ] }, { - "teal": 369, + "teal": 367, "source": 119, "pc": [ 426 ] }, { - "teal": 370, + "teal": 368, "source": 119, "pc": [ 427 ] }, { - "teal": 371, + "teal": 369, "source": 119, "pc": [ 428 ] }, { - "teal": 372, + "teal": 370, "source": 118, "pc": [ 429, @@ -1596,28 +1590,28 @@ ] }, { - "teal": 383, + "teal": 381, "source": 121, "pc": [ 432 ] }, { - "teal": 384, + "teal": 382, "source": 121, "pc": [ 433 ] }, { - "teal": 385, + "teal": 383, "source": 121, "pc": [ 434 ] }, { - "teal": 386, + "teal": 384, "source": 121, "pc": [ 435, @@ -1625,7 +1619,7 @@ ] }, { - "teal": 387, + "teal": 385, "source": 122, "pc": [ 437, @@ -1637,7 +1631,7 @@ ] }, { - "teal": 388, + "teal": 386, "source": 122, "pc": [ 443, @@ -1645,7 +1639,7 @@ ] }, { - "teal": 392, + "teal": 390, "source": 123, "pc": [ 445, @@ -1653,21 +1647,21 @@ ] }, { - "teal": 393, + "teal": 391, "source": 123, "pc": [ 447 ] }, { - "teal": 394, + "teal": 392, "source": 123, "pc": [ 448 ] }, { - "teal": 395, + "teal": 393, "source": 123, "pc": [ 449, @@ -1675,7 +1669,7 @@ ] }, { - "teal": 396, + "teal": 394, "source": 123, "pc": [ 451, @@ -1685,7 +1679,7 @@ ] }, { - "teal": 397, + "teal": 395, "source": 123, "pc": [ 455, @@ -1693,7 +1687,7 @@ ] }, { - "teal": 401, + "teal": 399, "source": 124, "pc": [ 457, @@ -1701,14 +1695,14 @@ ] }, { - "teal": 402, + "teal": 400, "source": 124, "pc": [ 459 ] }, { - "teal": 403, + "teal": 401, "source": 124, "pc": [ 460, @@ -1716,14 +1710,14 @@ ] }, { - "teal": 407, + "teal": 405, "source": 125, "pc": [ 462 ] }, { - "teal": 408, + "teal": 406, "source": 125, "pc": [ 463, @@ -1731,14 +1725,14 @@ ] }, { - "teal": 412, + "teal": 410, "source": 126, "pc": [ 465 ] }, { - "teal": 413, + "teal": 411, "source": 126, "pc": [ 466, @@ -1746,14 +1740,14 @@ ] }, { - "teal": 416, + "teal": 414, "source": 121, "pc": [ 468 ] }, { - "teal": 417, + "teal": 415, "source": 121, "pc": [ 469, @@ -1761,21 +1755,21 @@ ] }, { - "teal": 418, + "teal": 416, "source": 121, "pc": [ 471 ] }, { - "teal": 419, + "teal": 417, "source": 121, "pc": [ 472 ] }, { - "teal": 420, + "teal": 418, "source": 121, "pc": [ 473, @@ -1783,7 +1777,7 @@ ] }, { - "teal": 421, + "teal": 419, "source": 121, "pc": [ 475, @@ -1792,21 +1786,21 @@ ] }, { - "teal": 422, + "teal": 420, "source": 121, "pc": [ 478 ] }, { - "teal": 425, + "teal": 423, "source": 117, "pc": [ 479 ] }, { - "teal": 431, + "teal": 430, "source": 133, "pc": [ 480, @@ -1815,63 +1809,57 @@ ] }, { - "teal": 434, + "teal": 431, "source": 133, "pc": [ - 483, - 484, - 485 + 483 ] }, { - "teal": 435, + "teal": 432, "source": 133, "pc": [ - 486 + 484, + 485 ] }, { - "teal": 436, + "teal": 435, "source": 133, "pc": [ + 486, 487, 488 ] }, { - "teal": 439, - "source": 133, - "pc": [ - 489, - 490, - 491 - ] - }, - { - "teal": 440, + "teal": 436, "source": 133, "pc": [ - 492 + 489 ] }, { - "teal": 441, + "teal": 437, "source": 133, "pc": [ - 493 + 490 ] }, { - "teal": 444, + "teal": 440, "source": 133, "pc": [ + 491, + 492, + 493, 494, 495, 496 ] }, { - "teal": 448, + "teal": 444, "source": 135, "pc": [ 497, @@ -1880,49 +1868,49 @@ ] }, { - "teal": 449, + "teal": 445, "source": 135, "pc": [ 500 ] }, { - "teal": 450, + "teal": 446, "source": 135, "pc": [ 501 ] }, { - "teal": 451, + "teal": 447, "source": 135, "pc": [ 502 ] }, { - "teal": 452, + "teal": 448, "source": 135, "pc": [ 503 ] }, { - "teal": 453, + "teal": 449, "source": 135, "pc": [ 504 ] }, { - "teal": 454, + "teal": 450, "source": 135, "pc": [ 505 ] }, { - "teal": 458, + "teal": 454, "source": 136, "pc": [ 506, @@ -1931,7 +1919,7 @@ ] }, { - "teal": 462, + "teal": 458, "source": 140, "pc": [ 509, @@ -1939,14 +1927,14 @@ ] }, { - "teal": 463, + "teal": 459, "source": 140, "pc": [ 511 ] }, { - "teal": 464, + "teal": 460, "source": 140, "pc": [ 512, @@ -1954,14 +1942,14 @@ ] }, { - "teal": 468, + "teal": 464, "source": 142, "pc": [ 514 ] }, { - "teal": 469, + "teal": 465, "source": 142, "pc": [ 515, @@ -1969,21 +1957,21 @@ ] }, { - "teal": 474, + "teal": 470, "source": 146, "pc": [ 517 ] }, { - "teal": 475, + "teal": 471, "source": 146, "pc": [ 518 ] }, { - "teal": 476, + "teal": 472, "source": 146, "pc": [ 519, @@ -1991,14 +1979,14 @@ ] }, { - "teal": 477, + "teal": 473, "source": 146, "pc": [ 521 ] }, { - "teal": 478, + "teal": 474, "source": 146, "pc": [ 522, @@ -2006,7 +1994,7 @@ ] }, { - "teal": 482, + "teal": 478, "source": 148, "pc": [ 524, @@ -2014,7 +2002,7 @@ ] }, { - "teal": 483, + "teal": 479, "source": 148, "pc": [ 526, @@ -2022,14 +2010,14 @@ ] }, { - "teal": 484, + "teal": 480, "source": 148, "pc": [ 528 ] }, { - "teal": 485, + "teal": 481, "source": 148, "pc": [ 529, @@ -2037,7 +2025,7 @@ ] }, { - "teal": 489, + "teal": 485, "source": 150, "pc": [ 531, @@ -2045,7 +2033,7 @@ ] }, { - "teal": 490, + "teal": 486, "source": 5, "pc": [ 533, @@ -2053,7 +2041,7 @@ ] }, { - "teal": 491, + "teal": 487, "source": 5, "pc": [ 535, @@ -2061,7 +2049,7 @@ ] }, { - "teal": 492, + "teal": 488, "source": 150, "pc": [ 537, @@ -2069,28 +2057,28 @@ ] }, { - "teal": 493, + "teal": 489, "source": 150, "pc": [ 539 ] }, { - "teal": 494, + "teal": 490, "source": 150, "pc": [ 540 ] }, { - "teal": 495, + "teal": 491, "source": 150, "pc": [ 541 ] }, { - "teal": 496, + "teal": 492, "source": 150, "pc": [ 542, @@ -2098,28 +2086,28 @@ ] }, { - "teal": 497, + "teal": 493, "source": 150, "pc": [ 544 ] }, { - "teal": 498, + "teal": 494, "source": 150, "pc": [ 545 ] }, { - "teal": 499, + "teal": 495, "source": 150, "pc": [ 546 ] }, { - "teal": 500, + "teal": 496, "source": 150, "pc": [ 547, @@ -2127,7 +2115,7 @@ ] }, { - "teal": 501, + "teal": 497, "source": 151, "pc": [ 549, @@ -2135,14 +2123,14 @@ ] }, { - "teal": 502, + "teal": 498, "source": 151, "pc": [ 551 ] }, { - "teal": 503, + "teal": 499, "source": 151, "pc": [ 552, @@ -2151,7 +2139,7 @@ ] }, { - "teal": 504, + "teal": 500, "source": 151, "pc": [ 555, @@ -2159,7 +2147,7 @@ ] }, { - "teal": 505, + "teal": 501, "source": 151, "pc": [ 557, @@ -2167,21 +2155,21 @@ ] }, { - "teal": 506, + "teal": 502, "source": 151, "pc": [ 559 ] }, { - "teal": 507, + "teal": 503, "source": 151, "pc": [ 560 ] }, { - "teal": 510, + "teal": 506, "source": 145, "pc": [ 561, @@ -2190,7 +2178,7 @@ ] }, { - "teal": 515, + "teal": 511, "source": 153, "pc": [ 564, @@ -2198,7 +2186,7 @@ ] }, { - "teal": 516, + "teal": 512, "source": 153, "pc": [ 566, @@ -2207,14 +2195,14 @@ ] }, { - "teal": 521, + "teal": 517, "source": 153, "pc": [ 569 ] }, { - "teal": 522, + "teal": 518, "source": 153, "pc": [ 570, @@ -2222,14 +2210,14 @@ ] }, { - "teal": 523, + "teal": 519, "source": 153, "pc": [ 572 ] }, { - "teal": 524, + "teal": 520, "source": 153, "pc": [ 573, @@ -2237,14 +2225,14 @@ ] }, { - "teal": 525, + "teal": 521, "source": 153, "pc": [ 575 ] }, { - "teal": 526, + "teal": 522, "source": 153, "pc": [ 576, @@ -2252,42 +2240,42 @@ ] }, { - "teal": 527, + "teal": 523, "source": 153, "pc": [ 578 ] }, { - "teal": 528, + "teal": 524, "source": 153, "pc": [ 579 ] }, { - "teal": 529, + "teal": 525, "source": 153, "pc": [ 580 ] }, { - "teal": 530, + "teal": 526, "source": 153, "pc": [ 581 ] }, { - "teal": 535, + "teal": 531, "source": 155, "pc": [ 582 ] }, { - "teal": 536, + "teal": 532, "source": 155, "pc": [ 583, @@ -2295,7 +2283,7 @@ ] }, { - "teal": 537, + "teal": 533, "source": 155, "pc": [ 585, @@ -2303,28 +2291,28 @@ ] }, { - "teal": 538, + "teal": 534, "source": 155, "pc": [ 587 ] }, { - "teal": 539, + "teal": 535, "source": 155, "pc": [ 588 ] }, { - "teal": 543, + "teal": 539, "source": 156, "pc": [ 589 ] }, { - "teal": 544, + "teal": 540, "source": 156, "pc": [ 590, @@ -2332,14 +2320,14 @@ ] }, { - "teal": 545, + "teal": 541, "source": 156, "pc": [ 592 ] }, { - "teal": 546, + "teal": 542, "source": 156, "pc": [ 593, @@ -2347,14 +2335,14 @@ ] }, { - "teal": 547, + "teal": 543, "source": 156, "pc": [ 595 ] }, { - "teal": 548, + "teal": 544, "source": 156, "pc": [ 596, @@ -2362,82 +2350,70 @@ ] }, { - "teal": 549, + "teal": 545, "source": 156, "pc": [ 598 ] }, { - "teal": 550, + "teal": 546, "source": 156, "pc": [ 599 ] }, { - "teal": 551, + "teal": 547, "source": 156, "pc": [ 600 ] }, { - "teal": 552, + "teal": 548, "source": 156, "pc": [ 601 ] }, { - "teal": 558, + "teal": 555, "source": 160, "pc": [ - 602 + 602, + 603, + 604 ] }, { - "teal": 561, + "teal": 556, "source": 160, "pc": [ - 603, - 604, 605 ] }, { - "teal": 562, + "teal": 557, "source": 160, "pc": [ 606 ] }, { - "teal": 563, - "source": 160, - "pc": [ - 607 - ] - }, - { - "teal": 566, + "teal": 560, "source": 160, "pc": [ + 607, 608, 609, - 610 - ] - }, - { - "teal": 570, - "source": 161, - "pc": [ + 610, 611, 612 ] }, { - "teal": 571, + "teal": 564, "source": 161, "pc": [ 613, @@ -2445,7 +2421,7 @@ ] }, { - "teal": 575, + "teal": 565, "source": 161, "pc": [ 615, @@ -2453,161 +2429,161 @@ ] }, { - "teal": 576, - "source": 161, - "pc": [ - 617 - ] - }, - { - "teal": 577, + "teal": 569, "source": 161, "pc": [ + 617, 618 ] }, { - "teal": 578, - "source": 163, + "teal": 570, + "source": 161, "pc": [ - 619, - 620, - 621 + 619 ] }, { - "teal": 579, - "source": 163, + "teal": 571, + "source": 161, "pc": [ - 622 + 620 ] }, { - "teal": 580, + "teal": 572, "source": 163, "pc": [ + 621, + 622, 623 ] }, { - "teal": 581, + "teal": 573, "source": 163, "pc": [ 624 ] }, { - "teal": 582, + "teal": 574, "source": 163, "pc": [ 625 ] }, { - "teal": 583, + "teal": 575, "source": 163, "pc": [ 626 ] }, { - "teal": 587, - "source": 161, + "teal": 576, + "source": 163, "pc": [ - 627, - 628 + 627 ] }, { - "teal": 588, - "source": 161, + "teal": 577, + "source": 163, "pc": [ - 629 + 628 ] }, { - "teal": 589, + "teal": 581, "source": 161, "pc": [ + 629, 630 ] }, { - "teal": 590, - "source": 164, + "teal": 582, + "source": 161, "pc": [ - 631, - 632, - 633 + 631 ] }, { - "teal": 591, - "source": 164, + "teal": 583, + "source": 161, "pc": [ - 634 + 632 ] }, { - "teal": 592, + "teal": 584, "source": 164, "pc": [ + 633, + 634, 635 ] }, { - "teal": 593, + "teal": 585, "source": 164, "pc": [ 636 ] }, { - "teal": 594, + "teal": 586, "source": 164, "pc": [ 637 ] }, { - "teal": 595, + "teal": 587, "source": 164, "pc": [ 638 ] }, { - "teal": 605, - "source": 166, + "teal": 588, + "source": 164, "pc": [ 639 ] }, { - "teal": 606, - "source": 166, + "teal": 589, + "source": 164, "pc": [ 640 ] }, { - "teal": 607, + "teal": 599, + "source": 166, + "pc": [ + 641 + ] + }, + { + "teal": 600, "source": 166, "pc": [ - 641, 642 ] }, { - "teal": 611, - "source": 167, + "teal": 601, + "source": 166, "pc": [ 643, 644 ] }, { - "teal": 612, + "teal": 605, "source": 167, "pc": [ 645, @@ -2615,82 +2591,82 @@ ] }, { - "teal": 616, - "source": 168, + "teal": 606, + "source": 167, "pc": [ - 647 + 647, + 648 ] }, { - "teal": 617, + "teal": 610, "source": 168, "pc": [ - 648 + 649 ] }, { - "teal": 618, + "teal": 611, "source": 168, "pc": [ - 649, 650 ] }, { - "teal": 622, - "source": 169, + "teal": 612, + "source": 168, "pc": [ 651, 652 ] }, { - "teal": 623, + "teal": 616, "source": 169, "pc": [ - 653 + 653, + 654 ] }, { - "teal": 624, + "teal": 617, "source": 169, "pc": [ - 654 + 655 ] }, { - "teal": 625, + "teal": 618, "source": 169, "pc": [ - 655, 656 ] }, { - "teal": 626, + "teal": 619, "source": 169, "pc": [ - 657 + 657, + 658 ] }, { - "teal": 627, + "teal": 620, "source": 169, "pc": [ - 658, 659 ] }, { - "teal": 631, - "source": 170, + "teal": 621, + "source": 169, "pc": [ 660, 661 ] }, { - "teal": 632, + "teal": 625, "source": 170, "pc": [ 662, @@ -2698,44 +2674,44 @@ ] }, { - "teal": 636, - "source": 171, + "teal": 626, + "source": 170, "pc": [ - 664 + 664, + 665 ] }, { - "teal": 637, + "teal": 630, "source": 171, "pc": [ - 665, 666 ] }, { - "teal": 640, - "source": 166, + "teal": 631, + "source": 171, "pc": [ - 667 + 667, + 668 ] }, { - "teal": 641, - "source": 160, + "teal": 634, + "source": 166, "pc": [ - 668 + 669 ] }, { - "teal": 649, - "source": 180, + "teal": 635, + "source": 160, "pc": [ - 669, 670 ] }, { - "teal": 652, + "teal": 644, "source": 180, "pc": [ 671, @@ -2744,499 +2720,499 @@ ] }, { - "teal": 653, + "teal": 645, "source": 180, "pc": [ 674 ] }, { - "teal": 654, + "teal": 646, "source": 180, "pc": [ 675 ] }, { - "teal": 657, + "teal": 649, "source": 180, "pc": [ 676, 677, - 678 + 678, + 679, + 680, + 681 ] }, { - "teal": 661, + "teal": 653, "source": 181, "pc": [ - 679, - 680, - 681 + 682, + 683, + 684 ] }, { - "teal": 662, + "teal": 654, "source": 181, "pc": [ - 682 + 685 ] }, { - "teal": 663, + "teal": 655, "source": 181, "pc": [ - 683 + 686 ] }, { - "teal": 664, + "teal": 656, "source": 181, "pc": [ - 684 + 687 ] }, { - "teal": 665, + "teal": 657, "source": 181, "pc": [ - 685 + 688 ] }, { - "teal": 666, + "teal": 658, "source": 181, "pc": [ - 686 + 689 ] }, { - "teal": 667, + "teal": 659, "source": 181, "pc": [ - 687 + 690 ] }, { - "teal": 671, + "teal": 663, "source": 182, "pc": [ - 688, - 689 + 691, + 692 ] }, { - "teal": 672, + "teal": 664, "source": 182, "pc": [ - 690, - 691 + 693, + 694 ] }, { - "teal": 673, + "teal": 665, "source": 182, "pc": [ - 692 + 695 ] }, { - "teal": 674, + "teal": 666, "source": 182, "pc": [ - 693, - 694, - 695 + 696, + 697, + 698 ] }, { - "teal": 675, + "teal": 667, "source": 182, "pc": [ - 696 + 699 ] }, { - "teal": 676, + "teal": 668, "source": 182, "pc": [ - 697 + 700 ] }, { - "teal": 677, + "teal": 669, "source": 182, "pc": [ - 698 + 701 ] }, { - "teal": 681, + "teal": 673, "source": 184, "pc": [ - 699, - 700 + 702, + 703 ] }, { - "teal": 682, + "teal": 674, "source": 184, "pc": [ - 701, - 702 + 704, + 705 ] }, { - "teal": 686, + "teal": 678, "source": 184, "pc": [ - 703, - 704 + 706, + 707 ] }, { - "teal": 687, + "teal": 679, "source": 184, "pc": [ - 705 + 708 ] }, { - "teal": 688, + "teal": 680, "source": 184, "pc": [ - 706 + 709 ] }, { - "teal": 689, + "teal": 681, "source": 185, "pc": [ - 707, - 708, - 709 + 710, + 711, + 712 ] }, { - "teal": 690, + "teal": 682, "source": 185, "pc": [ - 710 + 713 ] }, { - "teal": 691, + "teal": 683, "source": 184, "pc": [ - 711, - 712 + 714, + 715 ] }, { - "teal": 692, + "teal": 684, "source": 184, "pc": [ - 713 + 716 ] }, { - "teal": 693, + "teal": 685, "source": 184, "pc": [ - 714 + 717 ] }, { - "teal": 694, + "teal": 686, "source": 185, "pc": [ - 715, - 716, - 717 + 718, + 719, + 720 ] }, { - "teal": 695, + "teal": 687, "source": 185, "pc": [ - 718 + 721 ] }, { - "teal": 696, + "teal": 688, "source": 185, "pc": [ - 719 + 722 ] }, { - "teal": 697, + "teal": 689, "source": 185, "pc": [ - 720 + 723 ] }, { - "teal": 698, + "teal": 690, "source": 185, "pc": [ - 721 + 724 ] }, { - "teal": 699, + "teal": 691, "source": 185, "pc": [ - 722, - 723 + 725, + 726 ] }, { - "teal": 703, + "teal": 695, "source": 187, "pc": [ - 724, - 725 + 727, + 728 ] }, { - "teal": 704, + "teal": 696, "source": 187, "pc": [ - 726 + 729 ] }, { - "teal": 712, + "teal": 704, "source": 189, "pc": [ - 727 + 730 ] }, { - "teal": 713, + "teal": 705, "source": 189, "pc": [ - 728 + 731 ] }, { - "teal": 714, + "teal": 706, "source": 189, "pc": [ - 729, - 730 + 732, + 733 ] }, { - "teal": 718, + "teal": 710, "source": 190, "pc": [ - 731, - 732 + 734, + 735 ] }, { - "teal": 719, + "teal": 711, "source": 190, "pc": [ - 733 + 736 ] }, { - "teal": 720, + "teal": 712, "source": 190, "pc": [ - 734, - 735 + 737, + 738 ] }, { - "teal": 721, + "teal": 713, "source": 190, "pc": [ - 736 + 739 ] }, { - "teal": 722, + "teal": 714, "source": 190, "pc": [ - 737, - 738 + 740, + 741 ] }, { - "teal": 726, + "teal": 718, "source": 191, "pc": [ - 739, - 740 + 742, + 743 ] }, { - "teal": 727, + "teal": 719, "source": 191, "pc": [ - 741, - 742 + 744, + 745 ] }, { - "teal": 731, + "teal": 723, "source": 192, "pc": [ - 743 + 746 ] }, { - "teal": 732, + "teal": 724, "source": 192, "pc": [ - 744, - 745 + 747, + 748 ] }, { - "teal": 735, + "teal": 727, "source": 189, "pc": [ - 746 + 749 ] }, { - "teal": 736, + "teal": 728, "source": 180, "pc": [ - 747 + 750 ] }, { - "teal": 739, + "teal": 731, "source": 8, "pc": [ - 748, - 749, - 750, 751, 752, - 753 - ] - }, - { - "teal": 740, - "source": 8, - "pc": [ + 753, 754, 755, 756 ] }, { - "teal": 741, + "teal": 732, "source": 8, "pc": [ 757, 758, - 759, - 760 + 759 ] }, { - "teal": 742, + "teal": 733, "source": 8, "pc": [ - 761 + 760, + 761, + 762, + 763 ] }, { - "teal": 745, + "teal": 734, "source": 8, "pc": [ - 762, - 763, - 764, - 765, - 766, - 767 + 764 ] }, { - "teal": 746, + "teal": 737, "source": 8, "pc": [ + 765, + 766, + 767, 768, 769, - 770, - 771, - 772, - 773 + 770 ] }, { - "teal": 747, + "teal": 738, "source": 8, "pc": [ + 771, + 772, + 773, 774, 775, - 776, - 777, - 778, - 779 + 776 ] }, { - "teal": 748, + "teal": 739, "source": 8, "pc": [ + 777, + 778, + 779, 780, 781, - 782, - 783, - 784, - 785 + 782 ] }, { - "teal": 749, + "teal": 740, "source": 8, "pc": [ + 783, + 784, + 785, 786, 787, - 788, - 789, - 790, - 791 + 788 ] }, { - "teal": 750, + "teal": 741, "source": 8, "pc": [ + 789, + 790, + 791, 792, 793, - 794, - 795, - 796, - 797 + 794 ] }, { - "teal": 751, + "teal": 742, "source": 8, "pc": [ + 795, + 796, + 797, 798, 799, 800 ] }, { - "teal": 752, + "teal": 743, "source": 8, "pc": [ 801, 802, - 803, + 803 + ] + }, + { + "teal": 744, + "source": 8, + "pc": [ 804, 805, 806, @@ -3247,14 +3223,17 @@ 811, 812, 813, - 814 + 814, + 815, + 816, + 817 ] }, { - "teal": 753, + "teal": 745, "source": 8, "pc": [ - 815 + 818 ] } ] \ No newline at end of file diff --git a/examples/raffle/raffle.algo.ts b/examples/raffle/raffle.algo.ts index f56c98fdb..0f71ecdac 100644 --- a/examples/raffle/raffle.algo.ts +++ b/examples/raffle/raffle.algo.ts @@ -123,7 +123,7 @@ class NFTRaffle extends Contract { methodArgs: [this.drawRound.value, ''], applicationID: Application.fromID(this.randomnessOracle.value), fee: 0, - onCompletion: 'NoOp', + onCompletion: OnCompletion.NoOp, }); } } diff --git a/src/lib/compiler.ts b/src/lib/compiler.ts index 6b5f505a6..ed8554480 100644 --- a/src/lib/compiler.ts +++ b/src/lib/compiler.ts @@ -5034,9 +5034,12 @@ export default class Compiler { this.pushComments(p); if (key === 'onCompletion') { - if (!ts.isPropertyAssignment(p) || !ts.isStringLiteral(p.initializer)) - throw new Error('OnCompletion key must be a string'); - this.pushVoid(p.initializer, `int ${p.initializer.text}`); + if (!ts.isPropertyAssignment(p) || !ts.isPropertyAccessExpression(p.initializer)) + throw new Error('OnCompletion expects OnCompletion enum'); + this.pushVoid( + p.initializer, + `int ${ON_COMPLETES.indexOf(p.initializer.name.getText() as OnComplete)} // ${p.initializer.name.getText()}` + ); this.pushVoid(p, 'itxn_field OnCompletion'); } else if (key === 'methodArgs') { if (typeArgs === undefined || !ts.isTupleTypeNode(typeArgs[0]))