diff --git a/.github/workflows/ci-deep.yml b/.github/workflows/ci-deep.yml index d075179c..068877b3 100644 --- a/.github/workflows/ci-deep.yml +++ b/.github/workflows/ci-deep.yml @@ -37,7 +37,6 @@ jobs: uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main" with: foundry-fuzz-runs: ${{ fromJSON(inputs.integrationFuzzRuns || '100000') }} - foundry-profile: "test-optimized" match-path: "tests/integration/**/*.sol" name: "Integration tests" @@ -47,7 +46,6 @@ jobs: with: foundry-invariant-depth: ${{ fromJSON(inputs.invariantDepth || '200') }} foundry-invariant-runs: ${{ fromJSON(inputs.invariantRuns || '50000') }} - foundry-profile: "test-optimized" match-path: "tests/invariant/**/*.sol" name: "Invariant tests" @@ -58,7 +56,6 @@ jobs: uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main" with: foundry-fuzz-runs: ${{ fromJSON(inputs.forkFuzzRuns || '20') }} - foundry-profile: "test-optimized" match-path: "tests/fork/**/*.sol" name: "Fork tests" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8964975..4a4336cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,6 @@ jobs: uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main" with: foundry-fuzz-runs: 10000 - foundry-profile: "test-optimized" match-path: "tests/integration/**/*.sol" name: "Integration tests" @@ -40,7 +39,6 @@ jobs: with: foundry-invariant-depth: 100 foundry-invariant-runs: 1000 - foundry-profile: "test-optimized" match-path: "tests/invariant/**/*.sol" name: "Invariant tests" @@ -51,7 +49,6 @@ jobs: uses: "sablier-labs/reusable-workflows/.github/workflows/forge-test.yml@main" with: foundry-fuzz-runs: 20 - foundry-profile: "test-optimized" match-path: "tests/fork/**/*.sol" name: "Fork tests" diff --git a/.gitignore b/.gitignore index 13a236df..382229c0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,6 @@ coverage docs node_modules out -out-optimized -out-svg # files *.env diff --git a/.prettierignore b/.prettierignore index 0fba7f6e..68315fa6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,8 +6,6 @@ coverage docs node_modules out -out-optimized -out-svg # files *.env diff --git a/benchmark/results/SablierFlow.md b/benchmark/results/SablierFlow.md index 22ced93b..29af4419 100644 --- a/benchmark/results/SablierFlow.md +++ b/benchmark/results/SablierFlow.md @@ -2,16 +2,16 @@ | Function | Gas Usage | | ----------------------------- | --------- | -| `adjustRatePerSecond` | 44193 | -| `create` | 113703 | -| `deposit` | 32997 | -| `depositViaBroker` | 22754 | -| `pause` | 7544 | -| `refund` | 22842 | -| `refundMax` | 23840 | -| `restart` | 7058 | -| `void (solvent stream)` | 9982 | -| `void (insolvent stream)` | 37482 | -| `withdraw (insolvent stream)` | 57711 | -| `withdraw (solvent stream)` | 38178 | -| `withdrawMax` | 52010 | +| `adjustRatePerSecond` | 45796 | +| `create` | 113271 | +| `deposit` | 31738 | +| `depositViaBroker` | 20634 | +| `pause` | 7220 | +| `refund` | 22059 | +| `refundMax` | 23128 | +| `restart` | 6660 | +| `void (solvent stream)` | 9658 | +| `void (insolvent stream)` | 37158 | +| `withdraw (insolvent stream)` | 56990 | +| `withdraw (solvent stream)` | 37457 | +| `withdrawMax` | 51364 | diff --git a/foundry.toml b/foundry.toml index 2480c3a2..00972133 100644 --- a/foundry.toml +++ b/foundry.toml @@ -3,7 +3,7 @@ bytecode_hash = "none" evm_version = "shanghai" fs_permissions = [ - { access = "read", path = "./out-optimized" }, + { access = "read", path = "./out" }, { access = "read", path = "package.json" }, { access = "read-write", path = "./benchmark/results"}, { access = "read-write", path = "./script"} @@ -11,17 +11,18 @@ gas_limit = 9223372036854775807 gas_reports = ["SablierFlow"] optimizer = true - optimizer_runs = 1000 + optimizer_runs = 10_000 out = "out" script = "script" sender = "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38" solc = "0.8.26" src = "src" test = "tests" + via_ir = true [profile.default.fuzz] max_test_rejects = 1_000_000 # Number of times `vm.assume` can fail - runs = 10000 + runs = 10_000 [profile.default.invariant] call_override = false # Override unsafe external calls to perform reentrancy checks @@ -31,6 +32,15 @@ runs = 1000 shrink_run_limit = 0 # Disable shrinking of a failed sequence +additional_compiler_profiles = [ + { name = "tests/", via_ir = false } +] + +compilation_restrictions = [ + { paths = "tests/mocks", via_ir = true }, + { paths = "tests/**", via_ir = false } +] + # Run only the code inside benchmark directory [profile.benchmark] test = "benchmark" @@ -38,6 +48,7 @@ # Speed up compilation and tests during development [profile.lite] optimizer = false + via_ir = false [profile.lite.invariant] depth = 50 @@ -46,18 +57,6 @@ [profile.lite.fuzz] runs = 20 -# Compile only the production code and the test mocks with via IR and 10,000 optimizer runs -[profile.optimized] - optimizer = true - optimizer_runs = 10_000 - out = "out-optimized" - test = "tests/mocks" - via_ir = true - -# Test the optimized contracts without re-compiling them -[profile.test-optimized] - src = "tests" - [doc] ignore = ["**/*.t.sol"] out = "docs" diff --git a/package.json b/package.json index ce075778..1e13814a 100644 --- a/package.json +++ b/package.json @@ -57,10 +57,9 @@ "access": "restricted" }, "scripts": { - "benchmark": "bun run build:optimized && FOUNDRY_PROFILE=benchmark forge test --mt testGas && bun run prettier:write", + "benchmark": "bun run build && FOUNDRY_PROFILE=benchmark forge test --mt testGas && bun run prettier:write", "build": "forge build", - "build:optimized": "FOUNDRY_PROFILE=optimized forge build", - "clean": "rm -rf artifacts broadcast cache docs out out-optimized out-svg", + "clean": "rm -rf artifacts broadcast cache docs out", "lint": "bun run lint:sol && bun run prettier:check", "lint:fix": "bun run lint:sol:fix && forge fmt", "lint:sol": "forge fmt --check && bun solhint \"{benchmark,precompiles,script,src,tests}/**/*.sol\"", @@ -70,7 +69,6 @@ "prettier:check": "prettier --check \"**/*.{json,md,svg,yml}\"", "prettier:write": "prettier --write \"**/*.{json,md,svg,yml}\"", "test": "forge test", - "test:lite": "FOUNDRY_PROFILE=lite forge test --nmt \"testFork\"", - "test:optimized": "bun run build:optimized && FOUNDRY_PROFILE=test-optimized forge test" + "test:lite": "FOUNDRY_PROFILE=lite forge test --nmt \"testFork\" --nmc \"Precompiles_Test\"" } } diff --git a/precompiles/Precompiles.sol b/precompiles/Precompiles.sol index 43c8f140..b581514a 100644 --- a/precompiles/Precompiles.sol +++ b/precompiles/Precompiles.sol @@ -13,10 +13,10 @@ import { ISablierFlow } from "./../src/interfaces/ISablierFlow.sol"; /// but allows for execution in test environments, such as a local development network or a testnet. contract Precompiles { bytes public constant BYTECODE_FLOW = - hex"60a0604052346103a957614b956040813803918261001c816103ad565b9384928339810103126103a95780516001600160a01b03811691908290036103a957602001516001600160a01b038116908190036103a95761005e60406103ad565b91601083526f14d8589b1a595c88119b1bddc813919560821b602084015261008660406103ad565b60088152675341422d464c4f5760c01b60208201523060805283519092906001600160401b0381116102ba57600154600181811c9116801561039f575b602082101461029c57601f811161033c575b50602094601f82116001146102d9579481929394955f926102ce575b50508160011b915f199060031b1c1916176001555b82516001600160401b0381116102ba57600254600181811c911680156102b0575b602082101461029c57601f8111610239575b506020601f82116001146101d657819293945f926101cb575b50508160011b915f199060031b1c1916176002555b60016008555f80546001600160a01b031990811684178255600980549091169290921790915560405191907fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf808180a36147c290816103d38239608051816131510152f35b015190505f80610152565b601f1982169060025f52805f20915f5b81811061022157509583600195969710610209575b505050811b01600255610167565b01515f1960f88460031b161c191690555f80806101fb565b9192602060018192868b0151815501940192016101e6565b60025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace601f830160051c81019160208410610292575b601f0160051c01905b8181106102875750610139565b5f815560010161027a565b9091508190610271565b634e487b7160e01b5f52602260045260245ffd5b90607f1690610127565b634e487b7160e01b5f52604160045260245ffd5b015190505f806100f1565b601f1982169560015f52805f20915f5b8881106103245750836001959697981061030c575b505050811b01600155610106565b01515f1960f88460031b161c191690555f80806102fe565b919260206001819286850151815501940192016102e9565b60015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f830160051c81019160208410610395575b601f0160051c01905b81811061038a57506100d5565b5f815560010161037d565b9091508190610374565b90607f16906100c3565b5f80fd5b6040519190601f01601f191682016001600160401b038111838210176102ba5760405256fe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a7146127675750806306fdde03146126ac578063081812fc1461268e57806308b8792314612654578063095ea7b3146125375780630c5fd195146124ed5780630c69962414612461578063136439dd146123c95780631400ecec1461238f5780631e010439146123385780631e897afb1461220f5780631e99d569146121f25780631f0cce58146120e357806323b872dd146120cc578063379d871a1461202b57806342842e0e1461200257806342e3e23d146108665780634426757014611fdc578063450ac90814611f94578063569f4c5914611f44578063597150fa14611efc5780635ea2145b14611c295780635f55315214611bf15780636352211e14611bc2578063648bf77414611a695780636d0cee7514611a1b57806370a08231146119b157806375829def1461192b5780637cad6cd11461182d5780637ddf9228146117f357806380448da3146117ab57806381632a861461171f578063894e9a0d1461157257806395d89b4114611433578063a22cb46514611361578063a7de07cd14611313578063a8a482a614611208578063ad35efd414611190578063b256456914611140578063b5b3ca2c14610fe5578063b61f758314610f42578063b62b31e414610f0a578063b88d4fde14610e80578063b8a3be6614610e4b578063b971302a14610dfa578063bc063e1a14610dd8578063bc7a2d6c14610d9e578063bcbd019e14610cc8578063bdf2a43c14610c7f578063c2f8e75014610a2a578063c87b56dd14610918578063d4b808841461089e578063d975dfed14610866578063e4b50cb814610815578063e985e9c5146107bc578063ea5ead1914610745578063eb5710d8146106c8578063ebb6f79a14610591578063f851a4401461056c578063fbf2777e146104ec578063fdd46d60146104155763ffe3d9f8146102c6575f80fd5b34610411576040600319360112610411576102df61289a565b6102e76128b0565b6001600160a01b035f54163381036103e257506001600160a01b03821691825f52600b6020526fffffffffffffffffffffffffffffffff60405f2054169081156103b657818361037a92865f52600b60205260405f207fffffffffffffffffffffffffffffffff000000000000000000000000000000008154169055865f52600760205260405f20838154039055613cc3565b6001600160a01b036040519216825260208201527fc9a4a66b97fd7e52e69c5be7b10bdc5341bded817201b9b7136a75068d4e4e0560403392a3005b837ff717901b000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7fc6cce6a4000000000000000000000000000000000000000000000000000000005f526004523360245260445ffd5b5f80fd5b34610411576060600319360112610411576004356104316128b0565b610439612911565b90610442613147565b825f52600c60205260ff600160405f20015460c81c16156104c05761048c83927ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce792602095613fe5565b939092604051908152a1604080516fffffffffffffffffffffffffffffffff928316815292909116602083015290f35b0390f35b827fe21c1431000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b346104115760c06003193601126104115761050561289a565b61050d6128b0565b90610516612911565b9161051f6128dc565b9161052861296a565b60a435936fffffffffffffffffffffffffffffffff85168503610411576020956105649461055d94610558613147565b6136e3565b9182613597565b604051908152f35b34610411575f6003193601126104115760206001600160a01b035f5416604051908152f35b34610411576040600319360112610411576004356105ad6128f2565b6105b5613147565b815f52600c60205260ff600160405f20015460c81c161561069c57815f52600c60205260ff600160405f20015460d81c1661067057815f52600c6020526001600160a01b03600160405f20015416330361064057816106376020927ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79461350e565b604051908152a1005b507fa9ad2a22000000000000000000000000000000000000000000000000000000005f526004523360245260445ffd5b507f7354d5f1000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b507fe21c1431000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c602052602064ffffffffff600160405f20015460a01c16604051908152f35b7fe21c1431000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b34610411576040600319360112610411576004356107616128b0565b610769613147565b815f52600c60205260ff600160405f20015460c81c161561069c57907ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce761048c6020936107b58461369f565b9084613fe5565b34610411576040600319360112610411576107d561289a565b6001600160a01b036107e56128b0565b91165f5260066020526001600160a01b0360405f2091165f52602052602060ff60405f2054166040519015158152f35b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c60205260206001600160a01b03600260405f20015416604051908152f35b34610411576020600319360112610411576020610884600435612d45565b6fffffffffffffffffffffffffffffffff60405191168152f35b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a57805f52600c60205260405f205460801c156108ed57610564602091612fc0565b7f167274c9000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b3461041157602060031936011261041157600435610935816130b9565b505f6001600160a01b0360095416916044604051809481937fe9dc637500000000000000000000000000000000000000000000000000000000835230600484015260248301525afa8015610a1f575f906109a2575b6104bc90604051918291602083526020830190612857565b503d805f833e6109b28183612996565b8101906020818303126104115780519067ffffffffffffffff821161041157019080601f83011215610411578151916109ea836129d7565b916109f86040519384612996565b83835260208483010111610411576104bc92610a1a9160208085019101612836565b61098a565b6040513d5f823e3d90fd5b346104115760c060031936011261041157600435610a466128f2565b610a4e6128c6565b610a566128dc565b60407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261041157610a88613147565b835f52600c60205260ff600160405f20015460c81c1615610c5357835f52600c60205260ff600160405f20015460d81c16610c2757610ac79184613eda565b604051916040830183811067ffffffffffffffff821117610bfa576040526084356001600160a01b038116810361041157835260a435602084019080825267016345785d8a00008111610bc357506001600160a01b0384511615610b9b577ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce793610b64610b5b6020956106379451906145df565b85929192613597565b835f52600c85526fffffffffffffffffffffffffffffffff6001600160a01b0380600260405f200154169351169116913390614429565b7f5f946a02000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f54b392b2000000000000000000000000000000000000000000000000000000005f5260045267016345785d8a000060245260445ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b837f7354d5f1000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b837fe21c1431000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c602052602060405f205460801c15604051908152f35b3461041157604060031936011261041157600435610ce46128f2565b610cec613147565b815f52600c60205260ff600160405f20015460c81c161561069c57815f52600c60205260405f205460801c15610d7257815f52600c6020526001600160a01b03600160405f2001541633036106405781610d696020927ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce794613597565b610637816133da565b507f167274c9000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a57610564602091613ea0565b34610411575f60031936011261041157602060405167016345785d8a00008152f35b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c60205260206001600160a01b03600160405f20015416604051908152f35b34610411576020600319360112610411576004355f52600c602052602060ff600160405f20015460c81c166040519015158152f35b3461041157608060031936011261041157610e9961289a565b610ea16128b0565b6064359167ffffffffffffffff8311610411573660238401121561041157826004013591610ece836129d7565b92610edc6040519485612996565b8084523660248287010111610411576020815f926024610f089801838801378501015260443591612dd4565b005b34610411576020600319360112610411576001600160a01b03610f2b61289a565b165f52600a602052602060405f2054604051908152f35b3461041157608060031936011261041157600435610f5e6128f2565b610f666128c6565b610f6e6128dc565b90610f77613147565b835f52600c60205260ff600160405f20015460c81c1615610c5357835f52600c60205260ff600160405f20015460d81c16610c2757602092610fdf8593610637937ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce797613eda565b82613597565b3461041157604060031936011261041157610ffe61289a565b602435906001600160a01b035f54163381036103e2575067016345785d8a00008211611108576001600160a01b031690815f52600a60205260405f205490825f52600a6020528060405f205560405191825260208201527f371789a3d97098f3070492613273a065a7e8a19e009fd1ae92a4b4d4c71ed62d60403392a36008547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116110db5760407f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91815190600182526020820152a1005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b507f34553172000000000000000000000000000000000000000000000000000000005f5260045267016345785d8a000060245260445ffd5b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c602052602060ff600160405f20015460d01c166040519015158152f35b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a576111c890612d79565b60405160058210156111db576020918152f35b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b34610411576040600319360112610411576004356112246128f2565b61122c613147565b815f52600c60205260ff600160405f20015460c81c161561069c57815f52600c60205260405f205460801c15610d7257815f52600c6020526001600160a01b03600160405f2001541633036106405781807ffddf01d0842635e80929251f6862b3baf136a29f2b2fb148968e8b236d5785fe60606020947ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7965f52600c86526fffffffffffffffffffffffffffffffff60405f205460801c916112ef8187613d6f565b6112f886613105565b9260405193845288840152166040820152a2604051908152a1005b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c602052602060ff600260405f20015460a01c16604051908152f35b346104115760406003193601126104115761137a61289a565b60243590811515809203610411576001600160a01b031690811561140757335f52600660205260405f20825f5260205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b507f5b08ba18000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b34610411575f600319360112610411576040515f6002548060011c90600181168015611568575b60208310811461153b578285529081156114f9575060011461149b575b6104bc8361148781850382612996565b604051918291602083526020830190612857565b91905060025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace915f905b8082106114df57509091508101602001611487611477565b9192600181602092548385880101520191019092916114c7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660208086019190915291151560051b840190910191506114879050611477565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b91607f169161145a565b34610411576020600319360112610411576004355f61012060405161159681612979565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201520152805f52600c60205260ff600160405f20015460c81c161561071a575f52600c60205260405f206040516115fe81612979565b81546fffffffffffffffffffffffffffffffff811692838352602083019160801c82526001810154604084016001600160a01b0382168152606085018260a01c64ffffffffff16815260808601908360c81c60ff161515825260a08701928460d01c60ff161515845260c088019460d81c60ff161515855260028601549660e08901966001600160a01b03891688526101008a019860a01c60ff168952600301549861012001988952604051998a52516fffffffffffffffffffffffffffffffff1660208a0152516001600160a01b031660408901525164ffffffffff166060880152511515608087015251151560a086015251151560c0850152516001600160a01b031660e08401525160ff166101008301525161012082015261014090f35b346104115760406003193601126104115760043561173b6128f2565b611743613147565b815f52600c60205260ff600160405f20015460c81c161561069c57815f52600c6020526001600160a01b03600160405f20015416330361064057816106376020927ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce794613205565b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c602052602060405f205460801c604051908152f35b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a57610564602091613d1f565b34610411576020600319360112610411576004356001600160a01b038116809103610411576001600160a01b035f54163381036103e2575060095490807fffffffffffffffffffffffff00000000000000000000000000000000000000008316176009556001600160a01b036040519216825260208201527fa2548bd4b805e907c1558a47b5858324fe8bb4a2e1ddfca647eecbf65610eebc60403392a26008547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116110db5760407f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c91815190600182526020820152a1005b346104115760206003193601126104115761194461289a565b5f546001600160a01b0381163381036103e257506001600160a01b037fffffffffffffffffffffffff0000000000000000000000000000000000000000921691829116175f55337fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf805f80a3005b34610411576020600319360112610411576001600160a01b036119d261289a565b1680156119ef575f526004602052602060405f2054604051908152f35b7f89c62b64000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600360205260206001600160a01b0360405f205416604051908152f35b3461041157604060031936011261041157611a8261289a565b611a8a6128b0565b6001600160a01b035f54163381036103e257506001600160a01b038216916040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152602081602481875afa8015610a1f575f90611b8e575b611b029150845f52600760205260405f205490612d6c565b908115611b625781611b397f21252411d5a999da4bc6a490f7143b61ba690edceb4577a2800eab8dfbb1e92c9385611b5d94613cc3565b604051918291339583602090939291936001600160a01b0360408201951681520152565b0390a3005b837ff4c3afcf000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b506020813d602011611bba575b81611ba860209383612996565b8101031261041157611b029051611aea565b3d9150611b9b565b34610411576020600319360112610411576020611be06004356130b9565b6001600160a01b0360405191168152f35b34610411576020600319360112610411576001600160a01b03611c1261289a565b165f526007602052602060405f2054604051908152f35b3461041157602060031936011261041157600435611c45613147565b805f52600c60205260ff600160405f20015460c81c161561071a57805f52600c60205260ff600160405f20015460d81c16611ed157805f52600c6020526001600160a01b03600160405f2001541633141580611ec1575b611e9257602081611ccd7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce793613ea0565b80611e4257611cdb82613d1f565b80611e21575b505b5f828152600c84526040902060010180547fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff164260a01b78ffffffffff000000000000000000000000000000000000000016179055815f52600c835260405f206fffffffffffffffffffffffffffffffff8154169055815f52600c8352600160405f20017b010000000000000000000000000000000000000000000000000000007fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff825416179055815f52600c83526001600160a01b03600160405f20015416825f5260038452827fa8e3d71a6c0c719305004b430f6d17f12536f7b803db23a4d7016f5b52699a8c60606001600160a01b0360405f20541694611e0684613105565b9060405191338352898301526040820152a4604051908152a1005b825f52600c8452611e3a600360405f2001918254612f7c565b905584611ce1565b815f52600c8352611e7e6fffffffffffffffffffffffffffffffff60405f205416835f52600c855260ff600260405f20015460a01c1690613fcc565b825f52600c8452600360405f200155611ce3565b7fa9ad2a22000000000000000000000000000000000000000000000000000000005f526004523360245260445ffd5b50611ecb816144df565b15611c9c565b7f7354d5f1000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b346104115760a0600319360112610411576020610564611f1a61289a565b611f226128b0565b611f2a612911565b611f326128dc565b91611f3b61296a565b93610558613147565b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c602052602060ff600160405f20015460d81c166040519015158152f35b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c6020526020600360405f200154604051908152f35b34610411575f6003193601126104115760206001600160a01b0360095416604051908152f35b3461041157610f0861201336612930565b9060405192612023602085612996565b5f8452612dd4565b34610411576040600319360112610411576004356120476128f2565b61204f613147565b815f52600c60205260ff600160405f20015460c81c161561069c57815f52600c60205260405f205460801c15610d7257815f52600c6020526001600160a01b03600160405f2001541633036106405781610d696020927ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce794613205565b3461041157610f086120dd36612930565b91612a62565b34610411576060600319360112610411576004356120ff6128f2565b612107612911565b90612110613147565b825f52600c60205260ff600160405f20015460c81c16156104c057825f52600c60205260ff600160405f20015460d81c166121c657825f52600c6020526001600160a01b03600160405f2001541633036121965791610637602092610fdf7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7958461350e565b827fa9ad2a22000000000000000000000000000000000000000000000000000000005f526004523360245260445ffd5b827f7354d5f1000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b34610411575f600319360112610411576020600854604051908152f35b346104115760206003193601126104115760043567ffffffffffffffff8111610411573660238201121561041157806004013567ffffffffffffffff8111610411573660248260051b8401011161041157905f907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbd81360301915b83811015610f085760248160051b830101358381121561041157820160248101359067ffffffffffffffff821161041157604401813603811361041157815f92918392604051928392833781018381520390305af46122e7612a33565b90156122f6575060010161228a565b612334906040519182917fd9354485000000000000000000000000000000000000000000000000000000008352602060048401526024830190612857565b0390fd5b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a575f52600c60205260206fffffffffffffffffffffffffffffffff60405f205416604051908152f35b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a576108846020916131d3565b34610411576020600319360112610411576004356123e5613147565b805f52600c60205260ff600160405f20015460c81c161561071a57805f52600c60205260405f205460801c156108ed57805f52600c6020526001600160a01b03600160405f200154163303611e92576020816106377ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7936133da565b346104115760206003193601126104115760043561247d613147565b805f52600c60205260ff600160405f20015460c81c161561071a57805f52600c6020526001600160a01b03600160405f200154163303611e92576020816106376124e77ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7946131d3565b82613205565b34610411576020600319360112610411576001600160a01b0361250e61289a565b165f52600b60205260206fffffffffffffffffffffffffffffffff60405f205416604051908152f35b346104115760406003193601126104115761255061289a565b60243561255c816130b9565b33151580612641575b8061260e575b6125e25781906001600160a01b0380851691167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f80a45f5260056020526001600160a01b0360405f2091167fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790555f80f35b7fa9fbf51f000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b506001600160a01b0381165f52600660205260405f206001600160a01b0333165f5260205260ff60405f2054161561256b565b50336001600160a01b0382161415612565565b3461041157602060031936011261041157600435805f52600c60205260ff600160405f20015460c81c161561071a57610564602091613105565b34610411576020600319360112610411576020611be0600435612a11565b34610411575f600319360112610411576040515f6001548060011c9060018116801561275d575b60208310811461153b578285529081156114f957506001146126ff576104bc8361148781850382612996565b91905060015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6915f905b80821061274357509091508101602001611487611477565b91926001816020925483858801015201910190929161272b565b91607f16916126d3565b3461041157602060031936011261041157600435907fffffffff00000000000000000000000000000000000000000000000000000000821680920361041157817f80ac58cd000000000000000000000000000000000000000000000000000000006020931490811561280c575b81156127e2575b5015158152f35b7f01ffc9a700000000000000000000000000000000000000000000000000000000915014836127db565b7f5b5e139f00000000000000000000000000000000000000000000000000000000811491506127d4565b5f5b8381106128475750505f910152565b8181015183820152602001612838565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209361289381518092818752878088019101612836565b0116010190565b600435906001600160a01b038216820361041157565b602435906001600160a01b038216820361041157565b604435906001600160a01b038216820361041157565b606435906001600160a01b038216820361041157565b602435906fffffffffffffffffffffffffffffffff8216820361041157565b604435906fffffffffffffffffffffffffffffffff8216820361041157565b6003196060910112610411576004356001600160a01b038116810361041157906024356001600160a01b0381168103610411579060443590565b60843590811515820361041157565b610140810190811067ffffffffffffffff821117610bfa57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610bfa57604052565b67ffffffffffffffff8111610bfa57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b612a1a816130b9565b505f5260056020526001600160a01b0360405f20541690565b3d15612a5d573d90612a44826129d7565b91612a526040519384612996565b82523d5f602084013e565b606090565b91906001600160a01b0316918215612d1957815f5260036020526001600160a01b0360405f205416151580612cfc575b612cd057815f5260036020526001600160a01b0360405f2054169233151580612c08575b50907ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce760206001600160a01b039386612b9b575b805f526004825260405f2060018154019055855f526003825260405f20817fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790558560405191887fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4858152a116808303612b6a57505050565b7f64283d7b000000000000000000000000000000000000000000000000000000005f5260045260245260445260645ffd5b612bd2865f52600560205260405f207fffffffffffffffffffffffff00000000000000000000000000000000000000008154169055565b865f526004825260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8154019055612aea565b80612c79575b15612c19575f612ab6565b8284612c4a577f7e273289000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7f177e802f000000000000000000000000000000000000000000000000000000005f523360045260245260445ffd5b503384148015612ca7575b80612c0e5750825f526005602052336001600160a01b0360405f20541614612c0e565b50835f52600660205260405f206001600160a01b0333165f5260205260ff60405f205416612c84565b507f7da2ea2b000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b50815f52600c60205260ff600160405f20015460d01c1615612a92565b7f64a0ae92000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b805f52600c60205260ff600160405f20015460c81c161561071a57612d699061369f565b90565b919082039182116110db57565b805f52600c60205260ff600160405f20015460d81c16612dce57612d9c81613ea0565b1515905f52600c60205260405f205460801c15612dc057612dbb575f90565b600190565b612dc957600290565b600390565b50600490565b90612de0838284612a62565b803b612ded575b50505050565b602091612e4c6001600160a01b038093169560405195869485947f150b7a020000000000000000000000000000000000000000000000000000000086523360048701521660248501526044840152608060648401526084830190612857565b03815f865af15f9181612f1f575b50612ea15750612e68612a33565b80519081612e9c57827f64a0ae92000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b602001fd5b7fffffffff000000000000000000000000000000000000000000000000000000007f150b7a0200000000000000000000000000000000000000000000000000000000911603612ef457505f808080612de7565b7f64a0ae92000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b9091506020813d602011612f74575b81612f3b60209383612996565b8101031261041157517fffffffff000000000000000000000000000000000000000000000000000000008116810361041157905f612e5a565b3d9150612f2e565b919082018092116110db57565b8115612f93570490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b805f52600c6020526fffffffffffffffffffffffffffffffff60405f2054169081156130b357805f52600c60205261300660ff600260405f20015460a01c168093613fcc565b91815f52600c602052613020600360405f20015491613faf565b9061303361302d84613d1f565b82612f7c565b61303d8386612f7c565b11156130ab57825f52600c60205260405f205460801c930301916130618184612f89565b928115612f93570661308a575f52600c60205264ffffffffff600160405f20015460a01c160190565b906001915f52600c60205264ffffffffff8260405f20015460a01c16010190565b505050505f90565b50505f90565b805f5260036020526001600160a01b0360405f2054169081156130da575090565b7f7e273289000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b612d699061312b61311582613d1f565b825f52600c602052600360405f20015490612f7c565b905f52600c60205260ff600260405f20015460a01c1690614409565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361317957565b7fa1c0d6e5000000000000000000000000000000000000000000000000000000005f5260045ffd5b906fffffffffffffffffffffffffffffffff809116911603906fffffffffffffffffffffffffffffffff82116110db57565b612d6990805f52600c6020526131ff6fffffffffffffffffffffffffffffffff60405f2054169161369f565b906131a1565b6fffffffffffffffffffffffffffffffff821680156133ae576fffffffffffffffffffffffffffffffff613238836131d3565b1680821161337c57825f52600c6020526fffffffffffffffffffffffffffffffff60405f2054161061332a5760207fe31f2d40d5780915b1e656a67e11bdf09b0a4a925ec42bbeae220c8ca937ab4991835f52600c8252613321816001600160a01b03600160405f200154168097875f52600c86526001600160a01b03600260405f2001541690885f52600c87526fffffffffffffffffffffffffffffffff8060405f2092818454160316167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055805f526007865260405f20838154039055613cc3565b604051908152a3565b90805f52600c6020526fffffffffffffffffffffffffffffffff60405f205416907fcb5f605f000000000000000000000000000000000000000000000000000000005f5260045260245260445260645ffd5b917fe9771401000000000000000000000000000000000000000000000000000000005f5260045260245260445260645ffd5b507fea66b871000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b805f52600c60205260405f205460801c156134df576133f881613d1f565b806134bd575b505f818152600c6020908152604080832060018101805478ffffffffff00000000000000000000000000000000000000004260a01b167fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff82161790915581546fffffffffffffffffffffffffffffffff16909155600383529220546001600160a01b0390811693921691907fda83bf669c651406e02062769e01d14cccb5625ea685fd95e0e56d29597dac47906134b483613105565b604051908152a4565b815f52600c6020526134d7600360405f2001918254612f7c565b90555f6133fe565b7fd2657d5a000000000000000000000000000000000000000000000000000000005f526004525f60245260445ffd5b805f52600c60205260405f205460801c61356c5761352c8282613d6f565b6fffffffffffffffffffffffffffffffff604051921682527fc2a543cfadbf862642247e28711aaa30e3460384be5712be6557fee3384454fd60203393a3565b7fdc6fbbbc000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b906fffffffffffffffffffffffffffffffff16908115613674575f818152600c60205260409020600281015481546fffffffffffffffffffffffffffffffff9081168501916001600160a01b03169082116110db57613646926fffffffffffffffffffffffffffffffff8693167fffffffffffffffffffffffffffffffff00000000000000000000000000000000825416179055805f52600760205260405f2082815401905530903390614429565b6040519182527fa06c1466b3c9751408a5ac337a2e8808e5ee0ceed1fd70635d041b21174eb6b460203393a3565b7f33f2df5a000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b805f52600c6020526fffffffffffffffffffffffffffffffff60405f2054169081156130b3576136ce90613105565b8082106136df57612d699150614483565b5090565b6001600160a01b039095949293919516908115613c9b576001600160a01b0316926040517f313ce567000000000000000000000000000000000000000000000000000000008152602081600481885afa8015610a1f575f90613c5e575b60ff9150169560128711613c32576008549687866040519261376184612979565b5f845260208401956fffffffffffffffffffffffffffffffff1695868152604085019088825260608601994264ffffffffff168b52608087016001815260a088019115159b8c835260c08901935f855260e08a019788526101008a019687526101208a01985f8a525f52600c60205260405f2099516fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168a547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016178a55516fffffffffffffffffffffffffffffffff1661387a908a906fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffff0000000000000000000000000000000083549260801b169116179055565b9351600189018054955178ffffffffff000000000000000000000000000000000000000060a09190911b166001600160a01b039092167fffffffffffffff00000000000000000000000000000000000000000000000000909616959095171784555115159083549051151560d01b7aff0000000000000000000000000000000000000000000000000000169160c81b79ff0000000000000000000000000000000000000000000000000016907fffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffff161717825551151581549060d81b7bff00000000000000000000000000000000000000000000000000000016907fffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffff161790556002840191516001600160a01b03166001600160a01b031682547fffffffffffffffffffffffff0000000000000000000000000000000000000000161782555181549060a01b74ff000000000000000000000000000000000000000016907fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16179055519060030155600187016008556001600160a01b0316928315612d1957865f5260036020526001600160a01b0360405f205416151580613c15575b613be957865f5260036020526001600160a01b0360405f2054167ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce760208215159283613b7c575b875f526004825260405f20600181540190558a5f526003825260405f20887fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055604051908b89827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f80a4508a8152a1613b50577f2262fa211f8507786a60fefb231f7898b8145fe16350f281c91f121bd2ee118d916060916040519189835260208301526040820152a4565b7f73c6ac6e000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b613bb38b5f52600560205260405f207fffffffffffffffffffffffff00000000000000000000000000000000000000008154169055565b805f526004825260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8154019055613a9e565b867f7da2ea2b000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b50865f52600c60205260ff600160405f20015460d01c1615613a57565b847fc9f55392000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b506020813d602011613c93575b81613c7860209383612996565b81010312610411575160ff811681036104115760ff90613740565b3d9150613c6b565b7ff9bb0fb3000000000000000000000000000000000000000000000000000000005f5260045ffd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000060208201526001600160a01b03929092166024830152604480830193909352918152613d1d91613d18606483612996565b614551565b565b5f908152600c602052604090206001810154905460801c9060a01c64ffffffffff1681158015613d65575b6130b357804203918083029283041490421417156110db5790565b5080421115613d4a565b91906fffffffffffffffffffffffffffffffff811692805f52600c60205260405f205460801c8414613e7057613d1d929350613daa81613d1f565b80613e4e575b505f908152600c6020526040902060018101805478ffffffffff00000000000000000000000000000000000000004260a01b167fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff90911617905580546fffffffffffffffffffffffffffffffff1660809290921b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016919091179055565b815f52600c602052613e68600360405f2001918254612f7c565b90555f613db0565b83907fd2657d5a000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b805f52600c602052613ec86fffffffffffffffffffffffffffffffff60405f20541691613105565b90818110156130b357612d6991612d6c565b90815f52600c6020526001600160a01b0380600160405f200154169116908103613f675750805f5260036020526001600160a01b038060405f2054169216918203613f23575050565b5f5260036020526001600160a01b0360405f205416907f5bdb8ad7000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b905f52600c6020526001600160a01b03600160405f20015416907fc8bac88d000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b601260ff821614613fc65760120360ff16600a0a90565b50600190565b90601260ff8216146136df5760120360ff16600a0a0290565b5f9392916fffffffffffffffffffffffffffffffff83169182156143de576001600160a01b0382169182156143b257815f5260036020526001600160a01b0360405f205416831415806143a2575b61436f57815f52600c60205260ff600260405f20015460a01c169361407061405a84613d1f565b845f52600c602052600360405f20015490612f7c565b61407a8682614409565b95845f52600c6020526fffffffffffffffffffffffffffffffff60405f205416928784105f14614350576fffffffffffffffffffffffffffffffff845b1680821161431d5750906140ca91613fcc565b90845f52600c602052600360405f2001548211155f146142ba5750835f52600c602052600360405f20019081540390555b5f838152600c6020908152604080832080546fffffffffffffffffffffffffffffffff8082168c9003167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116178155600201546001600160a01b0316808452600a909252909120549095908061424c575b506141cc6141b66fffffffffffffffffffffffffffffffff926141a7848b1680978b5f52600760205260405f208281540390558b613cc3565b6141b087613105565b90612d6c565b92855f52600c6020528260405f205416906131a1565b160361421f5760607f1a7b0d6c8f96b874563b711cf97793fe3be5dc42dbd1e0720ce40f326918e817916040519033825260208201526fffffffffffffffffffffffffffffffff89166040820152a49190565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b6141b699506142706141cc916fffffffffffffffffffffffffffffffff93996145df565b9a909a988b895f52600b602052848060405f2092818454160116167fffffffffffffffffffffffffffffffff0000000000000000000000000000000082541617905592505061416e565b5f858152600c60205260409020919003600382015560010180547fffffffffffffff0000000000ffffffffffffffffffffffffffffffffffffffff164260a01b78ffffffffff0000000000000000000000000000000000000000161790556140fb565b90867ff9f29859000000000000000000000000000000000000000000000000000000005f5260045260245260445260645ffd5b6fffffffffffffffffffffffffffffffff61436a89614483565b6140b7565b507f4208ab4c000000000000000000000000000000000000000000000000000000005f526004523360245260445260645ffd5b506143ac826144df565b15614033565b507f9f32c858000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b7fb4855052000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b90601260ff8216146136df579060ff612d699260120316600a0a90612f89565b9091926001600160a01b03613d1d9481604051957f23b872dd000000000000000000000000000000000000000000000000000000006020880152166024860152166044840152606483015260648252613d18608483612996565b6fffffffffffffffffffffffffffffffff81116144af576fffffffffffffffffffffffffffffffff1690565b7f6dfcc650000000000000000000000000000000000000000000000000000000005f52608060045260245260445ffd5b805f5260036020526001600160a01b0360405f20541690813314918215614525575b50811561450c575090565b90506001600160a01b036145203392612a11565b161490565b9091505f52600660205260405f206001600160a01b0333165f5260205260ff60405f205416905f614501565b5f806001600160a01b0361457a93169360208151910182865af1614573612a33565b9083614729565b80519081151591826145bb575b50506145905750565b7f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b81925090602091810103126104115760200151801590811503610411575f80614587565b91906145fd906fffffffffffffffffffffffffffffffff841661465c565b6fffffffffffffffffffffffffffffffff8111614631576fffffffffffffffffffffffffffffffff612d69911680936131a1565b7f4916adce000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b9190917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8382098382029182808310920391808303921461471857670de0b6b3a76400008210156146e8577faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106699394670de0b6b3a7640000910990828211900360ee1b910360121c170290565b84907f5173648d000000000000000000000000000000000000000000000000000000005f5260045260245260445ffd5b5050670de0b6b3a764000090049150565b90614766575080511561473e57805190602001fd5b7f1425ea42000000000000000000000000000000000000000000000000000000005f5260045ffd5b815115806147ac575b614777575090565b6001600160a01b03907f9996b315000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b50803b1561476f56fea164736f6c634300081a000a"; + hex"60a060405234801561000f575f80fd5b5060405161923638038061923683398181016040528101906100319190610278565b81816040518060400160405280601081526020017f5361626c69657220466c6f77204e4654000000000000000000000000000000008152506040518060400160405280600881526020017f5341422d464c4f570000000000000000000000000000000000000000000000008152503073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505081600190816100e291906104f0565b5080600290816100f291906104f0565b5050506001600881905550815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8060405160405180910390a3505050506105bf565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61020c826101e3565b9050919050565b61021c81610202565b8114610226575f80fd5b50565b5f8151905061023781610213565b92915050565b5f61024782610202565b9050919050565b6102578161023d565b8114610261575f80fd5b50565b5f815190506102728161024e565b92915050565b5f806040838503121561028e5761028d6101df565b5b5f61029b85828601610229565b92505060206102ac85828601610264565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061033157607f821691505b602082108103610344576103436102ed565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026103a67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261036b565b6103b0868361036b565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6103f46103ef6103ea846103c8565b6103d1565b6103c8565b9050919050565b5f819050919050565b61040d836103da565b610421610419826103fb565b848454610377565b825550505050565b5f90565b610435610429565b610440818484610404565b505050565b5b81811015610463576104585f8261042d565b600181019050610446565b5050565b601f8211156104a8576104798161034a565b6104828461035c565b81016020851015610491578190505b6104a561049d8561035c565b830182610445565b50505b505050565b5f82821c905092915050565b5f6104c85f19846008026104ad565b1980831691505092915050565b5f6104e083836104b9565b9150826002028217905092915050565b6104f9826102b6565b67ffffffffffffffff811115610512576105116102c0565b5b61051c825461031a565b610527828285610467565b5f60209050601f831160018114610558575f8415610546578287015190505b61055085826104d5565b8655506105b7565b601f1984166105668661034a565b5f5b8281101561058d57848901518255600182019150602085019450602081019050610568565b868310156105aa57848901516105a6601f8916826104b9565b8355505b6001600288020188555050505b505050505050565b608051618c5f6105d75f395f6144b00152618c5f5ff3fe608060405234801561000f575f80fd5b50600436106103b8575f3560e01c806381632a86116101f2578063bc7a2d6c11610118578063e985e9c5116100ab578063f851a4401161007a578063f851a44014610c9f578063fbf2777e14610cbd578063fdd46d6014610ced578063ffe3d9f814610d1e576103b8565b8063e985e9c514610bf2578063ea5ead1914610c22578063eb5710d814610c53578063ebb6f79a14610c83576103b8565b8063c87b56dd116100e7578063c87b56dd14610b32578063d4b8088414610b62578063d975dfed14610b92578063e4b50cb814610bc2576103b8565b8063bc7a2d6c14610a9a578063bcbd019e14610aca578063bdf2a43c14610ae6578063c2f8e75014610b16576103b8565b8063b256456911610190578063b88d4fde1161015f578063b88d4fde14610a00578063b8a3be6614610a1c578063b971302a14610a4c578063bc063e1a14610a7c576103b8565b8063b256456914610968578063b5b3ca2c14610998578063b61f7583146109b4578063b62b31e4146109d0576103b8565b8063a22cb465116101cc578063a22cb465146108d0578063a7de07cd146108ec578063a8a482a61461091c578063ad35efd414610938576103b8565b806381632a8614610866578063894e9a0d1461088257806395d89b41146108b2576103b8565b806342842e0e116102e25780636352211e1161027557806375829def1161024457806375829def146107ce5780637cad6cd1146107ea5780637ddf92281461080657806380448da314610836576103b8565b80636352211e14610722578063648bf774146107525780636d0cee751461076e57806370a082311461079e576103b8565b8063569f4c59116102b1578063569f4c5914610676578063597150fa146106a65780635ea2145b146106d65780635f553152146106f2576103b8565b806342842e0e146105dc57806342e3e23d146105f85780634426757014610628578063450ac90814610646576103b8565b8063136439dd1161035a5780631e99d569116103295780631e99d5691461056a5780631f0cce581461058857806323b872dd146105a4578063379d871a146105c0576103b8565b8063136439dd146104d25780631400ecec146104ee5780631e0104391461051e5780631e897afb1461054e576103b8565b806308b879231161039657806308b879231461043a578063095ea7b31461046a5780630c5fd195146104865780630c699624146104b6576103b8565b806301ffc9a7146103bc57806306fdde03146103ec578063081812fc1461040a575b5f80fd5b6103d660048036038101906103d19190617327565b610d3a565b6040516103e3919061736c565b60405180910390f35b6103f4610d7b565b604051610401919061740f565b60405180910390f35b610424600480360381019061041f9190617462565b610e0b565b60405161043191906174cc565b60405180910390f35b610454600480360381019061044f9190617462565b610e26565b60405161046191906174f4565b60405180910390f35b610484600480360381019061047f9190617537565b610e9c565b005b6104a0600480360381019061049b91906175b0565b610eb2565b6040516104ad9190617605565b60405180910390f35b6104d060048036038101906104cb9190617462565b610ede565b005b6104ec60048036038101906104e79190617462565b611045565b005b61050860048036038101906105039190617462565b61123f565b6040516105159190617605565b60405180910390f35b61053860048036038101906105339190617462565b6112b5565b6040516105459190617605565b60405180910390f35b6105686004803603810190610563919061767f565b611351565b005b610572611445565b60405161057f91906174f4565b60405180910390f35b6105a2600480360381019061059d919061771e565b61144b565b005b6105be60048036038101906105b9919061776e565b611617565b005b6105da60048036038101906105d591906177be565b611716565b005b6105f660048036038101906105f1919061776e565b61191b565b005b610612600480360381019061060d9190617462565b61193a565b60405161061f9190617605565b60405180910390f35b6106306119b0565b60405161063d9190617857565b60405180910390f35b610660600480360381019061065b9190617462565b6119d5565b60405161066d91906174f4565b60405180910390f35b610690600480360381019061068b9190617462565b611a57565b60405161069d919061736c565b60405180910390f35b6106c060048036038101906106bb919061789a565b611ae6565b6040516106cd91906174f4565b60405180910390f35b6106f060048036038101906106eb9190617462565b611b07565b005b61070c600480360381019061070791906175b0565b611c1f565b60405161071991906174f4565b60405180910390f35b61073c60048036038101906107379190617462565b611c34565b60405161074991906174cc565b60405180910390f35b61076c60048036038101906107679190617911565b611c45565b005b61078860048036038101906107839190617462565b611e93565b60405161079591906174cc565b60405180910390f35b6107b860048036038101906107b3919061794f565b611f09565b6040516107c591906174f4565b60405180910390f35b6107e860048036038101906107e3919061794f565b611fbf565b005b61080460048036038101906107ff91906179b5565b61210b565b005b610820600480360381019061081b9190617462565b6122bb565b60405161082d91906174f4565b60405180910390f35b610850600480360381019061084b9190617462565b612331565b60405161085d9190617a10565b60405180910390f35b610880600480360381019061087b91906177be565b6123ce565b005b61089c60048036038101906108979190617462565b612529565b6040516108a99190617b98565b60405180910390f35b6108ba612796565b6040516108c7919061740f565b60405180910390f35b6108ea60048036038101906108e59190617bb2565b612826565b005b61090660048036038101906109019190617462565b61283c565b6040516109139190617bff565b60405180910390f35b61093660048036038101906109319190617c18565b6128cb565b005b610952600480360381019061094d9190617462565b612b3f565b60405161095f9190617cc9565b60405180910390f35b610982600480360381019061097d9190617462565b612c79565b60405161098f919061736c565b60405180910390f35b6109b260048036038101906109ad9190617d0c565b612d08565b005b6109ce60048036038101906109c99190617d4a565b612f4c565b005b6109ea60048036038101906109e591906175b0565b613073565b6040516109f79190617dde565b60405180910390f35b610a1a6004803603810190610a159190617f1f565b613088565b005b610a366004803603810190610a319190617462565b6130a5565b604051610a43919061736c565b60405180910390f35b610a666004803603810190610a619190617462565b6130cf565b604051610a7391906174cc565b60405180910390f35b610a84613170565b604051610a919190617dde565b60405180910390f35b610ab46004803603810190610aaf9190617462565b61317c565b604051610ac191906174f4565b60405180910390f35b610ae46004803603810190610adf91906177be565b6131f2565b005b610b006004803603810190610afb9190617462565b6133f7565b604051610b0d919061736c565b60405180910390f35b610b306004803603810190610b2b9190617fc1565b6134c2565b005b610b4c6004803603810190610b479190617462565b6135fb565b604051610b59919061740f565b60405180910390f35b610b7c6004803603810190610b779190617462565b6136ac565b604051610b8991906174f4565b60405180910390f35b610bac6004803603810190610ba79190617462565b6139e2565b604051610bb99190617605565b60405180910390f35b610bdc6004803603810190610bd79190617462565b613a58565b604051610be99190618047565b60405180910390f35b610c0c6004803603810190610c079190618060565b613af9565b604051610c19919061736c565b60405180910390f35b610c3c6004803603810190610c37919061809e565b613b87565b604051610c4a9291906180dc565b60405180910390f35b610c6d6004803603810190610c689190617462565b613c56565b604051610c7a9190618112565b60405180910390f35b610c9d6004803603810190610c989190617c18565b613ce9565b005b610ca7613eaa565b604051610cb491906174cc565b60405180910390f35b610cd76004803603810190610cd2919061812b565b613ecd565b604051610ce491906174f4565b60405180910390f35b610d076004803603810190610d0291906181b4565b613ef9565b604051610d159291906180dc565b60405180910390f35b610d386004803603810190610d339190617911565b613fbc565b005b5f634906490660e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d745750610d7382614296565b5b9050919050565b606060018054610d8a90618231565b80601f0160208091040260200160405190810160405280929190818152602001828054610db690618231565b8015610e015780601f10610dd857610100808354040283529160200191610e01565b820191905f5260205f20905b815481529060010190602001808311610de457829003601f168201915b5050505050905090565b5f610e1582614377565b50610e1f826143fd565b9050919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16610e8b57806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401610e8291906174f4565b60405180910390fd5b610e9483614436565b915050919050565b610eae8282610ea9614495565b61449c565b5050565b600b602052805f5260405f205f915054906101000a90046fffffffffffffffffffffffffffffffff1681565b610ee66144ae565b80600c5f8281526020019081526020015f2060010160199054906101000a900460ff16610f4a57806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401610f4191906174f4565b60405180910390fd5b81600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ff05780336040517fa9ad2a22000000000000000000000000000000000000000000000000000000008152600401610fe7929190618261565b60405180910390fd5b825f610ffb85614535565b9050611007858261457f565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce78160405161103791906174f4565b60405180910390a150505050565b61104d6144ae565b80600c5f8281526020019081526020015f2060010160199054906101000a900460ff166110b157806040517fe21c14310000000000000000000000000000000000000000000000000000000081526004016110a891906174f4565b60405180910390fd5b815f6110fd600c5f8481526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff160361115157806040517f167274c900000000000000000000000000000000000000000000000000000000815260040161114891906174f4565b60405180910390fd5b82600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111f75780336040517fa9ad2a220000000000000000000000000000000000000000000000000000000081526004016111ee929190618261565b60405180910390fd5b83611201856148e7565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce78160405161123091906174f4565b60405180910390a15050505050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff166112a457806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161129b91906174f4565b60405180910390fd5b6112ad83614535565b915050919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661131a57806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161131191906174f4565b60405180910390fd5b600c5f8481526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff16915050919050565b5f8282905090505f5b8181101561143f575f803073ffffffffffffffffffffffffffffffffffffffff1686868581811061138e5761138d618288565b5b90506020028101906113a091906182c1565b6040516113ae929190618351565b5f60405180830381855af49150503d805f81146113e6576040519150601f19603f3d011682016040523d82523d5f602084013e6113eb565b606091505b50915091508161143257806040517fd935448500000000000000000000000000000000000000000000000000000000815260040161142991906183bb565b60405180910390fd5b505080600101905061135a565b50505050565b60085481565b6114536144ae565b82600c5f8281526020019081526020015f2060010160199054906101000a900460ff166114b757806040517fe21c14310000000000000000000000000000000000000000000000000000000081526004016114ae91906174f4565b60405180910390fd5b83600c5f8281526020019081526020015f20600101601b9054906101000a900460ff161561151c57806040517f7354d5f100000000000000000000000000000000000000000000000000000000815260040161151391906174f4565b60405180910390fd5b84600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146115c25780336040517fa9ad2a220000000000000000000000000000000000000000000000000000000081526004016115b9929190618261565b60405180910390fd5b856115cd87876149a5565b6115d78786614aa1565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce78160405161160691906174f4565b60405180910390a150505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611687575f6040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161167e91906174cc565b60405180910390fd5b5f61169a8383611695614495565b614c90565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611710578382826040517f64283d7b000000000000000000000000000000000000000000000000000000008152600401611707939291906183db565b60405180910390fd5b50505050565b61171e6144ae565b81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661178257806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161177991906174f4565b60405180910390fd5b825f6117ce600c5f8481526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff160361182257806040517f167274c900000000000000000000000000000000000000000000000000000000815260040161181991906174f4565b60405180910390fd5b83600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118c85780336040517fa9ad2a220000000000000000000000000000000000000000000000000000000081526004016118bf929190618261565b60405180910390fd5b846118d3868661457f565b6118dc866148e7565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce78160405161190b91906174f4565b60405180910390a1505050505050565b61193583838360405180602001604052805f815250613088565b505050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661199f57806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161199691906174f4565b60405180910390fd5b6119a883614d88565b915050919050565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16611a3a57806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401611a3191906174f4565b60405180910390fd5b600c5f8481526020019081526020015f2060030154915050919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16611abc57806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401611ab391906174f4565b60405180910390fd5b600c5f8481526020019081526020015f20600101601b9054906101000a900460ff16915050919050565b5f611aef6144ae565b611afc8686868686614e20565b905095945050505050565b611b0f6144ae565b80600c5f8281526020019081526020015f2060010160199054906101000a900460ff16611b7357806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401611b6a91906174f4565b60405180910390fd5b81600c5f8281526020019081526020015f20600101601b9054906101000a900460ff1615611bd857806040517f7354d5f1000000000000000000000000000000000000000000000000000000008152600401611bcf91906174f4565b60405180910390fd5b82611be284615259565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce781604051611c1191906174f4565b60405180910390a150505050565b6007602052805f5260405f205f915090505481565b5f611c3e82614377565b9050919050565b3373ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611cf5575f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff16336040517fc6cce6a4000000000000000000000000000000000000000000000000000000008152600401611cec929190618410565b60405180910390fd5b5f60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20548373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d6d91906174cc565b602060405180830381865afa158015611d88573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dac919061844b565b611db691906184a3565b90505f8103611dfc57826040517ff4c3afcf000000000000000000000000000000000000000000000000000000008152600401611df391906174cc565b60405180910390fd5b611e2782828573ffffffffffffffffffffffffffffffffffffffff166155539092919063ffffffff16565b8273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f21252411d5a999da4bc6a490f7143b61ba690edceb4577a2800eab8dfbb1e92c8484604051611e869291906184d6565b60405180910390a3505050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16611ef857806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401611eef91906174f4565b60405180910390fd5b611f01836155d2565b915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611f7a575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401611f7191906174cc565b60405180910390fd5b60045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b3373ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461206f575f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff16336040517fc6cce6a4000000000000000000000000000000000000000000000000000000008152600401612066929190618410565b60405180910390fd5b805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fbdd36143ee09de60bdefca70680e0f71189b2ed7acee364b53917ad433fdaf8060405160405180910390a350565b3373ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146121bb575f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff16336040517fc6cce6a40000000000000000000000000000000000000000000000000000000081526004016121b2929190618410565b60405180910390fd5b5f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160095f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167fa2548bd4b805e907c1558a47b5858324fe8bb4a2e1ddfca647eecbf65610eebc82846040516122689291906184fd565b60405180910390a27f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c6001806008546122a191906184a3565b6040516122af92919061855d565b60405180910390a15050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661232057806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161231791906174f4565b60405180910390fd5b6123298361560b565b915050919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661239657806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161238d91906174f4565b60405180910390fd5b600c5f8481526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff16915050919050565b6123d66144ae565b81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661243a57806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161243191906174f4565b60405180910390fd5b82600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146124e05780336040517fa9ad2a220000000000000000000000000000000000000000000000000000000081526004016124d7929190618261565b60405180910390fd5b836124eb858561457f565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce78160405161251a91906174f4565b60405180910390a15050505050565b612531617218565b81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661259557806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161258c91906174f4565b60405180910390fd5b600c5f8481526020019081526020015f20604051806101400160405290815f82015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020015f820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160149054906101000a900464ffffffffff1664ffffffffff1664ffffffffff1681526020016001820160199054906101000a900460ff1615151515815260200160018201601a9054906101000a900460ff1615151515815260200160018201601b9054906101000a900460ff16151515158152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160149054906101000a900460ff1660ff1660ff168152602001600382015481525050915050919050565b6060600280546127a590618231565b80601f01602080910402602001604051908101604052809291908181526020018280546127d190618231565b801561281c5780601f106127f35761010080835404028352916020019161281c565b820191905f5260205f20905b8154815290600101906020018083116127ff57829003601f168201915b5050505050905090565b612838612831614495565b83836156db565b5050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff166128a157806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161289891906174f4565b60405180910390fd5b600c5f8481526020019081526020015f2060020160149054906101000a900460ff16915050919050565b6128d36144ae565b81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661293757806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161292e91906174f4565b60405180910390fd5b825f612983600c5f8481526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff16036129d757806040517f167274c90000000000000000000000000000000000000000000000000000000081526004016129ce91906174f4565b60405180910390fd5b83600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612a7d5780336040517fa9ad2a22000000000000000000000000000000000000000000000000000000008152600401612a74929190618261565b60405180910390fd5b845f600c5f8881526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff169050612abb8787615844565b867ffddf01d0842635e80929251f6862b3baf136a29f2b2fb148968e8b236d5785fe612ae689614436565b8389604051612af793929190618584565b60405180910390a2507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce781604051612b2f91906174f4565b60405180910390a1505050505050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16612ba457806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401612b9b91906174f4565b60405180910390fd5b600c5f8481526020019081526020015f20600101601b9054906101000a900460ff1615612bd45760049150612c73565b5f80612bdf856159d4565b1190505f612c2d600c5f8781526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff1603612c5e578015612c54576003925050612c73565b6002925050612c73565b8015612c6e576001925050612c73565b5f9250505b50919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16612cde57806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401612cd591906174f4565b60405180910390fd5b600c5f8481526020019081526020015f20600101601a9054906101000a900460ff16915050919050565b3373ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612db8575f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff16336040517fc6cce6a4000000000000000000000000000000000000000000000000000000008152600401612daf929190618410565b60405180910390fd5b612dca8167016345785d8a0000615a5f565b15612e16578067016345785d8a00006040517f34553172000000000000000000000000000000000000000000000000000000008152600401612e0d9291906185b9565b60405180910390fd5b5f600a5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081600a5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f371789a3d97098f3070492613273a065a7e8a19e009fd1ae92a4b4d4c71ed62d8385604051612ef89291906185b9565b60405180910390a37f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c600180600854612f3191906184a3565b604051612f3f92919061855d565b60405180910390a1505050565b612f546144ae565b83600c5f8281526020019081526020015f2060010160199054906101000a900460ff16612fb857806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401612faf91906174f4565b60405180910390fd5b84600c5f8281526020019081526020015f20600101601b9054906101000a900460ff161561301d57806040517f7354d5f100000000000000000000000000000000000000000000000000000000815260040161301491906174f4565b60405180910390fd5b85613029878686615a7b565b6130338787614aa1565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce78160405161306291906174f4565b60405180910390a150505050505050565b600a602052805f5260405f205f915090505481565b613093848484611617565b61309f84848484615bda565b50505050565b5f600c5f8381526020019081526020015f2060010160199054906101000a900460ff169050919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661313457806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161312b91906174f4565b60405180910390fd5b600c5f8481526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b67016345785d8a000081565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff166131e157806040517fe21c14310000000000000000000000000000000000000000000000000000000081526004016131d891906174f4565b60405180910390fd5b6131ea836159d4565b915050919050565b6131fa6144ae565b81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661325e57806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161325591906174f4565b60405180910390fd5b825f6132aa600c5f8481526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff16036132fe57806040517f167274c90000000000000000000000000000000000000000000000000000000081526004016132f591906174f4565b60405180910390fd5b83600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146133a45780336040517fa9ad2a2200000000000000000000000000000000000000000000000000000000815260040161339b929190618261565b60405180910390fd5b846133af8686614aa1565b6133b8866148e7565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7816040516133e791906174f4565b60405180910390a1505050505050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661345c57806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161345391906174f4565b60405180910390fd5b5f6134a7600c5f8681526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff1614915050919050565b6134ca6144ae565b84600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661352e57806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161352591906174f4565b60405180910390fd5b85600c5f8281526020019081526020015f20600101601b9054906101000a900460ff161561359357806040517f7354d5f100000000000000000000000000000000000000000000000000000000815260040161358a91906174f4565b60405180910390fd5b8661359f888787615a7b565b6135ba8888868036038101906135b59190618631565b615d8c565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7816040516135e991906174f4565b60405180910390a15050505050505050565b606061360682614377565b5060095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e9dc637530846040518363ffffffff1660e01b815260040161366392919061867c565b5f60405180830381865afa15801561367d573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906136a59190618741565b9050919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff1661371157806040517fe21c143100000000000000000000000000000000000000000000000000000000815260040161370891906174f4565b60405180910390fd5b825f61375d600c5f8481526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff16036137b157806040517f167274c90000000000000000000000000000000000000000000000000000000081526004016137a891906174f4565b60405180910390fd5b5f600c5f8681526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff1690505f816fffffffffffffffffffffffffffffffff160361383957846040517f0f04b2a100000000000000000000000000000000000000000000000000000000815260040161383091906174f4565b60405180910390fd5b5f600c5f8781526020019081526020015f2060020160149054906101000a900460ff1690505f61387b836fffffffffffffffffffffffffffffffff1683615e2b565b90505f600c5f8981526020019081526020015f206003015490505f6138a1600185615e2b565b905080836138af9190618788565b6138b88a61560b565b836138c39190618788565b106138d5575f975050505050506139db565b5f613920600c5f8c81526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff1690505f828486030190505f82828161394d5761394c6187bb565b5b0490505f838381613961576139606187bb565b5b060361399d5780600c5f8e81526020019081526020015f2060010160149054906101000a900464ffffffffff1664ffffffffff16019a506139d2565b600181600c5f8f81526020019081526020015f2060010160149054906101000a900464ffffffffff1664ffffffffff1601019a505b50505050505050505b5050919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16613a4757806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401613a3e91906174f4565b60405180910390fd5b613a5083614d88565b915050919050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16613abd57806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401613ab491906174f4565b60405180910390fd5b600c5f8481526020019081526020015f206002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b5f60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f80613b916144ae565b83600c5f8281526020019081526020015f2060010160199054906101000a900460ff16613bf557806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401613bec91906174f4565b60405180910390fd5b845f613c0087614d88565b9050613c0d878783615e59565b8095508196505050507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce781604051613c4591906174f4565b60405180910390a150509250929050565b5f81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16613cbb57806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401613cb291906174f4565b60405180910390fd5b600c5f8481526020019081526020015f2060010160149054906101000a900464ffffffffff16915050919050565b613cf16144ae565b81600c5f8281526020019081526020015f2060010160199054906101000a900460ff16613d5557806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401613d4c91906174f4565b60405180910390fd5b82600c5f8281526020019081526020015f20600101601b9054906101000a900460ff1615613dba57806040517f7354d5f1000000000000000000000000000000000000000000000000000000008152600401613db191906174f4565b60405180910390fd5b83600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613e605780336040517fa9ad2a22000000000000000000000000000000000000000000000000000000008152600401613e57929190618261565b60405180910390fd5b84613e6b86866149a5565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce781604051613e9a91906174f4565b60405180910390a1505050505050565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f613ed66144ae565b613ee38787878787614e20565b9050613eef8183614aa1565b9695505050505050565b5f80613f036144ae565b84600c5f8281526020019081526020015f2060010160199054906101000a900460ff16613f6757806040517fe21c1431000000000000000000000000000000000000000000000000000000008152600401613f5e91906174f4565b60405180910390fd5b85613f73878787615e59565b80945081955050507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce781604051613faa91906174f4565b60405180910390a15050935093915050565b3373ffffffffffffffffffffffffffffffffffffffff165f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461406c575f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff16336040517fc6cce6a4000000000000000000000000000000000000000000000000000000008152600401614063929190618410565b60405180910390fd5b5f600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a90046fffffffffffffffffffffffffffffffff1690505f816fffffffffffffffffffffffffffffffff160361411e57826040517ff717901b00000000000000000000000000000000000000000000000000000000815260040161411591906174cc565b60405180910390fd5b5f600b5f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550806fffffffffffffffffffffffffffffffff1660075f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254039250508190555061422a82826fffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff166155539092919063ffffffff16565b8273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc9a4a66b97fd7e52e69c5be7b10bdc5341bded817201b9b7136a75068d4e4e0584846040516142899291906187e8565b60405180910390a3505050565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061436057507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80614370575061436f826164a9565b5b9050919050565b5f80614382836155d2565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036143f457826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016143eb91906174f4565b60405180910390fd5b80915050919050565b5f60055f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f80600c5f8481526020019081526020015f20600301546144568461560b565b6144609190618788565b905061448d81600c5f8681526020019081526020015f2060020160149054906101000a900460ff16616512565b915050919050565b5f33905090565b6144a9838383600161654e565b505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614614533576040517fa1c0d6e500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f61453f82614d88565b600c5f8481526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff16614578919061880f565b9050919050565b5f816fffffffffffffffffffffffffffffffff16036145d557816040517fea66b8710000000000000000000000000000000000000000000000000000000081526004016145cc91906174f4565b60405180910390fd5b5f6145df83614535565b9050806fffffffffffffffffffffffffffffffff16826fffffffffffffffffffffffffffffffff16111561464e578282826040517fe977140100000000000000000000000000000000000000000000000000000000815260040161464593929190618852565b60405180910390fd5b600c5f8481526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1611156147175782600c5f8581526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff16836040517fcb5f605f00000000000000000000000000000000000000000000000000000000815260040161470e93929190618852565b60405180910390fd5b5f600c5f8581526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f600c5f8681526020019081526020015f206002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083600c5f8781526020019081526020015f205f015f8282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550836fffffffffffffffffffffffffffffffff1660075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f828254039250508190555061488882856fffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff166155539092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff16857fe31f2d40d5780915b1e656a67e11bdf09b0a4a925ec42bbeae220c8ca937ab49866040516148cf9190617605565b60405180910390a35050505050565b5f819050919050565b6148f9816148f45f61670d565b615844565b614902816155d2565b73ffffffffffffffffffffffffffffffffffffffff16600c5f8381526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16827fda83bf669c651406e02062769e01d14cccb5625ea685fd95e0e56d29597dac4761498d85614436565b60405161499a91906174f4565b60405180910390a450565b5f6149f0600c5f8581526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff1614614a4457816040517fdc6fbbbc000000000000000000000000000000000000000000000000000000008152600401614a3b91906174f4565b60405180910390fd5b614a4e8282615844565b3373ffffffffffffffffffffffffffffffffffffffff16827fc2a543cfadbf862642247e28711aaa30e3460384be5712be6557fee3384454fd83604051614a959190617a10565b60405180910390a35050565b5f816fffffffffffffffffffffffffffffffff1603614af757816040517f33f2df5a000000000000000000000000000000000000000000000000000000008152600401614aee91906174f4565b60405180910390fd5b5f600c5f8481526020019081526020015f206002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600c5f8581526020019081526020015f205f015f8282829054906101000a90046fffffffffffffffffffffffffffffffff16614b6b9190618887565b92506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550816fffffffffffffffffffffffffffffffff1660075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282540192505081905550614c3c3330846fffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16616716909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff16837fa06c1466b3c9751408a5ac337a2e8808e5ee0ceed1fd70635d041b21174eb6b484604051614c839190617605565b60405180910390a3505050565b5f825f614c9c856155d2565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015614cf95750600c5f8681526020019081526020015f20600101601a9054906101000a900460ff16155b15614d3b57846040517f7da2ea2b000000000000000000000000000000000000000000000000000000008152600401614d3291906174f4565b60405180910390fd5b614d46868686616798565b9250507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce781604051614d7891906174f4565b60405180910390a1509392505050565b5f80600c5f8481526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff1690505f816fffffffffffffffffffffffffffffffff1603614ddd575f915050614e1b565b5f614de784614436565b905080826fffffffffffffffffffffffffffffffff161015614e0d578192505050614e1b565b614e16816169a3565b925050505b919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1603614e86576040517ff9bb0fb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015614ed0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614ef491906188f4565b905060128160ff161115614f3f57836040517fc9f55392000000000000000000000000000000000000000000000000000000008152600401614f3691906174cc565b60405180910390fd5b60085491506040518061014001604052805f6fffffffffffffffffffffffffffffffff168152602001866fffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1681526020014264ffffffffff16815260200160011515815260200184151581526020015f151581526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018260ff1681526020015f815250600c5f8481526020019081526020015f205f820151815f015f6101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506020820151815f0160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506040820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160010160146101000a81548164ffffffffff021916908364ffffffffff16021790555060808201518160010160196101000a81548160ff02191690831515021790555060a082015181600101601a6101000a81548160ff02191690831515021790555060c082015181600101601b6101000a81548160ff02191690831515021790555060e0820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160020160146101000a81548160ff021916908360ff1602179055506101208201518160030155905050600182016008819055506151cf8683616a06565b8373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f2262fa211f8507786a60fefb231f7898b8145fe16350f281c91f121bd2ee118d8589886040516152479392919061891f565b60405180910390a45095945050505050565b600c5f8281526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156152ce57506152cc81616af9565b155b156153125780336040517fa9ad2a22000000000000000000000000000000000000000000000000000000008152600401615309929190618261565b60405180910390fd5b5f61531c826159d4565b90505f810361536a575f61532f8361560b565b90505f8111156153645780600c5f8581526020019081526020015f206003015f82825461535c9190618788565b925050819055505b506153ee565b6153d5600c5f8481526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16600c5f8581526020019081526020015f2060020160149054906101000a900460ff16615e2b565b600c5f8481526020019081526020015f20600301819055505b42600c5f8481526020019081526020015f2060010160146101000a81548164ffffffffff021916908364ffffffffff16021790555061542c5f61670d565b600c5f8481526020019081526020015f205f0160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506001600c5f8481526020019081526020015f20600101601b6101000a81548160ff0219169083151502179055506154ab826155d2565b73ffffffffffffffffffffffffffffffffffffffff16600c5f8481526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16837fa8e3d71a6c0c719305004b430f6d17f12536f7b803db23a4d7016f5b52699a8c3361553787614436565b8660405161554793929190618954565b60405180910390a45050565b6155cd838473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040516024016155869291906184d6565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050616b8c565b505050565b5f60035f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f804290505f600c5f8581526020019081526020015f2060010160149054906101000a900464ffffffffff1664ffffffffff1690505f61568b600c5f8781526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff1690505f8114806156ad5750818311155b156156bd575f93505050506156d6565b5f828403905081816156cf9190618989565b9450505050505b919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361574b57816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161574291906174cc565b60405180910390fd5b8060065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051615837919061736c565b60405180910390a3505050565b61588e600c5f8481526020019081526020015f205f0160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff166158bb826fffffffffffffffffffffffffffffffff166148de565b6fffffffffffffffffffffffffffffffff16036159115781816040517fd2657d5a0000000000000000000000000000000000000000000000000000000081526004016159089291906189ca565b60405180910390fd5b5f61591b8361560b565b90505f8111156159505780600c5f8581526020019081526020015f206003015f8282546159489190618788565b925050819055505b42600c5f8581526020019081526020015f2060010160146101000a81548164ffffffffff021916908364ffffffffff16021790555081600c5f8581526020019081526020015f205f0160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550505050565b5f80600c5f8481526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff1690505f615a1184614436565b905080826fffffffffffffffffffffffffffffffff161015615a5457816fffffffffffffffffffffffffffffffff1681615a4b91906184a3565b92505050615a5a565b5f925050505b919050565b5f615a6982616c21565b615a7284616c21565b11905092915050565b600c5f8481526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614615b535781600c5f8581526020019081526020015f206001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fc8bac88d000000000000000000000000000000000000000000000000000000008152600401615b4a929190618410565b60405180910390fd5b615b5c836155d2565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614615bd55780615b98846155d2565b6040517f5bdb8ad7000000000000000000000000000000000000000000000000000000008152600401615bcc929190618410565b60405180910390fd5b505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b1115615d86578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02615c1d614495565b8685856040518563ffffffff1660e01b8152600401615c3f94939291906189f1565b6020604051808303815f875af1925050508015615c7a57506040513d601f19601f82011682018060405250810190615c779190618a4f565b60015b615cfb573d805f8114615ca8576040519150601f19603f3d011682016040523d82523d5f602084013e615cad565b606091505b505f815103615cf357836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401615cea91906174cc565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614615d8457836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401615d7b91906174cc565b60405180910390fd5b505b50505050565b5f80615da1848467016345785d8a0000616c2a565b91509150615daf8582614aa1565b615e2433845f0151846fffffffffffffffffffffffffffffffff16600c5f8a81526020019081526020015f206002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16616716909392919063ffffffff16565b5050505050565b5f60128260ff1603615e3f57829050615e53565b5f8260120360ff16600a0a90508084029150505b92915050565b5f805f836fffffffffffffffffffffffffffffffff1603615eb157846040517fb4855052000000000000000000000000000000000000000000000000000000008152600401615ea891906174f4565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603615f2157846040517f9f32c858000000000000000000000000000000000000000000000000000000008152600401615f1891906174f4565b60405180910390fd5b615f2a856155d2565b73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015615f6b5750615f6985616af9565b155b15615fb1578433856040517f4208ab4c000000000000000000000000000000000000000000000000000000008152600401615fa893929190618a7a565b60405180910390fd5b5f600c5f8781526020019081526020015f2060020160149054906101000a900460ff1690505f600c5f8881526020019081526020015f2060030154615ff58861560b565b615fff9190618788565b90505f61600c8284616512565b90505f600c5f8a81526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff1690505f82826fffffffffffffffffffffffffffffffff1610156160635781905061606f565b61606c836169a3565b90505b806fffffffffffffffffffffffffffffffff16886fffffffffffffffffffffffffffffffff1611156160dc578988826040517ff9f298590000000000000000000000000000000000000000000000000000000081526004016160d393929190618852565b60405180910390fd5b5f6160f9896fffffffffffffffffffffffffffffffff1687615e2b565b9050600c5f8c81526020019081526020015f2060030154811161613c5780600c5f8d81526020019081526020015f206003015f828254039250508190555061618d565b808503600c5f8d81526020019081526020015f206003018190555042600c5f8d81526020019081526020015f2060010160146101000a81548164ffffffffff021916908364ffffffffff1602179055505b88600c5f8d81526020019081526020015f205f015f8282829054906101000a90046fffffffffffffffffffffffffffffffff160392506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505f600c5f8d81526020019081526020015f206002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505f600a5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050616279815f615a5f565b15616325576162888b82616d11565b809c50819a50505088600b5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8282829054906101000a90046fffffffffffffffffffffffffffffffff160192506101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055505b8a6fffffffffffffffffffffffffffffffff1660075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055506163be8c8c6fffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff166155539092919063ffffffff16565b600c5f8e81526020019081526020015f205f015f9054906101000a90046fffffffffffffffffffffffffffffffff16856163f8919061880f565b6fffffffffffffffffffffffffffffffff166164138e614436565b8761641e91906184a3565b1461642c5761642b618aaf565b5b8173ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff168e7f1a7b0d6c8f96b874563b711cf97793fe3be5dc42dbd1e0720ce40f326918e817338f8e60405161648e93929190618adc565b60405180910390a48a99505050505050505050935093915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60128260ff160361652657829050616548565b5f8260120360ff16600a0a9050808481616543576165426187bb565b5b049150505b92915050565b808061658657505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156166b8575f61659584614377565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156165ff57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561661257506166108184613af9565b155b1561665457826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161664b91906174cc565b60405180910390fd5b81156166b657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360055f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f819050919050565b616792848573ffffffffffffffffffffffffffffffffffffffff166323b872dd86868660405160240161674b93929190618b11565b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050616b8c565b50505050565b5f806167a3846155d2565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146167e4576167e3818486616d5f565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461686f576168235f855f8061654e565b600160045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146168ee57600160045f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460035f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b5f6fffffffffffffffffffffffffffffffff80168211156169fe576080826040517f6dfcc6500000000000000000000000000000000000000000000000000000000081526004016169f5929190618b7f565b60405180910390fd5b819050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603616a76575f6040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401616a6d91906174cc565b60405180910390fd5b5f616a8283835f614c90565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614616af4575f6040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600401616aeb91906174cc565b60405180910390fd5b505050565b5f80616b04836155d2565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480616b465750616b458133613af9565b5b80616b8457503373ffffffffffffffffffffffffffffffffffffffff16616b6c84610e0b565b73ffffffffffffffffffffffffffffffffffffffff16145b915050919050565b5f616bb6828473ffffffffffffffffffffffffffffffffffffffff16616e2290919063ffffffff16565b90505f815114158015616bda575080806020019051810190616bd89190618bba565b155b15616c1c57826040517f5274afe7000000000000000000000000000000000000000000000000000000008152600401616c1391906174cc565b60405180910390fd5b505050565b5f819050919050565b5f80616c43838560200151615a5f90919063ffffffff16565b15616c8b578360200151836040517f54b392b2000000000000000000000000000000000000000000000000000000008152600401616c829291906185b9565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff16845f015173ffffffffffffffffffffffffffffffffffffffff1603616cf3576040517f5f946a0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b616d01858560200151616d11565b8092508193505050935093915050565b5f80616d48616d4384616d35876fffffffffffffffffffffffffffffffff16616e37565b616e4090919063ffffffff16565b616e6b565b91508184616d56919061880f565b90509250929050565b616d6a838383616ed0565b616e1d575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603616dde57806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401616dd591906174f4565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401616e149291906184d6565b60405180910390fd5b505050565b6060616e2f83835f616f90565b905092915050565b5f819050919050565b5f616e63616e5e616e5085616c21565b616e5985616c21565b617059565b61713e565b905092915050565b5f808290506fffffffffffffffffffffffffffffffff8016811115616ec757826040517f4916adce000000000000000000000000000000000000000000000000000000008152600401616ebe9190617dde565b60405180910390fd5b80915050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015616f8757508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480616f485750616f478484613af9565b5b80616f8657508273ffffffffffffffffffffffffffffffffffffffff16616f6e836143fd565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b606081471015616fd757306040517fcd786059000000000000000000000000000000000000000000000000000000008152600401616fce91906174cc565b60405180910390fd5b5f808573ffffffffffffffffffffffffffffffffffffffff168486604051616fff9190618c15565b5f6040518083038185875af1925050503d805f8114617039576040519150601f19603f3d011682016040523d82523d5f602084013e61703e565b606091505b509150915061704e868383617147565b925050509392505050565b5f805f80198486098486029250828110838203039150505f810361709957670de0b6b3a7640000828161708f5761708e6187bb565b5b0492505050617138565b670de0b6b3a764000081106170e75784846040517f5173648d0000000000000000000000000000000000000000000000000000000081526004016170de929190618c2b565b60405180910390fd5b5f670de0b6b3a764000085870990507faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac10669600162040000805f0304018483118403026204000083860304170293505050505b92915050565b5f819050919050565b60608261715c57617157826171d4565b6171cc565b5f825114801561718257505f8473ffffffffffffffffffffffffffffffffffffffff163b145b156171c457836040517f9996b3150000000000000000000000000000000000000000000000000000000081526004016171bb91906174cc565b60405180910390fd5b8190506171cd565b5b9392505050565b5f815111156171e65780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518061014001604052805f6fffffffffffffffffffffffffffffffff1681526020015f6fffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f64ffffffffff1681526020015f151581526020015f151581526020015f151581526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f60ff1681526020015f81525090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b617306816172d2565b8114617310575f80fd5b50565b5f81359050617321816172fd565b92915050565b5f6020828403121561733c5761733b6172ca565b5b5f61734984828501617313565b91505092915050565b5f8115159050919050565b61736681617352565b82525050565b5f60208201905061737f5f83018461735d565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156173bc5780820151818401526020810190506173a1565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6173e182617385565b6173eb818561738f565b93506173fb81856020860161739f565b617404816173c7565b840191505092915050565b5f6020820190508181035f83015261742781846173d7565b905092915050565b5f819050919050565b6174418161742f565b811461744b575f80fd5b50565b5f8135905061745c81617438565b92915050565b5f60208284031215617477576174766172ca565b5b5f6174848482850161744e565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6174b68261748d565b9050919050565b6174c6816174ac565b82525050565b5f6020820190506174df5f8301846174bd565b92915050565b6174ee8161742f565b82525050565b5f6020820190506175075f8301846174e5565b92915050565b617516816174ac565b8114617520575f80fd5b50565b5f813590506175318161750d565b92915050565b5f806040838503121561754d5761754c6172ca565b5b5f61755a85828601617523565b925050602061756b8582860161744e565b9150509250929050565b5f61757f826174ac565b9050919050565b61758f81617575565b8114617599575f80fd5b50565b5f813590506175aa81617586565b92915050565b5f602082840312156175c5576175c46172ca565b5b5f6175d28482850161759c565b91505092915050565b5f6fffffffffffffffffffffffffffffffff82169050919050565b6175ff816175db565b82525050565b5f6020820190506176185f8301846175f6565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261763f5761763e61761e565b5b8235905067ffffffffffffffff81111561765c5761765b617622565b5b60208301915083602082028301111561767857617677617626565b5b9250929050565b5f8060208385031215617695576176946172ca565b5b5f83013567ffffffffffffffff8111156176b2576176b16172ce565b5b6176be8582860161762a565b92509250509250929050565b6176d3816175db565b81146176dd575f80fd5b50565b5f813590506176ee816176ca565b92915050565b6176fd816175db565b8114617707575f80fd5b50565b5f81359050617718816176f4565b92915050565b5f805f60608486031215617735576177346172ca565b5b5f6177428682870161744e565b9350506020617753868287016176e0565b92505060406177648682870161770a565b9150509250925092565b5f805f60608486031215617785576177846172ca565b5b5f61779286828701617523565b93505060206177a386828701617523565b92505060406177b48682870161744e565b9150509250925092565b5f80604083850312156177d4576177d36172ca565b5b5f6177e18582860161744e565b92505060206177f28582860161770a565b9150509250929050565b5f819050919050565b5f61781f61781a6178158461748d565b6177fc565b61748d565b9050919050565b5f61783082617805565b9050919050565b5f61784182617826565b9050919050565b61785181617837565b82525050565b5f60208201905061786a5f830184617848565b92915050565b61787981617352565b8114617883575f80fd5b50565b5f8135905061789481617870565b92915050565b5f805f805f60a086880312156178b3576178b26172ca565b5b5f6178c088828901617523565b95505060206178d188828901617523565b94505060406178e2888289016176e0565b93505060606178f38882890161759c565b925050608061790488828901617886565b9150509295509295909350565b5f8060408385031215617927576179266172ca565b5b5f6179348582860161759c565b925050602061794585828601617523565b9150509250929050565b5f60208284031215617964576179636172ca565b5b5f61797184828501617523565b91505092915050565b5f617984826174ac565b9050919050565b6179948161797a565b811461799e575f80fd5b50565b5f813590506179af8161798b565b92915050565b5f602082840312156179ca576179c96172ca565b5b5f6179d7848285016179a1565b91505092915050565b5f6179fa6179f56179f0846175db565b6177fc565b6175db565b9050919050565b617a0a816179e0565b82525050565b5f602082019050617a235f830184617a01565b92915050565b617a32816175db565b82525050565b617a41816179e0565b82525050565b617a50816174ac565b82525050565b5f64ffffffffff82169050919050565b617a6f81617a56565b82525050565b617a7e81617352565b82525050565b5f617a8e82617826565b9050919050565b617a9e81617a84565b82525050565b5f60ff82169050919050565b617ab981617aa4565b82525050565b617ac88161742f565b82525050565b61014082015f820151617ae35f850182617a29565b506020820151617af66020850182617a38565b506040820151617b096040850182617a47565b506060820151617b1c6060850182617a66565b506080820151617b2f6080850182617a75565b5060a0820151617b4260a0850182617a75565b5060c0820151617b5560c0850182617a75565b5060e0820151617b6860e0850182617a95565b50610100820151617b7d610100850182617ab0565b50610120820151617b92610120850182617abf565b50505050565b5f61014082019050617bac5f830184617ace565b92915050565b5f8060408385031215617bc857617bc76172ca565b5b5f617bd585828601617523565b9250506020617be685828601617886565b9150509250929050565b617bf981617aa4565b82525050565b5f602082019050617c125f830184617bf0565b92915050565b5f8060408385031215617c2e57617c2d6172ca565b5b5f617c3b8582860161744e565b9250506020617c4c858286016176e0565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60058110617c9457617c93617c56565b5b50565b5f819050617ca482617c83565b919050565b5f617cb382617c97565b9050919050565b617cc381617ca9565b82525050565b5f602082019050617cdc5f830184617cba565b92915050565b617ceb8161742f565b8114617cf5575f80fd5b50565b5f81359050617d0681617ce2565b92915050565b5f8060408385031215617d2257617d216172ca565b5b5f617d2f8582860161759c565b9250506020617d4085828601617cf8565b9150509250929050565b5f805f8060808587031215617d6257617d616172ca565b5b5f617d6f8782880161744e565b9450506020617d808782880161770a565b9350506040617d9187828801617523565b9250506060617da287828801617523565b91505092959194509250565b5f617dc8617dc3617dbe8461742f565b6177fc565b61742f565b9050919050565b617dd881617dae565b82525050565b5f602082019050617df15f830184617dcf565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b617e31826173c7565b810181811067ffffffffffffffff82111715617e5057617e4f617dfb565b5b80604052505050565b5f617e626172c1565b9050617e6e8282617e28565b919050565b5f67ffffffffffffffff821115617e8d57617e8c617dfb565b5b617e96826173c7565b9050602081019050919050565b828183375f83830152505050565b5f617ec3617ebe84617e73565b617e59565b905082815260208101848484011115617edf57617ede617df7565b5b617eea848285617ea3565b509392505050565b5f82601f830112617f0657617f0561761e565b5b8135617f16848260208601617eb1565b91505092915050565b5f805f8060808587031215617f3757617f366172ca565b5b5f617f4487828801617523565b9450506020617f5587828801617523565b9350506040617f668782880161744e565b925050606085013567ffffffffffffffff811115617f8757617f866172ce565b5b617f9387828801617ef2565b91505092959194509250565b5f80fd5b5f60408284031215617fb857617fb7617f9f565b5b81905092915050565b5f805f805f60c08688031215617fda57617fd96172ca565b5b5f617fe78882890161744e565b9550506020617ff88882890161770a565b945050604061800988828901617523565b935050606061801a88828901617523565b925050608061802b88828901617fa3565b9150509295509295909350565b61804181617a84565b82525050565b5f60208201905061805a5f830184618038565b92915050565b5f8060408385031215618076576180756172ca565b5b5f61808385828601617523565b925050602061809485828601617523565b9150509250929050565b5f80604083850312156180b4576180b36172ca565b5b5f6180c18582860161744e565b92505060206180d285828601617523565b9150509250929050565b5f6040820190506180ef5f8301856175f6565b6180fc60208301846175f6565b9392505050565b61810c81617a56565b82525050565b5f6020820190506181255f830184618103565b92915050565b5f805f805f8060c08789031215618145576181446172ca565b5b5f61815289828a01617523565b965050602061816389828a01617523565b955050604061817489828a016176e0565b945050606061818589828a0161759c565b935050608061819689828a01617886565b92505060a06181a789828a0161770a565b9150509295509295509295565b5f805f606084860312156181cb576181ca6172ca565b5b5f6181d88682870161744e565b93505060206181e986828701617523565b92505060406181fa8682870161770a565b9150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061824857607f821691505b60208210810361825b5761825a618204565b5b50919050565b5f6040820190506182745f8301856174e5565b61828160208301846174bd565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f80fd5b5f80fd5b5f80fd5b5f80833560016020038436030381126182dd576182dc6182b5565b5b80840192508235915067ffffffffffffffff8211156182ff576182fe6182b9565b5b60208301925060018202360383131561831b5761831a6182bd565b5b509250929050565b5f81905092915050565b5f6183388385618323565b9350618345838584617ea3565b82840190509392505050565b5f61835d82848661832d565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f61838d82618369565b6183978185618373565b93506183a781856020860161739f565b6183b0816173c7565b840191505092915050565b5f6020820190508181035f8301526183d38184618383565b905092915050565b5f6060820190506183ee5f8301866174bd565b6183fb60208301856174e5565b61840860408301846174bd565b949350505050565b5f6040820190506184235f8301856174bd565b61843060208301846174bd565b9392505050565b5f8151905061844581617438565b92915050565b5f602082840312156184605761845f6172ca565b5b5f61846d84828501618437565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6184ad8261742f565b91506184b88361742f565b92508282039050818111156184d0576184cf618476565b5b92915050565b5f6040820190506184e95f8301856174bd565b6184f660208301846174e5565b9392505050565b5f6040820190506185105f830185617848565b61851d6020830184617848565b9392505050565b5f819050919050565b5f61854761854261853d84618524565b6177fc565b61742f565b9050919050565b6185578161852d565b82525050565b5f6040820190506185705f83018561854e565b61857d60208301846174e5565b9392505050565b5f6060820190506185975f8301866174e5565b6185a46020830185617a01565b6185b16040830184617a01565b949350505050565b5f6040820190506185cc5f830185617dcf565b6185d96020830184617dcf565b9392505050565b5f80fd5b5f604082840312156185f9576185f86185e0565b5b6186036040617e59565b90505f61861284828501617523565b5f83015250602061862584828501617cf8565b60208301525092915050565b5f60408284031215618646576186456172ca565b5b5f618653848285016185e4565b91505092915050565b5f61866682617826565b9050919050565b6186768161865c565b82525050565b5f60408201905061868f5f83018561866d565b61869c60208301846174e5565b9392505050565b5f67ffffffffffffffff8211156186bd576186bc617dfb565b5b6186c6826173c7565b9050602081019050919050565b5f6186e56186e0846186a3565b617e59565b90508281526020810184848401111561870157618700617df7565b5b61870c84828561739f565b509392505050565b5f82601f8301126187285761872761761e565b5b81516187388482602086016186d3565b91505092915050565b5f60208284031215618756576187556172ca565b5b5f82015167ffffffffffffffff811115618773576187726172ce565b5b61877f84828501618714565b91505092915050565b5f6187928261742f565b915061879d8361742f565b92508282019050808211156187b5576187b4618476565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6040820190506187fb5f8301856174bd565b61880860208301846175f6565b9392505050565b5f618819826175db565b9150618824836175db565b925082820390506fffffffffffffffffffffffffffffffff81111561884c5761884b618476565b5b92915050565b5f6060820190506188655f8301866174e5565b61887260208301856175f6565b61887f60408301846175f6565b949350505050565b5f618891826175db565b915061889c836175db565b925082820190506fffffffffffffffffffffffffffffffff8111156188c4576188c3618476565b5b92915050565b6188d381617aa4565b81146188dd575f80fd5b50565b5f815190506188ee816188ca565b92915050565b5f60208284031215618909576189086172ca565b5b5f618916848285016188e0565b91505092915050565b5f6060820190506189325f8301866174e5565b61893f6020830185617a01565b61894c604083018461735d565b949350505050565b5f6060820190506189675f8301866174bd565b61897460208301856174e5565b61898160408301846174e5565b949350505050565b5f6189938261742f565b915061899e8361742f565b92508282026189ac8161742f565b915082820484148315176189c3576189c2618476565b5b5092915050565b5f6040820190506189dd5f8301856174e5565b6189ea6020830184617a01565b9392505050565b5f608082019050618a045f8301876174bd565b618a1160208301866174bd565b618a1e60408301856174e5565b8181036060830152618a308184618383565b905095945050505050565b5f81519050618a49816172fd565b92915050565b5f60208284031215618a6457618a636172ca565b5b5f618a7184828501618a3b565b91505092915050565b5f606082019050618a8d5f8301866174e5565b618a9a60208301856174bd565b618aa760408301846174bd565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b5f606082019050618aef5f8301866174bd565b618afc60208301856175f6565b618b0960408301846175f6565b949350505050565b5f606082019050618b245f8301866174bd565b618b3160208301856174bd565b618b3e60408301846174e5565b949350505050565b5f819050919050565b5f618b69618b64618b5f84618b46565b6177fc565b617aa4565b9050919050565b618b7981618b4f565b82525050565b5f604082019050618b925f830185618b70565b618b9f60208301846174e5565b9392505050565b5f81519050618bb481617870565b92915050565b5f60208284031215618bcf57618bce6172ca565b5b5f618bdc84828501618ba6565b91505092915050565b5f618bef82618369565b618bf98185618323565b9350618c0981856020860161739f565b80840191505092915050565b5f618c208284618be5565b915081905092915050565b5f604082019050618c3e5f8301856174e5565b618c4b60208301846174e5565b939250505056fea164736f6c634300081a000a"; bytes public constant BYTECODE_NFT_DESCRIPTOR = - hex"60808060405234601557610ae4908161001a8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c63e9dc637514610024575f80fd5b346107d65760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126107d65760043573ffffffffffffffffffffffffffffffffffffffff8116036107d6576107cd604061073c61059561044061008c845191826107fb565b61041c81527f3c7376672077696474683d2235303022206865696768743d223530302220737460208201527f796c653d226261636b67726f756e642d636f6c6f723a20233134313631463b22848201527f20786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f7360608201527f7667222076696577426f783d223230202d343030203230302031303030223e3c60808201527f706174682069643d224c6f676f222066696c6c3d2223666666222066696c6c2d60a08201527f6f7061636974793d22312220643d226d3133332e3535392c3132342e3033346360c08201527f2d2e3031332c322e3431322d312e3035392c342e3834382d322e3932332c362e60e08201527f3430322d322e3535382c312e3831392d352e3136382c332e3433392d372e38386101008201527f382c342e3939362d31342e34342c382e3236322d33312e3034372c31322e35366101208201527f352d34372e3637342c31322e3536392d382e3835382e3033362d31372e3833386101408201527f2d312e3237322d32362e3332382d332e3636332d392e3830362d322e3736362d6101608201527f31392e3038372d372e3131332d32372e3536322d31322e3737382d31332e38346101808201527f322d382e3032352c392e3436382d32382e3630362c31362e3135332d33352e326101a08201527f3635683063322e3033352d312e3833382c342e3235322d332e3534362c362e346101c08201527f36332d352e323234683063362e3432392d352e3635352c31362e3231382d322e6101e08201527f3833352c32302e3335382c342e31372c342e3134332c352e3035372c382e38316102008201527f362c392e3634392c31332e39322c31332e373334682e30333763352e3733362c6102208201527f362e3436312c31352e3335372d322e3235332c392e33382d382e34382c302c306102408201527f2d332e3531352d332e3531352d332e3531352d332e3531352d31312e34392d316102608201527f312e3437382d35322e3635362d35322e3636342d36342e3833372d36342e38336102808201527f376c2e3034392d2e303337632d312e3732352d312e3630362d322e3731392d336102a08201527f2e3834372d322e3735312d362e3230346830632d2e3034362d322e3337352c316102c08201527f2e3036322d342e3538322c322e3732362d362e32323968306c2e3138352d2e316102e08201527f34386830632e3039392d2e3036322c2e3232322d2e3134382c2e33372d2e32356103008201527f39683063322e30362d312e3336322c332e3935312d322e3632312c362e3034346103208201527f2d332e3834324335372e3736332d332e3437332c39372e37362d322e3334312c6103408201527f3132382e3633372c31382e3333326331362e3637312c392e3934362d32362e336103608201527f34342c35342e3831332d33382e3635312c34302e3139392d362e3239392d362e6103808201527f3039362d31382e3036332d31372e3734332d31392e3636382d31382e3831312d6103a08201527f362e3031362d342e3034372d31332e3036312c342e3737362d372e3735322c396103c08201527f2e3735316c36382e3235342c36382e33373163312e3732342c312e3630312c326103e08201527f2e3731342c332e38342c322e3733382c362e3139325a22207472616e73666f726104008201527f6d3d227363616c6528312e352c20312e352922202f3e3c2f7376673e000000006104208201526108a3565b610737600260c8855180947f7b226465736372697074696f6e223a202254686973204e46542072657072657360208301527f656e74732061207061796d656e742073747265616d20696e205361626c696572888301527f20466c6f77222c0000000000000000000000000000000000000000000000000060608301527f2265787465726e616c5f75726c223a202268747470733a2f2f7361626c69657260678301527f2e636f6d222c000000000000000000000000000000000000000000000000000060878301527f226e616d65223a20225361626c69657220466c6f77222c000000000000000000608d8301527f22696d616765223a2022646174613a696d6167652f7376672b786d6c3b62617360a48301527f6536342c0000000000000000000000000000000000000000000000000000000060c48301526106e281518092602086860191016107da565b81017f227d0000000000000000000000000000000000000000000000000000000000008382015203017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe28101845201826107fb565b6108a3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8351926107b2603d8560208101937f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000085526107a381518092602086860191016107da565b810103018481018652856107fb565b845195869460208652518092816020880152878701906107da565b01168101030190f35b5f80fd5b5f5b8381106107eb5750505f910152565b81810151838201526020016107dc565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761083c57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b67ffffffffffffffff811161083c57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b90815115610ac157604051916108ba6060846107fb565b604083527f4142434445464748494a4b4c4d4e4f505152535455565758595a61626364656660208401527f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f6040840152805160028101809111610a945760039004908160021b917f3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811603610a945761096b61095583610869565b9261096360405194856107fb565b808452610869565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06020840191013682379080815182019560208701908151925f83525b888110610a4657505060039394959650525106806001146109f7576002146109ce575090565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff603d91015390565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81603d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81940153015390565b600360049199969901986001603f8b5182828260121c16870101518453828282600c1c16870101518385015382828260061c16870101516002850153168401015160038201530194976109a8565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b9050604051610ad16020826107fb565b5f81529056fea164736f6c634300081a000a"; + hex"6080604052348015600e575f80fd5b50610c028061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c8063e9dc63751461002d575b5f80fd5b610047600480360381019061004291906102ea565b61005d565b60405161005491906103b2565b60405180910390f35b60605f60405180610440016040528061041c815260200161079a61041c913990505f610088826100db565b60405160200161009891906105ce565b60405160208183030381529060405290506100b2816100db565b6040516020016100c29190610649565b6040516020818303038152906040529250505092915050565b60605f8251036100fb5760405180602001604052805f8152509050610243565b5f604051806060016040528060408152602001610bb66040913990505f600360028551610128919061069b565b61013291906106fb565b600461013e919061072b565b67ffffffffffffffff8111156101575761015661076c565b5b6040519080825280601f01601f1916602001820160405280156101895781602001600182028036833780820191505090505b509050600182016020820185865187016020810180515f82525b828410156101fe576003840193508351603f8160121c168701518653600186019550603f81600c1c168701518653600186019550603f8160061c168701518653600186019550603f81168701518653600186019550506101a3565b80825260038a51066001811461021b576002811461022e57610236565b603d6001870353603d6002870353610236565b603d60018703535b5050505050505080925050505b919050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6102758261024c565b9050919050565b5f6102868261026b565b9050919050565b6102968161027c565b81146102a0575f80fd5b50565b5f813590506102b18161028d565b92915050565b5f819050919050565b6102c9816102b7565b81146102d3575f80fd5b50565b5f813590506102e4816102c0565b92915050565b5f8060408385031215610300576102ff610248565b5b5f61030d858286016102a3565b925050602061031e858286016102d6565b9150509250929050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561035f578082015181840152602081019050610344565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61038482610328565b61038e8185610332565b935061039e818560208601610342565b6103a78161036a565b840191505092915050565b5f6020820190508181035f8301526103ca818461037a565b905092915050565b5f81905092915050565b7f7b226465736372697074696f6e223a202254686973204e4654207265707265735f8201527f656e74732061207061796d656e742073747265616d20696e205361626c69657260208201527f20466c6f77222c00000000000000000000000000000000000000000000000000604082015250565b5f61045c6047836103d2565b9150610467826103dc565b604782019050919050565b7f2265787465726e616c5f75726c223a202268747470733a2f2f7361626c6965725f8201527f2e636f6d222c0000000000000000000000000000000000000000000000000000602082015250565b5f6104cc6026836103d2565b91506104d782610472565b602682019050919050565b7f226e616d65223a20225361626c69657220466c6f77222c000000000000000000815250565b7f22696d616765223a2022646174613a696d6167652f7376672b786d6c3b6261735f8201527f6536342c00000000000000000000000000000000000000000000000000000000602082015250565b5f6105626024836103d2565b915061056d82610508565b602482019050919050565b5f61058282610328565b61058c81856103d2565b935061059c818560208601610342565b80840191505092915050565b7f227d000000000000000000000000000000000000000000000000000000000000815250565b5f6105d882610450565b91506105e3826104c0565b91506105ee826104e2565b6017820191506105fd82610556565b91506106098284610578565b9150610614826105a8565b60028201915081905092915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815250565b5f61065382610623565b601d820191506106638284610578565b915081905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6106a5826102b7565b91506106b0836102b7565b92508282019050808211156106c8576106c761066e565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f610705826102b7565b9150610710836102b7565b9250826107205761071f6106ce565b5b828204905092915050565b5f610735826102b7565b9150610740836102b7565b925082820261074e816102b7565b915082820484148315176107655761076461066e565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffdfe3c7376672077696474683d2235303022206865696768743d2235303022207374796c653d226261636b67726f756e642d636f6c6f723a20233134313631463b2220786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222076696577426f783d223230202d343030203230302031303030223e3c706174682069643d224c6f676f222066696c6c3d2223666666222066696c6c2d6f7061636974793d22312220643d226d3133332e3535392c3132342e303334632d2e3031332c322e3431322d312e3035392c342e3834382d322e3932332c362e3430322d322e3535382c312e3831392d352e3136382c332e3433392d372e3838382c342e3939362d31342e34342c382e3236322d33312e3034372c31322e3536352d34372e3637342c31322e3536392d382e3835382e3033362d31372e3833382d312e3237322d32362e3332382d332e3636332d392e3830362d322e3736362d31392e3038372d372e3131332d32372e3536322d31322e3737382d31332e3834322d382e3032352c392e3436382d32382e3630362c31362e3135332d33352e323635683063322e3033352d312e3833382c342e3235322d332e3534362c362e3436332d352e323234683063362e3432392d352e3635352c31362e3231382d322e3833352c32302e3335382c342e31372c342e3134332c352e3035372c382e3831362c392e3634392c31332e39322c31332e373334682e30333763352e3733362c362e3436312c31352e3335372d322e3235332c392e33382d382e34382c302c302d332e3531352d332e3531352d332e3531352d332e3531352d31312e34392d31312e3437382d35322e3635362d35322e3636342d36342e3833372d36342e3833376c2e3034392d2e303337632d312e3732352d312e3630362d322e3731392d332e3834372d322e3735312d362e3230346830632d2e3034362d322e3337352c312e3036322d342e3538322c322e3732362d362e32323968306c2e3138352d2e3134386830632e3039392d2e3036322c2e3232322d2e3134382c2e33372d2e323539683063322e30362d312e3336322c332e3935312d322e3632312c362e3034342d332e3834324335372e3736332d332e3437332c39372e37362d322e3334312c3132382e3633372c31382e3333326331362e3637312c392e3934362d32362e3334342c35342e3831332d33382e3635312c34302e3139392d362e3239392d362e3039362d31382e3036332d31372e3734332d31392e3636382d31382e3831312d362e3031362d342e3034372d31332e3036312c342e3737362d372e3735322c392e3735316c36382e3235342c36382e33373163312e3732342c312e3630312c322e3731342c332e38342c322e3733382c362e3139325a22207472616e73666f726d3d227363616c6528312e352c20312e352922202f3e3c2f7376673e4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa164736f6c634300081a000a"; /// @notice Deploys {SablierFlow} from precompiled bytecode. /// @dev A dummy {FlowNFTDescriptor} is deployed so that the user does not have to provide one. diff --git a/shell/prepare-artifacts.sh b/shell/prepare-artifacts.sh index c8bcbe81..9d3a1c2b 100755 --- a/shell/prepare-artifacts.sh +++ b/shell/prepare-artifacts.sh @@ -19,26 +19,26 @@ mkdir $artifacts \ "$artifacts/libraries" # Generate the artifacts with Forge -FOUNDRY_PROFILE=optimized forge build +forge build # Copy the production artifacts -cp out-optimized/SablierFlow.sol/SablierFlow.json $artifacts -cp out-optimized/FlowNFTDescriptor.sol/FlowNFTDescriptor.json $artifacts +cp out/SablierFlow.sol/SablierFlow.json $artifacts +cp out/FlowNFTDescriptor.sol/FlowNFTDescriptor.json $artifacts interfaces=./artifacts/interfaces -cp out-optimized/ISablierFlow.sol/ISablierFlow.json $interfaces -cp out-optimized/ISablierFlowBase.sol/ISablierFlowBase.json $interfaces -cp out-optimized/IFlowNFTDescriptor.sol/IFlowNFTDescriptor.json $interfaces +cp out/ISablierFlow.sol/ISablierFlow.json $interfaces +cp out/ISablierFlowBase.sol/ISablierFlowBase.json $interfaces +cp out/IFlowNFTDescriptor.sol/IFlowNFTDescriptor.json $interfaces erc20=./artifacts/interfaces/erc20 -cp out-optimized/IERC20.sol/IERC20.json $erc20 +cp out/IERC20.sol/IERC20.json $erc20 erc721=./artifacts/interfaces/erc721 -cp out-optimized/IERC721.sol/IERC721.json $erc721 -cp out-optimized/IERC721Metadata.sol/IERC721Metadata.json $erc721 +cp out/IERC721.sol/IERC721.json $erc721 +cp out/IERC721Metadata.sol/IERC721Metadata.json $erc721 libraries=./artifacts/libraries -cp out-optimized/Errors.sol/Errors.json $libraries +cp out/Errors.sol/Errors.json $libraries # Format the artifacts with Prettier bun prettier --write ./artifacts diff --git a/shell/update-precompiles.sh b/shell/update-precompiles.sh index f1e9d4f0..62c61b59 100755 --- a/shell/update-precompiles.sh +++ b/shell/update-precompiles.sh @@ -9,11 +9,11 @@ set -euo pipefail # Compile the contracts with Forge -FOUNDRY_PROFILE=optimized forge build +forge build # Retrieve the raw bytecodes, removing the "0x" prefix -flow=$(cat out-optimized/SablierFlow.sol/SablierFlow.json | jq -r '.bytecode.object' | cut -c 3-) -nft_descriptor=$(cat out-optimized/FlowNFTDescriptor.sol/FlowNFTDescriptor.json | jq -r '.bytecode.object' | cut -c 3-) +flow=$(cat out/SablierFlow.sol/SablierFlow.json | jq -r '.bytecode.object' | cut -c 3-) +nft_descriptor=$(cat out/FlowNFTDescriptor.sol/FlowNFTDescriptor.json | jq -r '.bytecode.object' | cut -c 3-) precompiles_path="precompiles/Precompiles.sol" if [ ! -f $precompiles_path ]; then diff --git a/tests/Base.t.sol b/tests/Base.t.sol index 2ca3634d..03ee2998 100644 --- a/tests/Base.t.sol +++ b/tests/Base.t.sol @@ -4,6 +4,8 @@ pragma solidity >=0.8.22; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { Test } from "forge-std/src/Test.sol"; import { FlowNFTDescriptor } from "src/FlowNFTDescriptor.sol"; +import { IFlowNFTDescriptor } from "src/interfaces/IFlowNFTDescriptor.sol"; +import { ISablierFlow } from "src/interfaces/ISablierFlow.sol"; import { SablierFlow } from "src/SablierFlow.sol"; import { ERC20MissingReturn } from "./mocks/ERC20MissingReturn.sol"; import { ERC20Mock } from "./mocks/ERC20Mock.sol"; @@ -30,8 +32,8 @@ abstract contract Base_Test is Assertions, Modifiers, Test { ERC20Mock internal usdc; ERC20MissingReturn internal usdt; - SablierFlow internal flow; - FlowNFTDescriptor internal nftDescriptor; + ISablierFlow internal flow; + IFlowNFTDescriptor internal nftDescriptor; /*////////////////////////////////////////////////////////////////////////// SET-UP FUNCTION @@ -40,15 +42,12 @@ abstract contract Base_Test is Assertions, Modifiers, Test { function setUp() public virtual { users.admin = payable(makeAddr("admin")); - if (!isBenchmarkProfile() && !isTestOptimizedProfile()) { - nftDescriptor = new FlowNFTDescriptor(); - flow = new SablierFlow(users.admin, nftDescriptor); - } else { - flow = deployOptimizedSablierFlow(); - } + // Deploy the Flow contracts. + deployOptimizedSablierFlow(); // Label the flow contract. vm.label(address(flow), "Flow"); + vm.label(address(nftDescriptor), "NFTDescriptor"); // Create new tokens and label them. createAndLabelTokens(); @@ -119,14 +118,11 @@ abstract contract Base_Test is Assertions, Modifiers, Test { return user; } - /// @dev Deploys {SablierFlow} from an optimized source compiled with `--via-ir`. - function deployOptimizedSablierFlow() internal returns (SablierFlow) { - nftDescriptor = FlowNFTDescriptor(deployCode("out-optimized/FlowNFTDescriptor.sol/FlowNFTDescriptor.json")); - - return SablierFlow( - deployCode( - "out-optimized/SablierFlow.sol/SablierFlow.json", abi.encode(users.admin, address(nftDescriptor)) - ) + /// @dev Deploys {FlowNFTDescriptor} and {SablierFlow} from an optimized source compiled with `--via-ir`. + function deployOptimizedSablierFlow() internal { + nftDescriptor = FlowNFTDescriptor(deployCode("out/FlowNFTDescriptor.sol/FlowNFTDescriptor.json")); + flow = ISablierFlow( + deployCode("out/SablierFlow.sol/SablierFlow.json", abi.encode(users.admin, address(nftDescriptor))) ); } diff --git a/tests/integration/concrete/set-nft-descriptor/setNFTDescriptor.t.sol b/tests/integration/concrete/set-nft-descriptor/setNFTDescriptor.t.sol index a2bf67cd..42f83555 100644 --- a/tests/integration/concrete/set-nft-descriptor/setNFTDescriptor.t.sol +++ b/tests/integration/concrete/set-nft-descriptor/setNFTDescriptor.t.sol @@ -24,7 +24,7 @@ contract SetNFTDescriptor_Integration_Concrete_Test is Shared_Integration_Concre // It should re-set the NFT descriptor flow.setNFTDescriptor(nftDescriptor); vm.expectCall(address(nftDescriptor), abi.encodeCall(FlowNFTDescriptor.tokenURI, (flow, 1))); - flow.tokenURI({ streamId: defaultStreamId }); + flow.tokenURI(defaultStreamId); } function test_WhenNewAndOldNFTDescriptorsAreNotSame() external whenCallerAdmin { diff --git a/tests/integration/concrete/token-uri/tokenURI.t.sol b/tests/integration/concrete/token-uri/tokenURI.t.sol index c881bc3b..52c9916f 100644 --- a/tests/integration/concrete/token-uri/tokenURI.t.sol +++ b/tests/integration/concrete/token-uri/tokenURI.t.sol @@ -8,12 +8,12 @@ import { Shared_Integration_Concrete_Test } from "../Concrete.t.sol"; contract TokenURI_Integration_Concrete_Test is Shared_Integration_Concrete_Test { function test_RevertGiven_NFTNotExist() external { vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, nullStreamId)); - flow.tokenURI({ streamId: nullStreamId }); + flow.tokenURI(nullStreamId); } function test_GivenNFTExists() external view { // It should return the correct token URI - string memory actualURI = flow.tokenURI({ streamId: defaultStreamId }); + string memory actualURI = flow.tokenURI(defaultStreamId); // solhint-disable max-line-length,quotes string memory expectedURI = "data:application/json;base64,eyJkZXNjcmlwdGlvbiI6ICJUaGlzIE5GVCByZXByZXNlbnRzIGEgcGF5bWVudCBzdHJlYW0gaW4gU2FibGllciBGbG93IiwiZXh0ZXJuYWxfdXJsIjogImh0dHBzOi8vc2FibGllci5jb20iLCJuYW1lIjogIlNhYmxpZXIgRmxvdyIsImltYWdlIjogImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjNhV1IwYUQwaU5UQXdJaUJvWldsbmFIUTlJalV3TUNJZ2MzUjViR1U5SW1KaFkydG5jbTkxYm1RdFkyOXNiM0k2SUNNeE5ERTJNVVk3SWlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUhacFpYZENiM2c5SWpJd0lDMDBNREFnTWpBd0lERXdNREFpUGp4d1lYUm9JR2xrUFNKTWIyZHZJaUJtYVd4c1BTSWpabVptSWlCbWFXeHNMVzl3WVdOcGRIazlJakVpSUdROUltMHhNek11TlRVNUxERXlOQzR3TXpSakxTNHdNVE1zTWk0ME1USXRNUzR3TlRrc05DNDRORGd0TWk0NU1qTXNOaTQwTURJdE1pNDFOVGdzTVM0NE1Ua3ROUzR4Tmpnc015NDBNemt0Tnk0NE9EZ3NOQzQ1T1RZdE1UUXVORFFzT0M0eU5qSXRNekV1TURRM0xERXlMalUyTlMwME55NDJOelFzTVRJdU5UWTVMVGd1T0RVNExqQXpOaTB4Tnk0NE16Z3RNUzR5TnpJdE1qWXVNekk0TFRNdU5qWXpMVGt1T0RBMkxUSXVOelkyTFRFNUxqQTROeTAzTGpFeE15MHlOeTQxTmpJdE1USXVOemM0TFRFekxqZzBNaTA0TGpBeU5TdzVMalEyT0MweU9DNDJNRFlzTVRZdU1UVXpMVE0xTGpJMk5XZ3dZekl1TURNMUxURXVPRE00TERRdU1qVXlMVE11TlRRMkxEWXVORFl6TFRVdU1qSTBhREJqTmk0ME1qa3ROUzQyTlRVc01UWXVNakU0TFRJdU9ETTFMREl3TGpNMU9DdzBMakUzTERRdU1UUXpMRFV1TURVM0xEZ3VPREUyTERrdU5qUTVMREV6TGpreUxERXpMamN6TkdndU1ETTNZelV1TnpNMkxEWXVORFl4TERFMUxqTTFOeTB5TGpJMU15dzVMak00TFRndU5EZ3NNQ3d3TFRNdU5URTFMVE11TlRFMUxUTXVOVEUxTFRNdU5URTFMVEV4TGpRNUxURXhMalEzT0MwMU1pNDJOVFl0TlRJdU5qWTBMVFkwTGpnek55MDJOQzQ0TXpkc0xqQTBPUzB1TURNM1l5MHhMamN5TlMweExqWXdOaTB5TGpjeE9TMHpMamcwTnkweUxqYzFNUzAyTGpJd05HZ3dZeTB1TURRMkxUSXVNemMxTERFdU1EWXlMVFF1TlRneUxESXVOekkyTFRZdU1qSTVhREJzTGpFNE5TMHVNVFE0YURCakxqQTVPUzB1TURZeUxDNHlNakl0TGpFME9Dd3VNemN0TGpJMU9XZ3dZekl1TURZdE1TNHpOaklzTXk0NU5URXRNaTQyTWpFc05pNHdORFF0TXk0NE5ESkROVGN1TnpZekxUTXVORGN6TERrM0xqYzJMVEl1TXpReExERXlPQzQyTXpjc01UZ3VNek15WXpFMkxqWTNNU3c1TGprME5pMHlOaTR6TkRRc05UUXVPREV6TFRNNExqWTFNU3cwTUM0eE9Ua3ROaTR5T1RrdE5pNHdPVFl0TVRndU1EWXpMVEUzTGpjME15MHhPUzQyTmpndE1UZ3VPREV4TFRZdU1ERTJMVFF1TURRM0xURXpMakEyTVN3MExqYzNOaTAzTGpjMU1pdzVMamMxTVd3Mk9DNHlOVFFzTmpndU16Y3hZekV1TnpJMExERXVOakF4TERJdU56RTBMRE11T0RRc01pNDNNemdzTmk0eE9USmFJaUIwY21GdWMyWnZjbTA5SW5OallXeGxLREV1TlN3Z01TNDFLU0lnTHo0OEwzTjJaejQ9In0="; diff --git a/tests/utils/Precompiles.t.sol b/tests/utils/Precompiles.t.sol index 5f8ea486..1602f6e6 100644 --- a/tests/utils/Precompiles.t.sol +++ b/tests/utils/Precompiles.t.sol @@ -12,15 +12,10 @@ contract Precompiles_Test is Base_Test { Precompiles internal precompiles = new Precompiles(); - modifier onlyTestOptimizedProfile() { - if (isTestOptimizedProfile()) { - _; - } - } - - function test_DeployFlow() external onlyTestOptimizedProfile { + function test_DeployFlow() external { + deployOptimizedSablierFlow(); address actualSablierFlow = address(precompiles.deploySablierFlow(users.admin, nftDescriptor)); - address expectedSablierFlow = address(deployOptimizedSablierFlow()); + address expectedSablierFlow = address(flow); bytes memory expectedSablierFlowCode = adjustBytecode(expectedSablierFlow.code, expectedSablierFlow, actualSablierFlow); assertEq(actualSablierFlow.code, expectedSablierFlowCode, "bytecodes mismatch"); diff --git a/tests/utils/Utils.sol b/tests/utils/Utils.sol index 88ca1d7b..56cc2a80 100644 --- a/tests/utils/Utils.sol +++ b/tests/utils/Utils.sol @@ -79,18 +79,6 @@ abstract contract Utils is CommonBase, Constants, PRBMathUtils { return amount * scaleFactor; } - /// @dev Checks if the Foundry profile is "benchmark". - function isBenchmarkProfile() internal view returns (bool) { - string memory profile = vm.envOr({ name: "FOUNDRY_PROFILE", defaultValue: string("default") }); - return Strings.equal(profile, "benchmark"); - } - - /// @dev Checks if the Foundry profile is "test-optimized". - function isTestOptimizedProfile() internal view returns (bool) { - string memory profile = vm.envOr({ name: "FOUNDRY_PROFILE", defaultValue: string("default") }); - return Strings.equal(profile, "test-optimized"); - } - /// @dev Stops the active prank and sets a new one. function resetPrank(address msgSender) internal { vm.stopPrank();