diff --git a/flake.lock b/flake.lock index f95210e86..4369ffcc1 100644 --- a/flake.lock +++ b/flake.lock @@ -362,11 +362,11 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1773260212, - "narHash": "sha256-lYbvufol78/ziIlZm043NT2byudb6NQpGHhYhVSlkVY=", + "lastModified": 1776017067, + "narHash": "sha256-oEp8fqJweZd5doqvH/aBAtc6NzZh+fh0tOhR09gQXck=", "owner": "nixos", "repo": "nixpkgs", - "rev": "37e1923adb6229cea0d12a5921b75c976017ccfe", + "rev": "a5a7cf16648d79134eb4da0e3354b08913917b2f", "type": "github" }, "original": { @@ -459,11 +459,11 @@ "solc": "solc_2" }, "locked": { - "lastModified": 1774379584, - "narHash": "sha256-xZagAIfb/9eZWO15MF8NQiqmrSWOIB5MTy91ghR+ZPI=", + "lastModified": 1776019532, + "narHash": "sha256-0aMnHCZ2fR0+ZwuRHFouYYUQqYL/dSp5cOgka0m6vE4=", "owner": "rainlanguage", "repo": "rainix", - "rev": "3f6497ddaf92e2db890aa3aef831c89367e75766", + "rev": "9babaac787d1e1119609b0d89c33a6b42249c066", "type": "github" }, "original": { diff --git a/script/BuildPointers.sol b/script/BuildPointers.sol index 054b02b11..4e7137528 100644 --- a/script/BuildPointers.sol +++ b/script/BuildPointers.sol @@ -30,7 +30,7 @@ contract BuildPointers is Script { /// @notice Generates a Solidity address constant declaration string. /// @param addr The address value. /// @return A string containing the Solidity code for the address constant. - function addressConstantString(address addr) internal view returns (string memory) { + function addressConstantString(address addr) internal pure returns (string memory) { return string.concat( "\n", "/// @dev The deterministic deploy address of the contract when deployed via\n", diff --git a/src/generated/Rainlang.pointers.sol b/src/generated/Rainlang.pointers.sol index 76c7f9619..20f96498f 100644 --- a/src/generated/Rainlang.pointers.sol +++ b/src/generated/Rainlang.pointers.sol @@ -10,16 +10,16 @@ pragma solidity ^0.8.25; // file needs the contract to exist so that it can be compiled. /// @dev Hash of the known bytecode. -bytes32 constant BYTECODE_HASH = bytes32(0xeb2e198804bcd1c08912d1467d176866536d12937ad18776552bf99a648581e7); +bytes32 constant BYTECODE_HASH = bytes32(0x986993ae9bce39b2b7396c4e3e0df86f4ffecd5bcc191cb38391ddd697a7254f); /// @dev The deterministic deploy address of the contract when deployed via /// the Zoltu factory. -address constant DEPLOYED_ADDRESS = address(0xb1E2C031d906D2C96B825AC7B18A476E1DaC5B9f); +address constant DEPLOYED_ADDRESS = address(0x52F99eEff08a29fb1a7E7D7753d18caBeb28F8e7); /// @dev The creation bytecode of the contract. bytes constant CREATION_CODE = - hex"6080604052348015600e575f80fd5b506101f78061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610064575f3560e01c8063107628021161004d57806310762802146100cb5780634501e517146100e5578063f2c4da93146100ff575f80fd5b806301ffc9a7146100685780630c1916a414610090575b5f80fd5b61007b6100763660046101b1565b610119565b60405190151581526020015b60405180910390f35b73dfc11de118ee6fcf787e2b17f42dc174bca4cf045b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610087565b73a4daeb07625879f4a584f92ddcbe3b64025ce11f6100a6565b73a8d499b9dcac7ec3373755e29911d9fa77ec79086100a6565b731aa775533e28b1d843e1a589034984e3a62005dc6100a6565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167fabaa01220000000000000000000000000000000000000000000000000000000014806101ab57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f602082840312156101c1575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146101f0575f80fd5b939250505056"; + hex"6080604052348015600e575f80fd5b506101f78061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610064575f3560e01c8063107628021161004d57806310762802146100cb5780634501e517146100e5578063f2c4da93146100ff575f80fd5b806301ffc9a7146100685780630c1916a414610090575b5f80fd5b61007b6100763660046101b1565b610119565b60405190151581526020015b60405180910390f35b73a0c9a33f4d13576ad0ae36cd431466ae641a951f5b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610087565b73db9a055c24070bfac87f1a44dbaf34ac5ef7cb056100a6565b73a8d499b9dcac7ec3373755e29911d9fa77ec79086100a6565b731aa775533e28b1d843e1a589034984e3a62005dc6100a6565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167fabaa01220000000000000000000000000000000000000000000000000000000014806101ab57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f602082840312156101c1575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146101f0575f80fd5b939250505056"; /// @dev The runtime bytecode of the contract. bytes constant RUNTIME_CODE = - hex"608060405234801561000f575f80fd5b5060043610610064575f3560e01c8063107628021161004d57806310762802146100cb5780634501e517146100e5578063f2c4da93146100ff575f80fd5b806301ffc9a7146100685780630c1916a414610090575b5f80fd5b61007b6100763660046101b1565b610119565b60405190151581526020015b60405180910390f35b73dfc11de118ee6fcf787e2b17f42dc174bca4cf045b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610087565b73a4daeb07625879f4a584f92ddcbe3b64025ce11f6100a6565b73a8d499b9dcac7ec3373755e29911d9fa77ec79086100a6565b731aa775533e28b1d843e1a589034984e3a62005dc6100a6565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167fabaa01220000000000000000000000000000000000000000000000000000000014806101ab57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f602082840312156101c1575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146101f0575f80fd5b939250505056"; + hex"608060405234801561000f575f80fd5b5060043610610064575f3560e01c8063107628021161004d57806310762802146100cb5780634501e517146100e5578063f2c4da93146100ff575f80fd5b806301ffc9a7146100685780630c1916a414610090575b5f80fd5b61007b6100763660046101b1565b610119565b60405190151581526020015b60405180910390f35b73a0c9a33f4d13576ad0ae36cd431466ae641a951f5b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610087565b73db9a055c24070bfac87f1a44dbaf34ac5ef7cb056100a6565b73a8d499b9dcac7ec3373755e29911d9fa77ec79086100a6565b731aa775533e28b1d843e1a589034984e3a62005dc6100a6565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167fabaa01220000000000000000000000000000000000000000000000000000000014806101ab57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b5f602082840312156101c1575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146101f0575f80fd5b939250505056"; diff --git a/src/generated/RainlangExpressionDeployer.pointers.sol b/src/generated/RainlangExpressionDeployer.pointers.sol index 38108a712..3f5862fbd 100644 --- a/src/generated/RainlangExpressionDeployer.pointers.sol +++ b/src/generated/RainlangExpressionDeployer.pointers.sol @@ -10,19 +10,19 @@ pragma solidity ^0.8.25; // file needs the contract to exist so that it can be compiled. /// @dev Hash of the known bytecode. -bytes32 constant BYTECODE_HASH = bytes32(0xef12d7bc7f6bdc8f098d54856801f1593a97e42434a55fb518d21a3643f53bf9); +bytes32 constant BYTECODE_HASH = bytes32(0x0409d29b54fe5ae5521f88199f6b1f27a8dac4b01e1a4d158d641bbee6b2aced); /// @dev The deterministic deploy address of the contract when deployed via /// the Zoltu factory. -address constant DEPLOYED_ADDRESS = address(0xA4dAEB07625879F4A584f92dDcbE3B64025cE11f); +address constant DEPLOYED_ADDRESS = address(0xdb9a055C24070bfAC87f1a44dbAF34Ac5Ef7cb05); /// @dev The creation bytecode of the contract. bytes constant CREATION_CODE = - hex"6080604052348015600e575f80fd5b50611ca88061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610064575f3560e01c80636f5aa28d1161004d5780636f5aa28d146100b0578063a3869e14146100de578063b92d7553146100fe575f80fd5b806301ffc9a7146100685780635514ca2014610090575b5f80fd5b61007b610076366004611619565b610106565b60405190151581526020015b60405180910390f35b6100a361009e366004611658565b610282565b60405161008791906116c4565b6040517f0ae1ecb6c0f6314beaf4d4cd803ba14c900b0eecb1ecd39a52739cff9ae2c34a8152602001610087565b6100f16100ec366004611813565b610347565b60405161008791906118d9565b6100f1610468565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f6f5aa28d00000000000000000000000000000000000000000000000000000000148061019857507fffffffff0000000000000000000000000000000000000000000000000000000082167fa3869e1400000000000000000000000000000000000000000000000000000000145b806101e457507fffffffff0000000000000000000000000000000000000000000000000000000082167f5514ca2000000000000000000000000000000000000000000000000000000000145b8061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167fb92d755300000000000000000000000000000000000000000000000000000000145b8061027c57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b604080516020810182526060815290517f5514ca2000000000000000000000000000000000000000000000000000000000815273dfc11de118ee6fcf787e2b17f42dc174bca4cf0490635514ca20906102e190869086906004016118eb565b5f60405180830381865afa1580156102fb573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610340919081019061195a565b9392505050565b6040517f7764fd9c0000000000000000000000000000000000000000000000000000000081526060905f90819073dfc11de118ee6fcf787e2b17f42dc174bca4cf0490637764fd9c9061039e9087906004016118d9565b5f60405180830381865afa1580156103b8573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103fd9190810190611a39565b915091505f610416838351905160406020909202010190565b60408051602083820181019092528281529192508101610437818686610477565b5f61045b6040518060c0016040528060908152602001611c186090913987876104ba565b5091979650505050505050565b6060610472610879565b905090565b80600182510160200281015b8082101561049e578151855260209485019490910190610483565b50506104b56104aa8390565b848451602001610b4c565b505050565b60605f6104c684610b55565b85519091506020860190600290046104dd86610b6f565b8260020267ffffffffffffffff8111156104f9576104f9611729565b6040519080825280601f01601f191660200182016040528015610523576020820181803683370190505b509350602084015f5b8481101561086d575f806105408a84610d8c565b915091508184538060018501536002840193505f61055f8b848c610daf565b90505f601861056e8d87610e16565b0390505f61057c8d87610e45565b600402820190505b808210156107b757815162ffffff811690601d81901a600f81169160049190911c90601c1a61160f8c82106106015760808801516040517fc8344ab1000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018e90526064015b60405180910390fd5b50600281028d015160f01c5f806106168a8885565b9150915085821461066a5760808a01516040517fddf56071000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018790526064016105f8565b8481146106ba5760808a01516040517ffc8b5603000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604481018690526064016105f8565b895182111561070c5760808a01518a516040517f2cab6bff00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018390526064016105f8565b8951829003808b5260408b0151111561076e5760808a01518a516040808d015190517f1bc5ab0f0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016105f8565b89518101808b5260208b0151101561078857895160208b01525b600181111561079957895160408b01525b50505060808701805160010190525050506004929092019150610584565b6107c18d87610e5c565b8360200151146108155782602001516107da8e88610e5c565b6040517f4d9c18dc000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105f8565b8251841461085c5782516040517f4689f0b30000000000000000000000000000000000000000000000000000000081526004810191909152602481018590526044016105f8565b50506001909301925061052c915050565b50505050509392505050565b606061160f5f604890508091505f6040518061092001604052808467ffffffffffffffff1667ffffffffffffffff168152602001610e748152602001610ef08152602001610f5381526020016111ae81526020016111b781526020016111c181526020016111ca81526020016111e481526020016111b78152602001611289815260200161128981526020016112e481526020016113ad81526020016113ba81526020016111b781526020016111c181526020016113ba81526020016111b781526020016111c181526020016111c181526020016111b781526020016111b781526020016111b781526020016111ae81526020016111ae81526020016111ae81526020016111ae81526020016113c481526020016111b781526020016113e8815260200161140181526020016111b781526020016113c481526020016111b781526020016111b781526020016113ba81526020016111c181526020016111b781526020016111b781526020016111c1815260200161140a81526020016111b781526020016111c1815260200161140a81526020016111ae81526020016111c181526020016111c181526020016111c181526020016111c181526020016111b781526020016111c181526020016111c1815260200161140a81526020016111ae81526020016111ae815260200161140a81526020016111ae81526020016111ae815260200161140a81526020016111b781526020016111c1815260200161140a81526020016113ba81526020016113ba815260200161140a815260200161140a81526020016111ae815260200161140a815260200161140a815260200161140a81526020016111c18152602001611401815250905060608190506048815114610b3a5780516040517fc8b569010000000000000000000000000000000000000000000000000000000081526004810191909152602481018490526044016105f8565b610b4381611423565b94505050505090565b8083835e505050565b5f81515f03610b6557505f919050565b50602001515f1a90565b5f610b7982610b55565b90508015610d4a5781516001600283020190811115610bc657826040517f17f4bc5e0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b82516020828501810191850101602160027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff860102860181019086015b808210610d0657815160f01c8481016004810185811115610c5157896040517e39ba560000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b81515f81901a90600181901a90600281901a9060031a80821180610c7457508281115b15610caf578d876040517feaf45f4f0000000000000000000000000000000000000000000000000000000081526004016105f8929190611b2a565b505050600481028201878114610cf3578b6040517ffbb8027a0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b8397506002870396505050505050610c03565b838314610d4157866040517fde67b29a0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b50505050505050565b600182511115610d8857816040517fd013da5d0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b5050565b5f805f610d998585610e16565b51600281901a9660039190911a95509350505050565b610de46040518060c001604052805f81526020015f81526020015f8152602001606081526020015f8152602001606081525090565b506040805160c081018252838152602081018490529081019290925260608201525f608082015260a081019190915290565b5f80610e2184610b55565b60020260010190505f610e3485856114b3565b949091019093016020019392505050565b5f80610e518484610e16565b515f1a949350505050565b5f80610e688484610e16565b5160011a949350505050565b81515f90819061ffff8416908110610ecf57608085015185516040517feaa16f3300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b8460400151811115610ee357604085018190525b505f946001945092505050565b6060820151515f90819061ffff8416908110610ee35760808501516060860151516040517feb78945400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b6060820151515f90819061ffff8416908110610fb65760808501516060860151516040517feb78945400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b5f85606001518281518110610fcd57610fcd611b4b565b602002602001015190505f80610fe6839060a082901c90565b91509150611014827f18003f8e00000000000000000000000000000000000000000000000000000000611509565b611062576040517f23016c8900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105f8565b6040517f40c04edc00000000000000000000000000000000000000000000000000000000815260048101829052600f601089901c81166024830181905260148a901c9091166044830181905290915f90819073ffffffffffffffffffffffffffffffffffffffff8716906340c04edc906064016040805180830381865afa1580156110ef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111139190611b78565b9150915083821461115a576040517f528cc0fb00000000000000000000000000000000000000000000000000000000815260048101859052602481018390526044016105f8565b82811461119d576040517fc5ff08dc00000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016105f8565b909b909a5098505050505050505050565b505f9160019150565b5060029160019150565b50600191829150565b5f806111d684846111e4565b506001958695509350505050565b5f8060ff83811690600885901c1680830361122b576040517f46f0ca6900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101006112388284611b9a565b111561127a576040517f8abcdd3f00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016105f8565b50600295600195509350505050565b5f8061ffff831660ff81118061129d575080155b156112d7576040517fc1be16a1000000000000000000000000000000000000000000000000000000008152600481018290526024016105f8565b5060019485945092505050565b60a08201515f90819061ffff841690600f601486901c811691601087901c90911690849081906113149086610d8c565b9150915081831461135b576040517f9199e58e00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016105f8565b8381101561139f576040517fff13710800000000000000000000000000000000000000000000000000000000815260048101829052602481018590526044016105f8565b509791965090945050505050565b60101c600f169160019150565b5060039160019150565b5f80600f601084901c16806113da5760016113dc565b805b95600195509350505050565b5f80600f601084901c16600281116113da5760026113dc565b506002915f9150565b5f80600f601084901c16600181116113da5760026113dc565b60605f825160020267ffffffffffffffff81111561144357611443611729565b6040519080825280601f01601f19166020018201604052801561146d576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156114a757805183518616908516178152602090920191600201611485565b50939695505050505050565b5f6114bd83610b55565b82106114f95781836040517ffcfaeff10000000000000000000000000000000000000000000000000000000081526004016105f8929190611bd2565b50600202016003015161ffff1690565b5f61151383611524565b80156103405750610340838361159e565b5f61154f827f01ffc9a70000000000000000000000000000000000000000000000000000000061159e565b15611597575f80611580847fffffffff000000000000000000000000000000000000000000000000000000006115c2565b9150915081801561158f575080155b949350505050565b505f919050565b5f805f6115ab85856115c2565b915091508180156115b95750805b95945050505050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000005f818152600483905290819060208260248188617530fa92505f511515601f3d11169150509250929050565b611617611bea565b565b5f60208284031215611629575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610340575f80fd5b5f8060208385031215611669575f80fd5b823567ffffffffffffffff80821115611680575f80fd5b818501915085601f830112611693575f80fd5b8135818111156116a1575f80fd5b8660208285010111156116b2575f80fd5b60209290920196919550909350505050565b602080825282518282018290528051604084018190525f9291820190839060608601905b8083101561171e57835173ffffffffffffffffffffffffffffffffffffffff1682529284019260019290920191908401906116e8565b509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516020810167ffffffffffffffff8111828210171561177957611779611729565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156117c6576117c6611729565b604052919050565b5f67ffffffffffffffff8211156117e7576117e7611729565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f60208284031215611823575f80fd5b813567ffffffffffffffff811115611839575f80fd5b8201601f81018413611849575f80fd5b803561185c611857826117ce565b61177f565b818152856020838501011115611870575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f610340602083018461188d565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b5f67ffffffffffffffff82111561195057611950611729565b5060051b60200190565b5f602080838503121561196b575f80fd5b825167ffffffffffffffff80821115611982575f80fd5b8185019150828287031215611995575f80fd5b61199d611756565b8251828111156119ab575f80fd5b80840193505086601f8401126119bf575f80fd5b825191506119cf61185783611937565b82815260059290921b830184019184810190888411156119ed575f80fd5b938501935b83851015611a2c57845173ffffffffffffffffffffffffffffffffffffffff81168114611a1d575f80fd5b825293850193908501906119f2565b8252509695505050505050565b5f8060408385031215611a4a575f80fd5b825167ffffffffffffffff80821115611a61575f80fd5b818501915085601f830112611a74575f80fd5b81516020611a84611857836117ce565b8281528882848701011115611a97575f80fd5b828286018383015e5f81840183015287820151909650935082841115611abb575f80fd5b838701935087601f850112611ace575f80fd5b83519250611ade61185784611937565b83815260059390931b8401810192818101925088841115611afd575f80fd5b938101935b83851015611b1b57845183529381019391810191611b02565b80955050505050509250929050565b604081525f611b3c604083018561188d565b90508260208301529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8060408385031215611b89575f80fd5b505080516020909101519092909150565b8082018082111561027c577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b828152604060208201525f61158f604083018461188d565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0e740ef00f5311ae11b711c111ca11e411b71289128912e413ad13ba11b711c113ba11b711c111c111b711b711b711ae11ae11ae11ae13c411b713e8140111b713c411b711b713ba11c111b711b711c1140a11b711c1140a11ae11c111c111c111c111b711c111c1140a11ae11ae140a11ae11ae140a11b711c1140a13ba13ba140a140a11ae140a140a140a11c11401"; + hex"6080604052348015600e575f80fd5b50611ca88061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610064575f3560e01c80636f5aa28d1161004d5780636f5aa28d146100b0578063a3869e14146100de578063b92d7553146100fe575f80fd5b806301ffc9a7146100685780635514ca2014610090575b5f80fd5b61007b610076366004611619565b610106565b60405190151581526020015b60405180910390f35b6100a361009e366004611658565b610282565b60405161008791906116c4565b6040517f0ae1ecb6c0f6314beaf4d4cd803ba14c900b0eecb1ecd39a52739cff9ae2c34a8152602001610087565b6100f16100ec366004611813565b610347565b60405161008791906118d9565b6100f1610468565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f6f5aa28d00000000000000000000000000000000000000000000000000000000148061019857507fffffffff0000000000000000000000000000000000000000000000000000000082167fa3869e1400000000000000000000000000000000000000000000000000000000145b806101e457507fffffffff0000000000000000000000000000000000000000000000000000000082167f5514ca2000000000000000000000000000000000000000000000000000000000145b8061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167fb92d755300000000000000000000000000000000000000000000000000000000145b8061027c57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b604080516020810182526060815290517f5514ca2000000000000000000000000000000000000000000000000000000000815273a0c9a33f4d13576ad0ae36cd431466ae641a951f90635514ca20906102e190869086906004016118eb565b5f60405180830381865afa1580156102fb573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610340919081019061195a565b9392505050565b6040517f7764fd9c0000000000000000000000000000000000000000000000000000000081526060905f90819073a0c9a33f4d13576ad0ae36cd431466ae641a951f90637764fd9c9061039e9087906004016118d9565b5f60405180830381865afa1580156103b8573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103fd9190810190611a39565b915091505f610416838351905160406020909202010190565b60408051602083820181019092528281529192508101610437818686610477565b5f61045b6040518060c0016040528060908152602001611c186090913987876104ba565b5091979650505050505050565b6060610472610879565b905090565b80600182510160200281015b8082101561049e578151855260209485019490910190610483565b50506104b56104aa8390565b848451602001610b4c565b505050565b60605f6104c684610b55565b85519091506020860190600290046104dd86610b6f565b8260020267ffffffffffffffff8111156104f9576104f9611729565b6040519080825280601f01601f191660200182016040528015610523576020820181803683370190505b509350602084015f5b8481101561086d575f806105408a84610d8c565b915091508184538060018501536002840193505f61055f8b848c610daf565b90505f601861056e8d87610e16565b0390505f61057c8d87610e45565b600402820190505b808210156107b757815162ffffff811690601d81901a600f81169160049190911c90601c1a61160f8c82106106015760808801516040517fc8344ab1000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018e90526064015b60405180910390fd5b50600281028d015160f01c5f806106168a8885565b9150915085821461066a5760808a01516040517fddf56071000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018790526064016105f8565b8481146106ba5760808a01516040517ffc8b5603000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604481018690526064016105f8565b895182111561070c5760808a01518a516040517f2cab6bff00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018390526064016105f8565b8951829003808b5260408b0151111561076e5760808a01518a516040808d015190517f1bc5ab0f0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016105f8565b89518101808b5260208b0151101561078857895160208b01525b600181111561079957895160408b01525b50505060808701805160010190525050506004929092019150610584565b6107c18d87610e5c565b8360200151146108155782602001516107da8e88610e5c565b6040517f4d9c18dc000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105f8565b8251841461085c5782516040517f4689f0b30000000000000000000000000000000000000000000000000000000081526004810191909152602481018590526044016105f8565b50506001909301925061052c915050565b50505050509392505050565b606061160f5f604890508091505f6040518061092001604052808467ffffffffffffffff1667ffffffffffffffff168152602001610e748152602001610ef08152602001610f5381526020016111ae81526020016111b781526020016111c181526020016111ca81526020016111e481526020016111b78152602001611289815260200161128981526020016112e481526020016113ad81526020016113ba81526020016111b781526020016111c181526020016113ba81526020016111b781526020016111c181526020016111c181526020016111b781526020016111b781526020016111b781526020016111ae81526020016111ae81526020016111ae81526020016111ae81526020016113c481526020016111b781526020016113e8815260200161140181526020016111b781526020016113c481526020016111b781526020016111b781526020016113ba81526020016111c181526020016111b781526020016111b781526020016111c1815260200161140a81526020016111b781526020016111c1815260200161140a81526020016111ae81526020016111c181526020016111c181526020016111c181526020016111c181526020016111b781526020016111c181526020016111c1815260200161140a81526020016111ae81526020016111ae815260200161140a81526020016111ae81526020016111ae815260200161140a81526020016111b781526020016111c1815260200161140a81526020016113ba81526020016113ba815260200161140a815260200161140a81526020016111ae815260200161140a815260200161140a815260200161140a81526020016111c18152602001611401815250905060608190506048815114610b3a5780516040517fc8b569010000000000000000000000000000000000000000000000000000000081526004810191909152602481018490526044016105f8565b610b4381611423565b94505050505090565b8083835e505050565b5f81515f03610b6557505f919050565b50602001515f1a90565b5f610b7982610b55565b90508015610d4a5781516001600283020190811115610bc657826040517f17f4bc5e0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b82516020828501810191850101602160027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff860102860181019086015b808210610d0657815160f01c8481016004810185811115610c5157896040517e39ba560000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b81515f81901a90600181901a90600281901a9060031a80821180610c7457508281115b15610caf578d876040517feaf45f4f0000000000000000000000000000000000000000000000000000000081526004016105f8929190611b2a565b505050600481028201878114610cf3578b6040517ffbb8027a0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b8397506002870396505050505050610c03565b838314610d4157866040517fde67b29a0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b50505050505050565b600182511115610d8857816040517fd013da5d0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b5050565b5f805f610d998585610e16565b51600281901a9660039190911a95509350505050565b610de46040518060c001604052805f81526020015f81526020015f8152602001606081526020015f8152602001606081525090565b506040805160c081018252838152602081018490529081019290925260608201525f608082015260a081019190915290565b5f80610e2184610b55565b60020260010190505f610e3485856114b3565b949091019093016020019392505050565b5f80610e518484610e16565b515f1a949350505050565b5f80610e688484610e16565b5160011a949350505050565b81515f90819061ffff8416908110610ecf57608085015185516040517feaa16f3300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b8460400151811115610ee357604085018190525b505f946001945092505050565b6060820151515f90819061ffff8416908110610ee35760808501516060860151516040517feb78945400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b6060820151515f90819061ffff8416908110610fb65760808501516060860151516040517feb78945400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b5f85606001518281518110610fcd57610fcd611b4b565b602002602001015190505f80610fe6839060a082901c90565b91509150611014827f18003f8e00000000000000000000000000000000000000000000000000000000611509565b611062576040517f23016c8900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105f8565b6040517f40c04edc00000000000000000000000000000000000000000000000000000000815260048101829052600f601089901c81166024830181905260148a901c9091166044830181905290915f90819073ffffffffffffffffffffffffffffffffffffffff8716906340c04edc906064016040805180830381865afa1580156110ef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111139190611b78565b9150915083821461115a576040517f528cc0fb00000000000000000000000000000000000000000000000000000000815260048101859052602481018390526044016105f8565b82811461119d576040517fc5ff08dc00000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016105f8565b909b909a5098505050505050505050565b505f9160019150565b5060029160019150565b50600191829150565b5f806111d684846111e4565b506001958695509350505050565b5f8060ff83811690600885901c1680830361122b576040517f46f0ca6900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101006112388284611b9a565b111561127a576040517f8abcdd3f00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016105f8565b50600295600195509350505050565b5f8061ffff831660ff81118061129d575080155b156112d7576040517fc1be16a1000000000000000000000000000000000000000000000000000000008152600481018290526024016105f8565b5060019485945092505050565b60a08201515f90819061ffff841690600f601486901c811691601087901c90911690849081906113149086610d8c565b9150915081831461135b576040517f9199e58e00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016105f8565b8381101561139f576040517fff13710800000000000000000000000000000000000000000000000000000000815260048101829052602481018590526044016105f8565b509791965090945050505050565b60101c600f169160019150565b5060039160019150565b5f80600f601084901c16806113da5760016113dc565b805b95600195509350505050565b5f80600f601084901c16600281116113da5760026113dc565b506002915f9150565b5f80600f601084901c16600181116113da5760026113dc565b60605f825160020267ffffffffffffffff81111561144357611443611729565b6040519080825280601f01601f19166020018201604052801561146d576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156114a757805183518616908516178152602090920191600201611485565b50939695505050505050565b5f6114bd83610b55565b82106114f95781836040517ffcfaeff10000000000000000000000000000000000000000000000000000000081526004016105f8929190611bd2565b50600202016003015161ffff1690565b5f61151383611524565b80156103405750610340838361159e565b5f61154f827f01ffc9a70000000000000000000000000000000000000000000000000000000061159e565b15611597575f80611580847fffffffff000000000000000000000000000000000000000000000000000000006115c2565b9150915081801561158f575080155b949350505050565b505f919050565b5f805f6115ab85856115c2565b915091508180156115b95750805b95945050505050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000005f818152600483905290819060208260248188617530fa92505f511515601f3d11169150509250929050565b611617611bea565b565b5f60208284031215611629575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610340575f80fd5b5f8060208385031215611669575f80fd5b823567ffffffffffffffff80821115611680575f80fd5b818501915085601f830112611693575f80fd5b8135818111156116a1575f80fd5b8660208285010111156116b2575f80fd5b60209290920196919550909350505050565b602080825282518282018290528051604084018190525f9291820190839060608601905b8083101561171e57835173ffffffffffffffffffffffffffffffffffffffff1682529284019260019290920191908401906116e8565b509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516020810167ffffffffffffffff8111828210171561177957611779611729565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156117c6576117c6611729565b604052919050565b5f67ffffffffffffffff8211156117e7576117e7611729565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f60208284031215611823575f80fd5b813567ffffffffffffffff811115611839575f80fd5b8201601f81018413611849575f80fd5b803561185c611857826117ce565b61177f565b818152856020838501011115611870575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f610340602083018461188d565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b5f67ffffffffffffffff82111561195057611950611729565b5060051b60200190565b5f602080838503121561196b575f80fd5b825167ffffffffffffffff80821115611982575f80fd5b8185019150828287031215611995575f80fd5b61199d611756565b8251828111156119ab575f80fd5b80840193505086601f8401126119bf575f80fd5b825191506119cf61185783611937565b82815260059290921b830184019184810190888411156119ed575f80fd5b938501935b83851015611a2c57845173ffffffffffffffffffffffffffffffffffffffff81168114611a1d575f80fd5b825293850193908501906119f2565b8252509695505050505050565b5f8060408385031215611a4a575f80fd5b825167ffffffffffffffff80821115611a61575f80fd5b818501915085601f830112611a74575f80fd5b81516020611a84611857836117ce565b8281528882848701011115611a97575f80fd5b828286018383015e5f81840183015287820151909650935082841115611abb575f80fd5b838701935087601f850112611ace575f80fd5b83519250611ade61185784611937565b83815260059390931b8401810192818101925088841115611afd575f80fd5b938101935b83851015611b1b57845183529381019391810191611b02565b80955050505050509250929050565b604081525f611b3c604083018561188d565b90508260208301529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8060408385031215611b89575f80fd5b505080516020909101519092909150565b8082018082111561027c577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b828152604060208201525f61158f604083018461188d565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0e740ef00f5311ae11b711c111ca11e411b71289128912e413ad13ba11b711c113ba11b711c111c111b711b711b711ae11ae11ae11ae13c411b713e8140111b713c411b711b713ba11c111b711b711c1140a11b711c1140a11ae11c111c111c111c111b711c111c1140a11ae11ae140a11ae11ae140a11b711c1140a13ba13ba140a140a11ae140a140a140a11c11401"; /// @dev The runtime bytecode of the contract. bytes constant RUNTIME_CODE = - hex"608060405234801561000f575f80fd5b5060043610610064575f3560e01c80636f5aa28d1161004d5780636f5aa28d146100b0578063a3869e14146100de578063b92d7553146100fe575f80fd5b806301ffc9a7146100685780635514ca2014610090575b5f80fd5b61007b610076366004611619565b610106565b60405190151581526020015b60405180910390f35b6100a361009e366004611658565b610282565b60405161008791906116c4565b6040517f0ae1ecb6c0f6314beaf4d4cd803ba14c900b0eecb1ecd39a52739cff9ae2c34a8152602001610087565b6100f16100ec366004611813565b610347565b60405161008791906118d9565b6100f1610468565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f6f5aa28d00000000000000000000000000000000000000000000000000000000148061019857507fffffffff0000000000000000000000000000000000000000000000000000000082167fa3869e1400000000000000000000000000000000000000000000000000000000145b806101e457507fffffffff0000000000000000000000000000000000000000000000000000000082167f5514ca2000000000000000000000000000000000000000000000000000000000145b8061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167fb92d755300000000000000000000000000000000000000000000000000000000145b8061027c57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b604080516020810182526060815290517f5514ca2000000000000000000000000000000000000000000000000000000000815273dfc11de118ee6fcf787e2b17f42dc174bca4cf0490635514ca20906102e190869086906004016118eb565b5f60405180830381865afa1580156102fb573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610340919081019061195a565b9392505050565b6040517f7764fd9c0000000000000000000000000000000000000000000000000000000081526060905f90819073dfc11de118ee6fcf787e2b17f42dc174bca4cf0490637764fd9c9061039e9087906004016118d9565b5f60405180830381865afa1580156103b8573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103fd9190810190611a39565b915091505f610416838351905160406020909202010190565b60408051602083820181019092528281529192508101610437818686610477565b5f61045b6040518060c0016040528060908152602001611c186090913987876104ba565b5091979650505050505050565b6060610472610879565b905090565b80600182510160200281015b8082101561049e578151855260209485019490910190610483565b50506104b56104aa8390565b848451602001610b4c565b505050565b60605f6104c684610b55565b85519091506020860190600290046104dd86610b6f565b8260020267ffffffffffffffff8111156104f9576104f9611729565b6040519080825280601f01601f191660200182016040528015610523576020820181803683370190505b509350602084015f5b8481101561086d575f806105408a84610d8c565b915091508184538060018501536002840193505f61055f8b848c610daf565b90505f601861056e8d87610e16565b0390505f61057c8d87610e45565b600402820190505b808210156107b757815162ffffff811690601d81901a600f81169160049190911c90601c1a61160f8c82106106015760808801516040517fc8344ab1000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018e90526064015b60405180910390fd5b50600281028d015160f01c5f806106168a8885565b9150915085821461066a5760808a01516040517fddf56071000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018790526064016105f8565b8481146106ba5760808a01516040517ffc8b5603000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604481018690526064016105f8565b895182111561070c5760808a01518a516040517f2cab6bff00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018390526064016105f8565b8951829003808b5260408b0151111561076e5760808a01518a516040808d015190517f1bc5ab0f0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016105f8565b89518101808b5260208b0151101561078857895160208b01525b600181111561079957895160408b01525b50505060808701805160010190525050506004929092019150610584565b6107c18d87610e5c565b8360200151146108155782602001516107da8e88610e5c565b6040517f4d9c18dc000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105f8565b8251841461085c5782516040517f4689f0b30000000000000000000000000000000000000000000000000000000081526004810191909152602481018590526044016105f8565b50506001909301925061052c915050565b50505050509392505050565b606061160f5f604890508091505f6040518061092001604052808467ffffffffffffffff1667ffffffffffffffff168152602001610e748152602001610ef08152602001610f5381526020016111ae81526020016111b781526020016111c181526020016111ca81526020016111e481526020016111b78152602001611289815260200161128981526020016112e481526020016113ad81526020016113ba81526020016111b781526020016111c181526020016113ba81526020016111b781526020016111c181526020016111c181526020016111b781526020016111b781526020016111b781526020016111ae81526020016111ae81526020016111ae81526020016111ae81526020016113c481526020016111b781526020016113e8815260200161140181526020016111b781526020016113c481526020016111b781526020016111b781526020016113ba81526020016111c181526020016111b781526020016111b781526020016111c1815260200161140a81526020016111b781526020016111c1815260200161140a81526020016111ae81526020016111c181526020016111c181526020016111c181526020016111c181526020016111b781526020016111c181526020016111c1815260200161140a81526020016111ae81526020016111ae815260200161140a81526020016111ae81526020016111ae815260200161140a81526020016111b781526020016111c1815260200161140a81526020016113ba81526020016113ba815260200161140a815260200161140a81526020016111ae815260200161140a815260200161140a815260200161140a81526020016111c18152602001611401815250905060608190506048815114610b3a5780516040517fc8b569010000000000000000000000000000000000000000000000000000000081526004810191909152602481018490526044016105f8565b610b4381611423565b94505050505090565b8083835e505050565b5f81515f03610b6557505f919050565b50602001515f1a90565b5f610b7982610b55565b90508015610d4a5781516001600283020190811115610bc657826040517f17f4bc5e0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b82516020828501810191850101602160027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff860102860181019086015b808210610d0657815160f01c8481016004810185811115610c5157896040517e39ba560000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b81515f81901a90600181901a90600281901a9060031a80821180610c7457508281115b15610caf578d876040517feaf45f4f0000000000000000000000000000000000000000000000000000000081526004016105f8929190611b2a565b505050600481028201878114610cf3578b6040517ffbb8027a0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b8397506002870396505050505050610c03565b838314610d4157866040517fde67b29a0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b50505050505050565b600182511115610d8857816040517fd013da5d0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b5050565b5f805f610d998585610e16565b51600281901a9660039190911a95509350505050565b610de46040518060c001604052805f81526020015f81526020015f8152602001606081526020015f8152602001606081525090565b506040805160c081018252838152602081018490529081019290925260608201525f608082015260a081019190915290565b5f80610e2184610b55565b60020260010190505f610e3485856114b3565b949091019093016020019392505050565b5f80610e518484610e16565b515f1a949350505050565b5f80610e688484610e16565b5160011a949350505050565b81515f90819061ffff8416908110610ecf57608085015185516040517feaa16f3300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b8460400151811115610ee357604085018190525b505f946001945092505050565b6060820151515f90819061ffff8416908110610ee35760808501516060860151516040517feb78945400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b6060820151515f90819061ffff8416908110610fb65760808501516060860151516040517feb78945400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b5f85606001518281518110610fcd57610fcd611b4b565b602002602001015190505f80610fe6839060a082901c90565b91509150611014827f18003f8e00000000000000000000000000000000000000000000000000000000611509565b611062576040517f23016c8900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105f8565b6040517f40c04edc00000000000000000000000000000000000000000000000000000000815260048101829052600f601089901c81166024830181905260148a901c9091166044830181905290915f90819073ffffffffffffffffffffffffffffffffffffffff8716906340c04edc906064016040805180830381865afa1580156110ef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111139190611b78565b9150915083821461115a576040517f528cc0fb00000000000000000000000000000000000000000000000000000000815260048101859052602481018390526044016105f8565b82811461119d576040517fc5ff08dc00000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016105f8565b909b909a5098505050505050505050565b505f9160019150565b5060029160019150565b50600191829150565b5f806111d684846111e4565b506001958695509350505050565b5f8060ff83811690600885901c1680830361122b576040517f46f0ca6900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101006112388284611b9a565b111561127a576040517f8abcdd3f00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016105f8565b50600295600195509350505050565b5f8061ffff831660ff81118061129d575080155b156112d7576040517fc1be16a1000000000000000000000000000000000000000000000000000000008152600481018290526024016105f8565b5060019485945092505050565b60a08201515f90819061ffff841690600f601486901c811691601087901c90911690849081906113149086610d8c565b9150915081831461135b576040517f9199e58e00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016105f8565b8381101561139f576040517fff13710800000000000000000000000000000000000000000000000000000000815260048101829052602481018590526044016105f8565b509791965090945050505050565b60101c600f169160019150565b5060039160019150565b5f80600f601084901c16806113da5760016113dc565b805b95600195509350505050565b5f80600f601084901c16600281116113da5760026113dc565b506002915f9150565b5f80600f601084901c16600181116113da5760026113dc565b60605f825160020267ffffffffffffffff81111561144357611443611729565b6040519080825280601f01601f19166020018201604052801561146d576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156114a757805183518616908516178152602090920191600201611485565b50939695505050505050565b5f6114bd83610b55565b82106114f95781836040517ffcfaeff10000000000000000000000000000000000000000000000000000000081526004016105f8929190611bd2565b50600202016003015161ffff1690565b5f61151383611524565b80156103405750610340838361159e565b5f61154f827f01ffc9a70000000000000000000000000000000000000000000000000000000061159e565b15611597575f80611580847fffffffff000000000000000000000000000000000000000000000000000000006115c2565b9150915081801561158f575080155b949350505050565b505f919050565b5f805f6115ab85856115c2565b915091508180156115b95750805b95945050505050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000005f818152600483905290819060208260248188617530fa92505f511515601f3d11169150509250929050565b611617611bea565b565b5f60208284031215611629575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610340575f80fd5b5f8060208385031215611669575f80fd5b823567ffffffffffffffff80821115611680575f80fd5b818501915085601f830112611693575f80fd5b8135818111156116a1575f80fd5b8660208285010111156116b2575f80fd5b60209290920196919550909350505050565b602080825282518282018290528051604084018190525f9291820190839060608601905b8083101561171e57835173ffffffffffffffffffffffffffffffffffffffff1682529284019260019290920191908401906116e8565b509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516020810167ffffffffffffffff8111828210171561177957611779611729565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156117c6576117c6611729565b604052919050565b5f67ffffffffffffffff8211156117e7576117e7611729565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f60208284031215611823575f80fd5b813567ffffffffffffffff811115611839575f80fd5b8201601f81018413611849575f80fd5b803561185c611857826117ce565b61177f565b818152856020838501011115611870575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f610340602083018461188d565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b5f67ffffffffffffffff82111561195057611950611729565b5060051b60200190565b5f602080838503121561196b575f80fd5b825167ffffffffffffffff80821115611982575f80fd5b8185019150828287031215611995575f80fd5b61199d611756565b8251828111156119ab575f80fd5b80840193505086601f8401126119bf575f80fd5b825191506119cf61185783611937565b82815260059290921b830184019184810190888411156119ed575f80fd5b938501935b83851015611a2c57845173ffffffffffffffffffffffffffffffffffffffff81168114611a1d575f80fd5b825293850193908501906119f2565b8252509695505050505050565b5f8060408385031215611a4a575f80fd5b825167ffffffffffffffff80821115611a61575f80fd5b818501915085601f830112611a74575f80fd5b81516020611a84611857836117ce565b8281528882848701011115611a97575f80fd5b828286018383015e5f81840183015287820151909650935082841115611abb575f80fd5b838701935087601f850112611ace575f80fd5b83519250611ade61185784611937565b83815260059390931b8401810192818101925088841115611afd575f80fd5b938101935b83851015611b1b57845183529381019391810191611b02565b80955050505050509250929050565b604081525f611b3c604083018561188d565b90508260208301529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8060408385031215611b89575f80fd5b505080516020909101519092909150565b8082018082111561027c577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b828152604060208201525f61158f604083018461188d565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0e740ef00f5311ae11b711c111ca11e411b71289128912e413ad13ba11b711c113ba11b711c111c111b711b711b711ae11ae11ae11ae13c411b713e8140111b713c411b711b713ba11c111b711b711c1140a11b711c1140a11ae11c111c111c111c111b711c111c1140a11ae11ae140a11ae11ae140a11b711c1140a13ba13ba140a140a11ae140a140a140a11c11401"; + hex"608060405234801561000f575f80fd5b5060043610610064575f3560e01c80636f5aa28d1161004d5780636f5aa28d146100b0578063a3869e14146100de578063b92d7553146100fe575f80fd5b806301ffc9a7146100685780635514ca2014610090575b5f80fd5b61007b610076366004611619565b610106565b60405190151581526020015b60405180910390f35b6100a361009e366004611658565b610282565b60405161008791906116c4565b6040517f0ae1ecb6c0f6314beaf4d4cd803ba14c900b0eecb1ecd39a52739cff9ae2c34a8152602001610087565b6100f16100ec366004611813565b610347565b60405161008791906118d9565b6100f1610468565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f6f5aa28d00000000000000000000000000000000000000000000000000000000148061019857507fffffffff0000000000000000000000000000000000000000000000000000000082167fa3869e1400000000000000000000000000000000000000000000000000000000145b806101e457507fffffffff0000000000000000000000000000000000000000000000000000000082167f5514ca2000000000000000000000000000000000000000000000000000000000145b8061023057507fffffffff0000000000000000000000000000000000000000000000000000000082167fb92d755300000000000000000000000000000000000000000000000000000000145b8061027c57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b604080516020810182526060815290517f5514ca2000000000000000000000000000000000000000000000000000000000815273a0c9a33f4d13576ad0ae36cd431466ae641a951f90635514ca20906102e190869086906004016118eb565b5f60405180830381865afa1580156102fb573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610340919081019061195a565b9392505050565b6040517f7764fd9c0000000000000000000000000000000000000000000000000000000081526060905f90819073a0c9a33f4d13576ad0ae36cd431466ae641a951f90637764fd9c9061039e9087906004016118d9565b5f60405180830381865afa1580156103b8573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526103fd9190810190611a39565b915091505f610416838351905160406020909202010190565b60408051602083820181019092528281529192508101610437818686610477565b5f61045b6040518060c0016040528060908152602001611c186090913987876104ba565b5091979650505050505050565b6060610472610879565b905090565b80600182510160200281015b8082101561049e578151855260209485019490910190610483565b50506104b56104aa8390565b848451602001610b4c565b505050565b60605f6104c684610b55565b85519091506020860190600290046104dd86610b6f565b8260020267ffffffffffffffff8111156104f9576104f9611729565b6040519080825280601f01601f191660200182016040528015610523576020820181803683370190505b509350602084015f5b8481101561086d575f806105408a84610d8c565b915091508184538060018501536002840193505f61055f8b848c610daf565b90505f601861056e8d87610e16565b0390505f61057c8d87610e45565b600402820190505b808210156107b757815162ffffff811690601d81901a600f81169160049190911c90601c1a61160f8c82106106015760808801516040517fc8344ab1000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018e90526064015b60405180910390fd5b50600281028d015160f01c5f806106168a8885565b9150915085821461066a5760808a01516040517fddf56071000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604481018790526064016105f8565b8481146106ba5760808a01516040517ffc8b5603000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604481018690526064016105f8565b895182111561070c5760808a01518a516040517f2cab6bff00000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018390526064016105f8565b8951829003808b5260408b0151111561076e5760808a01518a516040808d015190517f1bc5ab0f0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016105f8565b89518101808b5260208b0151101561078857895160208b01525b600181111561079957895160408b01525b50505060808701805160010190525050506004929092019150610584565b6107c18d87610e5c565b8360200151146108155782602001516107da8e88610e5c565b6040517f4d9c18dc000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105f8565b8251841461085c5782516040517f4689f0b30000000000000000000000000000000000000000000000000000000081526004810191909152602481018590526044016105f8565b50506001909301925061052c915050565b50505050509392505050565b606061160f5f604890508091505f6040518061092001604052808467ffffffffffffffff1667ffffffffffffffff168152602001610e748152602001610ef08152602001610f5381526020016111ae81526020016111b781526020016111c181526020016111ca81526020016111e481526020016111b78152602001611289815260200161128981526020016112e481526020016113ad81526020016113ba81526020016111b781526020016111c181526020016113ba81526020016111b781526020016111c181526020016111c181526020016111b781526020016111b781526020016111b781526020016111ae81526020016111ae81526020016111ae81526020016111ae81526020016113c481526020016111b781526020016113e8815260200161140181526020016111b781526020016113c481526020016111b781526020016111b781526020016113ba81526020016111c181526020016111b781526020016111b781526020016111c1815260200161140a81526020016111b781526020016111c1815260200161140a81526020016111ae81526020016111c181526020016111c181526020016111c181526020016111c181526020016111b781526020016111c181526020016111c1815260200161140a81526020016111ae81526020016111ae815260200161140a81526020016111ae81526020016111ae815260200161140a81526020016111b781526020016111c1815260200161140a81526020016113ba81526020016113ba815260200161140a815260200161140a81526020016111ae815260200161140a815260200161140a815260200161140a81526020016111c18152602001611401815250905060608190506048815114610b3a5780516040517fc8b569010000000000000000000000000000000000000000000000000000000081526004810191909152602481018490526044016105f8565b610b4381611423565b94505050505090565b8083835e505050565b5f81515f03610b6557505f919050565b50602001515f1a90565b5f610b7982610b55565b90508015610d4a5781516001600283020190811115610bc657826040517f17f4bc5e0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b82516020828501810191850101602160027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff860102860181019086015b808210610d0657815160f01c8481016004810185811115610c5157896040517e39ba560000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b81515f81901a90600181901a90600281901a9060031a80821180610c7457508281115b15610caf578d876040517feaf45f4f0000000000000000000000000000000000000000000000000000000081526004016105f8929190611b2a565b505050600481028201878114610cf3578b6040517ffbb8027a0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b8397506002870396505050505050610c03565b838314610d4157866040517fde67b29a0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b50505050505050565b600182511115610d8857816040517fd013da5d0000000000000000000000000000000000000000000000000000000081526004016105f891906118d9565b5050565b5f805f610d998585610e16565b51600281901a9660039190911a95509350505050565b610de46040518060c001604052805f81526020015f81526020015f8152602001606081526020015f8152602001606081525090565b506040805160c081018252838152602081018490529081019290925260608201525f608082015260a081019190915290565b5f80610e2184610b55565b60020260010190505f610e3485856114b3565b949091019093016020019392505050565b5f80610e518484610e16565b515f1a949350505050565b5f80610e688484610e16565b5160011a949350505050565b81515f90819061ffff8416908110610ecf57608085015185516040517feaa16f3300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b8460400151811115610ee357604085018190525b505f946001945092505050565b6060820151515f90819061ffff8416908110610ee35760808501516060860151516040517feb78945400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b6060820151515f90819061ffff8416908110610fb65760808501516060860151516040517feb78945400000000000000000000000000000000000000000000000000000000815260048101929092526024820152604481018290526064016105f8565b5f85606001518281518110610fcd57610fcd611b4b565b602002602001015190505f80610fe6839060a082901c90565b91509150611014827f18003f8e00000000000000000000000000000000000000000000000000000000611509565b611062576040517f23016c8900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105f8565b6040517f40c04edc00000000000000000000000000000000000000000000000000000000815260048101829052600f601089901c81166024830181905260148a901c9091166044830181905290915f90819073ffffffffffffffffffffffffffffffffffffffff8716906340c04edc906064016040805180830381865afa1580156110ef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111139190611b78565b9150915083821461115a576040517f528cc0fb00000000000000000000000000000000000000000000000000000000815260048101859052602481018390526044016105f8565b82811461119d576040517fc5ff08dc00000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016105f8565b909b909a5098505050505050505050565b505f9160019150565b5060029160019150565b50600191829150565b5f806111d684846111e4565b506001958695509350505050565b5f8060ff83811690600885901c1680830361122b576040517f46f0ca6900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101006112388284611b9a565b111561127a576040517f8abcdd3f00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016105f8565b50600295600195509350505050565b5f8061ffff831660ff81118061129d575080155b156112d7576040517fc1be16a1000000000000000000000000000000000000000000000000000000008152600481018290526024016105f8565b5060019485945092505050565b60a08201515f90819061ffff841690600f601486901c811691601087901c90911690849081906113149086610d8c565b9150915081831461135b576040517f9199e58e00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526044016105f8565b8381101561139f576040517fff13710800000000000000000000000000000000000000000000000000000000815260048101829052602481018590526044016105f8565b509791965090945050505050565b60101c600f169160019150565b5060039160019150565b5f80600f601084901c16806113da5760016113dc565b805b95600195509350505050565b5f80600f601084901c16600281116113da5760026113dc565b506002915f9150565b5f80600f601084901c16600181116113da5760026113dc565b60605f825160020267ffffffffffffffff81111561144357611443611729565b6040519080825280601f01601f19166020018201604052801561146d576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156114a757805183518616908516178152602090920191600201611485565b50939695505050505050565b5f6114bd83610b55565b82106114f95781836040517ffcfaeff10000000000000000000000000000000000000000000000000000000081526004016105f8929190611bd2565b50600202016003015161ffff1690565b5f61151383611524565b80156103405750610340838361159e565b5f61154f827f01ffc9a70000000000000000000000000000000000000000000000000000000061159e565b15611597575f80611580847fffffffff000000000000000000000000000000000000000000000000000000006115c2565b9150915081801561158f575080155b949350505050565b505f919050565b5f805f6115ab85856115c2565b915091508180156115b95750805b95945050505050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000005f818152600483905290819060208260248188617530fa92505f511515601f3d11169150509250929050565b611617611bea565b565b5f60208284031215611629575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610340575f80fd5b5f8060208385031215611669575f80fd5b823567ffffffffffffffff80821115611680575f80fd5b818501915085601f830112611693575f80fd5b8135818111156116a1575f80fd5b8660208285010111156116b2575f80fd5b60209290920196919550909350505050565b602080825282518282018290528051604084018190525f9291820190839060608601905b8083101561171e57835173ffffffffffffffffffffffffffffffffffffffff1682529284019260019290920191908401906116e8565b509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516020810167ffffffffffffffff8111828210171561177957611779611729565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156117c6576117c6611729565b604052919050565b5f67ffffffffffffffff8211156117e7576117e7611729565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f60208284031215611823575f80fd5b813567ffffffffffffffff811115611839575f80fd5b8201601f81018413611849575f80fd5b803561185c611857826117ce565b61177f565b818152856020838501011115611870575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f610340602083018461188d565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b5f67ffffffffffffffff82111561195057611950611729565b5060051b60200190565b5f602080838503121561196b575f80fd5b825167ffffffffffffffff80821115611982575f80fd5b8185019150828287031215611995575f80fd5b61199d611756565b8251828111156119ab575f80fd5b80840193505086601f8401126119bf575f80fd5b825191506119cf61185783611937565b82815260059290921b830184019184810190888411156119ed575f80fd5b938501935b83851015611a2c57845173ffffffffffffffffffffffffffffffffffffffff81168114611a1d575f80fd5b825293850193908501906119f2565b8252509695505050505050565b5f8060408385031215611a4a575f80fd5b825167ffffffffffffffff80821115611a61575f80fd5b818501915085601f830112611a74575f80fd5b81516020611a84611857836117ce565b8281528882848701011115611a97575f80fd5b828286018383015e5f81840183015287820151909650935082841115611abb575f80fd5b838701935087601f850112611ace575f80fd5b83519250611ade61185784611937565b83815260059390931b8401810192818101925088841115611afd575f80fd5b938101935b83851015611b1b57845183529381019391810191611b02565b80955050505050509250929050565b604081525f611b3c604083018561188d565b90508260208301529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8060408385031215611b89575f80fd5b505080516020909101519092909150565b8082018082111561027c577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b828152604060208201525f61158f604083018461188d565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0e740ef00f5311ae11b711c111ca11e411b71289128912e413ad13ba11b711c113ba11b711c111c111b711b711b711ae11ae11ae11ae13c411b713e8140111b713c411b711b713ba11c111b711b711c1140a11b711c1140a11ae11c111c111c111c111b711c111c1140a11ae11ae140a11ae11ae140a11b711c1140a13ba13ba140a140a11ae140a140a140a11c11401"; /// @dev The hash of the meta that describes the contract. bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0x0ae1ecb6c0f6314beaf4d4cd803ba14c900b0eecb1ecd39a52739cff9ae2c34a); diff --git a/src/generated/RainlangParser.pointers.sol b/src/generated/RainlangParser.pointers.sol index 6ed3314d6..f15fb26b3 100644 --- a/src/generated/RainlangParser.pointers.sol +++ b/src/generated/RainlangParser.pointers.sol @@ -10,19 +10,19 @@ pragma solidity ^0.8.25; // file needs the contract to exist so that it can be compiled. /// @dev Hash of the known bytecode. -bytes32 constant BYTECODE_HASH = bytes32(0xa446bfb83f0d066e06e06e06d4d53d699e736898c2df0c02af476bc303d4a173); +bytes32 constant BYTECODE_HASH = bytes32(0xeaba337950951ffbf239e47b30600eec41e969b3242f5508b9497d56a8773bd8); /// @dev The deterministic deploy address of the contract when deployed via /// the Zoltu factory. -address constant DEPLOYED_ADDRESS = address(0xdfc11DE118Ee6fcf787E2b17F42dc174BcA4Cf04); +address constant DEPLOYED_ADDRESS = address(0xA0c9a33f4d13576Ad0Ae36cD431466ae641A951f); /// @dev The creation bytecode of the contract. bytes constant CREATION_CODE = - hex"6080604052348015600e575f80fd5b50614fba8061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610064575f3560e01c80637764fd9c1161004d5780637764fd9c146100b0578063ccf44775146100d1578063d6d8c9a8146100e6575f80fd5b806301ffc9a7146100685780635514ca2014610090575b5f80fd5b61007b6100763660046146eb565b6100ee565b60405190151581526020015b60405180910390f35b6100a361009e3660046147eb565b610186565b6040516100879190614865565b6100c36100be3660046147eb565b61023e565b604051610087929190614916565b6100d961025e565b604051610087919061496b565b6100d961026d565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f1a2c8edd00000000000000000000000000000000000000000000000000000000148061018057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6040805160208101909152606081525f6101e3836101a2610277565b6101aa61029a565b60408051808201909152600881527f1a351cf91d391d9600000000000000000000000000000000000000000000000060208201526102ba565b90505f6020840190505f6101fa8580510160200190565b90506102078383836104ac565b915061021483838361050e565b9150604051806020016040528061022a85610697565b905293505050506102396106f5565b919050565b606080610255610250846101a2610277565b61073a565b91509150915091565b6060610268610895565b905090565b60606102686108e2565b6060604051806101a001604052806101638152602001614dc76101639139905090565b60606040518060c0016040528060908152602001614f2a60909139905090565b6103476040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b8152602001848152602001858152602001600467ffffffffffffffff8111156103cd576103cd61472a565b6040519080825280602002602001820160405280156103f6578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016828152808301825283517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001681178452855290840182905283018190529082018190526080820181905260a082018190526101208201819052610140820181905261020082015290505b95945050505050565b5f5b8183101561050457825160015f9190911a1b6401000026008116156104df576104d8858585610ba3565b93506104fe565b658000000000008116156104f8576104d8858585610be7565b50610504565b506104ae565b50815b9392505050565b815160408051808201909152601081527f7573696e672d776f7264732d66726f6d0000000000000000000000000000000060208201525f91906105509061497d565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008216146105815783915050610507565b506010830192508183106105f85761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517fe3e4992d0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b60405180910390fd5b825160015f91821a1b906401000026008216900361063f5761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016105ba565b836001019350505b818310156105045761065a8484846104ac565b925081831015610504575f80610671868686610daf565b909650909250905081610685575050610504565b610690868683610f3f565b5050610647565b60c08101516040516060919073ffffffffffffffffffffffffffffffffffffffff602082015f5b84156106df57848316825260a09490941c51936020909101906001016106be565b83526040526106ed82610fdc565b509392505050565b604051620100008110610737576040517f766c065f000000000000000000000000000000000000000000000000000000008152600481018290526024016105ef565b50565b6060805f83610220015151111561086a575f61075b84610220015160200190565b90505f61077085610220015180510160200190565b905061077d8583836104ac565b915061078a85838361050e565b91505b808210156107c1576107a08583836104ac565b91506107ad85838361102a565b91506107ba858383611383565b915061078d565b8082146107fa576040517f7d565df600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100850151600816156108675761022085015182037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517ff06f54cf0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b50505b5f8061087f61087886611898565b86906119cd565b9150915061088b6106f5565b9094909350915050565b6040805160a0810182526004808252611a356020830152611cf992820192909252611d39606082810191909152611d96608083015291908190805b6108d981611f19565b94505050505090565b60606146e15f604890508091505f6040518061092001604052808467ffffffffffffffff1667ffffffffffffffff168152602001611fa98152602001611fa98152602001611fa98152602001612075815260200161218981526020016121898152602001612075815260200161207581526020016121898152602001611fa98152602001611fa98152602001611fa98152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152509050606081905060488151146108d05780516040517fc8b569010000000000000000000000000000000000000000000000000000000081526004810191909152602481018490526044016105ef565b610100830180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690525f610bdf83836401000026006121cb565b949350505050565b6101008301805160011790525f60048301821015610c5f5761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517f25a764680000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b825160f01c612f2a8114610ccc5761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f3e47169c0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b6003840193505f5b83851015610d715784515f1a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd18101610d65577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86015160f01c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d18101610d6357505050600193840193610d71565b505b85600101955050610cd4565b80610da55761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001610c2a565b5092949350505050565b81515f90819081908190600181831a1b6703ff200000000000811615610eb45786610ddb8960016149ef565b1015610eab57600182811a1b7ffffffffffffffffffffffffffffffffffeffffffffffffffffff00000000000082821701610e18575f9350610ea5565b7ffffffffffffffffffffffffffffffffffffffffffeffffffffff00000000000082821701610ea0576102208a015189037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f75c28ff90000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b600193505b50610ef9565b60019250610ef9565b640400000000811615610eca5760029250610ef9565b6b080000000000000000000000811615610ee75760039250610ef9565b505f9450869350849250610f36915050565b505f9050610f27888888610f1f83876101a09190910151600291820201015161ffff1690565b63ffffffff16565b90975060019550879450925050505b93509350939050565b73ffffffffffffffffffffffffffffffffffffffff811115610fba5761022083015182037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f9d7e517e0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b60c09092018051604080516020810190915290815260a01b9290921790915250565b60208101602082510282015b808210156110255781518151835281526020909101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001610fe8565b505050565b5f5b818310156105045782515f90600190821a1b6f07fffffe80000000000000000000000081161561124157610100860151600116156110c45761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517f5520a5170000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b6f07fffffe000000000000000000000000811615611175576110f785856f07fffffe0000000003ff2000000000006121f4565b90955091505f61110787846122c3565b509050801561116f5761022087015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f53e6feba0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b50611196565b61119360018601856f07fffffe0000000003ff2000000000006121cb565b94505b856040015160ff1660ff14806111b357508560a0015160ff1660ff145b156112175761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f382063410000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b604086018051600190810190915260a087018051909101905261010086018051600917905261137c565b6401000026008116156112935761126160018601856401000026006121cb565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe169052945061137c565b6704000000000000008116156112df575050610100840180516008177ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe16905260019290920191610504565b6580000000000081161561134d5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517fedad0c580000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b61022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00161108f565b505061102c565b5f5b818310156105045782515f90600190821a1b6f07fffffe000000000000000000000000811615611581576101008601516001161561141d5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517f4e803df60000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b8461143981866f07fffffe0000000003ff2000000000006121f4565b80945081975050505f806114528961024001518661233e565b91509150811561149357611467898989612412565b97505f6114748a83612637565b90506114818a838361265d565b5061010089018051600217905261156d565b61149d8986612842565b909250905081156114c1576114b3895f8361265d565b6114bc896128bc565b61156d565b5f6060848a03600581016114d68d8d8d612412565b9b508c6101e0015151602002602001810190505f600590506040519350602082018401604052828185015281845283945061151e8860056115178760200190565b0185612922565b5050506101e08b01518051600101906115519061154b836115428680510160200190565b90602002900390565b8361292b565b5061155e8b60ff8461265d565b50506101008901805160021790525b505050610100860180516001179052611891565b61010086015160021615611681576501000000000081165f036115fd5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f23b5c6ea0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b606086810180515f1a6003019190829053603b821115611649576040517f6232f2d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050610100860180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc169052600190940193611891565b6502000000000081161561173b576060868101515f90811a91908290036117015761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f7f9db5420000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b808801600383039250828153826004820101515f1a8360028301015160f01c600101535061172e886128bc565b5050600190940193611891565b64010000260081161561178d5761175b60018601856401000026006121cb565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690529450611891565b6b0800000003ff2004000000008116156117c8576117ac868686612937565b94506117b7866128bc565b610100860180516001179052611891565b651000000000008116156117ed576117e08686612a3f565b5050600190920191610504565b670800000000000000811615611825576118078686612a3f565b61181086612ded565b50506004610100850152600190920191610504565b658000000000008116156118625761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001611318565b61022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016113e8565b5050611385565b60e08101518151516060919060f082901c90602081146118e4576040517f858f2dcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051935060208401601083045f8183535060016008850483018101928391015f80805b888110156119415789811c61ffff81165163ffff0000601092831b16811760e01b8786015284019360f08390031b929092179101611908565b50825117909152878203017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08181018952908801601f01166040525f5b828110156119c1576002810288016003015161ffff90811683018051602060f082901c019260e09190911c16906119b6838284612922565b50505060010161197e565b50505050505050919050565b6060805f6119da8461311b565b90505f5b81811015611a1d575f6119f18683613135565b60040190505f611a018784613164565b60040282019050611a1388838361317b565b50506001016119de565b5083611a288661343b565b92509250505b9250929050565b5f80808080611a458888886134b0565b985090925090508181036040811115611ab75761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517fff2f59490000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b805f03611b1d5761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517fc75cd5090000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b60028106600103611b875761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517fd76d9b570000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b6001820397505f5b838910611ce85788515f90811a906001821b906703ff000000000000821615611bdb57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd08201611cb2565b6c7e000000000000000000000000821615611c1957507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa98201611cb2565b687e0000000000000000821615611c5357507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc98201611cb2565b6102208d01518c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f69f1e3e60000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909b019a831b96909617955050600401611b8f565b50509350909150505b935093915050565b5f805f805f80611d098888613500565b92965090945092509050611d1e898486613943565b82611d2983836139a5565b9550955050505050935093915050565b5f808080611d488787876139f7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08301805184840382529199509294509092505f91611d8681613b6d565b9190529698969750505050505050565b6001909101905f8083611dba81856fffffffffdffffffffffffffeffffd9ff6121cb565b945084818103611e235761022087015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517ff73a1aa80000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b611e2e878787610ba3565b955085611e4c81876fffffffffdfffffffffffffffffffffff6121cb565b965086868110611eb65761022089015188037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517fc4b191350000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b875160015f91821a1b906b20000000000000000000000082169003611f04576102208a015189037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001611e81565b5060019097019687611d298a86868686613b99565b60605f825160020267ffffffffffffffff811115611f3957611f3961472a565b6040519080825280601f01601f191660200182016040528015611f63576020820181803683370190505b50905061ffff80196020850160208651028101600285015b81831015611f9d57805183518616908516178152602090920191600201611f7b565b50939695505050505050565b5f8151600103612034575060208101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116601b0b60e082901d5f611fec838383613d3b565b905061ffff81111561202a576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250610239915050565b81515f0361204357505f919050565b6040517f1ac6690800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f815160020361214d57602082015160408301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216601b0b60e083901d5f6120bc838383613d3b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8516601b0b935060e085901d925090505f6120f5848483613d3b565b905060ff821180612106575060ff81115b1561213d576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60081b1794506102399350505050565b600282511015612043576040517ff16066b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81515f146121c4576040517f9f16b02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505f919050565b5f5b5f82600186515f1a1b161183851016156121ec576001840193506121cd565b509192915050565b5f80806001818787036020811161220b578061220e565b60205b915050875192505b8519600184841a1b1615818310161561223457600182019150612216565b9681019660208290036008810293841c90931b926122b657604080516020810185905201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527fe47fe8b70000000000000000000000000000000000000000000000000000000082526105ef9160040161496b565b5095969095509350505050565b5f806122cf8484612842565b909250905081611a2e5750610120830180515f93845260209384902060408051928352948201855293909401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909316601084901b62ff00001617909317909252909160ff90911660010190565b600182810180515f928392600560ff93909316602102870192830192909101835b818310156124035760018301516021909301805190935f90819060ff168180612388838e613d97565b915091508186165f036123aa575f809b509b5050505050505050505050611a2e565b5f876123ba600185038916613dc2565b016004028b015195505062ffffff90811693508416830391506123ee9050575060019750601c1a9550611a2e945050505050565b6123f783613dc2565b8401935050505061235f565b505f9788975095505050505050565b81516101e08401515f80825291600190831a1b907ffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000008201610da55761245685614a2f565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe169052805190955060015f91821a1b9250805b858710156125f757865160015f9190911a1b93506401000026008416156124c4576124bd888888610ba3565b9650612491565b6740000000000000008416156124e8576124dd87614a2f565b9650600190506125f7565b6001886101000151165f03612597576004820361255e5761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f8c9fdbb30000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b5f61256a898989613e9a565b60208581028701018190526101008b0180516001179052909850905061258f83614a2f565b925050612491565b61022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517f722cd24a0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b8061262b5761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016125c2565b50905250919392505050565b6101c08201516002828102820101516101e08401515f9261ffff90921691906104a39083565b61266683613ec2565b610100830180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb1660081790526020808401515f90811a8501602101805190911a60ff8114929190600181018253505081156126ef576040517f8092d1ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050825180516060808601515f90811a87016061018051939461ffff8616949093921a60ff81149291600886048503601c0191600181018253505f60038201537fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe30180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016909117905281156127b2576040517f3abd0c5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050602090920183821b176018820185901b178083529160e082900361283a5760408051601083901b6020908117601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016918252810190915281517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000168117825286525b505050505050565b6101208201516101408301515f8381526020808220919384939290911c91600160ff84161b808216156128a75761ffff83165b80156128a5578360201c8503612898576001965061ffff8460101c1695506128a5565b51925061ffff8316612875565b505b17610140909601959095525090939092509050565b6060818101515f90811a919082900361102557602083810180515f1a600101919082815350603e821061291b576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b8083835e505050565b6020810283835e505050565b5f8080612945868686610daf565b90965092509050806129b15761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517fb0e4e5b30000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b5f806129bc84613f4e565b61018089015116156129fd5761016088015160101c5b80158015906129df575082155b156129fb576020810151905190851492506001909101906129d2565b505b61016088015161ffff16612a23600184612a175782612a1b565b8383035b8b919061265d565b5081612a3357612a338885613f65565b50949695505050505050565b6060828101515f1a908115612aad5761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f6fb11cdc0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b5050612ab882613ec2565b61010082018051600416600890811790915260a0830151602084015160ff8083169360f89290921c9290911c1681035f819003612bc0576004856101000151165f03612b5d5761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517fab1d3ea70000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b90820190603e8210612b9b576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60f882901b6020860152610200850151612bb59084613fb7565b610200860152612c97565b6001811115612c975780831015612c305761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f78ef27820000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b80831115612c975761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f43168e680000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b8082036001016020601083028101905b81811015612dd95760a08801516020848a0181015191831c61ffff16915f1a9060015b828111612dc75760208406601c03612ce357925160f01c925b83516102008d015160019190911a90612cfc908261403b565b6102008e01525f8285148015612d125750896001145b612d1d576001612d1f565b8b5b6102008f0151909150612d329082614081565b6102008f0152600f811180612d475750600f82115b15612dab576102208e01518d037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f7ea1869f0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b818160041b176001870153505060049390930192600101612cca565b50506001909401935050601001612ca7565b5050505060081b60a0909301929092525050565b60e081015160208083015160f083811c925f9290921a6001019190839003612e41576040517fa806284100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610200850151855180515f928392909160219060101c61ffff165b8015612e7357805190925060101c61ffff16612e5c565b506040518a82018051919650601c8401939160049160248901915f90811a805b8d831015612f585760048202860195506004878a03045b80821115612ec857965161ffff16601c810199509690036007612eaa565b506004810298899003805186529894909401938103865b6007821115612f24575160101c61ffff1680518652601c909501947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff990910190612edf565b8115612f3f575160101c61ffff168051865260048202909501945b50505060019182018051909291909101905f1a80612e93565b50505082895250600488810180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9290940491909101601881901b8817939093179052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405260ff109450508315613024576040517fe972437e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130316001808a1b614a66565b891685891b60f06130438b60106149ef565b901b171760e08b01526101008a0180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7169052604080516020601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01681815280820183525f80517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001682178152908d52908c01819052908b0181905260608b0181905260808b0181905260a08b018190526101208b018190526101408b018190526102008b015250505050505050505050565b5f81515f0361312b57505f919050565b50602001515f1a90565b5f806131408461311b565b60020260010190505f61315385856140f4565b949091019093016020019392505050565b5f806131708484613135565b515f1a949350505050565b808210156110255781517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160f882901c016133b55760c08401515b80156133b35760a081901c5161016086015161ffff60e085901c1660208101805160089390931b62ffff0016600187901a1760e81b7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316929092179091526040517f570c7a630000000000000000000000000000000000000000000000000000000081529192915f908190819073ffffffffffffffffffffffffffffffffffffffff86169063570c7a639061326e90879060040161496b565b5f60405180830381865afa158015613288573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526132cd9190810190614b05565b92509250925082156133a957815160041461331657816040517fbe2d187d0000000000000000000000000000000000000000000000000000000081526004016105ef919061496b565b60208201517fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff88161789525f5b815181101561339e5761339682828151811061337f5761337f614bb2565b60200260200101518c613f6590919063ffffffff16565b600101613361565b5050505050506133b3565b50505050506131b6565b505b5081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160f882901c0161342f57606061ffff8260e01c1690505f6003820152600581019050806040517faedfba2f0000000000000000000000000000000000000000000000000000000081526004016105ef919061496b565b5060048201915061317b565b6101608101516040805161ffff8316808252602080820283019081019093529092909160109190911c90835b808211156134a75760208301518252915161ffff16917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090910190613467565b50505050919050565b5f8080806134bf8660026149ef565b9050806c7e0000007e03ff0000000000005b86821081600184515f1a1b16151516156134f0576001820191506134d1565b5090979096508695509350505050565b5f8281806135158386652000000000006121cb565b9250858314158361352f81886703ff0000000000006121cb565b945080850361356957507f34bd20690000000000000000000000000000000000000000000000000000000094505f925082915061393a9050565b5f806135758a8861414a565b90925090507fffffffff000000000000000000000000000000000000000000000000000000008216156135b3575095505f935083925061393a915050565b86519095506540000000000060015f9290921a9190911b16151588871016915050801561384257506001909301925f846135f681896703ff0000000000006121cb565b955080860361363157507f7bfa48af0000000000000000000000000000000000000000000000000000000095505f935083925061393a915050565b855b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018051908a1160015f9290921a9190911b6601000000000000161515166001036136a0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01613633565b8181146136f7575f806136b3848461414a565b90925090507fffffffff000000000000000000000000000000000000000000000000000000008216156136f3575097505f955085945061393a9350505050565b9350505b5f83121561373257507f7bfa48af0000000000000000000000000000000000000000000000000000000096505f945084935061393a92505050565b831561373e57825f0392505b80820394505f85131561377e57507f013b2aaa0000000000000000000000000000000000000000000000000000000096505f945084935061393a92505050565b855f0361378d5782955061383f565b5f85900360438111156137ce57507f32b8b8be0000000000000000000000000000000000000000000000000000000097505f955085945061393a9350505050565b600a0a8681025f888383816137e5576137e5614a02565b0514159050601b82900b82141581806137fb5750805b1561383757507f32b8b8be000000000000000000000000000000000000000000000000000000009a505f985088975061393a9650505050505050565b505084019650505b50505b84516c2000000020000000000000000060015f9290921a9190911b16151587861016801561392b5760019095019485613882818a652000000000006121cb565b965086613898818b6703ff0000000000006121cb565b97508088036138d557507f013b2aaa0000000000000000000000000000000000000000000000000000000097505f955085945061393a9350505050565b505f806138e2838a61414a565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615613922575097505f955085945061393a9350505050565b95860195925050505b845f03613936575f93505b5050505b92959194509250565b7fffffffff00000000000000000000000000000000000000000000000000000000811615611025576102208301515f9083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0019050815f528060045260245ffd5b5f805f6139b28585614274565b91509150806106ed576040517f22c9f7bb00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016105ef565b5f80806001850181806f7ffffffffffffffffffffffb0000000081807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8b8b0301602080821015613a455750805b875193505b84600185851a1b1615158184101615613a6857600183019250613a4a565b505080602003613ad1576102208c01518b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f30515bda0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b85810180519095505f1a6001811b640400000000161580613af15750858b145b15613b55576102208d015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f04022fbf0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b50949b939a505060018a019850919650505050505050565b5f80601f90505f60e09050818451168082175f528060208601600183016020035e50505f519392505050565b5f60608186860361ffff811115613bdf576040517fb6da789c000000000000000000000000000000000000000000000000000000008152600481018290526024016105ef565b604080516041888803848101838101929092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690935260028281018590520181529350602284019250613c35898484612922565b613c428783850183612922565b50505060c08701515b8015613d0c5760a081901c516040517fc6c0cbb60000000000000000000000000000000000000000000000000000000081529091905f90819073ffffffffffffffffffffffffffffffffffffffff84169063c6c0cbb690613cb090889060040161496b565b6040805180830381865afa158015613cca573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613cee9190614bdf565b915091508115613d045794506104a39350505050565b505050613c4b565b61022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00161297c565b5f805f613d4986868661437a565b9150915080613d8e576040517f05e4767800000000000000000000000000000000000000000000000000000000815260048101879052602481018690526044016105ef565b50949350505050565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116611a2e575060019250929050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613df35750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f805f613eaa888888610daf565b9250925092508215613d0c579093509150611cf19050565b8051602080830180515f90811a8086016021015160a0939190831a613f145785518488018051600861ffff909316929092046020038801601e83901a840360010160100290811b909217905260f01092505b5050801561291b576040517f5b1a42d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f613f5b61010083614c09565b6001901b92915050565b6101608201805160408051808201909152601091821c808252602082018590528351600161ffff909116019282901b92909217909252613fa483613f4e565b6101809094018051909417909352505050565b5f613fc28383614081565b925060ff600884901c8116830190811115614009576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff841660089190911b17905092915050565b5f60ff83168281101561407a576040517f23b49a2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050900390565b5f60ff808416830190600885901c811690601086901c908311156140d1576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808311156140dc5750815b601081901b600883901b841717935050505092915050565b5f6140fe8361311b565b821061413a5781836040517ffcfaeff10000000000000000000000000000000000000000000000000000000081526004016105ef929190614c41565b50600202016003015161ffff1690565b81515f90819065200000000000600191831a9190911b1615158385101680850190828061417784886144c6565b90925090507fffffffff000000000000000000000000000000000000000000000000000000008216156141b2575093505f9250611a2e915050565b825f03614215577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81116141e6575f614208565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95509350611a2e92505050565b7f80000000000000000000000000000000000000000000000000000000000000008111614242575f614264565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95505f0393505050509250929050565b5f601b83900b83148383826142d8577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000008605156142b857620186a0860595506005850194505b8586601b0b146142d357600a860595508460010194506142b8565b6142ee565b855f036142ee57505f925060019150611a2e9050565b848560030b1461434a575f85121561430e57505f9250829150611a2e9050565b6040517fd556b11100000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016105ef565b50507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660e084901b1791509250929050565b5f805f8512156143c0576040517f4a7d166b00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016105ef565b845f036143d257505f90506001611cf1565b8460ff841685018581121561441d576040517fd556b11100000000000000000000000000000000000000000000000000000000815260048101889052602481018790526044016105ef565b5f805f831215614487577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb383121561445e575f809550955050505050611cf1565b825f03600a0a915081848161447557614475614a02565b0495505084029091149150611cf19050565b5f8313156144b65761449a83600a614d77565b91506144a68285614d82565b955060019450611cf19350505050565b8360019550955050505050611cf1565b5f808284106144f957507f34bd20690000000000000000000000000000000000000000000000000000000090505f611a2e565b835f03614532576040517fda6966d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60305f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501815b87821015801561456a5750604d83105b156145ad57815160018401937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90930192600a0a5f9190911a859003020161455a565b8782106146d35781515f1a84900360018111156145f557507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450611a2e9350505050565b600a84900a810282810183111561463857507f0fdc26350000000000000000000000000000000000000000000000000000000096505f9550611a2e945050505050565b9190910190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b8782106146d35781515f1a603081146146a857507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450611a2e9350505050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190614664565b5f9890975095505050505050565b6146e9614d99565b565b5f602082840312156146fb575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610507575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561479e5761479e61472a565b604052919050565b5f67ffffffffffffffff8211156147bf576147bf61472a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f602082840312156147fb575f80fd5b813567ffffffffffffffff811115614811575f80fd5b8201601f81018413614821575f80fd5b803561483461482f826147a6565b614757565b818152856020838501011115614848575f80fd5b816020840160208301375f91810160200191909152949350505050565b602080825282518282018290528051604084018190525f9291820190839060608601905b808310156148bf57835173ffffffffffffffffffffffffffffffffffffffff168252928401926001929092019190840190614889565b509695505050505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b604081525f61492860408301856148ca565b8281036020848101919091528451808352858201928201905f5b8181101561495e57845183529383019391830191600101614942565b5090979650505050505050565b602081525f61050760208301846148ca565b805160208083015191908110156149bc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115610180576101806149c2565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a5f57614a5f6149c2565b5060010190565b81810381811115610180576101806149c2565b80518015158114610239575f80fd5b5f82601f830112614a97575f80fd5b8151602067ffffffffffffffff821115614ab357614ab361472a565b8160051b614ac2828201614757565b9283528481018201928281019087851115614adb575f80fd5b83870192505b84831015614afa57825182529183019190830190614ae1565b979650505050505050565b5f805f60608486031215614b17575f80fd5b614b2084614a79565b9250602084015167ffffffffffffffff80821115614b3c575f80fd5b818601915086601f830112614b4f575f80fd5b8151614b5d61482f826147a6565b818152886020838601011115614b71575f80fd5b8160208501602083015e5f6020838301015280955050506040860151915080821115614b9b575f80fd5b50614ba886828701614a88565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8060408385031215614bf0575f80fd5b614bf983614a79565b9150602083015190509250929050565b5f82614c3c577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b828152604060208201525f610bdf60408301846148ca565b600181815b80851115614cb257817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614c9857614c986149c2565b80851615614ca557918102915b93841c9390800290614c5e565b509250929050565b5f82614cc857506001610180565b81614cd457505f610180565b8160018114614cea5760028114614cf457614d10565b6001915050610180565b60ff841115614d0557614d056149c2565b50506001821b610180565b5060208310610133831016604e8410600b8410161715614d33575081810a610180565b614d3d8383614c59565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d6f57614d6f6149c2565b029392505050565b5f6105078383614cba565b8082028115828204841417610180576101806149c2565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0288400100420b0280046b0641220186adb8a044003012020f2a880521281ac8811a000000000000000000080000000000100000000000000002000000000000000000290ea98a3a10f9c53927bda61c6395ad0e9fb4a8075dbeaf2d313e9e09b06d681dfe49062ce21ac13e83a6cc2ad2d2123422c3e0052f369e1f27267220a0a68d2f357696465d217b131120880f24f4a8242f1af53f41f7290afa3e8638acf3d13397e9fd00443a453b406bb547b9059d25a3cd1e11d0c3260b15eb4d16fc94274427bc412baf2cc2321b8f630dca9efe403ce35f1400684845c291e3425d68b13d5f9a151eb98c15239cd9c10c1f698235c8d3843c08d579273459d41a2c9ff617a5b2cd15c0031810f621af127ba34c26bb6c4137b2ad3d1b73563d0210215f36aa563921098e690457fb180376e752066a470128f11de101fcc60522de7ddd183d3d6d4196c37031cba2872e7b3af5304eee7219a8093543082b5f0801f5a51fa91fa91fa92075218921892075207521891fa91fa91fa9218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189"; + hex"6080604052348015600e575f80fd5b506154c68061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610064575f3560e01c80637764fd9c1161004d5780637764fd9c146100b0578063ccf44775146100d1578063d6d8c9a8146100e6575f80fd5b806301ffc9a7146100685780635514ca2014610090575b5f80fd5b61007b610076366004614bf7565b6100ee565b60405190151581526020015b60405180910390f35b6100a361009e366004614cf7565b610186565b6040516100879190614d71565b6100c36100be366004614cf7565b61023e565b604051610087929190614e22565b6100d961025e565b6040516100879190614e77565b6100d961026d565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f1a2c8edd00000000000000000000000000000000000000000000000000000000148061018057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6040805160208101909152606081525f6101e3836101a2610277565b6101aa61029a565b60408051808201909152600881527f1c991fe52025208200000000000000000000000000000000000000000000000060208201526102ba565b90505f6020840190505f6101fa8580510160200190565b90506102078383836104ac565b915061021483838361050e565b9150604051806020016040528061022a856106db565b90529350505050610239610739565b919050565b606080610255610250846101a2610277565b61077e565b91509150915091565b60606102686108fb565b905090565b6060610268610948565b6060604051806101a0016040528061016381526020016152d36101639139905090565b60606040518060c001604052806090815260200161543660909139905090565b6103476040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b8152602001848152602001858152602001600467ffffffffffffffff8111156103cd576103cd614c36565b6040519080825280602002602001820160405280156103f6578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016828152808301825283517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001681178452855290840182905283018190529082018190526080820181905260a082018190526101208201819052610140820181905261020082015290505b95945050505050565b5f5b8183101561050457825160015f9190911a1b6401000026008116156104df576104d8858585610c09565b93506104fe565b658000000000008116156104f8576104d8858585610c4d565b50610504565b506104ae565b50815b9392505050565b815160408051808201909152601081527f7573696e672d776f7264732d66726f6d0000000000000000000000000000000060208201525f919061055090614e89565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008216146105815783915050610507565b5060108301925081831061061a5761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517fe3e4992d00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b60405180910390fd5b825160015f91821a1b90640100002600821690036106835761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176105dc565b836001019350505b818310156105045761069e8484846104ac565b925081831015610504575f806106b5868686610e7b565b9096509092509050816106c9575050610504565b6106d486868361102d565b505061068b565b60c08101516040516060919073ffffffffffffffffffffffffffffffffffffffff602082015f5b841561072357848316825260a09490941c5193602090910190600101610702565b8352604052610731826110ec565b509392505050565b60405162010000811061077b576040517f766c065f00000000000000000000000000000000000000000000000000000000815260048101829052602401610611565b50565b6060805f8361022001515111156108d0575f61079f84610220015160200190565b90505f6107b485610220015180510160200190565b90506107c18583836104ac565b91506107ce85838361050e565b91505b80821015610805576107e48583836104ac565b91506107f185838361113a565b91506107fe85838361153d565b91506107d1565b80821461083e576040517f7d565df600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100850151600816156108cd5761022085015182037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517ff06f54cf00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b50505b5f806108e56108de86611afc565b8690611c31565b915091506108f1610739565b9094909350915050565b6040805160a0810182526004808252611c996020830152611fe592820192909252612025606082810191909152612082608083015291908190805b61093f8161226b565b94505050505090565b6060614bed5f604890508091505f6040518061092001604052808467ffffffffffffffff1667ffffffffffffffff1681526020016122fb81526020016122fb81526020016122fb81526020016123c781526020016124db81526020016124db81526020016123c781526020016123c781526020016124db81526020016122fb81526020016122fb81526020016122fb81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db8152509050606081905060488151146109365780516040517fc8b56901000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052604401610611565b610100830180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690525f610c45838364010000260061251d565b949350505050565b6101008301805160011790525f60048301821015610ce75761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517f25a7646800000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b825160f01c612f2a8114610d765761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f3e47169c00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b6003840193505f5b83851015610e1b5784515f1a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd18101610e0f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86015160f01c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d18101610e0d57505050600193840193610e1b565b505b85600101955050610d7e565b80610e715761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad7895000017610cb2565b5092949350505050565b81515f90819081908190600181831a1b6703ff200000000000811615610fa25786610ea7896001614efb565b1015610f9957600182811a1b7ffffffffffffffffffffffffffffffffffeffffffffffffffffff00000000000082821701610ee4575f9350610f93565b7ffffffffffffffffffffffffffffffffffffffffffeffffffffff00000000000082821701610f8e576102208a015189037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f75c28ff900000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b600193505b50610fe7565b60019250610fe7565b640400000000811615610fb85760029250610fe7565b6b080000000000000000000000811615610fd55760039250610fe7565b505f9450869350849250611024915050565b505f905061101588888861100d83876101a09190910151600291820201015161ffff1690565b63ffffffff16565b90975060019550879450925050505b93509350939050565b73ffffffffffffffffffffffffffffffffffffffff8111156110ca5761022083015182037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f9d7e517e00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b60c09092018051604080516020810190915290815260a01b9290921790915250565b60208101602082510282015b808210156111355781518151835281526020909101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016110f8565b505050565b5f5b818310156105045782515f90600190821a1b6f07fffffe8000000000000000000000008116156113b757610100860151600116156111f65761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517f5520a51700000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b6f07fffffe0000000000000000000000008116156112c95761122985856f07fffffe0000000003ff200000000000612546565b90955091505f6112398784612615565b50905080156112c35761022087015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f53e6feba00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b506112ea565b6112e760018601856f07fffffe0000000003ff20000000000061251d565b94505b856040015160ff1660ff148061130757508560a0015160ff1660ff145b1561138d5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f3820634100000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b604086018051600190810190915260a0870180519091019052610100860180516009179052611536565b640100002600811615611409576113d7600186018564010000260061251d565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690529450611536565b670400000000000000811615611455575050610100840180516008177ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe16905260019290920191610504565b658000000000008116156114e55761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517fedad0c5800000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b61022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176111c1565b505061113c565b5f5b818310156105045782515f90600190821a1b6f07fffffe00000000000000000000000081161561175d57610100860151600116156115f95761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517f4e803df600000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b8461161581866f07fffffe0000000003ff200000000000612546565b80945081975050505f8061162e89610240015186612690565b91509150811561166f57611643898989612764565b97505f6116508a836129ef565b905061165d8a8383612a15565b50610100890180516002179052611749565b6116798986612bfa565b9092509050811561169d5761168f895f83612a15565b61169889612c74565b611749565b5f6060848a03600581016116b28d8d8d612764565b9b508c6101e0015151602002602001810190505f60059050604051935060208201840160405282818501528184528394506116fa8860056116f38760200190565b0185612cda565b5050506101e08b015180516001019061172d906117278361171e8680510160200190565b90602002900390565b83612ce3565b5061173a8b60ff84612a15565b50506101008901805160021790525b505050610100860180516001179052611af5565b6101008601516002161561187f576501000000000081165f036117fb5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f23b5c6ea00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b606086810180515f1a6003019190829053603b821115611847576040517f6232f2d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050610100860180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc169052600190940193611af5565b6502000000000081161561195b576060868101515f90811a91908290036119215761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f7f9db54200000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b808801600383039250828153826004820101515f1a8360028301015160f01c600101535061194e88612c74565b5050600190940193611af5565b6401000026008116156119ad5761197b600186018564010000260061251d565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690529450611af5565b6b0800000003ff2004000000008116156119e8576119cc868686612cef565b94506119d786612c74565b610100860180516001179052611af5565b65100000000000811615611a0d57611a008686612e19565b5050600190920191610504565b670800000000000000811615611a4557611a278686612e19565b611a3086613271565b50506004610100850152600190920191610504565b65800000000000811615611aa45761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176114b0565b61022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176115c4565b505061153f565b60e08101518151516060919060f082901c9060208114611b48576040517f858f2dcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051935060208401601083045f8183535060016008850483018101928391015f80805b88811015611ba55789811c61ffff81165163ffff0000601092831b16811760e01b8786015284019360f08390031b929092179101611b6c565b50825117909152878203017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08181018952908801601f01166040525f5b82811015611c25576002810288016003015161ffff90811683018051602060f082901c019260e09190911c1690611c1a838284612cda565b505050600101611be2565b50505050505050919050565b6060805f611c3e8461359f565b90505f5b81811015611c81575f611c5586836135b9565b60040190505f611c6587846135e8565b60040282019050611c778883836135ff565b5050600101611c42565b5083611c8c866138bf565b92509250505b9250929050565b5f80808080611ca9888888613934565b985090925090508181036040811115611d3d5761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517fff2f594900000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b805f03611dc55761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517fc75cd50900000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b60028106600103611e515761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517fd76d9b5700000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b6001820397505f5b838910611fd45788515f90811a906001821b906703ff000000000000821615611ea557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd08201611f9e565b6c7e000000000000000000000000821615611ee357507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa98201611f9e565b687e0000000000000000821615611f1d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc98201611f9e565b6102208d01518c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f69f1e3e600000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909b019a831b96909617955050600401611e59565b50509350909150505b935093915050565b5f805f805f80611ff58888613984565b9296509094509250905061200a898486613dc7565b826120158383613e4b565b9550955050505050935093915050565b5f808080612034878787613e9d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08301805184840382529199509294509092505f9161207281614057565b9190529698969750505050505050565b6001909101905f80836120a681856fffffffffdffffffffffffffeffffd9ff61251d565b9450848181036121315761022087015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517ff73a1aa800000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b61213c878787610c09565b95508561215a81876fffffffffdfffffffffffffffffffffff61251d565b9650868681106121e65761022089015188037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517fc4b1913500000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b875160015f91821a1b906b20000000000000000000000082169003612256576102208a015189037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176121b1565b50600190970196876120158a86868686614083565b60605f825160020267ffffffffffffffff81111561228b5761228b614c36565b6040519080825280601f01601f1916602001820160405280156122b5576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156122ef578051835186169085161781526020909201916002016122cd565b50939695505050505050565b5f8151600103612386575060208101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116601b0b60e082901d5f61233e838383614247565b905061ffff81111561237c576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250610239915050565b81515f0361239557505f919050565b6040517f1ac6690800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f815160020361249f57602082015160408301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216601b0b60e083901d5f61240e838383614247565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8516601b0b935060e085901d925090505f612447848483614247565b905060ff821180612458575060ff81115b1561248f576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60081b1794506102399350505050565b600282511015612395576040517ff16066b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81515f14612516576040517f9f16b02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505f919050565b5f5b5f82600186515f1a1b1611838510161561253e5760018401935061251f565b509192915050565b5f80806001818787036020811161255d5780612560565b60205b915050875192505b8519600184841a1b1615818310161561258657600182019150612568565b9681019660208290036008810293841c90931b9261260857604080516020810185905201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527fe47fe8b700000000000000000000000000000000000000000000000000000000825261061191600401614e77565b5095969095509350505050565b5f806126218484612bfa565b909250905081611c925750610120830180515f93845260209384902060408051928352948201855293909401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909316601084901b62ff00001617909317909252909160ff90911660010190565b600182810180515f928392600560ff93909316602102870192830192909101835b818310156127555760018301516021909301805190935f90819060ff1681806126da838e6142a3565b915091508186165f036126fc575f809b509b5050505050505050505050611c92565b5f8761270c6001850389166142ce565b016004028b015195505062ffffff90811693508416830391506127409050575060019750601c1a9550611c92945050505050565b612749836142ce565b840193505050506126b1565b505f9788975095505050505050565b81516101e08401515f80825291600190831a1b907ffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000008201610e71576127a885614f3b565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe169052805190955060015f91821a1b9250805b8587101561298d57865160015f9190911a1b93506401000026008416156128165761280f888888610c09565b96506127e3565b67400000000000000084161561283a5761282f87614f3b565b96506001905061298d565b6001886101000151165f0361290b57600482036128d25761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f8c9fdbb300000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b5f6128de8989896143a6565b60208581028701018190526101008b0180516001179052909850905061290383614f3b565b9250506127e3565b61022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517f722cd24a00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b806129e35761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad7895000017612958565b50905250919392505050565b6101c08201516002828102820101516101e08401515f9261ffff90921691906104a39083565b612a1e836143ce565b610100830180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb1660081790526020808401515f90811a8501602101805190911a60ff811492919060018101825350508115612aa7576040517f8092d1ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050825180516060808601515f90811a87016061018051939461ffff8616949093921a60ff81149291600886048503601c0191600181018253505f60038201537fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe30180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690911790528115612b6a576040517f3abd0c5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050602090920183821b176018820185901b178083529160e0829003612bf25760408051601083901b6020908117601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016918252810190915281517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000168117825286525b505050505050565b6101208201516101408301515f8381526020808220919384939290911c91600160ff84161b80821615612c5f5761ffff83165b8015612c5d578360201c8503612c50576001965061ffff8460101c169550612c5d565b51925061ffff8316612c2d565b505b17610140909601959095525090939092509050565b6060818101515f90811a919082900361113557602083810180515f1a600101919082815350603e8210612cd3576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b8083835e505050565b6020810283835e505050565b5f8080612cfd868686610e7b565b9096509250905080612d8b5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517fb0e4e5b300000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b5f80612d968461445a565b6101808901511615612dd75761016088015160101c5b8015801590612db9575082155b15612dd557602081015190519085149250600190910190612dac565b505b61016088015161ffff16612dfd600184612df15782612df5565b8383035b8b9190612a15565b5081612e0d57612e0d8885614471565b50949695505050505050565b6060828101515f1a908115612ea95761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f6fb11cdc00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b5050612eb4826143ce565b61010082018051600416600890811790915260a0830151602084015160ff8083169360f89290921c9290911c1681035f819003612fde576004856101000151165f03612f7b5761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517fab1d3ea700000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b90820190603e8210612fb9576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60f882901b6020860152610200850151612fd390846144c3565b6102008601526130f9565b60018111156130f957808310156130705761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f78ef278200000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b808311156130f95761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f43168e6800000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b8082036001016020601083028101905b8181101561325d5760a08801516020848a0181015191831c61ffff16915f1a9060015b82811161324b5760208406601c0361314557925160f01c925b83516102008d015160019190911a9061315e9082614547565b6102008e01525f82851480156131745750896001145b61317f576001613181565b8b5b6102008f0151909150613194908261458d565b6102008f0152600f8111806131a95750600f82115b1561322f576102208e01518d037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f7ea1869f00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b818160041b17600187015350506004939093019260010161312c565b50506001909401935050601001613109565b5050505060081b60a0909301929092525050565b60e081015160208083015160f083811c925f9290921a60010191908390036132c5576040517fa806284100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610200850151855180515f928392909160219060101c61ffff165b80156132f757805190925060101c61ffff166132e0565b506040518a82018051919650601c8401939160049160248901915f90811a805b8d8310156133dc5760048202860195506004878a03045b8082111561334c57965161ffff16601c81019950969003600761332e565b506004810298899003805186529894909401938103865b60078211156133a8575160101c61ffff1680518652601c909501947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff990910190613363565b81156133c3575160101c61ffff168051865260048202909501945b50505060019182018051909291909101905f1a80613317565b50505082895250600488810180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9290940491909101601881901b8817939093179052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405260ff1094505083156134a8576040517fe972437e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6134b56001808a1b614f72565b891685891b60f06134c78b6010614efb565b901b171760e08b01526101008a0180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7169052604080516020601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01681815280820183525f80517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001682178152908d52908c01819052908b0181905260608b0181905260808b0181905260a08b018190526101208b018190526101408b018190526102008b015250505050505050505050565b5f81515f036135af57505f919050565b50602001515f1a90565b5f806135c48461359f565b60020260010190505f6135d78585614600565b949091019093016020019392505050565b5f806135f484846135b9565b515f1a949350505050565b808210156111355781517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160f882901c016138395760c08401515b80156138375760a081901c5161016086015161ffff60e085901c1660208101805160089390931b62ffff0016600187901a1760e81b7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316929092179091526040517f570c7a630000000000000000000000000000000000000000000000000000000081529192915f908190819073ffffffffffffffffffffffffffffffffffffffff86169063570c7a63906136f2908790600401614e77565b5f60405180830381865afa15801561370c573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526137519190810190615011565b925092509250821561382d57815160041461379a57816040517fbe2d187d0000000000000000000000000000000000000000000000000000000081526004016106119190614e77565b60208201517fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff88161789525f5b81518110156138225761381a828281518110613803576138036150be565b60200260200101518c61447190919063ffffffff16565b6001016137e5565b505050505050613837565b505050505061363a565b505b5081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160f882901c016138b357606061ffff8260e01c1690505f6003820152600581019050806040517faedfba2f0000000000000000000000000000000000000000000000000000000081526004016106119190614e77565b506004820191506135ff565b6101608101516040805161ffff8316808252602080820283019081019093529092909160109190911c90835b8082111561392b5760208301518252915161ffff16917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101906138eb565b50505050919050565b5f808080613943866002614efb565b9050806c7e0000007e03ff0000000000005b86821081600184515f1a1b161515161561397457600182019150613955565b5090979096508695509350505050565b5f82818061399983866520000000000061251d565b925085831415836139b381886703ff00000000000061251d565b94508085036139ed57507f34bd20690000000000000000000000000000000000000000000000000000000094505f9250829150613dbe9050565b5f806139f98a88614656565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615613a37575095505f9350839250613dbe915050565b86519095506540000000000060015f9290921a9190911b161515888710169150508015613cc657506001909301925f84613a7a81896703ff00000000000061251d565b9550808603613ab557507f7bfa48af0000000000000000000000000000000000000000000000000000000095505f9350839250613dbe915050565b855b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018051908a1160015f9290921a9190911b660100000000000016151516600103613b24577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01613ab7565b818114613b7b575f80613b378484614656565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615613b77575097505f9550859450613dbe9350505050565b9350505b5f831215613bb657507f7bfa48af0000000000000000000000000000000000000000000000000000000096505f9450849350613dbe92505050565b8315613bc257825f0392505b80820394505f851315613c0257507f013b2aaa0000000000000000000000000000000000000000000000000000000096505f9450849350613dbe92505050565b855f03613c1157829550613cc3565b5f8590036043811115613c5257507f32b8b8be0000000000000000000000000000000000000000000000000000000097505f9550859450613dbe9350505050565b600a0a8681025f88838381613c6957613c69614f0e565b0514159050601b82900b8214158180613c7f5750805b15613cbb57507f32b8b8be000000000000000000000000000000000000000000000000000000009a505f9850889750613dbe9650505050505050565b505084019650505b50505b84516c2000000020000000000000000060015f9290921a9190911b161515878610168015613daf5760019095019485613d06818a6520000000000061251d565b965086613d1c818b6703ff00000000000061251d565b9750808803613d5957507f013b2aaa0000000000000000000000000000000000000000000000000000000097505f9550859450613dbe9350505050565b505f80613d66838a614656565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615613da6575097505f9550859450613dbe9350505050565b95860195925050505b845f03613dba575f93505b5050505b92959194509250565b7fffffffff00000000000000000000000000000000000000000000000000000000811615611135576102208301515f9083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000179050815f528060045260245ffd5b5f805f613e588585614780565b9150915080610731576040517f22c9f7bb0000000000000000000000000000000000000000000000000000000081526004810186905260248101859052604401610611565b5f80806001850181806f7ffffffffffffffffffffffb0000000081807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8b8b0301602080821015613eeb5750805b875193505b84600185851a1b1615158184101615613f0e57600183019250613ef0565b505080602003613f99576102208c01518b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f30515bda00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b85810180519095505f1a6001811b640400000000161580613fb95750858b145b1561403f576102208d015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f04022fbf00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b50949b939a505060018a019850919650505050505050565b5f80601f90505f60e09050818451168082175f528060208601600183016020035e50505f519392505050565b5f60608186860361ffff8111156140c9576040517fb6da789c00000000000000000000000000000000000000000000000000000000815260048101829052602401610611565b604080516041888803848101838101929092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169093526002828101859052018152935060228401925061411f898484612cda565b61412c8783850183612cda565b50505060c08701515b80156141f65760a081901c516040517fc6c0cbb60000000000000000000000000000000000000000000000000000000081529091905f90819073ffffffffffffffffffffffffffffffffffffffff84169063c6c0cbb69061419a908890600401614e77565b6040805180830381865afa1580156141b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141d891906150eb565b9150915081156141ee5794506104a39350505050565b505050614135565b61022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad7895000017612d56565b5f805f614255868686614886565b915091508061429a576040517f05e476780000000000000000000000000000000000000000000000000000000081526004810187905260248101869052604401610611565b50949350505050565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116611c92575060019250929050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036142ff5750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f805f6143b6888888610e7b565b92509250925082156141f6579093509150611fdd9050565b8051602080830180515f90811a8086016021015160a0939190831a6144205785518488018051600861ffff909316929092046020038801601e83901a840360010160100290811b909217905260f01092505b50508015612cd3576040517f5b1a42d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61446761010083615115565b6001901b92915050565b6101608201805160408051808201909152601091821c808252602082018590528351600161ffff909116019282901b929092179092526144b08361445a565b6101809094018051909417909352505050565b5f6144ce838361458d565b925060ff600884901c8116830190811115614515576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff841660089190911b17905092915050565b5f60ff831682811015614586576040517f23b49a2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050900390565b5f60ff808416830190600885901c811690601086901c908311156145dd576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808311156145e85750815b601081901b600883901b841717935050505092915050565b5f61460a8361359f565b82106146465781836040517ffcfaeff100000000000000000000000000000000000000000000000000000000815260040161061192919061514d565b50600202016003015161ffff1690565b81515f90819065200000000000600191831a9190911b1615158385101680850190828061468384886149d2565b90925090507fffffffff000000000000000000000000000000000000000000000000000000008216156146be575093505f9250611c92915050565b825f03614721577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81116146f2575f614714565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95509350611c9292505050565b7f8000000000000000000000000000000000000000000000000000000000000000811161474e575f614770565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95505f0393505050509250929050565b5f601b83900b83148383826147e4577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000008605156147c457620186a0860595506005850194505b8586601b0b146147df57600a860595508460010194506147c4565b6147fa565b855f036147fa57505f925060019150611c929050565b848560030b14614856575f85121561481a57505f9250829150611c929050565b6040517fd556b1110000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610611565b50507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660e084901b1791509250929050565b5f805f8512156148cc576040517f4a7d166b0000000000000000000000000000000000000000000000000000000081526004810186905260248101859052604401610611565b845f036148de57505f90506001611fdd565b8460ff8416850185811215614929576040517fd556b1110000000000000000000000000000000000000000000000000000000081526004810188905260248101879052604401610611565b5f805f831215614993577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb383121561496a575f809550955050505050611fdd565b825f03600a0a915081848161498157614981614f0e565b0495505084029091149150611fdd9050565b5f8313156149c2576149a683600a615283565b91506149b2828561528e565b955060019450611fdd9350505050565b8360019550955050505050611fdd565b5f80828410614a0557507f34bd20690000000000000000000000000000000000000000000000000000000090505f611c92565b835f03614a3e576040517fda6966d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60305f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501815b878210158015614a765750604d83105b15614ab957815160018401937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90930192600a0a5f9190911a8590030201614a66565b878210614bdf5781515f1a8490036001811115614b0157507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450611c929350505050565b600a84900a8102828101831115614b4457507f0fdc26350000000000000000000000000000000000000000000000000000000096505f9550611c92945050505050565b9190910190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b878210614bdf5781515f1a60308114614bb457507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450611c929350505050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190614b70565b5f9890975095505050505050565b614bf56152a5565b565b5f60208284031215614c07575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610507575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614caa57614caa614c36565b604052919050565b5f67ffffffffffffffff821115614ccb57614ccb614c36565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f60208284031215614d07575f80fd5b813567ffffffffffffffff811115614d1d575f80fd5b8201601f81018413614d2d575f80fd5b8035614d40614d3b82614cb2565b614c63565b818152856020838501011115614d54575f80fd5b816020840160208301375f91810160200191909152949350505050565b602080825282518282018290528051604084018190525f9291820190839060608601905b80831015614dcb57835173ffffffffffffffffffffffffffffffffffffffff168252928401926001929092019190840190614d95565b509695505050505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b604081525f614e346040830185614dd6565b8281036020848101919091528451808352858201928201905f5b81811015614e6a57845183529383019391830191600101614e4e565b5090979650505050505050565b602081525f6105076020830184614dd6565b80516020808301519190811015614ec8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8082018082111561018057610180614ece565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614f6b57614f6b614ece565b5060010190565b8181038181111561018057610180614ece565b80518015158114610239575f80fd5b5f82601f830112614fa3575f80fd5b8151602067ffffffffffffffff821115614fbf57614fbf614c36565b8160051b614fce828201614c63565b9283528481018201928281019087851115614fe7575f80fd5b83870192505b8483101561500657825182529183019190830190614fed565b979650505050505050565b5f805f60608486031215615023575f80fd5b61502c84614f85565b9250602084015167ffffffffffffffff80821115615048575f80fd5b818601915086601f83011261505b575f80fd5b8151615069614d3b82614cb2565b81815288602083860101111561507d575f80fd5b8160208501602083015e5f60208383010152809550505060408601519150808211156150a7575f80fd5b506150b486828701614f94565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80604083850312156150fc575f80fd5b61510583614f85565b9150602083015190509250929050565b5f82615148577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b828152604060208201525f610c456040830184614dd6565b600181815b808511156151be57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156151a4576151a4614ece565b808516156151b157918102915b93841c939080029061516a565b509250929050565b5f826151d457506001610180565b816151e057505f610180565b81600181146151f657600281146152005761521c565b6001915050610180565b60ff84111561521157615211614ece565b50506001821b610180565b5060208310610133831016604e8410600b841016171561523f575081810a610180565b6152498383615165565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561527b5761527b614ece565b029392505050565b5f61050783836151c6565b808202811582820484141761018057610180614ece565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0288400100420b0280046b0641220186adb8a044003012020f2a880521281ac8811a000000000000000000080000000000100000000000000002000000000000000000290ea98a3a10f9c53927bda61c6395ad0e9fb4a8075dbeaf2d313e9e09b06d681dfe49062ce21ac13e83a6cc2ad2d2123422c3e0052f369e1f27267220a0a68d2f357696465d217b131120880f24f4a8242f1af53f41f7290afa3e8638acf3d13397e9fd00443a453b406bb547b9059d25a3cd1e11d0c3260b15eb4d16fc94274427bc412baf2cc2321b8f630dca9efe403ce35f1400684845c291e3425d68b13d5f9a151eb98c15239cd9c10c1f698235c8d3843c08d579273459d41a2c9ff617a5b2cd15c0031810f621af127ba34c26bb6c4137b2ad3d1b73563d0210215f36aa563921098e690457fb180376e752066a470128f11de101fcc60522de7ddd183d3d6d4196c37031cba2872e7b3af5304eee7219a8093543082b5f0801f5a522fb22fb22fb23c724db24db23c723c724db22fb22fb22fb24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db"; /// @dev The runtime bytecode of the contract. bytes constant RUNTIME_CODE = - hex"608060405234801561000f575f80fd5b5060043610610064575f3560e01c80637764fd9c1161004d5780637764fd9c146100b0578063ccf44775146100d1578063d6d8c9a8146100e6575f80fd5b806301ffc9a7146100685780635514ca2014610090575b5f80fd5b61007b6100763660046146eb565b6100ee565b60405190151581526020015b60405180910390f35b6100a361009e3660046147eb565b610186565b6040516100879190614865565b6100c36100be3660046147eb565b61023e565b604051610087929190614916565b6100d961025e565b604051610087919061496b565b6100d961026d565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f1a2c8edd00000000000000000000000000000000000000000000000000000000148061018057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6040805160208101909152606081525f6101e3836101a2610277565b6101aa61029a565b60408051808201909152600881527f1a351cf91d391d9600000000000000000000000000000000000000000000000060208201526102ba565b90505f6020840190505f6101fa8580510160200190565b90506102078383836104ac565b915061021483838361050e565b9150604051806020016040528061022a85610697565b905293505050506102396106f5565b919050565b606080610255610250846101a2610277565b61073a565b91509150915091565b6060610268610895565b905090565b60606102686108e2565b6060604051806101a001604052806101638152602001614dc76101639139905090565b60606040518060c0016040528060908152602001614f2a60909139905090565b6103476040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b8152602001848152602001858152602001600467ffffffffffffffff8111156103cd576103cd61472a565b6040519080825280602002602001820160405280156103f6578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016828152808301825283517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001681178452855290840182905283018190529082018190526080820181905260a082018190526101208201819052610140820181905261020082015290505b95945050505050565b5f5b8183101561050457825160015f9190911a1b6401000026008116156104df576104d8858585610ba3565b93506104fe565b658000000000008116156104f8576104d8858585610be7565b50610504565b506104ae565b50815b9392505050565b815160408051808201909152601081527f7573696e672d776f7264732d66726f6d0000000000000000000000000000000060208201525f91906105509061497d565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008216146105815783915050610507565b506010830192508183106105f85761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517fe3e4992d0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b60405180910390fd5b825160015f91821a1b906401000026008216900361063f5761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016105ba565b836001019350505b818310156105045761065a8484846104ac565b925081831015610504575f80610671868686610daf565b909650909250905081610685575050610504565b610690868683610f3f565b5050610647565b60c08101516040516060919073ffffffffffffffffffffffffffffffffffffffff602082015f5b84156106df57848316825260a09490941c51936020909101906001016106be565b83526040526106ed82610fdc565b509392505050565b604051620100008110610737576040517f766c065f000000000000000000000000000000000000000000000000000000008152600481018290526024016105ef565b50565b6060805f83610220015151111561086a575f61075b84610220015160200190565b90505f61077085610220015180510160200190565b905061077d8583836104ac565b915061078a85838361050e565b91505b808210156107c1576107a08583836104ac565b91506107ad85838361102a565b91506107ba858383611383565b915061078d565b8082146107fa576040517f7d565df600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100850151600816156108675761022085015182037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517ff06f54cf0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b50505b5f8061087f61087886611898565b86906119cd565b9150915061088b6106f5565b9094909350915050565b6040805160a0810182526004808252611a356020830152611cf992820192909252611d39606082810191909152611d96608083015291908190805b6108d981611f19565b94505050505090565b60606146e15f604890508091505f6040518061092001604052808467ffffffffffffffff1667ffffffffffffffff168152602001611fa98152602001611fa98152602001611fa98152602001612075815260200161218981526020016121898152602001612075815260200161207581526020016121898152602001611fa98152602001611fa98152602001611fa98152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152602001612189815260200161218981526020016121898152509050606081905060488151146108d05780516040517fc8b569010000000000000000000000000000000000000000000000000000000081526004810191909152602481018490526044016105ef565b610100830180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690525f610bdf83836401000026006121cb565b949350505050565b6101008301805160011790525f60048301821015610c5f5761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517f25a764680000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b825160f01c612f2a8114610ccc5761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f3e47169c0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b6003840193505f5b83851015610d715784515f1a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd18101610d65577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86015160f01c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d18101610d6357505050600193840193610d71565b505b85600101955050610cd4565b80610da55761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001610c2a565b5092949350505050565b81515f90819081908190600181831a1b6703ff200000000000811615610eb45786610ddb8960016149ef565b1015610eab57600182811a1b7ffffffffffffffffffffffffffffffffffeffffffffffffffffff00000000000082821701610e18575f9350610ea5565b7ffffffffffffffffffffffffffffffffffffffffffeffffffffff00000000000082821701610ea0576102208a015189037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f75c28ff90000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b600193505b50610ef9565b60019250610ef9565b640400000000811615610eca5760029250610ef9565b6b080000000000000000000000811615610ee75760039250610ef9565b505f9450869350849250610f36915050565b505f9050610f27888888610f1f83876101a09190910151600291820201015161ffff1690565b63ffffffff16565b90975060019550879450925050505b93509350939050565b73ffffffffffffffffffffffffffffffffffffffff811115610fba5761022083015182037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f9d7e517e0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b60c09092018051604080516020810190915290815260a01b9290921790915250565b60208101602082510282015b808210156110255781518151835281526020909101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001610fe8565b505050565b5f5b818310156105045782515f90600190821a1b6f07fffffe80000000000000000000000081161561124157610100860151600116156110c45761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517f5520a5170000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b6f07fffffe000000000000000000000000811615611175576110f785856f07fffffe0000000003ff2000000000006121f4565b90955091505f61110787846122c3565b509050801561116f5761022087015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f53e6feba0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b50611196565b61119360018601856f07fffffe0000000003ff2000000000006121cb565b94505b856040015160ff1660ff14806111b357508560a0015160ff1660ff145b156112175761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f382063410000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b604086018051600190810190915260a087018051909101905261010086018051600917905261137c565b6401000026008116156112935761126160018601856401000026006121cb565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe169052945061137c565b6704000000000000008116156112df575050610100840180516008177ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe16905260019290920191610504565b6580000000000081161561134d5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517fedad0c580000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b61022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00161108f565b505061102c565b5f5b818310156105045782515f90600190821a1b6f07fffffe000000000000000000000000811615611581576101008601516001161561141d5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517f4e803df60000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b8461143981866f07fffffe0000000003ff2000000000006121f4565b80945081975050505f806114528961024001518661233e565b91509150811561149357611467898989612412565b97505f6114748a83612637565b90506114818a838361265d565b5061010089018051600217905261156d565b61149d8986612842565b909250905081156114c1576114b3895f8361265d565b6114bc896128bc565b61156d565b5f6060848a03600581016114d68d8d8d612412565b9b508c6101e0015151602002602001810190505f600590506040519350602082018401604052828185015281845283945061151e8860056115178760200190565b0185612922565b5050506101e08b01518051600101906115519061154b836115428680510160200190565b90602002900390565b8361292b565b5061155e8b60ff8461265d565b50506101008901805160021790525b505050610100860180516001179052611891565b61010086015160021615611681576501000000000081165f036115fd5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f23b5c6ea0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b606086810180515f1a6003019190829053603b821115611649576040517f6232f2d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050610100860180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc169052600190940193611891565b6502000000000081161561173b576060868101515f90811a91908290036117015761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f7f9db5420000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b808801600383039250828153826004820101515f1a8360028301015160f01c600101535061172e886128bc565b5050600190940193611891565b64010000260081161561178d5761175b60018601856401000026006121cb565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690529450611891565b6b0800000003ff2004000000008116156117c8576117ac868686612937565b94506117b7866128bc565b610100860180516001179052611891565b651000000000008116156117ed576117e08686612a3f565b5050600190920191610504565b670800000000000000811615611825576118078686612a3f565b61181086612ded565b50506004610100850152600190920191610504565b658000000000008116156118625761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001611318565b61022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016113e8565b5050611385565b60e08101518151516060919060f082901c90602081146118e4576040517f858f2dcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051935060208401601083045f8183535060016008850483018101928391015f80805b888110156119415789811c61ffff81165163ffff0000601092831b16811760e01b8786015284019360f08390031b929092179101611908565b50825117909152878203017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08181018952908801601f01166040525f5b828110156119c1576002810288016003015161ffff90811683018051602060f082901c019260e09190911c16906119b6838284612922565b50505060010161197e565b50505050505050919050565b6060805f6119da8461311b565b90505f5b81811015611a1d575f6119f18683613135565b60040190505f611a018784613164565b60040282019050611a1388838361317b565b50506001016119de565b5083611a288661343b565b92509250505b9250929050565b5f80808080611a458888886134b0565b985090925090508181036040811115611ab75761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517fff2f59490000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b805f03611b1d5761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517fc75cd5090000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b60028106600103611b875761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517fd76d9b570000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b6001820397505f5b838910611ce85788515f90811a906001821b906703ff000000000000821615611bdb57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd08201611cb2565b6c7e000000000000000000000000821615611c1957507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa98201611cb2565b687e0000000000000000821615611c5357507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc98201611cb2565b6102208d01518c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f69f1e3e60000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909b019a831b96909617955050600401611b8f565b50509350909150505b935093915050565b5f805f805f80611d098888613500565b92965090945092509050611d1e898486613943565b82611d2983836139a5565b9550955050505050935093915050565b5f808080611d488787876139f7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08301805184840382529199509294509092505f91611d8681613b6d565b9190529698969750505050505050565b6001909101905f8083611dba81856fffffffffdffffffffffffffeffffd9ff6121cb565b945084818103611e235761022087015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517ff73a1aa80000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b611e2e878787610ba3565b955085611e4c81876fffffffffdfffffffffffffffffffffff6121cb565b965086868110611eb65761022089015188037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517fc4b191350000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b875160015f91821a1b906b20000000000000000000000082169003611f04576102208a015189037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001611e81565b5060019097019687611d298a86868686613b99565b60605f825160020267ffffffffffffffff811115611f3957611f3961472a565b6040519080825280601f01601f191660200182016040528015611f63576020820181803683370190505b50905061ffff80196020850160208651028101600285015b81831015611f9d57805183518616908516178152602090920191600201611f7b565b50939695505050505050565b5f8151600103612034575060208101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116601b0b60e082901d5f611fec838383613d3b565b905061ffff81111561202a576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250610239915050565b81515f0361204357505f919050565b6040517f1ac6690800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f815160020361214d57602082015160408301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216601b0b60e083901d5f6120bc838383613d3b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8516601b0b935060e085901d925090505f6120f5848483613d3b565b905060ff821180612106575060ff81115b1561213d576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60081b1794506102399350505050565b600282511015612043576040517ff16066b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81515f146121c4576040517f9f16b02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505f919050565b5f5b5f82600186515f1a1b161183851016156121ec576001840193506121cd565b509192915050565b5f80806001818787036020811161220b578061220e565b60205b915050875192505b8519600184841a1b1615818310161561223457600182019150612216565b9681019660208290036008810293841c90931b926122b657604080516020810185905201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527fe47fe8b70000000000000000000000000000000000000000000000000000000082526105ef9160040161496b565b5095969095509350505050565b5f806122cf8484612842565b909250905081611a2e5750610120830180515f93845260209384902060408051928352948201855293909401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909316601084901b62ff00001617909317909252909160ff90911660010190565b600182810180515f928392600560ff93909316602102870192830192909101835b818310156124035760018301516021909301805190935f90819060ff168180612388838e613d97565b915091508186165f036123aa575f809b509b5050505050505050505050611a2e565b5f876123ba600185038916613dc2565b016004028b015195505062ffffff90811693508416830391506123ee9050575060019750601c1a9550611a2e945050505050565b6123f783613dc2565b8401935050505061235f565b505f9788975095505050505050565b81516101e08401515f80825291600190831a1b907ffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000008201610da55761245685614a2f565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe169052805190955060015f91821a1b9250805b858710156125f757865160015f9190911a1b93506401000026008416156124c4576124bd888888610ba3565b9650612491565b6740000000000000008416156124e8576124dd87614a2f565b9650600190506125f7565b6001886101000151165f03612597576004820361255e5761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f8c9fdbb30000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b5f61256a898989613e9a565b60208581028701018190526101008b0180516001179052909850905061258f83614a2f565b925050612491565b61022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517f722cd24a0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b8061262b5761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016125c2565b50905250919392505050565b6101c08201516002828102820101516101e08401515f9261ffff90921691906104a39083565b61266683613ec2565b610100830180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb1660081790526020808401515f90811a8501602101805190911a60ff8114929190600181018253505081156126ef576040517f8092d1ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050825180516060808601515f90811a87016061018051939461ffff8616949093921a60ff81149291600886048503601c0191600181018253505f60038201537fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe30180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016909117905281156127b2576040517f3abd0c5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050602090920183821b176018820185901b178083529160e082900361283a5760408051601083901b6020908117601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016918252810190915281517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000168117825286525b505050505050565b6101208201516101408301515f8381526020808220919384939290911c91600160ff84161b808216156128a75761ffff83165b80156128a5578360201c8503612898576001965061ffff8460101c1695506128a5565b51925061ffff8316612875565b505b17610140909601959095525090939092509050565b6060818101515f90811a919082900361102557602083810180515f1a600101919082815350603e821061291b576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b8083835e505050565b6020810283835e505050565b5f8080612945868686610daf565b90965092509050806129b15761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015b6040517fb0e4e5b30000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b5f806129bc84613f4e565b61018089015116156129fd5761016088015160101c5b80158015906129df575082155b156129fb576020810151905190851492506001909101906129d2565b505b61016088015161ffff16612a23600184612a175782612a1b565b8383035b8b919061265d565b5081612a3357612a338885613f65565b50949695505050505050565b6060828101515f1a908115612aad5761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f6fb11cdc0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b5050612ab882613ec2565b61010082018051600416600890811790915260a0830151602084015160ff8083169360f89290921c9290911c1681035f819003612bc0576004856101000151165f03612b5d5761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517fab1d3ea70000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b90820190603e8210612b9b576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60f882901b6020860152610200850151612bb59084613fb7565b610200860152612c97565b6001811115612c975780831015612c305761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f78ef27820000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b80831115612c975761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f43168e680000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b8082036001016020601083028101905b81811015612dd95760a08801516020848a0181015191831c61ffff16915f1a9060015b828111612dc75760208406601c03612ce357925160f01c925b83516102008d015160019190911a90612cfc908261403b565b6102008e01525f8285148015612d125750896001145b612d1d576001612d1f565b8b5b6102008f0151909150612d329082614081565b6102008f0152600f811180612d475750600f82115b15612dab576102208e01518d037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f7ea1869f0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b818160041b176001870153505060049390930192600101612cca565b50506001909401935050601001612ca7565b5050505060081b60a0909301929092525050565b60e081015160208083015160f083811c925f9290921a6001019190839003612e41576040517fa806284100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610200850151855180515f928392909160219060101c61ffff165b8015612e7357805190925060101c61ffff16612e5c565b506040518a82018051919650601c8401939160049160248901915f90811a805b8d831015612f585760048202860195506004878a03045b80821115612ec857965161ffff16601c810199509690036007612eaa565b506004810298899003805186529894909401938103865b6007821115612f24575160101c61ffff1680518652601c909501947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff990910190612edf565b8115612f3f575160101c61ffff168051865260048202909501945b50505060019182018051909291909101905f1a80612e93565b50505082895250600488810180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9290940491909101601881901b8817939093179052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405260ff109450508315613024576040517fe972437e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130316001808a1b614a66565b891685891b60f06130438b60106149ef565b901b171760e08b01526101008a0180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7169052604080516020601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01681815280820183525f80517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001682178152908d52908c01819052908b0181905260608b0181905260808b0181905260a08b018190526101208b018190526101408b018190526102008b015250505050505050505050565b5f81515f0361312b57505f919050565b50602001515f1a90565b5f806131408461311b565b60020260010190505f61315385856140f4565b949091019093016020019392505050565b5f806131708484613135565b515f1a949350505050565b808210156110255781517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160f882901c016133b55760c08401515b80156133b35760a081901c5161016086015161ffff60e085901c1660208101805160089390931b62ffff0016600187901a1760e81b7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316929092179091526040517f570c7a630000000000000000000000000000000000000000000000000000000081529192915f908190819073ffffffffffffffffffffffffffffffffffffffff86169063570c7a639061326e90879060040161496b565b5f60405180830381865afa158015613288573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526132cd9190810190614b05565b92509250925082156133a957815160041461331657816040517fbe2d187d0000000000000000000000000000000000000000000000000000000081526004016105ef919061496b565b60208201517fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff88161789525f5b815181101561339e5761339682828151811061337f5761337f614bb2565b60200260200101518c613f6590919063ffffffff16565b600101613361565b5050505050506133b3565b50505050506131b6565b505b5081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160f882901c0161342f57606061ffff8260e01c1690505f6003820152600581019050806040517faedfba2f0000000000000000000000000000000000000000000000000000000081526004016105ef919061496b565b5060048201915061317b565b6101608101516040805161ffff8316808252602080820283019081019093529092909160109190911c90835b808211156134a75760208301518252915161ffff16917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090910190613467565b50505050919050565b5f8080806134bf8660026149ef565b9050806c7e0000007e03ff0000000000005b86821081600184515f1a1b16151516156134f0576001820191506134d1565b5090979096508695509350505050565b5f8281806135158386652000000000006121cb565b9250858314158361352f81886703ff0000000000006121cb565b945080850361356957507f34bd20690000000000000000000000000000000000000000000000000000000094505f925082915061393a9050565b5f806135758a8861414a565b90925090507fffffffff000000000000000000000000000000000000000000000000000000008216156135b3575095505f935083925061393a915050565b86519095506540000000000060015f9290921a9190911b16151588871016915050801561384257506001909301925f846135f681896703ff0000000000006121cb565b955080860361363157507f7bfa48af0000000000000000000000000000000000000000000000000000000095505f935083925061393a915050565b855b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018051908a1160015f9290921a9190911b6601000000000000161515166001036136a0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01613633565b8181146136f7575f806136b3848461414a565b90925090507fffffffff000000000000000000000000000000000000000000000000000000008216156136f3575097505f955085945061393a9350505050565b9350505b5f83121561373257507f7bfa48af0000000000000000000000000000000000000000000000000000000096505f945084935061393a92505050565b831561373e57825f0392505b80820394505f85131561377e57507f013b2aaa0000000000000000000000000000000000000000000000000000000096505f945084935061393a92505050565b855f0361378d5782955061383f565b5f85900360438111156137ce57507f32b8b8be0000000000000000000000000000000000000000000000000000000097505f955085945061393a9350505050565b600a0a8681025f888383816137e5576137e5614a02565b0514159050601b82900b82141581806137fb5750805b1561383757507f32b8b8be000000000000000000000000000000000000000000000000000000009a505f985088975061393a9650505050505050565b505084019650505b50505b84516c2000000020000000000000000060015f9290921a9190911b16151587861016801561392b5760019095019485613882818a652000000000006121cb565b965086613898818b6703ff0000000000006121cb565b97508088036138d557507f013b2aaa0000000000000000000000000000000000000000000000000000000097505f955085945061393a9350505050565b505f806138e2838a61414a565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615613922575097505f955085945061393a9350505050565b95860195925050505b845f03613936575f93505b5050505b92959194509250565b7fffffffff00000000000000000000000000000000000000000000000000000000811615611025576102208301515f9083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0019050815f528060045260245ffd5b5f805f6139b28585614274565b91509150806106ed576040517f22c9f7bb00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016105ef565b5f80806001850181806f7ffffffffffffffffffffffb0000000081807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8b8b0301602080821015613a455750805b875193505b84600185851a1b1615158184101615613a6857600183019250613a4a565b505080602003613ad1576102208c01518b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f30515bda0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b85810180519095505f1a6001811b640400000000161580613af15750858b145b15613b55576102208d015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016040517f04022fbf0000000000000000000000000000000000000000000000000000000081526004016105ef91815260200190565b50949b939a505060018a019850919650505050505050565b5f80601f90505f60e09050818451168082175f528060208601600183016020035e50505f519392505050565b5f60608186860361ffff811115613bdf576040517fb6da789c000000000000000000000000000000000000000000000000000000008152600481018290526024016105ef565b604080516041888803848101838101929092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690935260028281018590520181529350602284019250613c35898484612922565b613c428783850183612922565b50505060c08701515b8015613d0c5760a081901c516040517fc6c0cbb60000000000000000000000000000000000000000000000000000000081529091905f90819073ffffffffffffffffffffffffffffffffffffffff84169063c6c0cbb690613cb090889060040161496b565b6040805180830381865afa158015613cca573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613cee9190614bdf565b915091508115613d045794506104a39350505050565b505050613c4b565b61022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00161297c565b5f805f613d4986868661437a565b9150915080613d8e576040517f05e4767800000000000000000000000000000000000000000000000000000000815260048101879052602481018690526044016105ef565b50949350505050565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116611a2e575060019250929050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613df35750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f805f613eaa888888610daf565b9250925092508215613d0c579093509150611cf19050565b8051602080830180515f90811a8086016021015160a0939190831a613f145785518488018051600861ffff909316929092046020038801601e83901a840360010160100290811b909217905260f01092505b5050801561291b576040517f5b1a42d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f613f5b61010083614c09565b6001901b92915050565b6101608201805160408051808201909152601091821c808252602082018590528351600161ffff909116019282901b92909217909252613fa483613f4e565b6101809094018051909417909352505050565b5f613fc28383614081565b925060ff600884901c8116830190811115614009576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff841660089190911b17905092915050565b5f60ff83168281101561407a576040517f23b49a2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050900390565b5f60ff808416830190600885901c811690601086901c908311156140d1576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808311156140dc5750815b601081901b600883901b841717935050505092915050565b5f6140fe8361311b565b821061413a5781836040517ffcfaeff10000000000000000000000000000000000000000000000000000000081526004016105ef929190614c41565b50600202016003015161ffff1690565b81515f90819065200000000000600191831a9190911b1615158385101680850190828061417784886144c6565b90925090507fffffffff000000000000000000000000000000000000000000000000000000008216156141b2575093505f9250611a2e915050565b825f03614215577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81116141e6575f614208565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95509350611a2e92505050565b7f80000000000000000000000000000000000000000000000000000000000000008111614242575f614264565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95505f0393505050509250929050565b5f601b83900b83148383826142d8577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000008605156142b857620186a0860595506005850194505b8586601b0b146142d357600a860595508460010194506142b8565b6142ee565b855f036142ee57505f925060019150611a2e9050565b848560030b1461434a575f85121561430e57505f9250829150611a2e9050565b6040517fd556b11100000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016105ef565b50507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660e084901b1791509250929050565b5f805f8512156143c0576040517f4a7d166b00000000000000000000000000000000000000000000000000000000815260048101869052602481018590526044016105ef565b845f036143d257505f90506001611cf1565b8460ff841685018581121561441d576040517fd556b11100000000000000000000000000000000000000000000000000000000815260048101889052602481018790526044016105ef565b5f805f831215614487577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb383121561445e575f809550955050505050611cf1565b825f03600a0a915081848161447557614475614a02565b0495505084029091149150611cf19050565b5f8313156144b65761449a83600a614d77565b91506144a68285614d82565b955060019450611cf19350505050565b8360019550955050505050611cf1565b5f808284106144f957507f34bd20690000000000000000000000000000000000000000000000000000000090505f611a2e565b835f03614532576040517fda6966d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60305f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501815b87821015801561456a5750604d83105b156145ad57815160018401937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90930192600a0a5f9190911a859003020161455a565b8782106146d35781515f1a84900360018111156145f557507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450611a2e9350505050565b600a84900a810282810183111561463857507f0fdc26350000000000000000000000000000000000000000000000000000000096505f9550611a2e945050505050565b9190910190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b8782106146d35781515f1a603081146146a857507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450611a2e9350505050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190614664565b5f9890975095505050505050565b6146e9614d99565b565b5f602082840312156146fb575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610507575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561479e5761479e61472a565b604052919050565b5f67ffffffffffffffff8211156147bf576147bf61472a565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f602082840312156147fb575f80fd5b813567ffffffffffffffff811115614811575f80fd5b8201601f81018413614821575f80fd5b803561483461482f826147a6565b614757565b818152856020838501011115614848575f80fd5b816020840160208301375f91810160200191909152949350505050565b602080825282518282018290528051604084018190525f9291820190839060608601905b808310156148bf57835173ffffffffffffffffffffffffffffffffffffffff168252928401926001929092019190840190614889565b509695505050505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b604081525f61492860408301856148ca565b8281036020848101919091528451808352858201928201905f5b8181101561495e57845183529383019391830191600101614942565b5090979650505050505050565b602081525f61050760208301846148ca565b805160208083015191908110156149bc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115610180576101806149c2565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a5f57614a5f6149c2565b5060010190565b81810381811115610180576101806149c2565b80518015158114610239575f80fd5b5f82601f830112614a97575f80fd5b8151602067ffffffffffffffff821115614ab357614ab361472a565b8160051b614ac2828201614757565b9283528481018201928281019087851115614adb575f80fd5b83870192505b84831015614afa57825182529183019190830190614ae1565b979650505050505050565b5f805f60608486031215614b17575f80fd5b614b2084614a79565b9250602084015167ffffffffffffffff80821115614b3c575f80fd5b818601915086601f830112614b4f575f80fd5b8151614b5d61482f826147a6565b818152886020838601011115614b71575f80fd5b8160208501602083015e5f6020838301015280955050506040860151915080821115614b9b575f80fd5b50614ba886828701614a88565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8060408385031215614bf0575f80fd5b614bf983614a79565b9150602083015190509250929050565b5f82614c3c577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b828152604060208201525f610bdf60408301846148ca565b600181815b80851115614cb257817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614c9857614c986149c2565b80851615614ca557918102915b93841c9390800290614c5e565b509250929050565b5f82614cc857506001610180565b81614cd457505f610180565b8160018114614cea5760028114614cf457614d10565b6001915050610180565b60ff841115614d0557614d056149c2565b50506001821b610180565b5060208310610133831016604e8410600b8410161715614d33575081810a610180565b614d3d8383614c59565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115614d6f57614d6f6149c2565b029392505050565b5f6105078383614cba565b8082028115828204841417610180576101806149c2565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0288400100420b0280046b0641220186adb8a044003012020f2a880521281ac8811a000000000000000000080000000000100000000000000002000000000000000000290ea98a3a10f9c53927bda61c6395ad0e9fb4a8075dbeaf2d313e9e09b06d681dfe49062ce21ac13e83a6cc2ad2d2123422c3e0052f369e1f27267220a0a68d2f357696465d217b131120880f24f4a8242f1af53f41f7290afa3e8638acf3d13397e9fd00443a453b406bb547b9059d25a3cd1e11d0c3260b15eb4d16fc94274427bc412baf2cc2321b8f630dca9efe403ce35f1400684845c291e3425d68b13d5f9a151eb98c15239cd9c10c1f698235c8d3843c08d579273459d41a2c9ff617a5b2cd15c0031810f621af127ba34c26bb6c4137b2ad3d1b73563d0210215f36aa563921098e690457fb180376e752066a470128f11de101fcc60522de7ddd183d3d6d4196c37031cba2872e7b3af5304eee7219a8093543082b5f0801f5a51fa91fa91fa92075218921892075207521891fa91fa91fa9218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189"; + hex"608060405234801561000f575f80fd5b5060043610610064575f3560e01c80637764fd9c1161004d5780637764fd9c146100b0578063ccf44775146100d1578063d6d8c9a8146100e6575f80fd5b806301ffc9a7146100685780635514ca2014610090575b5f80fd5b61007b610076366004614bf7565b6100ee565b60405190151581526020015b60405180910390f35b6100a361009e366004614cf7565b610186565b6040516100879190614d71565b6100c36100be366004614cf7565b61023e565b604051610087929190614e22565b6100d961025e565b6040516100879190614e77565b6100d961026d565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f1a2c8edd00000000000000000000000000000000000000000000000000000000148061018057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6040805160208101909152606081525f6101e3836101a2610277565b6101aa61029a565b60408051808201909152600881527f1c991fe52025208200000000000000000000000000000000000000000000000060208201526102ba565b90505f6020840190505f6101fa8580510160200190565b90506102078383836104ac565b915061021483838361050e565b9150604051806020016040528061022a856106db565b90529350505050610239610739565b919050565b606080610255610250846101a2610277565b61077e565b91509150915091565b60606102686108fb565b905090565b6060610268610948565b6060604051806101a0016040528061016381526020016152d36101639139905090565b60606040518060c001604052806090815260200161543660909139905090565b6103476040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b8152602001848152602001858152602001600467ffffffffffffffff8111156103cd576103cd614c36565b6040519080825280602002602001820160405280156103f6578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016828152808301825283517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001681178452855290840182905283018190529082018190526080820181905260a082018190526101208201819052610140820181905261020082015290505b95945050505050565b5f5b8183101561050457825160015f9190911a1b6401000026008116156104df576104d8858585610c09565b93506104fe565b658000000000008116156104f8576104d8858585610c4d565b50610504565b506104ae565b50815b9392505050565b815160408051808201909152601081527f7573696e672d776f7264732d66726f6d0000000000000000000000000000000060208201525f919061055090614e89565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000008216146105815783915050610507565b5060108301925081831061061a5761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517fe3e4992d00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b60405180910390fd5b825160015f91821a1b90640100002600821690036106835761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176105dc565b836001019350505b818310156105045761069e8484846104ac565b925081831015610504575f806106b5868686610e7b565b9096509092509050816106c9575050610504565b6106d486868361102d565b505061068b565b60c08101516040516060919073ffffffffffffffffffffffffffffffffffffffff602082015f5b841561072357848316825260a09490941c5193602090910190600101610702565b8352604052610731826110ec565b509392505050565b60405162010000811061077b576040517f766c065f00000000000000000000000000000000000000000000000000000000815260048101829052602401610611565b50565b6060805f8361022001515111156108d0575f61079f84610220015160200190565b90505f6107b485610220015180510160200190565b90506107c18583836104ac565b91506107ce85838361050e565b91505b80821015610805576107e48583836104ac565b91506107f185838361113a565b91506107fe85838361153d565b91506107d1565b80821461083e576040517f7d565df600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610100850151600816156108cd5761022085015182037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517ff06f54cf00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b50505b5f806108e56108de86611afc565b8690611c31565b915091506108f1610739565b9094909350915050565b6040805160a0810182526004808252611c996020830152611fe592820192909252612025606082810191909152612082608083015291908190805b61093f8161226b565b94505050505090565b6060614bed5f604890508091505f6040518061092001604052808467ffffffffffffffff1667ffffffffffffffff1681526020016122fb81526020016122fb81526020016122fb81526020016123c781526020016124db81526020016124db81526020016123c781526020016123c781526020016124db81526020016122fb81526020016122fb81526020016122fb81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db81526020016124db8152509050606081905060488151146109365780516040517fc8b56901000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052604401610611565b610100830180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690525f610c45838364010000260061251d565b949350505050565b6101008301805160011790525f60048301821015610ce75761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517f25a7646800000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b825160f01c612f2a8114610d765761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f3e47169c00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b6003840193505f5b83851015610e1b5784515f1a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd18101610e0f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86015160f01c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d18101610e0d57505050600193840193610e1b565b505b85600101955050610d7e565b80610e715761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad7895000017610cb2565b5092949350505050565b81515f90819081908190600181831a1b6703ff200000000000811615610fa25786610ea7896001614efb565b1015610f9957600182811a1b7ffffffffffffffffffffffffffffffffffeffffffffffffffffff00000000000082821701610ee4575f9350610f93565b7ffffffffffffffffffffffffffffffffffffffffffeffffffffff00000000000082821701610f8e576102208a015189037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f75c28ff900000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b600193505b50610fe7565b60019250610fe7565b640400000000811615610fb85760029250610fe7565b6b080000000000000000000000811615610fd55760039250610fe7565b505f9450869350849250611024915050565b505f905061101588888861100d83876101a09190910151600291820201015161ffff1690565b63ffffffff16565b90975060019550879450925050505b93509350939050565b73ffffffffffffffffffffffffffffffffffffffff8111156110ca5761022083015182037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f9d7e517e00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b60c09092018051604080516020810190915290815260a01b9290921790915250565b60208101602082510282015b808210156111355781518151835281526020909101907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0016110f8565b505050565b5f5b818310156105045782515f90600190821a1b6f07fffffe8000000000000000000000008116156113b757610100860151600116156111f65761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517f5520a51700000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b6f07fffffe0000000000000000000000008116156112c95761122985856f07fffffe0000000003ff200000000000612546565b90955091505f6112398784612615565b50905080156112c35761022087015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f53e6feba00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b506112ea565b6112e760018601856f07fffffe0000000003ff20000000000061251d565b94505b856040015160ff1660ff148061130757508560a0015160ff1660ff145b1561138d5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f3820634100000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b604086018051600190810190915260a0870180519091019052610100860180516009179052611536565b640100002600811615611409576113d7600186018564010000260061251d565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690529450611536565b670400000000000000811615611455575050610100840180516008177ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe16905260019290920191610504565b658000000000008116156114e55761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517fedad0c5800000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b61022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176111c1565b505061113c565b5f5b818310156105045782515f90600190821a1b6f07fffffe00000000000000000000000081161561175d57610100860151600116156115f95761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517f4e803df600000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b8461161581866f07fffffe0000000003ff200000000000612546565b80945081975050505f8061162e89610240015186612690565b91509150811561166f57611643898989612764565b97505f6116508a836129ef565b905061165d8a8383612a15565b50610100890180516002179052611749565b6116798986612bfa565b9092509050811561169d5761168f895f83612a15565b61169889612c74565b611749565b5f6060848a03600581016116b28d8d8d612764565b9b508c6101e0015151602002602001810190505f60059050604051935060208201840160405282818501528184528394506116fa8860056116f38760200190565b0185612cda565b5050506101e08b015180516001019061172d906117278361171e8680510160200190565b90602002900390565b83612ce3565b5061173a8b60ff84612a15565b50506101008901805160021790525b505050610100860180516001179052611af5565b6101008601516002161561187f576501000000000081165f036117fb5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f23b5c6ea00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b606086810180515f1a6003019190829053603b821115611847576040517f6232f2d900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050610100860180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc169052600190940193611af5565b6502000000000081161561195b576060868101515f90811a91908290036119215761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f7f9db54200000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b808801600383039250828153826004820101515f1a8360028301015160f01c600101535061194e88612c74565b5050600190940193611af5565b6401000026008116156119ad5761197b600186018564010000260061251d565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1690529450611af5565b6b0800000003ff2004000000008116156119e8576119cc868686612cef565b94506119d786612c74565b610100860180516001179052611af5565b65100000000000811615611a0d57611a008686612e19565b5050600190920191610504565b670800000000000000811615611a4557611a278686612e19565b611a3086613271565b50506004610100850152600190920191610504565b65800000000000811615611aa45761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176114b0565b61022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176115c4565b505061153f565b60e08101518151516060919060f082901c9060208114611b48576040517f858f2dcf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051935060208401601083045f8183535060016008850483018101928391015f80805b88811015611ba55789811c61ffff81165163ffff0000601092831b16811760e01b8786015284019360f08390031b929092179101611b6c565b50825117909152878203017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08181018952908801601f01166040525f5b82811015611c25576002810288016003015161ffff90811683018051602060f082901c019260e09190911c1690611c1a838284612cda565b505050600101611be2565b50505050505050919050565b6060805f611c3e8461359f565b90505f5b81811015611c81575f611c5586836135b9565b60040190505f611c6587846135e8565b60040282019050611c778883836135ff565b5050600101611c42565b5083611c8c866138bf565b92509250505b9250929050565b5f80808080611ca9888888613934565b985090925090508181036040811115611d3d5761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517fff2f594900000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b805f03611dc55761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517fc75cd50900000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b60028106600103611e515761022089015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517fd76d9b5700000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b6001820397505f5b838910611fd45788515f90811a906001821b906703ff000000000000821615611ea557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd08201611f9e565b6c7e000000000000000000000000821615611ee357507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa98201611f9e565b687e0000000000000000821615611f1d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc98201611f9e565b6102208d01518c037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f69f1e3e600000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909b019a831b96909617955050600401611e59565b50509350909150505b935093915050565b5f805f805f80611ff58888613984565b9296509094509250905061200a898486613dc7565b826120158383613e4b565b9550955050505050935093915050565b5f808080612034878787613e9d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08301805184840382529199509294509092505f9161207281614057565b9190529698969750505050505050565b6001909101905f80836120a681856fffffffffdffffffffffffffeffffd9ff61251d565b9450848181036121315761022087015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517ff73a1aa800000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b61213c878787610c09565b95508561215a81876fffffffffdfffffffffffffffffffffff61251d565b9650868681106121e65761022089015188037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517fc4b1913500000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b875160015f91821a1b906b20000000000000000000000082169003612256576102208a015189037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176121b1565b50600190970196876120158a86868686614083565b60605f825160020267ffffffffffffffff81111561228b5761228b614c36565b6040519080825280601f01601f1916602001820160405280156122b5576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156122ef578051835186169085161781526020909201916002016122cd565b50939695505050505050565b5f8151600103612386575060208101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116601b0b60e082901d5f61233e838383614247565b905061ffff81111561237c576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250610239915050565b81515f0361239557505f919050565b6040517f1ac6690800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f815160020361249f57602082015160408301517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216601b0b60e083901d5f61240e838383614247565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8516601b0b935060e085901d925090505f612447848483614247565b905060ff821180612458575060ff81115b1561248f576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60081b1794506102399350505050565b600282511015612395576040517ff16066b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f81515f14612516576040517f9f16b02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505f919050565b5f5b5f82600186515f1a1b1611838510161561253e5760018401935061251f565b509192915050565b5f80806001818787036020811161255d5780612560565b60205b915050875192505b8519600184841a1b1615818310161561258657600182019150612568565b9681019660208290036008810293841c90931b9261260857604080516020810185905201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527fe47fe8b700000000000000000000000000000000000000000000000000000000825261061191600401614e77565b5095969095509350505050565b5f806126218484612bfa565b909250905081611c925750610120830180515f93845260209384902060408051928352948201855293909401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000909316601084901b62ff00001617909317909252909160ff90911660010190565b600182810180515f928392600560ff93909316602102870192830192909101835b818310156127555760018301516021909301805190935f90819060ff1681806126da838e6142a3565b915091508186165f036126fc575f809b509b5050505050505050505050611c92565b5f8761270c6001850389166142ce565b016004028b015195505062ffffff90811693508416830391506127409050575060019750601c1a9550611c92945050505050565b612749836142ce565b840193505050506126b1565b505f9788975095505050505050565b81516101e08401515f80825291600190831a1b907ffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000008201610e71576127a885614f3b565b610100870180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe169052805190955060015f91821a1b9250805b8587101561298d57865160015f9190911a1b93506401000026008416156128165761280f888888610c09565b96506127e3565b67400000000000000084161561283a5761282f87614f3b565b96506001905061298d565b6001886101000151165f0361290b57600482036128d25761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f8c9fdbb300000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b5f6128de8989896143a6565b60208581028701018190526101008b0180516001179052909850905061290383614f3b565b9250506127e3565b61022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517f722cd24a00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b806129e35761022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad7895000017612958565b50905250919392505050565b6101c08201516002828102820101516101e08401515f9261ffff90921691906104a39083565b612a1e836143ce565b610100830180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb1660081790526020808401515f90811a8501602101805190911a60ff811492919060018101825350508115612aa7576040517f8092d1ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050825180516060808601515f90811a87016061018051939461ffff8616949093921a60ff81149291600886048503601c0191600181018253505f60038201537fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe30180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690911790528115612b6a576040517f3abd0c5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050602090920183821b176018820185901b178083529160e0829003612bf25760408051601083901b6020908117601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016918252810190915281517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000168117825286525b505050505050565b6101208201516101408301515f8381526020808220919384939290911c91600160ff84161b80821615612c5f5761ffff83165b8015612c5d578360201c8503612c50576001965061ffff8460101c169550612c5d565b51925061ffff8316612c2d565b505b17610140909601959095525090939092509050565b6060818101515f90811a919082900361113557602083810180515f1a600101919082815350603e8210612cd3576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b8083835e505050565b6020810283835e505050565b5f8080612cfd868686610e7b565b9096509250905080612d8b5761022086015185037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000175b6040517fb0e4e5b300000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b5f80612d968461445a565b6101808901511615612dd75761016088015160101c5b8015801590612db9575082155b15612dd557602081015190519085149250600190910190612dac565b505b61016088015161ffff16612dfd600184612df15782612df5565b8383035b8b9190612a15565b5081612e0d57612e0d8885614471565b50949695505050505050565b6060828101515f1a908115612ea95761022084015183037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f6fb11cdc00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b5050612eb4826143ce565b61010082018051600416600890811790915260a0830151602084015160ff8083169360f89290921c9290911c1681035f819003612fde576004856101000151165f03612f7b5761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517fab1d3ea700000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b90820190603e8210612fb9576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60f882901b6020860152610200850151612fd390846144c3565b6102008601526130f9565b60018111156130f957808310156130705761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f78ef278200000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b808311156130f95761022085015184037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f43168e6800000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b8082036001016020601083028101905b8181101561325d5760a08801516020848a0181015191831c61ffff16915f1a9060015b82811161324b5760208406601c0361314557925160f01c925b83516102008d015160019190911a9061315e9082614547565b6102008e01525f82851480156131745750896001145b61317f576001613181565b8b5b6102008f0151909150613194908261458d565b6102008f0152600f8111806131a95750600f82115b1561322f576102208e01518d037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f7ea1869f00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b818160041b17600187015350506004939093019260010161312c565b50506001909401935050601001613109565b5050505060081b60a0909301929092525050565b60e081015160208083015160f083811c925f9290921a60010191908390036132c5576040517fa806284100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610200850151855180515f928392909160219060101c61ffff165b80156132f757805190925060101c61ffff166132e0565b506040518a82018051919650601c8401939160049160248901915f90811a805b8d8310156133dc5760048202860195506004878a03045b8082111561334c57965161ffff16601c81019950969003600761332e565b506004810298899003805186529894909401938103865b60078211156133a8575160101c61ffff1680518652601c909501947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff990910190613363565b81156133c3575160101c61ffff168051865260048202909501945b50505060019182018051909291909101905f1a80613317565b50505082895250600488810180517fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9290940491909101601881901b8817939093179052601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660405260ff1094505083156134a8576040517fe972437e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6134b56001808a1b614f72565b891685891b60f06134c78b6010614efb565b901b171760e08b01526101008a0180517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7169052604080516020601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01681815280820183525f80517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001682178152908d52908c01819052908b0181905260608b0181905260808b0181905260a08b018190526101208b018190526101408b018190526102008b015250505050505050505050565b5f81515f036135af57505f919050565b50602001515f1a90565b5f806135c48461359f565b60020260010190505f6135d78585614600565b949091019093016020019392505050565b5f806135f484846135b9565b515f1a949350505050565b808210156111355781517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160f882901c016138395760c08401515b80156138375760a081901c5161016086015161ffff60e085901c1660208101805160089390931b62ffff0016600187901a1760e81b7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909316929092179091526040517f570c7a630000000000000000000000000000000000000000000000000000000081529192915f908190819073ffffffffffffffffffffffffffffffffffffffff86169063570c7a63906136f2908790600401614e77565b5f60405180830381865afa15801561370c573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526137519190810190615011565b925092509250821561382d57815160041461379a57816040517fbe2d187d0000000000000000000000000000000000000000000000000000000081526004016106119190614e77565b60208201517fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff88161789525f5b81518110156138225761381a828281518110613803576138036150be565b60200260200101518c61447190919063ffffffff16565b6001016137e5565b505050505050613837565b505050505061363a565b505b5081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0160f882901c016138b357606061ffff8260e01c1690505f6003820152600581019050806040517faedfba2f0000000000000000000000000000000000000000000000000000000081526004016106119190614e77565b506004820191506135ff565b6101608101516040805161ffff8316808252602080820283019081019093529092909160109190911c90835b8082111561392b5760208301518252915161ffff16917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909101906138eb565b50505050919050565b5f808080613943866002614efb565b9050806c7e0000007e03ff0000000000005b86821081600184515f1a1b161515161561397457600182019150613955565b5090979096508695509350505050565b5f82818061399983866520000000000061251d565b925085831415836139b381886703ff00000000000061251d565b94508085036139ed57507f34bd20690000000000000000000000000000000000000000000000000000000094505f9250829150613dbe9050565b5f806139f98a88614656565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615613a37575095505f9350839250613dbe915050565b86519095506540000000000060015f9290921a9190911b161515888710169150508015613cc657506001909301925f84613a7a81896703ff00000000000061251d565b9550808603613ab557507f7bfa48af0000000000000000000000000000000000000000000000000000000095505f9350839250613dbe915050565b855b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018051908a1160015f9290921a9190911b660100000000000016151516600103613b24577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01613ab7565b818114613b7b575f80613b378484614656565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615613b77575097505f9550859450613dbe9350505050565b9350505b5f831215613bb657507f7bfa48af0000000000000000000000000000000000000000000000000000000096505f9450849350613dbe92505050565b8315613bc257825f0392505b80820394505f851315613c0257507f013b2aaa0000000000000000000000000000000000000000000000000000000096505f9450849350613dbe92505050565b855f03613c1157829550613cc3565b5f8590036043811115613c5257507f32b8b8be0000000000000000000000000000000000000000000000000000000097505f9550859450613dbe9350505050565b600a0a8681025f88838381613c6957613c69614f0e565b0514159050601b82900b8214158180613c7f5750805b15613cbb57507f32b8b8be000000000000000000000000000000000000000000000000000000009a505f9850889750613dbe9650505050505050565b505084019650505b50505b84516c2000000020000000000000000060015f9290921a9190911b161515878610168015613daf5760019095019485613d06818a6520000000000061251d565b965086613d1c818b6703ff00000000000061251d565b9750808803613d5957507f013b2aaa0000000000000000000000000000000000000000000000000000000097505f9550859450613dbe9350505050565b505f80613d66838a614656565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615613da6575097505f9550859450613dbe9350505050565b95860195925050505b845f03613dba575f93505b5050505b92959194509250565b7fffffffff00000000000000000000000000000000000000000000000000000000811615611135576102208301515f9083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000179050815f528060045260245ffd5b5f805f613e588585614780565b9150915080610731576040517f22c9f7bb0000000000000000000000000000000000000000000000000000000081526004810186905260248101859052604401610611565b5f80806001850181806f7ffffffffffffffffffffffb0000000081807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8b8b0301602080821015613eeb5750805b875193505b84600185851a1b1615158184101615613f0e57600183019250613ef0565b505080602003613f99576102208c01518b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f30515bda00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b85810180519095505f1a6001811b640400000000161580613fb95750858b145b1561403f576102208d015186037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000176040517f04022fbf00000000000000000000000000000000000000000000000000000000815260040161061191815260200190565b50949b939a505060018a019850919650505050505050565b5f80601f90505f60e09050818451168082175f528060208601600183016020035e50505f519392505050565b5f60608186860361ffff8111156140c9576040517fb6da789c00000000000000000000000000000000000000000000000000000000815260048101829052602401610611565b604080516041888803848101838101929092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169093526002828101859052018152935060228401925061411f898484612cda565b61412c8783850183612cda565b50505060c08701515b80156141f65760a081901c516040517fc6c0cbb60000000000000000000000000000000000000000000000000000000081529091905f90819073ffffffffffffffffffffffffffffffffffffffff84169063c6c0cbb69061419a908890600401614e77565b6040805180830381865afa1580156141b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141d891906150eb565b9150915081156141ee5794506104a39350505050565b505050614135565b61022088015187037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad7895000017612d56565b5f805f614255868686614886565b915091508061429a576040517f05e476780000000000000000000000000000000000000000000000000000000081526004810187905260248101869052604401610611565b50949350505050565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116611c92575060019250929050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036142ff5750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f805f6143b6888888610e7b565b92509250925082156141f6579093509150611fdd9050565b8051602080830180515f90811a8086016021015160a0939190831a6144205785518488018051600861ffff909316929092046020038801601e83901a840360010160100290811b909217905260f01092505b50508015612cd3576040517f5b1a42d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61446761010083615115565b6001901b92915050565b6101608201805160408051808201909152601091821c808252602082018590528351600161ffff909116019282901b929092179092526144b08361445a565b6101809094018051909417909352505050565b5f6144ce838361458d565b925060ff600884901c8116830190811115614515576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff841660089190911b17905092915050565b5f60ff831682811015614586576040517f23b49a2a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050900390565b5f60ff808416830190600885901c811690601086901c908311156145dd576040517fe826b5f600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808311156145e85750815b601081901b600883901b841717935050505092915050565b5f61460a8361359f565b82106146465781836040517ffcfaeff100000000000000000000000000000000000000000000000000000000815260040161061192919061514d565b50600202016003015161ffff1690565b81515f90819065200000000000600191831a9190911b1615158385101680850190828061468384886149d2565b90925090507fffffffff000000000000000000000000000000000000000000000000000000008216156146be575093505f9250611c92915050565b825f03614721577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81116146f2575f614714565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95509350611c9292505050565b7f8000000000000000000000000000000000000000000000000000000000000000811161474e575f614770565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95505f0393505050509250929050565b5f601b83900b83148383826147e4577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000008605156147c457620186a0860595506005850194505b8586601b0b146147df57600a860595508460010194506147c4565b6147fa565b855f036147fa57505f925060019150611c929050565b848560030b14614856575f85121561481a57505f9250829150611c929050565b6040517fd556b1110000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610611565b50507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660e084901b1791509250929050565b5f805f8512156148cc576040517f4a7d166b0000000000000000000000000000000000000000000000000000000081526004810186905260248101859052604401610611565b845f036148de57505f90506001611fdd565b8460ff8416850185811215614929576040517fd556b1110000000000000000000000000000000000000000000000000000000081526004810188905260248101879052604401610611565b5f805f831215614993577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb383121561496a575f809550955050505050611fdd565b825f03600a0a915081848161498157614981614f0e565b0495505084029091149150611fdd9050565b5f8313156149c2576149a683600a615283565b91506149b2828561528e565b955060019450611fdd9350505050565b8360019550955050505050611fdd565b5f80828410614a0557507f34bd20690000000000000000000000000000000000000000000000000000000090505f611c92565b835f03614a3e576040517fda6966d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60305f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501815b878210158015614a765750604d83105b15614ab957815160018401937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90930192600a0a5f9190911a8590030201614a66565b878210614bdf5781515f1a8490036001811115614b0157507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450611c929350505050565b600a84900a8102828101831115614b4457507f0fdc26350000000000000000000000000000000000000000000000000000000096505f9550611c92945050505050565b9190910190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b878210614bdf5781515f1a60308114614bb457507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450611c929350505050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190614b70565b5f9890975095505050505050565b614bf56152a5565b565b5f60208284031215614c07575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610507575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614caa57614caa614c36565b604052919050565b5f67ffffffffffffffff821115614ccb57614ccb614c36565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f60208284031215614d07575f80fd5b813567ffffffffffffffff811115614d1d575f80fd5b8201601f81018413614d2d575f80fd5b8035614d40614d3b82614cb2565b614c63565b818152856020838501011115614d54575f80fd5b816020840160208301375f91810160200191909152949350505050565b602080825282518282018290528051604084018190525f9291820190839060608601905b80831015614dcb57835173ffffffffffffffffffffffffffffffffffffffff168252928401926001929092019190840190614d95565b509695505050505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b604081525f614e346040830185614dd6565b8281036020848101919091528451808352858201928201905f5b81811015614e6a57845183529383019391830191600101614e4e565b5090979650505050505050565b602081525f6105076020830184614dd6565b80516020808301519190811015614ec8577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8082018082111561018057610180614ece565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614f6b57614f6b614ece565b5060010190565b8181038181111561018057610180614ece565b80518015158114610239575f80fd5b5f82601f830112614fa3575f80fd5b8151602067ffffffffffffffff821115614fbf57614fbf614c36565b8160051b614fce828201614c63565b9283528481018201928281019087851115614fe7575f80fd5b83870192505b8483101561500657825182529183019190830190614fed565b979650505050505050565b5f805f60608486031215615023575f80fd5b61502c84614f85565b9250602084015167ffffffffffffffff80821115615048575f80fd5b818601915086601f83011261505b575f80fd5b8151615069614d3b82614cb2565b81815288602083860101111561507d575f80fd5b8160208501602083015e5f60208383010152809550505060408601519150808211156150a7575f80fd5b506150b486828701614f94565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80604083850312156150fc575f80fd5b61510583614f85565b9150602083015190509250929050565b5f82615148577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b828152604060208201525f610c456040830184614dd6565b600181815b808511156151be57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156151a4576151a4614ece565b808516156151b157918102915b93841c939080029061516a565b509250929050565b5f826151d457506001610180565b816151e057505f610180565b81600181146151f657600281146152005761521c565b6001915050610180565b60ff84111561521157615211614ece565b50506001821b610180565b5060208310610133831016604e8410600b841016171561523f575081810a610180565b6152498383615165565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561527b5761527b614ece565b029392505050565b5f61050783836151c6565b808202811582820484141761018057610180614ece565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0288400100420b0280046b0641220186adb8a044003012020f2a880521281ac8811a000000000000000000080000000000100000000000000002000000000000000000290ea98a3a10f9c53927bda61c6395ad0e9fb4a8075dbeaf2d313e9e09b06d681dfe49062ce21ac13e83a6cc2ad2d2123422c3e0052f369e1f27267220a0a68d2f357696465d217b131120880f24f4a8242f1af53f41f7290afa3e8638acf3d13397e9fd00443a453b406bb547b9059d25a3cd1e11d0c3260b15eb4d16fc94274427bc412baf2cc2321b8f630dca9efe403ce35f1400684845c291e3425d68b13d5f9a151eb98c15239cd9c10c1f698235c8d3843c08d579273459d41a2c9ff617a5b2cd15c0031810f621af127ba34c26bb6c4137b2ad3d1b73563d0210215f36aa563921098e690457fb180376e752066a470128f11de101fcc60522de7ddd183d3d6d4196c37031cba2872e7b3af5304eee7219a8093543082b5f0801f5a522fb22fb22fb23c724db24db23c723c724db22fb22fb22fb24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db"; /// @dev The parse meta that is used to lookup word definitions. /// The structure of the parse meta is: @@ -51,11 +51,11 @@ uint8 constant PARSE_META_BUILD_DEPTH = 2; /// These positional indexes all map to the same indexes looked up in the parse /// meta. bytes constant OPERAND_HANDLER_FUNCTION_POINTERS = - hex"1fa91fa91fa92075218921892075207521891fa91fa91fa9218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189218921892189"; + hex"22fb22fb22fb23c724db24db23c723c724db22fb22fb22fb24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db24db"; /// @dev Every two bytes is a function pointer for a literal parser. /// Literal dispatches are determined by the first byte(s) of the literal /// rather than a full word lookup, and are done with simple conditional /// jumps as the possibilities are limited compared to the number of words we /// have. -bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"1a351cf91d391d96"; +bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"1c991fe520252082"; diff --git a/src/generated/RainlangReferenceExtern.pointers.sol b/src/generated/RainlangReferenceExtern.pointers.sol index 3922aee25..ee79cc84f 100644 --- a/src/generated/RainlangReferenceExtern.pointers.sol +++ b/src/generated/RainlangReferenceExtern.pointers.sol @@ -10,19 +10,19 @@ pragma solidity ^0.8.25; // file needs the contract to exist so that it can be compiled. /// @dev Hash of the known bytecode. -bytes32 constant BYTECODE_HASH = bytes32(0x2a2c5b9a0d2b61dc70078968ea4b565c91f0fcc33b33da02fb2607e4f7f6cdfc); +bytes32 constant BYTECODE_HASH = bytes32(0x948c7a8ef55255dd7a41250add9ec759c0e7177de7898969296b8887aab1b0bb); /// @dev The deterministic deploy address of the contract when deployed via /// the Zoltu factory. -address constant DEPLOYED_ADDRESS = address(0x609ac93ec99bd2A1d74996C915EBF8D6Ec36873C); +address constant DEPLOYED_ADDRESS = address(0xCEa9d8f639044C428C61c8AB4006B0e273FcFd03); /// @dev The creation bytecode of the contract. bytes constant CREATION_CODE = - hex"6080604052348015600e575f80fd5b505f602e604080518082019091526002815261090360f01b602082015290565b519050805f03605057604051630ae9809f60e31b815260040160405180910390fd5b5f606f6040805180820190915260028152610c9960f01b602082015290565b519050808214609f5760405163550eaa3b60e01b8152600481018390526024810182905260440160405180910390fd5b5050612e9a806100ae5f395ff3fe608060405234801561000f575f80fd5b50600436106100c4575f3560e01c806358c071521161007d578063c6c0cbb611610058578063c6c0cbb6146101ad578063ccf44775146101d7578063d6d8c9a8146101df575f80fd5b806358c07152146101575780636f5aa28d14610177578063b92d7553146101a5575f80fd5b806340c04edc116100ad57806340c04edc14610105578063514b5d4f1461012d578063570c7a6314610135575f80fd5b806301ffc9a7146100c8578063336284d4146100f0575b5f80fd5b6100db6100d636600461289c565b6101e7565b60405190151581526020015b60405180910390f35b6100f86101f7565b6040516100e7919061292e565b610118610113366004612940565b610259565b604080519283526020830191909152016100e7565b6100f8610328565b6101486101433660046129e5565b61034a565b6040516100e793929190612a92565b61016a610165366004612aef565b610500565b6040516100e79190612b9c565b6040517fadf71693c6ecf3fd560904bc46973d1b6e651440d15366673f9b3984749e7c1681526020016100e7565b6100f861058e565b6101c06101bb3660046129e5565b6105b0565b6040805192151583526020830191909152016100e7565b6100f86106c7565b6100f86106e9565b5f6101f18261072c565b92915050565b6040805160c0810182526005808252610819602083015261083992820192909252610847606082810191909152610855608083015261086460a08301529190819080610247565b60405180910390fd5b61025081610873565b94505050505090565b5f805f61029660408051808201909152600281527f0c99000000000000000000000000000000000000000000000000000000000000602082015290565b90505f60028251816102aa576102aa612bdf565b04905060208201601088901c61ffff168281106102fd576040517f417deaf3000000000000000000000000000000000000000000000000000000008152600481018290526024810184905260440161023e565b6002810282015161ffff8a169060f01c610316828b8b84565b909c909b509950505050505050505050565b6040805180820190915260018082526109036020830152606091819080610247565b5f6060805f805f6103968761035d6109af565b60408051808201909152600a81527f0f1a0f5c0f1a0f1a0f1a0000000000000000000000000000000000000000000060208201526109cf565b9250925092505f6103ac82610220015160200190565b90505f82610220015151826103c19190612c39565b90505f6103df83836f07fffffe0000000003ff200000000000610ac0565b80925081945050505f806103f886610240015184610b93565b9150915081156104d3575f61040d8783610c6a565b90506128925f61044d60408051808201909152600a81527f0819083908470855086400000000000000000000000000000000000000000000602082015290565b90505f6002825161045e9190612c4c565b90508085106104a3576040517f77ba3620000000000000000000000000000000000000000000000000000000008152600481018690526024810182905260440161023e565b6001850160020282015161ffff1692506104bc8c8c8686565b9e509e509e505050505050505050505050506104f9565b5050604080515f80825281830190925260208101828152919a5090985096505050505050505b9193909250565b60605f61053d60408051808201909152600281527f0903000000000000000000000000000000000000000000000000000000000000602082015290565b90505f600282518161055157610551612bdf565b04601086901c61ffff9081168281066002028501602090810151939450850192909188169060f01c610581828983565b9998505050505050505050565b604080518082019091526001808252610c996020830152606091819080610247565b5f805f805f6105d8866002810151815160228084019461ffff93909316840101920160200190565b9250925092505f805f6105eb8686610ca0565b92509250925082156106b7576128925f61063560408051808201909152600281527f0e71000000000000000000000000000000000000000000000000000000000000602082015290565b90505f600282516106469190612c4c565b905080851061068b576040517f77ba3620000000000000000000000000000000000000000000000000000000008152600481018690526024810182905260440161023e565b600185810160020283015161ffff1693506106a5858a8a87565b9a509a50505050505050505050915091565b505f988998509650505050505050565b604080518082019091526001808252610e716020830152606091819080610247565b6040805160c0810182526005808252610f1a60208301819052610f5c9383019390935260608281018490526080830184905260a083019390935290819080610247565b5f7f18003f8e000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614806107be57507fb92d7553000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061080a57507f514b5d4f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b806101f157506101f18261102d565b5f60608061082a308787875f6111a7565b92509250925093509350939050565b5f60608061082a868561125a565b5f60608061082a5f806112e5565b5f60608061082a5f60016112e5565b5f60608061082a60015f6112e5565b60605f825160020267ffffffffffffffff81111561089357610893612969565b6040519080825280601f01601f1916602001820160405280156108bd576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156108f7578051835186169085161781526020909201916002016108d5565b50939695505050505050565b60605f6109406f0785ee10d5da46d900f436a0000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb611380565b90505f5b83518110156109a6575f84828151811061096057610960612c84565b6020026020010151905061097d83826113da90919063ffffffff16565b90508085838151811061099257610992612c84565b602090810291909101015250600101610944565b50919392505050565b6060604051806060016040528060368152602001612e6460369139905090565b5f80610a5e6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b606061ffff600288015116935060ff600388015116925061ffff600588015116600588019750808852602081018801915050610aaa87878760405180602001604052805f81525061143d565b915080826101e001819052505093509350939050565b5f808060018187870360208111610ad75780610ada565b60205b915050875192505b8519600184841a1b16158183101615610b0057600182019150610ae2565b9681019660208290036008810293841c90931b92610b8257604080516020810185905201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527fe47fe8b700000000000000000000000000000000000000000000000000000000825261023e9160040161292e565b50869350909150505b935093915050565b600182810180515f928392600560ff93909316602102870192830192909101835b81831015610c585760018301516021909301805190935f90819060ff168180610bdd838e61162a565b915091508186165f03610bff575f809b509b5050505050505050505050610c63565b5f87610c0f600185038916611655565b016004028b015195505062ffffff9081169350841683039150610c439050575060019750601c1a9550610c63945050505050565b610c4c83611655565b84019350505050610bb4565b5f8095509550505050505b9250929050565b6101c08201516002828102820101516101e08401515f9261ffff9092169190610c909083565b95945050505050565b5091829150565b81515f908190819085850390601282118015610d1b57506040518060400160405280601281526020017f7265662d65787465726e2d7265706561742d0000000000000000000000000000815250610cf690612cb1565b7fffffffffffffffffffffffffffffffffffff00000000000000000000000000008216145b15610e595760408051602080820183525f808352835180830185528181528451808401865282815285519384019095528183529093610d5a939261143d565b90505f610d6b8260128b018a61172d565b9099509050878914610da9576040517fe502905600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80610dbe610db75f80611380565b829061176d565b80610dd95750610dd9610dd260095f611380565b82906117bc565b80610e0f5750610e0d610deb8261180b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b155b15610e46576040517fb6b34a6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600196505f95509350610e6a92505050565b505f9350839250829150610e6a9050565b9250925092565b5f6009841115610eb0576040517fae7c08430000000000000000000000000000000000000000000000000000000081526004810185905260240161023e565b5f838303604e8110610ef1576040517fd6073cd60000000000000000000000000000000000000000000000000000000081526004810182905260240161023e565b5f5b81811015610f0f57600a81900a87029290920191600101610ef3565b509095945050505050565b5f81515f14610f55576040517f9f16b02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505f919050565b5f8151600103610fe7575060208101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116601b0b60e082901d5f610f9f838383611857565b905061ffff811115610fdd576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250611028915050565b81515f03610ff657505f919050565b6040517f1ac6690800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f91ccb1d50000000000000000000000000000000000000000000000000000000014806110bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f6f5aa28d00000000000000000000000000000000000000000000000000000000145b8061110b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1a2c8edd00000000000000000000000000000000000000000000000000000000145b8061115757507fffffffff0000000000000000000000000000000000000000000000000000000082167f336284d400000000000000000000000000000000000000000000000000000000145b806101f157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146101f1565b5f60608061ffff8711156111ea576040517fcc3c82b10000000000000000000000000000000000000000000000000000000081526004810188905260240161023e565b6040805160248101909152600481018890526002876021830153806020830153506004815260408051808201909152600180825260109690961b9690961760a01b73ffffffffffffffffffffffffffffffffffffffff999099169890981760208601525091969294509192505050565b5f60608061ffff85111561129d576040517fec1899b50000000000000000000000000000000000000000000000000000000081526004810186905260240161023e565b60408051602481019091526004810186905260016010602183015380602083015350600481526040805180820190915260018082526020820196909652949690955092505050565b5f60608060ff8511806112f8575060ff84115b15611339576040517f9b0f3261000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b6040805160248101909152600386602383015385602283015360106021830153806020830153506004815260408051602081019091525f8152600197919650945092505050565b5f805f61138d85856118b3565b91509150806113d2576040517f22c9f7bb000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b509392505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d848061141f868686866119b9565b915091505f61142e83836118b3565b509a9950505050505050505050565b6114ca6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b8152602001848152602001858152602001600467ffffffffffffffff81111561155057611550612969565b604051908082528060200260200182016040528015611579578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016828152808301825283517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001681178452855290840182905283018190529082018190526080820181905260a08201819052610120820181905261014082018190526102008201529050610c90565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116610c63575060019250929050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036116865750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f805f8061173d8888611aef565b92965090945092509050611752898486611f32565b8261175d8383611380565b9550955050505050935093915050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d6117b084848484611f99565b13979650505050505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d6117ff84848484611f99565b12979650505050505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216601b0b60e083901d8261183e838361206d565b9150505f61184c82846118b3565b509695505050505050565b5f805f6118658686866120d5565b91509150806118aa576040517f05e47678000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260440161023e565b50949350505050565b5f601b83900b8314838382611917577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000008605156118f757620186a0860595506005850194505b8586601b0b1461191257600a860595508460010194506118f7565b61192d565b855f0361192d57505f925060019150610c639050565b848560030b14611989575f85121561194d57505f9250829150610c639050565b6040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161023e565b50507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660e084901b1791509250929050565b5f80851584151780156119e557865f036119d95784849250925050611ae6565b86869250925050611ae6565b6119ef8787612221565b90975095506119fe8585612221565b909550935085841315611a12579395929492935b838603604c811115611a2b578787935093505050611ae6565b80600a0a8681611a3d57611a3d612bdf565b0595505086850180881860ff90811c151589881890911c15168015611ad857877f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03611abf576040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018a90526024810189905260440161023e565b600a968790059690980586019760019790970196611adc565b8198505b5050868692509250505b94509492505050565b5f828180611b04838665200000000000612283565b92508583141583611b1e81886703ff000000000000612283565b9450808503611b5857507f34bd20690000000000000000000000000000000000000000000000000000000094505f9250829150611f299050565b5f80611b648a886122ac565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611ba2575095505f9350839250611f29915050565b86519095506540000000000060015f9290921a9190911b161515888710169150508015611e3157506001909301925f84611be581896703ff000000000000612283565b9550808603611c2057507f7bfa48af0000000000000000000000000000000000000000000000000000000095505f9350839250611f29915050565b855b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018051908a1160015f9290921a9190911b660100000000000016151516600103611c8f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611c22565b818114611ce6575f80611ca284846122ac565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611ce2575097505f9550859450611f299350505050565b9350505b5f831215611d2157507f7bfa48af0000000000000000000000000000000000000000000000000000000096505f9450849350611f2992505050565b8315611d2d57825f0392505b80820394505f851315611d6d57507f013b2aaa0000000000000000000000000000000000000000000000000000000096505f9450849350611f2992505050565b855f03611d7c57829550611e2e565b5f8590036043811115611dbd57507f32b8b8be0000000000000000000000000000000000000000000000000000000097505f9550859450611f299350505050565b600a0a8681025f88838381611dd457611dd4612bdf565b0514159050601b82900b8214158180611dea5750805b15611e2657507f32b8b8be000000000000000000000000000000000000000000000000000000009a505f9850889750611f299650505050505050565b505084019650505b50505b84516c2000000020000000000000000060015f9290921a9190911b161515878610168015611f1a5760019095019485611e71818a65200000000000612283565b965086611e87818b6703ff000000000000612283565b9750808803611ec457507f013b2aaa0000000000000000000000000000000000000000000000000000000097505f9550859450611f299350505050565b505f80611ed1838a6122ac565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611f11575097505f9550859450611f299350505050565b95860195925050505b845f03611f25575f93505b5050505b92959194509250565b7fffffffff00000000000000000000000000000000000000000000000000000000811615611f94576102208301515f9083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0019050815f528060045260245ffd5b505050565b5f8085158415178187128286121817858414178015611fbe5786859250925050611ae6565b505f85841315611fd2575092949193919260015b8386035f8112604c8213178015612005578215611ff7575f8994509450505050611ae6565b885f94509450505050611ae6565b600a82900a8981028a82828161201d5761201d612bdf565b0514612049578415612039575f8b965096505050505050611ae6565b8a5f965096505050505050611ae6565b841561205e578896509450611ae69350505050565b9550879450611ae69350505050565b5f805f831261208057508290505f610c63565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb48312156120b257505f905082610c63565b5f839003600a0a8085816120c8576120c8612bdf565b0794859003959350505050565b5f805f85121561211b576040517f4a7d166b000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b845f0361212d57505f90506001610b8b565b8460ff8416850185811215612178576040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260440161023e565b5f805f8312156121e2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb38312156121b9575f809550955050505050610b8b565b825f03600a0a91508184816121d0576121d0612bdf565b0495505084029091149150610b8b9050565b5f831315612211576121f583600a612e14565b91506122018285612e1f565b955060019450610b8b9350505050565b8360019550955050505050610b8b565b5f805f805f61223087876123d6565b92509250925080612277576040517f05e51ecb000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260440161023e565b50909590945092505050565b5f5b5f82600186515f1a1b161183851016156122a457600184019350612285565b509192915050565b81515f90819065200000000000600191831a9190911b161515838510168085019082806122d98488612677565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615612314575093505f9250610c63915050565b825f03612377577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8111612348575f61236a565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95509350610c6392505050565b7f800000000000000000000000000000000000000000000000000000000000000081116123a4575f6123c6565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95505f0393505050509250929050565b5f805f845f036123ee57505f91508190506001610e6a565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085055f03612602576f4b3b4ca85a86c47a098a224000000000850515801561245757507f80000000000000000000000000000000000000000000000000000000000000268412155b15612478576f4b3b4ca85a86c47a098a224000000000850294506026840393505b7728c87cb5c89a2571ebfdcb54864ada834a0000000000000085051580156124c057507f80000000000000000000000000000000000000000000000000000000000000138412155b156124d957678ac7230489e80000850294506013840393505b7b097edd871cfda3a5697758bf0e3cbb5ac5741c640000000000000000850515801561252557507f800000000000000000000000000000000000000000000000000000000000000a8412155b1561253b576402540be40085029450600a840393505b7e3899162693736ac531a5a58f1fbb4b746504382ca7e4000000000000000000850515801561258a57507f80000000000000000000000000000000000000000000000000000000000000028412155b156125a05760648502945060028403935061253b565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085051580156125f057507f80000000000000000000000000000000000000000000000000000000000000018412155b1561260257600a850294506001840393505b600a8086029081058614801561263857507f80000000000000000000000000000000000000000000000000000000000000018512155b15612647578095506001850394505b50939492935050507f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee80000000000000000008305151590565b5f808284106126aa57507f34bd20690000000000000000000000000000000000000000000000000000000090505f610c63565b835f036126e3576040517fda6966d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60305f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501815b87821015801561271b5750604d83105b1561275e57815160018401937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90930192600a0a5f9190911a859003020161270b565b8782106128845781515f1a84900360018111156127a657507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450610c639350505050565b600a84900a81028281018311156127e957507f0fdc26350000000000000000000000000000000000000000000000000000000096505f9550610c63945050505050565b9190910190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b8782106128845781515f1a6030811461285957507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450610c639350505050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190612815565b5f9890975095505050505050565b61289a612e36565b565b5f602082840312156128ac575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146128db575f80fd5b9392505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f6128db60208301846128e2565b5f805f60608486031215612952575f80fd5b505081359360208301359350604090920135919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156129dd576129dd612969565b604052919050565b5f60208083850312156129f6575f80fd5b823567ffffffffffffffff80821115612a0d575f80fd5b818501915085601f830112612a20575f80fd5b813581811115612a3257612a32612969565b612a62847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612996565b91508082528684828501011115612a77575f80fd5b80848401858401375f90820190930192909252509392505050565b83151581525f602060606020840152612aae60608401866128e2565b8381036040850152845180825260208087019201905f5b81811015612ae157835183529284019291840191600101612ac5565b509098975050505050505050565b5f8060408385031215612b00575f80fd5b8235915060208084013567ffffffffffffffff80821115612b1f575f80fd5b818601915086601f830112612b32575f80fd5b813581811115612b4457612b44612969565b8060051b9150612b55848301612996565b8181529183018401918481019089841115612b6e575f80fd5b938501935b83851015612b8c57843582529385019390850190612b73565b8096505050505050509250929050565b602080825282518282018190525f9190848201906040850190845b81811015612bd357835183529284019291840191600101612bb7565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b808201808211156101f1576101f1612c0c565b5f82612c7f577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b80516020808301519190811015612cf0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b600181815b80851115612d4f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612d3557612d35612c0c565b80851615612d4257918102915b93841c9390800290612cfb565b509250929050565b5f82612d65575060016101f1565b81612d7157505f6101f1565b8160018114612d875760028114612d9157612dad565b60019150506101f1565b60ff841115612da257612da2612c0c565b50506001821b6101f1565b5060208310610133831016604e8410600b8410161715612dd0575081810a6101f1565b612dda8383612cf6565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612e0c57612e0c612c0c565b029392505050565b5f6128db8383612d57565b80820281158282048414176101f1576101f1612c0c565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0100000000008000000000000000000000110000000000000020000000000000008000e438fc04aafc63025be81c0384254101285ca1"; + hex"6080604052348015600e575f80fd5b505f602e604080518082019091526002815261090360f01b602082015290565b519050805f03605057604051630ae9809f60e31b815260040160405180910390fd5b5f606f6040805180820190915260028152610c9960f01b602082015290565b519050808214609f5760405163550eaa3b60e01b8152600481018390526024810182905260440160405180910390fd5b5050612ebc806100ae5f395ff3fe608060405234801561000f575f80fd5b50600436106100c4575f3560e01c806358c071521161007d578063c6c0cbb611610058578063c6c0cbb6146101ad578063ccf44775146101d7578063d6d8c9a8146101df575f80fd5b806358c07152146101575780636f5aa28d14610177578063b92d7553146101a5575f80fd5b806340c04edc116100ad57806340c04edc14610105578063514b5d4f1461012d578063570c7a6314610135575f80fd5b806301ffc9a7146100c8578063336284d4146100f0575b5f80fd5b6100db6100d63660046128be565b6101e7565b60405190151581526020015b60405180910390f35b6100f86101f7565b6040516100e79190612950565b610118610113366004612962565b610259565b604080519283526020830191909152016100e7565b6100f8610328565b610148610143366004612a07565b61034a565b6040516100e793929190612ab4565b61016a610165366004612b11565b610500565b6040516100e79190612bbe565b6040517fadf71693c6ecf3fd560904bc46973d1b6e651440d15366673f9b3984749e7c1681526020016100e7565b6100f861058e565b6101c06101bb366004612a07565b6105b0565b6040805192151583526020830191909152016100e7565b6100f86106c7565b6100f86106e9565b5f6101f18261072c565b92915050565b6040805160c0810182526005808252610819602083015261083992820192909252610847606082810191909152610855608083015261086460a08301529190819080610247565b60405180910390fd5b61025081610873565b94505050505090565b5f805f61029660408051808201909152600281527f0c99000000000000000000000000000000000000000000000000000000000000602082015290565b90505f60028251816102aa576102aa612c01565b04905060208201601088901c61ffff168281106102fd576040517f417deaf3000000000000000000000000000000000000000000000000000000008152600481018290526024810184905260440161023e565b6002810282015161ffff8a169060f01c610316828b8b84565b909c909b509950505050505050505050565b6040805180820190915260018082526109036020830152606091819080610247565b5f6060805f805f6103968761035d6109af565b60408051808201909152600a81527f0f1a0f5c0f1a0f1a0f1a0000000000000000000000000000000000000000000060208201526109cf565b9250925092505f6103ac82610220015160200190565b90505f82610220015151826103c19190612c5b565b90505f6103df83836f07fffffe0000000003ff200000000000610ac0565b80925081945050505f806103f886610240015184610b93565b9150915081156104d3575f61040d8783610c6a565b90506128b45f61044d60408051808201909152600a81527f0819083908470855086400000000000000000000000000000000000000000000602082015290565b90505f6002825161045e9190612c6e565b90508085106104a3576040517f77ba3620000000000000000000000000000000000000000000000000000000008152600481018690526024810182905260440161023e565b6001850160020282015161ffff1692506104bc8c8c8686565b9e509e509e505050505050505050505050506104f9565b5050604080515f80825281830190925260208101828152919a5090985096505050505050505b9193909250565b60605f61053d60408051808201909152600281527f0903000000000000000000000000000000000000000000000000000000000000602082015290565b90505f600282518161055157610551612c01565b04601086901c61ffff9081168281066002028501602090810151939450850192909188169060f01c610581828983565b9998505050505050505050565b604080518082019091526001808252610c996020830152606091819080610247565b5f805f805f6105d8866002810151815160228084019461ffff93909316840101920160200190565b9250925092505f805f6105eb8686610ca0565b92509250925082156106b7576128b45f61063560408051808201909152600281527f0e71000000000000000000000000000000000000000000000000000000000000602082015290565b90505f600282516106469190612c6e565b905080851061068b576040517f77ba3620000000000000000000000000000000000000000000000000000000008152600481018690526024810182905260440161023e565b600185810160020283015161ffff1693506106a5858a8a87565b9a509a50505050505050505050915091565b505f988998509650505050505050565b604080518082019091526001808252610e716020830152606091819080610247565b6040805160c0810182526005808252610f1a60208301819052610f5c9383019390935260608281018490526080830184905260a083019390935290819080610247565b5f7f18003f8e000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614806107be57507fb92d7553000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061080a57507f514b5d4f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b806101f157506101f18261102d565b5f60608061082a308787875f6111a7565b92509250925093509350939050565b5f60608061082a868561125a565b5f60608061082a5f806112e5565b5f60608061082a5f60016112e5565b5f60608061082a60015f6112e5565b60605f825160020267ffffffffffffffff8111156108935761089361298b565b6040519080825280601f01601f1916602001820160405280156108bd576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156108f7578051835186169085161781526020909201916002016108d5565b50939695505050505050565b60605f6109406f0785ee10d5da46d900f436a0000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb611380565b90505f5b83518110156109a6575f84828151811061096057610960612ca6565b6020026020010151905061097d83826113da90919063ffffffff16565b90508085838151811061099257610992612ca6565b602090810291909101015250600101610944565b50919392505050565b6060604051806060016040528060368152602001612e8660369139905090565b5f80610a5e6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b606061ffff600288015116935060ff600388015116925061ffff600588015116600588019750808852602081018801915050610aaa87878760405180602001604052805f81525061143d565b915080826101e001819052505093509350939050565b5f808060018187870360208111610ad75780610ada565b60205b915050875192505b8519600184841a1b16158183101615610b0057600182019150610ae2565b9681019660208290036008810293841c90931b92610b8257604080516020810185905201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527fe47fe8b700000000000000000000000000000000000000000000000000000000825261023e91600401612950565b50869350909150505b935093915050565b600182810180515f928392600560ff93909316602102870192830192909101835b81831015610c585760018301516021909301805190935f90819060ff168180610bdd838e61162a565b915091508186165f03610bff575f809b509b5050505050505050505050610c63565b5f87610c0f600185038916611655565b016004028b015195505062ffffff9081169350841683039150610c439050575060019750601c1a9550610c63945050505050565b610c4c83611655565b84019350505050610bb4565b5f8095509550505050505b9250929050565b6101c08201516002828102820101516101e08401515f9261ffff9092169190610c909083565b95945050505050565b5091829150565b81515f908190819085850390601282118015610d1b57506040518060400160405280601281526020017f7265662d65787465726e2d7265706561742d0000000000000000000000000000815250610cf690612cd3565b7fffffffffffffffffffffffffffffffffffff00000000000000000000000000008216145b15610e595760408051602080820183525f808352835180830185528181528451808401865282815285519384019095528183529093610d5a939261143d565b90505f610d6b8260128b018a61172d565b9099509050878914610da9576040517fe502905600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80610dbe610db75f80611380565b829061176d565b80610dd95750610dd9610dd260095f611380565b82906117bc565b80610e0f5750610e0d610deb8261180b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b155b15610e46576040517fb6b34a6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600196505f95509350610e6a92505050565b505f9350839250829150610e6a9050565b9250925092565b5f6009841115610eb0576040517fae7c08430000000000000000000000000000000000000000000000000000000081526004810185905260240161023e565b5f838303604e8110610ef1576040517fd6073cd60000000000000000000000000000000000000000000000000000000081526004810182905260240161023e565b5f5b81811015610f0f57600a81900a87029290920191600101610ef3565b509095945050505050565b5f81515f14610f55576040517f9f16b02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505f919050565b5f8151600103610fe7575060208101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116601b0b60e082901d5f610f9f838383611857565b905061ffff811115610fdd576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250611028915050565b81515f03610ff657505f919050565b6040517f1ac6690800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f91ccb1d50000000000000000000000000000000000000000000000000000000014806110bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f6f5aa28d00000000000000000000000000000000000000000000000000000000145b8061110b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1a2c8edd00000000000000000000000000000000000000000000000000000000145b8061115757507fffffffff0000000000000000000000000000000000000000000000000000000082167f336284d400000000000000000000000000000000000000000000000000000000145b806101f157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146101f1565b5f60608061ffff8711156111ea576040517fcc3c82b10000000000000000000000000000000000000000000000000000000081526004810188905260240161023e565b6040805160248101909152600481018890526002876021830153806020830153506004815260408051808201909152600180825260109690961b9690961760a01b73ffffffffffffffffffffffffffffffffffffffff999099169890981760208601525091969294509192505050565b5f60608061ffff85111561129d576040517fec1899b50000000000000000000000000000000000000000000000000000000081526004810186905260240161023e565b60408051602481019091526004810186905260016010602183015380602083015350600481526040805180820190915260018082526020820196909652949690955092505050565b5f60608060ff8511806112f8575060ff84115b15611339576040517f9b0f3261000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b6040805160248101909152600386602383015385602283015360106021830153806020830153506004815260408051602081019091525f8152600197919650945092505050565b5f805f61138d85856118b3565b91509150806113d2576040517f22c9f7bb000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b509392505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d848061141f868686866119b9565b915091505f61142e83836118b3565b509a9950505050505050505050565b6114ca6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b8152602001848152602001858152602001600467ffffffffffffffff8111156115505761155061298b565b604051908082528060200260200182016040528015611579578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016828152808301825283517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001681178452855290840182905283018190529082018190526080820181905260a08201819052610120820181905261014082018190526102008201529050610c90565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116610c63575060019250929050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036116865750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f805f8061173d8888611aef565b92965090945092509050611752898486611f32565b8261175d8383611380565b9550955050505050935093915050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d6117b084848484611fbb565b13979650505050505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d6117ff84848484611fbb565b12979650505050505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216601b0b60e083901d8261183e838361208f565b9150505f61184c82846118b3565b509695505050505050565b5f805f6118658686866120f7565b91509150806118aa576040517f05e47678000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260440161023e565b50949350505050565b5f601b83900b8314838382611917577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000008605156118f757620186a0860595506005850194505b8586601b0b1461191257600a860595508460010194506118f7565b61192d565b855f0361192d57505f925060019150610c639050565b848560030b14611989575f85121561194d57505f9250829150610c639050565b6040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161023e565b50507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660e084901b1791509250929050565b5f80851584151780156119e557865f036119d95784849250925050611ae6565b86869250925050611ae6565b6119ef8787612243565b90975095506119fe8585612243565b909550935085841315611a12579395929492935b838603604c811115611a2b578787935093505050611ae6565b80600a0a8681611a3d57611a3d612c01565b0595505086850180881860ff90811c151589881890911c15168015611ad857877f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03611abf576040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018a90526024810189905260440161023e565b600a968790059690980586019760019790970196611adc565b8198505b5050868692509250505b94509492505050565b5f828180611b048386652000000000006122a5565b92508583141583611b1e81886703ff0000000000006122a5565b9450808503611b5857507f34bd20690000000000000000000000000000000000000000000000000000000094505f9250829150611f299050565b5f80611b648a886122ce565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611ba2575095505f9350839250611f29915050565b86519095506540000000000060015f9290921a9190911b161515888710169150508015611e3157506001909301925f84611be581896703ff0000000000006122a5565b9550808603611c2057507f7bfa48af0000000000000000000000000000000000000000000000000000000095505f9350839250611f29915050565b855b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018051908a1160015f9290921a9190911b660100000000000016151516600103611c8f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611c22565b818114611ce6575f80611ca284846122ce565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611ce2575097505f9550859450611f299350505050565b9350505b5f831215611d2157507f7bfa48af0000000000000000000000000000000000000000000000000000000096505f9450849350611f2992505050565b8315611d2d57825f0392505b80820394505f851315611d6d57507f013b2aaa0000000000000000000000000000000000000000000000000000000096505f9450849350611f2992505050565b855f03611d7c57829550611e2e565b5f8590036043811115611dbd57507f32b8b8be0000000000000000000000000000000000000000000000000000000097505f9550859450611f299350505050565b600a0a8681025f88838381611dd457611dd4612c01565b0514159050601b82900b8214158180611dea5750805b15611e2657507f32b8b8be000000000000000000000000000000000000000000000000000000009a505f9850889750611f299650505050505050565b505084019650505b50505b84516c2000000020000000000000000060015f9290921a9190911b161515878610168015611f1a5760019095019485611e71818a652000000000006122a5565b965086611e87818b6703ff0000000000006122a5565b9750808803611ec457507f013b2aaa0000000000000000000000000000000000000000000000000000000097505f9550859450611f299350505050565b505f80611ed1838a6122ce565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611f11575097505f9550859450611f299350505050565b95860195925050505b845f03611f25575f93505b5050505b92959194509250565b7fffffffff00000000000000000000000000000000000000000000000000000000811615611fb6576102208301515f9083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000179050815f528060045260245ffd5b505050565b5f8085158415178187128286121817858414178015611fe05786859250925050611ae6565b505f85841315611ff4575092949193919260015b8386035f8112604c8213178015612027578215612019575f8994509450505050611ae6565b885f94509450505050611ae6565b600a82900a8981028a82828161203f5761203f612c01565b051461206b57841561205b575f8b965096505050505050611ae6565b8a5f965096505050505050611ae6565b8415612080578896509450611ae69350505050565b9550879450611ae69350505050565b5f805f83126120a257508290505f610c63565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb48312156120d457505f905082610c63565b5f839003600a0a8085816120ea576120ea612c01565b0794859003959350505050565b5f805f85121561213d576040517f4a7d166b000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b845f0361214f57505f90506001610b8b565b8460ff841685018581121561219a576040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260440161023e565b5f805f831215612204577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb38312156121db575f809550955050505050610b8b565b825f03600a0a91508184816121f2576121f2612c01565b0495505084029091149150610b8b9050565b5f8313156122335761221783600a612e36565b91506122238285612e41565b955060019450610b8b9350505050565b8360019550955050505050610b8b565b5f805f805f61225287876123f8565b92509250925080612299576040517f05e51ecb000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260440161023e565b50909590945092505050565b5f5b5f82600186515f1a1b161183851016156122c6576001840193506122a7565b509192915050565b81515f90819065200000000000600191831a9190911b161515838510168085019082806122fb8488612699565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615612336575093505f9250610c63915050565b825f03612399577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811161236a575f61238c565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95509350610c6392505050565b7f800000000000000000000000000000000000000000000000000000000000000081116123c6575f6123e8565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95505f0393505050509250929050565b5f805f845f0361241057505f91508190506001610e6a565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085055f03612624576f4b3b4ca85a86c47a098a224000000000850515801561247957507f80000000000000000000000000000000000000000000000000000000000000268412155b1561249a576f4b3b4ca85a86c47a098a224000000000850294506026840393505b7728c87cb5c89a2571ebfdcb54864ada834a0000000000000085051580156124e257507f80000000000000000000000000000000000000000000000000000000000000138412155b156124fb57678ac7230489e80000850294506013840393505b7b097edd871cfda3a5697758bf0e3cbb5ac5741c640000000000000000850515801561254757507f800000000000000000000000000000000000000000000000000000000000000a8412155b1561255d576402540be40085029450600a840393505b7e3899162693736ac531a5a58f1fbb4b746504382ca7e400000000000000000085051580156125ac57507f80000000000000000000000000000000000000000000000000000000000000028412155b156125c25760648502945060028403935061255d565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee8000000000000000000850515801561261257507f80000000000000000000000000000000000000000000000000000000000000018412155b1561262457600a850294506001840393505b600a8086029081058614801561265a57507f80000000000000000000000000000000000000000000000000000000000000018512155b15612669578095506001850394505b50939492935050507f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee80000000000000000008305151590565b5f808284106126cc57507f34bd20690000000000000000000000000000000000000000000000000000000090505f610c63565b835f03612705576040517fda6966d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60305f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501815b87821015801561273d5750604d83105b1561278057815160018401937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90930192600a0a5f9190911a859003020161272d565b8782106128a65781515f1a84900360018111156127c857507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450610c639350505050565b600a84900a810282810183111561280b57507f0fdc26350000000000000000000000000000000000000000000000000000000096505f9550610c63945050505050565b9190910190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b8782106128a65781515f1a6030811461287b57507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450610c639350505050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190612837565b5f9890975095505050505050565b6128bc612e58565b565b5f602082840312156128ce575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146128fd575f80fd5b9392505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f6128fd6020830184612904565b5f805f60608486031215612974575f80fd5b505081359360208301359350604090920135919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156129ff576129ff61298b565b604052919050565b5f6020808385031215612a18575f80fd5b823567ffffffffffffffff80821115612a2f575f80fd5b818501915085601f830112612a42575f80fd5b813581811115612a5457612a5461298b565b612a84847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016129b8565b91508082528684828501011115612a99575f80fd5b80848401858401375f90820190930192909252509392505050565b83151581525f602060606020840152612ad06060840186612904565b8381036040850152845180825260208087019201905f5b81811015612b0357835183529284019291840191600101612ae7565b509098975050505050505050565b5f8060408385031215612b22575f80fd5b8235915060208084013567ffffffffffffffff80821115612b41575f80fd5b818601915086601f830112612b54575f80fd5b813581811115612b6657612b6661298b565b8060051b9150612b778483016129b8565b8181529183018401918481019089841115612b90575f80fd5b938501935b83851015612bae57843582529385019390850190612b95565b8096505050505050509250929050565b602080825282518282018190525f9190848201906040850190845b81811015612bf557835183529284019291840191600101612bd9565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b808201808211156101f1576101f1612c2e565b5f82612ca1577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b80516020808301519190811015612d12577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b600181815b80851115612d7157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612d5757612d57612c2e565b80851615612d6457918102915b93841c9390800290612d1d565b509250929050565b5f82612d87575060016101f1565b81612d9357505f6101f1565b8160018114612da95760028114612db357612dcf565b60019150506101f1565b60ff841115612dc457612dc4612c2e565b50506001821b6101f1565b5060208310610133831016604e8410600b8410161715612df2575081810a6101f1565b612dfc8383612d18565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612e2e57612e2e612c2e565b029392505050565b5f6128fd8383612d79565b80820281158282048414176101f1576101f1612c2e565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0100000000008000000000000000000000110000000000000020000000000000008000e438fc04aafc63025be81c0384254101285ca1"; /// @dev The runtime bytecode of the contract. bytes constant RUNTIME_CODE = - hex"608060405234801561000f575f80fd5b50600436106100c4575f3560e01c806358c071521161007d578063c6c0cbb611610058578063c6c0cbb6146101ad578063ccf44775146101d7578063d6d8c9a8146101df575f80fd5b806358c07152146101575780636f5aa28d14610177578063b92d7553146101a5575f80fd5b806340c04edc116100ad57806340c04edc14610105578063514b5d4f1461012d578063570c7a6314610135575f80fd5b806301ffc9a7146100c8578063336284d4146100f0575b5f80fd5b6100db6100d636600461289c565b6101e7565b60405190151581526020015b60405180910390f35b6100f86101f7565b6040516100e7919061292e565b610118610113366004612940565b610259565b604080519283526020830191909152016100e7565b6100f8610328565b6101486101433660046129e5565b61034a565b6040516100e793929190612a92565b61016a610165366004612aef565b610500565b6040516100e79190612b9c565b6040517fadf71693c6ecf3fd560904bc46973d1b6e651440d15366673f9b3984749e7c1681526020016100e7565b6100f861058e565b6101c06101bb3660046129e5565b6105b0565b6040805192151583526020830191909152016100e7565b6100f86106c7565b6100f86106e9565b5f6101f18261072c565b92915050565b6040805160c0810182526005808252610819602083015261083992820192909252610847606082810191909152610855608083015261086460a08301529190819080610247565b60405180910390fd5b61025081610873565b94505050505090565b5f805f61029660408051808201909152600281527f0c99000000000000000000000000000000000000000000000000000000000000602082015290565b90505f60028251816102aa576102aa612bdf565b04905060208201601088901c61ffff168281106102fd576040517f417deaf3000000000000000000000000000000000000000000000000000000008152600481018290526024810184905260440161023e565b6002810282015161ffff8a169060f01c610316828b8b84565b909c909b509950505050505050505050565b6040805180820190915260018082526109036020830152606091819080610247565b5f6060805f805f6103968761035d6109af565b60408051808201909152600a81527f0f1a0f5c0f1a0f1a0f1a0000000000000000000000000000000000000000000060208201526109cf565b9250925092505f6103ac82610220015160200190565b90505f82610220015151826103c19190612c39565b90505f6103df83836f07fffffe0000000003ff200000000000610ac0565b80925081945050505f806103f886610240015184610b93565b9150915081156104d3575f61040d8783610c6a565b90506128925f61044d60408051808201909152600a81527f0819083908470855086400000000000000000000000000000000000000000000602082015290565b90505f6002825161045e9190612c4c565b90508085106104a3576040517f77ba3620000000000000000000000000000000000000000000000000000000008152600481018690526024810182905260440161023e565b6001850160020282015161ffff1692506104bc8c8c8686565b9e509e509e505050505050505050505050506104f9565b5050604080515f80825281830190925260208101828152919a5090985096505050505050505b9193909250565b60605f61053d60408051808201909152600281527f0903000000000000000000000000000000000000000000000000000000000000602082015290565b90505f600282518161055157610551612bdf565b04601086901c61ffff9081168281066002028501602090810151939450850192909188169060f01c610581828983565b9998505050505050505050565b604080518082019091526001808252610c996020830152606091819080610247565b5f805f805f6105d8866002810151815160228084019461ffff93909316840101920160200190565b9250925092505f805f6105eb8686610ca0565b92509250925082156106b7576128925f61063560408051808201909152600281527f0e71000000000000000000000000000000000000000000000000000000000000602082015290565b90505f600282516106469190612c4c565b905080851061068b576040517f77ba3620000000000000000000000000000000000000000000000000000000008152600481018690526024810182905260440161023e565b600185810160020283015161ffff1693506106a5858a8a87565b9a509a50505050505050505050915091565b505f988998509650505050505050565b604080518082019091526001808252610e716020830152606091819080610247565b6040805160c0810182526005808252610f1a60208301819052610f5c9383019390935260608281018490526080830184905260a083019390935290819080610247565b5f7f18003f8e000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614806107be57507fb92d7553000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061080a57507f514b5d4f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b806101f157506101f18261102d565b5f60608061082a308787875f6111a7565b92509250925093509350939050565b5f60608061082a868561125a565b5f60608061082a5f806112e5565b5f60608061082a5f60016112e5565b5f60608061082a60015f6112e5565b60605f825160020267ffffffffffffffff81111561089357610893612969565b6040519080825280601f01601f1916602001820160405280156108bd576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156108f7578051835186169085161781526020909201916002016108d5565b50939695505050505050565b60605f6109406f0785ee10d5da46d900f436a0000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb611380565b90505f5b83518110156109a6575f84828151811061096057610960612c84565b6020026020010151905061097d83826113da90919063ffffffff16565b90508085838151811061099257610992612c84565b602090810291909101015250600101610944565b50919392505050565b6060604051806060016040528060368152602001612e6460369139905090565b5f80610a5e6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b606061ffff600288015116935060ff600388015116925061ffff600588015116600588019750808852602081018801915050610aaa87878760405180602001604052805f81525061143d565b915080826101e001819052505093509350939050565b5f808060018187870360208111610ad75780610ada565b60205b915050875192505b8519600184841a1b16158183101615610b0057600182019150610ae2565b9681019660208290036008810293841c90931b92610b8257604080516020810185905201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527fe47fe8b700000000000000000000000000000000000000000000000000000000825261023e9160040161292e565b50869350909150505b935093915050565b600182810180515f928392600560ff93909316602102870192830192909101835b81831015610c585760018301516021909301805190935f90819060ff168180610bdd838e61162a565b915091508186165f03610bff575f809b509b5050505050505050505050610c63565b5f87610c0f600185038916611655565b016004028b015195505062ffffff9081169350841683039150610c439050575060019750601c1a9550610c63945050505050565b610c4c83611655565b84019350505050610bb4565b5f8095509550505050505b9250929050565b6101c08201516002828102820101516101e08401515f9261ffff9092169190610c909083565b95945050505050565b5091829150565b81515f908190819085850390601282118015610d1b57506040518060400160405280601281526020017f7265662d65787465726e2d7265706561742d0000000000000000000000000000815250610cf690612cb1565b7fffffffffffffffffffffffffffffffffffff00000000000000000000000000008216145b15610e595760408051602080820183525f808352835180830185528181528451808401865282815285519384019095528183529093610d5a939261143d565b90505f610d6b8260128b018a61172d565b9099509050878914610da9576040517fe502905600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80610dbe610db75f80611380565b829061176d565b80610dd95750610dd9610dd260095f611380565b82906117bc565b80610e0f5750610e0d610deb8261180b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b155b15610e46576040517fb6b34a6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600196505f95509350610e6a92505050565b505f9350839250829150610e6a9050565b9250925092565b5f6009841115610eb0576040517fae7c08430000000000000000000000000000000000000000000000000000000081526004810185905260240161023e565b5f838303604e8110610ef1576040517fd6073cd60000000000000000000000000000000000000000000000000000000081526004810182905260240161023e565b5f5b81811015610f0f57600a81900a87029290920191600101610ef3565b509095945050505050565b5f81515f14610f55576040517f9f16b02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505f919050565b5f8151600103610fe7575060208101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116601b0b60e082901d5f610f9f838383611857565b905061ffff811115610fdd576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250611028915050565b81515f03610ff657505f919050565b6040517f1ac6690800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f91ccb1d50000000000000000000000000000000000000000000000000000000014806110bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f6f5aa28d00000000000000000000000000000000000000000000000000000000145b8061110b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1a2c8edd00000000000000000000000000000000000000000000000000000000145b8061115757507fffffffff0000000000000000000000000000000000000000000000000000000082167f336284d400000000000000000000000000000000000000000000000000000000145b806101f157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146101f1565b5f60608061ffff8711156111ea576040517fcc3c82b10000000000000000000000000000000000000000000000000000000081526004810188905260240161023e565b6040805160248101909152600481018890526002876021830153806020830153506004815260408051808201909152600180825260109690961b9690961760a01b73ffffffffffffffffffffffffffffffffffffffff999099169890981760208601525091969294509192505050565b5f60608061ffff85111561129d576040517fec1899b50000000000000000000000000000000000000000000000000000000081526004810186905260240161023e565b60408051602481019091526004810186905260016010602183015380602083015350600481526040805180820190915260018082526020820196909652949690955092505050565b5f60608060ff8511806112f8575060ff84115b15611339576040517f9b0f3261000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b6040805160248101909152600386602383015385602283015360106021830153806020830153506004815260408051602081019091525f8152600197919650945092505050565b5f805f61138d85856118b3565b91509150806113d2576040517f22c9f7bb000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b509392505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d848061141f868686866119b9565b915091505f61142e83836118b3565b509a9950505050505050505050565b6114ca6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b8152602001848152602001858152602001600467ffffffffffffffff81111561155057611550612969565b604051908082528060200260200182016040528015611579578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016828152808301825283517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001681178452855290840182905283018190529082018190526080820181905260a08201819052610120820181905261014082018190526102008201529050610c90565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116610c63575060019250929050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036116865750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f805f8061173d8888611aef565b92965090945092509050611752898486611f32565b8261175d8383611380565b9550955050505050935093915050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d6117b084848484611f99565b13979650505050505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d6117ff84848484611f99565b12979650505050505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216601b0b60e083901d8261183e838361206d565b9150505f61184c82846118b3565b509695505050505050565b5f805f6118658686866120d5565b91509150806118aa576040517f05e47678000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260440161023e565b50949350505050565b5f601b83900b8314838382611917577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000008605156118f757620186a0860595506005850194505b8586601b0b1461191257600a860595508460010194506118f7565b61192d565b855f0361192d57505f925060019150610c639050565b848560030b14611989575f85121561194d57505f9250829150610c639050565b6040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161023e565b50507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660e084901b1791509250929050565b5f80851584151780156119e557865f036119d95784849250925050611ae6565b86869250925050611ae6565b6119ef8787612221565b90975095506119fe8585612221565b909550935085841315611a12579395929492935b838603604c811115611a2b578787935093505050611ae6565b80600a0a8681611a3d57611a3d612bdf565b0595505086850180881860ff90811c151589881890911c15168015611ad857877f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03611abf576040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018a90526024810189905260440161023e565b600a968790059690980586019760019790970196611adc565b8198505b5050868692509250505b94509492505050565b5f828180611b04838665200000000000612283565b92508583141583611b1e81886703ff000000000000612283565b9450808503611b5857507f34bd20690000000000000000000000000000000000000000000000000000000094505f9250829150611f299050565b5f80611b648a886122ac565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611ba2575095505f9350839250611f29915050565b86519095506540000000000060015f9290921a9190911b161515888710169150508015611e3157506001909301925f84611be581896703ff000000000000612283565b9550808603611c2057507f7bfa48af0000000000000000000000000000000000000000000000000000000095505f9350839250611f29915050565b855b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018051908a1160015f9290921a9190911b660100000000000016151516600103611c8f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611c22565b818114611ce6575f80611ca284846122ac565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611ce2575097505f9550859450611f299350505050565b9350505b5f831215611d2157507f7bfa48af0000000000000000000000000000000000000000000000000000000096505f9450849350611f2992505050565b8315611d2d57825f0392505b80820394505f851315611d6d57507f013b2aaa0000000000000000000000000000000000000000000000000000000096505f9450849350611f2992505050565b855f03611d7c57829550611e2e565b5f8590036043811115611dbd57507f32b8b8be0000000000000000000000000000000000000000000000000000000097505f9550859450611f299350505050565b600a0a8681025f88838381611dd457611dd4612bdf565b0514159050601b82900b8214158180611dea5750805b15611e2657507f32b8b8be000000000000000000000000000000000000000000000000000000009a505f9850889750611f299650505050505050565b505084019650505b50505b84516c2000000020000000000000000060015f9290921a9190911b161515878610168015611f1a5760019095019485611e71818a65200000000000612283565b965086611e87818b6703ff000000000000612283565b9750808803611ec457507f013b2aaa0000000000000000000000000000000000000000000000000000000097505f9550859450611f299350505050565b505f80611ed1838a6122ac565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611f11575097505f9550859450611f299350505050565b95860195925050505b845f03611f25575f93505b5050505b92959194509250565b7fffffffff00000000000000000000000000000000000000000000000000000000811615611f94576102208301515f9083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0019050815f528060045260245ffd5b505050565b5f8085158415178187128286121817858414178015611fbe5786859250925050611ae6565b505f85841315611fd2575092949193919260015b8386035f8112604c8213178015612005578215611ff7575f8994509450505050611ae6565b885f94509450505050611ae6565b600a82900a8981028a82828161201d5761201d612bdf565b0514612049578415612039575f8b965096505050505050611ae6565b8a5f965096505050505050611ae6565b841561205e578896509450611ae69350505050565b9550879450611ae69350505050565b5f805f831261208057508290505f610c63565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb48312156120b257505f905082610c63565b5f839003600a0a8085816120c8576120c8612bdf565b0794859003959350505050565b5f805f85121561211b576040517f4a7d166b000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b845f0361212d57505f90506001610b8b565b8460ff8416850185811215612178576040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260440161023e565b5f805f8312156121e2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb38312156121b9575f809550955050505050610b8b565b825f03600a0a91508184816121d0576121d0612bdf565b0495505084029091149150610b8b9050565b5f831315612211576121f583600a612e14565b91506122018285612e1f565b955060019450610b8b9350505050565b8360019550955050505050610b8b565b5f805f805f61223087876123d6565b92509250925080612277576040517f05e51ecb000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260440161023e565b50909590945092505050565b5f5b5f82600186515f1a1b161183851016156122a457600184019350612285565b509192915050565b81515f90819065200000000000600191831a9190911b161515838510168085019082806122d98488612677565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615612314575093505f9250610c63915050565b825f03612377577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8111612348575f61236a565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95509350610c6392505050565b7f800000000000000000000000000000000000000000000000000000000000000081116123a4575f6123c6565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95505f0393505050509250929050565b5f805f845f036123ee57505f91508190506001610e6a565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085055f03612602576f4b3b4ca85a86c47a098a224000000000850515801561245757507f80000000000000000000000000000000000000000000000000000000000000268412155b15612478576f4b3b4ca85a86c47a098a224000000000850294506026840393505b7728c87cb5c89a2571ebfdcb54864ada834a0000000000000085051580156124c057507f80000000000000000000000000000000000000000000000000000000000000138412155b156124d957678ac7230489e80000850294506013840393505b7b097edd871cfda3a5697758bf0e3cbb5ac5741c640000000000000000850515801561252557507f800000000000000000000000000000000000000000000000000000000000000a8412155b1561253b576402540be40085029450600a840393505b7e3899162693736ac531a5a58f1fbb4b746504382ca7e4000000000000000000850515801561258a57507f80000000000000000000000000000000000000000000000000000000000000028412155b156125a05760648502945060028403935061253b565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085051580156125f057507f80000000000000000000000000000000000000000000000000000000000000018412155b1561260257600a850294506001840393505b600a8086029081058614801561263857507f80000000000000000000000000000000000000000000000000000000000000018512155b15612647578095506001850394505b50939492935050507f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee80000000000000000008305151590565b5f808284106126aa57507f34bd20690000000000000000000000000000000000000000000000000000000090505f610c63565b835f036126e3576040517fda6966d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60305f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501815b87821015801561271b5750604d83105b1561275e57815160018401937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90930192600a0a5f9190911a859003020161270b565b8782106128845781515f1a84900360018111156127a657507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450610c639350505050565b600a84900a81028281018311156127e957507f0fdc26350000000000000000000000000000000000000000000000000000000096505f9550610c63945050505050565b9190910190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b8782106128845781515f1a6030811461285957507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450610c639350505050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190612815565b5f9890975095505050505050565b61289a612e36565b565b5f602082840312156128ac575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146128db575f80fd5b9392505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f6128db60208301846128e2565b5f805f60608486031215612952575f80fd5b505081359360208301359350604090920135919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156129dd576129dd612969565b604052919050565b5f60208083850312156129f6575f80fd5b823567ffffffffffffffff80821115612a0d575f80fd5b818501915085601f830112612a20575f80fd5b813581811115612a3257612a32612969565b612a62847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612996565b91508082528684828501011115612a77575f80fd5b80848401858401375f90820190930192909252509392505050565b83151581525f602060606020840152612aae60608401866128e2565b8381036040850152845180825260208087019201905f5b81811015612ae157835183529284019291840191600101612ac5565b509098975050505050505050565b5f8060408385031215612b00575f80fd5b8235915060208084013567ffffffffffffffff80821115612b1f575f80fd5b818601915086601f830112612b32575f80fd5b813581811115612b4457612b44612969565b8060051b9150612b55848301612996565b8181529183018401918481019089841115612b6e575f80fd5b938501935b83851015612b8c57843582529385019390850190612b73565b8096505050505050509250929050565b602080825282518282018190525f9190848201906040850190845b81811015612bd357835183529284019291840191600101612bb7565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b808201808211156101f1576101f1612c0c565b5f82612c7f577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b80516020808301519190811015612cf0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b600181815b80851115612d4f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612d3557612d35612c0c565b80851615612d4257918102915b93841c9390800290612cfb565b509250929050565b5f82612d65575060016101f1565b81612d7157505f6101f1565b8160018114612d875760028114612d9157612dad565b60019150506101f1565b60ff841115612da257612da2612c0c565b50506001821b6101f1565b5060208310610133831016604e8410600b8410161715612dd0575081810a6101f1565b612dda8383612cf6565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612e0c57612e0c612c0c565b029392505050565b5f6128db8383612d57565b80820281158282048414176101f1576101f1612c0c565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0100000000008000000000000000000000110000000000000020000000000000008000e438fc04aafc63025be81c0384254101285ca1"; + hex"608060405234801561000f575f80fd5b50600436106100c4575f3560e01c806358c071521161007d578063c6c0cbb611610058578063c6c0cbb6146101ad578063ccf44775146101d7578063d6d8c9a8146101df575f80fd5b806358c07152146101575780636f5aa28d14610177578063b92d7553146101a5575f80fd5b806340c04edc116100ad57806340c04edc14610105578063514b5d4f1461012d578063570c7a6314610135575f80fd5b806301ffc9a7146100c8578063336284d4146100f0575b5f80fd5b6100db6100d63660046128be565b6101e7565b60405190151581526020015b60405180910390f35b6100f86101f7565b6040516100e79190612950565b610118610113366004612962565b610259565b604080519283526020830191909152016100e7565b6100f8610328565b610148610143366004612a07565b61034a565b6040516100e793929190612ab4565b61016a610165366004612b11565b610500565b6040516100e79190612bbe565b6040517fadf71693c6ecf3fd560904bc46973d1b6e651440d15366673f9b3984749e7c1681526020016100e7565b6100f861058e565b6101c06101bb366004612a07565b6105b0565b6040805192151583526020830191909152016100e7565b6100f86106c7565b6100f86106e9565b5f6101f18261072c565b92915050565b6040805160c0810182526005808252610819602083015261083992820192909252610847606082810191909152610855608083015261086460a08301529190819080610247565b60405180910390fd5b61025081610873565b94505050505090565b5f805f61029660408051808201909152600281527f0c99000000000000000000000000000000000000000000000000000000000000602082015290565b90505f60028251816102aa576102aa612c01565b04905060208201601088901c61ffff168281106102fd576040517f417deaf3000000000000000000000000000000000000000000000000000000008152600481018290526024810184905260440161023e565b6002810282015161ffff8a169060f01c610316828b8b84565b909c909b509950505050505050505050565b6040805180820190915260018082526109036020830152606091819080610247565b5f6060805f805f6103968761035d6109af565b60408051808201909152600a81527f0f1a0f5c0f1a0f1a0f1a0000000000000000000000000000000000000000000060208201526109cf565b9250925092505f6103ac82610220015160200190565b90505f82610220015151826103c19190612c5b565b90505f6103df83836f07fffffe0000000003ff200000000000610ac0565b80925081945050505f806103f886610240015184610b93565b9150915081156104d3575f61040d8783610c6a565b90506128b45f61044d60408051808201909152600a81527f0819083908470855086400000000000000000000000000000000000000000000602082015290565b90505f6002825161045e9190612c6e565b90508085106104a3576040517f77ba3620000000000000000000000000000000000000000000000000000000008152600481018690526024810182905260440161023e565b6001850160020282015161ffff1692506104bc8c8c8686565b9e509e509e505050505050505050505050506104f9565b5050604080515f80825281830190925260208101828152919a5090985096505050505050505b9193909250565b60605f61053d60408051808201909152600281527f0903000000000000000000000000000000000000000000000000000000000000602082015290565b90505f600282518161055157610551612c01565b04601086901c61ffff9081168281066002028501602090810151939450850192909188169060f01c610581828983565b9998505050505050505050565b604080518082019091526001808252610c996020830152606091819080610247565b5f805f805f6105d8866002810151815160228084019461ffff93909316840101920160200190565b9250925092505f805f6105eb8686610ca0565b92509250925082156106b7576128b45f61063560408051808201909152600281527f0e71000000000000000000000000000000000000000000000000000000000000602082015290565b90505f600282516106469190612c6e565b905080851061068b576040517f77ba3620000000000000000000000000000000000000000000000000000000008152600481018690526024810182905260440161023e565b600185810160020283015161ffff1693506106a5858a8a87565b9a509a50505050505050505050915091565b505f988998509650505050505050565b604080518082019091526001808252610e716020830152606091819080610247565b6040805160c0810182526005808252610f1a60208301819052610f5c9383019390935260608281018490526080830184905260a083019390935290819080610247565b5f7f18003f8e000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614806107be57507fb92d7553000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b8061080a57507f514b5d4f000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b806101f157506101f18261102d565b5f60608061082a308787875f6111a7565b92509250925093509350939050565b5f60608061082a868561125a565b5f60608061082a5f806112e5565b5f60608061082a5f60016112e5565b5f60608061082a60015f6112e5565b60605f825160020267ffffffffffffffff8111156108935761089361298b565b6040519080825280601f01601f1916602001820160405280156108bd576020820181803683370190505b50905061ffff80196020850160208651028101600285015b818310156108f7578051835186169085161781526020909201916002016108d5565b50939695505050505050565b60605f6109406f0785ee10d5da46d900f436a0000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdb611380565b90505f5b83518110156109a6575f84828151811061096057610960612ca6565b6020026020010151905061097d83826113da90919063ffffffff16565b90508085838151811061099257610992612ca6565b602090810291909101015250600101610944565b50919392505050565b6060604051806060016040528060368152602001612e8660369139905090565b5f80610a5e6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b606061ffff600288015116935060ff600388015116925061ffff600588015116600588019750808852602081018801915050610aaa87878760405180602001604052805f81525061143d565b915080826101e001819052505093509350939050565b5f808060018187870360208111610ad75780610ada565b60205b915050875192505b8519600184841a1b16158183101615610b0057600182019150610ae2565b9681019660208290036008810293841c90931b92610b8257604080516020810185905201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527fe47fe8b700000000000000000000000000000000000000000000000000000000825261023e91600401612950565b50869350909150505b935093915050565b600182810180515f928392600560ff93909316602102870192830192909101835b81831015610c585760018301516021909301805190935f90819060ff168180610bdd838e61162a565b915091508186165f03610bff575f809b509b5050505050505050505050610c63565b5f87610c0f600185038916611655565b016004028b015195505062ffffff9081169350841683039150610c439050575060019750601c1a9550610c63945050505050565b610c4c83611655565b84019350505050610bb4565b5f8095509550505050505b9250929050565b6101c08201516002828102820101516101e08401515f9261ffff9092169190610c909083565b95945050505050565b5091829150565b81515f908190819085850390601282118015610d1b57506040518060400160405280601281526020017f7265662d65787465726e2d7265706561742d0000000000000000000000000000815250610cf690612cd3565b7fffffffffffffffffffffffffffffffffffff00000000000000000000000000008216145b15610e595760408051602080820183525f808352835180830185528181528451808401865282815285519384019095528183529093610d5a939261143d565b90505f610d6b8260128b018a61172d565b9099509050878914610da9576040517fe502905600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80610dbe610db75f80611380565b829061176d565b80610dd95750610dd9610dd260095f611380565b82906117bc565b80610e0f5750610e0d610deb8261180b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b155b15610e46576040517fb6b34a6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600196505f95509350610e6a92505050565b505f9350839250829150610e6a9050565b9250925092565b5f6009841115610eb0576040517fae7c08430000000000000000000000000000000000000000000000000000000081526004810185905260240161023e565b5f838303604e8110610ef1576040517fd6073cd60000000000000000000000000000000000000000000000000000000081526004810182905260240161023e565b5f5b81811015610f0f57600a81900a87029290920191600101610ef3565b509095945050505050565b5f81515f14610f55576040517f9f16b02000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505f919050565b5f8151600103610fe7575060208101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116601b0b60e082901d5f610f9f838383611857565b905061ffff811115610fdd576040517f7938075c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9250611028915050565b81515f03610ff657505f919050565b6040517f1ac6690800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f91ccb1d50000000000000000000000000000000000000000000000000000000014806110bf57507fffffffff0000000000000000000000000000000000000000000000000000000082167f6f5aa28d00000000000000000000000000000000000000000000000000000000145b8061110b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f1a2c8edd00000000000000000000000000000000000000000000000000000000145b8061115757507fffffffff0000000000000000000000000000000000000000000000000000000082167f336284d400000000000000000000000000000000000000000000000000000000145b806101f157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146101f1565b5f60608061ffff8711156111ea576040517fcc3c82b10000000000000000000000000000000000000000000000000000000081526004810188905260240161023e565b6040805160248101909152600481018890526002876021830153806020830153506004815260408051808201909152600180825260109690961b9690961760a01b73ffffffffffffffffffffffffffffffffffffffff999099169890981760208601525091969294509192505050565b5f60608061ffff85111561129d576040517fec1899b50000000000000000000000000000000000000000000000000000000081526004810186905260240161023e565b60408051602481019091526004810186905260016010602183015380602083015350600481526040805180820190915260018082526020820196909652949690955092505050565b5f60608060ff8511806112f8575060ff84115b15611339576040517f9b0f3261000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b6040805160248101909152600386602383015385602283015360106021830153806020830153506004815260408051602081019091525f8152600197919650945092505050565b5f805f61138d85856118b3565b91509150806113d2576040517f22c9f7bb000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b509392505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d848061141f868686866119b9565b915091505f61142e83836118b3565b509a9950505050505050505050565b6114ca6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f80191681526020016060815260200160608152602001606081526020015f815260200160608152602001606081525090565b5f6040518061026001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f801b81526020015f8152602001600481526020015f81526020015f81526020015f81526020015f801b8152602001848152602001858152602001600467ffffffffffffffff8111156115505761155061298b565b604051908082528060200260200182016040528015611579578160200160208202803683370190505b5081525f602080830182905260408084018b905260609384018a90528051601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016828152808301825283517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001681178452855290840182905283018190529082018190526080820181905260a08201819052610120820181905261014082018190526102008201529050610c90565b5f80825f528360205360215f2090506001815f1a1b915062ffffff8116610c63575060019250929050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036116865750610100919050565b507f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c16909103600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c90565b5f805f805f8061173d8888611aef565b92965090945092509050611752898486611f32565b8261175d8383611380565b9550955050505050935093915050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d6117b084848484611fbb565b13979650505050505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838116601b90810b9160e086811d9291861690910b9085901d6117ff84848484611fbb565b12979650505050505050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8216601b0b60e083901d8261183e838361208f565b9150505f61184c82846118b3565b509695505050505050565b5f805f6118658686866120f7565b91509150806118aa576040517f05e47678000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260440161023e565b50949350505050565b5f601b83900b8314838382611917577d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000008605156118f757620186a0860595506005850194505b8586601b0b1461191257600a860595508460010194506118f7565b61192d565b855f0361192d57505f925060019150610c639050565b848560030b14611989575f85121561194d57505f9250829150610c639050565b6040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161023e565b50507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660e084901b1791509250929050565b5f80851584151780156119e557865f036119d95784849250925050611ae6565b86869250925050611ae6565b6119ef8787612243565b90975095506119fe8585612243565b909550935085841315611a12579395929492935b838603604c811115611a2b578787935093505050611ae6565b80600a0a8681611a3d57611a3d612c01565b0595505086850180881860ff90811c151589881890911c15168015611ad857877f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03611abf576040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018a90526024810189905260440161023e565b600a968790059690980586019760019790970196611adc565b8198505b5050868692509250505b94509492505050565b5f828180611b048386652000000000006122a5565b92508583141583611b1e81886703ff0000000000006122a5565b9450808503611b5857507f34bd20690000000000000000000000000000000000000000000000000000000094505f9250829150611f299050565b5f80611b648a886122ce565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611ba2575095505f9350839250611f29915050565b86519095506540000000000060015f9290921a9190911b161515888710169150508015611e3157506001909301925f84611be581896703ff0000000000006122a5565b9550808603611c2057507f7bfa48af0000000000000000000000000000000000000000000000000000000095505f9350839250611f29915050565b855b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018051908a1160015f9290921a9190911b660100000000000016151516600103611c8f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611c22565b818114611ce6575f80611ca284846122ce565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611ce2575097505f9550859450611f299350505050565b9350505b5f831215611d2157507f7bfa48af0000000000000000000000000000000000000000000000000000000096505f9450849350611f2992505050565b8315611d2d57825f0392505b80820394505f851315611d6d57507f013b2aaa0000000000000000000000000000000000000000000000000000000096505f9450849350611f2992505050565b855f03611d7c57829550611e2e565b5f8590036043811115611dbd57507f32b8b8be0000000000000000000000000000000000000000000000000000000097505f9550859450611f299350505050565b600a0a8681025f88838381611dd457611dd4612c01565b0514159050601b82900b8214158180611dea5750805b15611e2657507f32b8b8be000000000000000000000000000000000000000000000000000000009a505f9850889750611f299650505050505050565b505084019650505b50505b84516c2000000020000000000000000060015f9290921a9190911b161515878610168015611f1a5760019095019485611e71818a652000000000006122a5565b965086611e87818b6703ff0000000000006122a5565b9750808803611ec457507f013b2aaa0000000000000000000000000000000000000000000000000000000097505f9550859450611f299350505050565b505f80611ed1838a6122ce565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615611f11575097505f9550859450611f299350505050565b95860195925050505b845f03611f25575f93505b5050505b92959194509250565b7fffffffff00000000000000000000000000000000000000000000000000000000811615611fb6576102208301515f9083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0017f53c102422473590ce12511beab7637e1c33b596a7d58a80ea98463ad78950000179050815f528060045260245ffd5b505050565b5f8085158415178187128286121817858414178015611fe05786859250925050611ae6565b505f85841315611ff4575092949193919260015b8386035f8112604c8213178015612027578215612019575f8994509450505050611ae6565b885f94509450505050611ae6565b600a82900a8981028a82828161203f5761203f612c01565b051461206b57841561205b575f8b965096505050505050611ae6565b8a5f965096505050505050611ae6565b8415612080578896509450611ae69350505050565b9550879450611ae69350505050565b5f805f83126120a257508290505f610c63565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb48312156120d457505f905082610c63565b5f839003600a0a8085816120ea576120ea612c01565b0794859003959350505050565b5f805f85121561213d576040517f4a7d166b000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161023e565b845f0361214f57505f90506001610b8b565b8460ff841685018581121561219a576040517fd556b111000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260440161023e565b5f805f831215612204577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb38312156121db575f809550955050505050610b8b565b825f03600a0a91508184816121f2576121f2612c01565b0495505084029091149150610b8b9050565b5f8313156122335761221783600a612e36565b91506122238285612e41565b955060019450610b8b9350505050565b8360019550955050505050610b8b565b5f805f805f61225287876123f8565b92509250925080612299576040517f05e51ecb000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260440161023e565b50909590945092505050565b5f5b5f82600186515f1a1b161183851016156122c6576001840193506122a7565b509192915050565b81515f90819065200000000000600191831a9190911b161515838510168085019082806122fb8488612699565b90925090507fffffffff00000000000000000000000000000000000000000000000000000000821615612336575093505f9250610c63915050565b825f03612399577f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811161236a575f61238c565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95509350610c6392505050565b7f800000000000000000000000000000000000000000000000000000000000000081116123c6575f6123e8565b7f0fdc2635000000000000000000000000000000000000000000000000000000005b95505f0393505050509250929050565b5f805f845f0361241057505f91508190506001610e6a565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee800000000000000000085055f03612624576f4b3b4ca85a86c47a098a224000000000850515801561247957507f80000000000000000000000000000000000000000000000000000000000000268412155b1561249a576f4b3b4ca85a86c47a098a224000000000850294506026840393505b7728c87cb5c89a2571ebfdcb54864ada834a0000000000000085051580156124e257507f80000000000000000000000000000000000000000000000000000000000000138412155b156124fb57678ac7230489e80000850294506013840393505b7b097edd871cfda3a5697758bf0e3cbb5ac5741c640000000000000000850515801561254757507f800000000000000000000000000000000000000000000000000000000000000a8412155b1561255d576402540be40085029450600a840393505b7e3899162693736ac531a5a58f1fbb4b746504382ca7e400000000000000000085051580156125ac57507f80000000000000000000000000000000000000000000000000000000000000028412155b156125c25760648502945060028403935061255d565b7f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee8000000000000000000850515801561261257507f80000000000000000000000000000000000000000000000000000000000000018412155b1561262457600a850294506001840393505b600a8086029081058614801561265a57507f80000000000000000000000000000000000000000000000000000000000000018512155b15612669578095506001850394505b50939492935050507f0235fadd81c2822bb3f07877973d50f28bf22a31be8ee80000000000000000008305151590565b5f808284106126cc57507f34bd20690000000000000000000000000000000000000000000000000000000090505f610c63565b835f03612705576040517fda6966d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60305f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8501815b87821015801561273d5750604d83105b1561278057815160018401937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90930192600a0a5f9190911a859003020161272d565b8782106128a65781515f1a84900360018111156127c857507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450610c639350505050565b600a84900a810282810183111561280b57507f0fdc26350000000000000000000000000000000000000000000000000000000096505f9550610c63945050505050565b9190910190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909101905b8782106128a65781515f1a6030811461287b57507f0fdc26350000000000000000000000000000000000000000000000000000000095505f9450610c639350505050565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90910190612837565b5f9890975095505050505050565b6128bc612e58565b565b5f602082840312156128ce575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146128fd575f80fd5b9392505050565b5f81518084528060208401602086015e5f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f6128fd6020830184612904565b5f805f60608486031215612974575f80fd5b505081359360208301359350604090920135919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156129ff576129ff61298b565b604052919050565b5f6020808385031215612a18575f80fd5b823567ffffffffffffffff80821115612a2f575f80fd5b818501915085601f830112612a42575f80fd5b813581811115612a5457612a5461298b565b612a84847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016129b8565b91508082528684828501011115612a99575f80fd5b80848401858401375f90820190930192909252509392505050565b83151581525f602060606020840152612ad06060840186612904565b8381036040850152845180825260208087019201905f5b81811015612b0357835183529284019291840191600101612ae7565b509098975050505050505050565b5f8060408385031215612b22575f80fd5b8235915060208084013567ffffffffffffffff80821115612b41575f80fd5b818601915086601f830112612b54575f80fd5b813581811115612b6657612b6661298b565b8060051b9150612b778483016129b8565b8181529183018401918481019089841115612b90575f80fd5b938501935b83851015612bae57843582529385019390850190612b95565b8096505050505050509250929050565b602080825282518282018190525f9190848201906040850190845b81811015612bf557835183529284019291840191600101612bd9565b50909695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b808201808211156101f1576101f1612c2e565b5f82612ca1577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b80516020808301519190811015612d12577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b600181815b80851115612d7157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612d5757612d57612c2e565b80851615612d6457918102915b93841c9390800290612d1d565b509250929050565b5f82612d87575060016101f1565b81612d9357505f6101f1565b8160018114612da95760028114612db357612dcf565b60019150506101f1565b60ff841115612dc457612dc4612c2e565b50506001821b6101f1565b5060208310610133831016604e8410600b8410161715612df2575081810a6101f1565b612dfc8383612d18565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612e2e57612e2e612c2e565b029392505050565b5f6128fd8383612d79565b80820281158282048414176101f1576101f1612c2e565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52605160045260245ffdfe0100000000008000000000000000000000110000000000000020000000000000008000e438fc04aafc63025be81c0384254101285ca1"; /// @dev The hash of the meta that describes the contract. bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0xadf71693c6ecf3fd560904bc46973d1b6e651440d15366673f9b3984749e7c16); diff --git a/src/lib/parse/LibParseError.sol b/src/lib/parse/LibParseError.sol index 65f009c48..5778259cf 100644 --- a/src/lib/parse/LibParseError.sol +++ b/src/lib/parse/LibParseError.sol @@ -4,19 +4,54 @@ pragma solidity ^0.8.25; import {ParseState} from "./LibParseState.sol"; +/// @dev Magic number ORed into the high bits of every parse error offset so +/// that callers can distinguish Rain parse errors from other revert data. +/// Shifted left by 0x10 (16 bits) to leave room for the offset in the low +/// bytes. +bytes32 constant MAGIC_NUMBER_RAIN_PARSE_ERROR_V1 = keccak256("rain.interpreter.error.parse.0") << 0x10; + /// @title LibParseError /// @notice Utilities for computing error offsets during parsing. library LibParseError { /// @notice Calculates the byte offset of a cursor position relative to the start - /// of the parse data, for use in error reporting. + /// of the parse data, for use in error reporting. The offset is ORed with + /// `MAGIC_NUMBER_RAIN_PARSE_ERROR_V1` so that callers can identify Rain + /// parse errors by checking the high bits. /// @param state The parser state containing the source data reference. /// @param cursor The cursor position to calculate the offset for. - /// @return offset The byte offset from the start of the parse data. + /// @return offset The byte offset from the start of the parse data, ORed + /// with the magic number. function parseErrorOffset(ParseState memory state, uint256 cursor) internal pure returns (uint256 offset) { bytes memory data = state.data; assembly ("memory-safe") { offset := sub(cursor, add(data, 0x20)) } + offset = tagErrorOffset(offset); + } + + /// @notice Returns `true` if the given error offset was produced by + /// `parseErrorOffset`, i.e. it contains the magic number in its high bits. + /// @param errorOffset The error offset to check. + /// @return True if the magic number is present. + function isRainParseError(uint256 errorOffset) internal pure returns (bool) { + return (errorOffset & uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1)) == uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1); + } + + /// @notice Extracts the raw byte offset from a magic-number-tagged error + /// offset by masking out the magic number bits. + /// @param errorOffset The tagged error offset. + /// @return The raw byte offset within the parse data. + function parseOffset(uint256 errorOffset) internal pure returns (uint256) { + return errorOffset & ~uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1); + } + + /// @notice Tags a plain byte offset with the magic number. This is the + /// inverse of `parseOffset` and produces the same result as + /// `parseErrorOffset` without requiring a `ParseState`. + /// @param offset The plain byte offset to tag. + /// @return The offset ORed with `MAGIC_NUMBER_RAIN_PARSE_ERROR_V1`. + function tagErrorOffset(uint256 offset) internal pure returns (uint256) { + return uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1) | offset; } /// @notice Reverts with the given error selector and the cursor's byte offset if diff --git a/test/src/concrete/RainlangExpressionDeployer.parse2.t.sol b/test/src/concrete/RainlangExpressionDeployer.parse2.t.sol index eb246fd46..781435235 100644 --- a/test/src/concrete/RainlangExpressionDeployer.parse2.t.sol +++ b/test/src/concrete/RainlangExpressionDeployer.parse2.t.sol @@ -5,6 +5,7 @@ pragma solidity =0.8.25; import {OpTest} from "test/abstract/OpTest.sol"; import {MissingFinalSemi} from "../../../src/error/ErrParse.sol"; import {BadOpInputsLength} from "rain.interpreter.interface/error/ErrIntegrity.sol"; +import {LibParseError} from "../../../src/lib/parse/LibParseError.sol"; contract RainlangExpressionDeployerParse2Test is OpTest { /// parse2 with empty input must return valid serialized bytecode @@ -16,7 +17,7 @@ contract RainlangExpressionDeployerParse2Test is OpTest { /// parse2 with malformed Rainlang must propagate the parse error. function testParse2MissingFinalSemi() external { - vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, 4)); + vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, LibParseError.tagErrorOffset(4))); I_DEPLOYER.parse2("_: 1"); } diff --git a/test/src/concrete/RainlangExpressionDeployer.parsePragma1.t.sol b/test/src/concrete/RainlangExpressionDeployer.parsePragma1.t.sol index c8f2c556b..ba501782b 100644 --- a/test/src/concrete/RainlangExpressionDeployer.parsePragma1.t.sol +++ b/test/src/concrete/RainlangExpressionDeployer.parsePragma1.t.sol @@ -5,6 +5,7 @@ pragma solidity =0.8.25; import {OpTest} from "test/abstract/OpTest.sol"; import {PragmaV1} from "rain.interpreter.interface/interface/IParserPragmaV1.sol"; import {NoWhitespaceAfterUsingWordsFrom} from "../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../src/lib/parse/LibParseError.sol"; contract RainlangExpressionDeployerParsePragma1Test is OpTest { /// No pragma keyword yields empty usingWordsFrom. @@ -35,7 +36,9 @@ contract RainlangExpressionDeployerParsePragma1Test is OpTest { /// Error must propagate through the deployer proxy. function testParsePragma1ErrorPropagation() external { - vm.expectRevert(abi.encodeWithSelector(NoWhitespaceAfterUsingWordsFrom.selector, 16)); + vm.expectRevert( + abi.encodeWithSelector(NoWhitespaceAfterUsingWordsFrom.selector, LibParseError.tagErrorOffset(16)) + ); I_DEPLOYER.parsePragma1(bytes("using-words-from")); } } diff --git a/test/src/concrete/RainlangParser.parserPragma.t.sol b/test/src/concrete/RainlangParser.parserPragma.t.sol index 15788d586..a31baec3d 100644 --- a/test/src/concrete/RainlangParser.parserPragma.t.sol +++ b/test/src/concrete/RainlangParser.parserPragma.t.sol @@ -6,6 +6,7 @@ import {Test} from "forge-std/Test.sol"; import {RainlangParser} from "../../../src/concrete/RainlangParser.sol"; import {PragmaV1} from "rain.interpreter.interface/interface/IParserPragmaV1.sol"; import {NoWhitespaceAfterUsingWordsFrom} from "../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../src/lib/parse/LibParseError.sol"; contract RainlangParserParserPragma is Test { function checkPragma(bytes memory source, address[] memory expectedAddresses) internal { @@ -44,7 +45,9 @@ contract RainlangParserParserPragma is Test { /// must revert. function testParsePragmaNoWhitespaceAfterKeyword() external { RainlangParser parser = new RainlangParser(); - vm.expectRevert(abi.encodeWithSelector(NoWhitespaceAfterUsingWordsFrom.selector, 16)); + vm.expectRevert( + abi.encodeWithSelector(NoWhitespaceAfterUsingWordsFrom.selector, LibParseError.tagErrorOffset(16)) + ); parser.parsePragma1("using-words-from"); } diff --git a/test/src/lib/eval/LibEval.inputsLengthMismatch.t.sol b/test/src/lib/eval/LibEval.inputsLengthMismatch.t.sol index 8f4b27d16..ca1b0ccec 100644 --- a/test/src/lib/eval/LibEval.inputsLengthMismatch.t.sol +++ b/test/src/lib/eval/LibEval.inputsLengthMismatch.t.sol @@ -30,7 +30,7 @@ contract LibEvalInputsLengthMismatchTest is Test { /// Build an InterpreterState with a single source that expects /// `sourceInputs` inputs and has 0 ops / 0 outputs. - function buildState(uint8 sourceInputs) internal view returns (InterpreterState memory) { + function buildState(uint8 sourceInputs) internal pure returns (InterpreterState memory) { bytes memory fs = LibAllStandardOps.opcodeFunctionPointers(); // Bytecode: 1 source, 0 offset, 0 ops, sourceInputs stack allocation, diff --git a/test/src/lib/integrity/LibIntegrityCheck.io.t.sol b/test/src/lib/integrity/LibIntegrityCheck.io.t.sol index 94345d968..278eb8421 100644 --- a/test/src/lib/integrity/LibIntegrityCheck.io.t.sol +++ b/test/src/lib/integrity/LibIntegrityCheck.io.t.sol @@ -19,7 +19,7 @@ contract LibIntegrityCheckIoTest is RainlangExpressionDeployerDeploymentTest { } /// Single source with 0 inputs and 1 output. - function testIntegrityCheck2IoSingleSource() external { + function testIntegrityCheck2IoSingleSource() external view { (bytes memory bytecode, bytes32[] memory constants) = I_PARSER.unsafeParse(bytes("_: 1;")); bytes memory io = this.externalIntegrityCheck(bytecode, constants); assertEq(io.length, 2, "io length for 1 source"); @@ -28,7 +28,7 @@ contract LibIntegrityCheckIoTest is RainlangExpressionDeployerDeploymentTest { } /// Two sources with different output counts. - function testIntegrityCheck2IoTwoSources() external { + function testIntegrityCheck2IoTwoSources() external view { (bytes memory bytecode, bytes32[] memory constants) = I_PARSER.unsafeParse(bytes("_: 1;_: 2, _: 3;")); bytes memory io = this.externalIntegrityCheck(bytecode, constants); assertEq(io.length, 4, "io length for 2 sources"); diff --git a/test/src/lib/op/logic/LibOpEnsure.t.sol b/test/src/lib/op/logic/LibOpEnsure.t.sol index 3316af89f..674a5ae95 100644 --- a/test/src/lib/op/logic/LibOpEnsure.t.sol +++ b/test/src/lib/op/logic/LibOpEnsure.t.sol @@ -4,6 +4,7 @@ pragma solidity =0.8.25; import {OpTest, UnexpectedOperand} from "test/abstract/OpTest.sol"; import {ExcessRHSItems} from "../../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../../src/lib/parse/LibParseError.sol"; import {LibOpEnsure} from "../../../../../src/lib/op/logic/LibOpEnsure.sol"; import {IntegrityCheckState} from "../../../../../src/lib/integrity/LibIntegrityCheck.sol"; import {OperandV2, StackItem} from "rain.interpreter.interface/interface/IInterpreterV4.sol"; @@ -78,7 +79,7 @@ contract LibOpEnsureTest is OpTest { /// be used on the same line as another word as it has non-one outputs. /// Tests ensuring with an addition on the same line. function testOpEnsureEvalBadOutputs() external { - vm.expectRevert(abi.encodeWithSelector(ExcessRHSItems.selector, 34)); + vm.expectRevert(abi.encodeWithSelector(ExcessRHSItems.selector, LibParseError.tagErrorOffset(34))); (bytes memory bytecode, bytes32[] memory constants) = I_PARSER.unsafeParse("_:ensure(1 \"always true\") add(1 1);"); (bytecode); @@ -89,7 +90,7 @@ contract LibOpEnsureTest is OpTest { /// be used on the same line as another word as it has non-one outputs. /// Tests ensuring with another ensure on the same line. function testOpEnsureEvalBadOutputs2() external { - vm.expectRevert(abi.encodeWithSelector(ExcessRHSItems.selector, 48)); + vm.expectRevert(abi.encodeWithSelector(ExcessRHSItems.selector, LibParseError.tagErrorOffset(48))); (bytes memory bytecode, bytes32[] memory constants) = I_PARSER.unsafeParse(":ensure(1 \"always true\") ensure(1 \"always true\");"); (bytecode); diff --git a/test/src/lib/parse/LibParse.comments.t.sol b/test/src/lib/parse/LibParse.comments.t.sol index 8d5228e4e..9db679c55 100644 --- a/test/src/lib/parse/LibParse.comments.t.sol +++ b/test/src/lib/parse/LibParse.comments.t.sol @@ -10,6 +10,7 @@ import {LibBytecode} from "rain.interpreter.interface/lib/bytecode/LibBytecode.s import {UnclosedComment, UnexpectedComment, UnexpectedLHSChar} from "../../../../src/error/ErrParse.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; +import {LibParseError, MAGIC_NUMBER_RAIN_PARSE_ERROR_V1} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseCommentsTest /// @notice Test that the parser correctly parses comments. @@ -395,56 +396,70 @@ contract LibParseCommentsTest is OperandTest { /// Comments cause yang so cannot be without trailing whitespace. function testParseCommentNoTrailingWhitespace() external { string memory s = "/* comment */_:a();"; - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 13)); + vm.expectRevert( + abi.encodeWithSelector(UnexpectedLHSChar.selector, uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1) | 13) + ); this.parse(bytes(s)); } /// Comments cannot be in an ignored LHS item. function testParseCommentInIgnoredLHS() external { string memory s = "_/* comment */:a();"; - vm.expectRevert(abi.encodeWithSelector(UnexpectedComment.selector, 1)); + vm.expectRevert( + abi.encodeWithSelector(UnexpectedComment.selector, uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1) | 1) + ); this.parse(bytes(s)); } /// Comments cannot be in a named LHS item. function testParseCommentInNamedLHS() external { string memory s = "_a/* comment */:a();"; - vm.expectRevert(abi.encodeWithSelector(UnexpectedComment.selector, 2)); + vm.expectRevert( + abi.encodeWithSelector(UnexpectedComment.selector, uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1) | 2) + ); this.parse(bytes(s)); } /// Comments cannot be in the whitespace between LHS items. function testParseCommentInLHSWhitespace() external { string memory s = "_ /* comment */ _:a();"; - vm.expectRevert(abi.encodeWithSelector(UnexpectedComment.selector, 2)); + vm.expectRevert( + abi.encodeWithSelector(UnexpectedComment.selector, uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1) | 2) + ); this.parse(bytes(s)); } /// Comments cannot be in the RHS. Tests the start of the RHS. function testParseCommentInRHS() external { string memory s = "_:/* comment */a();"; - vm.expectRevert(abi.encodeWithSelector(UnexpectedComment.selector, 2)); + vm.expectRevert( + abi.encodeWithSelector(UnexpectedComment.selector, uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1) | 2) + ); this.parse(bytes(s)); } /// Comments cannot be in the RHS. Tests the middle of the RHS. function testParseCommentInRHS2() external { string memory s = "_:a()/* comment */ b();"; - vm.expectRevert(abi.encodeWithSelector(UnexpectedComment.selector, 5)); + vm.expectRevert( + abi.encodeWithSelector(UnexpectedComment.selector, uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1) | 5) + ); this.parse(bytes(s)); } /// Comments cannot be in the RHS. Tests the end of the RHS. function testParseCommentInRHS3() external { string memory s = "_:a()/* comment */;"; - vm.expectRevert(abi.encodeWithSelector(UnexpectedComment.selector, 5)); + vm.expectRevert( + abi.encodeWithSelector(UnexpectedComment.selector, uint256(MAGIC_NUMBER_RAIN_PARSE_ERROR_V1) | 5) + ); this.parse(bytes(s)); } /// Unclosed comments don't escape the data bounds. function testParseCommentUnclosed() external { string memory s = "/* unclosed comment"; - vm.expectRevert(abi.encodeWithSelector(UnclosedComment.selector, 19)); + vm.expectRevert(abi.encodeWithSelector(UnclosedComment.selector, LibParseError.tagErrorOffset(19))); this.parse(bytes(s)); } @@ -452,7 +467,7 @@ contract LibParseCommentsTest is OperandTest { /// so must revert and not escape the data bounds. function testParseCommentUnclosed2() external { string memory s = "/* unclosed comment *"; - vm.expectRevert(abi.encodeWithSelector(UnclosedComment.selector, 21)); + vm.expectRevert(abi.encodeWithSelector(UnclosedComment.selector, LibParseError.tagErrorOffset(21))); this.parse(bytes(s)); } } diff --git a/test/src/lib/parse/LibParse.lhsOverflow.t.sol b/test/src/lib/parse/LibParse.lhsOverflow.t.sol index ab33d16fd..fed060a7f 100644 --- a/test/src/lib/parse/LibParse.lhsOverflow.t.sol +++ b/test/src/lib/parse/LibParse.lhsOverflow.t.sol @@ -26,7 +26,7 @@ contract LibParseLHSOverflowTest is Test { /// 256 anonymous LHS items on a single line overflows both lineTracker /// (per-line counter) and topLevel1 (per-source counter). The parser /// must revert with LHSItemCountOverflow, not silently corrupt state. - function testLHSItemCountOverflow256() external { + function testLHSItemCountOverflow256() external view { // Build "_ _ _ ... (256 times) _ :;" bytes memory data = new bytes(256 * 2 + 2); for (uint256 i = 0; i < 256; i++) { diff --git a/test/src/lib/parse/LibParse.literalIntegerDecimal.t.sol b/test/src/lib/parse/LibParse.literalIntegerDecimal.t.sol index b7f9c67de..0f064e68a 100644 --- a/test/src/lib/parse/LibParse.literalIntegerDecimal.t.sol +++ b/test/src/lib/parse/LibParse.literalIntegerDecimal.t.sol @@ -10,6 +10,7 @@ import {LibBytecode} from "rain.interpreter.interface/lib/bytecode/LibBytecode.s import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; import {LibDecimalFloat, Float} from "rain.math.float/lib/LibDecimalFloat.sol"; import {ParseDecimalOverflow} from "rain.string/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseLiteralIntegerDecimalTest /// @notice Tests parsing integer literal decimal values. @@ -201,7 +202,7 @@ contract LibParseLiteralIntegerDecimalTest is ParseTest { /// Check that decimal literals will revert if they overflow uint256. function testParseIntegerLiteralDecimalUint256OverflowSimple() external { - vm.expectRevert(abi.encodeWithSelector(ParseDecimalOverflow.selector, 81)); + vm.expectRevert(abi.encodeWithSelector(ParseDecimalOverflow.selector, LibParseError.tagErrorOffset(81))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_: 115792089237316195423570985008687907853269984665640564039457584007913129639936e-18;"); (bytecode); @@ -211,7 +212,7 @@ contract LibParseLiteralIntegerDecimalTest is ParseTest { /// Check that decimal literals will revert if they overflow uint256 with /// leading zeros. function testParseIntegerLiteralDecimalUint256OverflowLeadingZeros() external { - vm.expectRevert(abi.encodeWithSelector(ParseDecimalOverflow.selector, 83)); + vm.expectRevert(abi.encodeWithSelector(ParseDecimalOverflow.selector, LibParseError.tagErrorOffset(83))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal( "_: 00115792089237316195423570985008687907853269984665640564039457584007913129639936e-18;" ); @@ -222,7 +223,7 @@ contract LibParseLiteralIntegerDecimalTest is ParseTest { // Check that decimal literals will revert if they overflow uint256 with // a non-one leading digit. function testParseIntegerLiteralDecimalUint256OverflowLeadingDigitBasic() external { - vm.expectRevert(abi.encodeWithSelector(ParseDecimalOverflow.selector, 81)); + vm.expectRevert(abi.encodeWithSelector(ParseDecimalOverflow.selector, LibParseError.tagErrorOffset(81))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_: 215792089237316195423570985008687907853269984665640564039457584007913129639935e-18;"); (bytecode); @@ -232,7 +233,7 @@ contract LibParseLiteralIntegerDecimalTest is ParseTest { /// Check that decimal literals will revert if they overflow uint256 with /// a non-one leading digit and leading zeros. function testParseIntegerLiteralDecimalUint256OverflowLeadingDigitLeadingZeros() external { - vm.expectRevert(abi.encodeWithSelector(ParseDecimalOverflow.selector, 83)); + vm.expectRevert(abi.encodeWithSelector(ParseDecimalOverflow.selector, LibParseError.tagErrorOffset(83))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal( "_: 00215792089237316195423570985008687907853269984665640564039457584007913129639935e-18;" ); @@ -292,7 +293,7 @@ contract LibParseLiteralIntegerDecimalTest is ParseTest { // The second e will happily be parsed up to by the internal bounds logic // but the parser will be in a state of yang, unable to receive the next // non-yin char. - vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, 5)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, LibParseError.tagErrorOffset(5))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:1e0e;"); (bytecode); (constants); @@ -301,7 +302,7 @@ contract LibParseLiteralIntegerDecimalTest is ParseTest { /// Check that decimals cannot be used with parens as they are literals not /// words. This tests left paren. function testParseIntegerLiteralDecimalParensLeft() external { - vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, LibParseError.tagErrorOffset(3))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:1(;"); (bytecode); (constants); @@ -310,7 +311,7 @@ contract LibParseLiteralIntegerDecimalTest is ParseTest { /// Check that decimals cannot be used with parens as they are literals not /// words. This tests right paren. function testParseIntegerLiteralDecimalParensRight() external { - vm.expectRevert(abi.encodeWithSelector(UnexpectedRightParen.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRightParen.selector, LibParseError.tagErrorOffset(3))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:1);"); (bytecode); (constants); @@ -319,7 +320,7 @@ contract LibParseLiteralIntegerDecimalTest is ParseTest { /// Check that decimals cannot be used with parens as they are literals not /// words. This tests both parens. function testParseIntegerLiteralDecimalParensBoth() external { - vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, LibParseError.tagErrorOffset(3))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:1();"); (bytecode); (constants); diff --git a/test/src/lib/parse/LibParse.literalString.t.sol b/test/src/lib/parse/LibParse.literalString.t.sol index f735d361c..70d1315a8 100644 --- a/test/src/lib/parse/LibParse.literalString.t.sol +++ b/test/src/lib/parse/LibParse.literalString.t.sol @@ -10,6 +10,7 @@ import {IntOrAString, LibIntOrAString} from "rain.intorastring/lib/LibIntOrAStri import {StringTooLong, UnclosedStringLiteral} from "../../../../src/error/ErrParse.sol"; import {LibConformString} from "rain.string/lib/mut/LibConformString.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseLiteralStringTest /// @notice Tests for parsing string literals. @@ -108,7 +109,7 @@ contract LibParseLiteralStringTest is Test { vm.assume(bytes(str).length >= 0x20); LibConformString.conformValidPrintableStringContent(str); - vm.expectRevert(abi.encodeWithSelector(StringTooLong.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(StringTooLong.selector, LibParseError.tagErrorOffset(3))); (bytes memory bytecode, bytes32[] memory constants) = this.externalParse(string.concat("_: \"", str, "\";")); (bytecode, constants); } @@ -124,7 +125,7 @@ contract LibParseLiteralStringTest is Test { mstore(strA, 0x20) } - vm.expectRevert(abi.encodeWithSelector(StringTooLong.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(StringTooLong.selector, LibParseError.tagErrorOffset(3))); (bytes memory bytecode, bytes32[] memory constants) = this.externalParse(string.concat("_: \"", strA, strB, "\";")); (bytecode, constants); @@ -140,7 +141,9 @@ contract LibParseLiteralStringTest is Test { LibConformString.corruptSingleChar(str, badIndex); - vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, 4 + badIndex)); + vm.expectRevert( + abi.encodeWithSelector(UnclosedStringLiteral.selector, LibParseError.tagErrorOffset(4 + badIndex)) + ); (bytes memory bytecode, bytes32[] memory constants) = this.externalParse(string.concat("_: \"", str, "\";")); (bytecode, constants); } diff --git a/test/src/lib/parse/LibParse.missingFinalSemi.t.sol b/test/src/lib/parse/LibParse.missingFinalSemi.t.sol index 6f775ccd4..12586dfd0 100644 --- a/test/src/lib/parse/LibParse.missingFinalSemi.t.sol +++ b/test/src/lib/parse/LibParse.missingFinalSemi.t.sol @@ -6,6 +6,7 @@ import {ParseTest} from "test/abstract/ParseTest.sol"; import {LibParse} from "../../../../src/lib/parse/LibParse.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; import {MissingFinalSemi} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseMissingFinalSemiTest /// @notice Tests that missing final semicolons are rejected. Every expression @@ -15,31 +16,31 @@ contract LibParseMissingFinalSemiTest is ParseTest { /// A lone colon should revert as missing a semi. function testParseMissingFinalSemiRevertsLoneColon() external { - vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, LibParseError.tagErrorOffset(1))); this.parseExternal(":"); } /// A lone colon after an empty source should error as missing a semi. function testParseMissingFinalSemiRevertsEmptySource() external { - vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, LibParseError.tagErrorOffset(3))); this.parseExternal(":;:"); } /// An empty source with a trailing comma should error as missing a semi. function testParseMissingFinalSemiRevertsTrailingComma() external { - vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, 2)); + vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, LibParseError.tagErrorOffset(2))); this.parseExternal(":,"); } /// A single word without a trailing semi should error as missing a semi. function testParseMissingFinalSemiRevertsSingleWord() external { - vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, 4)); + vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, LibParseError.tagErrorOffset(4))); this.parseExternal(":a()"); } /// Some detached LHS items should error as missing a semi. function testParseMissingFinalSemiRevertsLHSItems() external { - vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(MissingFinalSemi.selector, LibParseError.tagErrorOffset(3))); this.parseExternal("_ _"); } } diff --git a/test/src/lib/parse/LibParse.nOutput.t.sol b/test/src/lib/parse/LibParse.nOutput.t.sol index d6c1814b1..5ae2aa406 100644 --- a/test/src/lib/parse/LibParse.nOutput.t.sol +++ b/test/src/lib/parse/LibParse.nOutput.t.sol @@ -9,6 +9,7 @@ import {LibParse} from "../../../../src/lib/parse/LibParse.sol"; import {LibBytecode} from "rain.interpreter.interface/lib/bytecode/LibBytecode.sol"; import {ExcessLHSItems, ExcessRHSItems} from "../../../../src/error/ErrParse.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseNOutputTest /// @notice Test that the parser can handle multi and zero outputs for RHS items when @@ -42,14 +43,14 @@ contract LibParseNOutputTest is ParseTest { /// Multiple RHS items MUST NOT have 0 outputs. Tests two RHS items and zero /// LHS items. function testParseNOutputExcessRHS1() external { - vm.expectRevert(abi.encodeWithSelector(ExcessRHSItems.selector, 8)); + vm.expectRevert(abi.encodeWithSelector(ExcessRHSItems.selector, LibParseError.tagErrorOffset(8))); this.parseExternal(":a() b();"); } /// Multiple RHS items MUST NOT have 0 outputs. Tests two RHS items and one /// LHS item. function testParseNOutputExcessRHS2() external { - vm.expectRevert(abi.encodeWithSelector(ExcessRHSItems.selector, 9)); + vm.expectRevert(abi.encodeWithSelector(ExcessRHSItems.selector, LibParseError.tagErrorOffset(9))); this.parseExternal("_:a() b();"); } @@ -82,7 +83,7 @@ contract LibParseNOutputTest is ParseTest { /// Multiple RHS items MUST NOT have multiple outputs. Tests two RHS items /// and three LHS items. function testParseNOutputExcessRHS3() external { - vm.expectRevert(abi.encodeWithSelector(ExcessLHSItems.selector, 13)); + vm.expectRevert(abi.encodeWithSelector(ExcessLHSItems.selector, LibParseError.tagErrorOffset(13))); this.parseExternal("_ _ _:a() b();"); } diff --git a/test/src/lib/parse/LibParse.namedLHS.t.sol b/test/src/lib/parse/LibParse.namedLHS.t.sol index 1bb5a9595..a272a0e6c 100644 --- a/test/src/lib/parse/LibParse.namedLHS.t.sol +++ b/test/src/lib/parse/LibParse.namedLHS.t.sol @@ -12,6 +12,7 @@ import {LibParseState, ParseState} from "../../../../src/lib/parse/LibParseState import {OperandV2, LibParseOperand} from "../../../../src/lib/parse/LibParseOperand.sol"; import {LibConvert} from "rain.lib.typecast/LibConvert.sol"; import {LibAllStandardOps} from "../../../../src/lib/op/LibAllStandardOps.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; import {LibGenParseMeta} from "rain.interpreter.interface/lib/codegen/LibGenParseMeta.sol"; import {LibDecimalFloat, Float} from "rain.math.float/lib/LibDecimalFloat.sol"; @@ -227,7 +228,7 @@ contract LibParseNamedLHSTest is ParseTest { /// Duplicate names are disallowed in the same source. function testParseNamedErrorDuplicateSameSource() external { - vm.expectRevert(abi.encodeWithSelector(DuplicateLHSItem.selector, 4)); + vm.expectRevert(abi.encodeWithSelector(DuplicateLHSItem.selector, LibParseError.tagErrorOffset(4))); this.parseExternal("a:,a:;"); } diff --git a/test/src/lib/parse/LibParse.operand8M1M1.t.sol b/test/src/lib/parse/LibParse.operand8M1M1.t.sol index 30c3fefa0..45b0d4808 100644 --- a/test/src/lib/parse/LibParse.operand8M1M1.t.sol +++ b/test/src/lib/parse/LibParse.operand8M1M1.t.sol @@ -5,6 +5,7 @@ pragma solidity =0.8.25; import {ExpectedOperand, UnclosedOperand} from "../../../../src/error/ErrParse.sol"; import {OperandTest} from "test/abstract/OperandTest.sol"; import {OperandOverflow} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; contract LibParseOperand8M1M1Test is OperandTest { /// Default is disallowed. @@ -76,12 +77,12 @@ contract LibParseOperand8M1M1Test is OperandTest { /// Unclosed operand is disallowed. function testOperand8M1M1Unclosed() external { - checkParseError("_:e<1 1();", abi.encodeWithSelector(UnclosedOperand.selector, 7)); - checkParseError("_:e<1 0()", abi.encodeWithSelector(UnclosedOperand.selector, 7)); - checkParseError("_:e<1 ", abi.encodeWithSelector(UnclosedOperand.selector, 6)); - checkParseError("_:e<1", abi.encodeWithSelector(UnclosedOperand.selector, 5)); - checkParseError("_:e<1 1", abi.encodeWithSelector(UnclosedOperand.selector, 7)); - checkParseError("_:e<1 1 1", abi.encodeWithSelector(UnclosedOperand.selector, 9)); + checkParseError("_:e<1 1();", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(7))); + checkParseError("_:e<1 0()", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(7))); + checkParseError("_:e<1 ", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(6))); + checkParseError("_:e<1", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(5))); + checkParseError("_:e<1 1", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(7))); + checkParseError("_:e<1 1 1", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(9))); } /// Unopened operand is disallowed. diff --git a/test/src/lib/parse/LibParse.operandDisallowed.t.sol b/test/src/lib/parse/LibParse.operandDisallowed.t.sol index 505e4951d..3055603e1 100644 --- a/test/src/lib/parse/LibParse.operandDisallowed.t.sol +++ b/test/src/lib/parse/LibParse.operandDisallowed.t.sol @@ -7,13 +7,14 @@ import {ParseTest} from "test/abstract/ParseTest.sol"; import {UnexpectedOperand, UnsupportedLiteralType} from "../../../../src/error/ErrParse.sol"; import {LibParse, ExpectedLeftParen} from "../../../../src/lib/parse/LibParse.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; contract LibParseOperandDisallowedTest is ParseTest { using LibParse for ParseState; /// Opening an operand is disallowed for words that don't support it. function testOperandDisallowed() external { - vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, 4)); + vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, LibParseError.tagErrorOffset(4))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:a<;"); (bytecode); (constants); @@ -21,7 +22,7 @@ contract LibParseOperandDisallowedTest is ParseTest { /// Closing an operand is disallowed for words that don't support it. function testOperandDisallowed1() external { - vm.expectRevert(abi.encodeWithSelector(ExpectedLeftParen.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(ExpectedLeftParen.selector, LibParseError.tagErrorOffset(3))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:a>;"); (bytecode); (constants); diff --git a/test/src/lib/parse/LibParse.operandDoublePerByteNoDefault.t.sol b/test/src/lib/parse/LibParse.operandDoublePerByteNoDefault.t.sol index b0092c3cb..408422263 100644 --- a/test/src/lib/parse/LibParse.operandDoublePerByteNoDefault.t.sol +++ b/test/src/lib/parse/LibParse.operandDoublePerByteNoDefault.t.sol @@ -8,6 +8,7 @@ import {LibParse} from "../../../../src/lib/parse/LibParse.sol"; import {LibMetaFixture} from "test/lib/parse/LibMetaFixture.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; import {OperandOverflow} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; contract LibParseOperandDoublePerByteNoDefaultTest is OperandTest { using LibParse for ParseState; @@ -178,7 +179,7 @@ contract LibParseOperandDoublePerByteNoDefaultTest is OperandTest { /// Unclosed operand is disallowed. function testOperandDoublePerByteNoDefaultUnclosed() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, 7)); + vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(7))); (bytes memory bytecode, bytes32[] memory constants) = this.parse("_:c<1 2"); (bytecode); (constants); diff --git a/test/src/lib/parse/LibParse.operandM1M1.t.sol b/test/src/lib/parse/LibParse.operandM1M1.t.sol index e996deae2..fb737f695 100644 --- a/test/src/lib/parse/LibParse.operandM1M1.t.sol +++ b/test/src/lib/parse/LibParse.operandM1M1.t.sol @@ -8,6 +8,7 @@ import {OperandTest} from "test/abstract/OperandTest.sol"; import {LibMetaFixture} from "test/lib/parse/LibMetaFixture.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; import {OperandOverflow} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; contract LibParseOperandM1M1Test is OperandTest { using LibParse for ParseState; @@ -173,15 +174,17 @@ contract LibParseOperandM1M1Test is OperandTest { /// Unclosed operand is disallowed. function testOperandM1M1Unclosed() external { - checkParseError("_:d<1 1();", abi.encodeWithSelector(UnclosedOperand.selector, 7)); - checkParseError("_:d<1 0()", abi.encodeWithSelector(UnclosedOperand.selector, 7)); - checkParseError("_:d<1 ", abi.encodeWithSelector(UnclosedOperand.selector, 6)); - checkParseError("_:d<1", abi.encodeWithSelector(UnclosedOperand.selector, 5)); - checkParseError("_:d<1 1", abi.encodeWithSelector(UnclosedOperand.selector, 7)); + checkParseError("_:d<1 1();", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(7))); + checkParseError("_:d<1 0()", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(7))); + checkParseError("_:d<1 ", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(6))); + checkParseError("_:d<1", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(5))); + checkParseError("_:d<1 1", abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(7))); } /// Unopened operand is disallowed. function testOperandM1M1Unopened() external { - checkParseError("_:d>1 1>();", abi.encodeWithSelector(ExpectedLeftParen.selector, 3)); + checkParseError( + "_:d>1 1>();", abi.encodeWithSelector(ExpectedLeftParen.selector, LibParseError.tagErrorOffset(3)) + ); } } diff --git a/test/src/lib/parse/LibParse.operandSingleFull.t.sol b/test/src/lib/parse/LibParse.operandSingleFull.t.sol index d5281dfe7..10b7c7e2d 100644 --- a/test/src/lib/parse/LibParse.operandSingleFull.t.sol +++ b/test/src/lib/parse/LibParse.operandSingleFull.t.sol @@ -8,6 +8,7 @@ import {LibParse, ExpectedLeftParen} from "../../../../src/lib/parse/LibParse.so import {LibMetaFixture} from "test/lib/parse/LibMetaFixture.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; import {OperandOverflow} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; contract LibParseOperandSingleFullTest is ParseTest { using LibParse for ParseState; @@ -222,7 +223,7 @@ contract LibParseOperandSingleFullTest is ParseTest { /// Opening angle bracket without closing angle bracket reverts. function testOperandSingleFullUnclosed() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, 5)); + vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(5))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:b<0;"); (bytecode); (constants); @@ -230,7 +231,7 @@ contract LibParseOperandSingleFullTest is ParseTest { /// Closing angle bracket without opening angle bracket reverts. function testOperandSingleFullUnopened() external { - vm.expectRevert(abi.encodeWithSelector(ExpectedLeftParen.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(ExpectedLeftParen.selector, LibParseError.tagErrorOffset(3))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:b>0>;"); (bytecode); (constants); diff --git a/test/src/lib/parse/LibParse.unclosedLeftParen.t.sol b/test/src/lib/parse/LibParse.unclosedLeftParen.t.sol index a030bea77..956136779 100644 --- a/test/src/lib/parse/LibParse.unclosedLeftParen.t.sol +++ b/test/src/lib/parse/LibParse.unclosedLeftParen.t.sol @@ -6,6 +6,7 @@ import {ParseTest} from "test/abstract/ParseTest.sol"; import {LibParse} from "../../../../src/lib/parse/LibParse.sol"; import {UnclosedLeftParen} from "../../../../src/error/ErrParse.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseUnclosedLeftParenTest /// @notice Test that the parser errors when it encounters an unclosed left paren. @@ -14,20 +15,20 @@ contract LibParseUnclosedLeftParenTest is ParseTest { /// Check the parser reverts if it encounters an unclosed left paren. function testParseUnclosedLeftParen() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, 4)); + vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, LibParseError.tagErrorOffset(4))); this.parseExternal("_:a(;"); } /// Multiple unclosed left parens should be reported. function testParseUnclosedLeftParenNested() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, 20)); + vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, LibParseError.tagErrorOffset(20))); this.parseExternal("_:a(b(c<0 0>(d(e<0>(;"); } /// The parser should track the paren depth as it encounters left parens /// and report if there are any unclosed parens. function testParseUnclosedLeftParenNested2() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, 24)); + vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, LibParseError.tagErrorOffset(24))); this.parseExternal("_:a(b(c<0 0>(d(e<0>())));"); } @@ -35,13 +36,13 @@ contract LibParseUnclosedLeftParenTest is ParseTest { /// unclosed left parens. function testParseUnclosedLeftParenNested3() external { // Second nesting is unclosed. - vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, 34)); + vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, LibParseError.tagErrorOffset(34))); this.parseExternal("_:a(b(c<0 0>(d(e<0>())))) e<0>(a();"); } function testParseUnclosedLeftParenNested4() external { // First nesting is unclosed. - vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, 34)); + vm.expectRevert(abi.encodeWithSelector(UnclosedLeftParen.selector, LibParseError.tagErrorOffset(34))); this.parseExternal("_:a(b(c<0 0>(d(e<0>()))) e<0>(a());"); } } diff --git a/test/src/lib/parse/LibParse.unexpectedLHS.t.sol b/test/src/lib/parse/LibParse.unexpectedLHS.t.sol index a9bc370ab..c83a8b1ef 100644 --- a/test/src/lib/parse/LibParse.unexpectedLHS.t.sol +++ b/test/src/lib/parse/LibParse.unexpectedLHS.t.sol @@ -12,6 +12,7 @@ import { } from "rain.string/lib/parse/LibParseCMask.sol"; import {LibParse, UnexpectedLHSChar} from "../../../../src/lib/parse/LibParse.sol"; import {ParseState} from "../../../../src/lib/parse/LibParseState.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseUnexpectedLHSTest /// @notice The parser should revert if it encounters an unexpected character on the LHS. @@ -20,38 +21,38 @@ contract LibParseUnexpectedLHSTest is ParseTest { /// Check the parser reverts if it encounters an unexpected EOL on the LHS. function testParseUnexpectedLHSEOL() external { - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(0))); this.parseExternal(","); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(1))); this.parseExternal(" ,"); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(1))); this.parseExternal("_,"); } /// Check the parser reverts if it encounters an unexpected EOF on the LHS. function testParseUnexpectedLHSEOF() external { - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(0))); this.parseExternal(";"); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(1))); this.parseExternal(" ;"); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(1))); this.parseExternal("_;"); } /// Check the parser reverts if it encounters underscores in the tail of an /// LHS item. function testParseUnexpectedLHSUnderscoreTail() external { - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(1))); this.parseExternal("a_:;"); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(3))); this.parseExternal("a __:;"); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 2)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(2))); this.parseExternal("_a_:;"); } @@ -65,7 +66,7 @@ contract LibParseUnexpectedLHSTest is ParseTest { == 0 ); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(0))); this.parseExternal(string(bytes.concat(bytes1(a), ":;"))); } @@ -79,7 +80,7 @@ contract LibParseUnexpectedLHSTest is ParseTest { == 0 ); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(1))); this.parseExternal(string(bytes.concat("_", bytes1(a), ":;"))); } @@ -107,7 +108,7 @@ contract LibParseUnexpectedLHSTest is ParseTest { vm.assume(identifier.length > 0); vm.assume(identifier.length < 32); - vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, i + 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedLHSChar.selector, LibParseError.tagErrorOffset(i + 1))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal(string(bytes.concat(identifier, ":;"))); (bytecode, constants); } diff --git a/test/src/lib/parse/LibParse.unexpectedRHS.t.sol b/test/src/lib/parse/LibParse.unexpectedRHS.t.sol index efd42dcfe..b9dbc49ea 100644 --- a/test/src/lib/parse/LibParse.unexpectedRHS.t.sol +++ b/test/src/lib/parse/LibParse.unexpectedRHS.t.sol @@ -5,6 +5,7 @@ pragma solidity =0.8.25; import {ParseTest} from "test/abstract/ParseTest.sol"; import {LibParse} from "../../../../src/lib/parse/LibParse.sol"; import {UnexpectedRHSChar} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; import { CMASK_RHS_WORD_HEAD, CMASK_LITERAL_HEAD, @@ -49,7 +50,7 @@ contract LibParseUnexpectedRHSTest is ParseTest { ); string memory s = string(bytes.concat(":", bytes1(unexpected), ";")); - vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, LibParseError.tagErrorOffset(1))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal(s); (bytecode, constants); } @@ -59,7 +60,7 @@ contract LibParseUnexpectedRHSTest is ParseTest { function testParseUnexpectedRHSLeftParen() external { string memory s = ":();"; - vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, LibParseError.tagErrorOffset(1))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal(s); (bytecode, constants); } @@ -67,7 +68,7 @@ contract LibParseUnexpectedRHSTest is ParseTest { /// Check the parser reverts when two words appear consecutively without /// whitespace (yang-state word-word path). function testParseUnexpectedRHSYangWordWord() external { - vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, 10)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRHSChar.selector, LibParseError.tagErrorOffset(10))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal("_:add(1 2)add(3 4);"); (bytecode, constants); } diff --git a/test/src/lib/parse/LibParse.unexpectedRightParen.t.sol b/test/src/lib/parse/LibParse.unexpectedRightParen.t.sol index 55c89249f..cf1c140f3 100644 --- a/test/src/lib/parse/LibParse.unexpectedRightParen.t.sol +++ b/test/src/lib/parse/LibParse.unexpectedRightParen.t.sol @@ -9,6 +9,7 @@ import {LibParse} from "../../../../src/lib/parse/LibParse.sol"; import {LibParseState, ParseState} from "../../../../src/lib/parse/LibParseState.sol"; import {UnexpectedRightParen} from "../../../../src/error/ErrParse.sol"; import {LibAllStandardOps} from "../../../../src/lib/op/LibAllStandardOps.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseUnexpectedRightParenTest /// @notice Test that the parser errors when it encounters an unexpected right paren. @@ -33,7 +34,7 @@ contract LibParseUnexpectedRightParenTest is Test { LibAllStandardOps.literalParserFunctionPointers() ); - vm.expectRevert(abi.encodeWithSelector(UnexpectedRightParen.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRightParen.selector, LibParseError.tagErrorOffset(1))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal(state); (bytecode, constants); } @@ -48,7 +49,7 @@ contract LibParseUnexpectedRightParenTest is Test { LibAllStandardOps.literalParserFunctionPointers() ); - vm.expectRevert(abi.encodeWithSelector(UnexpectedRightParen.selector, 7)); + vm.expectRevert(abi.encodeWithSelector(UnexpectedRightParen.selector, LibParseError.tagErrorOffset(7))); (bytes memory bytecode, bytes32[] memory constants) = this.parseExternal(state); (bytecode, constants); } diff --git a/test/src/lib/parse/LibParseError.t.sol b/test/src/lib/parse/LibParseError.t.sol index 5b40be245..555fd6234 100644 --- a/test/src/lib/parse/LibParseError.t.sol +++ b/test/src/lib/parse/LibParseError.t.sol @@ -4,7 +4,7 @@ pragma solidity =0.8.25; import {Test} from "forge-std/Test.sol"; import {LibParseState, ParseState} from "../../../../src/lib/parse/LibParseState.sol"; -import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; +import {LibParseError, MAGIC_NUMBER_RAIN_PARSE_ERROR_V1} from "../../../../src/lib/parse/LibParseError.sol"; import {LibAllStandardOps} from "../../../../src/lib/op/LibAllStandardOps.sol"; /// @title LibParseErrorTest @@ -20,10 +20,13 @@ contract LibParseErrorTest is Test { assembly ("memory-safe") { cursor := add(data, 0x20) } - assertEq(state.parseErrorOffset(cursor), 0); + uint256 offset = state.parseErrorOffset(cursor); + assertTrue(LibParseError.isRainParseError(offset)); + assertEq(LibParseError.parseOffset(offset), 0); } - /// parseErrorOffset returns data.length - 1 when cursor points to the last byte. + /// parseErrorOffset returns magic-tagged data.length - 1 when cursor + /// points to the last byte. function testParseErrorOffsetLastByte() external pure { bytes memory data = "hello"; ParseState memory state = LibParseState.newState(data, "", "", ""); @@ -31,10 +34,13 @@ contract LibParseErrorTest is Test { assembly ("memory-safe") { cursor := add(add(data, 0x20), sub(mload(data), 1)) } - assertEq(state.parseErrorOffset(cursor), 4); + uint256 offset = state.parseErrorOffset(cursor); + assertTrue(LibParseError.isRainParseError(offset)); + assertEq(LibParseError.parseOffset(offset), 4); } /// parseErrorOffset works with a fuzzed cursor within data bounds. + /// The raw offset always equals the cursor index. function testParseErrorOffsetFuzz(uint8 dataLength, uint8 cursorIndex) external pure { dataLength = uint8(bound(dataLength, 1, 255)); cursorIndex = uint8(bound(cursorIndex, 0, dataLength - 1)); @@ -44,7 +50,16 @@ contract LibParseErrorTest is Test { assembly ("memory-safe") { cursor := add(add(data, 0x20), cursorIndex) } - assertEq(state.parseErrorOffset(cursor), cursorIndex); + uint256 offset = state.parseErrorOffset(cursor); + assertTrue(LibParseError.isRainParseError(offset)); + assertEq(LibParseError.parseOffset(offset), cursorIndex); + } + + /// A value without the magic number must not be identified as a Rain + /// parse error. + function testIsRainParseErrorFalse(uint256 value) external pure { + vm.assume(!LibParseError.isRainParseError(value)); + assertFalse(LibParseError.isRainParseError(value)); } /// External wrapper for handleErrorSelector so expectRevert works. @@ -57,12 +72,20 @@ contract LibParseErrorTest is Test { state.handleErrorSelector(cursor, errorSelector); } + /// tagErrorOffset round-trips with parseOffset. + function testTagErrorOffsetRoundTrip(uint256 offset) external pure { + offset = bound(offset, 0, type(uint16).max); + uint256 tagged = LibParseError.tagErrorOffset(offset); + assertTrue(LibParseError.isRainParseError(tagged)); + assertEq(LibParseError.parseOffset(tagged), offset); + } + /// handleErrorSelector with a non-zero selector reverts with the selector /// and the cursor offset. function testHandleErrorSelectorReverts() external { bytes memory data = "abcdefgh"; bytes4 selector = bytes4(keccak256("TestError(uint256)")); - vm.expectRevert(abi.encodeWithSelector(selector, 5)); + vm.expectRevert(abi.encodeWithSelector(selector, LibParseError.tagErrorOffset(5))); this.externalHandleErrorSelector(data, 5, selector); } diff --git a/test/src/lib/parse/LibParseInterstitial.t.sol b/test/src/lib/parse/LibParseInterstitial.t.sol index 774214d7e..15d0cb679 100644 --- a/test/src/lib/parse/LibParseInterstitial.t.sol +++ b/test/src/lib/parse/LibParseInterstitial.t.sol @@ -8,6 +8,7 @@ import {LibParseState, ParseState} from "../../../../src/lib/parse/LibParseState import {LibParseInterstitial} from "../../../../src/lib/parse/LibParseInterstitial.sol"; import {FSM_YANG_MASK} from "../../../../src/lib/parse/LibParseState.sol"; import {MalformedCommentStart, UnclosedComment} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseInterstitialTest /// @notice Tests for LibParseInterstitial. @@ -24,7 +25,7 @@ contract LibParseInterstitialTest is Test { //forge-lint: disable-next-line(unsafe-typecast) bytes memory data = abi.encodePacked(bytes1("/"), bytes1(secondByte), bytes2("*/")); - vm.expectRevert(abi.encodeWithSelector(MalformedCommentStart.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(MalformedCommentStart.selector, LibParseError.tagErrorOffset(0))); this.externalSkipComment(data); } @@ -38,13 +39,13 @@ contract LibParseInterstitialTest is Test { /// skipComment with fewer than 4 bytes reverts with UnclosedComment. function testSkipCommentTooShort() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedComment.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnclosedComment.selector, LibParseError.tagErrorOffset(0))); this.externalSkipComment(bytes("/*")); } /// skipComment with exactly 3 bytes reverts with UnclosedComment. function testSkipCommentThreeBytes() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedComment.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnclosedComment.selector, LibParseError.tagErrorOffset(0))); this.externalSkipComment(bytes("/* ")); } diff --git a/test/src/lib/parse/LibParseOperand.parseOperand.t.sol b/test/src/lib/parse/LibParseOperand.parseOperand.t.sol index b462e2b06..9dcb3dd4c 100644 --- a/test/src/lib/parse/LibParseOperand.parseOperand.t.sol +++ b/test/src/lib/parse/LibParseOperand.parseOperand.t.sol @@ -10,6 +10,7 @@ import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol"; import {LibMetaFixture} from "test/lib/parse/LibMetaFixture.sol"; import {LibConformString} from "rain.string/lib/mut/LibConformString.sol"; import {OperandValuesOverflow, UnclosedOperand} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; import {LibDecimalFloat, Float} from "rain.math.float/lib/LibDecimalFloat.sol"; contract LibParseOperandParseOperandTest is Test { @@ -272,19 +273,19 @@ contract LibParseOperandParseOperandTest is Test { /// More than 4 values is an error. function testParseOperandTooManyValues() external { - vm.expectRevert(abi.encodeWithSelector(OperandValuesOverflow.selector, 9)); + vm.expectRevert(abi.encodeWithSelector(OperandValuesOverflow.selector, LibParseError.tagErrorOffset(9))); this.checkParsingOperandFromData("<1 2 3 4 5>", new bytes32[](0), 0); } /// Unclosed operand is an error. function testParseOperandUnclosed() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, 8)); + vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(8))); this.checkParsingOperandFromData("<1 2 3 4", new bytes32[](0), 0); } // Unexpected chars will be treated as unclosed operands. function testParseOperandUnexpectedChars() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, 6)); + vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(6))); this.checkParsingOperandFromData("<1 2 3;> 6", new bytes32[](0), 0); } @@ -292,7 +293,7 @@ contract LibParseOperandParseOperandTest is Test { // UnclosedOperand revert at line 111. After parsing `2`, yang is set, // then `"` is a valid literal head but yang prevents parsing it. function testParseOperandYangStateLiteralCollision() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, 4)); + vm.expectRevert(abi.encodeWithSelector(UnclosedOperand.selector, LibParseError.tagErrorOffset(4))); this.checkParsingOperandFromData("<1 2\"hi\">", new bytes32[](0), 0); } } diff --git a/test/src/lib/parse/LibParsePragma.keyword.t.sol b/test/src/lib/parse/LibParsePragma.keyword.t.sol index 819d3e2f4..ac8cc30cf 100644 --- a/test/src/lib/parse/LibParsePragma.keyword.t.sol +++ b/test/src/lib/parse/LibParsePragma.keyword.t.sol @@ -19,6 +19,7 @@ import { } from "rain.string/lib/parse/LibParseCMask.sol"; import {LibConformString} from "rain.string/lib/mut/LibConformString.sol"; import {NoWhitespaceAfterUsingWordsFrom} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol"; import {LibAllStandardOps} from "../../../../src/lib/op/LibAllStandardOps.sol"; @@ -90,7 +91,11 @@ contract LibParsePragmaKeywordTest is Test { /// Input ends exactly at the keyword boundary with no trailing bytes. /// Hits the `cursor >= end` revert at line 55. function testPragmaKeywordEndAtKeyword() external { - vm.expectRevert(abi.encodeWithSelector(NoWhitespaceAfterUsingWordsFrom.selector, PRAGMA_KEYWORD_BYTES_LENGTH)); + vm.expectRevert( + abi.encodeWithSelector( + NoWhitespaceAfterUsingWordsFrom.selector, LibParseError.tagErrorOffset(PRAGMA_KEYWORD_BYTES_LENGTH) + ) + ); this.externalParsePragma(string(PRAGMA_KEYWORD_BYTES)); } @@ -101,7 +106,11 @@ contract LibParsePragmaKeywordTest is Test { bytes1 notWhitespace = LibConformString.charFromMask(seed, ~CMASK_WHITESPACE); string memory fullString = string.concat(string(PRAGMA_KEYWORD_BYTES), string(abi.encodePacked(notWhitespace)), str); - vm.expectRevert(abi.encodeWithSelector(NoWhitespaceAfterUsingWordsFrom.selector, PRAGMA_KEYWORD_BYTES_LENGTH)); + vm.expectRevert( + abi.encodeWithSelector( + NoWhitespaceAfterUsingWordsFrom.selector, LibParseError.tagErrorOffset(PRAGMA_KEYWORD_BYTES_LENGTH) + ) + ); this.externalParsePragma(fullString); } diff --git a/test/src/lib/parse/LibParseState.endLine.OpcodeIOOverflow.t.sol b/test/src/lib/parse/LibParseState.endLine.OpcodeIOOverflow.t.sol index 36b0e3939..a1a14d8ef 100644 --- a/test/src/lib/parse/LibParseState.endLine.OpcodeIOOverflow.t.sol +++ b/test/src/lib/parse/LibParseState.endLine.OpcodeIOOverflow.t.sol @@ -4,6 +4,7 @@ pragma solidity =0.8.25; import {RainlangExpressionDeployerDeploymentTest} from "test/abstract/RainlangExpressionDeployerDeploymentTest.sol"; import {OpcodeIOOverflow} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseStateOpcodeIOOverflowTest /// @notice Tests for OpcodeIOOverflow in endLine. @@ -14,7 +15,7 @@ contract LibParseStateOpcodeIOOverflowTest is RainlangExpressionDeployerDeployme // int-add with 16 inputs: int-add(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1) bytes memory rainlang = bytes("_: int-add(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1);"); - vm.expectRevert(abi.encodeWithSelector(OpcodeIOOverflow.selector, 43)); + vm.expectRevert(abi.encodeWithSelector(OpcodeIOOverflow.selector, LibParseError.tagErrorOffset(43))); I_PARSER.unsafeParse(rainlang); } @@ -25,7 +26,7 @@ contract LibParseStateOpcodeIOOverflowTest is RainlangExpressionDeployerDeployme // Use a 0-input word so inputs don't overflow first. bytes memory rainlang = bytes("a b c d e f g h i j k l m n o p: block-number();"); - vm.expectRevert(abi.encodeWithSelector(OpcodeIOOverflow.selector, 47)); + vm.expectRevert(abi.encodeWithSelector(OpcodeIOOverflow.selector, LibParseError.tagErrorOffset(47))); I_PARSER.unsafeParse(rainlang); } } diff --git a/test/src/lib/parse/LibParseState.endLine.t.sol b/test/src/lib/parse/LibParseState.endLine.t.sol index 219c581c3..2edc6540d 100644 --- a/test/src/lib/parse/LibParseState.endLine.t.sol +++ b/test/src/lib/parse/LibParseState.endLine.t.sol @@ -4,6 +4,7 @@ pragma solidity =0.8.25; import {RainlangExpressionDeployerDeploymentTest} from "test/abstract/RainlangExpressionDeployerDeploymentTest.sol"; import {NotAcceptingInputs} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseStateEndLineTest /// @notice Tests for endLine in LibParseState. @@ -14,7 +15,7 @@ contract LibParseStateEndLineTest is RainlangExpressionDeployerDeploymentTest { function testNotAcceptingInputs() external { // Line 1: "_: 1" has an RHS opcode, so FSM stops accepting inputs. // Line 2: "a:" has only LHS with no RHS — triggers NotAcceptingInputs. - vm.expectRevert(abi.encodeWithSelector(NotAcceptingInputs.selector, 8)); + vm.expectRevert(abi.encodeWithSelector(NotAcceptingInputs.selector, LibParseError.tagErrorOffset(8))); I_PARSER.unsafeParse(bytes("_: 1,\na:;")); } } diff --git a/test/src/lib/parse/LibParseState.pushLiteral.t.sol b/test/src/lib/parse/LibParseState.pushLiteral.t.sol index 134cf26b3..34e148f91 100644 --- a/test/src/lib/parse/LibParseState.pushLiteral.t.sol +++ b/test/src/lib/parse/LibParseState.pushLiteral.t.sol @@ -7,6 +7,7 @@ import {LibParseState, ParseState} from "../../../../src/lib/parse/LibParseState import {LibAllStandardOps} from "../../../../src/lib/op/LibAllStandardOps.sol"; import {LibBytes, Pointer} from "rain.solmem/lib/LibBytes.sol"; import {UnsupportedLiteralType} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseStatePushLiteralTest /// @notice Direct unit tests for pushLiteral. @@ -134,7 +135,7 @@ contract LibParseStatePushLiteralTest is Test { /// Unrecognized literal type should revert with UnsupportedLiteralType. function testPushLiteralUnsupported() external { // 'z' is not a valid literal start character. - vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, LibParseError.tagErrorOffset(0))); this.pushLiteralExternal(bytes("zzz"), 0); } } diff --git a/test/src/lib/parse/LibParseState.pushSubParser.t.sol b/test/src/lib/parse/LibParseState.pushSubParser.t.sol index dfb911837..6e61309b1 100644 --- a/test/src/lib/parse/LibParseState.pushSubParser.t.sol +++ b/test/src/lib/parse/LibParseState.pushSubParser.t.sol @@ -6,6 +6,7 @@ import {Test} from "forge-std/Test.sol"; import {LibParseState, ParseState, SUB_PARSER_POINTER_SHIFT} from "../../../../src/lib/parse/LibParseState.sol"; import {LibBytes, Pointer} from "rain.solmem/lib/LibBytes.sol"; import {InvalidSubParser} from "../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseStatePushSubParserTest /// @notice Tests for pushing sub parsers onto the parse state. @@ -23,7 +24,7 @@ contract LibParseStatePushSubParserTest is Test { value = bound(value, uint256(type(uint160).max) + 1, type(uint256).max); state.subParsers = 0; - vm.expectRevert(abi.encodeWithSelector(InvalidSubParser.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(InvalidSubParser.selector, LibParseError.tagErrorOffset(0))); this.pushSubParserExternal(state, bytes32(value)); } diff --git a/test/src/lib/parse/LibSubParse.subParseLiteral.t.sol b/test/src/lib/parse/LibSubParse.subParseLiteral.t.sol index 7fab41198..21a71dba9 100644 --- a/test/src/lib/parse/LibSubParse.subParseLiteral.t.sol +++ b/test/src/lib/parse/LibSubParse.subParseLiteral.t.sol @@ -10,6 +10,7 @@ import {LibBytes} from "rain.solmem/lib/LibBytes.sol"; import {ISubParserV4} from "rain.interpreter.interface/interface/ISubParserV4.sol"; import {UnsupportedLiteralType} from "../../../../src/error/ErrParse.sol"; import {SubParseLiteralDispatchLengthOverflow} from "../../../../src/error/ErrSubParse.sol"; +import {LibParseError} from "../../../../src/lib/parse/LibParseError.sol"; /// @title LibSubParseSubParseLiteralTest /// @notice Direct unit tests for `LibSubParse.subParseLiteral`. @@ -84,7 +85,7 @@ contract LibSubParseSubParseLiteralTest is Test { address[] memory subs = new address[](1); subs[0] = subParser; - vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, LibParseError.tagErrorOffset(0))); this.externalSubParseLiteral(dispatch, body, subs); } @@ -139,7 +140,7 @@ contract LibSubParseSubParseLiteralTest is Test { subs[0] = first; subs[1] = second; - vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, LibParseError.tagErrorOffset(0))); this.externalSubParseLiteral(dispatch, body, subs); } diff --git a/test/src/lib/parse/literal/LibParseLiteral.dispatch.t.sol b/test/src/lib/parse/literal/LibParseLiteral.dispatch.t.sol index 77a974e65..a4af3e88b 100644 --- a/test/src/lib/parse/literal/LibParseLiteral.dispatch.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteral.dispatch.t.sol @@ -7,6 +7,7 @@ import {LibBytes, Pointer} from "rain.solmem/lib/LibBytes.sol"; import {LibParseState, ParseState} from "../../../../../src/lib/parse/LibParseState.sol"; import {LibParseLiteral, UnsupportedLiteralType} from "../../../../../src/lib/parse/literal/LibParseLiteral.sol"; import {UppercaseHexPrefix} from "../../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../../src/lib/parse/LibParseError.sol"; import {LibAllStandardOps} from "../../../../../src/lib/op/LibAllStandardOps.sol"; import {LibDecimalFloat, Float} from "rain.math.float/lib/LibDecimalFloat.sol"; import {ISubParserV4} from "rain.interpreter.interface/interface/ISubParserV4.sol"; @@ -112,7 +113,7 @@ contract LibParseLiteralDispatchTest is Test { /// Uppercase '0X' must revert with UppercaseHexPrefix rather than /// silently parsing as decimal 0. function testTryParseLiteralUppercaseXReverts() external { - vm.expectRevert(abi.encodeWithSelector(UppercaseHexPrefix.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UppercaseHexPrefix.selector, LibParseError.tagErrorOffset(0))); this.externalParseLiteral(bytes("0X ")); } @@ -240,7 +241,7 @@ contract LibParseLiteralDispatchTest is Test { /// parseLiteral reverts with UnsupportedLiteralType for unrecognized head. function testParseLiteralUnsupportedType() external { - vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, LibParseError.tagErrorOffset(0))); this.externalParseLiteral(bytes("@ ")); } @@ -248,7 +249,7 @@ contract LibParseLiteralDispatchTest is Test { /// next byte in memory must route to decimal, not hex. Without a bounds /// check the parser reads past end and sees "0x", incorrectly dispatching /// to the hex parser which reverts with ZeroLengthHexLiteral. - function testTryParseLiteralOOBSecondBytePoison() external { + function testTryParseLiteralOOBSecondBytePoison() external view { // Allocate data "0" then immediately write 0x78 ('x') right after // the data in memory. end = cursor+1 (just the "0" byte), but // mload(cursor) reads 32 bytes so byte(1, word) picks up the 'x'. diff --git a/test/src/lib/parse/literal/LibParseLiteralDecimal.parseDecimalFloat.t.sol b/test/src/lib/parse/literal/LibParseLiteralDecimal.parseDecimalFloat.t.sol index dfeb539be..a995757d6 100644 --- a/test/src/lib/parse/literal/LibParseLiteralDecimal.parseDecimalFloat.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteralDecimal.parseDecimalFloat.t.sol @@ -15,6 +15,7 @@ import { MalformedDecimalPoint } from "rain.math.float/error/ErrParse.sol"; import {Float, LibDecimalFloat} from "rain.math.float/lib/LibDecimalFloat.sol"; +import {LibParseError} from "../../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseLiteralDecimalParseDecimalFloatTest /// @notice Tests for parsing decimal float literals. @@ -116,91 +117,123 @@ contract LibParseLiteralDecimalParseDecimalFloatTest is Test { /// An empty string should revert. function testParseLiteralDecimalFloatEmpty() external { - checkParseDecimalRevert("", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + "", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// A non decimal string should revert. function testParseLiteralDecimalFloatNonDecimal() external { - checkParseDecimalRevert("hello", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + "hello", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// e without a number should revert. function testParseLiteralDecimalFloatExponentRevert() external { - checkParseDecimalRevert("e", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + "e", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// e with a left digit but not right should revert. function testParseLiteralDecimalFloatExponentRevert2() external { - checkParseDecimalRevert("1e", abi.encodeWithSelector(MalformedExponentDigits.selector, 2)); + checkParseDecimalRevert( + "1e", abi.encodeWithSelector(MalformedExponentDigits.selector, LibParseError.tagErrorOffset(2)) + ); } /// e with a left digit but not right should revert. Add a negative sign. function testParseLiteralDecimalFloatExponentRevert3() external { - checkParseDecimalRevert("1e-", abi.encodeWithSelector(MalformedExponentDigits.selector, 3)); + checkParseDecimalRevert( + "1e-", abi.encodeWithSelector(MalformedExponentDigits.selector, LibParseError.tagErrorOffset(3)) + ); } /// e with a right digit but not left should revert. function testParseLiteralDecimalFloatExponentRevert4() external { - checkParseDecimalRevert("e1", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + "e1", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// e with a right digit but not left should revert. /// two digits. function testParseLiteralDecimalFloatExponentRevert5() external { - checkParseDecimalRevert("e10", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + "e10", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// e with a right digit but not left should revert. /// two digits with negative sign. function testParseLiteralDecimalFloatExponentRevert6() external { - checkParseDecimalRevert("e-10", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + "e-10", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// Dot without digits should revert. function testParseLiteralDecimalFloatDotRevert() external { - checkParseDecimalRevert(".", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + ".", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// Dot without leading digits should revert. function testParseLiteralDecimalFloatDotRevert2() external { - checkParseDecimalRevert(".1", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + ".1", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// Dot without trailing digits should revert. function testParseLiteralDecimalFloatDotRevert3() external { - checkParseDecimalRevert("1.", abi.encodeWithSelector(MalformedDecimalPoint.selector, 2)); + checkParseDecimalRevert( + "1.", abi.encodeWithSelector(MalformedDecimalPoint.selector, LibParseError.tagErrorOffset(2)) + ); } /// Dot e is an error. function testParseLiteralDecimalFloatDotE() external { - checkParseDecimalRevert(".e", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + ".e", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// Dot e0 is an error. function testParseLiteralDecimalFloatDotE0() external { - checkParseDecimalRevert(".e0", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + ".e0", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// e dot is an error. function testParseLiteralDecimalFloatEDot() external { - checkParseDecimalRevert("e.", abi.encodeWithSelector(ParseEmptyDecimalString.selector, 0)); + checkParseDecimalRevert( + "e.", abi.encodeWithSelector(ParseEmptyDecimalString.selector, LibParseError.tagErrorOffset(0)) + ); } /// Negative e with no digits is an error. function testParseLiteralDecimalFloatNegativeE() external { - checkParseDecimalRevert("0.0e-", abi.encodeWithSelector(MalformedExponentDigits.selector, 5)); + checkParseDecimalRevert( + "0.0e-", abi.encodeWithSelector(MalformedExponentDigits.selector, LibParseError.tagErrorOffset(5)) + ); } /// Negative frac is an error. function testParseLiteralDecimalFloatNegativeFrac() external { - checkParseDecimalRevert("0.-1", abi.encodeWithSelector(MalformedDecimalPoint.selector, 2)); + checkParseDecimalRevert( + "0.-1", abi.encodeWithSelector(MalformedDecimalPoint.selector, LibParseError.tagErrorOffset(2)) + ); } /// Can't have more than max total precision. Add decimals after the max int. function testParseLiteralDecimalFloatPrecisionRevert0() external { checkParseDecimalRevert( "57896044618658097711785492504343953926634992332820282019728792003956564819967.1", - abi.encodeWithSelector(ParseDecimalPrecisionLoss.selector, 79) + abi.encodeWithSelector(ParseDecimalPrecisionLoss.selector, LibParseError.tagErrorOffset(79)) ); } @@ -209,7 +242,7 @@ contract LibParseLiteralDecimalParseDecimalFloatTest is Test { function testParseLiteralDecimalFloatPrecisionRevert1() external { checkParseDecimalRevert( "1.57896044618658097711785492504343953926634992332820282019728792003956564819967", - abi.encodeWithSelector(ParseDecimalPrecisionLoss.selector, 79) + abi.encodeWithSelector(ParseDecimalPrecisionLoss.selector, LibParseError.tagErrorOffset(79)) ); } } diff --git a/test/src/lib/parse/literal/LibParseLiteralHex.parseHex.t.sol b/test/src/lib/parse/literal/LibParseLiteralHex.parseHex.t.sol index b94a60ec4..a54a326ec 100644 --- a/test/src/lib/parse/literal/LibParseLiteralHex.parseHex.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteralHex.parseHex.t.sol @@ -8,6 +8,7 @@ import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol"; import {LibParseState, ParseState} from "../../../../../src/lib/parse/LibParseState.sol"; import {LibParseLiteralHex} from "../../../../../src/lib/parse/literal/LibParseLiteralHex.sol"; import {HexLiteralOverflow, ZeroLengthHexLiteral, OddLengthHexLiteral} from "../../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseLiteralHexParseHexTest /// @notice Tests parsing hex literals with LibParseLiteralHex. @@ -37,7 +38,7 @@ contract LibParseLiteralHexParseHexTest is Test { bytes memory data = bytes("0x00000000000000000000000000000000000000000000000000000000000000000a"); // Offset 2: the hex digits start after the "0x" prefix. - vm.expectRevert(abi.encodeWithSelector(HexLiteralOverflow.selector, 2)); + vm.expectRevert(abi.encodeWithSelector(HexLiteralOverflow.selector, LibParseError.tagErrorOffset(2))); this.externalParseHex(data); } @@ -55,7 +56,7 @@ contract LibParseLiteralHexParseHexTest is Test { //forge-lint: disable-next-line(unsafe-typecast) bytes memory data = abi.encodePacked(bytes2("0x"), bytes1(trailingByte)); - vm.expectRevert(abi.encodeWithSelector(ZeroLengthHexLiteral.selector, 2)); + vm.expectRevert(abi.encodeWithSelector(ZeroLengthHexLiteral.selector, LibParseError.tagErrorOffset(2))); this.externalParseHex(data); } @@ -74,7 +75,7 @@ contract LibParseLiteralHexParseHexTest is Test { data[i + 2] = "a"; } - vm.expectRevert(abi.encodeWithSelector(OddLengthHexLiteral.selector, 2)); + vm.expectRevert(abi.encodeWithSelector(OddLengthHexLiteral.selector, LibParseError.tagErrorOffset(2))); this.externalParseHex(data); } diff --git a/test/src/lib/parse/literal/LibParseLiteralString.boundString.t.sol b/test/src/lib/parse/literal/LibParseLiteralString.boundString.t.sol index c3b188b64..fdf4a6f57 100644 --- a/test/src/lib/parse/literal/LibParseLiteralString.boundString.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteralString.boundString.t.sol @@ -7,6 +7,7 @@ import {LibBytes, Pointer} from "rain.solmem/lib/LibBytes.sol"; import {LibParseLiteralString} from "../../../../../src/lib/parse/literal/LibParseLiteralString.sol"; import {LibConformString} from "rain.string/lib/mut/LibConformString.sol"; import {StringTooLong, UnclosedStringLiteral} from "../../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../../src/lib/parse/LibParseError.sol"; import {LibParseState, ParseState} from "../../../../../src/lib/parse/LibParseState.sol"; import {LibAllStandardOps} from "../../../../../src/lib/op/LibAllStandardOps.sol"; @@ -71,7 +72,7 @@ contract LibParseLiteralStringBoundTest is Test { vm.assume(bytes(str).length >= 0x20); LibConformString.conformValidPrintableStringContent(str); - vm.expectRevert(abi.encodeWithSelector(StringTooLong.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(StringTooLong.selector, LibParseError.tagErrorOffset(0))); checkStringBounds(string.concat("\"", str, "\""), 0, 0, 0); } @@ -82,7 +83,9 @@ contract LibParseLiteralStringBoundTest is Test { badIndex = bound(badIndex, 0, (bytes(str).length > 0x1F ? 0x1F : bytes(str).length) - 1); LibConformString.corruptSingleChar(str, badIndex); - vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, 1 + badIndex)); + vm.expectRevert( + abi.encodeWithSelector(UnclosedStringLiteral.selector, LibParseError.tagErrorOffset(1 + badIndex)) + ); checkStringBounds(string.concat("\"", str, "\""), 0, 0, 0); } @@ -94,7 +97,7 @@ contract LibParseLiteralStringBoundTest is Test { str = string.concat("\"", str, "\""); length = bound(length, 1, bytes(str).length - 1); - vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, length)); + vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, LibParseError.tagErrorOffset(length))); (uint256 outerStart, uint256 innerStart, uint256 innerEnd, uint256 outerEnd) = this.externalBoundLiteralForceLength(bytes(str), length); (outerStart, innerStart, innerEnd, outerEnd); @@ -106,7 +109,7 @@ contract LibParseLiteralStringBoundTest is Test { // "hi" — length 4. Force length to 3 so end points at the closing ". // innerEnd scans "hi" (2 chars), lands at offset 3 which equals end. bytes memory data = bytes("\"hi\""); - vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, 3)); + vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, LibParseError.tagErrorOffset(3))); this.externalBoundLiteralForceLength(data, 3); } @@ -118,7 +121,7 @@ contract LibParseLiteralStringBoundTest is Test { bytes memory data = bytes(string.concat("\"", str, "\"")); // Force length to data.length - 1, placing end at the closing ". uint256 length = data.length - 1; - vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, length)); + vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, LibParseError.tagErrorOffset(length))); this.externalBoundLiteralForceLength(data, length); } } diff --git a/test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol b/test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol index 644f024e2..d0409963b 100644 --- a/test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteralString.parseString.t.sol @@ -10,6 +10,7 @@ import {LibParseState, ParseState} from "../../../../../src/lib/parse/LibParseSt import {CMASK_STRING_LITERAL_TAIL} from "rain.string/lib/parse/LibParseCMask.sol"; import {LibConformString} from "rain.string/lib/mut/LibConformString.sol"; import {UnclosedStringLiteral} from "../../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../../src/lib/parse/LibParseError.sol"; /// @title LibParseLiteralStringTest /// @notice Tests parsing strings with the LibParseLiteral library. @@ -77,7 +78,9 @@ contract LibParseLiteralStringTest is Test { ParseState memory state = LibParseState.newState(bytes(string.concat("\"", string(data), "\"")), "", "", ""); - vm.expectRevert(abi.encodeWithSelector(UnclosedStringLiteral.selector, 1 + corruptIndex)); + vm.expectRevert( + abi.encodeWithSelector(UnclosedStringLiteral.selector, LibParseError.tagErrorOffset(1 + corruptIndex)) + ); (uint256 cursorAfter, bytes32 value) = this.parseStringExternal(state); (cursorAfter, value); } diff --git a/test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol b/test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol index 0e85a884c..fb768fe9b 100644 --- a/test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol +++ b/test/src/lib/parse/literal/LibParseLiteralSubParseable.parseSubParseable.t.sol @@ -11,6 +11,7 @@ import { SubParseableMissingDispatch, UnsupportedLiteralType } from "../../../../../src/error/ErrParse.sol"; +import {LibParseError} from "../../../../../src/lib/parse/LibParseError.sol"; import {ISubParserV4} from "rain.interpreter.interface/interface/ISubParserV4.sol"; import {LibConformString} from "rain.string/lib/mut/LibConformString.sol"; import {CMASK_WHITESPACE, CMASK_SUB_PARSEABLE_LITERAL_END} from "rain.string/lib/parse/LibParseCMask.sol"; @@ -65,48 +66,66 @@ contract LibParseLiteralSubParseableTest is Test { /// An unclosed sub parseable literal is an error. function testParseLiteralSubParseableUnclosedDispatch0() external { - checkParseSubParseableError("[a", abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, 2)); + checkParseSubParseableError( + "[a", abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, LibParseError.tagErrorOffset(2)) + ); } /// Leading whitespace is not allowed. function testParseLiteralSubParseableUnclosedDispatchWhitespace1() external { - checkParseSubParseableError("[ a", abi.encodeWithSelector(SubParseableMissingDispatch.selector, 1)); + checkParseSubParseableError( + "[ a", abi.encodeWithSelector(SubParseableMissingDispatch.selector, LibParseError.tagErrorOffset(1)) + ); } /// An unclosed sub parseable literal is an error. function testParseLiteralSubParseableUnclosedDispatchWhitespace0() external { - checkParseSubParseableError("[a ", abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, 3)); + checkParseSubParseableError( + "[a ", abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, LibParseError.tagErrorOffset(3)) + ); } /// An unclosed sub parseable literal is an error. /// Tests with a body. function testParseLiteralSubParseableUnclosedDispatchBody() external { - checkParseSubParseableError("[a b", abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, 4)); + checkParseSubParseableError( + "[a b", abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, LibParseError.tagErrorOffset(4)) + ); } /// An unclosed sub parseable literal is an error. function testParseLiteralSubParseableUnclosedDoubleOpen() external { - checkParseSubParseableError("[[", abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, 2)); + checkParseSubParseableError( + "[[", abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, LibParseError.tagErrorOffset(2)) + ); } /// An empty sub parseable literal is an error. function testParseLiteralSubParseableMissingDispatchEmpty() external { - checkParseSubParseableError("[]", abi.encodeWithSelector(SubParseableMissingDispatch.selector, 1)); + checkParseSubParseableError( + "[]", abi.encodeWithSelector(SubParseableMissingDispatch.selector, LibParseError.tagErrorOffset(1)) + ); } /// An unclosed sub parseable literal with no dispatch is an error. function testParseLiteralSubParseableMissingDispatchUnclosed() external { - checkParseSubParseableError("[", abi.encodeWithSelector(SubParseableMissingDispatch.selector, 1)); + checkParseSubParseableError( + "[", abi.encodeWithSelector(SubParseableMissingDispatch.selector, LibParseError.tagErrorOffset(1)) + ); } /// An unclosed sub parseable literal with no dispatch is an error. function testParseLiteralSubParseableMissingDispatchUnclosedWhitespace0() external { - checkParseSubParseableError("[ ", abi.encodeWithSelector(SubParseableMissingDispatch.selector, 1)); + checkParseSubParseableError( + "[ ", abi.encodeWithSelector(SubParseableMissingDispatch.selector, LibParseError.tagErrorOffset(1)) + ); } /// An unclosed sub parseable literal with no dispatch is an error. function testParseLiteralSubParseableMissingDispatchUnclosedWhitespace1() external { - checkParseSubParseableError("[ ", abi.encodeWithSelector(SubParseableMissingDispatch.selector, 1)); + checkParseSubParseableError( + "[ ", abi.encodeWithSelector(SubParseableMissingDispatch.selector, LibParseError.tagErrorOffset(1)) + ); } /// A dispatch with an empty body is allowed. Trailing whitespace is ignored. @@ -186,7 +205,7 @@ contract LibParseLiteralSubParseableTest is Test { /// then shrink its length by 1 so `]` is still in memory but logically /// past the end of the data. function testParseLiteralSubParseableUnclosedBracketPastEnd() external { - vm.expectRevert(abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, 4)); + vm.expectRevert(abi.encodeWithSelector(UnclosedSubParseableLiteral.selector, LibParseError.tagErrorOffset(4))); this.parseSubParseableBracketPastEnd(bytes("[a b]")); } @@ -242,7 +261,7 @@ contract LibParseLiteralSubParseableTest is Test { mockSubParseLiteral(first, false, bytes32(0)); mockSubParseLiteral(second, false, bytes32(0)); - vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, 1)); + vm.expectRevert(abi.encodeWithSelector(UnsupportedLiteralType.selector, LibParseError.tagErrorOffset(1))); this.externalParseWithTwoSubParsers(bytes("[foo]"), first, second); } }