{"matchId":"56674873","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-10-21T18:51:46Z","creationBytecode":{"onchainBytecode":"0x610100604052348015610010575f5ffd5b5060405161575a38038061575a83398101604081905261002f9161033f565b866001600160a01b03811661005d57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b610066816102b9565b506001600160a01b03861661008e5760405163d92e233d60e01b815260040160405180910390fd5b846001600160a01b03163b5f036100b8576040516311a1e69760e01b815260040160405180910390fd5b836001600160a01b03163b5f036100e257604051633647040f60e01b815260040160405180910390fd5b826001600160a01b03163b5f0361010c57604051639a11fb3160e01b815260040160405180910390fd5b816001600160a01b03163b5f036101365760405163037e6a8560e01b815260040160405180910390fd5b806001600160a01b03163b5f036101605760405163614e3ba560e11b815260040160405180910390fd5b826001600160a01b0316826001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101ca91906103c0565b6001600160a01b03161415806102515750806001600160a01b0316826001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610221573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024591906103c0565b6001600160a01b031614155b1561026f5760405163037e6a8560e01b815260040160405180910390fd5b600280546001600160a01b03199081166001600160a01b03988916179091556003805490911695871695909517909455918416608052831660a052821660c0521660e052506103e0565b600180546001600160a01b03191690556102d2816102d5565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b038116811461033a575f5ffd5b919050565b5f5f5f5f5f5f5f60e0888a031215610355575f5ffd5b61035e88610324565b965061036c60208901610324565b955061037a60408901610324565b945061038860608901610324565b935061039660808901610324565b92506103a460a08901610324565b91506103b260c08901610324565b905092959891949750929550565b5f602082840312156103d0575f5ffd5b6103d982610324565b9392505050565b60805160a05160c05160e05161530f61044b5f395f81816102e5015281816104c401526106ee01525f8181610293015281816104a301526106cc01525f81816102600152818161048201526106aa01525f8181610348015281816104610152610688015261530f5ff3fe60806040526004361061011e575f3560e01c80637f1e9ef61161009d578063b4b57c3911610062578063b4b57c3914610337578063bdaad4881461036a578063e30c397814610389578063e74b981b146103a6578063f2fde38b146103c5575f5ffd5b80637f1e9ef6146102825780638854a0ff146102b55780638d72647e146102d45780638da5cb5b14610307578063a64ed8ba14610323575f5ffd5b806354fd4d50116100e357806354fd4d50146101eb578063634282af14610208578063715018a61461022757806379ba50971461023b5780637c887c591461024f575f5ffd5b806319f3736114610129578063266cedb31461016c5780633a5fedb71461019757806346904840146101b6578063476343ee146101d5575f5ffd5b3661012557005b5f5ffd5b348015610134575f5ffd5b50610157610143366004610b78565b60056020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61017f61017a366004610bdd565b6103e4565b6040516001600160a01b039091168152602001610163565b3480156101a2575f5ffd5b5061017f6101b1366004610c5a565b610644565b3480156101c1575f5ffd5b5060025461017f906001600160a01b031681565b3480156101e0575f5ffd5b506101e96107be565b005b3480156101f6575f5ffd5b5060025b604051908152602001610163565b348015610213575f5ffd5b5061017f610222366004610ce2565b61087d565b348015610232575f5ffd5b506101e96108a5565b348015610246575f5ffd5b506101e96108c6565b34801561025a575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561028d575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c0575f5ffd5b5060035461017f906001600160a01b031681565b3480156102df575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610312575f5ffd5b505f546001600160a01b031661017f565b34801561032e575f5ffd5b506004546101fa565b348015610342575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610375575f5ffd5b506101e9610384366004610b78565b61090f565b348015610394575f5ffd5b506001546001600160a01b031661017f565b3480156103b1575f5ffd5b506101e96103c0366004610b78565b610996565b3480156103d0575f5ffd5b506101e96103df366004610b78565b610a13565b5f8515806103f25750604086115b156104105760405163430f13b360e01b815260040160405180910390fd5b83158061041d5750601084115b1561043b5760405163010466f160e21b815260040160405180910390fd5b6104453383610a83565b878787873360035f9054906101000a90046001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006040516104ef90610b50565b6105029a99989796959493929190610d21565b8190604051809103905ff590508015801561051f573d5f5f3e3d5ffd5b506004805460018082019092557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0384169081179091555f8181526005602052604090819020805460ff1916909317909255905191925033917f5314f94e6e2d1a502483a5b446938dee47de600f90cbf915d89632d58a71aa2b906105c1908b908b908b908b908b90610d8e565b60405180910390a3341561063a5760405162de16a360e71b81523360048201526001600160a01b03821690636f0b518090349060240160206040518083038185885af1158015610613573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106389190610dc7565b505b9695505050505050565b5f5f6040518060200161065690610b50565b601f1982820381018352601f909101166040819052600354610716918a918a918a918a918f916001600160a01b0316907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090602001610d21565b60408051601f19818403018152908290526107349291602001610df5565b60405160208183030381529060405280519060200120905060ff60f81b3061075c8a86610a83565b6040516001600160f81b031993909316602084015260609190911b6bffffffffffffffffffffffff1916602183015260358201526055810182905260750160408051601f19818403018152919052805160209091012098975050505050505050565b60025460405147915f916001600160a01b039091169083908381818185875af1925050503d805f811461080c576040519150601f19603f3d011682016040523d82523d5f602084013e610811565b606091505b5050905080610833576040516312171d8360e31b815260040160405180910390fd5b600254604080516001600160a01b039092168252602082018490527fc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a910160405180910390a15050565b6004818154811061088c575f80fd5b5f918252602090912001546001600160a01b0316905081565b6108ad610abf565b604051638905116560e01b815260040160405180910390fd5b60015433906001600160a01b031681146109035760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61090c81610aed565b50565b610917610abf565b806001600160a01b03163b5f03610941576040516311a1e69760e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f1386da33541fecf49b0f53895aef3f30f6e3e08755deb017e106e7ae4f4c976d906020015b60405180910390a150565b61099e610abf565b6001600160a01b0381166109c55760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f7a7b5a0a132f9e0581eb8527f66eae9ee89c2a3e79d4ac7e41a1f1f4d48a7fc29060200161098b565b610a1b610abf565b600180546001600160a01b0383166001600160a01b03199091168117909155610a4b5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b03841660208201529081018290525f9060600160405160208183030381529060405280519060200120905092915050565b5f546001600160a01b03163314610aeb5760405163118cdaa760e01b81523360048201526024016108fa565b565b600180546001600160a01b031916905561090c815f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6144c880610e1283390190565b80356001600160a01b0381168114610b73575f5ffd5b919050565b5f60208284031215610b88575f5ffd5b610b9182610b5d565b9392505050565b5f5f83601f840112610ba8575f5ffd5b50813567ffffffffffffffff811115610bbf575f5ffd5b602083019150836020828501011115610bd6575f5ffd5b9250929050565b5f5f5f5f5f5f60808789031215610bf2575f5ffd5b863567ffffffffffffffff811115610c08575f5ffd5b610c1489828a01610b98565b909750955050602087013567ffffffffffffffff811115610c33575f5ffd5b610c3f89828a01610b98565b979a9699509760408101359660609091013595509350505050565b5f5f5f5f5f5f60808789031215610c6f575f5ffd5b610c7887610b5d565b9550602087013567ffffffffffffffff811115610c93575f5ffd5b610c9f89828a01610b98565b909650945050604087013567ffffffffffffffff811115610cbe575f5ffd5b610cca89828a01610b98565b979a9699509497949695606090950135949350505050565b5f60208284031215610cf2575f5ffd5b5035919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b61010081525f610d3661010083018c8e610cf9565b8281036020840152610d49818b8d610cf9565b6001600160a01b03998a16604085015297891660608401525050938616608085015291851660a0840152841660c083015290921660e090920191909152949350505050565b606081525f610da1606083018789610cf9565b8281036020840152610db4818688610cf9565b9150508260408301529695505050505050565b5f60208284031215610dd7575f5ffd5b5051919050565b5f81518060208401855e5f93019283525090919050565b5f610e09610e038386610dde565b84610dde565b94935050505056fe6101a0604052348015610010575f5ffd5b506040516144c83803806144c883398101604081905261002f91610877565b8787600361003d83826109cb565b50600461004a82826109cb565b5050600160055550336080526001600160a01b0386811660a05285811660c05284811660e0528381166101008190528382166101205290821661014081905230818110610160819052604051630b4c774160e11b815260048101929092526024820192909252612710604482015290915f91631698ee8290606401602060405180830381865afa1580156100e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101049190610a85565b90506001600160a01b03811661018e5760405163a167129560e01b81523060048201526001600160a01b038481166024830152612710604483015286169063a1671295906064016020604051808303815f875af1158015610167573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061018b9190610a85565b90505b806001600160a01b0316610180816001600160a01b0316815250505f816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156101e6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061020a9190610ab1565b5050505050509050806001600160a01b03165f0361028f576001600160a01b03821663f637731d61023a856102b5565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f604051808303815f87803b158015610278575f5ffd5b505af115801561028a573d5f5f3e3d5ffd5b505050505b6102a5306b033b2e3c9fd0803ce8000000610318565b5050505050505050505050610bd4565b5f806102cc6b0295be96e640669720000000610355565b9050826102f7576102f26102ed670de0b6b3a7640000600160c01b846103bb565b610471565b610311565b6103116102ed82600160c01b670de0b6b3a76400006103bb565b9392505050565b6001600160a01b0382166103465760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6103515f83836105c9565b5050565b5f8061036083610649565b905061036c8180610b64565b61038d6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b61039f90674a03ce68d2155555610b64565b6103b190670de0b6b3a7640000610b64565b6103119190610ba2565b5f838302815f1985870982811083820303915050805f036103ef578382816103e5576103e5610b8e565b0492505050610311565b80841161040657610406600385150260111861067c565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f6001821161047e575090565b816001600160801b82106104975760809190911c9060401b5b6801000000000000000082106104b25760409190911c9060201b5b64010000000082106104c95760209190911c9060101b5b6201000082106104de5760109190911c9060081b5b61010082106104f25760089190911c9060041b5b601082106105055760049190911c9060021b5b600482106105115760011b5b600302600190811c9081858161052957610529610b8e565b048201901c9050600181858161054157610541610b8e565b048201901c9050600181858161055957610559610b8e565b048201901c9050600181858161057157610571610b8e565b048201901c9050600181858161058957610589610b8e565b048201901c905060018185816105a1576105a1610b8e565b048201901c90506105c08185816105ba576105ba610b8e565b04821190565b90039392505050565b60065460ff161580156105e457506001600160a01b03831615155b80156105f957506001600160a01b0383163014155b801561061b575060ff5f5c16801561061957506001600160a01b03821630145b155b1561063957604051632b36b06160e01b815260040160405180910390fd5b61064483838361068d565b505050565b5f8161066c6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b6106769190610bc1565b92915050565b634e487b715f52806020526024601cfd5b6001600160a01b0383166106b7578060025f8282546106ac9190610b7b565b909155506107279050565b6001600160a01b0383165f90815260208190526040902054818110156107095760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161033d565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661074357600280548290039055610761565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107a691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126107d6575f5ffd5b81516001600160401b038111156107ef576107ef6107b3565b604051601f8201601f19908116603f011681016001600160401b038111828210171561081d5761081d6107b3565b604052818152838201602001851015610834575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b6001600160a01b0381168114610864575f5ffd5b50565b805161087281610850565b919050565b5f5f5f5f5f5f5f5f610100898b03121561088f575f5ffd5b88516001600160401b038111156108a4575f5ffd5b6108b08b828c016107c7565b60208b015190995090506001600160401b038111156108cd575f5ffd5b6108d98b828c016107c7565b97505060408901516108ea81610850565b60608a01519096506108fb81610850565b60808a015190955061090c81610850565b60a08a015190945061091d81610850565b925061092b60c08a01610867565b915061093960e08a01610867565b90509295985092959890939650565b600181811c9082168061095c57607f821691505b60208210810361097a57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561064457805f5260205f20601f840160051c810160208510156109a55750805b601f840160051c820191505b818110156109c4575f81556001016109b1565b5050505050565b81516001600160401b038111156109e4576109e46107b3565b6109f8816109f28454610948565b84610980565b6020601f821160018114610a2a575f8315610a135750848201515b5f19600385901b1c1916600184901b1784556109c4565b5f84815260208120601f198516915b82811015610a595787850151825560209485019460019092019101610a39565b5084821015610a7657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215610a95575f5ffd5b815161031181610850565b805161ffff81168114610872575f5ffd5b5f5f5f5f5f5f5f60e0888a031215610ac7575f5ffd5b8751610ad281610850565b8097505060208801518060020b8114610ae9575f5ffd5b9550610af760408901610aa0565b9450610b0560608901610aa0565b9350610b1360808901610aa0565b925060a088015163ffffffff81168114610b2b575f5ffd5b60c08901519092508015158114610b40575f5ffd5b8091505092959891949750929550565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761067657610676610b50565b8082018082111561067657610676610b50565b634e487b7160e01b5f52601260045260245ffd5b5f82610bbc57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561067657610676610b50565b60805160a05160c05160e051610100516101205161014051610160516101805161377e610d4a5f395f8181610376015281816109ec01528181611ea10152612d0f01525f81816104f20152818161098b01528181610ecf01528181611ec6015281816121ae015281816123f50152612cb701525f81816106770152818161187701528181612388015281816124850152818161254b0152818161258c015281816126f4015281816127a0015281816128620152818161293d015281816129e901528181612dcf01528181612e6b0152612f9801525f81816105df01528181610e600152818161241a015281816124560152818161250b0152818161268a015281816126c601528181612d650152612da101525f6105ac01525f8181610763015281816127ca015261288a01525f81816106120152610b0101525f81816102b20152610aa701525f81816107aa01528181610c3201528181610d740152818161119c015281816114820152612ed9015261377e5ff3fe608060405260043610610275575f3560e01c806371640de31161014a578063a8aa1b31116100be578063cd3293de11610078578063cd3293de146107e0578063d3618cca146107f4578063dd62ed3e14610808578063e4849b321461084c578063e7c2b7721461086b578063f6ccbda514610884575f5ffd5b8063a8aa1b3114610714578063a9059cbb14610733578063b4b57c3914610752578063b956993b14610785578063c45a015514610799578063c8796572146107cc575f5ffd5b80638d4b66c01161010f5780638d4b66c0146106475780638d72647e1461066657806395d89b41146106995780639c43a050146106ad578063a6195fd3146106c1578063a64190c4146106e0575f5ffd5b806371640de3146105865780637c887c591461059b5780637f1e9ef6146105ce5780638854a0ff146106015780638976254314610634575f5ffd5b806323b872dd116101ec5780635c1624ef116101a65780635c1624ef146104af5780635ed0447d146104c2578063604b1eba146104e1578063667022fd146105145780636f0b51801461053f57806370a0823114610552575f5ffd5b806323b872dd146103e9578063313ce56714610408578063398482d8146104295780634beb394c1461043d578063559f05dc1461047c578063577bd3361461049b575f5ffd5b806316e457f01161023d57806316e457f01461035157806316f0115b1461036557806318160ddd1461039857806320cce74b146103ac57806320f1fc61146103c057806323a69e75146103c8575f5ffd5b806302c7e7af1461027957806302d05d3f146102a157806303fd2a45146102ec57806306fdde0314610301578063095ea7b314610322575b5f5ffd5b348015610284575f5ffd5b5061028e60075481565b6040519081526020015b60405180910390f35b3480156102ac575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610298565b3480156102f7575f5ffd5b506102d461dead81565b34801561030c575f5ffd5b506103156108a2565b604051610298919061319c565b34801561032d575f5ffd5b5061034161033c3660046131e5565b610932565b6040519015158152602001610298565b34801561035c575f5ffd5b5061028e61094b565b348015610370575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a3575f5ffd5b5060025461028e565b3480156103b7575f5ffd5b506102d4610985565b61028e6109b4565b3480156103d3575f5ffd5b506103e76103e236600461320f565b6109d1565b005b3480156103f4575f5ffd5b5061034161040336600461328b565b610a47565b348015610413575f5ffd5b5060125b60405160ff9091168152602001610298565b348015610434575f5ffd5b5061028e610a6c565b348015610448575f5ffd5b5061045c6104573660046132c9565b610a78565b604080519485526020850193909352918301526060820152608001610298565b348015610487575f5ffd5b506103416104963660046132e0565b610a95565b3480156104a6575f5ffd5b5061028e610b73565b61028e6104bd3660046132c9565b610b9b565b3480156104cd575f5ffd5b5061045c6104dc3660046131e5565b610bc9565b3480156104ec575f5ffd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b34801561051f575f5ffd5b5061028e61052e3660046132e0565b60086020525f908152604090205481565b61028e61054d3660046132e0565b610c1e565b34801561055d575f5ffd5b5061028e61056c3660046132e0565b6001600160a01b03165f9081526020819052604090205490565b348015610591575f5ffd5b5061028e60095481565b3480156105a6575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d9575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561060c575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561063f575f5ffd5b506104175f81565b348015610652575f5ffd5b5061028e6106613660046132e0565b610c9f565b348015610671575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a4575f5ffd5b50610315610ccc565b3480156106b8575f5ffd5b50610417600281565b3480156106cc575f5ffd5b5061028e6106db3660046132fb565b610cdb565b3480156106eb575f5ffd5b506106ff6106fa3660046132c9565b610d04565b60408051928352602083019190915201610298565b34801561071f575f5ffd5b50600a546102d4906001600160a01b031681565b34801561073e575f5ffd5b5061034161074d3660046131e5565b610d2f565b34801561075d575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b348015610790575f5ffd5b50610417600181565b3480156107a4575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d7575f5ffd5b506106ff610d3c565b3480156107eb575f5ffd5b5061028e610f57565b3480156107ff575f5ffd5b506103e7610f63565b348015610813575f5ffd5b5061028e61082236600461331b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610857575f5ffd5b5061028e6108663660046132c9565b610fbd565b348015610876575f5ffd5b506006546103419060ff1681565b34801561088f575f5ffd5b5060065461041790610100900460ff1681565b6060600380546108b190613352565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90613352565b80156109285780601f106108ff57610100808354040283529160200191610928565b820191905f5260205f20905b81548152906001019060200180831161090b57829003601f168201915b5050505050905090565b5f3361093f818585610fda565b60019150505b92915050565b5f610954610fec565b61095d33611016565b335f818152602081905260408120546109769291611063565b90506109826001600555565b90565b5f6109af7f00000000000000000000000000000000000000000000000000000000000000006112a4565b905090565b5f6109bd610fec565b6109c633611016565b61097633345f611300565b60ff6101005f5c04161580610a0f5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b80610a1957508315155b80610a2357508215155b15610a415760405163f7a632f560e01b815260040160405180910390fd5b50505050565b5f33610a54858285611593565b610a5f85858561160d565b60019150505b9392505050565b5f6109af60075461166a565b5f5f5f5f610a863386610bc9565b93509350935093509193509193565b6006545f9060ff1615801561094557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061094557506040516370a0823160e01b81526001600160a01b0383811660048301525f917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015610b48573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6c919061338a565b1192915050565b5f6b0295be96e640669720000000600754612710610b9191906133b5565b6109af91906133e0565b5f610ba4610fec565b610bad33611016565b610bb8333484611300565b9050610bc46001600555565b919050565b6006545f9081908190819060ff1615610bec57505f925082915081905083610c15565b610bf686866116cf565b9195509350915081610c0884876133f3565b610c1291906133f3565b90505b92959194509250565b5f610c27610fec565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c7057604051630636a15760e11b815260040160405180910390fd5b60065460ff1615610c945760405163e6a0d45f60e01b815260040160405180910390fd5b610bb882345f611300565b6001600160a01b0381165f90815260086020526040812054610945906a18d0bf423c03d8de0000006133f3565b6060600480546108b190613352565b5f610ce4610fec565b610ced33611016565b610cf8338484611063565b90506109456001600555565b6006545f90819060ff1615610d1d57505f928392509050565b610d26836117a6565b91509150915091565b5f3361093f81858561160d565b5f5f610d46610fec565b600654610100900460ff16600114610d71576040516330aad80b60e01b815260040160405180910390fd5b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dce573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df29190613406565b6040805160808101825260095481526001600160a01b03838116602083019081526001600160801b0383850181815260608501828152955163fc6f786560e01b815294516004860152915183166024850152905181166044840152925190921660648201529192505f9182917f0000000000000000000000000000000000000000000000000000000000000000169063fc6f78659060840160408051808303815f875af1158015610ea5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ec99190613421565b915091507f0000000000000000000000000000000000000000000000000000000000000000610ef9578082610efc565b81815b60408051838152602081018390529297509095506001600160a01b038516917f2e4fb6077d4acf86e12bb7411fb82b2b3eaa6a49787f4b1e17b423e7ea841169910160405180910390a2505050610f536001600555565b9091565b5f6109af600754611807565b610f6b610fec565b60065460ff1680610f8a57506b0295be96e64066972000000060075414155b15610fa8576040516325a6766f60e21b815260040160405180910390fd5b610fb15f611860565b610fbb6001600555565b565b5f610fc6610fec565b610fcf33611016565b610bb833835f611063565b610fe78383836001611909565b505050565b60026005540361100f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600555565b60065460ff161561103a5760405163e6a0d45f60e01b815260040160405180910390fd5b61104381610a95565b61106057604051637c75aa6f60e11b815260040160405180910390fd5b50565b5f825f036110845760405163617ab12d60e11b815260040160405180910390fd5b6001600160a01b0384165f908152602081905260409020548311156110bc57604051631e9acf1760e31b815260040160405180910390fd5b5f6110c6846117a6565b90925090505f8290036110ec5760405163617ab12d60e11b815260040160405180910390fd5b8282101561110d57604051638199f5f360e01b815260040160405180910390fd5b5f8460075461111c91906133f3565b6007819055905060015f805c60ff19168217905d5061113c86308761160d565b5f60ff19815c16815d506040805186815260208101859052908101839052606081018290526001600160a01b038716907f483f8aec0fd892ac72ad1ba8d0e9c9e73db59c12d263fd71de480b5b3deeae3c9060800160405180910390a25f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611202576040519150601f19603f3d011682016040523d82523d5f602084013e611207565b606091505b505090508061122957604051634033e4e360e01b815260040160405180910390fd5b5f876001600160a01b0316856040515f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b505090508061129957604051630ec6ac4160e21b815260040160405180910390fd5b505050509392505050565b5f5f6112bb6b0295be96e64066972000000061166a565b9050826112e6576112e16112dc670de0b6b3a7640000600160c01b846119db565b611a91565b610a65565b610a656112dc82600160c01b670de0b6b3a76400006119db565b5f5f5f61130d86866116cf565b919450925090505f839003611377576001600160a01b0386165f908152600860205260409020546a18d0bf423c03d8de0000001161135e57604051636bf4c8e960e11b815260040160405180910390fd5b60405163617ab12d60e11b815260040160405180910390fd5b8383101561139857604051638199f5f360e01b815260040160405180910390fd5b5f836007546113a79190613443565b60078190556001600160a01b0388165f908152600860205260408120805492935086929091906113d8908490613443565b909155506113e9905030888661160d565b6040805184815260208101849052908101859052606081018290526001600160a01b038816907f064fb1933e186be0b289a87e98518dc18cc9856ecbc9f1353d1a138ddf733ec59060800160405180910390a25f8261144885896133f3565b61145291906133f3565b90506b0295be96e6406697200000008203611479576114796114748285613443565b611860565b8215611511575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846040515f6040518083038185875af1925050503d805f81146114e8576040519150601f19603f3d011682016040523d82523d5f602084013e6114ed565b606091505b505090508061150f57604051634033e4e360e01b815260040160405180910390fd5b505b8015611299575f886001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611560576040519150601f19603f3d011682016040523d82523d5f602084013e611565565b606091505b505090508061158757604051633c31275160e21b815260040160405180910390fd5b50505050509392505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f198114610a4157818110156115ff57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b610a4184848484035f611909565b6001600160a01b03831661163657604051634b637e8f60e11b81525f60048201526024016115f6565b6001600160a01b03821661165f5760405163ec442f0560e01b81525f60048201526024016115f6565b610fe7838383611be9565b5f5f61167583611c64565b905061168181806133b5565b6116a16a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b6116b390674a03ce68d21555556133b5565b6116c590670de0b6b3a76400006133b5565b610a6591906133e0565b6007545f9081908190816116e66064612710613443565b6116f2612710886133b5565b6116fc91906133e0565b90506117088282611c86565b94505f611721836b0295be96e6406697200000006133f3565b90508086111561172f578095505b6001600160a01b0388165f9081526008602052604081205461175c906a18d0bf423c03d8de0000006133f3565b90508087111561176a578096505b865f03611783575f5f5f9650965096505050505061179f565b61178d8488611d58565b955061179886611dfa565b9450505050505b9250925092565b6007545f9081908315806117b957508084115b156117c957505f93849350915050565b5f6117d48286611e2a565b90506117df81611dfa565b92508281116117f457505f9485945092505050565b6117fe83826133f3565b93505050915091565b5f674a03ce68d215555561181a83611c64565b61183a6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b61184c90674a03ce68d21555556133b5565b61185691906133e0565b61094591906133f3565b6006805460ff191660011790556001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d0e30db06118a683476133f3565b6040518263ffffffff1660e01b81526004015f604051808303818588803b1580156118cf575f5ffd5b505af11580156118e1573d5f5f3e3d5ffd5b50505050506118ee611e9e565b80156118fd57506118fd612355565b61106057611060612783565b6001600160a01b0384166119325760405163e602df0560e01b81525f60048201526024016115f6565b6001600160a01b03831661195b57604051634a1406b160e11b81525f60048201526024016115f6565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015610a4157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516119cd91815260200190565b60405180910390a350505050565b5f838302815f1985870982811083820303915050805f03611a0f57838281611a0557611a056133cc565b0492505050610a65565b808411611a2657611a266003851502601118612b19565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f60018211611a9e575090565b816001600160801b8210611ab75760809190911c9060401b5b680100000000000000008210611ad25760409190911c9060201b5b6401000000008210611ae95760209190911c9060101b5b620100008210611afe5760109190911c9060081b5b6101008210611b125760089190911c9060041b5b60108210611b255760049190911c9060021b5b60048210611b315760011b5b600302600190811c90818581611b4957611b496133cc565b048201901c90506001818581611b6157611b616133cc565b048201901c90506001818581611b7957611b796133cc565b048201901c90506001818581611b9157611b916133cc565b048201901c90506001818581611ba957611ba96133cc565b048201901c90506001818581611bc157611bc16133cc565b048201901c9050611be0818581611bda57611bda6133cc565b04821190565b90039392505050565b60065460ff16158015611c0457506001600160a01b03831615155b8015611c1957506001600160a01b0383163014155b8015611c3b575060ff5f5c168015611c3957506001600160a01b03821630145b155b15611c5957604051632b36b06160e01b815260040160405180910390fd5b610fe7838383612b2a565b5f816118566a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f5f611c9184611c64565b90505f81611cb56a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611cc790674a03ce68d21555556133b5565b611cd191906133e0565b90505f611cde8583613443565b611cfe6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d1090674a03ce68d21555556133b5565b611d1a91906133e0565b9050611d27816001613443565b8311611d38575f9350505050610945565b6001611d4482856133f3565b611d4e91906133f3565b9695505050505050565b5f5f611d6384611c64565b905080611d866a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d9890674a03ce68d21555556133b5565b611da291906133e0565b611dac84836133f3565b611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611dde90674a03ce68d21555556133b5565b611de891906133e0565b611df291906133f3565b949350505050565b5f612710600181611e0c6064866133b5565b611e169190613443565b611e2091906133f3565b61094591906133e0565b5f5f611e3584611c64565b9050611e418382613443565b611e616a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611e7390674a03ce68d21555556133b5565b611e7d91906133e0565b81611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f7f000000000000000000000000000000000000000000000000000000000000000081611eea7f00000000000000000000000000000000000000000000000000000000000000006112a4565b9050816001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f28573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4c919061346c565b6001600160801b031615611f62575f9250505090565b5f826001600160a01b03166370cf754a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f9f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fc3919061346c565b90506c0c9f2c9cd04674edea400000006001600160801b0382161015611fec575f935050505090565b5f6120046c0c9f2c9cd04674edea4000000083613485565b60405163f30dba9360e01b8152620d899f1960048201529091506001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa158015612058573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061207c919061346c565b6001600160801b0316118061210b575060405163f30dba9360e01b8152620d89a060048201526001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa1580156120dc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612100919061346c565b6001600160801b0316115b1561211a575f94505050505090565b5f5f856001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015612158573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061217c91906134c4565b505050505091509150846001600160a01b0316826001600160a01b0316036121ab576001965050505050505090565b5f7f00000000000000000000000000000000000000000000000000000000000000006121da5762027e5c6121e0565b62027e5c195b90506121ed878383612c43565b156121ff575f97505050505050505090565b6001600160a01b0380871690841611600161ff00195f805c9190911661010017905d50604051630251596160e31b81523060048201528115156024820152600160448201526001600160a01b03888116606483015260a060848301525f60a483015289169063128acb089060c40160408051808303815f875af19250505080156122a6575060408051601f3d908101601f191682019092526122a391810190613421565b60015b6122c3575f61ff0019815c16815d505f9850505050505050505090565b50505f61ff0019815c16815d50876001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa15801561230c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061233091906134c4565b5050506001600160a01b0393841693909a16929092149b9a5050505050505050505050565b305f9081526020819052604081205481906040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156123cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123f1919061338a565b90507f000000000000000000000000000000000000000000000000000000000000000061243f307f000000000000000000000000000000000000000000000000000000000000000085610fda565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156124cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124ef919061355a565b505f6124fd6103e8856133e0565b61250790856133f3565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663883164566040518061016001604052808561256f577f0000000000000000000000000000000000000000000000000000000000000000612571565b305b6001600160a01b031681526020018561258a57306125ac565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b031681526127106020820152620d899f196040820152620d89a06060820152608001856125e057866125e2565b875b8152602001856125f257876125f4565b865b815260200185612604575f612606565b845b8152602001856126165784612618565b5f5b815230602082015242604091820152516001600160e01b031960e084901b1681526126469190600401613573565b6080604051808303815f875af1925050508015612680575060408051601f3d908101601f1916820190925261267d91810190613637565b60015b612769576126af307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af115801561273a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275e919061355a565b505f94505050505090565b612774848383612c9f565b60019850505050505050505090565b60405163e6a4390560e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015612811573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128359190613406565b90506001600160a01b0381166128f7576040516364e329cb60e11b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063c9c65396906044016020604051808303815f875af11580156128d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128f49190613406565b90505b600a80546001600160a01b0319166001600160a01b03838116919091179091556006805461ff0019166102001790556040516370a0823160e01b81523060048201525f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612982573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129a6919061338a565b305f818152602081905260409020549192506129c390848361160d565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612a2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a53919061355a565b506040516335313c2160e11b815261dead60048201526001600160a01b03841690636a627842906024016020604051808303815f875af1158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd919061338a565b5060408051600281525f6020820152908101829052606081018390526001600160a01b0384169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe3906080015b60405180910390a3505050565b634e487b715f52806020526024601cfd5b6001600160a01b038316612b54578060025f828254612b499190613443565b90915550612bc49050565b6001600160a01b0383165f9081526020819052604090205481811015612ba65760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016115f6565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612be057600280548290039055612bfe565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b0c91815260200190565b5f8260020b8260020b13612c7357612c6c84612c5e84613052565b612c6786613052565b61308d565b9050610a65565b611df284612c8085613052565b612c8b906001613670565b612c9485613052565b612c67906001613670565b60098390556006805461ff0019166101001790555f807f0000000000000000000000000000000000000000000000000000000000000000612ce1578284612ce4565b83835b6040805160018152602081018990529081018390526060810182905291935091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe39060800160405180910390a3612d8a307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015612e15573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e39919061355a565b50305f908152602081905260408120546040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612eb0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed4919061338a565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f33573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f579190613406565b90508215612f6c57612f6c3061dead8561160d565b81156130045760405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612fde573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613002919061355a565b505b60408051848152602081018490526001600160a01b038316917fdb8b672bcfa06e1af0abf6157983be34c75ac7885f33fdfe514b4c800f3c5989910160405180910390a25050505050505050565b5f61305e60c883613695565b90505f8260020b12801561307e575061307860c8836136cd565b60020b15155b15610bc45780610a65816136ee565b5f8160020b8360020b13156130a357505f610a65565b600283810b600890811d9184900b901d815b8181136131905760405163299ce14b60e11b8152600182900b60048201525f906001600160a01b03891690635339c29690602401602060405180830381865afa158015613104573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613128919061338a565b9050805f03613137575061317e565b838203613147575f1960ff88161b165b8282036131695761315c60ff8088169061370f565b5f1962ffffff919091161c165b801561317c576001945050505050610a65565b505b806131888161372a565b9150506130b5565b505f9695505050505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114611060575f5ffd5b5f5f604083850312156131f6575f5ffd5b8235613201816131d1565b946020939093013593505050565b5f5f5f5f60608587031215613222575f5ffd5b8435935060208501359250604085013567ffffffffffffffff811115613246575f5ffd5b8501601f81018713613256575f5ffd5b803567ffffffffffffffff81111561326c575f5ffd5b87602082840101111561327d575f5ffd5b949793965060200194505050565b5f5f5f6060848603121561329d575f5ffd5b83356132a8816131d1565b925060208401356132b8816131d1565b929592945050506040919091013590565b5f602082840312156132d9575f5ffd5b5035919050565b5f602082840312156132f0575f5ffd5b8135610a65816131d1565b5f5f6040838503121561330c575f5ffd5b50508035926020909101359150565b5f5f6040838503121561332c575f5ffd5b8235613337816131d1565b91506020830135613347816131d1565b809150509250929050565b600181811c9082168061336657607f821691505b60208210810361338457634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561339a575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610945576109456133a1565b634e487b7160e01b5f52601260045260245ffd5b5f826133ee576133ee6133cc565b500490565b81810381811115610945576109456133a1565b5f60208284031215613416575f5ffd5b8151610a65816131d1565b5f5f60408385031215613432575f5ffd5b505080516020909101519092909150565b80820180821115610945576109456133a1565b80516001600160801b0381168114610bc4575f5ffd5b5f6020828403121561347c575f5ffd5b610a6582613456565b6001600160801b038281168282160390811115610945576109456133a1565b805161ffff81168114610bc4575f5ffd5b80518015158114610bc4575f5ffd5b5f5f5f5f5f5f5f60e0888a0312156134da575f5ffd5b87516134e5816131d1565b8097505060208801518060020b81146134fc575f5ffd5b955061350a604089016134a4565b9450613518606089016134a4565b9350613526608089016134a4565b925060a088015163ffffffff8116811461353e575f5ffd5b915061354c60c089016134b5565b905092959891949750929550565b5f6020828403121561356a575f5ffd5b610a65826134b5565b81516001600160a01b031681526101608101602083015161359f60208401826001600160a01b03169052565b5060408301516135b6604084018262ffffff169052565b5060608301516135cb606084018260020b9052565b5060808301516135e0608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008301516101008301526101208301516136276101208401826001600160a01b03169052565b5061014092830151919092015290565b5f5f5f5f6080858703121561364a575f5ffd5b8451935061365a60208601613456565b6040860151606090960151949790965092505050565b600281810b9083900b01627fffff8113627fffff1982121715610945576109456133a1565b5f8160020b8360020b806136ab576136ab6133cc565b627fffff1982145f19821416156136c4576136c46133a1565b90059392505050565b5f8260020b806136df576136df6133cc565b808360020b0791505092915050565b5f8160020b627fffff198103613706576137066133a1565b5f190192915050565b62ffffff8281168282160390811115610945576109456133a1565b5f6001600160ff1b018201613741576137416133a1565b506001019056fea2646970667358221220401939af5312071d413f49430baf389e94c154f401353af6e89995415dbba35d64736f6c634300081c0033a26469706673582212203f3257855e96725c5f82166ce21a590dfcc5b4bebf5f10a7c4713a80d6b53c3f64736f6c634300081c0033000000000000000000000000ed591b552a9ed3d99f2b43cdf7ae8aad6814ef59000000000000000000000000ed591b552a9ed3d99f2b43cdf7ae8aad6814ef5900000000000000000000000060b9262456de011f7d15a54cdd8c48baaa8b022f000000000000000000000000ca143ce32fe78f1f7019d7d551a6402fc5350c730000000000000000000000000bfbcf9fa4f9c56b0f40a671ad40e0805a09186500000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f4364000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c","recompiledBytecode":"0x610100604052348015610010575f5ffd5b5060405161575a38038061575a83398101604081905261002f9161033f565b866001600160a01b03811661005d57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b610066816102b9565b506001600160a01b03861661008e5760405163d92e233d60e01b815260040160405180910390fd5b846001600160a01b03163b5f036100b8576040516311a1e69760e01b815260040160405180910390fd5b836001600160a01b03163b5f036100e257604051633647040f60e01b815260040160405180910390fd5b826001600160a01b03163b5f0361010c57604051639a11fb3160e01b815260040160405180910390fd5b816001600160a01b03163b5f036101365760405163037e6a8560e01b815260040160405180910390fd5b806001600160a01b03163b5f036101605760405163614e3ba560e11b815260040160405180910390fd5b826001600160a01b0316826001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101ca91906103c0565b6001600160a01b03161415806102515750806001600160a01b0316826001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610221573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024591906103c0565b6001600160a01b031614155b1561026f5760405163037e6a8560e01b815260040160405180910390fd5b600280546001600160a01b03199081166001600160a01b03988916179091556003805490911695871695909517909455918416608052831660a052821660c0521660e052506103e0565b600180546001600160a01b03191690556102d2816102d5565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b038116811461033a575f5ffd5b919050565b5f5f5f5f5f5f5f60e0888a031215610355575f5ffd5b61035e88610324565b965061036c60208901610324565b955061037a60408901610324565b945061038860608901610324565b935061039660808901610324565b92506103a460a08901610324565b91506103b260c08901610324565b905092959891949750929550565b5f602082840312156103d0575f5ffd5b6103d982610324565b9392505050565b60805160a05160c05160e05161530f61044b5f395f81816102e5015281816104c401526106ee01525f8181610293015281816104a301526106cc01525f81816102600152818161048201526106aa01525f8181610348015281816104610152610688015261530f5ff3fe60806040526004361061011e575f3560e01c80637f1e9ef61161009d578063b4b57c3911610062578063b4b57c3914610337578063bdaad4881461036a578063e30c397814610389578063e74b981b146103a6578063f2fde38b146103c5575f5ffd5b80637f1e9ef6146102825780638854a0ff146102b55780638d72647e146102d45780638da5cb5b14610307578063a64ed8ba14610323575f5ffd5b806354fd4d50116100e357806354fd4d50146101eb578063634282af14610208578063715018a61461022757806379ba50971461023b5780637c887c591461024f575f5ffd5b806319f3736114610129578063266cedb31461016c5780633a5fedb71461019757806346904840146101b6578063476343ee146101d5575f5ffd5b3661012557005b5f5ffd5b348015610134575f5ffd5b50610157610143366004610b78565b60056020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61017f61017a366004610bdd565b6103e4565b6040516001600160a01b039091168152602001610163565b3480156101a2575f5ffd5b5061017f6101b1366004610c5a565b610644565b3480156101c1575f5ffd5b5060025461017f906001600160a01b031681565b3480156101e0575f5ffd5b506101e96107be565b005b3480156101f6575f5ffd5b5060025b604051908152602001610163565b348015610213575f5ffd5b5061017f610222366004610ce2565b61087d565b348015610232575f5ffd5b506101e96108a5565b348015610246575f5ffd5b506101e96108c6565b34801561025a575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561028d575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c0575f5ffd5b5060035461017f906001600160a01b031681565b3480156102df575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610312575f5ffd5b505f546001600160a01b031661017f565b34801561032e575f5ffd5b506004546101fa565b348015610342575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610375575f5ffd5b506101e9610384366004610b78565b61090f565b348015610394575f5ffd5b506001546001600160a01b031661017f565b3480156103b1575f5ffd5b506101e96103c0366004610b78565b610996565b3480156103d0575f5ffd5b506101e96103df366004610b78565b610a13565b5f8515806103f25750604086115b156104105760405163430f13b360e01b815260040160405180910390fd5b83158061041d5750601084115b1561043b5760405163010466f160e21b815260040160405180910390fd5b6104453383610a83565b878787873360035f9054906101000a90046001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006040516104ef90610b50565b6105029a99989796959493929190610d21565b8190604051809103905ff590508015801561051f573d5f5f3e3d5ffd5b506004805460018082019092557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0384169081179091555f8181526005602052604090819020805460ff1916909317909255905191925033917f5314f94e6e2d1a502483a5b446938dee47de600f90cbf915d89632d58a71aa2b906105c1908b908b908b908b908b90610d8e565b60405180910390a3341561063a5760405162de16a360e71b81523360048201526001600160a01b03821690636f0b518090349060240160206040518083038185885af1158015610613573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106389190610dc7565b505b9695505050505050565b5f5f6040518060200161065690610b50565b601f1982820381018352601f909101166040819052600354610716918a918a918a918a918f916001600160a01b0316907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090602001610d21565b60408051601f19818403018152908290526107349291602001610df5565b60405160208183030381529060405280519060200120905060ff60f81b3061075c8a86610a83565b6040516001600160f81b031993909316602084015260609190911b6bffffffffffffffffffffffff1916602183015260358201526055810182905260750160408051601f19818403018152919052805160209091012098975050505050505050565b60025460405147915f916001600160a01b039091169083908381818185875af1925050503d805f811461080c576040519150601f19603f3d011682016040523d82523d5f602084013e610811565b606091505b5050905080610833576040516312171d8360e31b815260040160405180910390fd5b600254604080516001600160a01b039092168252602082018490527fc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a910160405180910390a15050565b6004818154811061088c575f80fd5b5f918252602090912001546001600160a01b0316905081565b6108ad610abf565b604051638905116560e01b815260040160405180910390fd5b60015433906001600160a01b031681146109035760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61090c81610aed565b50565b610917610abf565b806001600160a01b03163b5f03610941576040516311a1e69760e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f1386da33541fecf49b0f53895aef3f30f6e3e08755deb017e106e7ae4f4c976d906020015b60405180910390a150565b61099e610abf565b6001600160a01b0381166109c55760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f7a7b5a0a132f9e0581eb8527f66eae9ee89c2a3e79d4ac7e41a1f1f4d48a7fc29060200161098b565b610a1b610abf565b600180546001600160a01b0383166001600160a01b03199091168117909155610a4b5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b03841660208201529081018290525f9060600160405160208183030381529060405280519060200120905092915050565b5f546001600160a01b03163314610aeb5760405163118cdaa760e01b81523360048201526024016108fa565b565b600180546001600160a01b031916905561090c815f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6144c880610e1283390190565b80356001600160a01b0381168114610b73575f5ffd5b919050565b5f60208284031215610b88575f5ffd5b610b9182610b5d565b9392505050565b5f5f83601f840112610ba8575f5ffd5b50813567ffffffffffffffff811115610bbf575f5ffd5b602083019150836020828501011115610bd6575f5ffd5b9250929050565b5f5f5f5f5f5f60808789031215610bf2575f5ffd5b863567ffffffffffffffff811115610c08575f5ffd5b610c1489828a01610b98565b909750955050602087013567ffffffffffffffff811115610c33575f5ffd5b610c3f89828a01610b98565b979a9699509760408101359660609091013595509350505050565b5f5f5f5f5f5f60808789031215610c6f575f5ffd5b610c7887610b5d565b9550602087013567ffffffffffffffff811115610c93575f5ffd5b610c9f89828a01610b98565b909650945050604087013567ffffffffffffffff811115610cbe575f5ffd5b610cca89828a01610b98565b979a9699509497949695606090950135949350505050565b5f60208284031215610cf2575f5ffd5b5035919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b61010081525f610d3661010083018c8e610cf9565b8281036020840152610d49818b8d610cf9565b6001600160a01b03998a16604085015297891660608401525050938616608085015291851660a0840152841660c083015290921660e090920191909152949350505050565b606081525f610da1606083018789610cf9565b8281036020840152610db4818688610cf9565b9150508260408301529695505050505050565b5f60208284031215610dd7575f5ffd5b5051919050565b5f81518060208401855e5f93019283525090919050565b5f610e09610e038386610dde565b84610dde565b94935050505056fe6101a0604052348015610010575f5ffd5b506040516144c83803806144c883398101604081905261002f91610877565b8787600361003d83826109cb565b50600461004a82826109cb565b5050600160055550336080526001600160a01b0386811660a05285811660c05284811660e0528381166101008190528382166101205290821661014081905230818110610160819052604051630b4c774160e11b815260048101929092526024820192909252612710604482015290915f91631698ee8290606401602060405180830381865afa1580156100e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101049190610a85565b90506001600160a01b03811661018e5760405163a167129560e01b81523060048201526001600160a01b038481166024830152612710604483015286169063a1671295906064016020604051808303815f875af1158015610167573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061018b9190610a85565b90505b806001600160a01b0316610180816001600160a01b0316815250505f816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156101e6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061020a9190610ab1565b5050505050509050806001600160a01b03165f0361028f576001600160a01b03821663f637731d61023a856102b5565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f604051808303815f87803b158015610278575f5ffd5b505af115801561028a573d5f5f3e3d5ffd5b505050505b6102a5306b033b2e3c9fd0803ce8000000610318565b5050505050505050505050610bd4565b5f806102cc6b0295be96e640669720000000610355565b9050826102f7576102f26102ed670de0b6b3a7640000600160c01b846103bb565b610471565b610311565b6103116102ed82600160c01b670de0b6b3a76400006103bb565b9392505050565b6001600160a01b0382166103465760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6103515f83836105c9565b5050565b5f8061036083610649565b905061036c8180610b64565b61038d6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b61039f90674a03ce68d2155555610b64565b6103b190670de0b6b3a7640000610b64565b6103119190610ba2565b5f838302815f1985870982811083820303915050805f036103ef578382816103e5576103e5610b8e565b0492505050610311565b80841161040657610406600385150260111861067c565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f6001821161047e575090565b816001600160801b82106104975760809190911c9060401b5b6801000000000000000082106104b25760409190911c9060201b5b64010000000082106104c95760209190911c9060101b5b6201000082106104de5760109190911c9060081b5b61010082106104f25760089190911c9060041b5b601082106105055760049190911c9060021b5b600482106105115760011b5b600302600190811c9081858161052957610529610b8e565b048201901c9050600181858161054157610541610b8e565b048201901c9050600181858161055957610559610b8e565b048201901c9050600181858161057157610571610b8e565b048201901c9050600181858161058957610589610b8e565b048201901c905060018185816105a1576105a1610b8e565b048201901c90506105c08185816105ba576105ba610b8e565b04821190565b90039392505050565b60065460ff161580156105e457506001600160a01b03831615155b80156105f957506001600160a01b0383163014155b801561061b575060ff5f5c16801561061957506001600160a01b03821630145b155b1561063957604051632b36b06160e01b815260040160405180910390fd5b61064483838361068d565b505050565b5f8161066c6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b6106769190610bc1565b92915050565b634e487b715f52806020526024601cfd5b6001600160a01b0383166106b7578060025f8282546106ac9190610b7b565b909155506107279050565b6001600160a01b0383165f90815260208190526040902054818110156107095760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161033d565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661074357600280548290039055610761565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107a691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126107d6575f5ffd5b81516001600160401b038111156107ef576107ef6107b3565b604051601f8201601f19908116603f011681016001600160401b038111828210171561081d5761081d6107b3565b604052818152838201602001851015610834575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b6001600160a01b0381168114610864575f5ffd5b50565b805161087281610850565b919050565b5f5f5f5f5f5f5f5f610100898b03121561088f575f5ffd5b88516001600160401b038111156108a4575f5ffd5b6108b08b828c016107c7565b60208b015190995090506001600160401b038111156108cd575f5ffd5b6108d98b828c016107c7565b97505060408901516108ea81610850565b60608a01519096506108fb81610850565b60808a015190955061090c81610850565b60a08a015190945061091d81610850565b925061092b60c08a01610867565b915061093960e08a01610867565b90509295985092959890939650565b600181811c9082168061095c57607f821691505b60208210810361097a57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561064457805f5260205f20601f840160051c810160208510156109a55750805b601f840160051c820191505b818110156109c4575f81556001016109b1565b5050505050565b81516001600160401b038111156109e4576109e46107b3565b6109f8816109f28454610948565b84610980565b6020601f821160018114610a2a575f8315610a135750848201515b5f19600385901b1c1916600184901b1784556109c4565b5f84815260208120601f198516915b82811015610a595787850151825560209485019460019092019101610a39565b5084821015610a7657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215610a95575f5ffd5b815161031181610850565b805161ffff81168114610872575f5ffd5b5f5f5f5f5f5f5f60e0888a031215610ac7575f5ffd5b8751610ad281610850565b8097505060208801518060020b8114610ae9575f5ffd5b9550610af760408901610aa0565b9450610b0560608901610aa0565b9350610b1360808901610aa0565b925060a088015163ffffffff81168114610b2b575f5ffd5b60c08901519092508015158114610b40575f5ffd5b8091505092959891949750929550565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761067657610676610b50565b8082018082111561067657610676610b50565b634e487b7160e01b5f52601260045260245ffd5b5f82610bbc57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561067657610676610b50565b60805160a05160c05160e051610100516101205161014051610160516101805161377e610d4a5f395f8181610376015281816109ec01528181611ea10152612d0f01525f81816104f20152818161098b01528181610ecf01528181611ec6015281816121ae015281816123f50152612cb701525f81816106770152818161187701528181612388015281816124850152818161254b0152818161258c015281816126f4015281816127a0015281816128620152818161293d015281816129e901528181612dcf01528181612e6b0152612f9801525f81816105df01528181610e600152818161241a015281816124560152818161250b0152818161268a015281816126c601528181612d650152612da101525f6105ac01525f8181610763015281816127ca015261288a01525f81816106120152610b0101525f81816102b20152610aa701525f81816107aa01528181610c3201528181610d740152818161119c015281816114820152612ed9015261377e5ff3fe608060405260043610610275575f3560e01c806371640de31161014a578063a8aa1b31116100be578063cd3293de11610078578063cd3293de146107e0578063d3618cca146107f4578063dd62ed3e14610808578063e4849b321461084c578063e7c2b7721461086b578063f6ccbda514610884575f5ffd5b8063a8aa1b3114610714578063a9059cbb14610733578063b4b57c3914610752578063b956993b14610785578063c45a015514610799578063c8796572146107cc575f5ffd5b80638d4b66c01161010f5780638d4b66c0146106475780638d72647e1461066657806395d89b41146106995780639c43a050146106ad578063a6195fd3146106c1578063a64190c4146106e0575f5ffd5b806371640de3146105865780637c887c591461059b5780637f1e9ef6146105ce5780638854a0ff146106015780638976254314610634575f5ffd5b806323b872dd116101ec5780635c1624ef116101a65780635c1624ef146104af5780635ed0447d146104c2578063604b1eba146104e1578063667022fd146105145780636f0b51801461053f57806370a0823114610552575f5ffd5b806323b872dd146103e9578063313ce56714610408578063398482d8146104295780634beb394c1461043d578063559f05dc1461047c578063577bd3361461049b575f5ffd5b806316e457f01161023d57806316e457f01461035157806316f0115b1461036557806318160ddd1461039857806320cce74b146103ac57806320f1fc61146103c057806323a69e75146103c8575f5ffd5b806302c7e7af1461027957806302d05d3f146102a157806303fd2a45146102ec57806306fdde0314610301578063095ea7b314610322575b5f5ffd5b348015610284575f5ffd5b5061028e60075481565b6040519081526020015b60405180910390f35b3480156102ac575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610298565b3480156102f7575f5ffd5b506102d461dead81565b34801561030c575f5ffd5b506103156108a2565b604051610298919061319c565b34801561032d575f5ffd5b5061034161033c3660046131e5565b610932565b6040519015158152602001610298565b34801561035c575f5ffd5b5061028e61094b565b348015610370575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a3575f5ffd5b5060025461028e565b3480156103b7575f5ffd5b506102d4610985565b61028e6109b4565b3480156103d3575f5ffd5b506103e76103e236600461320f565b6109d1565b005b3480156103f4575f5ffd5b5061034161040336600461328b565b610a47565b348015610413575f5ffd5b5060125b60405160ff9091168152602001610298565b348015610434575f5ffd5b5061028e610a6c565b348015610448575f5ffd5b5061045c6104573660046132c9565b610a78565b604080519485526020850193909352918301526060820152608001610298565b348015610487575f5ffd5b506103416104963660046132e0565b610a95565b3480156104a6575f5ffd5b5061028e610b73565b61028e6104bd3660046132c9565b610b9b565b3480156104cd575f5ffd5b5061045c6104dc3660046131e5565b610bc9565b3480156104ec575f5ffd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b34801561051f575f5ffd5b5061028e61052e3660046132e0565b60086020525f908152604090205481565b61028e61054d3660046132e0565b610c1e565b34801561055d575f5ffd5b5061028e61056c3660046132e0565b6001600160a01b03165f9081526020819052604090205490565b348015610591575f5ffd5b5061028e60095481565b3480156105a6575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d9575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561060c575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561063f575f5ffd5b506104175f81565b348015610652575f5ffd5b5061028e6106613660046132e0565b610c9f565b348015610671575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a4575f5ffd5b50610315610ccc565b3480156106b8575f5ffd5b50610417600281565b3480156106cc575f5ffd5b5061028e6106db3660046132fb565b610cdb565b3480156106eb575f5ffd5b506106ff6106fa3660046132c9565b610d04565b60408051928352602083019190915201610298565b34801561071f575f5ffd5b50600a546102d4906001600160a01b031681565b34801561073e575f5ffd5b5061034161074d3660046131e5565b610d2f565b34801561075d575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b348015610790575f5ffd5b50610417600181565b3480156107a4575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d7575f5ffd5b506106ff610d3c565b3480156107eb575f5ffd5b5061028e610f57565b3480156107ff575f5ffd5b506103e7610f63565b348015610813575f5ffd5b5061028e61082236600461331b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610857575f5ffd5b5061028e6108663660046132c9565b610fbd565b348015610876575f5ffd5b506006546103419060ff1681565b34801561088f575f5ffd5b5060065461041790610100900460ff1681565b6060600380546108b190613352565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90613352565b80156109285780601f106108ff57610100808354040283529160200191610928565b820191905f5260205f20905b81548152906001019060200180831161090b57829003601f168201915b5050505050905090565b5f3361093f818585610fda565b60019150505b92915050565b5f610954610fec565b61095d33611016565b335f818152602081905260408120546109769291611063565b90506109826001600555565b90565b5f6109af7f00000000000000000000000000000000000000000000000000000000000000006112a4565b905090565b5f6109bd610fec565b6109c633611016565b61097633345f611300565b60ff6101005f5c04161580610a0f5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b80610a1957508315155b80610a2357508215155b15610a415760405163f7a632f560e01b815260040160405180910390fd5b50505050565b5f33610a54858285611593565b610a5f85858561160d565b60019150505b9392505050565b5f6109af60075461166a565b5f5f5f5f610a863386610bc9565b93509350935093509193509193565b6006545f9060ff1615801561094557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061094557506040516370a0823160e01b81526001600160a01b0383811660048301525f917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015610b48573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6c919061338a565b1192915050565b5f6b0295be96e640669720000000600754612710610b9191906133b5565b6109af91906133e0565b5f610ba4610fec565b610bad33611016565b610bb8333484611300565b9050610bc46001600555565b919050565b6006545f9081908190819060ff1615610bec57505f925082915081905083610c15565b610bf686866116cf565b9195509350915081610c0884876133f3565b610c1291906133f3565b90505b92959194509250565b5f610c27610fec565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c7057604051630636a15760e11b815260040160405180910390fd5b60065460ff1615610c945760405163e6a0d45f60e01b815260040160405180910390fd5b610bb882345f611300565b6001600160a01b0381165f90815260086020526040812054610945906a18d0bf423c03d8de0000006133f3565b6060600480546108b190613352565b5f610ce4610fec565b610ced33611016565b610cf8338484611063565b90506109456001600555565b6006545f90819060ff1615610d1d57505f928392509050565b610d26836117a6565b91509150915091565b5f3361093f81858561160d565b5f5f610d46610fec565b600654610100900460ff16600114610d71576040516330aad80b60e01b815260040160405180910390fd5b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dce573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df29190613406565b6040805160808101825260095481526001600160a01b03838116602083019081526001600160801b0383850181815260608501828152955163fc6f786560e01b815294516004860152915183166024850152905181166044840152925190921660648201529192505f9182917f0000000000000000000000000000000000000000000000000000000000000000169063fc6f78659060840160408051808303815f875af1158015610ea5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ec99190613421565b915091507f0000000000000000000000000000000000000000000000000000000000000000610ef9578082610efc565b81815b60408051838152602081018390529297509095506001600160a01b038516917f2e4fb6077d4acf86e12bb7411fb82b2b3eaa6a49787f4b1e17b423e7ea841169910160405180910390a2505050610f536001600555565b9091565b5f6109af600754611807565b610f6b610fec565b60065460ff1680610f8a57506b0295be96e64066972000000060075414155b15610fa8576040516325a6766f60e21b815260040160405180910390fd5b610fb15f611860565b610fbb6001600555565b565b5f610fc6610fec565b610fcf33611016565b610bb833835f611063565b610fe78383836001611909565b505050565b60026005540361100f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600555565b60065460ff161561103a5760405163e6a0d45f60e01b815260040160405180910390fd5b61104381610a95565b61106057604051637c75aa6f60e11b815260040160405180910390fd5b50565b5f825f036110845760405163617ab12d60e11b815260040160405180910390fd5b6001600160a01b0384165f908152602081905260409020548311156110bc57604051631e9acf1760e31b815260040160405180910390fd5b5f6110c6846117a6565b90925090505f8290036110ec5760405163617ab12d60e11b815260040160405180910390fd5b8282101561110d57604051638199f5f360e01b815260040160405180910390fd5b5f8460075461111c91906133f3565b6007819055905060015f805c60ff19168217905d5061113c86308761160d565b5f60ff19815c16815d506040805186815260208101859052908101839052606081018290526001600160a01b038716907f483f8aec0fd892ac72ad1ba8d0e9c9e73db59c12d263fd71de480b5b3deeae3c9060800160405180910390a25f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611202576040519150601f19603f3d011682016040523d82523d5f602084013e611207565b606091505b505090508061122957604051634033e4e360e01b815260040160405180910390fd5b5f876001600160a01b0316856040515f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b505090508061129957604051630ec6ac4160e21b815260040160405180910390fd5b505050509392505050565b5f5f6112bb6b0295be96e64066972000000061166a565b9050826112e6576112e16112dc670de0b6b3a7640000600160c01b846119db565b611a91565b610a65565b610a656112dc82600160c01b670de0b6b3a76400006119db565b5f5f5f61130d86866116cf565b919450925090505f839003611377576001600160a01b0386165f908152600860205260409020546a18d0bf423c03d8de0000001161135e57604051636bf4c8e960e11b815260040160405180910390fd5b60405163617ab12d60e11b815260040160405180910390fd5b8383101561139857604051638199f5f360e01b815260040160405180910390fd5b5f836007546113a79190613443565b60078190556001600160a01b0388165f908152600860205260408120805492935086929091906113d8908490613443565b909155506113e9905030888661160d565b6040805184815260208101849052908101859052606081018290526001600160a01b038816907f064fb1933e186be0b289a87e98518dc18cc9856ecbc9f1353d1a138ddf733ec59060800160405180910390a25f8261144885896133f3565b61145291906133f3565b90506b0295be96e6406697200000008203611479576114796114748285613443565b611860565b8215611511575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846040515f6040518083038185875af1925050503d805f81146114e8576040519150601f19603f3d011682016040523d82523d5f602084013e6114ed565b606091505b505090508061150f57604051634033e4e360e01b815260040160405180910390fd5b505b8015611299575f886001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611560576040519150601f19603f3d011682016040523d82523d5f602084013e611565565b606091505b505090508061158757604051633c31275160e21b815260040160405180910390fd5b50505050509392505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f198114610a4157818110156115ff57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b610a4184848484035f611909565b6001600160a01b03831661163657604051634b637e8f60e11b81525f60048201526024016115f6565b6001600160a01b03821661165f5760405163ec442f0560e01b81525f60048201526024016115f6565b610fe7838383611be9565b5f5f61167583611c64565b905061168181806133b5565b6116a16a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b6116b390674a03ce68d21555556133b5565b6116c590670de0b6b3a76400006133b5565b610a6591906133e0565b6007545f9081908190816116e66064612710613443565b6116f2612710886133b5565b6116fc91906133e0565b90506117088282611c86565b94505f611721836b0295be96e6406697200000006133f3565b90508086111561172f578095505b6001600160a01b0388165f9081526008602052604081205461175c906a18d0bf423c03d8de0000006133f3565b90508087111561176a578096505b865f03611783575f5f5f9650965096505050505061179f565b61178d8488611d58565b955061179886611dfa565b9450505050505b9250925092565b6007545f9081908315806117b957508084115b156117c957505f93849350915050565b5f6117d48286611e2a565b90506117df81611dfa565b92508281116117f457505f9485945092505050565b6117fe83826133f3565b93505050915091565b5f674a03ce68d215555561181a83611c64565b61183a6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b61184c90674a03ce68d21555556133b5565b61185691906133e0565b61094591906133f3565b6006805460ff191660011790556001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d0e30db06118a683476133f3565b6040518263ffffffff1660e01b81526004015f604051808303818588803b1580156118cf575f5ffd5b505af11580156118e1573d5f5f3e3d5ffd5b50505050506118ee611e9e565b80156118fd57506118fd612355565b61106057611060612783565b6001600160a01b0384166119325760405163e602df0560e01b81525f60048201526024016115f6565b6001600160a01b03831661195b57604051634a1406b160e11b81525f60048201526024016115f6565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015610a4157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516119cd91815260200190565b60405180910390a350505050565b5f838302815f1985870982811083820303915050805f03611a0f57838281611a0557611a056133cc565b0492505050610a65565b808411611a2657611a266003851502601118612b19565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f60018211611a9e575090565b816001600160801b8210611ab75760809190911c9060401b5b680100000000000000008210611ad25760409190911c9060201b5b6401000000008210611ae95760209190911c9060101b5b620100008210611afe5760109190911c9060081b5b6101008210611b125760089190911c9060041b5b60108210611b255760049190911c9060021b5b60048210611b315760011b5b600302600190811c90818581611b4957611b496133cc565b048201901c90506001818581611b6157611b616133cc565b048201901c90506001818581611b7957611b796133cc565b048201901c90506001818581611b9157611b916133cc565b048201901c90506001818581611ba957611ba96133cc565b048201901c90506001818581611bc157611bc16133cc565b048201901c9050611be0818581611bda57611bda6133cc565b04821190565b90039392505050565b60065460ff16158015611c0457506001600160a01b03831615155b8015611c1957506001600160a01b0383163014155b8015611c3b575060ff5f5c168015611c3957506001600160a01b03821630145b155b15611c5957604051632b36b06160e01b815260040160405180910390fd5b610fe7838383612b2a565b5f816118566a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f5f611c9184611c64565b90505f81611cb56a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611cc790674a03ce68d21555556133b5565b611cd191906133e0565b90505f611cde8583613443565b611cfe6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d1090674a03ce68d21555556133b5565b611d1a91906133e0565b9050611d27816001613443565b8311611d38575f9350505050610945565b6001611d4482856133f3565b611d4e91906133f3565b9695505050505050565b5f5f611d6384611c64565b905080611d866a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d9890674a03ce68d21555556133b5565b611da291906133e0565b611dac84836133f3565b611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611dde90674a03ce68d21555556133b5565b611de891906133e0565b611df291906133f3565b949350505050565b5f612710600181611e0c6064866133b5565b611e169190613443565b611e2091906133f3565b61094591906133e0565b5f5f611e3584611c64565b9050611e418382613443565b611e616a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611e7390674a03ce68d21555556133b5565b611e7d91906133e0565b81611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f7f000000000000000000000000000000000000000000000000000000000000000081611eea7f00000000000000000000000000000000000000000000000000000000000000006112a4565b9050816001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f28573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4c919061346c565b6001600160801b031615611f62575f9250505090565b5f826001600160a01b03166370cf754a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f9f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fc3919061346c565b90506c0c9f2c9cd04674edea400000006001600160801b0382161015611fec575f935050505090565b5f6120046c0c9f2c9cd04674edea4000000083613485565b60405163f30dba9360e01b8152620d899f1960048201529091506001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa158015612058573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061207c919061346c565b6001600160801b0316118061210b575060405163f30dba9360e01b8152620d89a060048201526001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa1580156120dc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612100919061346c565b6001600160801b0316115b1561211a575f94505050505090565b5f5f856001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015612158573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061217c91906134c4565b505050505091509150846001600160a01b0316826001600160a01b0316036121ab576001965050505050505090565b5f7f00000000000000000000000000000000000000000000000000000000000000006121da5762027e5c6121e0565b62027e5c195b90506121ed878383612c43565b156121ff575f97505050505050505090565b6001600160a01b0380871690841611600161ff00195f805c9190911661010017905d50604051630251596160e31b81523060048201528115156024820152600160448201526001600160a01b03888116606483015260a060848301525f60a483015289169063128acb089060c40160408051808303815f875af19250505080156122a6575060408051601f3d908101601f191682019092526122a391810190613421565b60015b6122c3575f61ff0019815c16815d505f9850505050505050505090565b50505f61ff0019815c16815d50876001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa15801561230c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061233091906134c4565b5050506001600160a01b0393841693909a16929092149b9a5050505050505050505050565b305f9081526020819052604081205481906040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156123cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123f1919061338a565b90507f000000000000000000000000000000000000000000000000000000000000000061243f307f000000000000000000000000000000000000000000000000000000000000000085610fda565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156124cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124ef919061355a565b505f6124fd6103e8856133e0565b61250790856133f3565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663883164566040518061016001604052808561256f577f0000000000000000000000000000000000000000000000000000000000000000612571565b305b6001600160a01b031681526020018561258a57306125ac565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b031681526127106020820152620d899f196040820152620d89a06060820152608001856125e057866125e2565b875b8152602001856125f257876125f4565b865b815260200185612604575f612606565b845b8152602001856126165784612618565b5f5b815230602082015242604091820152516001600160e01b031960e084901b1681526126469190600401613573565b6080604051808303815f875af1925050508015612680575060408051601f3d908101601f1916820190925261267d91810190613637565b60015b612769576126af307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af115801561273a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275e919061355a565b505f94505050505090565b612774848383612c9f565b60019850505050505050505090565b60405163e6a4390560e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015612811573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128359190613406565b90506001600160a01b0381166128f7576040516364e329cb60e11b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063c9c65396906044016020604051808303815f875af11580156128d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128f49190613406565b90505b600a80546001600160a01b0319166001600160a01b03838116919091179091556006805461ff0019166102001790556040516370a0823160e01b81523060048201525f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612982573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129a6919061338a565b305f818152602081905260409020549192506129c390848361160d565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612a2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a53919061355a565b506040516335313c2160e11b815261dead60048201526001600160a01b03841690636a627842906024016020604051808303815f875af1158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd919061338a565b5060408051600281525f6020820152908101829052606081018390526001600160a01b0384169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe3906080015b60405180910390a3505050565b634e487b715f52806020526024601cfd5b6001600160a01b038316612b54578060025f828254612b499190613443565b90915550612bc49050565b6001600160a01b0383165f9081526020819052604090205481811015612ba65760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016115f6565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612be057600280548290039055612bfe565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b0c91815260200190565b5f8260020b8260020b13612c7357612c6c84612c5e84613052565b612c6786613052565b61308d565b9050610a65565b611df284612c8085613052565b612c8b906001613670565b612c9485613052565b612c67906001613670565b60098390556006805461ff0019166101001790555f807f0000000000000000000000000000000000000000000000000000000000000000612ce1578284612ce4565b83835b6040805160018152602081018990529081018390526060810182905291935091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe39060800160405180910390a3612d8a307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015612e15573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e39919061355a565b50305f908152602081905260408120546040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612eb0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed4919061338a565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f33573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f579190613406565b90508215612f6c57612f6c3061dead8561160d565b81156130045760405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612fde573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613002919061355a565b505b60408051848152602081018490526001600160a01b038316917fdb8b672bcfa06e1af0abf6157983be34c75ac7885f33fdfe514b4c800f3c5989910160405180910390a25050505050505050565b5f61305e60c883613695565b90505f8260020b12801561307e575061307860c8836136cd565b60020b15155b15610bc45780610a65816136ee565b5f8160020b8360020b13156130a357505f610a65565b600283810b600890811d9184900b901d815b8181136131905760405163299ce14b60e11b8152600182900b60048201525f906001600160a01b03891690635339c29690602401602060405180830381865afa158015613104573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613128919061338a565b9050805f03613137575061317e565b838203613147575f1960ff88161b165b8282036131695761315c60ff8088169061370f565b5f1962ffffff919091161c165b801561317c576001945050505050610a65565b505b806131888161372a565b9150506130b5565b505f9695505050505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114611060575f5ffd5b5f5f604083850312156131f6575f5ffd5b8235613201816131d1565b946020939093013593505050565b5f5f5f5f60608587031215613222575f5ffd5b8435935060208501359250604085013567ffffffffffffffff811115613246575f5ffd5b8501601f81018713613256575f5ffd5b803567ffffffffffffffff81111561326c575f5ffd5b87602082840101111561327d575f5ffd5b949793965060200194505050565b5f5f5f6060848603121561329d575f5ffd5b83356132a8816131d1565b925060208401356132b8816131d1565b929592945050506040919091013590565b5f602082840312156132d9575f5ffd5b5035919050565b5f602082840312156132f0575f5ffd5b8135610a65816131d1565b5f5f6040838503121561330c575f5ffd5b50508035926020909101359150565b5f5f6040838503121561332c575f5ffd5b8235613337816131d1565b91506020830135613347816131d1565b809150509250929050565b600181811c9082168061336657607f821691505b60208210810361338457634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561339a575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610945576109456133a1565b634e487b7160e01b5f52601260045260245ffd5b5f826133ee576133ee6133cc565b500490565b81810381811115610945576109456133a1565b5f60208284031215613416575f5ffd5b8151610a65816131d1565b5f5f60408385031215613432575f5ffd5b505080516020909101519092909150565b80820180821115610945576109456133a1565b80516001600160801b0381168114610bc4575f5ffd5b5f6020828403121561347c575f5ffd5b610a6582613456565b6001600160801b038281168282160390811115610945576109456133a1565b805161ffff81168114610bc4575f5ffd5b80518015158114610bc4575f5ffd5b5f5f5f5f5f5f5f60e0888a0312156134da575f5ffd5b87516134e5816131d1565b8097505060208801518060020b81146134fc575f5ffd5b955061350a604089016134a4565b9450613518606089016134a4565b9350613526608089016134a4565b925060a088015163ffffffff8116811461353e575f5ffd5b915061354c60c089016134b5565b905092959891949750929550565b5f6020828403121561356a575f5ffd5b610a65826134b5565b81516001600160a01b031681526101608101602083015161359f60208401826001600160a01b03169052565b5060408301516135b6604084018262ffffff169052565b5060608301516135cb606084018260020b9052565b5060808301516135e0608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008301516101008301526101208301516136276101208401826001600160a01b03169052565b5061014092830151919092015290565b5f5f5f5f6080858703121561364a575f5ffd5b8451935061365a60208601613456565b6040860151606090960151949790965092505050565b600281810b9083900b01627fffff8113627fffff1982121715610945576109456133a1565b5f8160020b8360020b806136ab576136ab6133cc565b627fffff1982145f19821416156136c4576136c46133a1565b90059392505050565b5f8260020b806136df576136df6133cc565b808360020b0791505092915050565b5f8160020b627fffff198103613706576137066133a1565b5f190192915050565b62ffffff8281168282160390811115610945576109456133a1565b5f6001600160ff1b018201613741576137416133a1565b506001019056fea2646970667358221220401939af5312071d413f49430baf389e94c154f401353af6e89995415dbba35d64736f6c634300081c0033a26469706673582212203f3257855e96725c5f82166ce21a590dfcc5b4bebf5f10a7c4713a80d6b53c3f64736f6c634300081c0033","sourceMap":"461:4966:11:-:0;;;1358:1074;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1567:6;-1:-1:-1;;;;;1273:26:0;;1269:95;;1322:31;;-1:-1:-1;;;1322:31:0;;1350:1;1322:31;;;1069:51:20;1042:18;;1322:31:0;;;;;;;1269:95;1373:32;1392:12;1373:18;:32::i;:::-;-1:-1:-1;;;;;;1589:27:11;::::1;1585:53;;1625:13;;-1:-1:-1::0;;;1625:13:11::1;;;;;;;;;;;1585:53;1652:9;-1:-1:-1::0;;;;;1652:21:11::1;;1677:1;1652:26:::0;1648:56:::1;;1687:17;;-1:-1:-1::0;;;1687:17:11::1;;;;;;;;;;;1648:56;1718:10;-1:-1:-1::0;;;;;1718:22:11::1;;1744:1;1718:27:::0;1714:58:::1;;1754:18;;-1:-1:-1::0;;;1754:18:11::1;;;;;;;;;;;1714:58;1786:10;-1:-1:-1::0;;;;;1786:22:11::1;;1812:1;1786:27:::0;1782:58:::1;;1822:18;;-1:-1:-1::0;;;1822:18:11::1;;;;;;;;;;;1782:58;1854:4;-1:-1:-1::0;;;;;1854:16:11::1;;1874:1;1854:21:::0;1850:46:::1;;1884:12;;-1:-1:-1::0;;;1884:12:11::1;;;;;;;;;;;1850:46;1910:5;-1:-1:-1::0;;;;;1910:17:11::1;;1931:1;1910:22:::0;1906:48:::1;;1941:13;;-1:-1:-1::0;;;1941:13:11::1;;;;;;;;;;;1906:48;2134:10;-1:-1:-1::0;;;;;2087:57:11::1;2115:4;-1:-1:-1::0;;;;;2087:41:11::1;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2087:57:11::1;;;:127;;;;2209:5;-1:-1:-1::0;;;;;2164:50:11::1;2192:4;-1:-1:-1::0;;;;;2164:39:11::1;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2164:50:11::1;;;2087:127;2070:174;;;2232:12;;-1:-1:-1::0;;;2232:12:11::1;;;;;;;;;;;2070:174;2254:12;:28:::0;;-1:-1:-1;;;;;;2254:28:11;;::::1;-1:-1:-1::0;;;;;2254:28:11;;::::1;;::::0;;;2292:15:::1;:27:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;2329:22;;::::1;;::::0;2361;::::1;;::::0;2393:10;::::1;;::::0;2413:12:::1;;::::0;-1:-1:-1;461:4966:11;;2011:153:1;2100:13;2093:20;;-1:-1:-1;;;;;;2093:20:1;;;2123:34;2148:8;2123:24;:34::i;:::-;2011:153;:::o;2912:187:0:-;2985:16;3004:6;;-1:-1:-1;;;;;3020:17:0;;;-1:-1:-1;;;;;;3020:17:0;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;14:177:20:-;93:13;;-1:-1:-1;;;;;135:31:20;;125:42;;115:70;;181:1;178;171:12;115:70;14:177;;;:::o;196:722::-;320:6;328;336;344;352;360;368;421:3;409:9;400:7;396:23;392:33;389:53;;;438:1;435;428:12;389:53;461:40;491:9;461:40;:::i;:::-;451:50;;520:49;565:2;554:9;550:18;520:49;:::i;:::-;510:59;;588:49;633:2;622:9;618:18;588:49;:::i;:::-;578:59;;656:49;701:2;690:9;686:18;656:49;:::i;:::-;646:59;;724:50;769:3;758:9;754:19;724:50;:::i;:::-;714:60;;793:50;838:3;827:9;823:19;793:50;:::i;:::-;783:60;;862:50;907:3;896:9;892:19;862:50;:::i;:::-;852:60;;196:722;;;;;;;;;;:::o;1131:208::-;1201:6;1254:2;1242:9;1233:7;1229:23;1225:32;1222:52;;;1270:1;1267;1260:12;1222:52;1293:40;1323:9;1293:40;:::i;:::-;1283:50;1131:208;-1:-1:-1;;;1131:208:20:o;:::-;461:4966:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa26469706673582212203f3257855e96725c5f82166ce21a590dfcc5b4bebf5f10a7c4713a80d6b53c3f64736f6c634300081c0033","offset":22309},"2":{"value":"0xa2646970667358221220401939af5312071d413f49430baf389e94c154f401353af6e89995415dbba35d64736f6c634300081c0033","offset":22256}},"transformations":[{"type":"insert","offset":22362,"reason":"constructorArguments"}],"transformationValues":{"constructorArguments":"0x000000000000000000000000ed591b552a9ed3d99f2b43cdf7ae8aad6814ef59000000000000000000000000ed591b552a9ed3d99f2b43cdf7ae8aad6814ef5900000000000000000000000060b9262456de011f7d15a54cdd8c48baaa8b022f000000000000000000000000ca143ce32fe78f1f7019d7d551a6402fc5350c730000000000000000000000000bfbcf9fa4f9c56b0f40a671ad40e0805a09186500000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f4364000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c"}},"runtimeBytecode":{"onchainBytecode":"0x60806040526004361061011e575f3560e01c80637f1e9ef61161009d578063b4b57c3911610062578063b4b57c3914610337578063bdaad4881461036a578063e30c397814610389578063e74b981b146103a6578063f2fde38b146103c5575f5ffd5b80637f1e9ef6146102825780638854a0ff146102b55780638d72647e146102d45780638da5cb5b14610307578063a64ed8ba14610323575f5ffd5b806354fd4d50116100e357806354fd4d50146101eb578063634282af14610208578063715018a61461022757806379ba50971461023b5780637c887c591461024f575f5ffd5b806319f3736114610129578063266cedb31461016c5780633a5fedb71461019757806346904840146101b6578063476343ee146101d5575f5ffd5b3661012557005b5f5ffd5b348015610134575f5ffd5b50610157610143366004610b78565b60056020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61017f61017a366004610bdd565b6103e4565b6040516001600160a01b039091168152602001610163565b3480156101a2575f5ffd5b5061017f6101b1366004610c5a565b610644565b3480156101c1575f5ffd5b5060025461017f906001600160a01b031681565b3480156101e0575f5ffd5b506101e96107be565b005b3480156101f6575f5ffd5b5060025b604051908152602001610163565b348015610213575f5ffd5b5061017f610222366004610ce2565b61087d565b348015610232575f5ffd5b506101e96108a5565b348015610246575f5ffd5b506101e96108c6565b34801561025a575f5ffd5b5061017f7f0000000000000000000000000bfbcf9fa4f9c56b0f40a671ad40e0805a09186581565b34801561028d575f5ffd5b5061017f7f00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f436481565b3480156102c0575f5ffd5b5060035461017f906001600160a01b031681565b3480156102df575f5ffd5b5061017f7f000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c81565b348015610312575f5ffd5b505f546001600160a01b031661017f565b34801561032e575f5ffd5b506004546101fa565b348015610342575f5ffd5b5061017f7f000000000000000000000000ca143ce32fe78f1f7019d7d551a6402fc5350c7381565b348015610375575f5ffd5b506101e9610384366004610b78565b61090f565b348015610394575f5ffd5b506001546001600160a01b031661017f565b3480156103b1575f5ffd5b506101e96103c0366004610b78565b610996565b3480156103d0575f5ffd5b506101e96103df366004610b78565b610a13565b5f8515806103f25750604086115b156104105760405163430f13b360e01b815260040160405180910390fd5b83158061041d5750601084115b1561043b5760405163010466f160e21b815260040160405180910390fd5b6104453383610a83565b878787873360035f9054906101000a90046001600160a01b03167f000000000000000000000000ca143ce32fe78f1f7019d7d551a6402fc5350c737f0000000000000000000000000bfbcf9fa4f9c56b0f40a671ad40e0805a0918657f00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f43647f000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c6040516104ef90610b50565b6105029a99989796959493929190610d21565b8190604051809103905ff590508015801561051f573d5f5f3e3d5ffd5b506004805460018082019092557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0384169081179091555f8181526005602052604090819020805460ff1916909317909255905191925033917f5314f94e6e2d1a502483a5b446938dee47de600f90cbf915d89632d58a71aa2b906105c1908b908b908b908b908b90610d8e565b60405180910390a3341561063a5760405162de16a360e71b81523360048201526001600160a01b03821690636f0b518090349060240160206040518083038185885af1158015610613573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106389190610dc7565b505b9695505050505050565b5f5f6040518060200161065690610b50565b601f1982820381018352601f909101166040819052600354610716918a918a918a918a918f916001600160a01b0316907f000000000000000000000000ca143ce32fe78f1f7019d7d551a6402fc5350c73907f0000000000000000000000000bfbcf9fa4f9c56b0f40a671ad40e0805a091865907f00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f4364907f000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c90602001610d21565b60408051601f19818403018152908290526107349291602001610df5565b60405160208183030381529060405280519060200120905060ff60f81b3061075c8a86610a83565b6040516001600160f81b031993909316602084015260609190911b6bffffffffffffffffffffffff1916602183015260358201526055810182905260750160408051601f19818403018152919052805160209091012098975050505050505050565b60025460405147915f916001600160a01b039091169083908381818185875af1925050503d805f811461080c576040519150601f19603f3d011682016040523d82523d5f602084013e610811565b606091505b5050905080610833576040516312171d8360e31b815260040160405180910390fd5b600254604080516001600160a01b039092168252602082018490527fc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a910160405180910390a15050565b6004818154811061088c575f80fd5b5f918252602090912001546001600160a01b0316905081565b6108ad610abf565b604051638905116560e01b815260040160405180910390fd5b60015433906001600160a01b031681146109035760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61090c81610aed565b50565b610917610abf565b806001600160a01b03163b5f03610941576040516311a1e69760e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f1386da33541fecf49b0f53895aef3f30f6e3e08755deb017e106e7ae4f4c976d906020015b60405180910390a150565b61099e610abf565b6001600160a01b0381166109c55760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f7a7b5a0a132f9e0581eb8527f66eae9ee89c2a3e79d4ac7e41a1f1f4d48a7fc29060200161098b565b610a1b610abf565b600180546001600160a01b0383166001600160a01b03199091168117909155610a4b5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b03841660208201529081018290525f9060600160405160208183030381529060405280519060200120905092915050565b5f546001600160a01b03163314610aeb5760405163118cdaa760e01b81523360048201526024016108fa565b565b600180546001600160a01b031916905561090c815f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6144c880610e1283390190565b80356001600160a01b0381168114610b73575f5ffd5b919050565b5f60208284031215610b88575f5ffd5b610b9182610b5d565b9392505050565b5f5f83601f840112610ba8575f5ffd5b50813567ffffffffffffffff811115610bbf575f5ffd5b602083019150836020828501011115610bd6575f5ffd5b9250929050565b5f5f5f5f5f5f60808789031215610bf2575f5ffd5b863567ffffffffffffffff811115610c08575f5ffd5b610c1489828a01610b98565b909750955050602087013567ffffffffffffffff811115610c33575f5ffd5b610c3f89828a01610b98565b979a9699509760408101359660609091013595509350505050565b5f5f5f5f5f5f60808789031215610c6f575f5ffd5b610c7887610b5d565b9550602087013567ffffffffffffffff811115610c93575f5ffd5b610c9f89828a01610b98565b909650945050604087013567ffffffffffffffff811115610cbe575f5ffd5b610cca89828a01610b98565b979a9699509497949695606090950135949350505050565b5f60208284031215610cf2575f5ffd5b5035919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b61010081525f610d3661010083018c8e610cf9565b8281036020840152610d49818b8d610cf9565b6001600160a01b03998a16604085015297891660608401525050938616608085015291851660a0840152841660c083015290921660e090920191909152949350505050565b606081525f610da1606083018789610cf9565b8281036020840152610db4818688610cf9565b9150508260408301529695505050505050565b5f60208284031215610dd7575f5ffd5b5051919050565b5f81518060208401855e5f93019283525090919050565b5f610e09610e038386610dde565b84610dde565b94935050505056fe6101a0604052348015610010575f5ffd5b506040516144c83803806144c883398101604081905261002f91610877565b8787600361003d83826109cb565b50600461004a82826109cb565b5050600160055550336080526001600160a01b0386811660a05285811660c05284811660e0528381166101008190528382166101205290821661014081905230818110610160819052604051630b4c774160e11b815260048101929092526024820192909252612710604482015290915f91631698ee8290606401602060405180830381865afa1580156100e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101049190610a85565b90506001600160a01b03811661018e5760405163a167129560e01b81523060048201526001600160a01b038481166024830152612710604483015286169063a1671295906064016020604051808303815f875af1158015610167573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061018b9190610a85565b90505b806001600160a01b0316610180816001600160a01b0316815250505f816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156101e6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061020a9190610ab1565b5050505050509050806001600160a01b03165f0361028f576001600160a01b03821663f637731d61023a856102b5565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f604051808303815f87803b158015610278575f5ffd5b505af115801561028a573d5f5f3e3d5ffd5b505050505b6102a5306b033b2e3c9fd0803ce8000000610318565b5050505050505050505050610bd4565b5f806102cc6b0295be96e640669720000000610355565b9050826102f7576102f26102ed670de0b6b3a7640000600160c01b846103bb565b610471565b610311565b6103116102ed82600160c01b670de0b6b3a76400006103bb565b9392505050565b6001600160a01b0382166103465760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6103515f83836105c9565b5050565b5f8061036083610649565b905061036c8180610b64565b61038d6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b61039f90674a03ce68d2155555610b64565b6103b190670de0b6b3a7640000610b64565b6103119190610ba2565b5f838302815f1985870982811083820303915050805f036103ef578382816103e5576103e5610b8e565b0492505050610311565b80841161040657610406600385150260111861067c565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f6001821161047e575090565b816001600160801b82106104975760809190911c9060401b5b6801000000000000000082106104b25760409190911c9060201b5b64010000000082106104c95760209190911c9060101b5b6201000082106104de5760109190911c9060081b5b61010082106104f25760089190911c9060041b5b601082106105055760049190911c9060021b5b600482106105115760011b5b600302600190811c9081858161052957610529610b8e565b048201901c9050600181858161054157610541610b8e565b048201901c9050600181858161055957610559610b8e565b048201901c9050600181858161057157610571610b8e565b048201901c9050600181858161058957610589610b8e565b048201901c905060018185816105a1576105a1610b8e565b048201901c90506105c08185816105ba576105ba610b8e565b04821190565b90039392505050565b60065460ff161580156105e457506001600160a01b03831615155b80156105f957506001600160a01b0383163014155b801561061b575060ff5f5c16801561061957506001600160a01b03821630145b155b1561063957604051632b36b06160e01b815260040160405180910390fd5b61064483838361068d565b505050565b5f8161066c6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b6106769190610bc1565b92915050565b634e487b715f52806020526024601cfd5b6001600160a01b0383166106b7578060025f8282546106ac9190610b7b565b909155506107279050565b6001600160a01b0383165f90815260208190526040902054818110156107095760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161033d565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661074357600280548290039055610761565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107a691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126107d6575f5ffd5b81516001600160401b038111156107ef576107ef6107b3565b604051601f8201601f19908116603f011681016001600160401b038111828210171561081d5761081d6107b3565b604052818152838201602001851015610834575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b6001600160a01b0381168114610864575f5ffd5b50565b805161087281610850565b919050565b5f5f5f5f5f5f5f5f610100898b03121561088f575f5ffd5b88516001600160401b038111156108a4575f5ffd5b6108b08b828c016107c7565b60208b015190995090506001600160401b038111156108cd575f5ffd5b6108d98b828c016107c7565b97505060408901516108ea81610850565b60608a01519096506108fb81610850565b60808a015190955061090c81610850565b60a08a015190945061091d81610850565b925061092b60c08a01610867565b915061093960e08a01610867565b90509295985092959890939650565b600181811c9082168061095c57607f821691505b60208210810361097a57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561064457805f5260205f20601f840160051c810160208510156109a55750805b601f840160051c820191505b818110156109c4575f81556001016109b1565b5050505050565b81516001600160401b038111156109e4576109e46107b3565b6109f8816109f28454610948565b84610980565b6020601f821160018114610a2a575f8315610a135750848201515b5f19600385901b1c1916600184901b1784556109c4565b5f84815260208120601f198516915b82811015610a595787850151825560209485019460019092019101610a39565b5084821015610a7657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215610a95575f5ffd5b815161031181610850565b805161ffff81168114610872575f5ffd5b5f5f5f5f5f5f5f60e0888a031215610ac7575f5ffd5b8751610ad281610850565b8097505060208801518060020b8114610ae9575f5ffd5b9550610af760408901610aa0565b9450610b0560608901610aa0565b9350610b1360808901610aa0565b925060a088015163ffffffff81168114610b2b575f5ffd5b60c08901519092508015158114610b40575f5ffd5b8091505092959891949750929550565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761067657610676610b50565b8082018082111561067657610676610b50565b634e487b7160e01b5f52601260045260245ffd5b5f82610bbc57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561067657610676610b50565b60805160a05160c05160e051610100516101205161014051610160516101805161377e610d4a5f395f8181610376015281816109ec01528181611ea10152612d0f01525f81816104f20152818161098b01528181610ecf01528181611ec6015281816121ae015281816123f50152612cb701525f81816106770152818161187701528181612388015281816124850152818161254b0152818161258c015281816126f4015281816127a0015281816128620152818161293d015281816129e901528181612dcf01528181612e6b0152612f9801525f81816105df01528181610e600152818161241a015281816124560152818161250b0152818161268a015281816126c601528181612d650152612da101525f6105ac01525f8181610763015281816127ca015261288a01525f81816106120152610b0101525f81816102b20152610aa701525f81816107aa01528181610c3201528181610d740152818161119c015281816114820152612ed9015261377e5ff3fe608060405260043610610275575f3560e01c806371640de31161014a578063a8aa1b31116100be578063cd3293de11610078578063cd3293de146107e0578063d3618cca146107f4578063dd62ed3e14610808578063e4849b321461084c578063e7c2b7721461086b578063f6ccbda514610884575f5ffd5b8063a8aa1b3114610714578063a9059cbb14610733578063b4b57c3914610752578063b956993b14610785578063c45a015514610799578063c8796572146107cc575f5ffd5b80638d4b66c01161010f5780638d4b66c0146106475780638d72647e1461066657806395d89b41146106995780639c43a050146106ad578063a6195fd3146106c1578063a64190c4146106e0575f5ffd5b806371640de3146105865780637c887c591461059b5780637f1e9ef6146105ce5780638854a0ff146106015780638976254314610634575f5ffd5b806323b872dd116101ec5780635c1624ef116101a65780635c1624ef146104af5780635ed0447d146104c2578063604b1eba146104e1578063667022fd146105145780636f0b51801461053f57806370a0823114610552575f5ffd5b806323b872dd146103e9578063313ce56714610408578063398482d8146104295780634beb394c1461043d578063559f05dc1461047c578063577bd3361461049b575f5ffd5b806316e457f01161023d57806316e457f01461035157806316f0115b1461036557806318160ddd1461039857806320cce74b146103ac57806320f1fc61146103c057806323a69e75146103c8575f5ffd5b806302c7e7af1461027957806302d05d3f146102a157806303fd2a45146102ec57806306fdde0314610301578063095ea7b314610322575b5f5ffd5b348015610284575f5ffd5b5061028e60075481565b6040519081526020015b60405180910390f35b3480156102ac575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610298565b3480156102f7575f5ffd5b506102d461dead81565b34801561030c575f5ffd5b506103156108a2565b604051610298919061319c565b34801561032d575f5ffd5b5061034161033c3660046131e5565b610932565b6040519015158152602001610298565b34801561035c575f5ffd5b5061028e61094b565b348015610370575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a3575f5ffd5b5060025461028e565b3480156103b7575f5ffd5b506102d4610985565b61028e6109b4565b3480156103d3575f5ffd5b506103e76103e236600461320f565b6109d1565b005b3480156103f4575f5ffd5b5061034161040336600461328b565b610a47565b348015610413575f5ffd5b5060125b60405160ff9091168152602001610298565b348015610434575f5ffd5b5061028e610a6c565b348015610448575f5ffd5b5061045c6104573660046132c9565b610a78565b604080519485526020850193909352918301526060820152608001610298565b348015610487575f5ffd5b506103416104963660046132e0565b610a95565b3480156104a6575f5ffd5b5061028e610b73565b61028e6104bd3660046132c9565b610b9b565b3480156104cd575f5ffd5b5061045c6104dc3660046131e5565b610bc9565b3480156104ec575f5ffd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b34801561051f575f5ffd5b5061028e61052e3660046132e0565b60086020525f908152604090205481565b61028e61054d3660046132e0565b610c1e565b34801561055d575f5ffd5b5061028e61056c3660046132e0565b6001600160a01b03165f9081526020819052604090205490565b348015610591575f5ffd5b5061028e60095481565b3480156105a6575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d9575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561060c575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561063f575f5ffd5b506104175f81565b348015610652575f5ffd5b5061028e6106613660046132e0565b610c9f565b348015610671575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a4575f5ffd5b50610315610ccc565b3480156106b8575f5ffd5b50610417600281565b3480156106cc575f5ffd5b5061028e6106db3660046132fb565b610cdb565b3480156106eb575f5ffd5b506106ff6106fa3660046132c9565b610d04565b60408051928352602083019190915201610298565b34801561071f575f5ffd5b50600a546102d4906001600160a01b031681565b34801561073e575f5ffd5b5061034161074d3660046131e5565b610d2f565b34801561075d575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b348015610790575f5ffd5b50610417600181565b3480156107a4575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d7575f5ffd5b506106ff610d3c565b3480156107eb575f5ffd5b5061028e610f57565b3480156107ff575f5ffd5b506103e7610f63565b348015610813575f5ffd5b5061028e61082236600461331b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610857575f5ffd5b5061028e6108663660046132c9565b610fbd565b348015610876575f5ffd5b506006546103419060ff1681565b34801561088f575f5ffd5b5060065461041790610100900460ff1681565b6060600380546108b190613352565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90613352565b80156109285780601f106108ff57610100808354040283529160200191610928565b820191905f5260205f20905b81548152906001019060200180831161090b57829003601f168201915b5050505050905090565b5f3361093f818585610fda565b60019150505b92915050565b5f610954610fec565b61095d33611016565b335f818152602081905260408120546109769291611063565b90506109826001600555565b90565b5f6109af7f00000000000000000000000000000000000000000000000000000000000000006112a4565b905090565b5f6109bd610fec565b6109c633611016565b61097633345f611300565b60ff6101005f5c04161580610a0f5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b80610a1957508315155b80610a2357508215155b15610a415760405163f7a632f560e01b815260040160405180910390fd5b50505050565b5f33610a54858285611593565b610a5f85858561160d565b60019150505b9392505050565b5f6109af60075461166a565b5f5f5f5f610a863386610bc9565b93509350935093509193509193565b6006545f9060ff1615801561094557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061094557506040516370a0823160e01b81526001600160a01b0383811660048301525f917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015610b48573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6c919061338a565b1192915050565b5f6b0295be96e640669720000000600754612710610b9191906133b5565b6109af91906133e0565b5f610ba4610fec565b610bad33611016565b610bb8333484611300565b9050610bc46001600555565b919050565b6006545f9081908190819060ff1615610bec57505f925082915081905083610c15565b610bf686866116cf565b9195509350915081610c0884876133f3565b610c1291906133f3565b90505b92959194509250565b5f610c27610fec565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c7057604051630636a15760e11b815260040160405180910390fd5b60065460ff1615610c945760405163e6a0d45f60e01b815260040160405180910390fd5b610bb882345f611300565b6001600160a01b0381165f90815260086020526040812054610945906a18d0bf423c03d8de0000006133f3565b6060600480546108b190613352565b5f610ce4610fec565b610ced33611016565b610cf8338484611063565b90506109456001600555565b6006545f90819060ff1615610d1d57505f928392509050565b610d26836117a6565b91509150915091565b5f3361093f81858561160d565b5f5f610d46610fec565b600654610100900460ff16600114610d71576040516330aad80b60e01b815260040160405180910390fd5b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dce573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df29190613406565b6040805160808101825260095481526001600160a01b03838116602083019081526001600160801b0383850181815260608501828152955163fc6f786560e01b815294516004860152915183166024850152905181166044840152925190921660648201529192505f9182917f0000000000000000000000000000000000000000000000000000000000000000169063fc6f78659060840160408051808303815f875af1158015610ea5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ec99190613421565b915091507f0000000000000000000000000000000000000000000000000000000000000000610ef9578082610efc565b81815b60408051838152602081018390529297509095506001600160a01b038516917f2e4fb6077d4acf86e12bb7411fb82b2b3eaa6a49787f4b1e17b423e7ea841169910160405180910390a2505050610f536001600555565b9091565b5f6109af600754611807565b610f6b610fec565b60065460ff1680610f8a57506b0295be96e64066972000000060075414155b15610fa8576040516325a6766f60e21b815260040160405180910390fd5b610fb15f611860565b610fbb6001600555565b565b5f610fc6610fec565b610fcf33611016565b610bb833835f611063565b610fe78383836001611909565b505050565b60026005540361100f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600555565b60065460ff161561103a5760405163e6a0d45f60e01b815260040160405180910390fd5b61104381610a95565b61106057604051637c75aa6f60e11b815260040160405180910390fd5b50565b5f825f036110845760405163617ab12d60e11b815260040160405180910390fd5b6001600160a01b0384165f908152602081905260409020548311156110bc57604051631e9acf1760e31b815260040160405180910390fd5b5f6110c6846117a6565b90925090505f8290036110ec5760405163617ab12d60e11b815260040160405180910390fd5b8282101561110d57604051638199f5f360e01b815260040160405180910390fd5b5f8460075461111c91906133f3565b6007819055905060015f805c60ff19168217905d5061113c86308761160d565b5f60ff19815c16815d506040805186815260208101859052908101839052606081018290526001600160a01b038716907f483f8aec0fd892ac72ad1ba8d0e9c9e73db59c12d263fd71de480b5b3deeae3c9060800160405180910390a25f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611202576040519150601f19603f3d011682016040523d82523d5f602084013e611207565b606091505b505090508061122957604051634033e4e360e01b815260040160405180910390fd5b5f876001600160a01b0316856040515f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b505090508061129957604051630ec6ac4160e21b815260040160405180910390fd5b505050509392505050565b5f5f6112bb6b0295be96e64066972000000061166a565b9050826112e6576112e16112dc670de0b6b3a7640000600160c01b846119db565b611a91565b610a65565b610a656112dc82600160c01b670de0b6b3a76400006119db565b5f5f5f61130d86866116cf565b919450925090505f839003611377576001600160a01b0386165f908152600860205260409020546a18d0bf423c03d8de0000001161135e57604051636bf4c8e960e11b815260040160405180910390fd5b60405163617ab12d60e11b815260040160405180910390fd5b8383101561139857604051638199f5f360e01b815260040160405180910390fd5b5f836007546113a79190613443565b60078190556001600160a01b0388165f908152600860205260408120805492935086929091906113d8908490613443565b909155506113e9905030888661160d565b6040805184815260208101849052908101859052606081018290526001600160a01b038816907f064fb1933e186be0b289a87e98518dc18cc9856ecbc9f1353d1a138ddf733ec59060800160405180910390a25f8261144885896133f3565b61145291906133f3565b90506b0295be96e6406697200000008203611479576114796114748285613443565b611860565b8215611511575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846040515f6040518083038185875af1925050503d805f81146114e8576040519150601f19603f3d011682016040523d82523d5f602084013e6114ed565b606091505b505090508061150f57604051634033e4e360e01b815260040160405180910390fd5b505b8015611299575f886001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611560576040519150601f19603f3d011682016040523d82523d5f602084013e611565565b606091505b505090508061158757604051633c31275160e21b815260040160405180910390fd5b50505050509392505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f198114610a4157818110156115ff57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b610a4184848484035f611909565b6001600160a01b03831661163657604051634b637e8f60e11b81525f60048201526024016115f6565b6001600160a01b03821661165f5760405163ec442f0560e01b81525f60048201526024016115f6565b610fe7838383611be9565b5f5f61167583611c64565b905061168181806133b5565b6116a16a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b6116b390674a03ce68d21555556133b5565b6116c590670de0b6b3a76400006133b5565b610a6591906133e0565b6007545f9081908190816116e66064612710613443565b6116f2612710886133b5565b6116fc91906133e0565b90506117088282611c86565b94505f611721836b0295be96e6406697200000006133f3565b90508086111561172f578095505b6001600160a01b0388165f9081526008602052604081205461175c906a18d0bf423c03d8de0000006133f3565b90508087111561176a578096505b865f03611783575f5f5f9650965096505050505061179f565b61178d8488611d58565b955061179886611dfa565b9450505050505b9250925092565b6007545f9081908315806117b957508084115b156117c957505f93849350915050565b5f6117d48286611e2a565b90506117df81611dfa565b92508281116117f457505f9485945092505050565b6117fe83826133f3565b93505050915091565b5f674a03ce68d215555561181a83611c64565b61183a6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b61184c90674a03ce68d21555556133b5565b61185691906133e0565b61094591906133f3565b6006805460ff191660011790556001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d0e30db06118a683476133f3565b6040518263ffffffff1660e01b81526004015f604051808303818588803b1580156118cf575f5ffd5b505af11580156118e1573d5f5f3e3d5ffd5b50505050506118ee611e9e565b80156118fd57506118fd612355565b61106057611060612783565b6001600160a01b0384166119325760405163e602df0560e01b81525f60048201526024016115f6565b6001600160a01b03831661195b57604051634a1406b160e11b81525f60048201526024016115f6565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015610a4157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516119cd91815260200190565b60405180910390a350505050565b5f838302815f1985870982811083820303915050805f03611a0f57838281611a0557611a056133cc565b0492505050610a65565b808411611a2657611a266003851502601118612b19565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f60018211611a9e575090565b816001600160801b8210611ab75760809190911c9060401b5b680100000000000000008210611ad25760409190911c9060201b5b6401000000008210611ae95760209190911c9060101b5b620100008210611afe5760109190911c9060081b5b6101008210611b125760089190911c9060041b5b60108210611b255760049190911c9060021b5b60048210611b315760011b5b600302600190811c90818581611b4957611b496133cc565b048201901c90506001818581611b6157611b616133cc565b048201901c90506001818581611b7957611b796133cc565b048201901c90506001818581611b9157611b916133cc565b048201901c90506001818581611ba957611ba96133cc565b048201901c90506001818581611bc157611bc16133cc565b048201901c9050611be0818581611bda57611bda6133cc565b04821190565b90039392505050565b60065460ff16158015611c0457506001600160a01b03831615155b8015611c1957506001600160a01b0383163014155b8015611c3b575060ff5f5c168015611c3957506001600160a01b03821630145b155b15611c5957604051632b36b06160e01b815260040160405180910390fd5b610fe7838383612b2a565b5f816118566a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f5f611c9184611c64565b90505f81611cb56a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611cc790674a03ce68d21555556133b5565b611cd191906133e0565b90505f611cde8583613443565b611cfe6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d1090674a03ce68d21555556133b5565b611d1a91906133e0565b9050611d27816001613443565b8311611d38575f9350505050610945565b6001611d4482856133f3565b611d4e91906133f3565b9695505050505050565b5f5f611d6384611c64565b905080611d866a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d9890674a03ce68d21555556133b5565b611da291906133e0565b611dac84836133f3565b611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611dde90674a03ce68d21555556133b5565b611de891906133e0565b611df291906133f3565b949350505050565b5f612710600181611e0c6064866133b5565b611e169190613443565b611e2091906133f3565b61094591906133e0565b5f5f611e3584611c64565b9050611e418382613443565b611e616a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611e7390674a03ce68d21555556133b5565b611e7d91906133e0565b81611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f7f000000000000000000000000000000000000000000000000000000000000000081611eea7f00000000000000000000000000000000000000000000000000000000000000006112a4565b9050816001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f28573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4c919061346c565b6001600160801b031615611f62575f9250505090565b5f826001600160a01b03166370cf754a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f9f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fc3919061346c565b90506c0c9f2c9cd04674edea400000006001600160801b0382161015611fec575f935050505090565b5f6120046c0c9f2c9cd04674edea4000000083613485565b60405163f30dba9360e01b8152620d899f1960048201529091506001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa158015612058573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061207c919061346c565b6001600160801b0316118061210b575060405163f30dba9360e01b8152620d89a060048201526001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa1580156120dc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612100919061346c565b6001600160801b0316115b1561211a575f94505050505090565b5f5f856001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015612158573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061217c91906134c4565b505050505091509150846001600160a01b0316826001600160a01b0316036121ab576001965050505050505090565b5f7f00000000000000000000000000000000000000000000000000000000000000006121da5762027e5c6121e0565b62027e5c195b90506121ed878383612c43565b156121ff575f97505050505050505090565b6001600160a01b0380871690841611600161ff00195f805c9190911661010017905d50604051630251596160e31b81523060048201528115156024820152600160448201526001600160a01b03888116606483015260a060848301525f60a483015289169063128acb089060c40160408051808303815f875af19250505080156122a6575060408051601f3d908101601f191682019092526122a391810190613421565b60015b6122c3575f61ff0019815c16815d505f9850505050505050505090565b50505f61ff0019815c16815d50876001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa15801561230c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061233091906134c4565b5050506001600160a01b0393841693909a16929092149b9a5050505050505050505050565b305f9081526020819052604081205481906040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156123cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123f1919061338a565b90507f000000000000000000000000000000000000000000000000000000000000000061243f307f000000000000000000000000000000000000000000000000000000000000000085610fda565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156124cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124ef919061355a565b505f6124fd6103e8856133e0565b61250790856133f3565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663883164566040518061016001604052808561256f577f0000000000000000000000000000000000000000000000000000000000000000612571565b305b6001600160a01b031681526020018561258a57306125ac565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b031681526127106020820152620d899f196040820152620d89a06060820152608001856125e057866125e2565b875b8152602001856125f257876125f4565b865b815260200185612604575f612606565b845b8152602001856126165784612618565b5f5b815230602082015242604091820152516001600160e01b031960e084901b1681526126469190600401613573565b6080604051808303815f875af1925050508015612680575060408051601f3d908101601f1916820190925261267d91810190613637565b60015b612769576126af307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af115801561273a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275e919061355a565b505f94505050505090565b612774848383612c9f565b60019850505050505050505090565b60405163e6a4390560e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015612811573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128359190613406565b90506001600160a01b0381166128f7576040516364e329cb60e11b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063c9c65396906044016020604051808303815f875af11580156128d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128f49190613406565b90505b600a80546001600160a01b0319166001600160a01b03838116919091179091556006805461ff0019166102001790556040516370a0823160e01b81523060048201525f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612982573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129a6919061338a565b305f818152602081905260409020549192506129c390848361160d565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612a2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a53919061355a565b506040516335313c2160e11b815261dead60048201526001600160a01b03841690636a627842906024016020604051808303815f875af1158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd919061338a565b5060408051600281525f6020820152908101829052606081018390526001600160a01b0384169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe3906080015b60405180910390a3505050565b634e487b715f52806020526024601cfd5b6001600160a01b038316612b54578060025f828254612b499190613443565b90915550612bc49050565b6001600160a01b0383165f9081526020819052604090205481811015612ba65760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016115f6565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612be057600280548290039055612bfe565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b0c91815260200190565b5f8260020b8260020b13612c7357612c6c84612c5e84613052565b612c6786613052565b61308d565b9050610a65565b611df284612c8085613052565b612c8b906001613670565b612c9485613052565b612c67906001613670565b60098390556006805461ff0019166101001790555f807f0000000000000000000000000000000000000000000000000000000000000000612ce1578284612ce4565b83835b6040805160018152602081018990529081018390526060810182905291935091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe39060800160405180910390a3612d8a307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015612e15573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e39919061355a565b50305f908152602081905260408120546040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612eb0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed4919061338a565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f33573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f579190613406565b90508215612f6c57612f6c3061dead8561160d565b81156130045760405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612fde573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613002919061355a565b505b60408051848152602081018490526001600160a01b038316917fdb8b672bcfa06e1af0abf6157983be34c75ac7885f33fdfe514b4c800f3c5989910160405180910390a25050505050505050565b5f61305e60c883613695565b90505f8260020b12801561307e575061307860c8836136cd565b60020b15155b15610bc45780610a65816136ee565b5f8160020b8360020b13156130a357505f610a65565b600283810b600890811d9184900b901d815b8181136131905760405163299ce14b60e11b8152600182900b60048201525f906001600160a01b03891690635339c29690602401602060405180830381865afa158015613104573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613128919061338a565b9050805f03613137575061317e565b838203613147575f1960ff88161b165b8282036131695761315c60ff8088169061370f565b5f1962ffffff919091161c165b801561317c576001945050505050610a65565b505b806131888161372a565b9150506130b5565b505f9695505050505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114611060575f5ffd5b5f5f604083850312156131f6575f5ffd5b8235613201816131d1565b946020939093013593505050565b5f5f5f5f60608587031215613222575f5ffd5b8435935060208501359250604085013567ffffffffffffffff811115613246575f5ffd5b8501601f81018713613256575f5ffd5b803567ffffffffffffffff81111561326c575f5ffd5b87602082840101111561327d575f5ffd5b949793965060200194505050565b5f5f5f6060848603121561329d575f5ffd5b83356132a8816131d1565b925060208401356132b8816131d1565b929592945050506040919091013590565b5f602082840312156132d9575f5ffd5b5035919050565b5f602082840312156132f0575f5ffd5b8135610a65816131d1565b5f5f6040838503121561330c575f5ffd5b50508035926020909101359150565b5f5f6040838503121561332c575f5ffd5b8235613337816131d1565b91506020830135613347816131d1565b809150509250929050565b600181811c9082168061336657607f821691505b60208210810361338457634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561339a575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610945576109456133a1565b634e487b7160e01b5f52601260045260245ffd5b5f826133ee576133ee6133cc565b500490565b81810381811115610945576109456133a1565b5f60208284031215613416575f5ffd5b8151610a65816131d1565b5f5f60408385031215613432575f5ffd5b505080516020909101519092909150565b80820180821115610945576109456133a1565b80516001600160801b0381168114610bc4575f5ffd5b5f6020828403121561347c575f5ffd5b610a6582613456565b6001600160801b038281168282160390811115610945576109456133a1565b805161ffff81168114610bc4575f5ffd5b80518015158114610bc4575f5ffd5b5f5f5f5f5f5f5f60e0888a0312156134da575f5ffd5b87516134e5816131d1565b8097505060208801518060020b81146134fc575f5ffd5b955061350a604089016134a4565b9450613518606089016134a4565b9350613526608089016134a4565b925060a088015163ffffffff8116811461353e575f5ffd5b915061354c60c089016134b5565b905092959891949750929550565b5f6020828403121561356a575f5ffd5b610a65826134b5565b81516001600160a01b031681526101608101602083015161359f60208401826001600160a01b03169052565b5060408301516135b6604084018262ffffff169052565b5060608301516135cb606084018260020b9052565b5060808301516135e0608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008301516101008301526101208301516136276101208401826001600160a01b03169052565b5061014092830151919092015290565b5f5f5f5f6080858703121561364a575f5ffd5b8451935061365a60208601613456565b6040860151606090960151949790965092505050565b600281810b9083900b01627fffff8113627fffff1982121715610945576109456133a1565b5f8160020b8360020b806136ab576136ab6133cc565b627fffff1982145f19821416156136c4576136c46133a1565b90059392505050565b5f8260020b806136df576136df6133cc565b808360020b0791505092915050565b5f8160020b627fffff198103613706576137066133a1565b5f190192915050565b62ffffff8281168282160390811115610945576109456133a1565b5f6001600160ff1b018201613741576137416133a1565b506001019056fea2646970667358221220401939af5312071d413f49430baf389e94c154f401353af6e89995415dbba35d64736f6c634300081c0033a26469706673582212203f3257855e96725c5f82166ce21a590dfcc5b4bebf5f10a7c4713a80d6b53c3f64736f6c634300081c0033","recompiledBytecode":"0x60806040526004361061011e575f3560e01c80637f1e9ef61161009d578063b4b57c3911610062578063b4b57c3914610337578063bdaad4881461036a578063e30c397814610389578063e74b981b146103a6578063f2fde38b146103c5575f5ffd5b80637f1e9ef6146102825780638854a0ff146102b55780638d72647e146102d45780638da5cb5b14610307578063a64ed8ba14610323575f5ffd5b806354fd4d50116100e357806354fd4d50146101eb578063634282af14610208578063715018a61461022757806379ba50971461023b5780637c887c591461024f575f5ffd5b806319f3736114610129578063266cedb31461016c5780633a5fedb71461019757806346904840146101b6578063476343ee146101d5575f5ffd5b3661012557005b5f5ffd5b348015610134575f5ffd5b50610157610143366004610b78565b60056020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61017f61017a366004610bdd565b6103e4565b6040516001600160a01b039091168152602001610163565b3480156101a2575f5ffd5b5061017f6101b1366004610c5a565b610644565b3480156101c1575f5ffd5b5060025461017f906001600160a01b031681565b3480156101e0575f5ffd5b506101e96107be565b005b3480156101f6575f5ffd5b5060025b604051908152602001610163565b348015610213575f5ffd5b5061017f610222366004610ce2565b61087d565b348015610232575f5ffd5b506101e96108a5565b348015610246575f5ffd5b506101e96108c6565b34801561025a575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561028d575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c0575f5ffd5b5060035461017f906001600160a01b031681565b3480156102df575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610312575f5ffd5b505f546001600160a01b031661017f565b34801561032e575f5ffd5b506004546101fa565b348015610342575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610375575f5ffd5b506101e9610384366004610b78565b61090f565b348015610394575f5ffd5b506001546001600160a01b031661017f565b3480156103b1575f5ffd5b506101e96103c0366004610b78565b610996565b3480156103d0575f5ffd5b506101e96103df366004610b78565b610a13565b5f8515806103f25750604086115b156104105760405163430f13b360e01b815260040160405180910390fd5b83158061041d5750601084115b1561043b5760405163010466f160e21b815260040160405180910390fd5b6104453383610a83565b878787873360035f9054906101000a90046001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006040516104ef90610b50565b6105029a99989796959493929190610d21565b8190604051809103905ff590508015801561051f573d5f5f3e3d5ffd5b506004805460018082019092557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0384169081179091555f8181526005602052604090819020805460ff1916909317909255905191925033917f5314f94e6e2d1a502483a5b446938dee47de600f90cbf915d89632d58a71aa2b906105c1908b908b908b908b908b90610d8e565b60405180910390a3341561063a5760405162de16a360e71b81523360048201526001600160a01b03821690636f0b518090349060240160206040518083038185885af1158015610613573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106389190610dc7565b505b9695505050505050565b5f5f6040518060200161065690610b50565b601f1982820381018352601f909101166040819052600354610716918a918a918a918a918f916001600160a01b0316907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090602001610d21565b60408051601f19818403018152908290526107349291602001610df5565b60405160208183030381529060405280519060200120905060ff60f81b3061075c8a86610a83565b6040516001600160f81b031993909316602084015260609190911b6bffffffffffffffffffffffff1916602183015260358201526055810182905260750160408051601f19818403018152919052805160209091012098975050505050505050565b60025460405147915f916001600160a01b039091169083908381818185875af1925050503d805f811461080c576040519150601f19603f3d011682016040523d82523d5f602084013e610811565b606091505b5050905080610833576040516312171d8360e31b815260040160405180910390fd5b600254604080516001600160a01b039092168252602082018490527fc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a910160405180910390a15050565b6004818154811061088c575f80fd5b5f918252602090912001546001600160a01b0316905081565b6108ad610abf565b604051638905116560e01b815260040160405180910390fd5b60015433906001600160a01b031681146109035760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61090c81610aed565b50565b610917610abf565b806001600160a01b03163b5f03610941576040516311a1e69760e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f1386da33541fecf49b0f53895aef3f30f6e3e08755deb017e106e7ae4f4c976d906020015b60405180910390a150565b61099e610abf565b6001600160a01b0381166109c55760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f7a7b5a0a132f9e0581eb8527f66eae9ee89c2a3e79d4ac7e41a1f1f4d48a7fc29060200161098b565b610a1b610abf565b600180546001600160a01b0383166001600160a01b03199091168117909155610a4b5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b03841660208201529081018290525f9060600160405160208183030381529060405280519060200120905092915050565b5f546001600160a01b03163314610aeb5760405163118cdaa760e01b81523360048201526024016108fa565b565b600180546001600160a01b031916905561090c815f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6144c880610e1283390190565b80356001600160a01b0381168114610b73575f5ffd5b919050565b5f60208284031215610b88575f5ffd5b610b9182610b5d565b9392505050565b5f5f83601f840112610ba8575f5ffd5b50813567ffffffffffffffff811115610bbf575f5ffd5b602083019150836020828501011115610bd6575f5ffd5b9250929050565b5f5f5f5f5f5f60808789031215610bf2575f5ffd5b863567ffffffffffffffff811115610c08575f5ffd5b610c1489828a01610b98565b909750955050602087013567ffffffffffffffff811115610c33575f5ffd5b610c3f89828a01610b98565b979a9699509760408101359660609091013595509350505050565b5f5f5f5f5f5f60808789031215610c6f575f5ffd5b610c7887610b5d565b9550602087013567ffffffffffffffff811115610c93575f5ffd5b610c9f89828a01610b98565b909650945050604087013567ffffffffffffffff811115610cbe575f5ffd5b610cca89828a01610b98565b979a9699509497949695606090950135949350505050565b5f60208284031215610cf2575f5ffd5b5035919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b61010081525f610d3661010083018c8e610cf9565b8281036020840152610d49818b8d610cf9565b6001600160a01b03998a16604085015297891660608401525050938616608085015291851660a0840152841660c083015290921660e090920191909152949350505050565b606081525f610da1606083018789610cf9565b8281036020840152610db4818688610cf9565b9150508260408301529695505050505050565b5f60208284031215610dd7575f5ffd5b5051919050565b5f81518060208401855e5f93019283525090919050565b5f610e09610e038386610dde565b84610dde565b94935050505056fe6101a0604052348015610010575f5ffd5b506040516144c83803806144c883398101604081905261002f91610877565b8787600361003d83826109cb565b50600461004a82826109cb565b5050600160055550336080526001600160a01b0386811660a05285811660c05284811660e0528381166101008190528382166101205290821661014081905230818110610160819052604051630b4c774160e11b815260048101929092526024820192909252612710604482015290915f91631698ee8290606401602060405180830381865afa1580156100e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101049190610a85565b90506001600160a01b03811661018e5760405163a167129560e01b81523060048201526001600160a01b038481166024830152612710604483015286169063a1671295906064016020604051808303815f875af1158015610167573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061018b9190610a85565b90505b806001600160a01b0316610180816001600160a01b0316815250505f816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156101e6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061020a9190610ab1565b5050505050509050806001600160a01b03165f0361028f576001600160a01b03821663f637731d61023a856102b5565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f604051808303815f87803b158015610278575f5ffd5b505af115801561028a573d5f5f3e3d5ffd5b505050505b6102a5306b033b2e3c9fd0803ce8000000610318565b5050505050505050505050610bd4565b5f806102cc6b0295be96e640669720000000610355565b9050826102f7576102f26102ed670de0b6b3a7640000600160c01b846103bb565b610471565b610311565b6103116102ed82600160c01b670de0b6b3a76400006103bb565b9392505050565b6001600160a01b0382166103465760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6103515f83836105c9565b5050565b5f8061036083610649565b905061036c8180610b64565b61038d6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b61039f90674a03ce68d2155555610b64565b6103b190670de0b6b3a7640000610b64565b6103119190610ba2565b5f838302815f1985870982811083820303915050805f036103ef578382816103e5576103e5610b8e565b0492505050610311565b80841161040657610406600385150260111861067c565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f6001821161047e575090565b816001600160801b82106104975760809190911c9060401b5b6801000000000000000082106104b25760409190911c9060201b5b64010000000082106104c95760209190911c9060101b5b6201000082106104de5760109190911c9060081b5b61010082106104f25760089190911c9060041b5b601082106105055760049190911c9060021b5b600482106105115760011b5b600302600190811c9081858161052957610529610b8e565b048201901c9050600181858161054157610541610b8e565b048201901c9050600181858161055957610559610b8e565b048201901c9050600181858161057157610571610b8e565b048201901c9050600181858161058957610589610b8e565b048201901c905060018185816105a1576105a1610b8e565b048201901c90506105c08185816105ba576105ba610b8e565b04821190565b90039392505050565b60065460ff161580156105e457506001600160a01b03831615155b80156105f957506001600160a01b0383163014155b801561061b575060ff5f5c16801561061957506001600160a01b03821630145b155b1561063957604051632b36b06160e01b815260040160405180910390fd5b61064483838361068d565b505050565b5f8161066c6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b6106769190610bc1565b92915050565b634e487b715f52806020526024601cfd5b6001600160a01b0383166106b7578060025f8282546106ac9190610b7b565b909155506107279050565b6001600160a01b0383165f90815260208190526040902054818110156107095760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161033d565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661074357600280548290039055610761565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107a691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126107d6575f5ffd5b81516001600160401b038111156107ef576107ef6107b3565b604051601f8201601f19908116603f011681016001600160401b038111828210171561081d5761081d6107b3565b604052818152838201602001851015610834575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b6001600160a01b0381168114610864575f5ffd5b50565b805161087281610850565b919050565b5f5f5f5f5f5f5f5f610100898b03121561088f575f5ffd5b88516001600160401b038111156108a4575f5ffd5b6108b08b828c016107c7565b60208b015190995090506001600160401b038111156108cd575f5ffd5b6108d98b828c016107c7565b97505060408901516108ea81610850565b60608a01519096506108fb81610850565b60808a015190955061090c81610850565b60a08a015190945061091d81610850565b925061092b60c08a01610867565b915061093960e08a01610867565b90509295985092959890939650565b600181811c9082168061095c57607f821691505b60208210810361097a57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561064457805f5260205f20601f840160051c810160208510156109a55750805b601f840160051c820191505b818110156109c4575f81556001016109b1565b5050505050565b81516001600160401b038111156109e4576109e46107b3565b6109f8816109f28454610948565b84610980565b6020601f821160018114610a2a575f8315610a135750848201515b5f19600385901b1c1916600184901b1784556109c4565b5f84815260208120601f198516915b82811015610a595787850151825560209485019460019092019101610a39565b5084821015610a7657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215610a95575f5ffd5b815161031181610850565b805161ffff81168114610872575f5ffd5b5f5f5f5f5f5f5f60e0888a031215610ac7575f5ffd5b8751610ad281610850565b8097505060208801518060020b8114610ae9575f5ffd5b9550610af760408901610aa0565b9450610b0560608901610aa0565b9350610b1360808901610aa0565b925060a088015163ffffffff81168114610b2b575f5ffd5b60c08901519092508015158114610b40575f5ffd5b8091505092959891949750929550565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761067657610676610b50565b8082018082111561067657610676610b50565b634e487b7160e01b5f52601260045260245ffd5b5f82610bbc57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561067657610676610b50565b60805160a05160c05160e051610100516101205161014051610160516101805161377e610d4a5f395f8181610376015281816109ec01528181611ea10152612d0f01525f81816104f20152818161098b01528181610ecf01528181611ec6015281816121ae015281816123f50152612cb701525f81816106770152818161187701528181612388015281816124850152818161254b0152818161258c015281816126f4015281816127a0015281816128620152818161293d015281816129e901528181612dcf01528181612e6b0152612f9801525f81816105df01528181610e600152818161241a015281816124560152818161250b0152818161268a015281816126c601528181612d650152612da101525f6105ac01525f8181610763015281816127ca015261288a01525f81816106120152610b0101525f81816102b20152610aa701525f81816107aa01528181610c3201528181610d740152818161119c015281816114820152612ed9015261377e5ff3fe608060405260043610610275575f3560e01c806371640de31161014a578063a8aa1b31116100be578063cd3293de11610078578063cd3293de146107e0578063d3618cca146107f4578063dd62ed3e14610808578063e4849b321461084c578063e7c2b7721461086b578063f6ccbda514610884575f5ffd5b8063a8aa1b3114610714578063a9059cbb14610733578063b4b57c3914610752578063b956993b14610785578063c45a015514610799578063c8796572146107cc575f5ffd5b80638d4b66c01161010f5780638d4b66c0146106475780638d72647e1461066657806395d89b41146106995780639c43a050146106ad578063a6195fd3146106c1578063a64190c4146106e0575f5ffd5b806371640de3146105865780637c887c591461059b5780637f1e9ef6146105ce5780638854a0ff146106015780638976254314610634575f5ffd5b806323b872dd116101ec5780635c1624ef116101a65780635c1624ef146104af5780635ed0447d146104c2578063604b1eba146104e1578063667022fd146105145780636f0b51801461053f57806370a0823114610552575f5ffd5b806323b872dd146103e9578063313ce56714610408578063398482d8146104295780634beb394c1461043d578063559f05dc1461047c578063577bd3361461049b575f5ffd5b806316e457f01161023d57806316e457f01461035157806316f0115b1461036557806318160ddd1461039857806320cce74b146103ac57806320f1fc61146103c057806323a69e75146103c8575f5ffd5b806302c7e7af1461027957806302d05d3f146102a157806303fd2a45146102ec57806306fdde0314610301578063095ea7b314610322575b5f5ffd5b348015610284575f5ffd5b5061028e60075481565b6040519081526020015b60405180910390f35b3480156102ac575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610298565b3480156102f7575f5ffd5b506102d461dead81565b34801561030c575f5ffd5b506103156108a2565b604051610298919061319c565b34801561032d575f5ffd5b5061034161033c3660046131e5565b610932565b6040519015158152602001610298565b34801561035c575f5ffd5b5061028e61094b565b348015610370575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a3575f5ffd5b5060025461028e565b3480156103b7575f5ffd5b506102d4610985565b61028e6109b4565b3480156103d3575f5ffd5b506103e76103e236600461320f565b6109d1565b005b3480156103f4575f5ffd5b5061034161040336600461328b565b610a47565b348015610413575f5ffd5b5060125b60405160ff9091168152602001610298565b348015610434575f5ffd5b5061028e610a6c565b348015610448575f5ffd5b5061045c6104573660046132c9565b610a78565b604080519485526020850193909352918301526060820152608001610298565b348015610487575f5ffd5b506103416104963660046132e0565b610a95565b3480156104a6575f5ffd5b5061028e610b73565b61028e6104bd3660046132c9565b610b9b565b3480156104cd575f5ffd5b5061045c6104dc3660046131e5565b610bc9565b3480156104ec575f5ffd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b34801561051f575f5ffd5b5061028e61052e3660046132e0565b60086020525f908152604090205481565b61028e61054d3660046132e0565b610c1e565b34801561055d575f5ffd5b5061028e61056c3660046132e0565b6001600160a01b03165f9081526020819052604090205490565b348015610591575f5ffd5b5061028e60095481565b3480156105a6575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d9575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561060c575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561063f575f5ffd5b506104175f81565b348015610652575f5ffd5b5061028e6106613660046132e0565b610c9f565b348015610671575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a4575f5ffd5b50610315610ccc565b3480156106b8575f5ffd5b50610417600281565b3480156106cc575f5ffd5b5061028e6106db3660046132fb565b610cdb565b3480156106eb575f5ffd5b506106ff6106fa3660046132c9565b610d04565b60408051928352602083019190915201610298565b34801561071f575f5ffd5b50600a546102d4906001600160a01b031681565b34801561073e575f5ffd5b5061034161074d3660046131e5565b610d2f565b34801561075d575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b348015610790575f5ffd5b50610417600181565b3480156107a4575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d7575f5ffd5b506106ff610d3c565b3480156107eb575f5ffd5b5061028e610f57565b3480156107ff575f5ffd5b506103e7610f63565b348015610813575f5ffd5b5061028e61082236600461331b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610857575f5ffd5b5061028e6108663660046132c9565b610fbd565b348015610876575f5ffd5b506006546103419060ff1681565b34801561088f575f5ffd5b5060065461041790610100900460ff1681565b6060600380546108b190613352565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90613352565b80156109285780601f106108ff57610100808354040283529160200191610928565b820191905f5260205f20905b81548152906001019060200180831161090b57829003601f168201915b5050505050905090565b5f3361093f818585610fda565b60019150505b92915050565b5f610954610fec565b61095d33611016565b335f818152602081905260408120546109769291611063565b90506109826001600555565b90565b5f6109af7f00000000000000000000000000000000000000000000000000000000000000006112a4565b905090565b5f6109bd610fec565b6109c633611016565b61097633345f611300565b60ff6101005f5c04161580610a0f5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b80610a1957508315155b80610a2357508215155b15610a415760405163f7a632f560e01b815260040160405180910390fd5b50505050565b5f33610a54858285611593565b610a5f85858561160d565b60019150505b9392505050565b5f6109af60075461166a565b5f5f5f5f610a863386610bc9565b93509350935093509193509193565b6006545f9060ff1615801561094557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061094557506040516370a0823160e01b81526001600160a01b0383811660048301525f917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015610b48573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6c919061338a565b1192915050565b5f6b0295be96e640669720000000600754612710610b9191906133b5565b6109af91906133e0565b5f610ba4610fec565b610bad33611016565b610bb8333484611300565b9050610bc46001600555565b919050565b6006545f9081908190819060ff1615610bec57505f925082915081905083610c15565b610bf686866116cf565b9195509350915081610c0884876133f3565b610c1291906133f3565b90505b92959194509250565b5f610c27610fec565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c7057604051630636a15760e11b815260040160405180910390fd5b60065460ff1615610c945760405163e6a0d45f60e01b815260040160405180910390fd5b610bb882345f611300565b6001600160a01b0381165f90815260086020526040812054610945906a18d0bf423c03d8de0000006133f3565b6060600480546108b190613352565b5f610ce4610fec565b610ced33611016565b610cf8338484611063565b90506109456001600555565b6006545f90819060ff1615610d1d57505f928392509050565b610d26836117a6565b91509150915091565b5f3361093f81858561160d565b5f5f610d46610fec565b600654610100900460ff16600114610d71576040516330aad80b60e01b815260040160405180910390fd5b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dce573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df29190613406565b6040805160808101825260095481526001600160a01b03838116602083019081526001600160801b0383850181815260608501828152955163fc6f786560e01b815294516004860152915183166024850152905181166044840152925190921660648201529192505f9182917f0000000000000000000000000000000000000000000000000000000000000000169063fc6f78659060840160408051808303815f875af1158015610ea5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ec99190613421565b915091507f0000000000000000000000000000000000000000000000000000000000000000610ef9578082610efc565b81815b60408051838152602081018390529297509095506001600160a01b038516917f2e4fb6077d4acf86e12bb7411fb82b2b3eaa6a49787f4b1e17b423e7ea841169910160405180910390a2505050610f536001600555565b9091565b5f6109af600754611807565b610f6b610fec565b60065460ff1680610f8a57506b0295be96e64066972000000060075414155b15610fa8576040516325a6766f60e21b815260040160405180910390fd5b610fb15f611860565b610fbb6001600555565b565b5f610fc6610fec565b610fcf33611016565b610bb833835f611063565b610fe78383836001611909565b505050565b60026005540361100f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600555565b60065460ff161561103a5760405163e6a0d45f60e01b815260040160405180910390fd5b61104381610a95565b61106057604051637c75aa6f60e11b815260040160405180910390fd5b50565b5f825f036110845760405163617ab12d60e11b815260040160405180910390fd5b6001600160a01b0384165f908152602081905260409020548311156110bc57604051631e9acf1760e31b815260040160405180910390fd5b5f6110c6846117a6565b90925090505f8290036110ec5760405163617ab12d60e11b815260040160405180910390fd5b8282101561110d57604051638199f5f360e01b815260040160405180910390fd5b5f8460075461111c91906133f3565b6007819055905060015f805c60ff19168217905d5061113c86308761160d565b5f60ff19815c16815d506040805186815260208101859052908101839052606081018290526001600160a01b038716907f483f8aec0fd892ac72ad1ba8d0e9c9e73db59c12d263fd71de480b5b3deeae3c9060800160405180910390a25f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611202576040519150601f19603f3d011682016040523d82523d5f602084013e611207565b606091505b505090508061122957604051634033e4e360e01b815260040160405180910390fd5b5f876001600160a01b0316856040515f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b505090508061129957604051630ec6ac4160e21b815260040160405180910390fd5b505050509392505050565b5f5f6112bb6b0295be96e64066972000000061166a565b9050826112e6576112e16112dc670de0b6b3a7640000600160c01b846119db565b611a91565b610a65565b610a656112dc82600160c01b670de0b6b3a76400006119db565b5f5f5f61130d86866116cf565b919450925090505f839003611377576001600160a01b0386165f908152600860205260409020546a18d0bf423c03d8de0000001161135e57604051636bf4c8e960e11b815260040160405180910390fd5b60405163617ab12d60e11b815260040160405180910390fd5b8383101561139857604051638199f5f360e01b815260040160405180910390fd5b5f836007546113a79190613443565b60078190556001600160a01b0388165f908152600860205260408120805492935086929091906113d8908490613443565b909155506113e9905030888661160d565b6040805184815260208101849052908101859052606081018290526001600160a01b038816907f064fb1933e186be0b289a87e98518dc18cc9856ecbc9f1353d1a138ddf733ec59060800160405180910390a25f8261144885896133f3565b61145291906133f3565b90506b0295be96e6406697200000008203611479576114796114748285613443565b611860565b8215611511575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846040515f6040518083038185875af1925050503d805f81146114e8576040519150601f19603f3d011682016040523d82523d5f602084013e6114ed565b606091505b505090508061150f57604051634033e4e360e01b815260040160405180910390fd5b505b8015611299575f886001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611560576040519150601f19603f3d011682016040523d82523d5f602084013e611565565b606091505b505090508061158757604051633c31275160e21b815260040160405180910390fd5b50505050509392505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f198114610a4157818110156115ff57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b610a4184848484035f611909565b6001600160a01b03831661163657604051634b637e8f60e11b81525f60048201526024016115f6565b6001600160a01b03821661165f5760405163ec442f0560e01b81525f60048201526024016115f6565b610fe7838383611be9565b5f5f61167583611c64565b905061168181806133b5565b6116a16a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b6116b390674a03ce68d21555556133b5565b6116c590670de0b6b3a76400006133b5565b610a6591906133e0565b6007545f9081908190816116e66064612710613443565b6116f2612710886133b5565b6116fc91906133e0565b90506117088282611c86565b94505f611721836b0295be96e6406697200000006133f3565b90508086111561172f578095505b6001600160a01b0388165f9081526008602052604081205461175c906a18d0bf423c03d8de0000006133f3565b90508087111561176a578096505b865f03611783575f5f5f9650965096505050505061179f565b61178d8488611d58565b955061179886611dfa565b9450505050505b9250925092565b6007545f9081908315806117b957508084115b156117c957505f93849350915050565b5f6117d48286611e2a565b90506117df81611dfa565b92508281116117f457505f9485945092505050565b6117fe83826133f3565b93505050915091565b5f674a03ce68d215555561181a83611c64565b61183a6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b61184c90674a03ce68d21555556133b5565b61185691906133e0565b61094591906133f3565b6006805460ff191660011790556001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d0e30db06118a683476133f3565b6040518263ffffffff1660e01b81526004015f604051808303818588803b1580156118cf575f5ffd5b505af11580156118e1573d5f5f3e3d5ffd5b50505050506118ee611e9e565b80156118fd57506118fd612355565b61106057611060612783565b6001600160a01b0384166119325760405163e602df0560e01b81525f60048201526024016115f6565b6001600160a01b03831661195b57604051634a1406b160e11b81525f60048201526024016115f6565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015610a4157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516119cd91815260200190565b60405180910390a350505050565b5f838302815f1985870982811083820303915050805f03611a0f57838281611a0557611a056133cc565b0492505050610a65565b808411611a2657611a266003851502601118612b19565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f60018211611a9e575090565b816001600160801b8210611ab75760809190911c9060401b5b680100000000000000008210611ad25760409190911c9060201b5b6401000000008210611ae95760209190911c9060101b5b620100008210611afe5760109190911c9060081b5b6101008210611b125760089190911c9060041b5b60108210611b255760049190911c9060021b5b60048210611b315760011b5b600302600190811c90818581611b4957611b496133cc565b048201901c90506001818581611b6157611b616133cc565b048201901c90506001818581611b7957611b796133cc565b048201901c90506001818581611b9157611b916133cc565b048201901c90506001818581611ba957611ba96133cc565b048201901c90506001818581611bc157611bc16133cc565b048201901c9050611be0818581611bda57611bda6133cc565b04821190565b90039392505050565b60065460ff16158015611c0457506001600160a01b03831615155b8015611c1957506001600160a01b0383163014155b8015611c3b575060ff5f5c168015611c3957506001600160a01b03821630145b155b15611c5957604051632b36b06160e01b815260040160405180910390fd5b610fe7838383612b2a565b5f816118566a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f5f611c9184611c64565b90505f81611cb56a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611cc790674a03ce68d21555556133b5565b611cd191906133e0565b90505f611cde8583613443565b611cfe6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d1090674a03ce68d21555556133b5565b611d1a91906133e0565b9050611d27816001613443565b8311611d38575f9350505050610945565b6001611d4482856133f3565b611d4e91906133f3565b9695505050505050565b5f5f611d6384611c64565b905080611d866a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d9890674a03ce68d21555556133b5565b611da291906133e0565b611dac84836133f3565b611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611dde90674a03ce68d21555556133b5565b611de891906133e0565b611df291906133f3565b949350505050565b5f612710600181611e0c6064866133b5565b611e169190613443565b611e2091906133f3565b61094591906133e0565b5f5f611e3584611c64565b9050611e418382613443565b611e616a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611e7390674a03ce68d21555556133b5565b611e7d91906133e0565b81611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f7f000000000000000000000000000000000000000000000000000000000000000081611eea7f00000000000000000000000000000000000000000000000000000000000000006112a4565b9050816001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f28573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4c919061346c565b6001600160801b031615611f62575f9250505090565b5f826001600160a01b03166370cf754a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f9f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fc3919061346c565b90506c0c9f2c9cd04674edea400000006001600160801b0382161015611fec575f935050505090565b5f6120046c0c9f2c9cd04674edea4000000083613485565b60405163f30dba9360e01b8152620d899f1960048201529091506001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa158015612058573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061207c919061346c565b6001600160801b0316118061210b575060405163f30dba9360e01b8152620d89a060048201526001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa1580156120dc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612100919061346c565b6001600160801b0316115b1561211a575f94505050505090565b5f5f856001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015612158573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061217c91906134c4565b505050505091509150846001600160a01b0316826001600160a01b0316036121ab576001965050505050505090565b5f7f00000000000000000000000000000000000000000000000000000000000000006121da5762027e5c6121e0565b62027e5c195b90506121ed878383612c43565b156121ff575f97505050505050505090565b6001600160a01b0380871690841611600161ff00195f805c9190911661010017905d50604051630251596160e31b81523060048201528115156024820152600160448201526001600160a01b03888116606483015260a060848301525f60a483015289169063128acb089060c40160408051808303815f875af19250505080156122a6575060408051601f3d908101601f191682019092526122a391810190613421565b60015b6122c3575f61ff0019815c16815d505f9850505050505050505090565b50505f61ff0019815c16815d50876001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa15801561230c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061233091906134c4565b5050506001600160a01b0393841693909a16929092149b9a5050505050505050505050565b305f9081526020819052604081205481906040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156123cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123f1919061338a565b90507f000000000000000000000000000000000000000000000000000000000000000061243f307f000000000000000000000000000000000000000000000000000000000000000085610fda565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156124cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124ef919061355a565b505f6124fd6103e8856133e0565b61250790856133f3565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663883164566040518061016001604052808561256f577f0000000000000000000000000000000000000000000000000000000000000000612571565b305b6001600160a01b031681526020018561258a57306125ac565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b031681526127106020820152620d899f196040820152620d89a06060820152608001856125e057866125e2565b875b8152602001856125f257876125f4565b865b815260200185612604575f612606565b845b8152602001856126165784612618565b5f5b815230602082015242604091820152516001600160e01b031960e084901b1681526126469190600401613573565b6080604051808303815f875af1925050508015612680575060408051601f3d908101601f1916820190925261267d91810190613637565b60015b612769576126af307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af115801561273a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275e919061355a565b505f94505050505090565b612774848383612c9f565b60019850505050505050505090565b60405163e6a4390560e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015612811573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128359190613406565b90506001600160a01b0381166128f7576040516364e329cb60e11b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063c9c65396906044016020604051808303815f875af11580156128d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128f49190613406565b90505b600a80546001600160a01b0319166001600160a01b03838116919091179091556006805461ff0019166102001790556040516370a0823160e01b81523060048201525f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612982573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129a6919061338a565b305f818152602081905260409020549192506129c390848361160d565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612a2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a53919061355a565b506040516335313c2160e11b815261dead60048201526001600160a01b03841690636a627842906024016020604051808303815f875af1158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd919061338a565b5060408051600281525f6020820152908101829052606081018390526001600160a01b0384169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe3906080015b60405180910390a3505050565b634e487b715f52806020526024601cfd5b6001600160a01b038316612b54578060025f828254612b499190613443565b90915550612bc49050565b6001600160a01b0383165f9081526020819052604090205481811015612ba65760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016115f6565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612be057600280548290039055612bfe565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b0c91815260200190565b5f8260020b8260020b13612c7357612c6c84612c5e84613052565b612c6786613052565b61308d565b9050610a65565b611df284612c8085613052565b612c8b906001613670565b612c9485613052565b612c67906001613670565b60098390556006805461ff0019166101001790555f807f0000000000000000000000000000000000000000000000000000000000000000612ce1578284612ce4565b83835b6040805160018152602081018990529081018390526060810182905291935091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe39060800160405180910390a3612d8a307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015612e15573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e39919061355a565b50305f908152602081905260408120546040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612eb0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed4919061338a565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f33573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f579190613406565b90508215612f6c57612f6c3061dead8561160d565b81156130045760405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612fde573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613002919061355a565b505b60408051848152602081018490526001600160a01b038316917fdb8b672bcfa06e1af0abf6157983be34c75ac7885f33fdfe514b4c800f3c5989910160405180910390a25050505050505050565b5f61305e60c883613695565b90505f8260020b12801561307e575061307860c8836136cd565b60020b15155b15610bc45780610a65816136ee565b5f8160020b8360020b13156130a357505f610a65565b600283810b600890811d9184900b901d815b8181136131905760405163299ce14b60e11b8152600182900b60048201525f906001600160a01b03891690635339c29690602401602060405180830381865afa158015613104573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613128919061338a565b9050805f03613137575061317e565b838203613147575f1960ff88161b165b8282036131695761315c60ff8088169061370f565b5f1962ffffff919091161c165b801561317c576001945050505050610a65565b505b806131888161372a565b9150506130b5565b505f9695505050505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114611060575f5ffd5b5f5f604083850312156131f6575f5ffd5b8235613201816131d1565b946020939093013593505050565b5f5f5f5f60608587031215613222575f5ffd5b8435935060208501359250604085013567ffffffffffffffff811115613246575f5ffd5b8501601f81018713613256575f5ffd5b803567ffffffffffffffff81111561326c575f5ffd5b87602082840101111561327d575f5ffd5b949793965060200194505050565b5f5f5f6060848603121561329d575f5ffd5b83356132a8816131d1565b925060208401356132b8816131d1565b929592945050506040919091013590565b5f602082840312156132d9575f5ffd5b5035919050565b5f602082840312156132f0575f5ffd5b8135610a65816131d1565b5f5f6040838503121561330c575f5ffd5b50508035926020909101359150565b5f5f6040838503121561332c575f5ffd5b8235613337816131d1565b91506020830135613347816131d1565b809150509250929050565b600181811c9082168061336657607f821691505b60208210810361338457634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561339a575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610945576109456133a1565b634e487b7160e01b5f52601260045260245ffd5b5f826133ee576133ee6133cc565b500490565b81810381811115610945576109456133a1565b5f60208284031215613416575f5ffd5b8151610a65816131d1565b5f5f60408385031215613432575f5ffd5b505080516020909101519092909150565b80820180821115610945576109456133a1565b80516001600160801b0381168114610bc4575f5ffd5b5f6020828403121561347c575f5ffd5b610a6582613456565b6001600160801b038281168282160390811115610945576109456133a1565b805161ffff81168114610bc4575f5ffd5b80518015158114610bc4575f5ffd5b5f5f5f5f5f5f5f60e0888a0312156134da575f5ffd5b87516134e5816131d1565b8097505060208801518060020b81146134fc575f5ffd5b955061350a604089016134a4565b9450613518606089016134a4565b9350613526608089016134a4565b925060a088015163ffffffff8116811461353e575f5ffd5b915061354c60c089016134b5565b905092959891949750929550565b5f6020828403121561356a575f5ffd5b610a65826134b5565b81516001600160a01b031681526101608101602083015161359f60208401826001600160a01b03169052565b5060408301516135b6604084018262ffffff169052565b5060608301516135cb606084018260020b9052565b5060808301516135e0608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008301516101008301526101208301516136276101208401826001600160a01b03169052565b5061014092830151919092015290565b5f5f5f5f6080858703121561364a575f5ffd5b8451935061365a60208601613456565b6040860151606090960151949790965092505050565b600281810b9083900b01627fffff8113627fffff1982121715610945576109456133a1565b5f8160020b8360020b806136ab576136ab6133cc565b627fffff1982145f19821416156136c4576136c46133a1565b90059392505050565b5f8260020b806136df576136df6133cc565b808360020b0791505092915050565b5f8160020b627fffff198103613706576137066133a1565b5f190192915050565b62ffffff8281168282160390811115610945576109456133a1565b5f6001600160ff1b018201613741576137416133a1565b506001019056fea2646970667358221220401939af5312071d413f49430baf389e94c154f401353af6e89995415dbba35d64736f6c634300081c0033a26469706673582212203f3257855e96725c5f82166ce21a590dfcc5b4bebf5f10a7c4713a80d6b53c3f64736f6c634300081c0033","sourceMap":"461:4966:11:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1312:39;;;;;;;;;;-1:-1:-1;1312:39:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;548:14:20;;541:22;523:41;;511:2;496:18;1312:39:11;;;;;;;;2650:788;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2048:32:20;;;2030:51;;2018:2;2003:18;2650:788:11;1884:203:20;3444:580:11;;;;;;;;;;-1:-1:-1;3444:580:11;;;;;:::i;:::-;;:::i;1211:27::-;;;;;;;;;;-1:-1:-1;1211:27:11;;;;-1:-1:-1;;;;;1211:27:11;;;5035:239;;;;;;;;;;;;;:::i;:::-;;2568:76;;;;;;;;;;-1:-1:-1;2636:1:11;2568:76;;;3148:25:20;;;3136:2;3121:18;2568:76:11;3002:177:20;1280:26:11;;;;;;;;;;-1:-1:-1;1280:26:11;;;;;:::i;:::-;;:::i;4856:102::-;;;;;;;;;;;;;:::i;2244:229:1:-;;;;;;;;;;;;;:::i;1101:34:11:-;;;;;;;;;;;;;;;1141:28;;;;;;;;;;;;;;;1244:30;;;;;;;;;;-1:-1:-1;1244:30:11;;;;-1:-1:-1;;;;;1244:30:11;;;1175:29;;;;;;;;;;;;;;;1638:85:0;;;;;;;;;;-1:-1:-1;1684:7:0;1710:6;-1:-1:-1;;;;;1710:6:0;1638:85;;4030:95:11;;;;;;;;;;-1:-1:-1;4102:9:11;:16;4030:95;;1061:34;;;;;;;;;;;;;;;4535:224;;;;;;;;;;-1:-1:-1;4535:224:11;;;;;:::i;:::-;;:::i;1232:99:1:-;;;;;;;;;;-1:-1:-1;1311:13:1;;-1:-1:-1;;;;;1311:13:1;1232:99;;4243:224:11;;;;;;;;;;-1:-1:-1;4243:224:11;;;;;:::i;:::-;;:::i;1649:178:1:-;;;;;;;;;;-1:-1:-1;1649:178:1;;;;;:::i;:::-;;:::i;2650:788:11:-;2803:13;2836:23;;;:50;;-1:-1:-1;2884:2:11;2863:23;;2836:50;2832:76;;;2895:13;;-1:-1:-1;;;2895:13:11;;;;;;;;;;;2832:76;2922:25;;;:54;;-1:-1:-1;2974:2:11;2951:25;;2922:54;2918:82;;;2985:15;;-1:-1:-1;;;2985:15:11;;;;;;;;;;;2918:82;3066:27;3072:10;3084:8;3066:5;:27::i;:::-;3112:4;;3118:6;;3126:10;3138:15;;;;;;;;;-1:-1:-1;;;;;3138:15:11;3155:9;3166;3177:3;3182:4;3040:160;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3220:9:11;:21;;;;;;;;;;;;;-1:-1:-1;;;;;;3220:21:11;-1:-1:-1;;;;;3220:21:11;;;;;;;;-1:-1:-1;3251:14:11;;;:7;3220:21;3251:14;;;;;;:21;;-1:-1:-1;;3251:21:11;;;;;;;3287:55;;3220:21;;-1:-1:-1;3307:10:11;;3287:55;;;;3319:4;;;;3325:6;;;;3333:8;;3287:55;:::i;:::-;;;;;;;;3357:9;:13;3353:78;;3372:59;;-1:-1:-1;;;3372:59:11;;3420:10;3372:59;;;2030:51:20;-1:-1:-1;;;;;3372:29:11;;;;;3409:9;;2003:18:20;;3372:59:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3353:78;2650:788;;;;;;;;:::o;3444:580::-;3601:7;3624:16;3700:34;;;;;;;;:::i;:::-;-1:-1:-1;;3700:34:11;;;;;;;;;;;;;;;;3786:15;;3752:83;;3763:4;;;;3769:6;;;;3777:7;;-1:-1:-1;;;;;3786:15:11;;3803:9;;3814;;3825:3;;3830:4;;3700:34;3752:83;;:::i;:::-;;;;-1:-1:-1;;3752:83:11;;;;;;;;;;3666:183;;;3752:83;3666:183;;:::i;:::-;;;;;;;;;;;;;3643:216;;;;;;3624:235;;3947:4;3940:12;;3962:4;3969:24;3975:7;3984:8;3969:5;:24::i;:::-;3923:81;;-1:-1:-1;;;;;;6078:26:20;;;;3923:81:11;;;6066:39:20;6142:2;6138:15;;;;-1:-1:-1;;6134:53:20;6121:11;;;6114:74;6204:12;;;6197:28;6241:12;;;6234:28;;;6278:12;;3923:81:11;;;-1:-1:-1;;3923:81:11;;;;;;;;;3913:92;;3923:81;3913:92;;;;;3444:580;-1:-1:-1;;;;;;;;3444:580:11:o;5035:239::-;5139:12;;:36;;5095:21;;5078:14;;-1:-1:-1;;;;;5139:12:11;;;;5095:21;;5078:14;5139:36;5078:14;5139:36;5095:21;5139:12;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5126:49;;;5190:2;5185:32;;5201:16;;-1:-1:-1;;;5201:16:11;;;;;;;;;;;5185:32;5246:12;;5232:35;;;-1:-1:-1;;;;;5246:12:11;;;6685:51:20;;6767:2;6752:18;;6745:34;;;5232:35:11;;6658:18:20;5232:35:11;;;;;;;5068:206;;5035:239::o;1280:26::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1280:26:11;;-1:-1:-1;1280:26:11;:::o;4856:102::-;1531:13:0;:11;:13::i;:::-;4933:18:11::1;;-1:-1:-1::0;;;4933:18:11::1;;;;;;;;;;;2244:229:1::0;1311:13;;735:10:6;;-1:-1:-1;;;;;1311:13:1;2339:24;;2335:96;;2386:34;;-1:-1:-1;;;2386:34:1;;-1:-1:-1;;;;;2048:32:20;;2386:34:1;;;2030:51:20;2003:18;;2386:34:1;;;;;;;;2335:96;2440:26;2459:6;2440:18;:26::i;:::-;2286:187;2244:229::o;4535:224:11:-;1531:13:0;:11;:13::i;:::-;4615:9:11::1;-1:-1:-1::0;;;;;4615:21:11::1;;4640:1;4615:26:::0;4611:56:::1;;4650:17;;-1:-1:-1::0;;;4650:17:11::1;;;;;;;;;;;4611:56;4677:15;:27:::0;;-1:-1:-1;;;;;;4677:27:11::1;-1:-1:-1::0;;;;;4677:27:11;::::1;::::0;;::::1;::::0;;;4719:33:::1;::::0;2030:51:20;;;4719:33:11::1;::::0;2018:2:20;2003:18;4719:33:11::1;;;;;;;;4535:224:::0;:::o;4243:::-;1531:13:0;:11;:13::i;:::-;-1:-1:-1;;;;;4324:27:11;::::1;4320:53;;4360:13;;-1:-1:-1::0;;;4360:13:11::1;;;;;;;;;;;4320:53;4383:12;:28:::0;;-1:-1:-1;;;;;;4383:28:11::1;-1:-1:-1::0;;;;;4383:28:11;::::1;::::0;;::::1;::::0;;;4426:34:::1;::::0;2030:51:20;;;4426:34:11::1;::::0;2018:2:20;2003:18;4426:34:11::1;1884:203:20::0;1649:178:1;1531:13:0;:11;:13::i;:::-;1738::1::1;:24:::0;;-1:-1:-1;;;;;1738:24:1;::::1;-1:-1:-1::0;;;;;;1738:24:1;;::::1;::::0;::::1;::::0;;;1802:7:::1;1684::0::0;1710:6;-1:-1:-1;;;;;1710:6:0;;1638:85;1802:7:1::1;-1:-1:-1::0;;;;;1777:43:1::1;;;;;;;;;;;1649:178:::0;:::o;5280:145:11:-;5388:29;;;-1:-1:-1;;;;;6703:32:20;;5388:29:11;;;6685:51:20;6752:18;;;6745:34;;;5352:7:11;;6658:18:20;;5388:29:11;;;;;;;;;;;;5378:40;;;;;;5371:47;;5280:145;;;;:::o;1796:162:0:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:0;735:10:6;1855:23:0;1851:101;;1901:40;;-1:-1:-1;;;1901:40:0;;735:10:6;1901:40:0;;;2030:51:20;2003:18;;1901:40:0;1884:203:20;1851:101:0;1796:162::o;2011:153:1:-;2100:13;2093:20;;-1:-1:-1;;;;;;2093:20:1;;;2123:34;2148:8;2985:16:0;3004:6;;-1:-1:-1;;;;;3020:17:0;;;-1:-1:-1;;;;;;3020:17:0;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;-1:-1:-1:-;;;;;;;;:::o;14:173:20:-;82:20;;-1:-1:-1;;;;;131:31:20;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;:::-;333:39;192:186;-1:-1:-1;;;192:186:20:o;575:348::-;627:8;637:6;691:3;684:4;676:6;672:17;668:27;658:55;;709:1;706;699:12;658:55;-1:-1:-1;732:20:20;;775:18;764:30;;761:50;;;807:1;804;797:12;761:50;844:4;836:6;832:17;820:29;;896:3;889:4;880:6;872;868:19;864:30;861:39;858:59;;;913:1;910;903:12;858:59;575:348;;;;;:::o;928:951::-;1038:6;1046;1054;1062;1070;1078;1131:3;1119:9;1110:7;1106:23;1102:33;1099:53;;;1148:1;1145;1138:12;1099:53;1188:9;1175:23;1221:18;1213:6;1210:30;1207:50;;;1253:1;1250;1243:12;1207:50;1292:59;1343:7;1334:6;1323:9;1319:22;1292:59;:::i;:::-;1370:8;;-1:-1:-1;1266:85:20;-1:-1:-1;;1458:2:20;1443:18;;1430:32;1487:18;1474:32;;1471:52;;;1519:1;1516;1509:12;1471:52;1558:61;1611:7;1600:8;1589:9;1585:24;1558:61;:::i;:::-;928:951;;;;-1:-1:-1;1638:8:20;1742:2;1727:18;;1714:32;;1843:2;1828:18;;;1815:32;;-1:-1:-1;928:951:20;-1:-1:-1;;;;928:951:20:o;2092:905::-;2202:6;2210;2218;2226;2234;2242;2295:3;2283:9;2274:7;2270:23;2266:33;2263:53;;;2312:1;2309;2302:12;2263:53;2335:29;2354:9;2335:29;:::i;:::-;2325:39;;2415:2;2404:9;2400:18;2387:32;2442:18;2434:6;2431:30;2428:50;;;2474:1;2471;2464:12;2428:50;2513:59;2564:7;2555:6;2544:9;2540:22;2513:59;:::i;:::-;2591:8;;-1:-1:-1;2487:85:20;-1:-1:-1;;2679:2:20;2664:18;;2651:32;2708:18;2695:32;;2692:52;;;2740:1;2737;2730:12;2692:52;2779:61;2832:7;2821:8;2810:9;2806:24;2779:61;:::i;:::-;2092:905;;;;-1:-1:-1;2092:905:20;;;;;2963:2;2948:18;;;2935:32;;2092:905;-1:-1:-1;;;;2092:905:20:o;3184:180::-;3243:6;3296:2;3284:9;3275:7;3271:23;3267:32;3264:52;;;3312:1;3309;3302:12;3264:52;-1:-1:-1;3335:23:20;;3184:180;-1:-1:-1;3184:180:20:o;3369:267::-;3458:6;3453:3;3446:19;3510:6;3503:5;3496:4;3491:3;3487:14;3474:43;-1:-1:-1;3562:1:20;3537:16;;;3555:4;3533:27;;;3526:38;;;;3618:2;3597:15;;;-1:-1:-1;;3593:29:20;3584:39;;;3580:50;;3369:267::o;3641:1025::-;4026:3;4015:9;4008:22;3989:4;4053:63;4111:3;4100:9;4096:19;4088:6;4080;4053:63;:::i;:::-;4164:9;4156:6;4152:22;4147:2;4136:9;4132:18;4125:50;4192;4235:6;4227;4219;4192:50;:::i;:::-;-1:-1:-1;;;;;4278:32:20;;;4273:2;4258:18;;4251:60;4347:32;;;4342:2;4327:18;;4320:60;-1:-1:-1;;4417:32:20;;;4411:3;4396:19;;4389:61;4487:32;;;4298:3;4466:19;;4459:61;4557:32;;4551:3;4536:19;;4529:61;4627:32;;;4621:3;4606:19;;;4599:61;;;;4184:58;3641:1025;-1:-1:-1;;;;3641:1025:20:o;4671:508::-;4916:2;4905:9;4898:21;4879:4;4942:62;5000:2;4989:9;4985:18;4977:6;4969;4942:62;:::i;:::-;5052:9;5044:6;5040:22;5035:2;5024:9;5020:18;5013:50;5080;5123:6;5115;5107;5080:50;:::i;:::-;5072:58;;;5166:6;5161:2;5150:9;5146:18;5139:34;4671:508;;;;;;;;:::o;5184:184::-;5254:6;5307:2;5295:9;5286:7;5282:23;5278:32;5275:52;;;5323:1;5320;5313:12;5275:52;-1:-1:-1;5346:16:20;;5184:184;-1:-1:-1;5184:184:20:o;5373:211::-;5414:3;5452:5;5446:12;5496:6;5489:4;5482:5;5478:16;5473:3;5467:36;5558:1;5522:16;;5547:13;;;-1:-1:-1;5522:16:20;;5373:211;-1:-1:-1;5373:211:20:o;5589:261::-;5764:3;5789:55;5814:29;5839:3;5831:6;5814:29;:::i;:::-;5806:6;5789:55;:::i;:::-;5782:62;5589:261;-1:-1:-1;;;;5589:261:20:o","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa26469706673582212203f3257855e96725c5f82166ce21a590dfcc5b4bebf5f10a7c4713a80d6b53c3f64736f6c634300081c0033","offset":21210},"2":{"value":"0xa2646970667358221220401939af5312071d413f49430baf389e94c154f401353af6e89995415dbba35d64736f6c634300081c0033","offset":21157}},"immutableReferences":{"4571":[{"start":840,"length":32},{"start":1121,"length":32},{"start":1672,"length":32}],"4573":[{"start":608,"length":32},{"start":1154,"length":32},{"start":1706,"length":32}],"4575":[{"start":659,"length":32},{"start":1187,"length":32},{"start":1740,"length":32}],"4577":[{"start":741,"length":32},{"start":1220,"length":32},{"start":1774,"length":32}]},"transformations":[{"id":"4573","type":"replace","offset":608,"reason":"immutable"},{"id":"4575","type":"replace","offset":659,"reason":"immutable"},{"id":"4577","type":"replace","offset":741,"reason":"immutable"},{"id":"4571","type":"replace","offset":840,"reason":"immutable"},{"id":"4571","type":"replace","offset":1121,"reason":"immutable"},{"id":"4573","type":"replace","offset":1154,"reason":"immutable"},{"id":"4575","type":"replace","offset":1187,"reason":"immutable"},{"id":"4577","type":"replace","offset":1220,"reason":"immutable"},{"id":"4571","type":"replace","offset":1672,"reason":"immutable"},{"id":"4573","type":"replace","offset":1706,"reason":"immutable"},{"id":"4575","type":"replace","offset":1740,"reason":"immutable"},{"id":"4577","type":"replace","offset":1774,"reason":"immutable"}],"transformationValues":{"immutables":{"4571":"0x000000000000000000000000ca143ce32fe78f1f7019d7d551a6402fc5350c73","4573":"0x0000000000000000000000000bfbcf9fa4f9c56b0f40a671ad40e0805a091865","4575":"0x00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f4364","4577":"0x000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c"}}},"deployment":{"transactionHash":"0xc6db1011da68ee39229944ccd0b06d86722b9dfc05af120cd6601a272defd1d2","blockNumber":"128989097","transactionIndex":"31","deployer":"0xed591b552a9ed3d99F2B43CDF7aE8AaD6814Ef59"},"sources":{"src/AgentPadFactoryV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Ownable, Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {AgentPadTokenV3} from \"./AgentPadTokenV3.sol\";\nimport {INonfungiblePositionManager} from \"./interfaces/IPancakeV3.sol\";\n\n/// @notice v2 factory: same as AgentPadFactory (v1) except tokens graduate into PancakeSwap V3\n///         (falling back to v1-style Pancake V2 graduation when the V3 pool is not clean).\ncontract AgentPadFactoryV2 is Ownable2Step {\n    error InvalidName();\n    error InvalidSymbol();\n    error ZeroAddress();\n    error TransferFailed();\n    error InvalidRegistry();\n    error InvalidV2Factory();\n    error InvalidV3Factory();\n    error InvalidNpm();\n    error InvalidWbnb();\n    error RenounceDisabled();\n\n    event TokenCreated(address indexed token, address indexed creator, string name, string symbol, bytes32 metaHash);\n    event FeeRecipientUpdated(address feeRecipient);\n    event AgentIdRegistryUpdated(address registry);\n    event FeesWithdrawn(address to, uint256 amount);\n\n    address public immutable v2Factory;\n    address public immutable v3Factory;\n    address public immutable npm;\n    address public immutable wbnb;\n\n    address public feeRecipient;\n    address public agentIdRegistry;\n    address[] public allTokens;\n    mapping(address => bool) public isToken;\n\n    constructor(\n        address owner_,\n        address feeRecipient_,\n        address registry_,\n        address v2Factory_,\n        address v3Factory_,\n        address npm_,\n        address wbnb_\n    ) Ownable(owner_) {\n        if (feeRecipient_ == address(0)) revert ZeroAddress();\n        if (registry_.code.length == 0) revert InvalidRegistry();\n        if (v2Factory_.code.length == 0) revert InvalidV2Factory();\n        if (v3Factory_.code.length == 0) revert InvalidV3Factory();\n        if (npm_.code.length == 0) revert InvalidNpm();\n        if (wbnb_.code.length == 0) revert InvalidWbnb();\n        // The NPM must be the one bound to this V3 factory and this WBNB (catches mixed-network config).\n        if (\n            INonfungiblePositionManager(npm_).factory() != v3Factory_\n                || INonfungiblePositionManager(npm_).WETH9() != wbnb_\n        ) revert InvalidNpm();\n        feeRecipient = feeRecipient_;\n        agentIdRegistry = registry_;\n        v2Factory = v2Factory_;\n        v3Factory = v3Factory_;\n        npm = npm_;\n        wbnb = wbnb_;\n    }\n\n    receive() external payable {}\n\n    /// @notice Factory generation; v1 (AgentPadFactory) has no version() and is treated as 1.\n    function version() external pure returns (uint256) {\n        return 2;\n    }\n\n    function createToken(string calldata name, string calldata symbol, bytes32 metaHash, bytes32 userSalt)\n        external\n        payable\n        returns (address token)\n    {\n        if (bytes(name).length == 0 || bytes(name).length > 64) revert InvalidName();\n        if (bytes(symbol).length == 0 || bytes(symbol).length > 16) revert InvalidSymbol();\n\n        token = address(\n            new AgentPadTokenV3{salt: _salt(msg.sender, userSalt)}(\n                name, symbol, msg.sender, agentIdRegistry, v2Factory, v3Factory, npm, wbnb\n            )\n        );\n        allTokens.push(token);\n        isToken[token] = true;\n        emit TokenCreated(token, msg.sender, name, symbol, metaHash);\n\n        if (msg.value > 0) AgentPadTokenV3(token).buyFor{value: msg.value}(msg.sender);\n    }\n\n    function predictTokenAddress(address creator, string calldata name, string calldata symbol, bytes32 userSalt)\n        external\n        view\n        returns (address)\n    {\n        bytes32 initHash = keccak256(\n            abi.encodePacked(\n                type(AgentPadTokenV3).creationCode,\n                abi.encode(name, symbol, creator, agentIdRegistry, v2Factory, v3Factory, npm, wbnb)\n            )\n        );\n        return address(\n            uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt(creator, userSalt), initHash))))\n        );\n    }\n\n    function tokensCount() external view returns (uint256) {\n        return allTokens.length;\n    }\n\n    /// @notice Also redirects graduated v2 tokens' outer-market fees (they read feeRecipient at collect time).\n    function setFeeRecipient(address feeRecipient_) external onlyOwner {\n        if (feeRecipient_ == address(0)) revert ZeroAddress();\n        feeRecipient = feeRecipient_;\n        emit FeeRecipientUpdated(feeRecipient_);\n    }\n\n    /// @notice Only affects tokens created after the change.\n    function setAgentIdRegistry(address registry_) external onlyOwner {\n        if (registry_.code.length == 0) revert InvalidRegistry();\n        agentIdRegistry = registry_;\n        emit AgentIdRegistryUpdated(registry_);\n    }\n\n    /// @notice Disabled: renouncing would freeze `feeRecipient` and the registry forever.\n    function renounceOwnership() public view override onlyOwner {\n        revert RenounceDisabled();\n    }\n\n    /// @notice Anyone may call; funds only ever go to `feeRecipient`.\n    function withdrawFees() external {\n        uint256 amount = address(this).balance;\n        (bool ok,) = feeRecipient.call{value: amount}(\"\");\n        if (!ok) revert TransferFailed();\n        emit FeesWithdrawn(feeRecipient, amount);\n    }\n\n    function _salt(address creator, bytes32 userSalt) private pure returns (bytes32) {\n        return keccak256(abi.encode(creator, userSalt));\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\n * old one. This can help prevent common mistakes, such as transfers of ownership to\n * incorrect accounts, or to contracts that are unable to interact with the\n * permission system.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     *\n     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"},"src/AgentPadTokenV3.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {CurveMath} from \"./CurveMath.sol\";\nimport {V3PathLib} from \"./V3PathLib.sol\";\nimport {IAgentIdRegistry} from \"./interfaces/IAgentIdRegistry.sol\";\nimport {IAgentPadFactory} from \"./interfaces/IAgentPadFactory.sol\";\nimport {IPancakeV2Factory, IPancakeV2Pair} from \"./interfaces/IPancakeV2.sol\";\nimport {IPancakeV3Factory, IPancakeV3Pool, INonfungiblePositionManager} from \"./interfaces/IPancakeV3.sol\";\nimport {IWBNB} from \"./interfaces/IWBNB.sol\";\n\n/// @notice v2 bonding-curve token. The inner market is a verbatim copy of AgentPadToken (v1); only\n///         graduation differs. Graduation is atomic (inside the filling buy, as in v1) and picks:\n///         - V3: if the PancakeSwap V3 (token, WBNB, 1%) pool is still clean (no liquidity in range,\n///           no initialized tick between its price and the curve-end price, and both full-range edge\n///           ticks keep EDGE_HEADROOM below maxLiquidityPerTick; dust positions on the edge ticks are\n///           harmless and do not count), move it to the curve-end price for free (zero-liquidity\n///           swap) and mint a full-range position this contract holds forever (no path to decrease\n///           liquidity, burn or move the NFT). Outer-market fees are collectable by anyone and only\n///           ever paid to the factory's feeRecipient.\n///         - V2: otherwise, exactly v1's graduation (Pancake V2 pair, LP burned to DEAD, no platform\n///           fees). Also the fallback if the NPM mint reverts for any reason. Nobody can force a V3\n///           graduation at a wrong price; the worst an attacker can do is push the token to V2 (by\n///           putting WBNB liquidity on the price path or in range, or saturating an edge tick up\n///           to the per-tick cap); a dust position on an edge tick no longer does.\n/// @dev Deliberately no receive()/fallback(): plain BNB transfers to the token revert.\ncontract AgentPadTokenV3 is ERC20, ReentrancyGuard {\n    error NotEligible();\n    error AlreadyGraduated();\n    error CapReached();\n    error AmountTooSmall();\n    error SlippageExceeded();\n    error RefundFailed();\n    error FeeTransferFailed();\n    error OnlyFactory();\n    /// @notice Pre-graduation transfers other than curve->holder / holder->curve.\n    error TransferLocked();\n    /// @notice sell amount exceeds the seller's token balance.\n    error InsufficientBalance();\n    /// @notice BNB payout to the seller failed (seller cannot receive BNB).\n    error PayoutFailed();\n    /// @notice graduate() called while already graduated or before sold == SOLD_CAP.\n    error NotGraduatable();\n    /// @notice collectFees() when the token did not graduate into V3 (not yet, or into V2).\n    error NotV3();\n    /// @notice pancakeV3SwapCallback from anyone but the pool, outside graduation's correction swap,\n    ///         or asking for any payment (the correction only runs through empty range).\n    error InvalidCallback();\n\n    /// @param bnbIn curve cost, excluding the fee\n    event Buy(address indexed buyer, uint256 bnbIn, uint256 fee, uint256 tokensOut, uint256 newSold);\n    /// @param bnbOut BNB paid to the seller, after the fee\n    event Sell(address indexed seller, uint256 tokensIn, uint256 bnbOut, uint256 fee, uint256 newSold);\n    /// @param venue the V3 pool (mode V3) or the V2 pair (mode V2)\n    /// @param positionId the locked V3 position (0 in mode V2)\n    /// @param tokens tokens seeded into the venue\n    /// @param bnb WBNB seeded into the venue\n    event Graduated(\n        address indexed token, address indexed venue, uint8 mode, uint256 positionId, uint256 tokens, uint256 bnb\n    );\n    /// @notice Outer-market fees collected from the locked V3 position and paid to `recipient`.\n    event FeesCollected(address indexed recipient, uint256 amountToken, uint256 amountWbnb);\n    /// @notice V3 mode leftovers: token rounding dust to DEAD, WBNB rounding dust (plus any BNB\n    ///         force-sent to the token, which cannot fit a position at a fixed price) to feeRecipient.\n    event DustSwept(address indexed feeRecipient, uint256 tokensToDead, uint256 wbnbToFeeRecipient);\n\n    /// @notice Receives V2 LP tokens (mode V2) and token dust (mode V3).\n    address public constant DEAD = 0x000000000000000000000000000000000000dEaD;\n\n    uint8 public constant MODE_NONE = 0;\n    uint8 public constant MODE_V3 = 1;\n    uint8 public constant MODE_V2 = 2;\n\n    uint24 internal constant FEE = 10000; // 1% tier, tick spacing 200\n    int24 internal constant TICK_LOWER = -887200; // full range for tick spacing 200\n    int24 internal constant TICK_UPPER = 887200;\n    /// @dev Graduation goes to V2 only if a full-range edge tick already holds more than\n    ///      maxLiquidityPerTick - EDGE_HEADROOM gross liquidity (our mint could then hit the per-tick\n    ///      cap). Our own full-range liquidity is ~5.7e22 (fixed seed amounts); the cap is ~3.8e34.\n    uint128 internal constant EDGE_HEADROOM = 1e30;\n\n    address public immutable factory;\n    address public immutable creator;\n    address public immutable agentIdRegistry;\n    address public immutable v2Factory;\n    address public immutable v3Factory;\n    address public immutable npm;\n    address public immutable wbnb;\n    bool public immutable token0IsSelf;\n    /// @notice The PancakeSwap V3 (token, WBNB, 1%) pool, created (and initialized at the curve-end\n    ///         price if nobody had) in the constructor.\n    address public immutable pool;\n\n    bool public graduated;\n    /// @notice MODE_NONE until graduation, then MODE_V3 or MODE_V2.\n    uint8 public graduationMode;\n    uint256 public sold;\n    mapping(address => uint256) public bought;\n    /// @notice NPM token id of the locked full-range position (mode V3 only).\n    uint256 public positionId;\n    /// @notice The Pancake V2 pair (mode V2 only).\n    address public pair;\n\n    /// @dev True only around the seller -> curve transfer inside _sell; the one pre-graduation path\n    ///      allowed to move tokens into the curve.\n    bool private transient _selling;\n    /// @dev True only around graduation's own zero-liquidity correction swap.\n    bool private transient _correcting;\n\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        address creator_,\n        address registry_,\n        address v2Factory_,\n        address v3Factory_,\n        address npm_,\n        address wbnb_\n    ) ERC20(name_, symbol_) {\n        factory = msg.sender;\n        creator = creator_;\n        agentIdRegistry = registry_;\n        v2Factory = v2Factory_;\n        v3Factory = v3Factory_;\n        npm = npm_;\n        wbnb = wbnb_;\n        bool t0 = address(this) < wbnb_;\n        token0IsSelf = t0;\n\n        // Someone may have front-run the pool for the predicted address (even initialized it at any\n        // price): reuse it; graduation decides whether it is still usable.\n        address p = IPancakeV3Factory(v3Factory_).getPool(address(this), wbnb_, FEE);\n        if (p == address(0)) p = IPancakeV3Factory(v3Factory_).createPool(address(this), wbnb_, FEE);\n        pool = p;\n        (uint160 sqrtP,,,,,,) = IPancakeV3Pool(p).slot0();\n        if (sqrtP == 0) IPancakeV3Pool(p).initialize(_target(t0));\n\n        _mint(address(this), CurveMath.TOTAL_SUPPLY);\n    }\n\n    // ------------------------------------------------------------------ buys\n\n    function buyWithBNB() external payable nonReentrant returns (uint256 tokensOut) {\n        _checkEligible(msg.sender);\n        return _buy(msg.sender, msg.value, 0);\n    }\n\n    function buyWithBNBMinOut(uint256 minTokens) external payable nonReentrant returns (uint256 tokensOut) {\n        _checkEligible(msg.sender);\n        return _buy(msg.sender, msg.value, minTokens);\n    }\n\n    /// @notice Dev buy at launch. Factory only; no ID gate (the buyer is the creator).\n    function buyFor(address buyer) external payable nonReentrant returns (uint256 tokensOut) {\n        if (msg.sender != factory) revert OnlyFactory();\n        if (graduated) revert AlreadyGraduated();\n        return _buy(buyer, msg.value, 0);\n    }\n\n    // ----------------------------------------------------------------- sells\n\n    function sell(uint256 amount) external nonReentrant returns (uint256 bnbOut) {\n        _checkEligible(msg.sender);\n        return _sell(msg.sender, amount, 0);\n    }\n\n    function sellWithMin(uint256 amount, uint256 minBnb) external nonReentrant returns (uint256 bnbOut) {\n        _checkEligible(msg.sender);\n        return _sell(msg.sender, amount, minBnb);\n    }\n\n    /// @notice Sells the caller's whole balance. Reverts AmountTooSmall on a zero balance.\n    function sellAll() external nonReentrant returns (uint256 bnbOut) {\n        _checkEligible(msg.sender);\n        return _sell(msg.sender, balanceOf(msg.sender), 0);\n    }\n\n    // ------------------------------------------------------------ graduation\n\n    /// @notice Fallback: anyone may graduate a full curve. Normally the filling buy graduates in\n    ///         the same transaction, so this only matters if that ever did not happen.\n    function graduate() external nonReentrant {\n        if (graduated || sold != CurveMath.SOLD_CAP) revert NotGraduatable();\n        _graduate(0);\n    }\n\n    /// @notice Anyone may call after a V3 graduation: pays the locked position's accrued outer-market\n    ///         fees (both tokens, as-is) to the factory's current feeRecipient. Never touches liquidity.\n    function collectFees() external nonReentrant returns (uint256 amountToken, uint256 amountWbnb) {\n        if (graduationMode != MODE_V3) revert NotV3();\n        address recipient = IAgentPadFactory(factory).feeRecipient();\n        // The position's liquidity is never decreased, so tokensOwed is only ever accrued fees.\n        (uint256 a0, uint256 a1) = INonfungiblePositionManager(npm).collect(\n            INonfungiblePositionManager.CollectParams({\n                tokenId: positionId,\n                recipient: recipient,\n                amount0Max: type(uint128).max,\n                amount1Max: type(uint128).max\n            })\n        );\n        (amountToken, amountWbnb) = token0IsSelf ? (a0, a1) : (a1, a0);\n        emit FeesCollected(recipient, amountToken, amountWbnb);\n    }\n\n    /// @notice Graduation's correction swap runs only through empty range, so the pool never asks for\n    ///         a payment. Anything else (other caller, outside that swap, any non-zero delta) reverts.\n    function pancakeV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata) external view {\n        if (!_correcting || msg.sender != pool || amount0Delta != 0 || amount1Delta != 0) revert InvalidCallback();\n    }\n\n    // ------------------------------------------------------------------ views\n\n    /// @notice Curve-end price CurveMath.spotPrice(SOLD_CAP) as a V3 sqrtPriceX96 for this token's\n    ///         ordering: sqrt(token1 per token0, raw units) * 2^96.\n    function targetSqrtPriceX96() public view returns (uint160) {\n        return _target(token0IsSelf);\n    }\n\n    function canTrade(address a) public view returns (bool) {\n        return !graduated && (a == creator || IAgentIdRegistry(agentIdRegistry).balanceOf(a) > 0);\n    }\n\n    /// @notice Tokens `a` may still buy on the curve (cumulative, never reset by selling).\n    function remainingCap(address a) external view returns (uint256) {\n        return CurveMath.MAX_BUY_PER_WALLET - bought[a];\n    }\n\n    /// @notice Exact result of `buyer` calling buyWithBNB{value: grossBnb}(), using buyer's remaining cap.\n    ///         Returns zeros and refund == grossBnb when nothing would fill (including after graduation).\n    function quoteBuyFor(address buyer, uint256 grossBnb)\n        public\n        view\n        returns (uint256 tokensOut, uint256 cost, uint256 fee, uint256 refund)\n    {\n        if (graduated) return (0, 0, 0, grossBnb);\n        (tokensOut, cost, fee) = _quote(buyer, grossBnb);\n        refund = grossBnb - cost - fee;\n    }\n\n    /// @notice quoteBuyFor(msg.sender, grossBnb).\n    function quoteBuy(uint256 grossBnb)\n        external\n        view\n        returns (uint256 tokensOut, uint256 cost, uint256 fee, uint256 refund)\n    {\n        return quoteBuyFor(msg.sender, grossBnb);\n    }\n\n    /// @notice Exact result of a successful sell(amount) now: BNB to the seller (after fee) and the fee.\n    ///         Returns (0, 0) whenever sell(amount) would revert for amount reasons or after graduation:\n    ///         amount == 0, amount > sold, or the sale is worth 0 BNB after the fee. Does not check any\n    ///         particular seller's balance or eligibility.\n    function quoteSell(uint256 amount) external view returns (uint256 bnbOut, uint256 fee) {\n        if (graduated) return (0, 0);\n        return _quoteSell(amount);\n    }\n\n    function spotPrice() external view returns (uint256) {\n        return CurveMath.spotPrice(sold);\n    }\n\n    /// @notice Curve progress in basis points (10000 = graduated).\n    function progress() external view returns (uint256) {\n        return sold * 10000 / CurveMath.SOLD_CAP;\n    }\n\n    function reserve() external view returns (uint256) {\n        return CurveMath.reserveAt(sold);\n    }\n\n    // --------------------------------------------------------------- internal\n\n    function _checkEligible(address a) private view {\n        if (graduated) revert AlreadyGraduated();\n        if (!canTrade(a)) revert NotEligible();\n    }\n\n    /// @dev out = min(curve-affordable, curve remainder, personal remainder); cost + fee <= gross always.\n    function _quote(address buyer, uint256 gross) private view returns (uint256 out, uint256 cost, uint256 fee) {\n        uint256 s = sold;\n        uint256 net = gross * CurveMath.BPS / (CurveMath.BPS + CurveMath.FEE_BPS);\n        out = CurveMath.maxTokensFor(s, net);\n        uint256 curveLeft = CurveMath.SOLD_CAP - s;\n        if (out > curveLeft) out = curveLeft;\n        uint256 walletLeft = CurveMath.MAX_BUY_PER_WALLET - bought[buyer];\n        if (out > walletLeft) out = walletLeft;\n        if (out == 0) return (0, 0, 0);\n        cost = CurveMath.costOf(s, out);\n        fee = CurveMath.feeOf(cost);\n    }\n\n    function _buy(address buyer, uint256 gross, uint256 minOut) private returns (uint256 out) {\n        uint256 cost;\n        uint256 fee;\n        (out, cost, fee) = _quote(buyer, gross);\n        if (out == 0) {\n            if (bought[buyer] >= CurveMath.MAX_BUY_PER_WALLET) revert CapReached();\n            revert AmountTooSmall();\n        }\n        if (out < minOut) revert SlippageExceeded();\n\n        // Effects\n        uint256 newSold = sold + out;\n        sold = newSold;\n        bought[buyer] += out;\n        _transfer(address(this), buyer, out);\n        emit Buy(buyer, cost, fee, out, newSold);\n        uint256 refund = gross - cost - fee;\n\n        // Graduate before the fee push and refund, so no untrusted callback ever observes\n        // sold == SOLD_CAP && !graduated. _graduate only calls WBNB, the factory, the Pancake V2/V3\n        // factories, pair, pool and the NPM (none calls back into untrusted code). fee + refund are\n        // still in this contract's balance at this point and are excluded from the LP seed.\n        if (newSold == CurveMath.SOLD_CAP) _graduate(fee + refund);\n\n        // Interactions\n        if (fee > 0) {\n            (bool okFee,) = factory.call{value: fee}(\"\");\n            if (!okFee) revert FeeTransferFailed();\n        }\n        if (refund > 0) {\n            (bool okRefund,) = buyer.call{value: refund}(\"\");\n            if (!okRefund) revert RefundFailed();\n        }\n    }\n\n    /// @dev (0, 0) for amount == 0, amount > sold (proceeds would exceed the reserve), or a net-zero sale.\n    function _quoteSell(uint256 amount) private view returns (uint256 bnbOut, uint256 fee) {\n        uint256 s = sold;\n        if (amount == 0 || amount > s) return (0, 0);\n        uint256 proceeds = CurveMath.proceedsOf(s, amount);\n        fee = CurveMath.feeOf(proceeds);\n        if (proceeds <= fee) return (0, 0);\n        bnbOut = proceeds - fee;\n    }\n\n    function _sell(address seller, uint256 amount, uint256 minBnb) private returns (uint256 bnbOut) {\n        if (amount == 0) revert AmountTooSmall();\n        // Pre-graduation, holder balances sum to `sold`, so this also guarantees amount <= sold.\n        if (amount > balanceOf(seller)) revert InsufficientBalance();\n        uint256 fee;\n        (bnbOut, fee) = _quoteSell(amount);\n        if (bnbOut == 0) revert AmountTooSmall();\n        if (bnbOut < minBnb) revert SlippageExceeded();\n\n        // Effects\n        uint256 newSold = sold - amount;\n        sold = newSold;\n        _selling = true;\n        _transfer(seller, address(this), amount);\n        _selling = false;\n        emit Sell(seller, amount, bnbOut, fee, newSold);\n\n        // Interactions\n        (bool okFee,) = factory.call{value: fee}(\"\");\n        if (!okFee) revert FeeTransferFailed();\n        (bool okOut,) = seller.call{value: bnbOut}(\"\");\n        if (!okOut) revert PayoutFailed();\n    }\n\n    /// @dev Inner market: only curve -> holder (mint/buy) and holder -> curve inside _sell move tokens.\n    ///      A plain transfer to the curve is locked too, so pre-graduation\n    ///      balanceOf(this) == TOTAL_SUPPLY - sold always, and nobody can hold or deposit tokens in the\n    ///      V3 pool or V2 pair before graduation (any pre-existing liquidity there is WBNB-only).\n    ///      After graduation the token is a plain ERC20.\n    function _update(address from, address to, uint256 value) internal override {\n        if (!graduated && from != address(0) && from != address(this) && !(_selling && to == address(this))) {\n            revert TransferLocked();\n        }\n        super._update(from, to, value);\n    }\n\n    // ------------------------------------------------------------ graduation internals\n\n    /// @dev Any V3 obstacle (dirty pool, failed correction swap, failed NPM mint) falls back to v1's\n    ///      V2 graduation inside the same call; a V3 problem can never block graduation.\n    /// @param pendingOut BNB still owed out of this balance by the calling buy (fee + refund).\n    function _graduate(uint256 pendingOut) private {\n        graduated = true; // first: closes the inner market and unlocks transfers before any call out\n\n        // Curve reserve (+ any force-sent BNB) as WBNB.\n        IWBNB(wbnb).deposit{value: address(this).balance - pendingOut}();\n\n        if (!(_poolAtTarget() && _graduateV3())) _graduateV2();\n    }\n\n    /// @dev True once the V3 pool sits exactly at the target price, moving it there first if that is\n    ///      free: only when the pool has no in-range liquidity, our full-range edge ticks have headroom\n    ///      for our mint, and no initialized tick lies on the path, so the swap has no counterparty and\n    ///      both deltas are zero (the callback enforces it).\n    ///      Before graduation nobody can hold the token in the pool, so any foreign liquidity is\n    ///      WBNB-only; any such liquidity on the path or in range sends the token to V2 instead.\n    ///      Foreign liquidity on an edge tick is harmless unless it is within EDGE_HEADROOM of\n    ///      maxLiquidityPerTick (our mint would revert), so a dust position there cannot force V2.\n    ///      Returns false rather than reverting on every pool-side failure.\n    function _poolAtTarget() private returns (bool) {\n        address p = pool;\n        uint160 target = _target(token0IsSelf);\n        if (IPancakeV3Pool(p).liquidity() != 0) return false;\n        uint128 maxGross = IPancakeV3Pool(p).maxLiquidityPerTick();\n        if (maxGross < EDGE_HEADROOM) return false;\n        uint128 limit = maxGross - EDGE_HEADROOM;\n        if (IPancakeV3Pool(p).ticks(TICK_LOWER) > limit || IPancakeV3Pool(p).ticks(TICK_UPPER) > limit) return false;\n        (uint160 sqrtP, int24 tick,,,,,) = IPancakeV3Pool(p).slot0();\n        if (sqrtP == target) return true;\n        int24 targetTick = token0IsSelf ? V3PathLib.TARGET_TICK_TOKEN0 : V3PathLib.TARGET_TICK_TOKEN1;\n        if (V3PathLib.pathHasInitializedTick(p, tick, targetTick)) return false;\n\n        bool zeroForOne = sqrtP > target;\n        _correcting = true;\n        // 1 wei exact input: with zero liquidity nothing is consumed and the price limit stops it.\n        try IPancakeV3Pool(p).swap(address(this), zeroForOne, 1, target, \"\") {}\n        catch {\n            _correcting = false;\n            return false;\n        }\n        _correcting = false;\n        (sqrtP,,,,,,) = IPancakeV3Pool(p).slot0();\n        return sqrtP == target;\n    }\n\n    /// @dev Full-range position at exactly the target price, NFT kept by this contract forever.\n    ///      Returns false (nothing changed: approvals reset, all tokens and WBNB still here) if the NPM\n    ///      mint reverts for any reason, so the caller falls back to V2.\n    function _graduateV3() private returns (bool) {\n        uint256 tokens = balanceOf(address(this)); // TOTAL_SUPPLY - SOLD_CAP\n        uint256 bnb = IERC20(wbnb).balanceOf(address(this));\n        bool t0 = token0IsSelf;\n        _approve(address(this), npm, tokens);\n        IERC20(wbnb).approve(npm, bnb);\n        // At the target price the curve reserve matches 200M tokens exactly, so tokens are the binding\n        // side (any force-sent BNB only adds WBNB); the min only tolerates rounding.\n        uint256 minTokens = tokens - tokens / 1000;\n        try INonfungiblePositionManager(npm).mint(\n            INonfungiblePositionManager.MintParams({\n                token0: t0 ? address(this) : wbnb,\n                token1: t0 ? wbnb : address(this),\n                fee: FEE,\n                tickLower: TICK_LOWER,\n                tickUpper: TICK_UPPER,\n                amount0Desired: t0 ? tokens : bnb,\n                amount1Desired: t0 ? bnb : tokens,\n                amount0Min: t0 ? minTokens : 0,\n                amount1Min: t0 ? 0 : minTokens,\n                recipient: address(this),\n                deadline: block.timestamp\n            })\n        ) returns (uint256 id, uint128, uint256 a0, uint256 a1) {\n            _finishV3(id, a0, a1);\n            return true;\n        } catch {\n            _approve(address(this), npm, 0);\n            IERC20(wbnb).approve(npm, 0);\n            return false;\n        }\n    }\n\n    /// @dev Records the V3 graduation and sweeps leftovers (actual balances, so nothing stays behind;\n    ///      allowances cleared): token rounding dust to DEAD; WBNB rounding dust (~2e8 wei, < 1e12) to\n    ///      feeRecipient. BNB force-sent to the token before graduation cannot fit a full-range\n    ///      position at the fixed target price, so in V3 mode it also goes to feeRecipient (in V2 mode\n    ///      it joins the pair, as in v1). Only the donor loses; nothing trades against anyone here.\n    function _finishV3(uint256 id, uint256 a0, uint256 a1) private {\n        positionId = id;\n        graduationMode = MODE_V3;\n        (uint256 usedTokens, uint256 usedBnb) = token0IsSelf ? (a0, a1) : (a1, a0);\n        emit Graduated(address(this), pool, MODE_V3, id, usedTokens, usedBnb);\n\n        _approve(address(this), npm, 0);\n        IERC20(wbnb).approve(npm, 0);\n        uint256 dustTokens = balanceOf(address(this));\n        uint256 dustBnb = IERC20(wbnb).balanceOf(address(this));\n        address recipient = IAgentPadFactory(factory).feeRecipient();\n        if (dustTokens > 0) _transfer(address(this), DEAD, dustTokens);\n        // Canonical WBNB reverts on failure; its return value is always true. A WBNB transfer never\n        // calls the recipient, so feeRecipient cannot block graduation.\n        if (dustBnb > 0) IERC20(wbnb).transfer(recipient, dustBnb);\n        emit DustSwept(recipient, dustTokens, dustBnb);\n    }\n\n    /// @dev v1's graduation (AgentPadToken._graduate after the wrap), verbatim apart from creating the\n    ///      pair here instead of in the constructor: seeds the Pancake V2 pair directly and burns the LP.\n    ///      Poison-proof: pair.mint only uses balance - reserve, so donated or sync'd WBNB just joins\n    ///      the pool. The pair's LP totalSupply is 0 here: a first mint needs both sides, and the pair\n    ///      can never hold this token before graduation (transfers to it are locked), so nobody can\n    ///      mint first and pick the price.\n    function _graduateV2() private {\n        address p = IPancakeV2Factory(v2Factory).getPair(address(this), wbnb);\n        if (p == address(0)) p = IPancakeV2Factory(v2Factory).createPair(address(this), wbnb);\n        pair = p;\n        graduationMode = MODE_V2;\n\n        uint256 bnb = IERC20(wbnb).balanceOf(address(this)); // curve reserve (+ any force-sent BNB)\n        uint256 tokens = balanceOf(address(this)); // == TOTAL_SUPPLY - SOLD_CAP\n\n        _transfer(address(this), p, tokens);\n        // Canonical WBNB reverts on failure; its return value is always true.\n        IWBNB(wbnb).transfer(p, bnb);\n        IPancakeV2Pair(p).mint(DEAD);\n\n        emit Graduated(address(this), p, MODE_V2, 0, tokens, bnb);\n    }\n\n    /// @dev Curve-end price CurveMath.spotPrice(SOLD_CAP) as a V3 sqrtPriceX96: sqrt(token1 per\n    ///      token0, raw units) * 2^96. spotPrice is wei per 1e18 tokens (~8e10), so either ratio\n    ///      * 2^192 fits in 256 bits (~5e68 / ~8e64) and mulDiv keeps full precision before the sqrt.\n    function _target(bool t0) private pure returns (uint160) {\n        uint256 p = CurveMath.spotPrice(CurveMath.SOLD_CAP);\n        return uint160(t0 ? Math.sqrt(Math.mulDiv(p, 1 << 192, 1e18)) : Math.sqrt(Math.mulDiv(1e18, 1 << 192, p)));\n    }\n}\n"},"src/interfaces/IPancakeV3.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @dev Minimal PancakeSwap V3 surface used by AgentPadTokenV3 / AgentPadFactoryV2.\n///      Checked against the verified mainnet contracts (BSC 56).\ninterface IPancakeV3Factory {\n    function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool);\n    function createPool(address tokenA, address tokenB, uint24 fee) external returns (address pool);\n}\n\ninterface IPancakeV3Pool {\n    /// @dev Pancake's slot0: feeProtocol is uint32 (Uniswap's is uint8).\n    function slot0()\n        external\n        view\n        returns (\n            uint160 sqrtPriceX96,\n            int24 tick,\n            uint16 observationIndex,\n            uint16 observationCardinality,\n            uint16 observationCardinalityNext,\n            uint32 feeProtocol,\n            bool unlocked\n        );\n    /// @dev In-range liquidity at the current tick.\n    function liquidity() external view returns (uint128);\n    function maxLiquidityPerTick() external view returns (uint128);\n    /// @dev Only the first return value (liquidityGross) is declared; the ABI decoder ignores the rest.\n    function ticks(int24 tick) external view returns (uint128 liquidityGross);\n    function initialize(uint160 sqrtPriceX96) external;\n    function swap(\n        address recipient,\n        bool zeroForOne,\n        int256 amountSpecified,\n        uint160 sqrtPriceLimitX96,\n        bytes calldata data\n    ) external returns (int256 amount0, int256 amount1);\n}\n\ninterface INonfungiblePositionManager {\n    struct MintParams {\n        address token0;\n        address token1;\n        uint24 fee;\n        int24 tickLower;\n        int24 tickUpper;\n        uint256 amount0Desired;\n        uint256 amount1Desired;\n        uint256 amount0Min;\n        uint256 amount1Min;\n        address recipient;\n        uint256 deadline;\n    }\n\n    struct CollectParams {\n        uint256 tokenId;\n        address recipient;\n        uint128 amount0Max;\n        uint128 amount1Max;\n    }\n\n    function factory() external view returns (address);\n    function WETH9() external view returns (address);\n    function mint(MintParams calldata params)\n        external\n        payable\n        returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);\n    function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1);\n}\n"},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Skips emitting an {Approval} event indicating an allowance update. This is not\n     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n     * true using the following override:\n     *\n     * ```solidity\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,\n * consider using {ReentrancyGuardTransient} instead.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    uint256 private _status;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if (_status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        _status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == ENTERED;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with an success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n            // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2²⁵⁶ + prod0.\n            uint256 prod0 = x * y; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n        for (uint256 i = 0; i < byteArray.length; ++i) {\n            if (byteArray[i] != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        uint256 exp;\n        unchecked {\n            exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);\n            value >>= exp;\n            result += exp;\n\n            result += SafeCast.toUint(value > 1);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        uint256 isGt;\n        unchecked {\n            isGt = SafeCast.toUint(value > (1 << 128) - 1);\n            value >>= isGt * 128;\n            result += isGt * 16;\n\n            isGt = SafeCast.toUint(value > (1 << 64) - 1);\n            value >>= isGt * 64;\n            result += isGt * 8;\n\n            isGt = SafeCast.toUint(value > (1 << 32) - 1);\n            value >>= isGt * 32;\n            result += isGt * 4;\n\n            isGt = SafeCast.toUint(value > (1 << 16) - 1);\n            value >>= isGt * 16;\n            result += isGt * 2;\n\n            result += SafeCast.toUint(value > (1 << 8) - 1);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n"},"src/CurveMath.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @notice Virtual-reserve constant-product bonding curve: (reserveBnb + R) * (depth) = K,\n///         where depth = TOTAL_SUPPLY + H - sold. All amounts are in wei / 1e18-scaled tokens.\nlibrary CurveMath {\n    uint256 internal constant TOTAL_SUPPLY = 1_000_000_000e18;\n    uint256 internal constant SOLD_CAP = 800_000_000e18;\n    uint256 internal constant H = 66_666_666_666_666_666_666_666_667;\n    uint256 internal constant R = 5_333_333_333_333_333_333;\n    uint256 internal constant K = R * (TOTAL_SUPPLY + H);\n    uint256 internal constant MAX_BUY_PER_WALLET = 30_000_000e18;\n    uint256 internal constant FEE_BPS = 100;\n    uint256 internal constant BPS = 10_000;\n\n    /// @dev Virtual token depth remaining on the curve.\n    function depth(uint256 sold) internal pure returns (uint256) {\n        return TOTAL_SUPPLY + H - sold;\n    }\n\n    /// @dev Real BNB reserve held by the curve once `sold` tokens have been sold.\n    function reserveAt(uint256 sold) internal pure returns (uint256) {\n        return K / depth(sold) - R;\n    }\n\n    /// @dev Largest token amount purchasable with `netBnb` (after fee) at `sold`; rounds so cost <= netBnb.\n    function maxTokensFor(uint256 sold, uint256 netBnb) internal pure returns (uint256) {\n        uint256 d = depth(sold);\n        uint256 x = K / d;\n        uint256 y = K / (x + netBnb);\n        if (d <= y + 1) return 0;\n        return d - y - 1;\n    }\n\n    /// @dev BNB cost (before fee) of buying `amount` tokens at `sold`.\n    function costOf(uint256 sold, uint256 amount) internal pure returns (uint256) {\n        uint256 d = depth(sold);\n        return K / (d - amount) - K / d;\n    }\n\n    /// @dev BNB proceeds (before fee) of selling `amount` tokens back at `sold`.\n    function proceedsOf(uint256 sold, uint256 amount) internal pure returns (uint256) {\n        uint256 d = depth(sold);\n        return K / d - K / (d + amount);\n    }\n\n    /// @dev Spot price in wei per 1e18 tokens.\n    function spotPrice(uint256 sold) internal pure returns (uint256) {\n        uint256 d = depth(sold);\n        return K * 1e18 / (d * d);\n    }\n\n    /// @dev 1% fee, rounded up.\n    function feeOf(uint256 amount) internal pure returns (uint256) {\n        return (amount * FEE_BPS + BPS - 1) / BPS;\n    }\n}\n"},"src/V3PathLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IPancakeV3TickBitmap {\n    function tickBitmap(int16 wordPosition) external view returns (uint256);\n}\n\n/// @notice Decides whether a V3 swap from the current tick to the target tick could cross an\n///         initialized tick, by reading the pool's tick bitmap. Used by AgentPadTokenV3 so its price\n///         correction only ever runs through empty range (zero liquidity, zero token deltas).\n/// @dev Tick bitmap layout (Uniswap/Pancake V3): a tick t (a multiple of the spacing) is flagged at\n///      compressed = floor(t / spacing), word = compressed >> 8, bit = compressed & 0xff.\nlibrary V3PathLib {\n    int24 internal constant TICK_SPACING = 200;\n    /// @dev slot0.tick of a pool sitting at AgentPadTokenV3's target price, per ordering:\n    ///      floor(log_1.0001(spotPrice(SOLD_CAP) / 1e18)) = floor(-163420.5625...) when the token is\n    ///      token0, floor(+163420.5625...) when it is token1 (verified on fork in V3PathLib.t.sol).\n    int24 internal constant TARGET_TICK_TOKEN0 = -163421;\n    int24 internal constant TARGET_TICK_TOKEN1 = 163420;\n\n    /// @dev floor(tick / TICK_SPACING) (Solidity division truncates toward zero).\n    function compress(int24 tick) internal pure returns (int24 c) {\n        c = tick / TICK_SPACING;\n        if (tick < 0 && tick % TICK_SPACING != 0) c--;\n    }\n\n    /// @notice Could a swap from `currentTick` toward `targetTick` cross an initialized tick?\n    ///         Conservative (it may answer true for a tick that would not quite be reached):\n    ///         - price down (target below): a swap crosses every initialized tick k with\n    ///           target < price(k) <= current price, including the current tick's own lower boundary\n    ///           (nextInitializedTickWithinOneWord with lte = true starts at the current tick).\n    ///           Checked: compressed ticks [compress(targetTick), compress(currentTick)].\n    ///         - price up (target above): crosses initialized ticks strictly above the current tick\n    ///           up to the target. Checked: [compress(currentTick) + 1, compress(targetTick) + 1].\n    function pathHasInitializedTick(address pool, int24 currentTick, int24 targetTick) internal view returns (bool) {\n        if (targetTick <= currentTick) return anyInitialized(pool, compress(targetTick), compress(currentTick));\n        return anyInitialized(pool, compress(currentTick) + 1, compress(targetTick) + 1);\n    }\n\n    /// @notice True if any compressed tick in [cLo, cHi] (inclusive) is flagged in the pool's bitmap.\n    function anyInitialized(address pool, int24 cLo, int24 cHi) internal view returns (bool) {\n        if (cLo > cHi) return false;\n        int256 wLo = int256(cLo) >> 8;\n        int256 wHi = int256(cHi) >> 8;\n        for (int256 w = wLo; w <= wHi; w++) {\n            uint256 word = IPancakeV3TickBitmap(pool).tickBitmap(int16(w));\n            if (word == 0) continue;\n            if (w == wLo) word &= type(uint256).max << (uint24(cLo) & 0xff);\n            if (w == wHi) word &= type(uint256).max >> (255 - (uint24(cHi) & 0xff));\n            if (word != 0) return true;\n        }\n        return false;\n    }\n}\n"},"src/interfaces/IAgentIdRegistry.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IAgentIdRegistry {\n    function balanceOf(address owner) external view returns (uint256);\n}\n"},"src/interfaces/IAgentPadFactory.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IAgentPadFactory {\n    function feeRecipient() external view returns (address);\n}\n"},"src/interfaces/IPancakeV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IPancakeV2Factory {\n    function getPair(address tokenA, address tokenB) external view returns (address pair);\n    function createPair(address tokenA, address tokenB) external returns (address pair);\n}\n\ninterface IPancakeV2Pair {\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n    function mint(address to) external returns (uint256 liquidity);\n    function sync() external;\n    function totalSupply() external view returns (uint256);\n    function balanceOf(address owner) external view returns (uint256);\n    function token0() external view returns (address);\n}\n"},"src/interfaces/IWBNB.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IWBNB {\n    function deposit() external payable;\n    function transfer(address to, uint256 value) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev An uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.8.28+commit.7893614a","compilerSettings":{"viaIR":false,"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"libraries":{},"optimizer":{"runs":200,"enabled":true},"evmVersion":"cancun","remappings":["@openzeppelin/=lib/openzeppelin-contracts/","forge-std/=lib/forge-std/src/","ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/"]},"name":"AgentPadFactoryV2","fullyQualifiedName":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},"abi":[{"type":"constructor","inputs":[{"name":"owner_","type":"address","internalType":"address"},{"name":"feeRecipient_","type":"address","internalType":"address"},{"name":"registry_","type":"address","internalType":"address"},{"name":"v2Factory_","type":"address","internalType":"address"},{"name":"v3Factory_","type":"address","internalType":"address"},{"name":"npm_","type":"address","internalType":"address"},{"name":"wbnb_","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"InvalidName","type":"error","inputs":[]},{"name":"InvalidNpm","type":"error","inputs":[]},{"name":"InvalidRegistry","type":"error","inputs":[]},{"name":"InvalidSymbol","type":"error","inputs":[]},{"name":"InvalidV2Factory","type":"error","inputs":[]},{"name":"InvalidV3Factory","type":"error","inputs":[]},{"name":"InvalidWbnb","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"RenounceDisabled","type":"error","inputs":[]},{"name":"TransferFailed","type":"error","inputs":[]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"AgentIdRegistryUpdated","type":"event","inputs":[{"name":"registry","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"FeeRecipientUpdated","type":"event","inputs":[{"name":"feeRecipient","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"FeesWithdrawn","type":"event","inputs":[{"name":"to","type":"address","indexed":false,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"OwnershipTransferStarted","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"TokenCreated","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"creator","type":"address","indexed":true,"internalType":"address"},{"name":"name","type":"string","indexed":false,"internalType":"string"},{"name":"symbol","type":"string","indexed":false,"internalType":"string"},{"name":"metaHash","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"name":"acceptOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"agentIdRegistry","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"allTokens","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"createToken","type":"function","inputs":[{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"metaHash","type":"bytes32","internalType":"bytes32"},{"name":"userSalt","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"token","type":"address","internalType":"address"}],"stateMutability":"payable"},{"name":"feeRecipient","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"isToken","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"npm","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pendingOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"predictTokenAddress","type":"function","inputs":[{"name":"creator","type":"address","internalType":"address"},{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"userSalt","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"view"},{"name":"setAgentIdRegistry","type":"function","inputs":[{"name":"registry_","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setFeeRecipient","type":"function","inputs":[{"name":"feeRecipient_","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"tokensCount","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"v2Factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"v3Factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"version","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"pure"},{"name":"wbnb","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"withdrawFees","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"receive","stateMutability":"payable"}],"metadata":{"compiler":{"version":"0.8.28+commit.7893614a"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"feeRecipient_","type":"address"},{"internalType":"address","name":"registry_","type":"address"},{"internalType":"address","name":"v2Factory_","type":"address"},{"internalType":"address","name":"v3Factory_","type":"address"},{"internalType":"address","name":"npm_","type":"address"},{"internalType":"address","name":"wbnb_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidName","type":"error"},{"inputs":[],"name":"InvalidNpm","type":"error"},{"inputs":[],"name":"InvalidRegistry","type":"error"},{"inputs":[],"name":"InvalidSymbol","type":"error"},{"inputs":[],"name":"InvalidV2Factory","type":"error"},{"inputs":[],"name":"InvalidV3Factory","type":"error"},{"inputs":[],"name":"InvalidWbnb","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"RenounceDisabled","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"registry","type":"address"}],"name":"AgentIdRegistryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeRecipient","type":"address"}],"name":"FeeRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"bytes32","name":"metaHash","type":"bytes32"}],"name":"TokenCreated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"agentIdRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"bytes32","name":"metaHash","type":"bytes32"},{"internalType":"bytes32","name":"userSalt","type":"bytes32"}],"name":"createToken","outputs":[{"internalType":"address","name":"token","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"feeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"npm","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"bytes32","name":"userSalt","type":"bytes32"}],"name":"predictTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"registry_","type":"address"}],"name":"setAgentIdRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"feeRecipient_","type":"address"}],"name":"setFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokensCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"v2Factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"v3Factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"wbnb","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"OwnableUnauthorizedAccount(address)":[{"details":"The caller account is not authorized to perform an operation."}]},"kind":"dev","methods":{"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer."}},"version":1},"userdoc":{"kind":"user","methods":{"renounceOwnership()":{"notice":"Disabled: renouncing would freeze `feeRecipient` and the registry forever."},"setAgentIdRegistry(address)":{"notice":"Only affects tokens created after the change."},"setFeeRecipient(address)":{"notice":"Also redirects graduated v2 tokens' outer-market fees (they read feeRecipient at collect time)."},"version()":{"notice":"Factory generation; v1 (AgentPadFactory) has no version() and is treated as 1."},"withdrawFees()":{"notice":"Anyone may call; funds only ever go to `feeRecipient`."}},"notice":"v2 factory: same as AgentPadFactory (v1) except tokens graduate into PancakeSwap V3         (falling back to v1-style Pancake V2 graduation when the V3 pool is not clean).","version":1}},"settings":{"compilationTarget":{"src/AgentPadFactoryV2.sol":"AgentPadFactoryV2"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":200},"remappings":[":@openzeppelin/=lib/openzeppelin-contracts/",":ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",":forge-std/=lib/forge-std/src/",":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",":openzeppelin-contracts/=lib/openzeppelin-contracts/"]},"sources":{"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"keccak256":"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb","license":"MIT","urls":["bzz-raw://8ed324d3920bb545059d66ab97d43e43ee85fd3bd52e03e401f020afb0b120f6","dweb:/ipfs/QmfEckWLmZkDDcoWrkEvMWhms66xwTLff9DDhegYpvHo1a"]},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"keccak256":"0xdcad8898fda432696597752e8ec361b87d85c82cb258115427af006dacf7128c","license":"MIT","urls":["bzz-raw://e2c9d517f0c136d54bd00cd57959d25681d4d6273f5bbbc263afe228303772f0","dweb:/ipfs/QmReNFjXBiufByiAAzfSQ2SM5r3qeUErn46BmN3yVRvrek"]},"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol":{"keccak256":"0x880da465c203cec76b10d72dbd87c80f387df4102274f23eea1f9c9b0918792b","license":"MIT","urls":["bzz-raw://399594cd8bb0143bc9e55e0f1d071d0d8c850a394fb7a319d50edd55d9ed822b","dweb:/ipfs/QmbPZzgtT6LEm9CMqWfagQFwETbV1ztpECBB1DtQHrKiRz"]},"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol":{"keccak256":"0xbf61ab2ae1d575a17ea58fbb99ca232baddcc4e0eeea180e84cbc74b0c348b31","license":"MIT","urls":["bzz-raw://4e0968705bad99747a8e5288aa008678c2be2f471f919dce3925a3cc4f1dee09","dweb:/ipfs/QmbAFnCQfo4tw6ssfQSjhA5LzwHWNNryXN8bX7ty8jiqqn"]},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"keccak256":"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7","license":"MIT","urls":["bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db","dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9"]},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0x70f2f713b13b7ce4610bcd0ac9fec0f3cc43693b043abcb8dc40a42a726eb330","license":"MIT","urls":["bzz-raw://c13d13304ac79a83ab1c30168967d19e2203342ebbd6a9bbce4db7550522dcbf","dweb:/ipfs/QmeN5jKMN2vw5bhacr6tkg78afbTTZUeaacNHqjWt4Ew1r"]},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"keccak256":"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2","license":"MIT","urls":["bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12","dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF"]},"lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"keccak256":"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a","license":"MIT","urls":["bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a","dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG"]},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0x11a5a79827df29e915a12740caf62fe21ebe27c08c9ae3e09abe9ee3ba3866d3","license":"MIT","urls":["bzz-raw://3cf0c69ab827e3251db9ee6a50647d62c90ba580a4d7bbff21f2bea39e7b2f4a","dweb:/ipfs/QmZiKwtKU1SBX4RGfQtY7PZfiapbbu6SZ9vizGQD9UHjRA"]},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"keccak256":"0xa00be322d7db5786750ce0ac7e2f5b633ac30a5ed5fa1ced1e74acfc19acecea","license":"MIT","urls":["bzz-raw://6c84e822f87cbdc4082533b626667b6928715bb2b1e8e7eb96954cebb9e38c8d","dweb:/ipfs/QmZmy9dgxLTerBAQDuuHqbL6EpgRxddqgv5KmwpXYVbKz1"]},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"keccak256":"0x195533c86d0ef72bcc06456a4f66a9b941f38eb403739b00f21fd7c1abd1ae54","license":"MIT","urls":["bzz-raw://b1d578337048cad08c1c03041cca5978eff5428aa130c781b271ad9e5566e1f8","dweb:/ipfs/QmPFKL2r9CBsMwmUqqdcFPfHZB2qcs9g1HDrPxzWSxomvy"]},"src/AgentPadFactoryV2.sol":{"keccak256":"0xf4a687bfa784737f96e24d14e873c58ad39ed46b3a9d3d3612d83d8232fb1d43","license":"MIT","urls":["bzz-raw://d06a027bb1592ba87ebc069e11ea8fb611570fcbfab5074bce80186dbb3e5501","dweb:/ipfs/QmRikNn6rNAgoZUp5xpGfnv5Tq4LhWn1gAfz8hBb7nA6hk"]},"src/AgentPadTokenV3.sol":{"keccak256":"0xb8795555c6115f19438a8e1ccef54e41bf280d3cec339d135392cdda156a6042","license":"MIT","urls":["bzz-raw://4e94d7fa47b97b6cb7cd5048db54f8b94e2f8716f17fc7d0290cb4e7383e9bd5","dweb:/ipfs/QmZazoQFdpPjRETBMeNky85S2T1BjBeTEgSJJE72oewZxV"]},"src/CurveMath.sol":{"keccak256":"0xbf8f246a9dba28f601abeac7b5baddbede4fb2f0c5f4ef91e41e35bdb9ea2ee0","license":"MIT","urls":["bzz-raw://de25122071af69716e06eb24b48346dc7a706805f7be03a72e2541b381570a72","dweb:/ipfs/QmZ25TYdBFxoX6gscnvn7ASTivHSAjR1bX9Zp1W5SC6JLZ"]},"src/V3PathLib.sol":{"keccak256":"0x5b1f7f652ff66593236eed32f4b4e1ac64f409c3410c68de70526302906040c9","license":"MIT","urls":["bzz-raw://64a611bff8e0f78ffd1767afcc0b6cc6965259033c86b39131c5078446080fc9","dweb:/ipfs/QmYGxdAd3gn92LkhYBTg14VMEoDT8HHGDazY2XzMAuvWeB"]},"src/interfaces/IAgentIdRegistry.sol":{"keccak256":"0xb8cdaef0addc1f11c5327227aa35c430250c8502c2aa39cd4ad737c8179d79d8","license":"MIT","urls":["bzz-raw://df683f34056173cc6c758bdf12534d77e27f12c186a75159f35d82e79235990d","dweb:/ipfs/QmU596PJaZ7ZTGqRSnpJaJwbGrVxzbWLqLRG3yYkaNQFPD"]},"src/interfaces/IAgentPadFactory.sol":{"keccak256":"0x83ff4223b86a398e4d1a006da4e9ff48dce1f16a076e07ea479f0188aca4d83c","license":"MIT","urls":["bzz-raw://a5db3d9d78a5ab65e50be5bbf134f621a3291a70ee8acf55d705575d41b59e83","dweb:/ipfs/QmVD9XEz3SCF3F6LtLG3wc1sAZxw8JBAivkhonJMPNU7tS"]},"src/interfaces/IPancakeV2.sol":{"keccak256":"0x0379f5f3a23bc6656f251addf4ffe3cf65155a4c14c823be441b02ff0f209b60","license":"MIT","urls":["bzz-raw://a23d7b51d41adf43aa3e6d6ca51f9e43fbca4dccb9f802086750485e0ba761c5","dweb:/ipfs/QmUnFq86TwokmUG8rLtggy4gQanqBccA13ExknhwY8XMyb"]},"src/interfaces/IPancakeV3.sol":{"keccak256":"0x672dd1db34d5e607df818a24099cedfa545a482e031f3c9efb90c7fe8a105fd1","license":"MIT","urls":["bzz-raw://628d1a9f990af1da6895e42e42bda78a55e962813105dffe07435ccf73d0261d","dweb:/ipfs/QmSyPKDitGz2UyAMiMpNQBZRGLMaFEiZqHbtb1inu7PoyW"]},"src/interfaces/IWBNB.sol":{"keccak256":"0x292ab1d3bc1b513abbc2f19581673a6d4e41f918c958e175350e4c446aa9d486","license":"MIT","urls":["bzz-raw://bf3a7115048e62cefea6c74da305093a0b034cd477b9e5fabdfe1af7f5b439d4","dweb:/ipfs/QmT1zWqNpicYy9eBPA4WcZ9wDo8JJEzab8wpwFfbyH6AgE"]}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_mapping(t_address,t_bool)":{"key":"t_address","label":"mapping(address => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"},"t_array(t_address)dyn_storage":{"base":"t_address","label":"address[]","encoding":"dynamic_array","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":8,"label":"_owner","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"1","type":"t_address","astId":156,"label":"_pendingOwner","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"2","type":"t_address","astId":4579,"label":"feeRecipient","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"3","type":"t_address","astId":4581,"label":"agentIdRegistry","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"4","type":"t_array(t_address)dyn_storage","astId":4584,"label":"allTokens","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"5","type":"t_mapping(t_address,t_bool)","astId":4588,"label":"isToken","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"}]},"transientStorageLayout":{"types":null,"storage":[]},"userdoc":{"kind":"user","notice":"v2 factory: same as AgentPadFactory (v1) except tokens graduate into PancakeSwap V3         (falling back to v1-style Pancake V2 graduation when the V3 pool is not clean).","methods":{"version()":{"notice":"Factory generation; v1 (AgentPadFactory) has no version() and is treated as 1."},"withdrawFees()":{"notice":"Anyone may call; funds only ever go to `feeRecipient`."},"renounceOwnership()":{"notice":"Disabled: renouncing would freeze `feeRecipient` and the registry forever."},"setFeeRecipient(address)":{"notice":"Also redirects graduated v2 tokens' outer-market fees (they read feeRecipient at collect time)."},"setAgentIdRegistry(address)":{"notice":"Only affects tokens created after the change."}},"version":1},"devdoc":{"kind":"dev","errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"OwnableUnauthorizedAccount(address)":[{"details":"The caller account is not authorized to perform an operation."}]},"methods":{"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer."}},"version":1},"sourceIds":{"src/CurveMath.sol":{"id":13},"src/V3PathLib.sol":{"id":14},"src/AgentPadTokenV3.sol":{"id":12},"src/interfaces/IWBNB.sol":{"id":19},"src/AgentPadFactoryV2.sol":{"id":11},"src/interfaces/IPancakeV2.sol":{"id":17},"src/interfaces/IPancakeV3.sol":{"id":18},"src/interfaces/IAgentIdRegistry.sol":{"id":15},"src/interfaces/IAgentPadFactory.sol":{"id":16},"lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"id":7},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"id":6},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"id":0},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"id":9},"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol":{"id":3},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"id":4},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"id":1},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"id":10},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"id":8},"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol":{"id":2},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":5}},"additionalInput":null,"stdJsonInput":{"sources":{"src/CurveMath.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @notice Virtual-reserve constant-product bonding curve: (reserveBnb + R) * (depth) = K,\n///         where depth = TOTAL_SUPPLY + H - sold. All amounts are in wei / 1e18-scaled tokens.\nlibrary CurveMath {\n    uint256 internal constant TOTAL_SUPPLY = 1_000_000_000e18;\n    uint256 internal constant SOLD_CAP = 800_000_000e18;\n    uint256 internal constant H = 66_666_666_666_666_666_666_666_667;\n    uint256 internal constant R = 5_333_333_333_333_333_333;\n    uint256 internal constant K = R * (TOTAL_SUPPLY + H);\n    uint256 internal constant MAX_BUY_PER_WALLET = 30_000_000e18;\n    uint256 internal constant FEE_BPS = 100;\n    uint256 internal constant BPS = 10_000;\n\n    /// @dev Virtual token depth remaining on the curve.\n    function depth(uint256 sold) internal pure returns (uint256) {\n        return TOTAL_SUPPLY + H - sold;\n    }\n\n    /// @dev Real BNB reserve held by the curve once `sold` tokens have been sold.\n    function reserveAt(uint256 sold) internal pure returns (uint256) {\n        return K / depth(sold) - R;\n    }\n\n    /// @dev Largest token amount purchasable with `netBnb` (after fee) at `sold`; rounds so cost <= netBnb.\n    function maxTokensFor(uint256 sold, uint256 netBnb) internal pure returns (uint256) {\n        uint256 d = depth(sold);\n        uint256 x = K / d;\n        uint256 y = K / (x + netBnb);\n        if (d <= y + 1) return 0;\n        return d - y - 1;\n    }\n\n    /// @dev BNB cost (before fee) of buying `amount` tokens at `sold`.\n    function costOf(uint256 sold, uint256 amount) internal pure returns (uint256) {\n        uint256 d = depth(sold);\n        return K / (d - amount) - K / d;\n    }\n\n    /// @dev BNB proceeds (before fee) of selling `amount` tokens back at `sold`.\n    function proceedsOf(uint256 sold, uint256 amount) internal pure returns (uint256) {\n        uint256 d = depth(sold);\n        return K / d - K / (d + amount);\n    }\n\n    /// @dev Spot price in wei per 1e18 tokens.\n    function spotPrice(uint256 sold) internal pure returns (uint256) {\n        uint256 d = depth(sold);\n        return K * 1e18 / (d * d);\n    }\n\n    /// @dev 1% fee, rounded up.\n    function feeOf(uint256 amount) internal pure returns (uint256) {\n        return (amount * FEE_BPS + BPS - 1) / BPS;\n    }\n}\n"},"src/V3PathLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IPancakeV3TickBitmap {\n    function tickBitmap(int16 wordPosition) external view returns (uint256);\n}\n\n/// @notice Decides whether a V3 swap from the current tick to the target tick could cross an\n///         initialized tick, by reading the pool's tick bitmap. Used by AgentPadTokenV3 so its price\n///         correction only ever runs through empty range (zero liquidity, zero token deltas).\n/// @dev Tick bitmap layout (Uniswap/Pancake V3): a tick t (a multiple of the spacing) is flagged at\n///      compressed = floor(t / spacing), word = compressed >> 8, bit = compressed & 0xff.\nlibrary V3PathLib {\n    int24 internal constant TICK_SPACING = 200;\n    /// @dev slot0.tick of a pool sitting at AgentPadTokenV3's target price, per ordering:\n    ///      floor(log_1.0001(spotPrice(SOLD_CAP) / 1e18)) = floor(-163420.5625...) when the token is\n    ///      token0, floor(+163420.5625...) when it is token1 (verified on fork in V3PathLib.t.sol).\n    int24 internal constant TARGET_TICK_TOKEN0 = -163421;\n    int24 internal constant TARGET_TICK_TOKEN1 = 163420;\n\n    /// @dev floor(tick / TICK_SPACING) (Solidity division truncates toward zero).\n    function compress(int24 tick) internal pure returns (int24 c) {\n        c = tick / TICK_SPACING;\n        if (tick < 0 && tick % TICK_SPACING != 0) c--;\n    }\n\n    /// @notice Could a swap from `currentTick` toward `targetTick` cross an initialized tick?\n    ///         Conservative (it may answer true for a tick that would not quite be reached):\n    ///         - price down (target below): a swap crosses every initialized tick k with\n    ///           target < price(k) <= current price, including the current tick's own lower boundary\n    ///           (nextInitializedTickWithinOneWord with lte = true starts at the current tick).\n    ///           Checked: compressed ticks [compress(targetTick), compress(currentTick)].\n    ///         - price up (target above): crosses initialized ticks strictly above the current tick\n    ///           up to the target. Checked: [compress(currentTick) + 1, compress(targetTick) + 1].\n    function pathHasInitializedTick(address pool, int24 currentTick, int24 targetTick) internal view returns (bool) {\n        if (targetTick <= currentTick) return anyInitialized(pool, compress(targetTick), compress(currentTick));\n        return anyInitialized(pool, compress(currentTick) + 1, compress(targetTick) + 1);\n    }\n\n    /// @notice True if any compressed tick in [cLo, cHi] (inclusive) is flagged in the pool's bitmap.\n    function anyInitialized(address pool, int24 cLo, int24 cHi) internal view returns (bool) {\n        if (cLo > cHi) return false;\n        int256 wLo = int256(cLo) >> 8;\n        int256 wHi = int256(cHi) >> 8;\n        for (int256 w = wLo; w <= wHi; w++) {\n            uint256 word = IPancakeV3TickBitmap(pool).tickBitmap(int16(w));\n            if (word == 0) continue;\n            if (w == wLo) word &= type(uint256).max << (uint24(cLo) & 0xff);\n            if (w == wHi) word &= type(uint256).max >> (255 - (uint24(cHi) & 0xff));\n            if (word != 0) return true;\n        }\n        return false;\n    }\n}\n"},"src/AgentPadTokenV3.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {CurveMath} from \"./CurveMath.sol\";\nimport {V3PathLib} from \"./V3PathLib.sol\";\nimport {IAgentIdRegistry} from \"./interfaces/IAgentIdRegistry.sol\";\nimport {IAgentPadFactory} from \"./interfaces/IAgentPadFactory.sol\";\nimport {IPancakeV2Factory, IPancakeV2Pair} from \"./interfaces/IPancakeV2.sol\";\nimport {IPancakeV3Factory, IPancakeV3Pool, INonfungiblePositionManager} from \"./interfaces/IPancakeV3.sol\";\nimport {IWBNB} from \"./interfaces/IWBNB.sol\";\n\n/// @notice v2 bonding-curve token. The inner market is a verbatim copy of AgentPadToken (v1); only\n///         graduation differs. Graduation is atomic (inside the filling buy, as in v1) and picks:\n///         - V3: if the PancakeSwap V3 (token, WBNB, 1%) pool is still clean (no liquidity in range,\n///           no initialized tick between its price and the curve-end price, and both full-range edge\n///           ticks keep EDGE_HEADROOM below maxLiquidityPerTick; dust positions on the edge ticks are\n///           harmless and do not count), move it to the curve-end price for free (zero-liquidity\n///           swap) and mint a full-range position this contract holds forever (no path to decrease\n///           liquidity, burn or move the NFT). Outer-market fees are collectable by anyone and only\n///           ever paid to the factory's feeRecipient.\n///         - V2: otherwise, exactly v1's graduation (Pancake V2 pair, LP burned to DEAD, no platform\n///           fees). Also the fallback if the NPM mint reverts for any reason. Nobody can force a V3\n///           graduation at a wrong price; the worst an attacker can do is push the token to V2 (by\n///           putting WBNB liquidity on the price path or in range, or saturating an edge tick up\n///           to the per-tick cap); a dust position on an edge tick no longer does.\n/// @dev Deliberately no receive()/fallback(): plain BNB transfers to the token revert.\ncontract AgentPadTokenV3 is ERC20, ReentrancyGuard {\n    error NotEligible();\n    error AlreadyGraduated();\n    error CapReached();\n    error AmountTooSmall();\n    error SlippageExceeded();\n    error RefundFailed();\n    error FeeTransferFailed();\n    error OnlyFactory();\n    /// @notice Pre-graduation transfers other than curve->holder / holder->curve.\n    error TransferLocked();\n    /// @notice sell amount exceeds the seller's token balance.\n    error InsufficientBalance();\n    /// @notice BNB payout to the seller failed (seller cannot receive BNB).\n    error PayoutFailed();\n    /// @notice graduate() called while already graduated or before sold == SOLD_CAP.\n    error NotGraduatable();\n    /// @notice collectFees() when the token did not graduate into V3 (not yet, or into V2).\n    error NotV3();\n    /// @notice pancakeV3SwapCallback from anyone but the pool, outside graduation's correction swap,\n    ///         or asking for any payment (the correction only runs through empty range).\n    error InvalidCallback();\n\n    /// @param bnbIn curve cost, excluding the fee\n    event Buy(address indexed buyer, uint256 bnbIn, uint256 fee, uint256 tokensOut, uint256 newSold);\n    /// @param bnbOut BNB paid to the seller, after the fee\n    event Sell(address indexed seller, uint256 tokensIn, uint256 bnbOut, uint256 fee, uint256 newSold);\n    /// @param venue the V3 pool (mode V3) or the V2 pair (mode V2)\n    /// @param positionId the locked V3 position (0 in mode V2)\n    /// @param tokens tokens seeded into the venue\n    /// @param bnb WBNB seeded into the venue\n    event Graduated(\n        address indexed token, address indexed venue, uint8 mode, uint256 positionId, uint256 tokens, uint256 bnb\n    );\n    /// @notice Outer-market fees collected from the locked V3 position and paid to `recipient`.\n    event FeesCollected(address indexed recipient, uint256 amountToken, uint256 amountWbnb);\n    /// @notice V3 mode leftovers: token rounding dust to DEAD, WBNB rounding dust (plus any BNB\n    ///         force-sent to the token, which cannot fit a position at a fixed price) to feeRecipient.\n    event DustSwept(address indexed feeRecipient, uint256 tokensToDead, uint256 wbnbToFeeRecipient);\n\n    /// @notice Receives V2 LP tokens (mode V2) and token dust (mode V3).\n    address public constant DEAD = 0x000000000000000000000000000000000000dEaD;\n\n    uint8 public constant MODE_NONE = 0;\n    uint8 public constant MODE_V3 = 1;\n    uint8 public constant MODE_V2 = 2;\n\n    uint24 internal constant FEE = 10000; // 1% tier, tick spacing 200\n    int24 internal constant TICK_LOWER = -887200; // full range for tick spacing 200\n    int24 internal constant TICK_UPPER = 887200;\n    /// @dev Graduation goes to V2 only if a full-range edge tick already holds more than\n    ///      maxLiquidityPerTick - EDGE_HEADROOM gross liquidity (our mint could then hit the per-tick\n    ///      cap). Our own full-range liquidity is ~5.7e22 (fixed seed amounts); the cap is ~3.8e34.\n    uint128 internal constant EDGE_HEADROOM = 1e30;\n\n    address public immutable factory;\n    address public immutable creator;\n    address public immutable agentIdRegistry;\n    address public immutable v2Factory;\n    address public immutable v3Factory;\n    address public immutable npm;\n    address public immutable wbnb;\n    bool public immutable token0IsSelf;\n    /// @notice The PancakeSwap V3 (token, WBNB, 1%) pool, created (and initialized at the curve-end\n    ///         price if nobody had) in the constructor.\n    address public immutable pool;\n\n    bool public graduated;\n    /// @notice MODE_NONE until graduation, then MODE_V3 or MODE_V2.\n    uint8 public graduationMode;\n    uint256 public sold;\n    mapping(address => uint256) public bought;\n    /// @notice NPM token id of the locked full-range position (mode V3 only).\n    uint256 public positionId;\n    /// @notice The Pancake V2 pair (mode V2 only).\n    address public pair;\n\n    /// @dev True only around the seller -> curve transfer inside _sell; the one pre-graduation path\n    ///      allowed to move tokens into the curve.\n    bool private transient _selling;\n    /// @dev True only around graduation's own zero-liquidity correction swap.\n    bool private transient _correcting;\n\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        address creator_,\n        address registry_,\n        address v2Factory_,\n        address v3Factory_,\n        address npm_,\n        address wbnb_\n    ) ERC20(name_, symbol_) {\n        factory = msg.sender;\n        creator = creator_;\n        agentIdRegistry = registry_;\n        v2Factory = v2Factory_;\n        v3Factory = v3Factory_;\n        npm = npm_;\n        wbnb = wbnb_;\n        bool t0 = address(this) < wbnb_;\n        token0IsSelf = t0;\n\n        // Someone may have front-run the pool for the predicted address (even initialized it at any\n        // price): reuse it; graduation decides whether it is still usable.\n        address p = IPancakeV3Factory(v3Factory_).getPool(address(this), wbnb_, FEE);\n        if (p == address(0)) p = IPancakeV3Factory(v3Factory_).createPool(address(this), wbnb_, FEE);\n        pool = p;\n        (uint160 sqrtP,,,,,,) = IPancakeV3Pool(p).slot0();\n        if (sqrtP == 0) IPancakeV3Pool(p).initialize(_target(t0));\n\n        _mint(address(this), CurveMath.TOTAL_SUPPLY);\n    }\n\n    // ------------------------------------------------------------------ buys\n\n    function buyWithBNB() external payable nonReentrant returns (uint256 tokensOut) {\n        _checkEligible(msg.sender);\n        return _buy(msg.sender, msg.value, 0);\n    }\n\n    function buyWithBNBMinOut(uint256 minTokens) external payable nonReentrant returns (uint256 tokensOut) {\n        _checkEligible(msg.sender);\n        return _buy(msg.sender, msg.value, minTokens);\n    }\n\n    /// @notice Dev buy at launch. Factory only; no ID gate (the buyer is the creator).\n    function buyFor(address buyer) external payable nonReentrant returns (uint256 tokensOut) {\n        if (msg.sender != factory) revert OnlyFactory();\n        if (graduated) revert AlreadyGraduated();\n        return _buy(buyer, msg.value, 0);\n    }\n\n    // ----------------------------------------------------------------- sells\n\n    function sell(uint256 amount) external nonReentrant returns (uint256 bnbOut) {\n        _checkEligible(msg.sender);\n        return _sell(msg.sender, amount, 0);\n    }\n\n    function sellWithMin(uint256 amount, uint256 minBnb) external nonReentrant returns (uint256 bnbOut) {\n        _checkEligible(msg.sender);\n        return _sell(msg.sender, amount, minBnb);\n    }\n\n    /// @notice Sells the caller's whole balance. Reverts AmountTooSmall on a zero balance.\n    function sellAll() external nonReentrant returns (uint256 bnbOut) {\n        _checkEligible(msg.sender);\n        return _sell(msg.sender, balanceOf(msg.sender), 0);\n    }\n\n    // ------------------------------------------------------------ graduation\n\n    /// @notice Fallback: anyone may graduate a full curve. Normally the filling buy graduates in\n    ///         the same transaction, so this only matters if that ever did not happen.\n    function graduate() external nonReentrant {\n        if (graduated || sold != CurveMath.SOLD_CAP) revert NotGraduatable();\n        _graduate(0);\n    }\n\n    /// @notice Anyone may call after a V3 graduation: pays the locked position's accrued outer-market\n    ///         fees (both tokens, as-is) to the factory's current feeRecipient. Never touches liquidity.\n    function collectFees() external nonReentrant returns (uint256 amountToken, uint256 amountWbnb) {\n        if (graduationMode != MODE_V3) revert NotV3();\n        address recipient = IAgentPadFactory(factory).feeRecipient();\n        // The position's liquidity is never decreased, so tokensOwed is only ever accrued fees.\n        (uint256 a0, uint256 a1) = INonfungiblePositionManager(npm).collect(\n            INonfungiblePositionManager.CollectParams({\n                tokenId: positionId,\n                recipient: recipient,\n                amount0Max: type(uint128).max,\n                amount1Max: type(uint128).max\n            })\n        );\n        (amountToken, amountWbnb) = token0IsSelf ? (a0, a1) : (a1, a0);\n        emit FeesCollected(recipient, amountToken, amountWbnb);\n    }\n\n    /// @notice Graduation's correction swap runs only through empty range, so the pool never asks for\n    ///         a payment. Anything else (other caller, outside that swap, any non-zero delta) reverts.\n    function pancakeV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata) external view {\n        if (!_correcting || msg.sender != pool || amount0Delta != 0 || amount1Delta != 0) revert InvalidCallback();\n    }\n\n    // ------------------------------------------------------------------ views\n\n    /// @notice Curve-end price CurveMath.spotPrice(SOLD_CAP) as a V3 sqrtPriceX96 for this token's\n    ///         ordering: sqrt(token1 per token0, raw units) * 2^96.\n    function targetSqrtPriceX96() public view returns (uint160) {\n        return _target(token0IsSelf);\n    }\n\n    function canTrade(address a) public view returns (bool) {\n        return !graduated && (a == creator || IAgentIdRegistry(agentIdRegistry).balanceOf(a) > 0);\n    }\n\n    /// @notice Tokens `a` may still buy on the curve (cumulative, never reset by selling).\n    function remainingCap(address a) external view returns (uint256) {\n        return CurveMath.MAX_BUY_PER_WALLET - bought[a];\n    }\n\n    /// @notice Exact result of `buyer` calling buyWithBNB{value: grossBnb}(), using buyer's remaining cap.\n    ///         Returns zeros and refund == grossBnb when nothing would fill (including after graduation).\n    function quoteBuyFor(address buyer, uint256 grossBnb)\n        public\n        view\n        returns (uint256 tokensOut, uint256 cost, uint256 fee, uint256 refund)\n    {\n        if (graduated) return (0, 0, 0, grossBnb);\n        (tokensOut, cost, fee) = _quote(buyer, grossBnb);\n        refund = grossBnb - cost - fee;\n    }\n\n    /// @notice quoteBuyFor(msg.sender, grossBnb).\n    function quoteBuy(uint256 grossBnb)\n        external\n        view\n        returns (uint256 tokensOut, uint256 cost, uint256 fee, uint256 refund)\n    {\n        return quoteBuyFor(msg.sender, grossBnb);\n    }\n\n    /// @notice Exact result of a successful sell(amount) now: BNB to the seller (after fee) and the fee.\n    ///         Returns (0, 0) whenever sell(amount) would revert for amount reasons or after graduation:\n    ///         amount == 0, amount > sold, or the sale is worth 0 BNB after the fee. Does not check any\n    ///         particular seller's balance or eligibility.\n    function quoteSell(uint256 amount) external view returns (uint256 bnbOut, uint256 fee) {\n        if (graduated) return (0, 0);\n        return _quoteSell(amount);\n    }\n\n    function spotPrice() external view returns (uint256) {\n        return CurveMath.spotPrice(sold);\n    }\n\n    /// @notice Curve progress in basis points (10000 = graduated).\n    function progress() external view returns (uint256) {\n        return sold * 10000 / CurveMath.SOLD_CAP;\n    }\n\n    function reserve() external view returns (uint256) {\n        return CurveMath.reserveAt(sold);\n    }\n\n    // --------------------------------------------------------------- internal\n\n    function _checkEligible(address a) private view {\n        if (graduated) revert AlreadyGraduated();\n        if (!canTrade(a)) revert NotEligible();\n    }\n\n    /// @dev out = min(curve-affordable, curve remainder, personal remainder); cost + fee <= gross always.\n    function _quote(address buyer, uint256 gross) private view returns (uint256 out, uint256 cost, uint256 fee) {\n        uint256 s = sold;\n        uint256 net = gross * CurveMath.BPS / (CurveMath.BPS + CurveMath.FEE_BPS);\n        out = CurveMath.maxTokensFor(s, net);\n        uint256 curveLeft = CurveMath.SOLD_CAP - s;\n        if (out > curveLeft) out = curveLeft;\n        uint256 walletLeft = CurveMath.MAX_BUY_PER_WALLET - bought[buyer];\n        if (out > walletLeft) out = walletLeft;\n        if (out == 0) return (0, 0, 0);\n        cost = CurveMath.costOf(s, out);\n        fee = CurveMath.feeOf(cost);\n    }\n\n    function _buy(address buyer, uint256 gross, uint256 minOut) private returns (uint256 out) {\n        uint256 cost;\n        uint256 fee;\n        (out, cost, fee) = _quote(buyer, gross);\n        if (out == 0) {\n            if (bought[buyer] >= CurveMath.MAX_BUY_PER_WALLET) revert CapReached();\n            revert AmountTooSmall();\n        }\n        if (out < minOut) revert SlippageExceeded();\n\n        // Effects\n        uint256 newSold = sold + out;\n        sold = newSold;\n        bought[buyer] += out;\n        _transfer(address(this), buyer, out);\n        emit Buy(buyer, cost, fee, out, newSold);\n        uint256 refund = gross - cost - fee;\n\n        // Graduate before the fee push and refund, so no untrusted callback ever observes\n        // sold == SOLD_CAP && !graduated. _graduate only calls WBNB, the factory, the Pancake V2/V3\n        // factories, pair, pool and the NPM (none calls back into untrusted code). fee + refund are\n        // still in this contract's balance at this point and are excluded from the LP seed.\n        if (newSold == CurveMath.SOLD_CAP) _graduate(fee + refund);\n\n        // Interactions\n        if (fee > 0) {\n            (bool okFee,) = factory.call{value: fee}(\"\");\n            if (!okFee) revert FeeTransferFailed();\n        }\n        if (refund > 0) {\n            (bool okRefund,) = buyer.call{value: refund}(\"\");\n            if (!okRefund) revert RefundFailed();\n        }\n    }\n\n    /// @dev (0, 0) for amount == 0, amount > sold (proceeds would exceed the reserve), or a net-zero sale.\n    function _quoteSell(uint256 amount) private view returns (uint256 bnbOut, uint256 fee) {\n        uint256 s = sold;\n        if (amount == 0 || amount > s) return (0, 0);\n        uint256 proceeds = CurveMath.proceedsOf(s, amount);\n        fee = CurveMath.feeOf(proceeds);\n        if (proceeds <= fee) return (0, 0);\n        bnbOut = proceeds - fee;\n    }\n\n    function _sell(address seller, uint256 amount, uint256 minBnb) private returns (uint256 bnbOut) {\n        if (amount == 0) revert AmountTooSmall();\n        // Pre-graduation, holder balances sum to `sold`, so this also guarantees amount <= sold.\n        if (amount > balanceOf(seller)) revert InsufficientBalance();\n        uint256 fee;\n        (bnbOut, fee) = _quoteSell(amount);\n        if (bnbOut == 0) revert AmountTooSmall();\n        if (bnbOut < minBnb) revert SlippageExceeded();\n\n        // Effects\n        uint256 newSold = sold - amount;\n        sold = newSold;\n        _selling = true;\n        _transfer(seller, address(this), amount);\n        _selling = false;\n        emit Sell(seller, amount, bnbOut, fee, newSold);\n\n        // Interactions\n        (bool okFee,) = factory.call{value: fee}(\"\");\n        if (!okFee) revert FeeTransferFailed();\n        (bool okOut,) = seller.call{value: bnbOut}(\"\");\n        if (!okOut) revert PayoutFailed();\n    }\n\n    /// @dev Inner market: only curve -> holder (mint/buy) and holder -> curve inside _sell move tokens.\n    ///      A plain transfer to the curve is locked too, so pre-graduation\n    ///      balanceOf(this) == TOTAL_SUPPLY - sold always, and nobody can hold or deposit tokens in the\n    ///      V3 pool or V2 pair before graduation (any pre-existing liquidity there is WBNB-only).\n    ///      After graduation the token is a plain ERC20.\n    function _update(address from, address to, uint256 value) internal override {\n        if (!graduated && from != address(0) && from != address(this) && !(_selling && to == address(this))) {\n            revert TransferLocked();\n        }\n        super._update(from, to, value);\n    }\n\n    // ------------------------------------------------------------ graduation internals\n\n    /// @dev Any V3 obstacle (dirty pool, failed correction swap, failed NPM mint) falls back to v1's\n    ///      V2 graduation inside the same call; a V3 problem can never block graduation.\n    /// @param pendingOut BNB still owed out of this balance by the calling buy (fee + refund).\n    function _graduate(uint256 pendingOut) private {\n        graduated = true; // first: closes the inner market and unlocks transfers before any call out\n\n        // Curve reserve (+ any force-sent BNB) as WBNB.\n        IWBNB(wbnb).deposit{value: address(this).balance - pendingOut}();\n\n        if (!(_poolAtTarget() && _graduateV3())) _graduateV2();\n    }\n\n    /// @dev True once the V3 pool sits exactly at the target price, moving it there first if that is\n    ///      free: only when the pool has no in-range liquidity, our full-range edge ticks have headroom\n    ///      for our mint, and no initialized tick lies on the path, so the swap has no counterparty and\n    ///      both deltas are zero (the callback enforces it).\n    ///      Before graduation nobody can hold the token in the pool, so any foreign liquidity is\n    ///      WBNB-only; any such liquidity on the path or in range sends the token to V2 instead.\n    ///      Foreign liquidity on an edge tick is harmless unless it is within EDGE_HEADROOM of\n    ///      maxLiquidityPerTick (our mint would revert), so a dust position there cannot force V2.\n    ///      Returns false rather than reverting on every pool-side failure.\n    function _poolAtTarget() private returns (bool) {\n        address p = pool;\n        uint160 target = _target(token0IsSelf);\n        if (IPancakeV3Pool(p).liquidity() != 0) return false;\n        uint128 maxGross = IPancakeV3Pool(p).maxLiquidityPerTick();\n        if (maxGross < EDGE_HEADROOM) return false;\n        uint128 limit = maxGross - EDGE_HEADROOM;\n        if (IPancakeV3Pool(p).ticks(TICK_LOWER) > limit || IPancakeV3Pool(p).ticks(TICK_UPPER) > limit) return false;\n        (uint160 sqrtP, int24 tick,,,,,) = IPancakeV3Pool(p).slot0();\n        if (sqrtP == target) return true;\n        int24 targetTick = token0IsSelf ? V3PathLib.TARGET_TICK_TOKEN0 : V3PathLib.TARGET_TICK_TOKEN1;\n        if (V3PathLib.pathHasInitializedTick(p, tick, targetTick)) return false;\n\n        bool zeroForOne = sqrtP > target;\n        _correcting = true;\n        // 1 wei exact input: with zero liquidity nothing is consumed and the price limit stops it.\n        try IPancakeV3Pool(p).swap(address(this), zeroForOne, 1, target, \"\") {}\n        catch {\n            _correcting = false;\n            return false;\n        }\n        _correcting = false;\n        (sqrtP,,,,,,) = IPancakeV3Pool(p).slot0();\n        return sqrtP == target;\n    }\n\n    /// @dev Full-range position at exactly the target price, NFT kept by this contract forever.\n    ///      Returns false (nothing changed: approvals reset, all tokens and WBNB still here) if the NPM\n    ///      mint reverts for any reason, so the caller falls back to V2.\n    function _graduateV3() private returns (bool) {\n        uint256 tokens = balanceOf(address(this)); // TOTAL_SUPPLY - SOLD_CAP\n        uint256 bnb = IERC20(wbnb).balanceOf(address(this));\n        bool t0 = token0IsSelf;\n        _approve(address(this), npm, tokens);\n        IERC20(wbnb).approve(npm, bnb);\n        // At the target price the curve reserve matches 200M tokens exactly, so tokens are the binding\n        // side (any force-sent BNB only adds WBNB); the min only tolerates rounding.\n        uint256 minTokens = tokens - tokens / 1000;\n        try INonfungiblePositionManager(npm).mint(\n            INonfungiblePositionManager.MintParams({\n                token0: t0 ? address(this) : wbnb,\n                token1: t0 ? wbnb : address(this),\n                fee: FEE,\n                tickLower: TICK_LOWER,\n                tickUpper: TICK_UPPER,\n                amount0Desired: t0 ? tokens : bnb,\n                amount1Desired: t0 ? bnb : tokens,\n                amount0Min: t0 ? minTokens : 0,\n                amount1Min: t0 ? 0 : minTokens,\n                recipient: address(this),\n                deadline: block.timestamp\n            })\n        ) returns (uint256 id, uint128, uint256 a0, uint256 a1) {\n            _finishV3(id, a0, a1);\n            return true;\n        } catch {\n            _approve(address(this), npm, 0);\n            IERC20(wbnb).approve(npm, 0);\n            return false;\n        }\n    }\n\n    /// @dev Records the V3 graduation and sweeps leftovers (actual balances, so nothing stays behind;\n    ///      allowances cleared): token rounding dust to DEAD; WBNB rounding dust (~2e8 wei, < 1e12) to\n    ///      feeRecipient. BNB force-sent to the token before graduation cannot fit a full-range\n    ///      position at the fixed target price, so in V3 mode it also goes to feeRecipient (in V2 mode\n    ///      it joins the pair, as in v1). Only the donor loses; nothing trades against anyone here.\n    function _finishV3(uint256 id, uint256 a0, uint256 a1) private {\n        positionId = id;\n        graduationMode = MODE_V3;\n        (uint256 usedTokens, uint256 usedBnb) = token0IsSelf ? (a0, a1) : (a1, a0);\n        emit Graduated(address(this), pool, MODE_V3, id, usedTokens, usedBnb);\n\n        _approve(address(this), npm, 0);\n        IERC20(wbnb).approve(npm, 0);\n        uint256 dustTokens = balanceOf(address(this));\n        uint256 dustBnb = IERC20(wbnb).balanceOf(address(this));\n        address recipient = IAgentPadFactory(factory).feeRecipient();\n        if (dustTokens > 0) _transfer(address(this), DEAD, dustTokens);\n        // Canonical WBNB reverts on failure; its return value is always true. A WBNB transfer never\n        // calls the recipient, so feeRecipient cannot block graduation.\n        if (dustBnb > 0) IERC20(wbnb).transfer(recipient, dustBnb);\n        emit DustSwept(recipient, dustTokens, dustBnb);\n    }\n\n    /// @dev v1's graduation (AgentPadToken._graduate after the wrap), verbatim apart from creating the\n    ///      pair here instead of in the constructor: seeds the Pancake V2 pair directly and burns the LP.\n    ///      Poison-proof: pair.mint only uses balance - reserve, so donated or sync'd WBNB just joins\n    ///      the pool. The pair's LP totalSupply is 0 here: a first mint needs both sides, and the pair\n    ///      can never hold this token before graduation (transfers to it are locked), so nobody can\n    ///      mint first and pick the price.\n    function _graduateV2() private {\n        address p = IPancakeV2Factory(v2Factory).getPair(address(this), wbnb);\n        if (p == address(0)) p = IPancakeV2Factory(v2Factory).createPair(address(this), wbnb);\n        pair = p;\n        graduationMode = MODE_V2;\n\n        uint256 bnb = IERC20(wbnb).balanceOf(address(this)); // curve reserve (+ any force-sent BNB)\n        uint256 tokens = balanceOf(address(this)); // == TOTAL_SUPPLY - SOLD_CAP\n\n        _transfer(address(this), p, tokens);\n        // Canonical WBNB reverts on failure; its return value is always true.\n        IWBNB(wbnb).transfer(p, bnb);\n        IPancakeV2Pair(p).mint(DEAD);\n\n        emit Graduated(address(this), p, MODE_V2, 0, tokens, bnb);\n    }\n\n    /// @dev Curve-end price CurveMath.spotPrice(SOLD_CAP) as a V3 sqrtPriceX96: sqrt(token1 per\n    ///      token0, raw units) * 2^96. spotPrice is wei per 1e18 tokens (~8e10), so either ratio\n    ///      * 2^192 fits in 256 bits (~5e68 / ~8e64) and mulDiv keeps full precision before the sqrt.\n    function _target(bool t0) private pure returns (uint160) {\n        uint256 p = CurveMath.spotPrice(CurveMath.SOLD_CAP);\n        return uint160(t0 ? Math.sqrt(Math.mulDiv(p, 1 << 192, 1e18)) : Math.sqrt(Math.mulDiv(1e18, 1 << 192, p)));\n    }\n}\n"},"src/interfaces/IWBNB.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IWBNB {\n    function deposit() external payable;\n    function transfer(address to, uint256 value) external returns (bool);\n}\n"},"src/AgentPadFactoryV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Ownable, Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {AgentPadTokenV3} from \"./AgentPadTokenV3.sol\";\nimport {INonfungiblePositionManager} from \"./interfaces/IPancakeV3.sol\";\n\n/// @notice v2 factory: same as AgentPadFactory (v1) except tokens graduate into PancakeSwap V3\n///         (falling back to v1-style Pancake V2 graduation when the V3 pool is not clean).\ncontract AgentPadFactoryV2 is Ownable2Step {\n    error InvalidName();\n    error InvalidSymbol();\n    error ZeroAddress();\n    error TransferFailed();\n    error InvalidRegistry();\n    error InvalidV2Factory();\n    error InvalidV3Factory();\n    error InvalidNpm();\n    error InvalidWbnb();\n    error RenounceDisabled();\n\n    event TokenCreated(address indexed token, address indexed creator, string name, string symbol, bytes32 metaHash);\n    event FeeRecipientUpdated(address feeRecipient);\n    event AgentIdRegistryUpdated(address registry);\n    event FeesWithdrawn(address to, uint256 amount);\n\n    address public immutable v2Factory;\n    address public immutable v3Factory;\n    address public immutable npm;\n    address public immutable wbnb;\n\n    address public feeRecipient;\n    address public agentIdRegistry;\n    address[] public allTokens;\n    mapping(address => bool) public isToken;\n\n    constructor(\n        address owner_,\n        address feeRecipient_,\n        address registry_,\n        address v2Factory_,\n        address v3Factory_,\n        address npm_,\n        address wbnb_\n    ) Ownable(owner_) {\n        if (feeRecipient_ == address(0)) revert ZeroAddress();\n        if (registry_.code.length == 0) revert InvalidRegistry();\n        if (v2Factory_.code.length == 0) revert InvalidV2Factory();\n        if (v3Factory_.code.length == 0) revert InvalidV3Factory();\n        if (npm_.code.length == 0) revert InvalidNpm();\n        if (wbnb_.code.length == 0) revert InvalidWbnb();\n        // The NPM must be the one bound to this V3 factory and this WBNB (catches mixed-network config).\n        if (\n            INonfungiblePositionManager(npm_).factory() != v3Factory_\n                || INonfungiblePositionManager(npm_).WETH9() != wbnb_\n        ) revert InvalidNpm();\n        feeRecipient = feeRecipient_;\n        agentIdRegistry = registry_;\n        v2Factory = v2Factory_;\n        v3Factory = v3Factory_;\n        npm = npm_;\n        wbnb = wbnb_;\n    }\n\n    receive() external payable {}\n\n    /// @notice Factory generation; v1 (AgentPadFactory) has no version() and is treated as 1.\n    function version() external pure returns (uint256) {\n        return 2;\n    }\n\n    function createToken(string calldata name, string calldata symbol, bytes32 metaHash, bytes32 userSalt)\n        external\n        payable\n        returns (address token)\n    {\n        if (bytes(name).length == 0 || bytes(name).length > 64) revert InvalidName();\n        if (bytes(symbol).length == 0 || bytes(symbol).length > 16) revert InvalidSymbol();\n\n        token = address(\n            new AgentPadTokenV3{salt: _salt(msg.sender, userSalt)}(\n                name, symbol, msg.sender, agentIdRegistry, v2Factory, v3Factory, npm, wbnb\n            )\n        );\n        allTokens.push(token);\n        isToken[token] = true;\n        emit TokenCreated(token, msg.sender, name, symbol, metaHash);\n\n        if (msg.value > 0) AgentPadTokenV3(token).buyFor{value: msg.value}(msg.sender);\n    }\n\n    function predictTokenAddress(address creator, string calldata name, string calldata symbol, bytes32 userSalt)\n        external\n        view\n        returns (address)\n    {\n        bytes32 initHash = keccak256(\n            abi.encodePacked(\n                type(AgentPadTokenV3).creationCode,\n                abi.encode(name, symbol, creator, agentIdRegistry, v2Factory, v3Factory, npm, wbnb)\n            )\n        );\n        return address(\n            uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt(creator, userSalt), initHash))))\n        );\n    }\n\n    function tokensCount() external view returns (uint256) {\n        return allTokens.length;\n    }\n\n    /// @notice Also redirects graduated v2 tokens' outer-market fees (they read feeRecipient at collect time).\n    function setFeeRecipient(address feeRecipient_) external onlyOwner {\n        if (feeRecipient_ == address(0)) revert ZeroAddress();\n        feeRecipient = feeRecipient_;\n        emit FeeRecipientUpdated(feeRecipient_);\n    }\n\n    /// @notice Only affects tokens created after the change.\n    function setAgentIdRegistry(address registry_) external onlyOwner {\n        if (registry_.code.length == 0) revert InvalidRegistry();\n        agentIdRegistry = registry_;\n        emit AgentIdRegistryUpdated(registry_);\n    }\n\n    /// @notice Disabled: renouncing would freeze `feeRecipient` and the registry forever.\n    function renounceOwnership() public view override onlyOwner {\n        revert RenounceDisabled();\n    }\n\n    /// @notice Anyone may call; funds only ever go to `feeRecipient`.\n    function withdrawFees() external {\n        uint256 amount = address(this).balance;\n        (bool ok,) = feeRecipient.call{value: amount}(\"\");\n        if (!ok) revert TransferFailed();\n        emit FeesWithdrawn(feeRecipient, amount);\n    }\n\n    function _salt(address creator, bytes32 userSalt) private pure returns (bytes32) {\n        return keccak256(abi.encode(creator, userSalt));\n    }\n}\n"},"src/interfaces/IPancakeV2.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IPancakeV2Factory {\n    function getPair(address tokenA, address tokenB) external view returns (address pair);\n    function createPair(address tokenA, address tokenB) external returns (address pair);\n}\n\ninterface IPancakeV2Pair {\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n    function mint(address to) external returns (uint256 liquidity);\n    function sync() external;\n    function totalSupply() external view returns (uint256);\n    function balanceOf(address owner) external view returns (uint256);\n    function token0() external view returns (address);\n}\n"},"src/interfaces/IPancakeV3.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @dev Minimal PancakeSwap V3 surface used by AgentPadTokenV3 / AgentPadFactoryV2.\n///      Checked against the verified mainnet contracts (BSC 56).\ninterface IPancakeV3Factory {\n    function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool);\n    function createPool(address tokenA, address tokenB, uint24 fee) external returns (address pool);\n}\n\ninterface IPancakeV3Pool {\n    /// @dev Pancake's slot0: feeProtocol is uint32 (Uniswap's is uint8).\n    function slot0()\n        external\n        view\n        returns (\n            uint160 sqrtPriceX96,\n            int24 tick,\n            uint16 observationIndex,\n            uint16 observationCardinality,\n            uint16 observationCardinalityNext,\n            uint32 feeProtocol,\n            bool unlocked\n        );\n    /// @dev In-range liquidity at the current tick.\n    function liquidity() external view returns (uint128);\n    function maxLiquidityPerTick() external view returns (uint128);\n    /// @dev Only the first return value (liquidityGross) is declared; the ABI decoder ignores the rest.\n    function ticks(int24 tick) external view returns (uint128 liquidityGross);\n    function initialize(uint160 sqrtPriceX96) external;\n    function swap(\n        address recipient,\n        bool zeroForOne,\n        int256 amountSpecified,\n        uint160 sqrtPriceLimitX96,\n        bytes calldata data\n    ) external returns (int256 amount0, int256 amount1);\n}\n\ninterface INonfungiblePositionManager {\n    struct MintParams {\n        address token0;\n        address token1;\n        uint24 fee;\n        int24 tickLower;\n        int24 tickUpper;\n        uint256 amount0Desired;\n        uint256 amount1Desired;\n        uint256 amount0Min;\n        uint256 amount1Min;\n        address recipient;\n        uint256 deadline;\n    }\n\n    struct CollectParams {\n        uint256 tokenId;\n        address recipient;\n        uint128 amount0Max;\n        uint128 amount1Max;\n    }\n\n    function factory() external view returns (address);\n    function WETH9() external view returns (address);\n    function mint(MintParams calldata params)\n        external\n        payable\n        returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);\n    function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1);\n}\n"},"src/interfaces/IAgentIdRegistry.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IAgentIdRegistry {\n    function balanceOf(address owner) external view returns (uint256);\n}\n"},"src/interfaces/IAgentPadFactory.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IAgentPadFactory {\n    function feeRecipient() external view returns (address);\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with an success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n            // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2²⁵⁶ + prod0.\n            uint256 prod0 = x * y; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n        for (uint256 i = 0; i < byteArray.length; ++i) {\n            if (byteArray[i] != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        uint256 exp;\n        unchecked {\n            exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);\n            value >>= exp;\n            result += exp;\n\n            exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);\n            value >>= exp;\n            result += exp;\n\n            result += SafeCast.toUint(value > 1);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        uint256 isGt;\n        unchecked {\n            isGt = SafeCast.toUint(value > (1 << 128) - 1);\n            value >>= isGt * 128;\n            result += isGt * 16;\n\n            isGt = SafeCast.toUint(value > (1 << 64) - 1);\n            value >>= isGt * 64;\n            result += isGt * 8;\n\n            isGt = SafeCast.toUint(value > (1 << 32) - 1);\n            value >>= isGt * 32;\n            result += isGt * 4;\n\n            isGt = SafeCast.toUint(value > (1 << 16) - 1);\n            value >>= isGt * 16;\n            result += isGt * 2;\n\n            result += SafeCast.toUint(value > (1 << 8) - 1);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC-20\n * applications.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Skips emitting an {Approval} event indicating an allowance update. This is not\n     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n     * true using the following override:\n     *\n     * ```solidity\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.20;\n\nimport {Ownable} from \"./Ownable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * This extension of the {Ownable} contract includes a two-step mechanism to transfer\n * ownership, where the new owner must call {acceptOwnership} in order to replace the\n * old one. This can help prevent common mistakes, such as transfers of ownership to\n * incorrect accounts, or to contracts that are unable to interact with the\n * permission system.\n *\n * The initial owner is specified at deployment time in the constructor for `Ownable`. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2Step is Ownable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     *\n     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        if (pendingOwner() != sender) {\n            revert OwnableUnauthorizedAccount(sender);\n        }\n        _transferOwnership(sender);\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev An uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,\n * consider using {ReentrancyGuardTransient} instead.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    uint256 private _status;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if (_status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        _status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == ENTERED;\n    }\n}\n"},"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC-20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC-721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC-1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"}},"language":"Solidity","settings":{"viaIR":false,"metadata":{"appendCBOR":true,"bytecodeHash":"ipfs","useLiteralContent":false},"libraries":{},"optimizer":{"runs":200,"enabled":true},"evmVersion":"cancun","remappings":["@openzeppelin/=lib/openzeppelin-contracts/","forge-std/=lib/forge-std/src/","ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/"]}},"stdJsonOutput":{"sources":{"src/CurveMath.sol":{"id":13},"src/V3PathLib.sol":{"id":14},"src/AgentPadTokenV3.sol":{"id":12},"src/interfaces/IWBNB.sol":{"id":19},"src/AgentPadFactoryV2.sol":{"id":11},"src/interfaces/IPancakeV2.sol":{"id":17},"src/interfaces/IPancakeV3.sol":{"id":18},"src/interfaces/IAgentIdRegistry.sol":{"id":15},"src/interfaces/IAgentPadFactory.sol":{"id":16},"lib/openzeppelin-contracts/contracts/utils/Panic.sol":{"id":7},"lib/openzeppelin-contracts/contracts/utils/Context.sol":{"id":6},"lib/openzeppelin-contracts/contracts/access/Ownable.sol":{"id":0},"lib/openzeppelin-contracts/contracts/utils/math/Math.sol":{"id":9},"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol":{"id":3},"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol":{"id":4},"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol":{"id":1},"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol":{"id":10},"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol":{"id":8},"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol":{"id":2},"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":5}},"contracts":{"src/AgentPadFactoryV2.sol":{"AgentPadFactoryV2":{"abi":[{"type":"constructor","inputs":[{"name":"owner_","type":"address","internalType":"address"},{"name":"feeRecipient_","type":"address","internalType":"address"},{"name":"registry_","type":"address","internalType":"address"},{"name":"v2Factory_","type":"address","internalType":"address"},{"name":"v3Factory_","type":"address","internalType":"address"},{"name":"npm_","type":"address","internalType":"address"},{"name":"wbnb_","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"InvalidName","type":"error","inputs":[]},{"name":"InvalidNpm","type":"error","inputs":[]},{"name":"InvalidRegistry","type":"error","inputs":[]},{"name":"InvalidSymbol","type":"error","inputs":[]},{"name":"InvalidV2Factory","type":"error","inputs":[]},{"name":"InvalidV3Factory","type":"error","inputs":[]},{"name":"InvalidWbnb","type":"error","inputs":[]},{"name":"OwnableInvalidOwner","type":"error","inputs":[{"name":"owner","type":"address","internalType":"address"}]},{"name":"OwnableUnauthorizedAccount","type":"error","inputs":[{"name":"account","type":"address","internalType":"address"}]},{"name":"RenounceDisabled","type":"error","inputs":[]},{"name":"TransferFailed","type":"error","inputs":[]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"AgentIdRegistryUpdated","type":"event","inputs":[{"name":"registry","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"FeeRecipientUpdated","type":"event","inputs":[{"name":"feeRecipient","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"FeesWithdrawn","type":"event","inputs":[{"name":"to","type":"address","indexed":false,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"OwnershipTransferStarted","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"OwnershipTransferred","type":"event","inputs":[{"name":"previousOwner","type":"address","indexed":true,"internalType":"address"},{"name":"newOwner","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"TokenCreated","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"creator","type":"address","indexed":true,"internalType":"address"},{"name":"name","type":"string","indexed":false,"internalType":"string"},{"name":"symbol","type":"string","indexed":false,"internalType":"string"},{"name":"metaHash","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"name":"acceptOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"agentIdRegistry","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"allTokens","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"createToken","type":"function","inputs":[{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"metaHash","type":"bytes32","internalType":"bytes32"},{"name":"userSalt","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"token","type":"address","internalType":"address"}],"stateMutability":"payable"},{"name":"feeRecipient","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"isToken","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"npm","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pendingOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"predictTokenAddress","type":"function","inputs":[{"name":"creator","type":"address","internalType":"address"},{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"userSalt","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"view"},{"name":"setAgentIdRegistry","type":"function","inputs":[{"name":"registry_","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setFeeRecipient","type":"function","inputs":[{"name":"feeRecipient_","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"tokensCount","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"v2Factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"v3Factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"version","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"pure"},{"name":"wbnb","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"withdrawFees","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"receive","stateMutability":"payable"}],"metadata":"{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"feeRecipient_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"registry_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"v2Factory_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"v3Factory_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"npm_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"wbnb_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidName\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidNpm\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRegistry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSymbol\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidV2Factory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidV3Factory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWbnb\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RenounceDisabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"registry\",\"type\":\"address\"}],\"name\":\"AgentIdRegistryUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeRecipient\",\"type\":\"address\"}],\"name\":\"FeeRecipientUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FeesWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"metaHash\",\"type\":\"bytes32\"}],\"name\":\"TokenCreated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"agentIdRegistry\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"allTokens\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"metaHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"userSalt\",\"type\":\"bytes32\"}],\"name\":\"createToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isToken\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"npm\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"userSalt\",\"type\":\"bytes32\"}],\"name\":\"predictTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"registry_\",\"type\":\"address\"}],\"name\":\"setAgentIdRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"feeRecipient_\",\"type\":\"address\"}],\"name\":\"setFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tokensCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"v2Factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"v3Factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"wbnb\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"OwnableInvalidOwner(address)\":[{\"details\":\"The owner is not a valid owner account. (eg. `address(0)`)\"}],\"OwnableUnauthorizedAccount(address)\":[{\"details\":\"The caller account is not authorized to perform an operation.\"}]},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"renounceOwnership()\":{\"notice\":\"Disabled: renouncing would freeze `feeRecipient` and the registry forever.\"},\"setAgentIdRegistry(address)\":{\"notice\":\"Only affects tokens created after the change.\"},\"setFeeRecipient(address)\":{\"notice\":\"Also redirects graduated v2 tokens' outer-market fees (they read feeRecipient at collect time).\"},\"version()\":{\"notice\":\"Factory generation; v1 (AgentPadFactory) has no version() and is treated as 1.\"},\"withdrawFees()\":{\"notice\":\"Anyone may call; funds only ever go to `feeRecipient`.\"}},\"notice\":\"v2 factory: same as AgentPadFactory (v1) except tokens graduate into PancakeSwap V3         (falling back to v1-style Pancake V2 graduation when the V3 pool is not clean).\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/AgentPadFactoryV2.sol\":\"AgentPadFactoryV2\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/=lib/openzeppelin-contracts/\",\":ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/\"]},\"sources\":{\"lib/openzeppelin-contracts/contracts/access/Ownable.sol\":{\"keccak256\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8ed324d3920bb545059d66ab97d43e43ee85fd3bd52e03e401f020afb0b120f6\",\"dweb:/ipfs/QmfEckWLmZkDDcoWrkEvMWhms66xwTLff9DDhegYpvHo1a\"]},\"lib/openzeppelin-contracts/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xdcad8898fda432696597752e8ec361b87d85c82cb258115427af006dacf7128c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e2c9d517f0c136d54bd00cd57959d25681d4d6273f5bbbc263afe228303772f0\",\"dweb:/ipfs/QmReNFjXBiufByiAAzfSQ2SM5r3qeUErn46BmN3yVRvrek\"]},\"lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol\":{\"keccak256\":\"0x880da465c203cec76b10d72dbd87c80f387df4102274f23eea1f9c9b0918792b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://399594cd8bb0143bc9e55e0f1d071d0d8c850a394fb7a319d50edd55d9ed822b\",\"dweb:/ipfs/QmbPZzgtT6LEm9CMqWfagQFwETbV1ztpECBB1DtQHrKiRz\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0xbf61ab2ae1d575a17ea58fbb99ca232baddcc4e0eeea180e84cbc74b0c348b31\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4e0968705bad99747a8e5288aa008678c2be2f471f919dce3925a3cc4f1dee09\",\"dweb:/ipfs/QmbAFnCQfo4tw6ssfQSjhA5LzwHWNNryXN8bX7ty8jiqqn\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xe06a3f08a987af6ad2e1c1e774405d4fe08f1694b67517438b467cecf0da0ef7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://df6f0c459663c9858b6cba2cda1d14a7d05a985bed6d2de72bd8e78c25ee79db\",\"dweb:/ipfs/QmeTTxZ7qVk9rjEv2R4CpCwdf8UMCcRqDNMvzNxHc3Fnn9\"]},\"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x70f2f713b13b7ce4610bcd0ac9fec0f3cc43693b043abcb8dc40a42a726eb330\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c13d13304ac79a83ab1c30168967d19e2203342ebbd6a9bbce4db7550522dcbf\",\"dweb:/ipfs/QmeN5jKMN2vw5bhacr6tkg78afbTTZUeaacNHqjWt4Ew1r\"]},\"lib/openzeppelin-contracts/contracts/utils/Context.sol\":{\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12\",\"dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF\"]},\"lib/openzeppelin-contracts/contracts/utils/Panic.sol\":{\"keccak256\":\"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a\",\"dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG\"]},\"lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0x11a5a79827df29e915a12740caf62fe21ebe27c08c9ae3e09abe9ee3ba3866d3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://3cf0c69ab827e3251db9ee6a50647d62c90ba580a4d7bbff21f2bea39e7b2f4a\",\"dweb:/ipfs/QmZiKwtKU1SBX4RGfQtY7PZfiapbbu6SZ9vizGQD9UHjRA\"]},\"lib/openzeppelin-contracts/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xa00be322d7db5786750ce0ac7e2f5b633ac30a5ed5fa1ced1e74acfc19acecea\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6c84e822f87cbdc4082533b626667b6928715bb2b1e8e7eb96954cebb9e38c8d\",\"dweb:/ipfs/QmZmy9dgxLTerBAQDuuHqbL6EpgRxddqgv5KmwpXYVbKz1\"]},\"lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x195533c86d0ef72bcc06456a4f66a9b941f38eb403739b00f21fd7c1abd1ae54\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b1d578337048cad08c1c03041cca5978eff5428aa130c781b271ad9e5566e1f8\",\"dweb:/ipfs/QmPFKL2r9CBsMwmUqqdcFPfHZB2qcs9g1HDrPxzWSxomvy\"]},\"src/AgentPadFactoryV2.sol\":{\"keccak256\":\"0xf4a687bfa784737f96e24d14e873c58ad39ed46b3a9d3d3612d83d8232fb1d43\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://d06a027bb1592ba87ebc069e11ea8fb611570fcbfab5074bce80186dbb3e5501\",\"dweb:/ipfs/QmRikNn6rNAgoZUp5xpGfnv5Tq4LhWn1gAfz8hBb7nA6hk\"]},\"src/AgentPadTokenV3.sol\":{\"keccak256\":\"0xb8795555c6115f19438a8e1ccef54e41bf280d3cec339d135392cdda156a6042\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4e94d7fa47b97b6cb7cd5048db54f8b94e2f8716f17fc7d0290cb4e7383e9bd5\",\"dweb:/ipfs/QmZazoQFdpPjRETBMeNky85S2T1BjBeTEgSJJE72oewZxV\"]},\"src/CurveMath.sol\":{\"keccak256\":\"0xbf8f246a9dba28f601abeac7b5baddbede4fb2f0c5f4ef91e41e35bdb9ea2ee0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://de25122071af69716e06eb24b48346dc7a706805f7be03a72e2541b381570a72\",\"dweb:/ipfs/QmZ25TYdBFxoX6gscnvn7ASTivHSAjR1bX9Zp1W5SC6JLZ\"]},\"src/V3PathLib.sol\":{\"keccak256\":\"0x5b1f7f652ff66593236eed32f4b4e1ac64f409c3410c68de70526302906040c9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://64a611bff8e0f78ffd1767afcc0b6cc6965259033c86b39131c5078446080fc9\",\"dweb:/ipfs/QmYGxdAd3gn92LkhYBTg14VMEoDT8HHGDazY2XzMAuvWeB\"]},\"src/interfaces/IAgentIdRegistry.sol\":{\"keccak256\":\"0xb8cdaef0addc1f11c5327227aa35c430250c8502c2aa39cd4ad737c8179d79d8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://df683f34056173cc6c758bdf12534d77e27f12c186a75159f35d82e79235990d\",\"dweb:/ipfs/QmU596PJaZ7ZTGqRSnpJaJwbGrVxzbWLqLRG3yYkaNQFPD\"]},\"src/interfaces/IAgentPadFactory.sol\":{\"keccak256\":\"0x83ff4223b86a398e4d1a006da4e9ff48dce1f16a076e07ea479f0188aca4d83c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a5db3d9d78a5ab65e50be5bbf134f621a3291a70ee8acf55d705575d41b59e83\",\"dweb:/ipfs/QmVD9XEz3SCF3F6LtLG3wc1sAZxw8JBAivkhonJMPNU7tS\"]},\"src/interfaces/IPancakeV2.sol\":{\"keccak256\":\"0x0379f5f3a23bc6656f251addf4ffe3cf65155a4c14c823be441b02ff0f209b60\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a23d7b51d41adf43aa3e6d6ca51f9e43fbca4dccb9f802086750485e0ba761c5\",\"dweb:/ipfs/QmUnFq86TwokmUG8rLtggy4gQanqBccA13ExknhwY8XMyb\"]},\"src/interfaces/IPancakeV3.sol\":{\"keccak256\":\"0x672dd1db34d5e607df818a24099cedfa545a482e031f3c9efb90c7fe8a105fd1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://628d1a9f990af1da6895e42e42bda78a55e962813105dffe07435ccf73d0261d\",\"dweb:/ipfs/QmSyPKDitGz2UyAMiMpNQBZRGLMaFEiZqHbtb1inu7PoyW\"]},\"src/interfaces/IWBNB.sol\":{\"keccak256\":\"0x292ab1d3bc1b513abbc2f19581673a6d4e41f918c958e175350e4c446aa9d486\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://bf3a7115048e62cefea6c74da305093a0b034cd477b9e5fabdfe1af7f5b439d4\",\"dweb:/ipfs/QmT1zWqNpicYy9eBPA4WcZ9wDo8JJEzab8wpwFfbyH6AgE\"]}},\"version\":1}","userdoc":{"kind":"user","notice":"v2 factory: same as AgentPadFactory (v1) except tokens graduate into PancakeSwap V3         (falling back to v1-style Pancake V2 graduation when the V3 pool is not clean).","methods":{"version()":{"notice":"Factory generation; v1 (AgentPadFactory) has no version() and is treated as 1."},"withdrawFees()":{"notice":"Anyone may call; funds only ever go to `feeRecipient`."},"renounceOwnership()":{"notice":"Disabled: renouncing would freeze `feeRecipient` and the registry forever."},"setFeeRecipient(address)":{"notice":"Also redirects graduated v2 tokens' outer-market fees (they read feeRecipient at collect time)."},"setAgentIdRegistry(address)":{"notice":"Only affects tokens created after the change."}},"version":1},"devdoc":{"kind":"dev","errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"OwnableUnauthorizedAccount(address)":[{"details":"The caller account is not authorized to perform an operation."}]},"methods":{"owner()":{"details":"Returns the address of the current owner."},"pendingOwner()":{"details":"Returns the address of the pending owner."},"acceptOwnership()":{"details":"The new owner accepts the ownership transfer."},"transferOwnership(address)":{"details":"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner. Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer."}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_mapping(t_address,t_bool)":{"key":"t_address","label":"mapping(address => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"},"t_array(t_address)dyn_storage":{"base":"t_address","label":"address[]","encoding":"dynamic_array","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":8,"label":"_owner","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"1","type":"t_address","astId":156,"label":"_pendingOwner","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"2","type":"t_address","astId":4579,"label":"feeRecipient","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"3","type":"t_address","astId":4581,"label":"agentIdRegistry","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"4","type":"t_array(t_address)dyn_storage","astId":4584,"label":"allTokens","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"},{"slot":"5","type":"t_mapping(t_address,t_bool)","astId":4588,"label":"isToken","offset":0,"contract":"src/AgentPadFactoryV2.sol:AgentPadFactoryV2"}]},"transientStorageLayout":{"types":null,"storage":[]},"evm":{"bytecode":{"object":"610100604052348015610010575f5ffd5b5060405161575a38038061575a83398101604081905261002f9161033f565b866001600160a01b03811661005d57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b610066816102b9565b506001600160a01b03861661008e5760405163d92e233d60e01b815260040160405180910390fd5b846001600160a01b03163b5f036100b8576040516311a1e69760e01b815260040160405180910390fd5b836001600160a01b03163b5f036100e257604051633647040f60e01b815260040160405180910390fd5b826001600160a01b03163b5f0361010c57604051639a11fb3160e01b815260040160405180910390fd5b816001600160a01b03163b5f036101365760405163037e6a8560e01b815260040160405180910390fd5b806001600160a01b03163b5f036101605760405163614e3ba560e11b815260040160405180910390fd5b826001600160a01b0316826001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a6573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101ca91906103c0565b6001600160a01b03161415806102515750806001600160a01b0316826001600160a01b0316634aa4a4fc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610221573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024591906103c0565b6001600160a01b031614155b1561026f5760405163037e6a8560e01b815260040160405180910390fd5b600280546001600160a01b03199081166001600160a01b03988916179091556003805490911695871695909517909455918416608052831660a052821660c0521660e052506103e0565b600180546001600160a01b03191690556102d2816102d5565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b038116811461033a575f5ffd5b919050565b5f5f5f5f5f5f5f60e0888a031215610355575f5ffd5b61035e88610324565b965061036c60208901610324565b955061037a60408901610324565b945061038860608901610324565b935061039660808901610324565b92506103a460a08901610324565b91506103b260c08901610324565b905092959891949750929550565b5f602082840312156103d0575f5ffd5b6103d982610324565b9392505050565b60805160a05160c05160e05161530f61044b5f395f81816102e5015281816104c401526106ee01525f8181610293015281816104a301526106cc01525f81816102600152818161048201526106aa01525f8181610348015281816104610152610688015261530f5ff3fe60806040526004361061011e575f3560e01c80637f1e9ef61161009d578063b4b57c3911610062578063b4b57c3914610337578063bdaad4881461036a578063e30c397814610389578063e74b981b146103a6578063f2fde38b146103c5575f5ffd5b80637f1e9ef6146102825780638854a0ff146102b55780638d72647e146102d45780638da5cb5b14610307578063a64ed8ba14610323575f5ffd5b806354fd4d50116100e357806354fd4d50146101eb578063634282af14610208578063715018a61461022757806379ba50971461023b5780637c887c591461024f575f5ffd5b806319f3736114610129578063266cedb31461016c5780633a5fedb71461019757806346904840146101b6578063476343ee146101d5575f5ffd5b3661012557005b5f5ffd5b348015610134575f5ffd5b50610157610143366004610b78565b60056020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61017f61017a366004610bdd565b6103e4565b6040516001600160a01b039091168152602001610163565b3480156101a2575f5ffd5b5061017f6101b1366004610c5a565b610644565b3480156101c1575f5ffd5b5060025461017f906001600160a01b031681565b3480156101e0575f5ffd5b506101e96107be565b005b3480156101f6575f5ffd5b5060025b604051908152602001610163565b348015610213575f5ffd5b5061017f610222366004610ce2565b61087d565b348015610232575f5ffd5b506101e96108a5565b348015610246575f5ffd5b506101e96108c6565b34801561025a575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561028d575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c0575f5ffd5b5060035461017f906001600160a01b031681565b3480156102df575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610312575f5ffd5b505f546001600160a01b031661017f565b34801561032e575f5ffd5b506004546101fa565b348015610342575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610375575f5ffd5b506101e9610384366004610b78565b61090f565b348015610394575f5ffd5b506001546001600160a01b031661017f565b3480156103b1575f5ffd5b506101e96103c0366004610b78565b610996565b3480156103d0575f5ffd5b506101e96103df366004610b78565b610a13565b5f8515806103f25750604086115b156104105760405163430f13b360e01b815260040160405180910390fd5b83158061041d5750601084115b1561043b5760405163010466f160e21b815260040160405180910390fd5b6104453383610a83565b878787873360035f9054906101000a90046001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006040516104ef90610b50565b6105029a99989796959493929190610d21565b8190604051809103905ff590508015801561051f573d5f5f3e3d5ffd5b506004805460018082019092557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0384169081179091555f8181526005602052604090819020805460ff1916909317909255905191925033917f5314f94e6e2d1a502483a5b446938dee47de600f90cbf915d89632d58a71aa2b906105c1908b908b908b908b908b90610d8e565b60405180910390a3341561063a5760405162de16a360e71b81523360048201526001600160a01b03821690636f0b518090349060240160206040518083038185885af1158015610613573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106389190610dc7565b505b9695505050505050565b5f5f6040518060200161065690610b50565b601f1982820381018352601f909101166040819052600354610716918a918a918a918a918f916001600160a01b0316907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090602001610d21565b60408051601f19818403018152908290526107349291602001610df5565b60405160208183030381529060405280519060200120905060ff60f81b3061075c8a86610a83565b6040516001600160f81b031993909316602084015260609190911b6bffffffffffffffffffffffff1916602183015260358201526055810182905260750160408051601f19818403018152919052805160209091012098975050505050505050565b60025460405147915f916001600160a01b039091169083908381818185875af1925050503d805f811461080c576040519150601f19603f3d011682016040523d82523d5f602084013e610811565b606091505b5050905080610833576040516312171d8360e31b815260040160405180910390fd5b600254604080516001600160a01b039092168252602082018490527fc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a910160405180910390a15050565b6004818154811061088c575f80fd5b5f918252602090912001546001600160a01b0316905081565b6108ad610abf565b604051638905116560e01b815260040160405180910390fd5b60015433906001600160a01b031681146109035760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61090c81610aed565b50565b610917610abf565b806001600160a01b03163b5f03610941576040516311a1e69760e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f1386da33541fecf49b0f53895aef3f30f6e3e08755deb017e106e7ae4f4c976d906020015b60405180910390a150565b61099e610abf565b6001600160a01b0381166109c55760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f7a7b5a0a132f9e0581eb8527f66eae9ee89c2a3e79d4ac7e41a1f1f4d48a7fc29060200161098b565b610a1b610abf565b600180546001600160a01b0383166001600160a01b03199091168117909155610a4b5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b03841660208201529081018290525f9060600160405160208183030381529060405280519060200120905092915050565b5f546001600160a01b03163314610aeb5760405163118cdaa760e01b81523360048201526024016108fa565b565b600180546001600160a01b031916905561090c815f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6144c880610e1283390190565b80356001600160a01b0381168114610b73575f5ffd5b919050565b5f60208284031215610b88575f5ffd5b610b9182610b5d565b9392505050565b5f5f83601f840112610ba8575f5ffd5b50813567ffffffffffffffff811115610bbf575f5ffd5b602083019150836020828501011115610bd6575f5ffd5b9250929050565b5f5f5f5f5f5f60808789031215610bf2575f5ffd5b863567ffffffffffffffff811115610c08575f5ffd5b610c1489828a01610b98565b909750955050602087013567ffffffffffffffff811115610c33575f5ffd5b610c3f89828a01610b98565b979a9699509760408101359660609091013595509350505050565b5f5f5f5f5f5f60808789031215610c6f575f5ffd5b610c7887610b5d565b9550602087013567ffffffffffffffff811115610c93575f5ffd5b610c9f89828a01610b98565b909650945050604087013567ffffffffffffffff811115610cbe575f5ffd5b610cca89828a01610b98565b979a9699509497949695606090950135949350505050565b5f60208284031215610cf2575f5ffd5b5035919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b61010081525f610d3661010083018c8e610cf9565b8281036020840152610d49818b8d610cf9565b6001600160a01b03998a16604085015297891660608401525050938616608085015291851660a0840152841660c083015290921660e090920191909152949350505050565b606081525f610da1606083018789610cf9565b8281036020840152610db4818688610cf9565b9150508260408301529695505050505050565b5f60208284031215610dd7575f5ffd5b5051919050565b5f81518060208401855e5f93019283525090919050565b5f610e09610e038386610dde565b84610dde565b94935050505056fe6101a0604052348015610010575f5ffd5b506040516144c83803806144c883398101604081905261002f91610877565b8787600361003d83826109cb565b50600461004a82826109cb565b5050600160055550336080526001600160a01b0386811660a05285811660c05284811660e0528381166101008190528382166101205290821661014081905230818110610160819052604051630b4c774160e11b815260048101929092526024820192909252612710604482015290915f91631698ee8290606401602060405180830381865afa1580156100e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101049190610a85565b90506001600160a01b03811661018e5760405163a167129560e01b81523060048201526001600160a01b038481166024830152612710604483015286169063a1671295906064016020604051808303815f875af1158015610167573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061018b9190610a85565b90505b806001600160a01b0316610180816001600160a01b0316815250505f816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156101e6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061020a9190610ab1565b5050505050509050806001600160a01b03165f0361028f576001600160a01b03821663f637731d61023a856102b5565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f604051808303815f87803b158015610278575f5ffd5b505af115801561028a573d5f5f3e3d5ffd5b505050505b6102a5306b033b2e3c9fd0803ce8000000610318565b5050505050505050505050610bd4565b5f806102cc6b0295be96e640669720000000610355565b9050826102f7576102f26102ed670de0b6b3a7640000600160c01b846103bb565b610471565b610311565b6103116102ed82600160c01b670de0b6b3a76400006103bb565b9392505050565b6001600160a01b0382166103465760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6103515f83836105c9565b5050565b5f8061036083610649565b905061036c8180610b64565b61038d6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b61039f90674a03ce68d2155555610b64565b6103b190670de0b6b3a7640000610b64565b6103119190610ba2565b5f838302815f1985870982811083820303915050805f036103ef578382816103e5576103e5610b8e565b0492505050610311565b80841161040657610406600385150260111861067c565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f6001821161047e575090565b816001600160801b82106104975760809190911c9060401b5b6801000000000000000082106104b25760409190911c9060201b5b64010000000082106104c95760209190911c9060101b5b6201000082106104de5760109190911c9060081b5b61010082106104f25760089190911c9060041b5b601082106105055760049190911c9060021b5b600482106105115760011b5b600302600190811c9081858161052957610529610b8e565b048201901c9050600181858161054157610541610b8e565b048201901c9050600181858161055957610559610b8e565b048201901c9050600181858161057157610571610b8e565b048201901c9050600181858161058957610589610b8e565b048201901c905060018185816105a1576105a1610b8e565b048201901c90506105c08185816105ba576105ba610b8e565b04821190565b90039392505050565b60065460ff161580156105e457506001600160a01b03831615155b80156105f957506001600160a01b0383163014155b801561061b575060ff5f5c16801561061957506001600160a01b03821630145b155b1561063957604051632b36b06160e01b815260040160405180910390fd5b61064483838361068d565b505050565b5f8161066c6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b6106769190610bc1565b92915050565b634e487b715f52806020526024601cfd5b6001600160a01b0383166106b7578060025f8282546106ac9190610b7b565b909155506107279050565b6001600160a01b0383165f90815260208190526040902054818110156107095760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161033d565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661074357600280548290039055610761565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107a691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126107d6575f5ffd5b81516001600160401b038111156107ef576107ef6107b3565b604051601f8201601f19908116603f011681016001600160401b038111828210171561081d5761081d6107b3565b604052818152838201602001851015610834575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b6001600160a01b0381168114610864575f5ffd5b50565b805161087281610850565b919050565b5f5f5f5f5f5f5f5f610100898b03121561088f575f5ffd5b88516001600160401b038111156108a4575f5ffd5b6108b08b828c016107c7565b60208b015190995090506001600160401b038111156108cd575f5ffd5b6108d98b828c016107c7565b97505060408901516108ea81610850565b60608a01519096506108fb81610850565b60808a015190955061090c81610850565b60a08a015190945061091d81610850565b925061092b60c08a01610867565b915061093960e08a01610867565b90509295985092959890939650565b600181811c9082168061095c57607f821691505b60208210810361097a57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561064457805f5260205f20601f840160051c810160208510156109a55750805b601f840160051c820191505b818110156109c4575f81556001016109b1565b5050505050565b81516001600160401b038111156109e4576109e46107b3565b6109f8816109f28454610948565b84610980565b6020601f821160018114610a2a575f8315610a135750848201515b5f19600385901b1c1916600184901b1784556109c4565b5f84815260208120601f198516915b82811015610a595787850151825560209485019460019092019101610a39565b5084821015610a7657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215610a95575f5ffd5b815161031181610850565b805161ffff81168114610872575f5ffd5b5f5f5f5f5f5f5f60e0888a031215610ac7575f5ffd5b8751610ad281610850565b8097505060208801518060020b8114610ae9575f5ffd5b9550610af760408901610aa0565b9450610b0560608901610aa0565b9350610b1360808901610aa0565b925060a088015163ffffffff81168114610b2b575f5ffd5b60c08901519092508015158114610b40575f5ffd5b8091505092959891949750929550565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761067657610676610b50565b8082018082111561067657610676610b50565b634e487b7160e01b5f52601260045260245ffd5b5f82610bbc57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561067657610676610b50565b60805160a05160c05160e051610100516101205161014051610160516101805161377e610d4a5f395f8181610376015281816109ec01528181611ea10152612d0f01525f81816104f20152818161098b01528181610ecf01528181611ec6015281816121ae015281816123f50152612cb701525f81816106770152818161187701528181612388015281816124850152818161254b0152818161258c015281816126f4015281816127a0015281816128620152818161293d015281816129e901528181612dcf01528181612e6b0152612f9801525f81816105df01528181610e600152818161241a015281816124560152818161250b0152818161268a015281816126c601528181612d650152612da101525f6105ac01525f8181610763015281816127ca015261288a01525f81816106120152610b0101525f81816102b20152610aa701525f81816107aa01528181610c3201528181610d740152818161119c015281816114820152612ed9015261377e5ff3fe608060405260043610610275575f3560e01c806371640de31161014a578063a8aa1b31116100be578063cd3293de11610078578063cd3293de146107e0578063d3618cca146107f4578063dd62ed3e14610808578063e4849b321461084c578063e7c2b7721461086b578063f6ccbda514610884575f5ffd5b8063a8aa1b3114610714578063a9059cbb14610733578063b4b57c3914610752578063b956993b14610785578063c45a015514610799578063c8796572146107cc575f5ffd5b80638d4b66c01161010f5780638d4b66c0146106475780638d72647e1461066657806395d89b41146106995780639c43a050146106ad578063a6195fd3146106c1578063a64190c4146106e0575f5ffd5b806371640de3146105865780637c887c591461059b5780637f1e9ef6146105ce5780638854a0ff146106015780638976254314610634575f5ffd5b806323b872dd116101ec5780635c1624ef116101a65780635c1624ef146104af5780635ed0447d146104c2578063604b1eba146104e1578063667022fd146105145780636f0b51801461053f57806370a0823114610552575f5ffd5b806323b872dd146103e9578063313ce56714610408578063398482d8146104295780634beb394c1461043d578063559f05dc1461047c578063577bd3361461049b575f5ffd5b806316e457f01161023d57806316e457f01461035157806316f0115b1461036557806318160ddd1461039857806320cce74b146103ac57806320f1fc61146103c057806323a69e75146103c8575f5ffd5b806302c7e7af1461027957806302d05d3f146102a157806303fd2a45146102ec57806306fdde0314610301578063095ea7b314610322575b5f5ffd5b348015610284575f5ffd5b5061028e60075481565b6040519081526020015b60405180910390f35b3480156102ac575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610298565b3480156102f7575f5ffd5b506102d461dead81565b34801561030c575f5ffd5b506103156108a2565b604051610298919061319c565b34801561032d575f5ffd5b5061034161033c3660046131e5565b610932565b6040519015158152602001610298565b34801561035c575f5ffd5b5061028e61094b565b348015610370575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a3575f5ffd5b5060025461028e565b3480156103b7575f5ffd5b506102d4610985565b61028e6109b4565b3480156103d3575f5ffd5b506103e76103e236600461320f565b6109d1565b005b3480156103f4575f5ffd5b5061034161040336600461328b565b610a47565b348015610413575f5ffd5b5060125b60405160ff9091168152602001610298565b348015610434575f5ffd5b5061028e610a6c565b348015610448575f5ffd5b5061045c6104573660046132c9565b610a78565b604080519485526020850193909352918301526060820152608001610298565b348015610487575f5ffd5b506103416104963660046132e0565b610a95565b3480156104a6575f5ffd5b5061028e610b73565b61028e6104bd3660046132c9565b610b9b565b3480156104cd575f5ffd5b5061045c6104dc3660046131e5565b610bc9565b3480156104ec575f5ffd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b34801561051f575f5ffd5b5061028e61052e3660046132e0565b60086020525f908152604090205481565b61028e61054d3660046132e0565b610c1e565b34801561055d575f5ffd5b5061028e61056c3660046132e0565b6001600160a01b03165f9081526020819052604090205490565b348015610591575f5ffd5b5061028e60095481565b3480156105a6575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d9575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561060c575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561063f575f5ffd5b506104175f81565b348015610652575f5ffd5b5061028e6106613660046132e0565b610c9f565b348015610671575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a4575f5ffd5b50610315610ccc565b3480156106b8575f5ffd5b50610417600281565b3480156106cc575f5ffd5b5061028e6106db3660046132fb565b610cdb565b3480156106eb575f5ffd5b506106ff6106fa3660046132c9565b610d04565b60408051928352602083019190915201610298565b34801561071f575f5ffd5b50600a546102d4906001600160a01b031681565b34801561073e575f5ffd5b5061034161074d3660046131e5565b610d2f565b34801561075d575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b348015610790575f5ffd5b50610417600181565b3480156107a4575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d7575f5ffd5b506106ff610d3c565b3480156107eb575f5ffd5b5061028e610f57565b3480156107ff575f5ffd5b506103e7610f63565b348015610813575f5ffd5b5061028e61082236600461331b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610857575f5ffd5b5061028e6108663660046132c9565b610fbd565b348015610876575f5ffd5b506006546103419060ff1681565b34801561088f575f5ffd5b5060065461041790610100900460ff1681565b6060600380546108b190613352565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90613352565b80156109285780601f106108ff57610100808354040283529160200191610928565b820191905f5260205f20905b81548152906001019060200180831161090b57829003601f168201915b5050505050905090565b5f3361093f818585610fda565b60019150505b92915050565b5f610954610fec565b61095d33611016565b335f818152602081905260408120546109769291611063565b90506109826001600555565b90565b5f6109af7f00000000000000000000000000000000000000000000000000000000000000006112a4565b905090565b5f6109bd610fec565b6109c633611016565b61097633345f611300565b60ff6101005f5c04161580610a0f5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b80610a1957508315155b80610a2357508215155b15610a415760405163f7a632f560e01b815260040160405180910390fd5b50505050565b5f33610a54858285611593565b610a5f85858561160d565b60019150505b9392505050565b5f6109af60075461166a565b5f5f5f5f610a863386610bc9565b93509350935093509193509193565b6006545f9060ff1615801561094557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061094557506040516370a0823160e01b81526001600160a01b0383811660048301525f917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015610b48573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6c919061338a565b1192915050565b5f6b0295be96e640669720000000600754612710610b9191906133b5565b6109af91906133e0565b5f610ba4610fec565b610bad33611016565b610bb8333484611300565b9050610bc46001600555565b919050565b6006545f9081908190819060ff1615610bec57505f925082915081905083610c15565b610bf686866116cf565b9195509350915081610c0884876133f3565b610c1291906133f3565b90505b92959194509250565b5f610c27610fec565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c7057604051630636a15760e11b815260040160405180910390fd5b60065460ff1615610c945760405163e6a0d45f60e01b815260040160405180910390fd5b610bb882345f611300565b6001600160a01b0381165f90815260086020526040812054610945906a18d0bf423c03d8de0000006133f3565b6060600480546108b190613352565b5f610ce4610fec565b610ced33611016565b610cf8338484611063565b90506109456001600555565b6006545f90819060ff1615610d1d57505f928392509050565b610d26836117a6565b91509150915091565b5f3361093f81858561160d565b5f5f610d46610fec565b600654610100900460ff16600114610d71576040516330aad80b60e01b815260040160405180910390fd5b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dce573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df29190613406565b6040805160808101825260095481526001600160a01b03838116602083019081526001600160801b0383850181815260608501828152955163fc6f786560e01b815294516004860152915183166024850152905181166044840152925190921660648201529192505f9182917f0000000000000000000000000000000000000000000000000000000000000000169063fc6f78659060840160408051808303815f875af1158015610ea5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ec99190613421565b915091507f0000000000000000000000000000000000000000000000000000000000000000610ef9578082610efc565b81815b60408051838152602081018390529297509095506001600160a01b038516917f2e4fb6077d4acf86e12bb7411fb82b2b3eaa6a49787f4b1e17b423e7ea841169910160405180910390a2505050610f536001600555565b9091565b5f6109af600754611807565b610f6b610fec565b60065460ff1680610f8a57506b0295be96e64066972000000060075414155b15610fa8576040516325a6766f60e21b815260040160405180910390fd5b610fb15f611860565b610fbb6001600555565b565b5f610fc6610fec565b610fcf33611016565b610bb833835f611063565b610fe78383836001611909565b505050565b60026005540361100f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600555565b60065460ff161561103a5760405163e6a0d45f60e01b815260040160405180910390fd5b61104381610a95565b61106057604051637c75aa6f60e11b815260040160405180910390fd5b50565b5f825f036110845760405163617ab12d60e11b815260040160405180910390fd5b6001600160a01b0384165f908152602081905260409020548311156110bc57604051631e9acf1760e31b815260040160405180910390fd5b5f6110c6846117a6565b90925090505f8290036110ec5760405163617ab12d60e11b815260040160405180910390fd5b8282101561110d57604051638199f5f360e01b815260040160405180910390fd5b5f8460075461111c91906133f3565b6007819055905060015f805c60ff19168217905d5061113c86308761160d565b5f60ff19815c16815d506040805186815260208101859052908101839052606081018290526001600160a01b038716907f483f8aec0fd892ac72ad1ba8d0e9c9e73db59c12d263fd71de480b5b3deeae3c9060800160405180910390a25f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611202576040519150601f19603f3d011682016040523d82523d5f602084013e611207565b606091505b505090508061122957604051634033e4e360e01b815260040160405180910390fd5b5f876001600160a01b0316856040515f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b505090508061129957604051630ec6ac4160e21b815260040160405180910390fd5b505050509392505050565b5f5f6112bb6b0295be96e64066972000000061166a565b9050826112e6576112e16112dc670de0b6b3a7640000600160c01b846119db565b611a91565b610a65565b610a656112dc82600160c01b670de0b6b3a76400006119db565b5f5f5f61130d86866116cf565b919450925090505f839003611377576001600160a01b0386165f908152600860205260409020546a18d0bf423c03d8de0000001161135e57604051636bf4c8e960e11b815260040160405180910390fd5b60405163617ab12d60e11b815260040160405180910390fd5b8383101561139857604051638199f5f360e01b815260040160405180910390fd5b5f836007546113a79190613443565b60078190556001600160a01b0388165f908152600860205260408120805492935086929091906113d8908490613443565b909155506113e9905030888661160d565b6040805184815260208101849052908101859052606081018290526001600160a01b038816907f064fb1933e186be0b289a87e98518dc18cc9856ecbc9f1353d1a138ddf733ec59060800160405180910390a25f8261144885896133f3565b61145291906133f3565b90506b0295be96e6406697200000008203611479576114796114748285613443565b611860565b8215611511575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846040515f6040518083038185875af1925050503d805f81146114e8576040519150601f19603f3d011682016040523d82523d5f602084013e6114ed565b606091505b505090508061150f57604051634033e4e360e01b815260040160405180910390fd5b505b8015611299575f886001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611560576040519150601f19603f3d011682016040523d82523d5f602084013e611565565b606091505b505090508061158757604051633c31275160e21b815260040160405180910390fd5b50505050509392505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f198114610a4157818110156115ff57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b610a4184848484035f611909565b6001600160a01b03831661163657604051634b637e8f60e11b81525f60048201526024016115f6565b6001600160a01b03821661165f5760405163ec442f0560e01b81525f60048201526024016115f6565b610fe7838383611be9565b5f5f61167583611c64565b905061168181806133b5565b6116a16a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b6116b390674a03ce68d21555556133b5565b6116c590670de0b6b3a76400006133b5565b610a6591906133e0565b6007545f9081908190816116e66064612710613443565b6116f2612710886133b5565b6116fc91906133e0565b90506117088282611c86565b94505f611721836b0295be96e6406697200000006133f3565b90508086111561172f578095505b6001600160a01b0388165f9081526008602052604081205461175c906a18d0bf423c03d8de0000006133f3565b90508087111561176a578096505b865f03611783575f5f5f9650965096505050505061179f565b61178d8488611d58565b955061179886611dfa565b9450505050505b9250925092565b6007545f9081908315806117b957508084115b156117c957505f93849350915050565b5f6117d48286611e2a565b90506117df81611dfa565b92508281116117f457505f9485945092505050565b6117fe83826133f3565b93505050915091565b5f674a03ce68d215555561181a83611c64565b61183a6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b61184c90674a03ce68d21555556133b5565b61185691906133e0565b61094591906133f3565b6006805460ff191660011790556001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d0e30db06118a683476133f3565b6040518263ffffffff1660e01b81526004015f604051808303818588803b1580156118cf575f5ffd5b505af11580156118e1573d5f5f3e3d5ffd5b50505050506118ee611e9e565b80156118fd57506118fd612355565b61106057611060612783565b6001600160a01b0384166119325760405163e602df0560e01b81525f60048201526024016115f6565b6001600160a01b03831661195b57604051634a1406b160e11b81525f60048201526024016115f6565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015610a4157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516119cd91815260200190565b60405180910390a350505050565b5f838302815f1985870982811083820303915050805f03611a0f57838281611a0557611a056133cc565b0492505050610a65565b808411611a2657611a266003851502601118612b19565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f60018211611a9e575090565b816001600160801b8210611ab75760809190911c9060401b5b680100000000000000008210611ad25760409190911c9060201b5b6401000000008210611ae95760209190911c9060101b5b620100008210611afe5760109190911c9060081b5b6101008210611b125760089190911c9060041b5b60108210611b255760049190911c9060021b5b60048210611b315760011b5b600302600190811c90818581611b4957611b496133cc565b048201901c90506001818581611b6157611b616133cc565b048201901c90506001818581611b7957611b796133cc565b048201901c90506001818581611b9157611b916133cc565b048201901c90506001818581611ba957611ba96133cc565b048201901c90506001818581611bc157611bc16133cc565b048201901c9050611be0818581611bda57611bda6133cc565b04821190565b90039392505050565b60065460ff16158015611c0457506001600160a01b03831615155b8015611c1957506001600160a01b0383163014155b8015611c3b575060ff5f5c168015611c3957506001600160a01b03821630145b155b15611c5957604051632b36b06160e01b815260040160405180910390fd5b610fe7838383612b2a565b5f816118566a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f5f611c9184611c64565b90505f81611cb56a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611cc790674a03ce68d21555556133b5565b611cd191906133e0565b90505f611cde8583613443565b611cfe6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d1090674a03ce68d21555556133b5565b611d1a91906133e0565b9050611d27816001613443565b8311611d38575f9350505050610945565b6001611d4482856133f3565b611d4e91906133f3565b9695505050505050565b5f5f611d6384611c64565b905080611d866a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d9890674a03ce68d21555556133b5565b611da291906133e0565b611dac84836133f3565b611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611dde90674a03ce68d21555556133b5565b611de891906133e0565b611df291906133f3565b949350505050565b5f612710600181611e0c6064866133b5565b611e169190613443565b611e2091906133f3565b61094591906133e0565b5f5f611e3584611c64565b9050611e418382613443565b611e616a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611e7390674a03ce68d21555556133b5565b611e7d91906133e0565b81611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f7f000000000000000000000000000000000000000000000000000000000000000081611eea7f00000000000000000000000000000000000000000000000000000000000000006112a4565b9050816001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f28573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4c919061346c565b6001600160801b031615611f62575f9250505090565b5f826001600160a01b03166370cf754a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f9f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fc3919061346c565b90506c0c9f2c9cd04674edea400000006001600160801b0382161015611fec575f935050505090565b5f6120046c0c9f2c9cd04674edea4000000083613485565b60405163f30dba9360e01b8152620d899f1960048201529091506001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa158015612058573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061207c919061346c565b6001600160801b0316118061210b575060405163f30dba9360e01b8152620d89a060048201526001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa1580156120dc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612100919061346c565b6001600160801b0316115b1561211a575f94505050505090565b5f5f856001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015612158573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061217c91906134c4565b505050505091509150846001600160a01b0316826001600160a01b0316036121ab576001965050505050505090565b5f7f00000000000000000000000000000000000000000000000000000000000000006121da5762027e5c6121e0565b62027e5c195b90506121ed878383612c43565b156121ff575f97505050505050505090565b6001600160a01b0380871690841611600161ff00195f805c9190911661010017905d50604051630251596160e31b81523060048201528115156024820152600160448201526001600160a01b03888116606483015260a060848301525f60a483015289169063128acb089060c40160408051808303815f875af19250505080156122a6575060408051601f3d908101601f191682019092526122a391810190613421565b60015b6122c3575f61ff0019815c16815d505f9850505050505050505090565b50505f61ff0019815c16815d50876001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa15801561230c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061233091906134c4565b5050506001600160a01b0393841693909a16929092149b9a5050505050505050505050565b305f9081526020819052604081205481906040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156123cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123f1919061338a565b90507f000000000000000000000000000000000000000000000000000000000000000061243f307f000000000000000000000000000000000000000000000000000000000000000085610fda565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156124cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124ef919061355a565b505f6124fd6103e8856133e0565b61250790856133f3565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663883164566040518061016001604052808561256f577f0000000000000000000000000000000000000000000000000000000000000000612571565b305b6001600160a01b031681526020018561258a57306125ac565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b031681526127106020820152620d899f196040820152620d89a06060820152608001856125e057866125e2565b875b8152602001856125f257876125f4565b865b815260200185612604575f612606565b845b8152602001856126165784612618565b5f5b815230602082015242604091820152516001600160e01b031960e084901b1681526126469190600401613573565b6080604051808303815f875af1925050508015612680575060408051601f3d908101601f1916820190925261267d91810190613637565b60015b612769576126af307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af115801561273a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275e919061355a565b505f94505050505090565b612774848383612c9f565b60019850505050505050505090565b60405163e6a4390560e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015612811573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128359190613406565b90506001600160a01b0381166128f7576040516364e329cb60e11b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063c9c65396906044016020604051808303815f875af11580156128d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128f49190613406565b90505b600a80546001600160a01b0319166001600160a01b03838116919091179091556006805461ff0019166102001790556040516370a0823160e01b81523060048201525f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612982573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129a6919061338a565b305f818152602081905260409020549192506129c390848361160d565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612a2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a53919061355a565b506040516335313c2160e11b815261dead60048201526001600160a01b03841690636a627842906024016020604051808303815f875af1158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd919061338a565b5060408051600281525f6020820152908101829052606081018390526001600160a01b0384169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe3906080015b60405180910390a3505050565b634e487b715f52806020526024601cfd5b6001600160a01b038316612b54578060025f828254612b499190613443565b90915550612bc49050565b6001600160a01b0383165f9081526020819052604090205481811015612ba65760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016115f6565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612be057600280548290039055612bfe565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b0c91815260200190565b5f8260020b8260020b13612c7357612c6c84612c5e84613052565b612c6786613052565b61308d565b9050610a65565b611df284612c8085613052565b612c8b906001613670565b612c9485613052565b612c67906001613670565b60098390556006805461ff0019166101001790555f807f0000000000000000000000000000000000000000000000000000000000000000612ce1578284612ce4565b83835b6040805160018152602081018990529081018390526060810182905291935091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe39060800160405180910390a3612d8a307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015612e15573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e39919061355a565b50305f908152602081905260408120546040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612eb0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed4919061338a565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f33573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f579190613406565b90508215612f6c57612f6c3061dead8561160d565b81156130045760405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612fde573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613002919061355a565b505b60408051848152602081018490526001600160a01b038316917fdb8b672bcfa06e1af0abf6157983be34c75ac7885f33fdfe514b4c800f3c5989910160405180910390a25050505050505050565b5f61305e60c883613695565b90505f8260020b12801561307e575061307860c8836136cd565b60020b15155b15610bc45780610a65816136ee565b5f8160020b8360020b13156130a357505f610a65565b600283810b600890811d9184900b901d815b8181136131905760405163299ce14b60e11b8152600182900b60048201525f906001600160a01b03891690635339c29690602401602060405180830381865afa158015613104573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613128919061338a565b9050805f03613137575061317e565b838203613147575f1960ff88161b165b8282036131695761315c60ff8088169061370f565b5f1962ffffff919091161c165b801561317c576001945050505050610a65565b505b806131888161372a565b9150506130b5565b505f9695505050505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114611060575f5ffd5b5f5f604083850312156131f6575f5ffd5b8235613201816131d1565b946020939093013593505050565b5f5f5f5f60608587031215613222575f5ffd5b8435935060208501359250604085013567ffffffffffffffff811115613246575f5ffd5b8501601f81018713613256575f5ffd5b803567ffffffffffffffff81111561326c575f5ffd5b87602082840101111561327d575f5ffd5b949793965060200194505050565b5f5f5f6060848603121561329d575f5ffd5b83356132a8816131d1565b925060208401356132b8816131d1565b929592945050506040919091013590565b5f602082840312156132d9575f5ffd5b5035919050565b5f602082840312156132f0575f5ffd5b8135610a65816131d1565b5f5f6040838503121561330c575f5ffd5b50508035926020909101359150565b5f5f6040838503121561332c575f5ffd5b8235613337816131d1565b91506020830135613347816131d1565b809150509250929050565b600181811c9082168061336657607f821691505b60208210810361338457634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561339a575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610945576109456133a1565b634e487b7160e01b5f52601260045260245ffd5b5f826133ee576133ee6133cc565b500490565b81810381811115610945576109456133a1565b5f60208284031215613416575f5ffd5b8151610a65816131d1565b5f5f60408385031215613432575f5ffd5b505080516020909101519092909150565b80820180821115610945576109456133a1565b80516001600160801b0381168114610bc4575f5ffd5b5f6020828403121561347c575f5ffd5b610a6582613456565b6001600160801b038281168282160390811115610945576109456133a1565b805161ffff81168114610bc4575f5ffd5b80518015158114610bc4575f5ffd5b5f5f5f5f5f5f5f60e0888a0312156134da575f5ffd5b87516134e5816131d1565b8097505060208801518060020b81146134fc575f5ffd5b955061350a604089016134a4565b9450613518606089016134a4565b9350613526608089016134a4565b925060a088015163ffffffff8116811461353e575f5ffd5b915061354c60c089016134b5565b905092959891949750929550565b5f6020828403121561356a575f5ffd5b610a65826134b5565b81516001600160a01b031681526101608101602083015161359f60208401826001600160a01b03169052565b5060408301516135b6604084018262ffffff169052565b5060608301516135cb606084018260020b9052565b5060808301516135e0608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008301516101008301526101208301516136276101208401826001600160a01b03169052565b5061014092830151919092015290565b5f5f5f5f6080858703121561364a575f5ffd5b8451935061365a60208601613456565b6040860151606090960151949790965092505050565b600281810b9083900b01627fffff8113627fffff1982121715610945576109456133a1565b5f8160020b8360020b806136ab576136ab6133cc565b627fffff1982145f19821416156136c4576136c46133a1565b90059392505050565b5f8260020b806136df576136df6133cc565b808360020b0791505092915050565b5f8160020b627fffff198103613706576137066133a1565b5f190192915050565b62ffffff8281168282160390811115610945576109456133a1565b5f6001600160ff1b018201613741576137416133a1565b506001019056fea2646970667358221220401939af5312071d413f49430baf389e94c154f401353af6e89995415dbba35d64736f6c634300081c0033a26469706673582212203f3257855e96725c5f82166ce21a590dfcc5b4bebf5f10a7c4713a80d6b53c3f64736f6c634300081c0033","sourceMap":"461:4966:11:-:0;;;1358:1074;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1567:6;-1:-1:-1;;;;;1273:26:0;;1269:95;;1322:31;;-1:-1:-1;;;1322:31:0;;1350:1;1322:31;;;1069:51:20;1042:18;;1322:31:0;;;;;;;1269:95;1373:32;1392:12;1373:18;:32::i;:::-;-1:-1:-1;;;;;;1589:27:11;::::1;1585:53;;1625:13;;-1:-1:-1::0;;;1625:13:11::1;;;;;;;;;;;1585:53;1652:9;-1:-1:-1::0;;;;;1652:21:11::1;;1677:1;1652:26:::0;1648:56:::1;;1687:17;;-1:-1:-1::0;;;1687:17:11::1;;;;;;;;;;;1648:56;1718:10;-1:-1:-1::0;;;;;1718:22:11::1;;1744:1;1718:27:::0;1714:58:::1;;1754:18;;-1:-1:-1::0;;;1754:18:11::1;;;;;;;;;;;1714:58;1786:10;-1:-1:-1::0;;;;;1786:22:11::1;;1812:1;1786:27:::0;1782:58:::1;;1822:18;;-1:-1:-1::0;;;1822:18:11::1;;;;;;;;;;;1782:58;1854:4;-1:-1:-1::0;;;;;1854:16:11::1;;1874:1;1854:21:::0;1850:46:::1;;1884:12;;-1:-1:-1::0;;;1884:12:11::1;;;;;;;;;;;1850:46;1910:5;-1:-1:-1::0;;;;;1910:17:11::1;;1931:1;1910:22:::0;1906:48:::1;;1941:13;;-1:-1:-1::0;;;1941:13:11::1;;;;;;;;;;;1906:48;2134:10;-1:-1:-1::0;;;;;2087:57:11::1;2115:4;-1:-1:-1::0;;;;;2087:41:11::1;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2087:57:11::1;;;:127;;;;2209:5;-1:-1:-1::0;;;;;2164:50:11::1;2192:4;-1:-1:-1::0;;;;;2164:39:11::1;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2164:50:11::1;;;2087:127;2070:174;;;2232:12;;-1:-1:-1::0;;;2232:12:11::1;;;;;;;;;;;2070:174;2254:12;:28:::0;;-1:-1:-1;;;;;;2254:28:11;;::::1;-1:-1:-1::0;;;;;2254:28:11;;::::1;;::::0;;;2292:15:::1;:27:::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;2329:22;;::::1;;::::0;2361;::::1;;::::0;2393:10;::::1;;::::0;2413:12:::1;;::::0;-1:-1:-1;461:4966:11;;2011:153:1;2100:13;2093:20;;-1:-1:-1;;;;;;2093:20:1;;;2123:34;2148:8;2123:24;:34::i;:::-;2011:153;:::o;2912:187:0:-;2985:16;3004:6;;-1:-1:-1;;;;;3020:17:0;;;-1:-1:-1;;;;;;3020:17:0;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;14:177:20:-;93:13;;-1:-1:-1;;;;;135:31:20;;125:42;;115:70;;181:1;178;171:12;115:70;14:177;;;:::o;196:722::-;320:6;328;336;344;352;360;368;421:3;409:9;400:7;396:23;392:33;389:53;;;438:1;435;428:12;389:53;461:40;491:9;461:40;:::i;:::-;451:50;;520:49;565:2;554:9;550:18;520:49;:::i;:::-;510:59;;588:49;633:2;622:9;618:18;588:49;:::i;:::-;578:59;;656:49;701:2;690:9;686:18;656:49;:::i;:::-;646:59;;724:50;769:3;758:9;754:19;724:50;:::i;:::-;714:60;;793:50;838:3;827:9;823:19;793:50;:::i;:::-;783:60;;862:50;907:3;896:9;892:19;862:50;:::i;:::-;852:60;;196:722;;;;;;;;;;:::o;1131:208::-;1201:6;1254:2;1242:9;1233:7;1229:23;1225:32;1222:52;;;1270:1;1267;1260:12;1222:52;1293:40;1323:9;1293:40;:::i;:::-;1283:50;1131:208;-1:-1:-1;;;1131:208:20:o;:::-;461:4966:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"60806040526004361061011e575f3560e01c80637f1e9ef61161009d578063b4b57c3911610062578063b4b57c3914610337578063bdaad4881461036a578063e30c397814610389578063e74b981b146103a6578063f2fde38b146103c5575f5ffd5b80637f1e9ef6146102825780638854a0ff146102b55780638d72647e146102d45780638da5cb5b14610307578063a64ed8ba14610323575f5ffd5b806354fd4d50116100e357806354fd4d50146101eb578063634282af14610208578063715018a61461022757806379ba50971461023b5780637c887c591461024f575f5ffd5b806319f3736114610129578063266cedb31461016c5780633a5fedb71461019757806346904840146101b6578063476343ee146101d5575f5ffd5b3661012557005b5f5ffd5b348015610134575f5ffd5b50610157610143366004610b78565b60056020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61017f61017a366004610bdd565b6103e4565b6040516001600160a01b039091168152602001610163565b3480156101a2575f5ffd5b5061017f6101b1366004610c5a565b610644565b3480156101c1575f5ffd5b5060025461017f906001600160a01b031681565b3480156101e0575f5ffd5b506101e96107be565b005b3480156101f6575f5ffd5b5060025b604051908152602001610163565b348015610213575f5ffd5b5061017f610222366004610ce2565b61087d565b348015610232575f5ffd5b506101e96108a5565b348015610246575f5ffd5b506101e96108c6565b34801561025a575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561028d575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c0575f5ffd5b5060035461017f906001600160a01b031681565b3480156102df575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610312575f5ffd5b505f546001600160a01b031661017f565b34801561032e575f5ffd5b506004546101fa565b348015610342575f5ffd5b5061017f7f000000000000000000000000000000000000000000000000000000000000000081565b348015610375575f5ffd5b506101e9610384366004610b78565b61090f565b348015610394575f5ffd5b506001546001600160a01b031661017f565b3480156103b1575f5ffd5b506101e96103c0366004610b78565b610996565b3480156103d0575f5ffd5b506101e96103df366004610b78565b610a13565b5f8515806103f25750604086115b156104105760405163430f13b360e01b815260040160405180910390fd5b83158061041d5750601084115b1561043b5760405163010466f160e21b815260040160405180910390fd5b6104453383610a83565b878787873360035f9054906101000a90046001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006040516104ef90610b50565b6105029a99989796959493929190610d21565b8190604051809103905ff590508015801561051f573d5f5f3e3d5ffd5b506004805460018082019092557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b0384169081179091555f8181526005602052604090819020805460ff1916909317909255905191925033917f5314f94e6e2d1a502483a5b446938dee47de600f90cbf915d89632d58a71aa2b906105c1908b908b908b908b908b90610d8e565b60405180910390a3341561063a5760405162de16a360e71b81523360048201526001600160a01b03821690636f0b518090349060240160206040518083038185885af1158015610613573d5f5f3e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906106389190610dc7565b505b9695505050505050565b5f5f6040518060200161065690610b50565b601f1982820381018352601f909101166040819052600354610716918a918a918a918a918f916001600160a01b0316907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090602001610d21565b60408051601f19818403018152908290526107349291602001610df5565b60405160208183030381529060405280519060200120905060ff60f81b3061075c8a86610a83565b6040516001600160f81b031993909316602084015260609190911b6bffffffffffffffffffffffff1916602183015260358201526055810182905260750160408051601f19818403018152919052805160209091012098975050505050505050565b60025460405147915f916001600160a01b039091169083908381818185875af1925050503d805f811461080c576040519150601f19603f3d011682016040523d82523d5f602084013e610811565b606091505b5050905080610833576040516312171d8360e31b815260040160405180910390fd5b600254604080516001600160a01b039092168252602082018490527fc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a910160405180910390a15050565b6004818154811061088c575f80fd5b5f918252602090912001546001600160a01b0316905081565b6108ad610abf565b604051638905116560e01b815260040160405180910390fd5b60015433906001600160a01b031681146109035760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b61090c81610aed565b50565b610917610abf565b806001600160a01b03163b5f03610941576040516311a1e69760e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f1386da33541fecf49b0f53895aef3f30f6e3e08755deb017e106e7ae4f4c976d906020015b60405180910390a150565b61099e610abf565b6001600160a01b0381166109c55760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f7a7b5a0a132f9e0581eb8527f66eae9ee89c2a3e79d4ac7e41a1f1f4d48a7fc29060200161098b565b610a1b610abf565b600180546001600160a01b0383166001600160a01b03199091168117909155610a4b5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b604080516001600160a01b03841660208201529081018290525f9060600160405160208183030381529060405280519060200120905092915050565b5f546001600160a01b03163314610aeb5760405163118cdaa760e01b81523360048201526024016108fa565b565b600180546001600160a01b031916905561090c815f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6144c880610e1283390190565b80356001600160a01b0381168114610b73575f5ffd5b919050565b5f60208284031215610b88575f5ffd5b610b9182610b5d565b9392505050565b5f5f83601f840112610ba8575f5ffd5b50813567ffffffffffffffff811115610bbf575f5ffd5b602083019150836020828501011115610bd6575f5ffd5b9250929050565b5f5f5f5f5f5f60808789031215610bf2575f5ffd5b863567ffffffffffffffff811115610c08575f5ffd5b610c1489828a01610b98565b909750955050602087013567ffffffffffffffff811115610c33575f5ffd5b610c3f89828a01610b98565b979a9699509760408101359660609091013595509350505050565b5f5f5f5f5f5f60808789031215610c6f575f5ffd5b610c7887610b5d565b9550602087013567ffffffffffffffff811115610c93575f5ffd5b610c9f89828a01610b98565b909650945050604087013567ffffffffffffffff811115610cbe575f5ffd5b610cca89828a01610b98565b979a9699509497949695606090950135949350505050565b5f60208284031215610cf2575f5ffd5b5035919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b61010081525f610d3661010083018c8e610cf9565b8281036020840152610d49818b8d610cf9565b6001600160a01b03998a16604085015297891660608401525050938616608085015291851660a0840152841660c083015290921660e090920191909152949350505050565b606081525f610da1606083018789610cf9565b8281036020840152610db4818688610cf9565b9150508260408301529695505050505050565b5f60208284031215610dd7575f5ffd5b5051919050565b5f81518060208401855e5f93019283525090919050565b5f610e09610e038386610dde565b84610dde565b94935050505056fe6101a0604052348015610010575f5ffd5b506040516144c83803806144c883398101604081905261002f91610877565b8787600361003d83826109cb565b50600461004a82826109cb565b5050600160055550336080526001600160a01b0386811660a05285811660c05284811660e0528381166101008190528382166101205290821661014081905230818110610160819052604051630b4c774160e11b815260048101929092526024820192909252612710604482015290915f91631698ee8290606401602060405180830381865afa1580156100e0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101049190610a85565b90506001600160a01b03811661018e5760405163a167129560e01b81523060048201526001600160a01b038481166024830152612710604483015286169063a1671295906064016020604051808303815f875af1158015610167573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061018b9190610a85565b90505b806001600160a01b0316610180816001600160a01b0316815250505f816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156101e6573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061020a9190610ab1565b5050505050509050806001600160a01b03165f0361028f576001600160a01b03821663f637731d61023a856102b5565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f604051808303815f87803b158015610278575f5ffd5b505af115801561028a573d5f5f3e3d5ffd5b505050505b6102a5306b033b2e3c9fd0803ce8000000610318565b5050505050505050505050610bd4565b5f806102cc6b0295be96e640669720000000610355565b9050826102f7576102f26102ed670de0b6b3a7640000600160c01b846103bb565b610471565b610311565b6103116102ed82600160c01b670de0b6b3a76400006103bb565b9392505050565b6001600160a01b0382166103465760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6103515f83836105c9565b5050565b5f8061036083610649565b905061036c8180610b64565b61038d6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b61039f90674a03ce68d2155555610b64565b6103b190670de0b6b3a7640000610b64565b6103119190610ba2565b5f838302815f1985870982811083820303915050805f036103ef578382816103e5576103e5610b8e565b0492505050610311565b80841161040657610406600385150260111861067c565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f6001821161047e575090565b816001600160801b82106104975760809190911c9060401b5b6801000000000000000082106104b25760409190911c9060201b5b64010000000082106104c95760209190911c9060101b5b6201000082106104de5760109190911c9060081b5b61010082106104f25760089190911c9060041b5b601082106105055760049190911c9060021b5b600482106105115760011b5b600302600190811c9081858161052957610529610b8e565b048201901c9050600181858161054157610541610b8e565b048201901c9050600181858161055957610559610b8e565b048201901c9050600181858161057157610571610b8e565b048201901c9050600181858161058957610589610b8e565b048201901c905060018185816105a1576105a1610b8e565b048201901c90506105c08185816105ba576105ba610b8e565b04821190565b90039392505050565b60065460ff161580156105e457506001600160a01b03831615155b80156105f957506001600160a01b0383163014155b801561061b575060ff5f5c16801561061957506001600160a01b03821630145b155b1561063957604051632b36b06160e01b815260040160405180910390fd5b61064483838361068d565b505050565b5f8161066c6a3725373ddab33742aaaaab6b033b2e3c9fd0803ce8000000610b7b565b6106769190610bc1565b92915050565b634e487b715f52806020526024601cfd5b6001600160a01b0383166106b7578060025f8282546106ac9190610b7b565b909155506107279050565b6001600160a01b0383165f90815260208190526040902054818110156107095760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161033d565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661074357600280548290039055610761565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107a691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126107d6575f5ffd5b81516001600160401b038111156107ef576107ef6107b3565b604051601f8201601f19908116603f011681016001600160401b038111828210171561081d5761081d6107b3565b604052818152838201602001851015610834575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b6001600160a01b0381168114610864575f5ffd5b50565b805161087281610850565b919050565b5f5f5f5f5f5f5f5f610100898b03121561088f575f5ffd5b88516001600160401b038111156108a4575f5ffd5b6108b08b828c016107c7565b60208b015190995090506001600160401b038111156108cd575f5ffd5b6108d98b828c016107c7565b97505060408901516108ea81610850565b60608a01519096506108fb81610850565b60808a015190955061090c81610850565b60a08a015190945061091d81610850565b925061092b60c08a01610867565b915061093960e08a01610867565b90509295985092959890939650565b600181811c9082168061095c57607f821691505b60208210810361097a57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561064457805f5260205f20601f840160051c810160208510156109a55750805b601f840160051c820191505b818110156109c4575f81556001016109b1565b5050505050565b81516001600160401b038111156109e4576109e46107b3565b6109f8816109f28454610948565b84610980565b6020601f821160018114610a2a575f8315610a135750848201515b5f19600385901b1c1916600184901b1784556109c4565b5f84815260208120601f198516915b82811015610a595787850151825560209485019460019092019101610a39565b5084821015610a7657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215610a95575f5ffd5b815161031181610850565b805161ffff81168114610872575f5ffd5b5f5f5f5f5f5f5f60e0888a031215610ac7575f5ffd5b8751610ad281610850565b8097505060208801518060020b8114610ae9575f5ffd5b9550610af760408901610aa0565b9450610b0560608901610aa0565b9350610b1360808901610aa0565b925060a088015163ffffffff81168114610b2b575f5ffd5b60c08901519092508015158114610b40575f5ffd5b8091505092959891949750929550565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761067657610676610b50565b8082018082111561067657610676610b50565b634e487b7160e01b5f52601260045260245ffd5b5f82610bbc57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561067657610676610b50565b60805160a05160c05160e051610100516101205161014051610160516101805161377e610d4a5f395f8181610376015281816109ec01528181611ea10152612d0f01525f81816104f20152818161098b01528181610ecf01528181611ec6015281816121ae015281816123f50152612cb701525f81816106770152818161187701528181612388015281816124850152818161254b0152818161258c015281816126f4015281816127a0015281816128620152818161293d015281816129e901528181612dcf01528181612e6b0152612f9801525f81816105df01528181610e600152818161241a015281816124560152818161250b0152818161268a015281816126c601528181612d650152612da101525f6105ac01525f8181610763015281816127ca015261288a01525f81816106120152610b0101525f81816102b20152610aa701525f81816107aa01528181610c3201528181610d740152818161119c015281816114820152612ed9015261377e5ff3fe608060405260043610610275575f3560e01c806371640de31161014a578063a8aa1b31116100be578063cd3293de11610078578063cd3293de146107e0578063d3618cca146107f4578063dd62ed3e14610808578063e4849b321461084c578063e7c2b7721461086b578063f6ccbda514610884575f5ffd5b8063a8aa1b3114610714578063a9059cbb14610733578063b4b57c3914610752578063b956993b14610785578063c45a015514610799578063c8796572146107cc575f5ffd5b80638d4b66c01161010f5780638d4b66c0146106475780638d72647e1461066657806395d89b41146106995780639c43a050146106ad578063a6195fd3146106c1578063a64190c4146106e0575f5ffd5b806371640de3146105865780637c887c591461059b5780637f1e9ef6146105ce5780638854a0ff146106015780638976254314610634575f5ffd5b806323b872dd116101ec5780635c1624ef116101a65780635c1624ef146104af5780635ed0447d146104c2578063604b1eba146104e1578063667022fd146105145780636f0b51801461053f57806370a0823114610552575f5ffd5b806323b872dd146103e9578063313ce56714610408578063398482d8146104295780634beb394c1461043d578063559f05dc1461047c578063577bd3361461049b575f5ffd5b806316e457f01161023d57806316e457f01461035157806316f0115b1461036557806318160ddd1461039857806320cce74b146103ac57806320f1fc61146103c057806323a69e75146103c8575f5ffd5b806302c7e7af1461027957806302d05d3f146102a157806303fd2a45146102ec57806306fdde0314610301578063095ea7b314610322575b5f5ffd5b348015610284575f5ffd5b5061028e60075481565b6040519081526020015b60405180910390f35b3480156102ac575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610298565b3480156102f7575f5ffd5b506102d461dead81565b34801561030c575f5ffd5b506103156108a2565b604051610298919061319c565b34801561032d575f5ffd5b5061034161033c3660046131e5565b610932565b6040519015158152602001610298565b34801561035c575f5ffd5b5061028e61094b565b348015610370575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156103a3575f5ffd5b5060025461028e565b3480156103b7575f5ffd5b506102d4610985565b61028e6109b4565b3480156103d3575f5ffd5b506103e76103e236600461320f565b6109d1565b005b3480156103f4575f5ffd5b5061034161040336600461328b565b610a47565b348015610413575f5ffd5b5060125b60405160ff9091168152602001610298565b348015610434575f5ffd5b5061028e610a6c565b348015610448575f5ffd5b5061045c6104573660046132c9565b610a78565b604080519485526020850193909352918301526060820152608001610298565b348015610487575f5ffd5b506103416104963660046132e0565b610a95565b3480156104a6575f5ffd5b5061028e610b73565b61028e6104bd3660046132c9565b610b9b565b3480156104cd575f5ffd5b5061045c6104dc3660046131e5565b610bc9565b3480156104ec575f5ffd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b34801561051f575f5ffd5b5061028e61052e3660046132e0565b60086020525f908152604090205481565b61028e61054d3660046132e0565b610c1e565b34801561055d575f5ffd5b5061028e61056c3660046132e0565b6001600160a01b03165f9081526020819052604090205490565b348015610591575f5ffd5b5061028e60095481565b3480156105a6575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d9575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561060c575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561063f575f5ffd5b506104175f81565b348015610652575f5ffd5b5061028e6106613660046132e0565b610c9f565b348015610671575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a4575f5ffd5b50610315610ccc565b3480156106b8575f5ffd5b50610417600281565b3480156106cc575f5ffd5b5061028e6106db3660046132fb565b610cdb565b3480156106eb575f5ffd5b506106ff6106fa3660046132c9565b610d04565b60408051928352602083019190915201610298565b34801561071f575f5ffd5b50600a546102d4906001600160a01b031681565b34801561073e575f5ffd5b5061034161074d3660046131e5565b610d2f565b34801561075d575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b348015610790575f5ffd5b50610417600181565b3480156107a4575f5ffd5b506102d47f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d7575f5ffd5b506106ff610d3c565b3480156107eb575f5ffd5b5061028e610f57565b3480156107ff575f5ffd5b506103e7610f63565b348015610813575f5ffd5b5061028e61082236600461331b565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610857575f5ffd5b5061028e6108663660046132c9565b610fbd565b348015610876575f5ffd5b506006546103419060ff1681565b34801561088f575f5ffd5b5060065461041790610100900460ff1681565b6060600380546108b190613352565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90613352565b80156109285780601f106108ff57610100808354040283529160200191610928565b820191905f5260205f20905b81548152906001019060200180831161090b57829003601f168201915b5050505050905090565b5f3361093f818585610fda565b60019150505b92915050565b5f610954610fec565b61095d33611016565b335f818152602081905260408120546109769291611063565b90506109826001600555565b90565b5f6109af7f00000000000000000000000000000000000000000000000000000000000000006112a4565b905090565b5f6109bd610fec565b6109c633611016565b61097633345f611300565b60ff6101005f5c04161580610a0f5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b80610a1957508315155b80610a2357508215155b15610a415760405163f7a632f560e01b815260040160405180910390fd5b50505050565b5f33610a54858285611593565b610a5f85858561160d565b60019150505b9392505050565b5f6109af60075461166a565b5f5f5f5f610a863386610bc9565b93509350935093509193509193565b6006545f9060ff1615801561094557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061094557506040516370a0823160e01b81526001600160a01b0383811660048301525f917f0000000000000000000000000000000000000000000000000000000000000000909116906370a0823190602401602060405180830381865afa158015610b48573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6c919061338a565b1192915050565b5f6b0295be96e640669720000000600754612710610b9191906133b5565b6109af91906133e0565b5f610ba4610fec565b610bad33611016565b610bb8333484611300565b9050610bc46001600555565b919050565b6006545f9081908190819060ff1615610bec57505f925082915081905083610c15565b610bf686866116cf565b9195509350915081610c0884876133f3565b610c1291906133f3565b90505b92959194509250565b5f610c27610fec565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c7057604051630636a15760e11b815260040160405180910390fd5b60065460ff1615610c945760405163e6a0d45f60e01b815260040160405180910390fd5b610bb882345f611300565b6001600160a01b0381165f90815260086020526040812054610945906a18d0bf423c03d8de0000006133f3565b6060600480546108b190613352565b5f610ce4610fec565b610ced33611016565b610cf8338484611063565b90506109456001600555565b6006545f90819060ff1615610d1d57505f928392509050565b610d26836117a6565b91509150915091565b5f3361093f81858561160d565b5f5f610d46610fec565b600654610100900460ff16600114610d71576040516330aad80b60e01b815260040160405180910390fd5b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015610dce573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610df29190613406565b6040805160808101825260095481526001600160a01b03838116602083019081526001600160801b0383850181815260608501828152955163fc6f786560e01b815294516004860152915183166024850152905181166044840152925190921660648201529192505f9182917f0000000000000000000000000000000000000000000000000000000000000000169063fc6f78659060840160408051808303815f875af1158015610ea5573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ec99190613421565b915091507f0000000000000000000000000000000000000000000000000000000000000000610ef9578082610efc565b81815b60408051838152602081018390529297509095506001600160a01b038516917f2e4fb6077d4acf86e12bb7411fb82b2b3eaa6a49787f4b1e17b423e7ea841169910160405180910390a2505050610f536001600555565b9091565b5f6109af600754611807565b610f6b610fec565b60065460ff1680610f8a57506b0295be96e64066972000000060075414155b15610fa8576040516325a6766f60e21b815260040160405180910390fd5b610fb15f611860565b610fbb6001600555565b565b5f610fc6610fec565b610fcf33611016565b610bb833835f611063565b610fe78383836001611909565b505050565b60026005540361100f57604051633ee5aeb560e01b815260040160405180910390fd5b6002600555565b60065460ff161561103a5760405163e6a0d45f60e01b815260040160405180910390fd5b61104381610a95565b61106057604051637c75aa6f60e11b815260040160405180910390fd5b50565b5f825f036110845760405163617ab12d60e11b815260040160405180910390fd5b6001600160a01b0384165f908152602081905260409020548311156110bc57604051631e9acf1760e31b815260040160405180910390fd5b5f6110c6846117a6565b90925090505f8290036110ec5760405163617ab12d60e11b815260040160405180910390fd5b8282101561110d57604051638199f5f360e01b815260040160405180910390fd5b5f8460075461111c91906133f3565b6007819055905060015f805c60ff19168217905d5061113c86308761160d565b5f60ff19815c16815d506040805186815260208101859052908101839052606081018290526001600160a01b038716907f483f8aec0fd892ac72ad1ba8d0e9c9e73db59c12d263fd71de480b5b3deeae3c9060800160405180910390a25f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836040515f6040518083038185875af1925050503d805f8114611202576040519150601f19603f3d011682016040523d82523d5f602084013e611207565b606091505b505090508061122957604051634033e4e360e01b815260040160405180910390fd5b5f876001600160a01b0316856040515f6040518083038185875af1925050503d805f8114611272576040519150601f19603f3d011682016040523d82523d5f602084013e611277565b606091505b505090508061129957604051630ec6ac4160e21b815260040160405180910390fd5b505050509392505050565b5f5f6112bb6b0295be96e64066972000000061166a565b9050826112e6576112e16112dc670de0b6b3a7640000600160c01b846119db565b611a91565b610a65565b610a656112dc82600160c01b670de0b6b3a76400006119db565b5f5f5f61130d86866116cf565b919450925090505f839003611377576001600160a01b0386165f908152600860205260409020546a18d0bf423c03d8de0000001161135e57604051636bf4c8e960e11b815260040160405180910390fd5b60405163617ab12d60e11b815260040160405180910390fd5b8383101561139857604051638199f5f360e01b815260040160405180910390fd5b5f836007546113a79190613443565b60078190556001600160a01b0388165f908152600860205260408120805492935086929091906113d8908490613443565b909155506113e9905030888661160d565b6040805184815260208101849052908101859052606081018290526001600160a01b038816907f064fb1933e186be0b289a87e98518dc18cc9856ecbc9f1353d1a138ddf733ec59060800160405180910390a25f8261144885896133f3565b61145291906133f3565b90506b0295be96e6406697200000008203611479576114796114748285613443565b611860565b8215611511575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846040515f6040518083038185875af1925050503d805f81146114e8576040519150601f19603f3d011682016040523d82523d5f602084013e6114ed565b606091505b505090508061150f57604051634033e4e360e01b815260040160405180910390fd5b505b8015611299575f886001600160a01b0316826040515f6040518083038185875af1925050503d805f8114611560576040519150601f19603f3d011682016040523d82523d5f602084013e611565565b606091505b505090508061158757604051633c31275160e21b815260040160405180910390fd5b50505050509392505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f198114610a4157818110156115ff57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b610a4184848484035f611909565b6001600160a01b03831661163657604051634b637e8f60e11b81525f60048201526024016115f6565b6001600160a01b03821661165f5760405163ec442f0560e01b81525f60048201526024016115f6565b610fe7838383611be9565b5f5f61167583611c64565b905061168181806133b5565b6116a16a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b6116b390674a03ce68d21555556133b5565b6116c590670de0b6b3a76400006133b5565b610a6591906133e0565b6007545f9081908190816116e66064612710613443565b6116f2612710886133b5565b6116fc91906133e0565b90506117088282611c86565b94505f611721836b0295be96e6406697200000006133f3565b90508086111561172f578095505b6001600160a01b0388165f9081526008602052604081205461175c906a18d0bf423c03d8de0000006133f3565b90508087111561176a578096505b865f03611783575f5f5f9650965096505050505061179f565b61178d8488611d58565b955061179886611dfa565b9450505050505b9250925092565b6007545f9081908315806117b957508084115b156117c957505f93849350915050565b5f6117d48286611e2a565b90506117df81611dfa565b92508281116117f457505f9485945092505050565b6117fe83826133f3565b93505050915091565b5f674a03ce68d215555561181a83611c64565b61183a6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b61184c90674a03ce68d21555556133b5565b61185691906133e0565b61094591906133f3565b6006805460ff191660011790556001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663d0e30db06118a683476133f3565b6040518263ffffffff1660e01b81526004015f604051808303818588803b1580156118cf575f5ffd5b505af11580156118e1573d5f5f3e3d5ffd5b50505050506118ee611e9e565b80156118fd57506118fd612355565b61106057611060612783565b6001600160a01b0384166119325760405163e602df0560e01b81525f60048201526024016115f6565b6001600160a01b03831661195b57604051634a1406b160e11b81525f60048201526024016115f6565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015610a4157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516119cd91815260200190565b60405180910390a350505050565b5f838302815f1985870982811083820303915050805f03611a0f57838281611a0557611a056133cc565b0492505050610a65565b808411611a2657611a266003851502601118612b19565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b5f60018211611a9e575090565b816001600160801b8210611ab75760809190911c9060401b5b680100000000000000008210611ad25760409190911c9060201b5b6401000000008210611ae95760209190911c9060101b5b620100008210611afe5760109190911c9060081b5b6101008210611b125760089190911c9060041b5b60108210611b255760049190911c9060021b5b60048210611b315760011b5b600302600190811c90818581611b4957611b496133cc565b048201901c90506001818581611b6157611b616133cc565b048201901c90506001818581611b7957611b796133cc565b048201901c90506001818581611b9157611b916133cc565b048201901c90506001818581611ba957611ba96133cc565b048201901c90506001818581611bc157611bc16133cc565b048201901c9050611be0818581611bda57611bda6133cc565b04821190565b90039392505050565b60065460ff16158015611c0457506001600160a01b03831615155b8015611c1957506001600160a01b0383163014155b8015611c3b575060ff5f5c168015611c3957506001600160a01b03821630145b155b15611c5957604051632b36b06160e01b815260040160405180910390fd5b610fe7838383612b2a565b5f816118566a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f5f611c9184611c64565b90505f81611cb56a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611cc790674a03ce68d21555556133b5565b611cd191906133e0565b90505f611cde8583613443565b611cfe6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d1090674a03ce68d21555556133b5565b611d1a91906133e0565b9050611d27816001613443565b8311611d38575f9350505050610945565b6001611d4482856133f3565b611d4e91906133f3565b9695505050505050565b5f5f611d6384611c64565b905080611d866a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611d9890674a03ce68d21555556133b5565b611da291906133e0565b611dac84836133f3565b611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611dde90674a03ce68d21555556133b5565b611de891906133e0565b611df291906133f3565b949350505050565b5f612710600181611e0c6064866133b5565b611e169190613443565b611e2091906133f3565b61094591906133e0565b5f5f611e3584611c64565b9050611e418382613443565b611e616a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b611e7390674a03ce68d21555556133b5565b611e7d91906133e0565b81611dcc6a3725373ddab33742aaaaab676765c793fa10079d601b1b613443565b5f7f000000000000000000000000000000000000000000000000000000000000000081611eea7f00000000000000000000000000000000000000000000000000000000000000006112a4565b9050816001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f28573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4c919061346c565b6001600160801b031615611f62575f9250505090565b5f826001600160a01b03166370cf754a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f9f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fc3919061346c565b90506c0c9f2c9cd04674edea400000006001600160801b0382161015611fec575f935050505090565b5f6120046c0c9f2c9cd04674edea4000000083613485565b60405163f30dba9360e01b8152620d899f1960048201529091506001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa158015612058573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061207c919061346c565b6001600160801b0316118061210b575060405163f30dba9360e01b8152620d89a060048201526001600160801b038216906001600160a01b0386169063f30dba9390602401602060405180830381865afa1580156120dc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612100919061346c565b6001600160801b0316115b1561211a575f94505050505090565b5f5f856001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa158015612158573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061217c91906134c4565b505050505091509150846001600160a01b0316826001600160a01b0316036121ab576001965050505050505090565b5f7f00000000000000000000000000000000000000000000000000000000000000006121da5762027e5c6121e0565b62027e5c195b90506121ed878383612c43565b156121ff575f97505050505050505090565b6001600160a01b0380871690841611600161ff00195f805c9190911661010017905d50604051630251596160e31b81523060048201528115156024820152600160448201526001600160a01b03888116606483015260a060848301525f60a483015289169063128acb089060c40160408051808303815f875af19250505080156122a6575060408051601f3d908101601f191682019092526122a391810190613421565b60015b6122c3575f61ff0019815c16815d505f9850505050505050505090565b50505f61ff0019815c16815d50876001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa15801561230c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061233091906134c4565b5050506001600160a01b0393841693909a16929092149b9a5050505050505050505050565b305f9081526020819052604081205481906040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156123cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123f1919061338a565b90507f000000000000000000000000000000000000000000000000000000000000000061243f307f000000000000000000000000000000000000000000000000000000000000000085610fda565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156124cb573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124ef919061355a565b505f6124fd6103e8856133e0565b61250790856133f3565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663883164566040518061016001604052808561256f577f0000000000000000000000000000000000000000000000000000000000000000612571565b305b6001600160a01b031681526020018561258a57306125ac565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b031681526127106020820152620d899f196040820152620d89a06060820152608001856125e057866125e2565b875b8152602001856125f257876125f4565b865b815260200185612604575f612606565b845b8152602001856126165784612618565b5f5b815230602082015242604091820152516001600160e01b031960e084901b1681526126469190600401613573565b6080604051808303815f875af1925050508015612680575060408051601f3d908101601f1916820190925261267d91810190613637565b60015b612769576126af307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af115801561273a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275e919061355a565b505f94505050505090565b612774848383612c9f565b60019850505050505050505090565b60405163e6a4390560e01b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a4390590604401602060405180830381865afa158015612811573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128359190613406565b90506001600160a01b0381166128f7576040516364e329cb60e11b81523060048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063c9c65396906044016020604051808303815f875af11580156128d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128f49190613406565b90505b600a80546001600160a01b0319166001600160a01b03838116919091179091556006805461ff0019166102001790556040516370a0823160e01b81523060048201525f917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612982573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129a6919061338a565b305f818152602081905260409020549192506129c390848361160d565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612a2f573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a53919061355a565b506040516335313c2160e11b815261dead60048201526001600160a01b03841690636a627842906024016020604051808303815f875af1158015612a99573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612abd919061338a565b5060408051600281525f6020820152908101829052606081018390526001600160a01b0384169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe3906080015b60405180910390a3505050565b634e487b715f52806020526024601cfd5b6001600160a01b038316612b54578060025f828254612b499190613443565b90915550612bc49050565b6001600160a01b0383165f9081526020819052604090205481811015612ba65760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016115f6565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612be057600280548290039055612bfe565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b0c91815260200190565b5f8260020b8260020b13612c7357612c6c84612c5e84613052565b612c6786613052565b61308d565b9050610a65565b611df284612c8085613052565b612c8b906001613670565b612c9485613052565b612c67906001613670565b60098390556006805461ff0019166101001790555f807f0000000000000000000000000000000000000000000000000000000000000000612ce1578284612ce4565b83835b6040805160018152602081018990529081018390526060810182905291935091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169030907fb5554518bc713c4a6bbe8322b3e4a823926900d1e945810811dd71b782ceabe39060800160405180910390a3612d8a307f00000000000000000000000000000000000000000000000000000000000000005f610fda565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f60248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015612e15573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e39919061355a565b50305f908152602081905260408120546040516370a0823160e01b81523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612eb0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ed4919061338a565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f33573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f579190613406565b90508215612f6c57612f6c3061dead8561160d565b81156130045760405163a9059cbb60e01b81526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612fde573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613002919061355a565b505b60408051848152602081018490526001600160a01b038316917fdb8b672bcfa06e1af0abf6157983be34c75ac7885f33fdfe514b4c800f3c5989910160405180910390a25050505050505050565b5f61305e60c883613695565b90505f8260020b12801561307e575061307860c8836136cd565b60020b15155b15610bc45780610a65816136ee565b5f8160020b8360020b13156130a357505f610a65565b600283810b600890811d9184900b901d815b8181136131905760405163299ce14b60e11b8152600182900b60048201525f906001600160a01b03891690635339c29690602401602060405180830381865afa158015613104573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613128919061338a565b9050805f03613137575061317e565b838203613147575f1960ff88161b165b8282036131695761315c60ff8088169061370f565b5f1962ffffff919091161c165b801561317c576001945050505050610a65565b505b806131888161372a565b9150506130b5565b505f9695505050505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114611060575f5ffd5b5f5f604083850312156131f6575f5ffd5b8235613201816131d1565b946020939093013593505050565b5f5f5f5f60608587031215613222575f5ffd5b8435935060208501359250604085013567ffffffffffffffff811115613246575f5ffd5b8501601f81018713613256575f5ffd5b803567ffffffffffffffff81111561326c575f5ffd5b87602082840101111561327d575f5ffd5b949793965060200194505050565b5f5f5f6060848603121561329d575f5ffd5b83356132a8816131d1565b925060208401356132b8816131d1565b929592945050506040919091013590565b5f602082840312156132d9575f5ffd5b5035919050565b5f602082840312156132f0575f5ffd5b8135610a65816131d1565b5f5f6040838503121561330c575f5ffd5b50508035926020909101359150565b5f5f6040838503121561332c575f5ffd5b8235613337816131d1565b91506020830135613347816131d1565b809150509250929050565b600181811c9082168061336657607f821691505b60208210810361338457634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561339a575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610945576109456133a1565b634e487b7160e01b5f52601260045260245ffd5b5f826133ee576133ee6133cc565b500490565b81810381811115610945576109456133a1565b5f60208284031215613416575f5ffd5b8151610a65816131d1565b5f5f60408385031215613432575f5ffd5b505080516020909101519092909150565b80820180821115610945576109456133a1565b80516001600160801b0381168114610bc4575f5ffd5b5f6020828403121561347c575f5ffd5b610a6582613456565b6001600160801b038281168282160390811115610945576109456133a1565b805161ffff81168114610bc4575f5ffd5b80518015158114610bc4575f5ffd5b5f5f5f5f5f5f5f60e0888a0312156134da575f5ffd5b87516134e5816131d1565b8097505060208801518060020b81146134fc575f5ffd5b955061350a604089016134a4565b9450613518606089016134a4565b9350613526608089016134a4565b925060a088015163ffffffff8116811461353e575f5ffd5b915061354c60c089016134b5565b905092959891949750929550565b5f6020828403121561356a575f5ffd5b610a65826134b5565b81516001600160a01b031681526101608101602083015161359f60208401826001600160a01b03169052565b5060408301516135b6604084018262ffffff169052565b5060608301516135cb606084018260020b9052565b5060808301516135e0608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008301516101008301526101208301516136276101208401826001600160a01b03169052565b5061014092830151919092015290565b5f5f5f5f6080858703121561364a575f5ffd5b8451935061365a60208601613456565b6040860151606090960151949790965092505050565b600281810b9083900b01627fffff8113627fffff1982121715610945576109456133a1565b5f8160020b8360020b806136ab576136ab6133cc565b627fffff1982145f19821416156136c4576136c46133a1565b90059392505050565b5f8260020b806136df576136df6133cc565b808360020b0791505092915050565b5f8160020b627fffff198103613706576137066133a1565b5f190192915050565b62ffffff8281168282160390811115610945576109456133a1565b5f6001600160ff1b018201613741576137416133a1565b506001019056fea2646970667358221220401939af5312071d413f49430baf389e94c154f401353af6e89995415dbba35d64736f6c634300081c0033a26469706673582212203f3257855e96725c5f82166ce21a590dfcc5b4bebf5f10a7c4713a80d6b53c3f64736f6c634300081c0033","sourceMap":"461:4966:11:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1312:39;;;;;;;;;;-1:-1:-1;1312:39:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;548:14:20;;541:22;523:41;;511:2;496:18;1312:39:11;;;;;;;;2650:788;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2048:32:20;;;2030:51;;2018:2;2003:18;2650:788:11;1884:203:20;3444:580:11;;;;;;;;;;-1:-1:-1;3444:580:11;;;;;:::i;:::-;;:::i;1211:27::-;;;;;;;;;;-1:-1:-1;1211:27:11;;;;-1:-1:-1;;;;;1211:27:11;;;5035:239;;;;;;;;;;;;;:::i;:::-;;2568:76;;;;;;;;;;-1:-1:-1;2636:1:11;2568:76;;;3148:25:20;;;3136:2;3121:18;2568:76:11;3002:177:20;1280:26:11;;;;;;;;;;-1:-1:-1;1280:26:11;;;;;:::i;:::-;;:::i;4856:102::-;;;;;;;;;;;;;:::i;2244:229:1:-;;;;;;;;;;;;;:::i;1101:34:11:-;;;;;;;;;;;;;;;1141:28;;;;;;;;;;;;;;;1244:30;;;;;;;;;;-1:-1:-1;1244:30:11;;;;-1:-1:-1;;;;;1244:30:11;;;1175:29;;;;;;;;;;;;;;;1638:85:0;;;;;;;;;;-1:-1:-1;1684:7:0;1710:6;-1:-1:-1;;;;;1710:6:0;1638:85;;4030:95:11;;;;;;;;;;-1:-1:-1;4102:9:11;:16;4030:95;;1061:34;;;;;;;;;;;;;;;4535:224;;;;;;;;;;-1:-1:-1;4535:224:11;;;;;:::i;:::-;;:::i;1232:99:1:-;;;;;;;;;;-1:-1:-1;1311:13:1;;-1:-1:-1;;;;;1311:13:1;1232:99;;4243:224:11;;;;;;;;;;-1:-1:-1;4243:224:11;;;;;:::i;:::-;;:::i;1649:178:1:-;;;;;;;;;;-1:-1:-1;1649:178:1;;;;;:::i;:::-;;:::i;2650:788:11:-;2803:13;2836:23;;;:50;;-1:-1:-1;2884:2:11;2863:23;;2836:50;2832:76;;;2895:13;;-1:-1:-1;;;2895:13:11;;;;;;;;;;;2832:76;2922:25;;;:54;;-1:-1:-1;2974:2:11;2951:25;;2922:54;2918:82;;;2985:15;;-1:-1:-1;;;2985:15:11;;;;;;;;;;;2918:82;3066:27;3072:10;3084:8;3066:5;:27::i;:::-;3112:4;;3118:6;;3126:10;3138:15;;;;;;;;;-1:-1:-1;;;;;3138:15:11;3155:9;3166;3177:3;3182:4;3040:160;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3220:9:11;:21;;;;;;;;;;;;;-1:-1:-1;;;;;;3220:21:11;-1:-1:-1;;;;;3220:21:11;;;;;;;;-1:-1:-1;3251:14:11;;;:7;3220:21;3251:14;;;;;;:21;;-1:-1:-1;;3251:21:11;;;;;;;3287:55;;3220:21;;-1:-1:-1;3307:10:11;;3287:55;;;;3319:4;;;;3325:6;;;;3333:8;;3287:55;:::i;:::-;;;;;;;;3357:9;:13;3353:78;;3372:59;;-1:-1:-1;;;3372:59:11;;3420:10;3372:59;;;2030:51:20;-1:-1:-1;;;;;3372:29:11;;;;;3409:9;;2003:18:20;;3372:59:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3353:78;2650:788;;;;;;;;:::o;3444:580::-;3601:7;3624:16;3700:34;;;;;;;;:::i;:::-;-1:-1:-1;;3700:34:11;;;;;;;;;;;;;;;;3786:15;;3752:83;;3763:4;;;;3769:6;;;;3777:7;;-1:-1:-1;;;;;3786:15:11;;3803:9;;3814;;3825:3;;3830:4;;3700:34;3752:83;;:::i;:::-;;;;-1:-1:-1;;3752:83:11;;;;;;;;;;3666:183;;;3752:83;3666:183;;:::i;:::-;;;;;;;;;;;;;3643:216;;;;;;3624:235;;3947:4;3940:12;;3962:4;3969:24;3975:7;3984:8;3969:5;:24::i;:::-;3923:81;;-1:-1:-1;;;;;;6078:26:20;;;;3923:81:11;;;6066:39:20;6142:2;6138:15;;;;-1:-1:-1;;6134:53:20;6121:11;;;6114:74;6204:12;;;6197:28;6241:12;;;6234:28;;;6278:12;;3923:81:11;;;-1:-1:-1;;3923:81:11;;;;;;;;;3913:92;;3923:81;3913:92;;;;;3444:580;-1:-1:-1;;;;;;;;3444:580:11:o;5035:239::-;5139:12;;:36;;5095:21;;5078:14;;-1:-1:-1;;;;;5139:12:11;;;;5095:21;;5078:14;5139:36;5078:14;5139:36;5095:21;5139:12;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5126:49;;;5190:2;5185:32;;5201:16;;-1:-1:-1;;;5201:16:11;;;;;;;;;;;5185:32;5246:12;;5232:35;;;-1:-1:-1;;;;;5246:12:11;;;6685:51:20;;6767:2;6752:18;;6745:34;;;5232:35:11;;6658:18:20;5232:35:11;;;;;;;5068:206;;5035:239::o;1280:26::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1280:26:11;;-1:-1:-1;1280:26:11;:::o;4856:102::-;1531:13:0;:11;:13::i;:::-;4933:18:11::1;;-1:-1:-1::0;;;4933:18:11::1;;;;;;;;;;;2244:229:1::0;1311:13;;735:10:6;;-1:-1:-1;;;;;1311:13:1;2339:24;;2335:96;;2386:34;;-1:-1:-1;;;2386:34:1;;-1:-1:-1;;;;;2048:32:20;;2386:34:1;;;2030:51:20;2003:18;;2386:34:1;;;;;;;;2335:96;2440:26;2459:6;2440:18;:26::i;:::-;2286:187;2244:229::o;4535:224:11:-;1531:13:0;:11;:13::i;:::-;4615:9:11::1;-1:-1:-1::0;;;;;4615:21:11::1;;4640:1;4615:26:::0;4611:56:::1;;4650:17;;-1:-1:-1::0;;;4650:17:11::1;;;;;;;;;;;4611:56;4677:15;:27:::0;;-1:-1:-1;;;;;;4677:27:11::1;-1:-1:-1::0;;;;;4677:27:11;::::1;::::0;;::::1;::::0;;;4719:33:::1;::::0;2030:51:20;;;4719:33:11::1;::::0;2018:2:20;2003:18;4719:33:11::1;;;;;;;;4535:224:::0;:::o;4243:::-;1531:13:0;:11;:13::i;:::-;-1:-1:-1;;;;;4324:27:11;::::1;4320:53;;4360:13;;-1:-1:-1::0;;;4360:13:11::1;;;;;;;;;;;4320:53;4383:12;:28:::0;;-1:-1:-1;;;;;;4383:28:11::1;-1:-1:-1::0;;;;;4383:28:11;::::1;::::0;;::::1;::::0;;;4426:34:::1;::::0;2030:51:20;;;4426:34:11::1;::::0;2018:2:20;2003:18;4426:34:11::1;1884:203:20::0;1649:178:1;1531:13:0;:11;:13::i;:::-;1738::1::1;:24:::0;;-1:-1:-1;;;;;1738:24:1;::::1;-1:-1:-1::0;;;;;;1738:24:1;;::::1;::::0;::::1;::::0;;;1802:7:::1;1684::0::0;1710:6;-1:-1:-1;;;;;1710:6:0;;1638:85;1802:7:1::1;-1:-1:-1::0;;;;;1777:43:1::1;;;;;;;;;;;1649:178:::0;:::o;5280:145:11:-;5388:29;;;-1:-1:-1;;;;;6703:32:20;;5388:29:11;;;6685:51:20;6752:18;;;6745:34;;;5352:7:11;;6658:18:20;;5388:29:11;;;;;;;;;;;;5378:40;;;;;;5371:47;;5280:145;;;;:::o;1796:162:0:-;1684:7;1710:6;-1:-1:-1;;;;;1710:6:0;735:10:6;1855:23:0;1851:101;;1901:40;;-1:-1:-1;;;1901:40:0;;735:10:6;1901:40:0;;;2030:51:20;2003:18;;1901:40:0;1884:203:20;1851:101:0;1796:162::o;2011:153:1:-;2100:13;2093:20;;-1:-1:-1;;;;;;2093:20:1;;;2123:34;2148:8;2985:16:0;3004:6;;-1:-1:-1;;;;;3020:17:0;;;-1:-1:-1;;;;;;3020:17:0;;;;;;3052:40;;3004:6;;;;;;;3052:40;;2985:16;3052:40;2975:124;2912:187;:::o;-1:-1:-1:-;;;;;;;;:::o;14:173:20:-;82:20;;-1:-1:-1;;;;;131:31:20;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;:::-;333:39;192:186;-1:-1:-1;;;192:186:20:o;575:348::-;627:8;637:6;691:3;684:4;676:6;672:17;668:27;658:55;;709:1;706;699:12;658:55;-1:-1:-1;732:20:20;;775:18;764:30;;761:50;;;807:1;804;797:12;761:50;844:4;836:6;832:17;820:29;;896:3;889:4;880:6;872;868:19;864:30;861:39;858:59;;;913:1;910;903:12;858:59;575:348;;;;;:::o;928:951::-;1038:6;1046;1054;1062;1070;1078;1131:3;1119:9;1110:7;1106:23;1102:33;1099:53;;;1148:1;1145;1138:12;1099:53;1188:9;1175:23;1221:18;1213:6;1210:30;1207:50;;;1253:1;1250;1243:12;1207:50;1292:59;1343:7;1334:6;1323:9;1319:22;1292:59;:::i;:::-;1370:8;;-1:-1:-1;1266:85:20;-1:-1:-1;;1458:2:20;1443:18;;1430:32;1487:18;1474:32;;1471:52;;;1519:1;1516;1509:12;1471:52;1558:61;1611:7;1600:8;1589:9;1585:24;1558:61;:::i;:::-;928:951;;;;-1:-1:-1;1638:8:20;1742:2;1727:18;;1714:32;;1843:2;1828:18;;;1815:32;;-1:-1:-1;928:951:20;-1:-1:-1;;;;928:951:20:o;2092:905::-;2202:6;2210;2218;2226;2234;2242;2295:3;2283:9;2274:7;2270:23;2266:33;2263:53;;;2312:1;2309;2302:12;2263:53;2335:29;2354:9;2335:29;:::i;:::-;2325:39;;2415:2;2404:9;2400:18;2387:32;2442:18;2434:6;2431:30;2428:50;;;2474:1;2471;2464:12;2428:50;2513:59;2564:7;2555:6;2544:9;2540:22;2513:59;:::i;:::-;2591:8;;-1:-1:-1;2487:85:20;-1:-1:-1;;2679:2:20;2664:18;;2651:32;2708:18;2695:32;;2692:52;;;2740:1;2737;2730:12;2692:52;2779:61;2832:7;2821:8;2810:9;2806:24;2779:61;:::i;:::-;2092:905;;;;-1:-1:-1;2092:905:20;;;;;2963:2;2948:18;;;2935:32;;2092:905;-1:-1:-1;;;;2092:905:20:o;3184:180::-;3243:6;3296:2;3284:9;3275:7;3271:23;3267:32;3264:52;;;3312:1;3309;3302:12;3264:52;-1:-1:-1;3335:23:20;;3184:180;-1:-1:-1;3184:180:20:o;3369:267::-;3458:6;3453:3;3446:19;3510:6;3503:5;3496:4;3491:3;3487:14;3474:43;-1:-1:-1;3562:1:20;3537:16;;;3555:4;3533:27;;;3526:38;;;;3618:2;3597:15;;;-1:-1:-1;;3593:29:20;3584:39;;;3580:50;;3369:267::o;3641:1025::-;4026:3;4015:9;4008:22;3989:4;4053:63;4111:3;4100:9;4096:19;4088:6;4080;4053:63;:::i;:::-;4164:9;4156:6;4152:22;4147:2;4136:9;4132:18;4125:50;4192;4235:6;4227;4219;4192:50;:::i;:::-;-1:-1:-1;;;;;4278:32:20;;;4273:2;4258:18;;4251:60;4347:32;;;4342:2;4327:18;;4320:60;-1:-1:-1;;4417:32:20;;;4411:3;4396:19;;4389:61;4487:32;;;4298:3;4466:19;;4459:61;4557:32;;4551:3;4536:19;;4529:61;4627:32;;;4621:3;4606:19;;;4599:61;;;;4184:58;3641:1025;-1:-1:-1;;;;3641:1025:20:o;4671:508::-;4916:2;4905:9;4898:21;4879:4;4942:62;5000:2;4989:9;4985:18;4977:6;4969;4942:62;:::i;:::-;5052:9;5044:6;5040:22;5035:2;5024:9;5020:18;5013:50;5080;5123:6;5115;5107;5080:50;:::i;:::-;5072:58;;;5166:6;5161:2;5150:9;5146:18;5139:34;4671:508;;;;;;;;:::o;5184:184::-;5254:6;5307:2;5295:9;5286:7;5282:23;5278:32;5275:52;;;5323:1;5320;5313:12;5275:52;-1:-1:-1;5346:16:20;;5184:184;-1:-1:-1;5184:184:20:o;5373:211::-;5414:3;5452:5;5446:12;5496:6;5489:4;5482:5;5478:16;5473:3;5467:36;5558:1;5522:16;;5547:13;;;-1:-1:-1;5522:16:20;;5373:211;-1:-1:-1;5373:211:20:o;5589:261::-;5764:3;5789:55;5814:29;5839:3;5831:6;5814:29;:::i;:::-;5806:6;5789:55;:::i;:::-;5782:62;5589:261;-1:-1:-1;;;;5589:261:20:o","linkReferences":{},"immutableReferences":{"4571":[{"start":840,"length":32},{"start":1121,"length":32},{"start":1672,"length":32}],"4573":[{"start":608,"length":32},{"start":1154,"length":32},{"start":1706,"length":32}],"4575":[{"start":659,"length":32},{"start":1187,"length":32},{"start":1740,"length":32}],"4577":[{"start":741,"length":32},{"start":1220,"length":32},{"start":1774,"length":32}]}}}}}}},"signatures":{"function":[{"signature":"acceptOwnership()","signatureHash4":"0x79ba5097","signatureHash32":"0x79ba5097e5519a381a52113cdcc59540d13f73fd9d26abc0453484a096cc96f2"},{"signature":"agentIdRegistry()","signatureHash4":"0x8854a0ff","signatureHash32":"0x8854a0ff3e111616697df151de04aace9be980204035ef70a232784d5e0c6fd9"},{"signature":"allTokens(uint256)","signatureHash4":"0x634282af","signatureHash32":"0x634282af9f986ebb14d6a80ea2de4677b0709bc19aa5dbad95a445b87551526d"},{"signature":"createToken(string,string,bytes32,bytes32)","signatureHash4":"0x266cedb3","signatureHash32":"0x266cedb3bfd507a5e0c1c5b88f6b1eeeb61b019ad72072861400228fe51627e2"},{"signature":"feeRecipient()","signatureHash4":"0x46904840","signatureHash32":"0x46904840b6b05d7bd13973931bbfab50fdf290a35cb7abbfdd5a1d4a81b1e8e8"},{"signature":"isToken(address)","signatureHash4":"0x19f37361","signatureHash32":"0x19f37361ec059ba719731abebe90cd970182984fbd935dc7d2e6ca039761fee2"},{"signature":"npm()","signatureHash4":"0x7f1e9ef6","signatureHash32":"0x7f1e9ef6915d48f86cdab649abfc7e1135501205ba7332ca02b8009d20043fce"},{"signature":"owner()","signatureHash4":"0x8da5cb5b","signatureHash32":"0x8da5cb5b36e7f68c1d2e56001220cdbdd3ba2616072f718acfda4a06441a807d"},{"signature":"pendingOwner()","signatureHash4":"0xe30c3978","signatureHash32":"0xe30c3978ddd82956a01b5cb08d17f1a2d73e636aeefb7b36f896e41d4c2aab90"},{"signature":"predictTokenAddress(address,string,string,bytes32)","signatureHash4":"0x3a5fedb7","signatureHash32":"0x3a5fedb70b8f6d6bf8259da908a57be3b92c94abf02dbb058a4224c06b1888b0"},{"signature":"renounceOwnership()","signatureHash4":"0x715018a6","signatureHash32":"0x715018a616b5f2044428f6fadb7deef4ce9ca76ef60ea57978964ad137bbe7ae"},{"signature":"setAgentIdRegistry(address)","signatureHash4":"0xbdaad488","signatureHash32":"0xbdaad488fb47f8d13b651a5f67f60482958534a0b7974ab561eefc3ba4ac7315"},{"signature":"setFeeRecipient(address)","signatureHash4":"0xe74b981b","signatureHash32":"0xe74b981b15b470d91075cececf40a8c44bc07bb6cc644ca08d3c2784845fdd29"},{"signature":"tokensCount()","signatureHash4":"0xa64ed8ba","signatureHash32":"0xa64ed8ba5455d8fff3553d4c5b8b92c6cf0ceb0256d255f128e6394110f0152f"},{"signature":"transferOwnership(address)","signatureHash4":"0xf2fde38b","signatureHash32":"0xf2fde38b092330466c661fc723d5289b90272a3e580e3187d1d7ef788506c557"},{"signature":"v2Factory()","signatureHash4":"0xb4b57c39","signatureHash32":"0xb4b57c39d6e8a89eed9eca3384c33a3da29c2f41d4d29c95b89ac30fd2a16344"},{"signature":"v3Factory()","signatureHash4":"0x7c887c59","signatureHash32":"0x7c887c59b79776e9d3ae8714b1202f6a2b362e514b00a4a58052c2648a11fb95"},{"signature":"version()","signatureHash4":"0x54fd4d50","signatureHash32":"0x54fd4d50fce680dbc2593d9e893064bfa880e5642d0036394e1a1849f7fc0749"},{"signature":"wbnb()","signatureHash4":"0x8d72647e","signatureHash32":"0x8d72647e86342293dd7499f1d005b63e9b685db91c87f52313aee315385649f6"},{"signature":"withdrawFees()","signatureHash4":"0x476343ee","signatureHash32":"0x476343ee989dfb229e5c6a6c310eef6d906a6cb911650e2008e58b04a3dcdcfe"}],"event":[{"signature":"AgentIdRegistryUpdated(address)","signatureHash4":"0x1386da33","signatureHash32":"0x1386da33541fecf49b0f53895aef3f30f6e3e08755deb017e106e7ae4f4c976d"},{"signature":"FeeRecipientUpdated(address)","signatureHash4":"0x7a7b5a0a","signatureHash32":"0x7a7b5a0a132f9e0581eb8527f66eae9ee89c2a3e79d4ac7e41a1f1f4d48a7fc2"},{"signature":"FeesWithdrawn(address,uint256)","signatureHash4":"0xc0819c13","signatureHash32":"0xc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a"},{"signature":"OwnershipTransferred(address,address)","signatureHash4":"0x8be0079c","signatureHash32":"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0"},{"signature":"OwnershipTransferStarted(address,address)","signatureHash4":"0x38d16b8c","signatureHash32":"0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700"},{"signature":"TokenCreated(address,address,string,string,bytes32)","signatureHash4":"0x5314f94e","signatureHash32":"0x5314f94e6e2d1a502483a5b446938dee47de600f90cbf915d89632d58a71aa2b"}],"error":[{"signature":"InvalidName()","signatureHash4":"0x430f13b3","signatureHash32":"0x430f13b3258f41708e03c9ac10900c92a05198a20080a57c2127a1b40ea76e92"},{"signature":"InvalidNpm()","signatureHash4":"0x037e6a85","signatureHash32":"0x037e6a85d91b211b4e8953fd6f1839426381950d5276da312fea5fd657d6e8ee"},{"signature":"InvalidRegistry()","signatureHash4":"0x11a1e697","signatureHash32":"0x11a1e697a1c85975448db6646a7687242f7872b0e576fef10a19373ad31e3e4d"},{"signature":"InvalidSymbol()","signatureHash4":"0x04119bc4","signatureHash32":"0x04119bc463cbaad70c035ff41b8e99def150c7fef0c59420332fbb28d8e79053"},{"signature":"InvalidV2Factory()","signatureHash4":"0x3647040f","signatureHash32":"0x3647040f6aed8892e8d17b2f906b42c1f598eaf417faacf9fb73eb245be53be5"},{"signature":"InvalidV3Factory()","signatureHash4":"0x9a11fb31","signatureHash32":"0x9a11fb31cd65cbcd53feecf9d165d4f32a0de6f4b5ccfe87a57472a8a7c9f3d4"},{"signature":"InvalidWbnb()","signatureHash4":"0xc29c774a","signatureHash32":"0xc29c774a90996a633d2110744b3cf741d7de6d153f808997070642b936c3bbe9"},{"signature":"OwnableInvalidOwner(address)","signatureHash4":"0x1e4fbdf7","signatureHash32":"0x1e4fbdf7f3ef8bcaa855599e3abf48b232380f183f08f6f813d9ffa5bd585188"},{"signature":"OwnableUnauthorizedAccount(address)","signatureHash4":"0x118cdaa7","signatureHash32":"0x118cdaa7a341953d1887a2245fd6665d741c67c8c50581daa59e1d03373fa188"},{"signature":"RenounceDisabled()","signatureHash4":"0x89051165","signatureHash32":"0x8905116560d0223388013a6344e0f340294b54bf7b203773dd2cb8f2e5a0d511"},{"signature":"TransferFailed()","signatureHash4":"0x90b8ec18","signatureHash32":"0x90b8ec1877afffd816d05d9b13947f3ff18ec5851c38bad15ec2b710f92391b1"},{"signature":"ZeroAddress()","signatureHash4":"0xd92e233d","signatureHash32":"0xd92e233df2717d4a40030e20904abd27b68fcbeede117eaaccbbdac9618c8c73"}]},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"match":"exact_match","chainId":"56","address":"0xb31e99882d23377a9Ea360f1C065AD7b53Fb8Ec5"}