{"matchId":"47533037","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-09-08T16:11:32Z","creationBytecode":{"onchainBytecode":"0x61012080604052346103d3575f90604081619f5880380380916100228285610457565b8339810103126103d35780516001600160a01b03811691908290036103d357602001516001600160a01b0381168082036103d357821561044457600180546001600160a01b03199081169091555f805491821685178155604051939185916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556601c6bf526340006002556103e86003556126ac6004556003600555813b1561043557600483602093819360e05263313ce56760e01b82525afa9081156103c8575f916103f9575b50601260ff8216116103eb5761010052600680546001600160a01b0319168217905560405160a081016001600160401b038111828210176103d7576040908152828252610bb86020830152611388828201526064606083015261012c608090920191909152600880546001600160e01b031916600160a01b600160e01b0319909316929092176625800c8271017760a31b17909155516107ca8082018281106001600160401b038211176103d757829161369a833903905ff080156103c8576080819052604051906112db8083016001600160401b038111848210176103d7576060928492613e6484393080835260208301526001600160a01b031660408201520301905ff080156103c85760a08190526001600160a01b0316803b156103d3575f8091602460405180948193630b768f0160e31b83523060048401525af180156103c8576103b5575b5060805160a05160405191614e19808401926001600160a01b039081169216906001600160401b038411858510176103a1579160609391859361513f85393083526020830152604082015203019082f080156103945760c052604080519081016001600160401b0381118282101761038057906001916040526717508f1956a80000815260406020820193838552808052600e6020522090518155019051151560ff8019835416911617905560405161321f908161047b8239608051818181610655015281816111ba0152612f3f015260a05181818161031b0152612611015260c051818181610c22015281816116c90152612b69015260e05181818161170d01526122b401526101005181818161058a01526123340152f35b634e487b7160e01b83526041600452602483fd5b50604051903d90823e3d90fd5b634e487b7160e01b86526041600452602486fd5b6103c191505f90610457565b5f5f610266565b6040513d5f823e3d90fd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b62fc7cad60e51b5f5260045ffd5b90506020813d60201161042d575b8161041460209383610457565b810103126103d3575160ff811681036103d3575f61011c565b3d9150610407565b63d92e233d60e01b5f5260045ffd5b631e4fbdf760e01b5f525f60045260245ffd5b601f909101601f19168101906001600160401b038211908210176103d75760405256fe6080806040526004361015610012575f80fd5b5f905f3560e01c90816327cca59f14612018575080632931861b14611fc3578063315226d914611b9157806334fcaa3714611ec35780633cf28b5a14611d465780633d3d2d5814611c7257806345fb206314611c47578063470ef5fc14611bb357806350e25ac214611b96578063523af32814611b9157806354a4931c14611b7457806354faf9c314611b0357806358373f0414611ade5780636499386614611aad5780636783774b14611a905780636cd5bce4146119ff5780636dc97d6a146119885780636e47a1881461191b5780636f471f2d146118c5578063715018a614611862578063767b7c16146117c157806379ba50971461173c5780638009b7bd146116f8578063858f5964146116b457806389a69bd8146116455780638a36a6bb1461161d5780638da5cb5b146115f65780638e8d8ec5146114e55780639b924452146114bd5780639beacf4a1461145e5780639c5693eb146107cf578063abb918d814610786578063b18f1db114610684578063c4b7de971461063f578063c50497ae14610618578063cf3cf573146105fa578063df41ead2146105d7578063e30c3978146105ae578063e68b52e714610570578063e7ed38bd1461034a578063f1f5c99314610305578063f2fde38b14610298578063f325a5fb1461027a578063f9b3b8d9146102475763ffcb6e9f1461020d575f80fd5b3461024457602036600319011261024457602061022b60043561254a565b905460405160039290921b1c6001600160a01b03168152f35b80fd5b5034610244576020366003190112610244576020906004358152600c8252604060018060a01b0391205416604051908152f35b50346102445780600319360112610244576020600354604051908152f35b5034610244576020366003190112610244576102b2612032565b6102ba6126ee565b600180546001600160a01b0319166001600160a01b0392831690811790915582549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610244576101203660031901126102445760643560443560243560a036608319011261056c5761037a6126ee565b6103e881118015610561575b8015610559575b801561054d575b8015610535575b801561051f575b8015610509575b80156104f3575b80156104e0575b80156104c9575b6104ba5760048035600255600391909155556005556001600160a01b036103e36124cc565b166001600160601b0360a01b60085416176008556103ff6124f6565b6008805461ffff60a01b191660a09290921b61ffff60a01b16919091179055610426612507565b6008805461ffff60b01b191660b09290921b61ffff60b01b1691909117905561044d612518565b6008805461ffff60c01b191660c09290921b61ffff60c01b16919091179055610474612529565b6008805461ffff60d01b191660d09290921b61ffff60d01b169190911790557f8f70233f68d766cfab4ff696858b5eba8fa61e09191134073df956473102569b8180a180f35b630256965f60e01b8452600484fd5b5061271061ffff6104d8612529565b1610156103be565b5061ffff6104ec612529565b16156103b7565b506103e861ffff610502612518565b16116103b0565b5061271061ffff610518612507565b16116103a9565b5061271061ffff61052e6124f6565b16116103a2565b506001600160a01b036105466124cc565b161561039b565b50620151808311610394565b50821561038d565b506126ac8211610386565b8380fd5b5034610244578060031936011261024457602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346102445780600319360112610244576001546040516001600160a01b039091168152602090f35b503461024457806003193601126102445760206040516717508f1956a800008152f35b50346102445780600319360112610244576020600254604051908152f35b503461024457806003193601126102445760206040516b033b2e3c9fd0803ce80000008152f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346102445760403660031901126102445761069e612032565b906024359182151590818403610782576106b790612562565b60038101546001600160a01b031633141580610767575b6107585760048101805460ff60b01b191694151560b01b60ff60b01b16949094179093559091829190600101546001600160a01b031690813b15610754578291602483926040519485938492639a9b567d60e01b845260048401525af18015610749576107385750f35b8161074291612177565b6102445780f35b6040513d84823e3d90fd5b5050fd5b632e7e4e5160e21b8352600483fd5b5082546001600160a01b0316331415806106ce5750836106ce565b8280fd5b50346102445760403660031901126102445760209060ff906040906001600160a01b036107b1612032565b168152600d8452818120602435825284522054166040519015158152f35b50606036600319011261127c576001600160401b036004351161127c576101606004353603600319011261127c576108056126ee565b61080d61280f565b60243515801561143c575b61142e5761082760443561228f565b9161010460043501350361141f5760025434036114105761084c60c46004350161253b565b61ffff60035491161180156113e1575b6113d257335f52600d60205260405f2061012460043501355f5260205260ff60405f2054166113c357602061089c610144600435016004356004016130da565b9050116113b457335f52600d60205260405f2061012460043501355f5260205260405f20600160ff1982541617905560018060a01b036108e060a4600435016124e2565b166113a05733925b6acecb8f27f4200f3a0000009261ffff60085460c01c169161090e60c46004350161253b565b61ffff61091f60e46004350161310f565b916040519561092d8761215c565b5f875260018060a01b038a1660208801528760408801526060870152166080850152151560a084015260405192638dabdc8360e01b84526101e06004850152610a186109f06109c86109a061098c600435600401600435600401613130565b6101606101e48b01526103448a0191613161565b6109b4602460043501600435600401613130565b8983036101e319016102048b015290613161565b6109dc604460043501600435600401613130565b8883036101e319016102248a015290613161565b610a04606460043501600435600401613130565b8783036101e3190161024489015290613161565b60043560848101359190360360a2190182121561127c576004610ad99281350101906101e31987820301610264880152610acb610ac0610aa5610a8a610a6f610a618780613130565b60a0885260a0880191613161565b610a7c6020880188613130565b908783036020890152613161565b610a976040870187613130565b908683036040880152613161565b610ab26060860186613130565b908583036060870152613161565b926080810190613130565b916080818503910152613161565b906001600160a01b03610af060043560a40161205e565b1661028486015260c4600435013561ffff811680910361127c576102a4860152610b1e60e4600435016120d5565b15156102c48601526004356101048101356102e48701526101248101356103048701526101448101359036036022190181121561127c576004908135010160208101926001600160401b0382351161127c57813560051b3603841361127c578681036101e319016103248801528135815291928692602001915f5b8135811061137057505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190610bfb60e48301612701565b336101848301526b033b2e3c9fd0803ce80000006101a48301526101c4820189905203815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af193841561124f575f935f95611327575b50868486610e03610c7160c46004350161253b565b610de861ffff610c8560e46004350161310f565b926004604051610c948161210a565b60018060a01b0389168152602081019760018060a01b031688526040810199338b52606082019060018060a01b03168152608082019a5f8c528560a084019516855260c08301971515885260e083019960018b5261010084019b60018d5260018060a01b03165f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b51845460ff60b01b191690151560b01b60ff60b01b16178455565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790556001600160a01b0384165f908152600a602052604090206007198101611294575b50600b54600160401b8110156112805784610e73826001610e979401600b5561254a565b81546001600160a01b0393841660039290921b91821b9390911b1916919091179055565b610eac610144600435016004356004016130da565b979050600288018811610f7d57610ee06002610ec9818b01613181565b99610ed76040519b8c612177565b01808a52613181565b601f19013660208a013733610ef489613198565b526001600160a01b0316610f07886131a5565b525f5b610f1f610144600435016004356004016130da565b9050811015610fa557610f3d610144600435016004356004016130da565b821015610f9157610f52908260051b016124e2565b90600281018111610f7d57600191610f6d600283018b6131b5565b90838060a01b0316905201610f0a565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5085876001600160a01b0387163b1561127c576040805163251b648160e21b81526001600160a01b03881660048201526024810191909152815160448201819052909182916064830191602001905f5b81811061125a57505f93928390039150829050836001600160a01b038c165af1801561124f5761123a575b50600254806111ad575b506110f9916110b29160405190858252826020830152600160408301526060820152339060018060a01b038916907ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b608060018060a01b038b1692a46024358452600c6020526040842080546001600160a01b0319166001600160a01b03881617905561273e565b916001604051916110c283612126565b84835260406020840191838352838060a01b0389168152600e602052209251835551151591019060ff801983541691151516179055565b60408051918252600160208301526001600160a01b038416917fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79190a260408051604435815260208101929092526001600160a01b03831691602435917ff58d88bf88870587ec1fdf8ab973f10a093d9dc3c1a243e32f41fa5d73eda1b791a360015f5160206131ca5f395f51905f5255604080516001600160a01b039283168152929091166020830152819081015b0390f35b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b1561123657906024869260405194859384926301aba89b60e71b845260048401525af1801561122b57908491611216575b5061102a565b8161122091612177565b610782578287611210565b6040513d86823e3d90fd5b8580fd5b6112479193505f90612177565b5f9186611020565b6040513d5f823e3d90fd5b82516001600160a01b0316845285945060209384019390920191600101610ff5565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155611321905b600854815461ffff60b01b191661ffff60b01b909116178155600854815461ffff60c01b191661ffff60c01b909116178155600854815461ffff60d01b191661ffff60d01b909116179055565b5f610e4f565b935093506040833d604011611368575b8161134460409383612177565b8101031261127c57611361602061135a8561311c565b940161311c565b935f610c5c565b3d9150611337565b919493509160019060209081906001600160a01b0361138e8961205e565b16815201950191019187939492610b99565b6113ae60a4600435016124e2565b926108e8565b630256965f60e01b5f5260045ffd5b630ced304360e01b5f5260045ffd5b6326b5197760e21b5f5260045ffd5b506107d061140a61ffff6113f960c46004350161253b565b1661ffff60085460c01c16906120e2565b1161085c565b637e6d78a560e01b5f5260045ffd5b631e5d0a3f60e11b5f5260045ffd5b62d532eb60e71b5f5260045ffd5b506024355f908152600c60205260409020546001600160a01b03161515610818565b3461127c57602036600319011261127c576001600160a01b0361147f612032565b165f908152600f60209081526040918290208054600182015460029092015484516001600160a01b0390921682529281019190915291820152606090f35b3461127c575f36600319011261127c576007546040516001600160a01b039091168152602090f35b3461127c57606036600319011261127c576114fe612032565b602435906044358015159182820361127c576115186126ee565b6001600160a01b031692831515806115d9575b6115ca57801580156115ba575b6113b4576115a07fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79360016040519161157083612126565b84835260208301908152875f52600e60205260405f209251835551151591019060ff801983541691151516179055565b60408051918252911515602082015290819081015b0390a2005b506001600160801b038111611538565b6349285dfb60e01b5f5260045ffd5b50835f52600960205260ff600460405f20015460b81c161561152b565b3461127c575f36600319011261127c575f546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c576006546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c5761165d61224e565b506111a960405161166d81612141565b61ffff60085460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c57600154336001600160a01b03909116036117ae57600180546001600160a01b03199081169091555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461127c57602036600319011261127c576117da612032565b6117e26126ee565b600754906001600160a01b03821661185357803b15611844576001600160a01b03166001600160a01b03199190911681176007556040519081527f56b32d3633fed72f97c4df44a78b5fa04f1d662d4bddebcd8a9b216d26d093ad90602090a1005b63d92e233d60e01b5f5260045ffd5b63a741a04560e01b5f5260045ffd5b3461127c575f36600319011261127c5761187a6126ee565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461127c57602036600319011261127c576001600160a01b036118e6612032565b165f52600e60205260405f2060ff6001825492015416906111a960405192839283909291602090604083019483521515910152565b3461127c57602036600319011261127c57611934612032565b61193c6126ee565b6001600160a01b03165f818152600f60205260408120818155600181018290556002018190557f30241dede93b23e050576be65d204d53b18e8c6d9f75006095bfd422094d87569080a2005b604036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c576119d2906119c0612048565b6119c861280f565b3391600401612847565b60015f5160206131ca5f395f51905f5255604080516001600160a01b039384168152919092166020820152f35b606036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c57611a33612048565b604435906001600160a01b03821680830361127c57611a5061280f565b6007546001600160a01b0316331480159190611a87575b50611a78576119d292600401612847565b63754f554b60e11b5f5260045ffd5b90501584611a67565b3461127c575f36600319011261127c576020600554604051908152f35b3461127c57602036600319011261127c576060611acb60043561228f565b9060405192835260208301526040820152f35b3461127c57602036600319011261127c57611af7612032565b50602060405160018152f35b3461127c57602036600319011261127c57611b1c612032565b611b246126ee565b6001600160a01b03168015611844576020817fae994ca926e252e299c3df7516cb609272a57bf80b0e0715297e55939f873420926001600160601b0360a01b6006541617600655604051908152a1005b3461127c575f36600319011261127c576020604051620151808152f35b612072565b3461127c575f36600319011261127c576020600454604051908152f35b3461127c57602036600319011261127c57611bcc612032565b611bd461224e565b50611bde81612562565b5060018060a01b03165f52600a6020526111a960405f2061ffff60405191611c0583612141565b5460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c57602036600319011261127c576020611c6a611c65612032565b612198565b604051908152f35b3461127c57602036600319011261127c57611c8b612032565b611c936126ee565b60018060a01b03811690815f52600f60205260405f2060405190611cb6826120ef565b80546001600160a01b0316808352600182015460208401819052600290920154604084018190529015918215611d3c575b508115611d32575b50611d2357611d21925f52600f6020525f600260408220828155826001820155015560018060a01b0390511690612597565b005b63aa0b7b6160e01b5f5260045ffd5b9050421184611cef565b4210915085611ce7565b3461127c57602036600319011261127c57611d5f612032565b5f610100604051611d6f8161210a565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152015260018060a01b03165f52600960205261012060405f2060405190611dc18261210a565b60018060a01b038154169182815260018060a01b036001830154166020820190815261ffff60018060a01b0360028501541660408401908152600460018060a01b036003870154169560608601968752015494608085019060018060a01b038716825260a0860192848860a01c16845260c087019560ff8960b01c161515875260ff61010060e08a0199828c60b81c1615158b52019960c01c1615158952604051998a5260018060a01b0390511660208a015260018060a01b03905116604089015260018060a01b03905116606088015260018060a01b039051166080870152511660a085015251151560c084015251151560e0830152511515610100820152f35b3461127c57604036600319011261127c57611edc612032565b611ee4612048565b611eec6126ee565b611ef582612562565b506001600160a01b038116908115611844576203f480420190814211610f7d576207e900420192838311610f7d577f22b336cc3c163283ca94b8a02d1107b4485a820fa77cc12ea205640452d37b5e936115b59160405190611f56826120ef565b8152602080820186815260408084018581526001600160a01b039a8b165f818152600f8652839020955186546001600160a01b031916908d161786559251600186015551600294909401939093558251959098168552840194909452928201929092529081906060820190565b3461127c57604036600319011261127c57611fdc612032565b611fe4612048565b6001600160a01b036003611ff784612562565b015416330361200957611d2191612597565b632e7e4e5160e21b5f5260045ffd5b3461127c575f36600319011261127c57602090600b548152f35b600435906001600160a01b038216820361127c57565b602435906001600160a01b038216820361127c57565b35906001600160a01b038216820361127c57565b3461127c575f36600319011261127c5760206040516203f4808152f35b919091608061ffff8160a084019560018060a01b038151168552826020820151166020860152826040820151166040860152826060820151166060860152015116910152565b3590811515820361127c57565b91908201809211610f7d57565b606081019081106001600160401b0382111761128057604052565b61012081019081106001600160401b0382111761128057604052565b604081019081106001600160401b0382111761128057604052565b60a081019081106001600160401b0382111761128057604052565b60c081019081106001600160401b0382111761128057604052565b90601f801991011681019081106001600160401b0382111761128057604052565b60018060a01b0316805f52600e60205260405f2060ff6001604051926121bd84612126565b8054845201541615801560208301526115ca575160025460035460045490600554926040519460208601964688523060408801526b033b2e3c9fd0803ce80000006060880152608087015260a08601525f60c086015260e08501526101008401526101208301526101408201526122376101608201612701565b6101e0815261224861020082612177565b51902090565b6040519061225b82612141565b5f6080838281528260208201528260408201528260608201520152565b519069ffffffffffffffffffff8216820361127c57565b614650811080156124c1575b61241757604051633fabe5a360e21b815260a0816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801561124f575f915f9161246d575b505f821390811591612464575b811561245a575b8115612444575b50612436578091670de0b6b3a7640000810290808204670de0b6b3a76400001490151715610f7d5760ff7f000000000000000000000000000000000000000000000000000000000000000016604d8111610f7d57600a0a80600302906003820403610f7d576001600160fe1b0383168303610f7d5761238a9260021b91612770565b9081158015612426575b61241757600254600354600454600554906040519260208401944686523060408601526b033b2e3c9fd0803ce800000060608601525f60808601528760a0860152600160c086015260e08501526101008401526101208301526101408201526124006101608201612701565b6101e0815261241161020082612177565b51902092565b6330d7115160e11b5f5260045ffd5b506001600160801b038211612394565b62fc7cad60e51b5f5260045ffd5b90504203428111610f7d5762015180105f612308565b4281119150612301565b801591506122fa565b91505060a0813d60a0116124b9575b8161248960a09383612177565b8101031261127c5761249a81612278565b5060208101516124b1608060608401519301612278565b50905f6122ed565b3d915061247c565b506161a8811161229b565b6084356001600160a01b038116810361127c5790565b356001600160a01b038116810361127c5790565b60a43561ffff8116810361127c5790565b60c43561ffff8116810361127c5790565b60e43561ffff8116810361127c5790565b6101043561ffff8116810361127c5790565b3561ffff8116810361127c5790565b600b54811015610f9157600b5f5260205f2001905f90565b60018060a01b03165f52600960205260405f209060ff600483015460c01c161561258857565b638698bf3760e01b5f5260045ffd5b6001600160a01b03821691905f908315611844576125b481612562565b6003810180546001600160a01b0319811687179091556001909101546001600160a01b03918216949116803b1561127c575f8091602460405180948193633d82753160e11b83528b60048401525af1801561124f576126d9575b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b1561056c57604051635ad7fc1760e01b81526001600160a01b0384811660048301529190911660248201529083908290604490829084905af180156126ce579083916126b5575b50506001600160a01b0316907f308c390ed1ab5873392818e036cabdf408bc8ad042fbaead3108954ff75ba9809080a4565b816126bf91612177565b6126ca57815f612683565b5080fd5b6040513d85823e3d90fd5b6126e69193505f90612177565b5f915f61260e565b5f546001600160a01b031633036117ae57565b608061ffff60085460018060a01b0381168452818160a01c166020850152818160b01c166040850152818160c01c16606085015260d01c16910152565b801561275c57723880173480caadff41f996746e3000000000000490565b634e487b7160e01b5f52601260045260245ffd5b90915f19838309928083029283808610950394808603951461280157848311156127e95790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b50509150811561275c570490565b60025f5160206131ca5f395f51905f5254146128385760025f5160206131ca5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b90915f9361285484612198565b6101008401350361141f5760018060a01b0384165f52600e60205260405f20549460025434036114105761288a60c0850161253b565b61ffff60035491161180156130be575b6113d25760018060a01b0383165f52600d60205260405f206101208501355f5260205260ff60405f2054166113c35760206128d96101408601866130da565b9050116113b4576001600160a01b038381165f908152600d6020908152604080832061012089013584529091529020805460ff1916600117905561291f60a086016124e2565b166130ac5782945b61ffff60085460c01c169161293e60c0870161253b565b61ffff61294d60e0890161310f565b916040519561295b8761215c565b6001600160a01b0386811688528b16602088015260408088018d905260608801919091529116608086015290151560a085015251638dabdc8360e01b81526101e06004820152926129df6129d26129c56129b861098c8b80613130565b6109b460208c018c613130565b6109dc60408b018b613130565b610a0460608a018a613130565b90608088013588360392609e19840182121561127c578681036101e31901610264880152612a23918a0190610acb610ac0610aa5610a8a610a6f610a618780613130565b916001600160a01b03612a3860a08b0161205e565b1661028487015260c089013561ffff811680910361127c576102a4870152612a6260e08a016120d5565b15156102c48701526101008901356102e487015261012089013561030487015261014089013590601e190181121561127c578801602081359101926001600160401b03821161127c578160051b3603841361127c578681036101e3190161032488015281815291928692602001915f5b81811061307c57505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190612b3360e48301612701565b6001600160a01b038981166101848401526b033b2e3c9fd0803ce80000006101a48401525f6101c48401819052929091039183917f0000000000000000000000000000000000000000000000000000000000000000165af194851561124f5787915f945f9761302c575b5090600491848989612d32612bc060e0612bb960c0860161253b565b940161310f565b610de861ffff60405195612bd38761210a565b8d60018060a01b03169a878c809952602081019760018060a01b03169d8e8952604082018d60018060a01b03168152606083019160018060a01b03168252608083019b60018060a01b03168c528560a084019516855260c08301971515885260e08301995f8b5261010084019b60018d525f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790555f838152600a602052604090206007198101612fe2575b50600b54600160401b8110156112805786610e73826001612d989401600b5561254a565b612da66101408a018a6130da565b9b905060028c01809c11610f7d57612dbd8c613181565b9b6040519c612dcc908e612177565b808d52612dd890613181565b60208d019b90601f1901368d376001600160a01b038416612df88e613198565b526001600160a01b0316612e0b8d6131a5565b525f5b612e1c6101408c018c6130da565b9050811015612e7257612e336101408c018c6130da565b821015610f9157612e48908260051b016124e2565b906002810191828211610f7d57612e628f936001946131b5565b90838060a01b0316905201612e0e565b50929598509295989990939699863b1561127c576040805163251b648160e21b8152600481018890526024810191909152915160448301819052829160648301915f5b818110612fc05750505090805f920381838a5af1801561124f57612fab575b5060025480612f32575b50604080516001600160a01b0397881681526020810192909252810182905260608101919091529316927ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b90608090a49190565b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b15612fa757906024859260405194859384926301aba89b60e71b845260048401525af180156126ce5715612ede57612f9d838092612177565b6126ca575f612ede565b8480fd5b612fb89192505f90612177565b5f905f612ed4565b82516001600160a01b0316845285945060209384019390920191600101612eb5565b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155613026906112d4565b5f612d74565b9450955090506040833d604011613074575b8161304b60409383612177565b8101031261127c576004879161306c60206130658761311c565b960161311c565b969091612b9d565b3d915061303e565b919493509160019060209081906001600160a01b0361309a8961205e565b16815201950191019187939492612ad2565b6130b860a085016124e2565b94612927565b506107d06130d461ffff6113f960c0880161253b565b1161289a565b903590601e198136030182121561127c57018035906001600160401b03821161127c57602001918160051b3603831361127c57565b35801515810361127c5790565b51906001600160a01b038216820361127c57565b9035601e198236030181121561127c5701602081359101916001600160401b03821161127c57813603831361127c57565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b0381116112805760051b60200190565b805115610f915760200190565b805160011015610f915760400190565b8051821015610f915760209160051b01019056fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212203190683f5d6bc5abb39a655d737ec2428316f3ace65c6ab0d982473f4e38da5864736f6c634300082300336080806040523460395760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005561078c908161003e8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c806309ad4dd9146102015780631698755f146101d257806332f289cf14610187578063379607f5146101615780634e71d92d1461011a57806370a08231146100e3578063d5d44d80146100c55763f59e38b714610071575f80fd5b346100c15760403660031901126100c15761008a610249565b61009261025f565b6001600160a01b039182165f908152600160209081526040808320949093168252928352819020549051908152f35b5f80fd5b60203660031901126100c1576100e16100dc610249565b6104bd565b005b346100c15760203660031901126100c1576001600160a01b03610104610249565b165f525f602052602060405f2054604051908152f35b346100c1575f3660031901126100c15761013261051c565b335f525f602052602061014860405f2054610669565b60015f5160206107375f395f51905f5255604051908152f35b346100c15760203660031901126100c15761017a61051c565b6020610148600435610669565b346100c15760203660031901126100c15760206101486101a5610249565b6101ad61051c565b335f9081526001845260408082206001600160a01b0384168352855290205490610554565b346100c15760403660031901126100c15760206101486101f0610249565b6101f861051c565b60243590610554565b346100c15760603660031901126100c15761023661021d610249565b61022561025f565b61022d61051c565b604435916102d9565b60015f5160206107375f395f51905f5255005b600435906001600160a01b03821682036100c157565b602435906001600160a01b03821682036100c157565b90601f8019910116810190811067ffffffffffffffff82111761029757604052565b634e487b7160e01b5f52604160045260245ffd5b919082039182116102b857565b634e487b7160e01b5f52601160045260245ffd5b919082018092116102b857565b6001600160a01b03169190821580156104ac575b61049d5781156103f5576040516370a0823160e01b81523060048201526001600160a01b03919091169190602081602481865afa90811561042e575f9161046b575b50604051916323b872dd60e01b5f52336004523060245260445260205f60648180875af160015f511481161561044c575b826040525f60605215610439576370a0823160e01b8252306004830152602082602481865afa801561042e575f906103fa575b61039d92506102ab565b9182156103f557805f52600160205260405f20825f5260205260405f206103c58482546102cc565b90556040519283527f5d104c62f50449fadfe6f4013c8f36588d32737f94b5ac9b83ddad33b3e1ffdf60203394a4565b505050565b506020823d602011610426575b8161041460209383610275565b810103126100c15761039d9151610393565b3d9150610407565b6040513d5f823e3d90fd5b82635274afe760e01b5f5260045260245ffd5b600181151661046257833b15153d151616610360565b823d5f823e3d90fd5b90506020813d602011610495575b8161048660209383610275565b810103126100c157515f61032f565b3d9150610479565b63d92e233d60e01b5f5260045ffd5b506001600160a01b038116156102ed565b6001600160a01b0316801561049d57341561051957805f525f60205260405f206104e83482546102cc565b9055604051903482527f4e45da441832cf53bdaa69235704fc0575e68210f459ee1562911024b12967d560203393a3565b50565b60025f5160206107375f395f51905f5254146105455760025f5160206107375f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b811561065a57335f52600160205260405f2060018060a01b0382165f5260205260405f2054808311610644578261058a916102ab565b335f52600160205260405f2060018060a01b0383165f5260205260405f205560018060a01b031660405163a9059cbb60e01b5f52336004528260245260205f60448180865af160015f5114811615610625575b8160405215610612578281527fdbc1ea3a8459e4c7e11fb385b52bbb5cc8c8ab85eec5d883ac9aa78c171f514160203392a390565b50635274afe760e01b5f5260045260245ffd5b600181151661063b57823b15153d1516166105dd565b503d5f823e3d90fd5b8263cf47918160e01b5f5260045260245260445ffd5b636165515360e11b5f5260045ffd5b801561065a57335f525f60205260405f2054808211610720578161068c916102ab565b335f525f60205260405f20555f80808084335af13d1561071b573d67ffffffffffffffff811161029757604051906106ce601f8201601f191660200183610275565b81525f60203d92013e5b1561070c576040518181527fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a60203392a290565b6312171d8360e31b5f5260045ffd5b6106d8565b9063cf47918160e01b5f5260045260245260445ffdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220dbbc16195d46dd822a5bbc7c7a2c8ac6b3a2c13959882c7f071ff2c011021a2464736f6c6343000823003360c03461015f57601f6112db38819003918201601f19168301916001600160401b038311848410176101635780849260609460405283398101031261015f5780516001600160a01b038116919082900361015f5760208101516001600160a01b0381169182820361015f5760400151916001600160a01b0383169081840361015f57841561014c57600180546001600160a01b03199081169091555f80549182168717815560405196916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005515908115610143575b506101345760805260a05261116390816101788239608051816103cf015260a05181818161021301526107aa0152f35b63d92e233d60e01b5f5260045ffd5b9050155f610104565b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c908163032bbf4f146106235750806319165587146105df578063384711cc1461058f5780634cfc4d30146105715780635ad7fc171461053a5780635bb478081461049d578063715018a61461047e57806379ba5097146103fe57806382589038146103ba578063892823f7146103445780638da5cb5b1461031d578063a3f8eace146102cd578063b224cf641461026a578063c45a015514610242578063c4b7de97146101fe578063d79779b2146101c3578063d8fb93371461018b578063e30c3978146101635763f2fde38b146100ed575f80fd5b3461015f57602036600319011261015f5761010661065a565b61010e610e1b565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b5f80fd5b3461015f575f36600319011261015f576001546040516001600160a01b039091168152602090f35b3461015f57602036600319011261015f576001600160a01b036101ac61065a565b165f526003602052602060405f2054604051908152f35b3461015f57602036600319011261015f576001600160a01b036101e461065a565b165f5260036020526020600160405f200154604051908152f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576002546040516001600160a01b039091168152602090f35b3461015f57602036600319011261015f576001600160a01b0361028b61065a565b165f526003602052606060405f2061ffff600860018060a01b0360078401541692015460405192835260018060a01b038116602084015260a01c166040820152f35b3461015f57602036600319011261015f576001600160a01b036102ee61065a565b165f526003602052602061031560405f2061030f60038201549142906110b4565b90610670565b604051908152f35b3461015f575f36600319011261015f575f546040516001600160a01b039091168152602090f35b3461015f5760a036600319011261015f5761035d61065a565b6044356001600160a01b038116810361015f576064356001600160a01b038116810361015f576084359161ffff8316830361015f576103a79361039e610da6565b60243590610adc565b60015f51602061110e5f395f51905f5255005b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f57600154336001600160a01b0382160361046b576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461015f575f36600319011261015f576317d5c96560e11b5f5260045ffd5b3461015f57602036600319011261015f576104b661065a565b6104be610e1b565b600254906001600160a01b03821661052c576001600160a01b031690811561051d576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b3461015f57604036600319011261015f5761055361065a565b6024356001600160a01b038116810361015f5761056f91610a3d565b005b3461015f575f36600319011261015f57602060405163096601808152f35b3461015f57602036600319011261015f576001600160a01b036105b061065a565b165f526003602052602061031560405f2061030f6105d76001830154600384015490610670565b9142906110b4565b3461015f57602036600319011261015f57602061060a6105fd61065a565b610605610da6565b610705565b60015f51602061110e5f395f51905f5255604051908152f35b3461015f57602036600319011261015f576020906001600160a01b0361064761065a565b165f5260038252600260405f2001548152f35b600435906001600160a01b038216820361015f57565b9190820180921161067d57565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561067d57565b81156106ae570490565b634e487b7160e01b5f52601260045260245ffd5b9190820391821161067d57565b90601f8019910116810190811067ffffffffffffffff8211176106f157604052565b634e487b7160e01b5f52604160045260245ffd5b6002549091905f906001600160a01b031615610a2e576001600160a01b038381165f81815260036020526040902060078101805491969294909390911633141580610a17575b610a08576107594287610dde565b600386019586549687156109fd57905f600892556001810161077c898254610670565b90550161271061079461ffff835460a01c1689610691565b04926107a084896106c2565b9460018060a01b037f0000000000000000000000000000000000000000000000000000000000000000169260405163095ea7b360e01b5f52846004528a60245260205f604481808d5af19060015f51148216156109ee575b60405215610938575b856108c7575b5085610844575b505050507f82e416ba72d10e709b5de7ac16f5f49ff1d94f22d55bf582d353d3c313a1e8dd9160409182519182526020820152a2565b546001600160a01b0316823b156108c3576040516309ad4dd960e01b81526001600160a01b03918216600482015291166024820152604481018590529082908290606490829084905af180156108b8576108a0575b808061080e565b6108ab8280926106cf565b6108b55780610899565b80fd5b6040513d84823e3d90fd5b8380fd5b546001600160a01b0316833b1561015f576040516309ad4dd960e01b81526001600160a01b0391821660048201529083166024820152604481018690525f8160648183885af1801561092d5715610807576109259194505f906106cf565b5f925f610807565b6040513d5f823e3d90fd5b60405163095ea7b360e01b5f52846004525f60245260205f604481808d5af19060015f51148216156109d6575b604052156109a25760405163095ea7b360e01b5f52846004528a60245260205f604481808d5af19060015f51148216156109b5575b604052610801575b87635274afe760e01b5f5260045260245ffd5b9060018115166109cd57893b15153d1516169061099a565b503d5f823e3d90fd5b9060018115166109cd57893b15153d15161690610965565b90893b15153d151616906107f8565b505f96505050505050565b630da3333b60e01b5f5260045ffd5b5060088601546001600160a01b031633141561074b565b631966391b60e11b5f5260045ffd5b6002546001600160a01b03163303610a2e576001600160a01b03169081158015610acb575b61051d575f82815260036020526040902060070180546001600160a01b039283169392169190838314610ac55780546001600160a01b031916841790557f38f9c71383b6e3fe639172c6b3a3d4418fa722b4abf99bfd8e31f92bd5ea23f05f80a4565b50505050565b506001600160a01b03811615610a62565b92936001600160a01b038416939291841561051d576002546001600160a01b031615610a2e57610b0c3385610e4f565b15610d97578015610cc8576001600160a01b038316158015610d86575b8015610d77575b610d68576040516370a0823160e01b8152306004820152602081602481895afa90811561092d575f91610d36575b50604051916323b872dd60e01b5f52336004523060245260445260205f606481808a5af160015f5114811615610d17575b826040525f60605215610d04576370a0823160e01b8252306004830152602082602481895afa801561092d575f90610cd0575b610bcc92506106c2565b948515610cc857610bf492855f52600360205260405f2094610bee4287610dde565b85610fa3565b600481018054610c14610c078683610670565b9180610cb4575f90610691565b6309660180860286810463096601800361067d57610c368391610c3b93610670565b6106a4565b9155426005830155610c4d8142610670565b60068301556309660180036309660180811161067d57610c6d90426106c2565b90816002820155610c7f848254610670565b905560405192835260208301527f967ad762aa9070ada8db64577288e214771e89667066ae38e8750cb8a86c542960403393a3565b610cc24260068701546106c2565b90610691565b505050505050565b506020823d602011610cfc575b81610cea602093836106cf565b8101031261015f57610bcc9151610bc2565b3d9150610cdd565b85635274afe760e01b5f5260045260245ffd5b6001811516610d2d57863b15153d151616610b8f565b823d5f823e3d90fd5b90506020813d602011610d60575b81610d51602093836106cf565b8101031261015f57515f610b5e565b3d9150610d44565b63a7d7d0c560e01b5f5260045ffd5b5061271061ffff831611610b30565b506001600160a01b03861615610b29565b63ba13c3d960e01b5f5260045ffd5b60025f51602061110e5f395f51905f525414610dcf5760025f51602061110e5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b600590610deb83826110b4565b80610df557500155565b60048201610e048282546106c2565b9055610e1560038301918254610670565b90550155565b5f546001600160a01b0316330361046b57565b51906001600160a01b038216820361015f57565b5190811515820361015f57565b6002546001600160a01b0316908115610f9c57604051631e7945ad60e11b81526001600160a01b0390911660048201529061012090829060249082905afa90811561092d575f91610eb1575b50602001516001600160a01b0391821691161490565b9050610120813d8211610f94575b81610ecd61012093836106cf565b8101031261015f5760405190610120820182811067ffffffffffffffff8211176106f157604052610efd81610e2e565b8252610f0b60208201610e2e565b6020830152610f1c60408201610e2e565b6040830152610f2d60608201610e2e565b6060830152610f3e60808201610e2e565b608083015260a081015161ffff8116810361015f57610f88916101009160a0850152610f6c60c08201610e42565b60c0850152610f7d60e08201610e42565b60e085015201610e42565b6101008201525f610e9b565b3d9150610ebf565b5050505f90565b91600483015415806110a8575b611001575050600801546001600160a01b0380821692169190911480159290610feb575b5050610fdc57565b638a621fd960e01b5f5260045ffd5b61ffff91925081169160a01c1614155f80610fd4565b6007830180549295937fa92f5227e67257769e49f294586ea055f8d5714595dfdcc2d8a0cac8a3e50fbe93602093600892916001600160a01b031615611087575b500180546001600160b01b0319166001600160a01b0396871690811760a087901b61ffff60a01b1617909155905460405161ffff9590951685529095908516941692a4565b83546001600160a01b0319166001600160a01b03919091161783555f611042565b50600383015415610fb0565b90600482015491821580156110ff575b610f9c57600681015490818310156110f95792610cc2610c36926110f060056110f697015480926106c2565b946106c2565b90565b50505090565b5060058101548211156110c456fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220f824fefce66b4cf1569e7d371fa6370cdccc1c2f8a88bdedc443c0ce47e0831a64736f6c6343000823003360e0346100c157601f614e1938819003918201601f19168301916001600160401b038311848410176100c5578084926060946040528339810103126100c1578051906001600160a01b03821682036100c1576020810151906001600160a01b03821682036100c15760400151916001600160a01b03831683036100c15760805260a05260c052604051614d3f90816100da823960805181818160e90152610182015260a05181818160a5015261028d015260c051818181605d01526102b50152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c9081638dabdc831461011857508063c45a0155146100d4578063c4b7de97146100905763f1f5c99314610048575f80fd5b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5f80fd5b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461008c576101e036600319011261008c576004359067ffffffffffffffff821161008c578160040191610160600319823603011261008c5760c036602319011261008c5760a03660e319011261008c57610184356001600160a01b038116939084900361008c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316933385900361068e576101bd828061069d565b9050158015610679575b8015610663575b801561064b575b8015610632575b8015610619575b61057e5760848301916101006102026101fc85846106d0565b8061069d565b90501180156105f6575b80156105d3575b80156105b0575b801561058d575b61057e576020850194828652610124850135604082015260408152606081019581871067ffffffffffffffff88111761056a578660405281519020956128b1808301906060820183811067ffffffffffffffff82111761056a578a916107388539526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660808301527f0000000000000000000000000000000000000000000000000000000000000000811660a083015260e4359081169081900361008c5760c08201526101043561ffff811680910361008c5760e08201526101243561ffff811680910361008c576101008201526101443561ffff811680910361008c576101208201526101643561ffff811680910361008c576101408201526024356001600160a01b0381169081900361008c576101608201526044356001600160a01b0381169081900361008c576101808201526064356101a08201526084356101c082015260a4356101e082015260c43580151580910361008c5761020082015287926101c0910301905ff5801561055f576001600160a01b0316956103ce828061069d565b929060646103df602489018461069d565b9390976104076103ff6103f560448d018561069d565b95909c018461069d565b9290936106d0565b936040519a611d2194858d01998d8b1067ffffffffffffffff8c111761056a578d9c610515996104528f96610460948f6101409061047c9d61046e9b612fe9903981815201916106e5565b8d810360208f0152916106e5565b918a830360408c01526106e5565b9187830360608901526106e5565b84810360808601526105076104fc6104e16104c66104ab61049d8780610705565b60a0885260a08801916106e5565b6104b86020880188610705565b9087830360208901526106e5565b6104d36040870187610705565b9086830360408801526106e5565b6104ee6060860186610705565b9085830360608701526106e5565b926080810190610705565b9160808185039101526106e5565b9260a08301528660c083015260e08201526101a4356101008201526101206101c43591015203905ff5801561055f57604080516001600160a01b0390921682526020820192909252f35b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b635e765b2560e11b5f5260045ffd5b506101006105a861059e85846106d0565b608081019061069d565b905011610221565b506101006105cb6105c185846106d0565b606081019061069d565b90501161021a565b506101006105ee6105e485846106d0565b604081019061069d565b905011610213565b5061010061061161060785846106d0565b602081019061069d565b90501161020c565b5061080061062a606485018461069d565b9050116101e3565b50610200610643604485018461069d565b9050116101dc565b50601061065b602485018461069d565b9050116101d5565b50610671602484018361069d565b9050156101ce565b506040610686838061069d565b9050116101c7565b631966391b60e11b5f5260045ffd5b903590601e198136030182121561008c570180359067ffffffffffffffff821161008c5760200191813603831361008c57565b903590609e198136030182121561008c570190565b908060209392818452848401375f828201840152601f01601f1916010190565b9035601e198236030181121561008c57016020813591019167ffffffffffffffff821161008c57813603831361008c5756fe610220604052346104b1576040516128b138819003601f8101601f191683016001600160401b038111848210176104b557839282916040528339810103906101c082126104b15761004f816104c9565b602082015190916001600160a01b0382168083036104b15760408201516001600160a01b038116938482036104b15760a0605f198801126104b1576040519660a088016001600160401b038111898210176104b5576040526100b3606086016104c9565b88526100c1608086016104dd565b95602089019687526100d560a087016104dd565b60408a019081526100e860c088016104dd565b60608b015260c06100fb60e089016104dd565b60808c019081529360ff1901126104b1576040519860c08a016001600160401b0381118b8210176104b55760405261013661010089016104c9565b8a5261014561012089016104c9565b9860208b019a8a8c526101408a015197604082019889526101608b015199606083019a8b526101a06101808d01519c608085019d8e5201519c8d801515036104b15760a084019d8e5260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556001600160a01b0386169788159283156104a8575b50821561049f575b50811561048d575b5061047e578d516001600160a01b031615801561046e575b801561045e575b8015610451575b8015610440575b8015610415575b61040657885180159081156103f5575b506103e65761ffff978896879560a05260c05260e0526101005260018060a01b0390511660805260018060a01b038b51169a6001549c60018060a01b039051166101205260018060a01b039051166101405251166101605251166101805251166101a052516101c052516101e052516102005260ff60a01b9051151560a01b169160018060a81b03191617176001556040516123c490816104ed823960805181818161029e01528181610a7301528181610bd30152818161112301528181611eab0152611ff3015260a05181818161044801528181610605015281816106e90152610f7f015260c051818181610f350152611347015260e05181818161040401528181611edb0152611f6d01526101005181818161021c015261152c01526101205181818161104d015281816114e401526115be0152610140518181816111670152611596015261016051818181610b08015281816113b901526121760152610180518181816110cd01526121a701526101a051818181610aca01526116a401526101c0518181816103cc015281816105c1015261183e01526101e0518181816111f4015281816118850152611a1901526102005181818161048e015281816118b80152611a4f0152f35b63bc0ecfe360e01b5f5260045ffd5b6001600160801b031090505f61021b565b637a34030f60e01b5f5260045ffd5b5089518b51810180911161042c576107d01061020b565b634e487b7160e01b5f52601160045260245ffd5b5061271061ffff8851161015610204565b5061ffff875116156101fd565b5061271061ffff865116116101f6565b5061271061ffff845116116101ef565b63d92e233d60e01b5f5260045ffd5b6001600160a01b03161590505f6101d7565b1591505f6101cf565b1592505f6101c7565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036104b157565b519061ffff821682036104b15756fe60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f00000000000000000000000000000000000000000000000000000000000000006112ac565b3461020357602036600319011261020357600435801515809103610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000000166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f0000000000000000000000000000000000000000000000000000000000000000611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448401527f00000000000000000000000000000000000000000000000000000000000000001660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000000016101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f00000000000000000000000000000000000000000000000000000000000000009061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000000080612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000000090611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f00000000000000000000000000000000000000000000000000000000000000001682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c6343000823003361012060405234610ee557611d218038038061001a81610ee9565b92833981019061014081830312610ee55780516001600160401b038111610ee55782610047918301610f0e565b60208201519091906001600160401b038111610ee55783610069918301610f0e565b60408201519091906001600160401b038111610ee5578461008b918301610f0e565b60608201519094906001600160401b038111610ee557816100ad918401610f0e565b60808301519091906001600160401b038111610ee557830160a081830312610ee55760405160a081016001600160401b038111828210176107195760405281516001600160401b038111610ee55783610107918401610f0e565b815260208201516001600160401b038111610ee55783610128918401610f0e565b6020820190815260408301519091906001600160401b038111610ee55784610151918501610f0e565b6040820190815260608401519093906001600160401b038111610ee5578561017a918301610f0e565b6060830190815260808201519095906001600160401b038111610ee5576101a19201610f0e565b94608082019586526101b560a08801610f5f565b996101c260c08901610f5f565b986101cf60e08a01610f5f565b906101206101008b01519a01519b80519060018060401b0382116107195760035490600182811c92168015610edb575b60208310146106fb5781601f849311610e65575b50602090601f8311600114610dff575f92610df4575b50508160011b915f199060031b1c1916176003555b8051906001600160401b0382116107195760045490600182811c92168015610dea575b60208310146106fb5781601f849311610d74575b50602090601f8311600114610d0e575f92610d03575b50508160011b915f199060031b1c1916176004555b6001600160a01b038c16158015610cf2575b8015610ce1575b610cd2578b60805260a0528860c05287158015610cc6575b610cb75760e08890526101008a90528051906001600160401b0382116107195760055490600182811c92168015610cad575b60208310146106fb5781601f849311610c53575b50602090601f8311600114610bed575f92610be2575b50508160011b915f199060031b1c1916176005555b8051906001600160401b0382116107195760065490600182811c92168015610bd8575b60208310146106fb5781601f849311610b62575b50602090601f8311600114610afc575f92610af1575b50508160011b915f199060031b1c1916176006555b518051906001600160401b0382116107195760075490600182811c92168015610ae7575b60208310146106fb5781601f849311610a71575b50602090601f8311600114610a0b575f92610a00575b50508160011b915f199060031b1c1916176007555b518051906001600160401b0382116107195760085490600182811c921680156109f6575b60208310146106fb5781601f849311610980575b50602090601f831160011461091a575f9261090f575b50508160011b915f199060031b1c1916176008555b518051906001600160401b0382116107195760095490600182811c92168015610905575b60208310146106fb5781601f84931161088f575b50602090601f8311600114610829575f9261081e575b50508160011b915f199060031b1c1916176009555b518051906001600160401b03821161071957600a5490600182811c92168015610814575b60208310146106fb5781601f84931161079e575b50602090601f8311600114610738575f9261072d575b50508160011b915f199060031b1c191617600a555b518051906001600160401b03821161071957600b5490600182811c9216801561070f575b60208310146106fb5781601f849311610685575b50602090601f831160011461061f575f92610614575b50508160011b915f199060031b1c191617600b555b828103908111610600576105a691610f73565b806105f0575b604051610d3a9081610fe782396080518181816101cb0152610261015260a0518161059d015260c05181610496015260e05181610600015261010051816101430152f35b6105f991610f73565b5f806105ac565b634e487b7160e01b5f52601160045260245ffd5b015190505f8061057e565b600b5f9081528281209350601f198516905b81811061066d5750908460019594939210610655575b505050811b01600b55610593565b01515f1960f88460031b161c191690555f8080610647565b92936020600181928786015181550195019301610631565b8281111561056857600b5f52909150601f830160051c7f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9602085106106f3575b849392601f0160051c82900391015f5b8281106106e3575050610568565b5f818301558594506001016106d5565b5f91506106c5565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610554565b634e487b7160e01b5f52604160045260245ffd5b015190505f8061051b565b600a5f9081528281209350601f198516905b818110610786575090846001959493921061076e575b505050811b01600a55610530565b01515f1960f88460031b161c191690555f8080610760565b9293602060018192878601518155019501930161074a565b8281111561050557600a5f52909150601f830160051c7fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a86020851061080c575b849392601f0160051c82900391015f5b8281106107fc575050610505565b5f818301558594506001016107ee565b5f91506107de565b91607f16916104f1565b015190505f806104b8565b60095f9081528281209350601f198516905b818110610877575090846001959493921061085f575b505050811b016009556104cd565b01515f1960f88460031b161c191690555f8080610851565b9293602060018192878601518155019501930161083b565b828111156104a25760095f52909150601f830160051c7f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af602085106108fd575b849392601f0160051c82900391015f5b8281106108ed5750506104a2565b5f818301558594506001016108df565b5f91506108cf565b91607f169161048e565b015190505f80610455565b60085f9081528281209350601f198516905b8181106109685750908460019594939210610950575b505050811b0160085561046a565b01515f1960f88460031b161c191690555f8080610942565b9293602060018192878601518155019501930161092c565b8281111561043f5760085f52909150601f830160051c7ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3602085106109ee575b849392601f0160051c82900391015f5b8281106109de57505061043f565b5f818301558594506001016109d0565b5f91506109c0565b91607f169161042b565b015190505f806103f2565b60075f9081528281209350601f198516905b818110610a595750908460019594939210610a41575b505050811b01600755610407565b01515f1960f88460031b161c191690555f8080610a33565b92936020600181928786015181550195019301610a1d565b828111156103dc5760075f52909150601f830160051c7fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860208510610adf575b849392601f0160051c82900391015f5b828110610acf5750506103dc565b5f81830155859450600101610ac1565b5f9150610ab1565b91607f16916103c8565b015190505f8061038f565b60065f9081528281209350601f198516905b818110610b4a5750908460019594939210610b32575b505050811b016006556103a4565b01515f1960f88460031b161c191690555f8080610b24565b92936020600181928786015181550195019301610b0e565b828111156103795760065f52909150601f830160051c7ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f60208510610bd0575b849392601f0160051c82900391015f5b828110610bc0575050610379565b5f81830155859450600101610bb2565b5f9150610ba2565b91607f1691610365565b015190505f8061032d565b60055f9081528281209350601f198516905b818110610c3b5750908460019594939210610c23575b505050811b01600555610342565b01515f1960f88460031b161c191690555f8080610c15565b92936020600181928786015181550195019301610bff565b828111156103175790915060055f5260205f20601f840160051c9060208510610ca5575b849392601f0160051c82900391015f5b828110610c95575050610317565b5f81830155859450600101610c87565b5f9150610c77565b91607f1691610303565b6305d7ba1960e11b5f5260045ffd5b508760021c8a116102d1565b63d92e233d60e01b5f5260045ffd5b506001600160a01b038116156102b9565b506001600160a01b038a16156102b2565b015190505f8061028b565b60045f9081528281209350601f198516905b818110610d5c5750908460019594939210610d44575b505050811b016004556102a0565b01515f1960f88460031b161c191690555f8080610d36565b92936020600181928786015181550195019301610d20565b828111156102755760045f52909150601f830160051c7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b60208510610de2575b849392601f0160051c82900391015f5b828110610dd2575050610275565b5f81830155859450600101610dc4565b5f9150610db4565b91607f1691610261565b015190505f80610229565b60035f9081528281209350601f198516905b818110610e4d5750908460019594939210610e35575b505050811b0160035561023e565b01515f1960f88460031b161c191690555f8080610e27565b92936020600181928786015181550195019301610e11565b828111156102135760035f52909150601f830160051c7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b60208510610ed3575b849392601f0160051c82900391015f5b828110610ec3575050610213565b5f81830155859450600101610eb5565b5f9150610ea5565b91607f16916101ff565b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761071957604052565b81601f82011215610ee5578051906001600160401b03821161071957610f3d601f8301601f1916602001610ee9565b9282845260208383010111610ee557815f9260208093018386015e8301015290565b51906001600160a01b0382168203610ee557565b6001600160a01b0316908115610fd357600254908082018092116106005760207fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef915f9360025584845283825260408420818154019055604051908152a3565b63ec442f0560e01b5f525f60045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c806306fdde031461073b578063095ea7b31461069357806318160ddd1461067657806323b872dd1461063e578063313ce56714610623578063378dc3dc146105e957806342966c68146105cc578063536dac9b1461058857806353cd512a146104fc57806370a08231146104c55780637165485d146104815780637284e4161461046657806379cc67901461043457806395d89b4114610340578063a9059cbb1461030f578063abb1dc44146101fa578063d5f39488146101b6578063dd62ed3e14610166578063e029607c1461012c5763fb7f21eb146100f5575f80fd5b34610128575f36600319011261012857610124610110610966565b6040519182916020835260208301906107f6565b0390f35b5f80fd5b34610128575f3660031901126101285760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346101285760403660031901126101285761017f61081a565b610187610830565b6001600160a01b039182165f908152600160209081526040808320949093168252928352819020549051908152f35b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610128575f366003190112610128576060608060405161021a81610846565b8281528260208201528260408201528280820152015261029461023b610966565b610124610246610898565b6102a2610251610ac8565b9160405195869560018060a01b037f00000000000000000000000000000000000000000000000000000000000000001687526080602088015260808701906107f6565b9085820360408701526107f6565b838103606085015260806102fe6102ec6102da6102c8865160a0875260a08701906107f6565b602087015186820360208801526107f6565b604086015185820360408701526107f6565b606085015184820360608601526107f6565b9201519060808184039101526107f6565b346101285760403660031901126101285761033561032b61081a565b6024359033610bc3565b602060405160018152f35b34610128575f366003190112610128576040515f6004548060011c9060018116801561042a575b602083108114610416578285529081156103f25750600114610394575b6101248361011081850382610876565b60045f9081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b8082106103d857509091508101602001610110610384565b9192600181602092548385880101520191019092916103c0565b60ff191660208086019190915291151560051b840190910191506101109050610384565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610367565b346101285760403660031901126101285761046461045061081a565b6024359061045f823383610b20565b610c80565b005b34610128575f36600319011261012857610124610110610898565b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610128576020366003190112610128576001600160a01b036104e661081a565b165f525f602052602060405f2054604051908152f35b34610128575f36600319011261012857610550610517610ac8565b61012481519161057a60208201519161056c604082015161055e6080606085015194015195604051998a9960a08b5260a08b01906107f6565b9089820360208b01526107f6565b9087820360408901526107f6565b9085820360608701526107f6565b9083820360808501526107f6565b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346101285760203660031901126101285761046460043533610c80565b34610128575f3660031901126101285760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610128575f36600319011261012857602060405160128152f35b346101285760603660031901126101285761033561065a61081a565b610662610830565b60443591610671833383610b20565b610bc3565b34610128575f366003190112610128576020600254604051908152f35b34610128576040366003190112610128576106ac61081a565b602435903315610728576001600160a01b031690811561071557335f52600160205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b634a1406b160e11b5f525f60045260245ffd5b63e602df0560e01b5f525f60045260245ffd5b34610128575f366003190112610128576040515f6003548060011c906001811680156107ec575b602083108114610416578285529081156103f2575060011461078e576101248361011081850382610876565b60035f9081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b8082106107d257509091508101602001610110610384565b9192600181602092548385880101520191019092916107ba565b91607f1691610762565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361012857565b602435906001600160a01b038216820361012857565b60a0810190811067ffffffffffffffff82111761086257604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff82111761086257604052565b604051905f6006548060011c916001821691821561095c575b60208410831461041657838652859290811561093d57506001146108de575b6108dc92500383610876565b565b5060065f90815290917ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f5b8183106109215750509060206108dc928201016108d0565b6020919350806001915483858901015201910190918492610909565b602092506108dc94915060ff191682840152151560051b8201016108d0565b92607f16926108b1565b604051905f6005548060011c9160018216918215610a08575b60208410831461041657838652859290811561093d57506001146109a9576108dc92500383610876565b5060055f90815290917f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b8183106109ec5750509060206108dc928201016108d0565b60209193508060019154838589010152019101909184926109d4565b92607f169261097f565b90604051915f8154908160011c9260018316928315610abe575b602085108414610416578487528693908115610a9c5750600114610a58575b506108dc92500383610876565b90505f9291925260205f20905f915b818310610a805750509060206108dc928201015f610a4b565b6020919350806001915483858901015201910190918492610a67565b9050602092506108dc94915060ff191682840152151560051b8201015f610a4b565b93607f1693610a2c565b60405190610ad582610846565b81610ae06007610a12565b8152610aec6008610a12565b6020820152610afb6009610a12565b6040820152610b0a600a610a12565b60608201526080610b1b600b610a12565b910152565b6001600160a01b039081165f818152600160209081526040808320948616835293905291909120549291905f198410610b5a575b50505050565b828410610ba0578015610728576001600160a01b03821615610715575f52600160205260405f209060018060a01b03165f5260205260405f20910390555f808080610b54565b508290637dc7a0d960e11b5f5260018060a01b031660045260245260445260645ffd5b6001600160a01b0316908115610c6d576001600160a01b0316918215610c5a57815f525f60205260405f2054818110610c4157817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f525f84520360405f2055845f525f825260405f20818154019055604051908152a3565b8263391434e360e21b5f5260045260245260445260645ffd5b63ec442f0560e01b5f525f60045260245ffd5b634b637e8f60e11b5f525f60045260245ffd5b9091906001600160a01b03168015610c6d57805f525f60205260405f2054838110610cea576020845f94957fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef938587528684520360408620558060025403600255604051908152a3565b915063391434e360e21b5f5260045260245260445260645ffdfea26469706673582212201aca4a2b55465a13b08ec36674fca845ba424b771f3ea8c117e712cc7ec430c264736f6c63430008230033a2646970667358221220272ca8beeb8120e5fcea1f6abad3910174ee29119b3514eea8a2ceccb1bdce8764736f6c6343000823003300000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d00000000000000000000000078f3556b67e17df817d51ef5a990cdaf09e8d3a9","recompiledBytecode":"0x61012080604052346103d3575f90604081619f5880380380916100228285610457565b8339810103126103d35780516001600160a01b03811691908290036103d357602001516001600160a01b0381168082036103d357821561044457600180546001600160a01b03199081169091555f805491821685178155604051939185916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556601c6bf526340006002556103e86003556126ac6004556003600555813b1561043557600483602093819360e05263313ce56760e01b82525afa9081156103c8575f916103f9575b50601260ff8216116103eb5761010052600680546001600160a01b0319168217905560405160a081016001600160401b038111828210176103d7576040908152828252610bb86020830152611388828201526064606083015261012c608090920191909152600880546001600160e01b031916600160a01b600160e01b0319909316929092176625800c8271017760a31b17909155516107ca8082018281106001600160401b038211176103d757829161369a833903905ff080156103c8576080819052604051906112db8083016001600160401b038111848210176103d7576060928492613e6484393080835260208301526001600160a01b031660408201520301905ff080156103c85760a08190526001600160a01b0316803b156103d3575f8091602460405180948193630b768f0160e31b83523060048401525af180156103c8576103b5575b5060805160a05160405191614e19808401926001600160a01b039081169216906001600160401b038411858510176103a1579160609391859361513f85393083526020830152604082015203019082f080156103945760c052604080519081016001600160401b0381118282101761038057906001916040526717508f1956a80000815260406020820193838552808052600e6020522090518155019051151560ff8019835416911617905560405161321f908161047b8239608051818181610655015281816111ba0152612f3f015260a05181818161031b0152612611015260c051818181610c22015281816116c90152612b69015260e05181818161170d01526122b401526101005181818161058a01526123340152f35b634e487b7160e01b83526041600452602483fd5b50604051903d90823e3d90fd5b634e487b7160e01b86526041600452602486fd5b6103c191505f90610457565b5f5f610266565b6040513d5f823e3d90fd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b62fc7cad60e51b5f5260045ffd5b90506020813d60201161042d575b8161041460209383610457565b810103126103d3575160ff811681036103d3575f61011c565b3d9150610407565b63d92e233d60e01b5f5260045ffd5b631e4fbdf760e01b5f525f60045260245ffd5b601f909101601f19168101906001600160401b038211908210176103d75760405256fe6080806040526004361015610012575f80fd5b5f905f3560e01c90816327cca59f14612018575080632931861b14611fc3578063315226d914611b9157806334fcaa3714611ec35780633cf28b5a14611d465780633d3d2d5814611c7257806345fb206314611c47578063470ef5fc14611bb357806350e25ac214611b96578063523af32814611b9157806354a4931c14611b7457806354faf9c314611b0357806358373f0414611ade5780636499386614611aad5780636783774b14611a905780636cd5bce4146119ff5780636dc97d6a146119885780636e47a1881461191b5780636f471f2d146118c5578063715018a614611862578063767b7c16146117c157806379ba50971461173c5780638009b7bd146116f8578063858f5964146116b457806389a69bd8146116455780638a36a6bb1461161d5780638da5cb5b146115f65780638e8d8ec5146114e55780639b924452146114bd5780639beacf4a1461145e5780639c5693eb146107cf578063abb918d814610786578063b18f1db114610684578063c4b7de971461063f578063c50497ae14610618578063cf3cf573146105fa578063df41ead2146105d7578063e30c3978146105ae578063e68b52e714610570578063e7ed38bd1461034a578063f1f5c99314610305578063f2fde38b14610298578063f325a5fb1461027a578063f9b3b8d9146102475763ffcb6e9f1461020d575f80fd5b3461024457602036600319011261024457602061022b60043561254a565b905460405160039290921b1c6001600160a01b03168152f35b80fd5b5034610244576020366003190112610244576020906004358152600c8252604060018060a01b0391205416604051908152f35b50346102445780600319360112610244576020600354604051908152f35b5034610244576020366003190112610244576102b2612032565b6102ba6126ee565b600180546001600160a01b0319166001600160a01b0392831690811790915582549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610244576101203660031901126102445760643560443560243560a036608319011261056c5761037a6126ee565b6103e881118015610561575b8015610559575b801561054d575b8015610535575b801561051f575b8015610509575b80156104f3575b80156104e0575b80156104c9575b6104ba5760048035600255600391909155556005556001600160a01b036103e36124cc565b166001600160601b0360a01b60085416176008556103ff6124f6565b6008805461ffff60a01b191660a09290921b61ffff60a01b16919091179055610426612507565b6008805461ffff60b01b191660b09290921b61ffff60b01b1691909117905561044d612518565b6008805461ffff60c01b191660c09290921b61ffff60c01b16919091179055610474612529565b6008805461ffff60d01b191660d09290921b61ffff60d01b169190911790557f8f70233f68d766cfab4ff696858b5eba8fa61e09191134073df956473102569b8180a180f35b630256965f60e01b8452600484fd5b5061271061ffff6104d8612529565b1610156103be565b5061ffff6104ec612529565b16156103b7565b506103e861ffff610502612518565b16116103b0565b5061271061ffff610518612507565b16116103a9565b5061271061ffff61052e6124f6565b16116103a2565b506001600160a01b036105466124cc565b161561039b565b50620151808311610394565b50821561038d565b506126ac8211610386565b8380fd5b5034610244578060031936011261024457602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346102445780600319360112610244576001546040516001600160a01b039091168152602090f35b503461024457806003193601126102445760206040516717508f1956a800008152f35b50346102445780600319360112610244576020600254604051908152f35b503461024457806003193601126102445760206040516b033b2e3c9fd0803ce80000008152f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346102445760403660031901126102445761069e612032565b906024359182151590818403610782576106b790612562565b60038101546001600160a01b031633141580610767575b6107585760048101805460ff60b01b191694151560b01b60ff60b01b16949094179093559091829190600101546001600160a01b031690813b15610754578291602483926040519485938492639a9b567d60e01b845260048401525af18015610749576107385750f35b8161074291612177565b6102445780f35b6040513d84823e3d90fd5b5050fd5b632e7e4e5160e21b8352600483fd5b5082546001600160a01b0316331415806106ce5750836106ce565b8280fd5b50346102445760403660031901126102445760209060ff906040906001600160a01b036107b1612032565b168152600d8452818120602435825284522054166040519015158152f35b50606036600319011261127c576001600160401b036004351161127c576101606004353603600319011261127c576108056126ee565b61080d61280f565b60243515801561143c575b61142e5761082760443561228f565b9161010460043501350361141f5760025434036114105761084c60c46004350161253b565b61ffff60035491161180156113e1575b6113d257335f52600d60205260405f2061012460043501355f5260205260ff60405f2054166113c357602061089c610144600435016004356004016130da565b9050116113b457335f52600d60205260405f2061012460043501355f5260205260405f20600160ff1982541617905560018060a01b036108e060a4600435016124e2565b166113a05733925b6acecb8f27f4200f3a0000009261ffff60085460c01c169161090e60c46004350161253b565b61ffff61091f60e46004350161310f565b916040519561092d8761215c565b5f875260018060a01b038a1660208801528760408801526060870152166080850152151560a084015260405192638dabdc8360e01b84526101e06004850152610a186109f06109c86109a061098c600435600401600435600401613130565b6101606101e48b01526103448a0191613161565b6109b4602460043501600435600401613130565b8983036101e319016102048b015290613161565b6109dc604460043501600435600401613130565b8883036101e319016102248a015290613161565b610a04606460043501600435600401613130565b8783036101e3190161024489015290613161565b60043560848101359190360360a2190182121561127c576004610ad99281350101906101e31987820301610264880152610acb610ac0610aa5610a8a610a6f610a618780613130565b60a0885260a0880191613161565b610a7c6020880188613130565b908783036020890152613161565b610a976040870187613130565b908683036040880152613161565b610ab26060860186613130565b908583036060870152613161565b926080810190613130565b916080818503910152613161565b906001600160a01b03610af060043560a40161205e565b1661028486015260c4600435013561ffff811680910361127c576102a4860152610b1e60e4600435016120d5565b15156102c48601526004356101048101356102e48701526101248101356103048701526101448101359036036022190181121561127c576004908135010160208101926001600160401b0382351161127c57813560051b3603841361127c578681036101e319016103248801528135815291928692602001915f5b8135811061137057505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190610bfb60e48301612701565b336101848301526b033b2e3c9fd0803ce80000006101a48301526101c4820189905203815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af193841561124f575f935f95611327575b50868486610e03610c7160c46004350161253b565b610de861ffff610c8560e46004350161310f565b926004604051610c948161210a565b60018060a01b0389168152602081019760018060a01b031688526040810199338b52606082019060018060a01b03168152608082019a5f8c528560a084019516855260c08301971515885260e083019960018b5261010084019b60018d5260018060a01b03165f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b51845460ff60b01b191690151560b01b60ff60b01b16178455565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790556001600160a01b0384165f908152600a602052604090206007198101611294575b50600b54600160401b8110156112805784610e73826001610e979401600b5561254a565b81546001600160a01b0393841660039290921b91821b9390911b1916919091179055565b610eac610144600435016004356004016130da565b979050600288018811610f7d57610ee06002610ec9818b01613181565b99610ed76040519b8c612177565b01808a52613181565b601f19013660208a013733610ef489613198565b526001600160a01b0316610f07886131a5565b525f5b610f1f610144600435016004356004016130da565b9050811015610fa557610f3d610144600435016004356004016130da565b821015610f9157610f52908260051b016124e2565b90600281018111610f7d57600191610f6d600283018b6131b5565b90838060a01b0316905201610f0a565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5085876001600160a01b0387163b1561127c576040805163251b648160e21b81526001600160a01b03881660048201526024810191909152815160448201819052909182916064830191602001905f5b81811061125a57505f93928390039150829050836001600160a01b038c165af1801561124f5761123a575b50600254806111ad575b506110f9916110b29160405190858252826020830152600160408301526060820152339060018060a01b038916907ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b608060018060a01b038b1692a46024358452600c6020526040842080546001600160a01b0319166001600160a01b03881617905561273e565b916001604051916110c283612126565b84835260406020840191838352838060a01b0389168152600e602052209251835551151591019060ff801983541691151516179055565b60408051918252600160208301526001600160a01b038416917fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79190a260408051604435815260208101929092526001600160a01b03831691602435917ff58d88bf88870587ec1fdf8ab973f10a093d9dc3c1a243e32f41fa5d73eda1b791a360015f5160206131ca5f395f51905f5255604080516001600160a01b039283168152929091166020830152819081015b0390f35b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b1561123657906024869260405194859384926301aba89b60e71b845260048401525af1801561122b57908491611216575b5061102a565b8161122091612177565b610782578287611210565b6040513d86823e3d90fd5b8580fd5b6112479193505f90612177565b5f9186611020565b6040513d5f823e3d90fd5b82516001600160a01b0316845285945060209384019390920191600101610ff5565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155611321905b600854815461ffff60b01b191661ffff60b01b909116178155600854815461ffff60c01b191661ffff60c01b909116178155600854815461ffff60d01b191661ffff60d01b909116179055565b5f610e4f565b935093506040833d604011611368575b8161134460409383612177565b8101031261127c57611361602061135a8561311c565b940161311c565b935f610c5c565b3d9150611337565b919493509160019060209081906001600160a01b0361138e8961205e565b16815201950191019187939492610b99565b6113ae60a4600435016124e2565b926108e8565b630256965f60e01b5f5260045ffd5b630ced304360e01b5f5260045ffd5b6326b5197760e21b5f5260045ffd5b506107d061140a61ffff6113f960c46004350161253b565b1661ffff60085460c01c16906120e2565b1161085c565b637e6d78a560e01b5f5260045ffd5b631e5d0a3f60e11b5f5260045ffd5b62d532eb60e71b5f5260045ffd5b506024355f908152600c60205260409020546001600160a01b03161515610818565b3461127c57602036600319011261127c576001600160a01b0361147f612032565b165f908152600f60209081526040918290208054600182015460029092015484516001600160a01b0390921682529281019190915291820152606090f35b3461127c575f36600319011261127c576007546040516001600160a01b039091168152602090f35b3461127c57606036600319011261127c576114fe612032565b602435906044358015159182820361127c576115186126ee565b6001600160a01b031692831515806115d9575b6115ca57801580156115ba575b6113b4576115a07fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79360016040519161157083612126565b84835260208301908152875f52600e60205260405f209251835551151591019060ff801983541691151516179055565b60408051918252911515602082015290819081015b0390a2005b506001600160801b038111611538565b6349285dfb60e01b5f5260045ffd5b50835f52600960205260ff600460405f20015460b81c161561152b565b3461127c575f36600319011261127c575f546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c576006546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c5761165d61224e565b506111a960405161166d81612141565b61ffff60085460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c57600154336001600160a01b03909116036117ae57600180546001600160a01b03199081169091555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461127c57602036600319011261127c576117da612032565b6117e26126ee565b600754906001600160a01b03821661185357803b15611844576001600160a01b03166001600160a01b03199190911681176007556040519081527f56b32d3633fed72f97c4df44a78b5fa04f1d662d4bddebcd8a9b216d26d093ad90602090a1005b63d92e233d60e01b5f5260045ffd5b63a741a04560e01b5f5260045ffd5b3461127c575f36600319011261127c5761187a6126ee565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461127c57602036600319011261127c576001600160a01b036118e6612032565b165f52600e60205260405f2060ff6001825492015416906111a960405192839283909291602090604083019483521515910152565b3461127c57602036600319011261127c57611934612032565b61193c6126ee565b6001600160a01b03165f818152600f60205260408120818155600181018290556002018190557f30241dede93b23e050576be65d204d53b18e8c6d9f75006095bfd422094d87569080a2005b604036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c576119d2906119c0612048565b6119c861280f565b3391600401612847565b60015f5160206131ca5f395f51905f5255604080516001600160a01b039384168152919092166020820152f35b606036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c57611a33612048565b604435906001600160a01b03821680830361127c57611a5061280f565b6007546001600160a01b0316331480159190611a87575b50611a78576119d292600401612847565b63754f554b60e11b5f5260045ffd5b90501584611a67565b3461127c575f36600319011261127c576020600554604051908152f35b3461127c57602036600319011261127c576060611acb60043561228f565b9060405192835260208301526040820152f35b3461127c57602036600319011261127c57611af7612032565b50602060405160018152f35b3461127c57602036600319011261127c57611b1c612032565b611b246126ee565b6001600160a01b03168015611844576020817fae994ca926e252e299c3df7516cb609272a57bf80b0e0715297e55939f873420926001600160601b0360a01b6006541617600655604051908152a1005b3461127c575f36600319011261127c576020604051620151808152f35b612072565b3461127c575f36600319011261127c576020600454604051908152f35b3461127c57602036600319011261127c57611bcc612032565b611bd461224e565b50611bde81612562565b5060018060a01b03165f52600a6020526111a960405f2061ffff60405191611c0583612141565b5460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c57602036600319011261127c576020611c6a611c65612032565b612198565b604051908152f35b3461127c57602036600319011261127c57611c8b612032565b611c936126ee565b60018060a01b03811690815f52600f60205260405f2060405190611cb6826120ef565b80546001600160a01b0316808352600182015460208401819052600290920154604084018190529015918215611d3c575b508115611d32575b50611d2357611d21925f52600f6020525f600260408220828155826001820155015560018060a01b0390511690612597565b005b63aa0b7b6160e01b5f5260045ffd5b9050421184611cef565b4210915085611ce7565b3461127c57602036600319011261127c57611d5f612032565b5f610100604051611d6f8161210a565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152015260018060a01b03165f52600960205261012060405f2060405190611dc18261210a565b60018060a01b038154169182815260018060a01b036001830154166020820190815261ffff60018060a01b0360028501541660408401908152600460018060a01b036003870154169560608601968752015494608085019060018060a01b038716825260a0860192848860a01c16845260c087019560ff8960b01c161515875260ff61010060e08a0199828c60b81c1615158b52019960c01c1615158952604051998a5260018060a01b0390511660208a015260018060a01b03905116604089015260018060a01b03905116606088015260018060a01b039051166080870152511660a085015251151560c084015251151560e0830152511515610100820152f35b3461127c57604036600319011261127c57611edc612032565b611ee4612048565b611eec6126ee565b611ef582612562565b506001600160a01b038116908115611844576203f480420190814211610f7d576207e900420192838311610f7d577f22b336cc3c163283ca94b8a02d1107b4485a820fa77cc12ea205640452d37b5e936115b59160405190611f56826120ef565b8152602080820186815260408084018581526001600160a01b039a8b165f818152600f8652839020955186546001600160a01b031916908d161786559251600186015551600294909401939093558251959098168552840194909452928201929092529081906060820190565b3461127c57604036600319011261127c57611fdc612032565b611fe4612048565b6001600160a01b036003611ff784612562565b015416330361200957611d2191612597565b632e7e4e5160e21b5f5260045ffd5b3461127c575f36600319011261127c57602090600b548152f35b600435906001600160a01b038216820361127c57565b602435906001600160a01b038216820361127c57565b35906001600160a01b038216820361127c57565b3461127c575f36600319011261127c5760206040516203f4808152f35b919091608061ffff8160a084019560018060a01b038151168552826020820151166020860152826040820151166040860152826060820151166060860152015116910152565b3590811515820361127c57565b91908201809211610f7d57565b606081019081106001600160401b0382111761128057604052565b61012081019081106001600160401b0382111761128057604052565b604081019081106001600160401b0382111761128057604052565b60a081019081106001600160401b0382111761128057604052565b60c081019081106001600160401b0382111761128057604052565b90601f801991011681019081106001600160401b0382111761128057604052565b60018060a01b0316805f52600e60205260405f2060ff6001604051926121bd84612126565b8054845201541615801560208301526115ca575160025460035460045490600554926040519460208601964688523060408801526b033b2e3c9fd0803ce80000006060880152608087015260a08601525f60c086015260e08501526101008401526101208301526101408201526122376101608201612701565b6101e0815261224861020082612177565b51902090565b6040519061225b82612141565b5f6080838281528260208201528260408201528260608201520152565b519069ffffffffffffffffffff8216820361127c57565b614650811080156124c1575b61241757604051633fabe5a360e21b815260a0816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801561124f575f915f9161246d575b505f821390811591612464575b811561245a575b8115612444575b50612436578091670de0b6b3a7640000810290808204670de0b6b3a76400001490151715610f7d5760ff7f000000000000000000000000000000000000000000000000000000000000000016604d8111610f7d57600a0a80600302906003820403610f7d576001600160fe1b0383168303610f7d5761238a9260021b91612770565b9081158015612426575b61241757600254600354600454600554906040519260208401944686523060408601526b033b2e3c9fd0803ce800000060608601525f60808601528760a0860152600160c086015260e08501526101008401526101208301526101408201526124006101608201612701565b6101e0815261241161020082612177565b51902092565b6330d7115160e11b5f5260045ffd5b506001600160801b038211612394565b62fc7cad60e51b5f5260045ffd5b90504203428111610f7d5762015180105f612308565b4281119150612301565b801591506122fa565b91505060a0813d60a0116124b9575b8161248960a09383612177565b8101031261127c5761249a81612278565b5060208101516124b1608060608401519301612278565b50905f6122ed565b3d915061247c565b506161a8811161229b565b6084356001600160a01b038116810361127c5790565b356001600160a01b038116810361127c5790565b60a43561ffff8116810361127c5790565b60c43561ffff8116810361127c5790565b60e43561ffff8116810361127c5790565b6101043561ffff8116810361127c5790565b3561ffff8116810361127c5790565b600b54811015610f9157600b5f5260205f2001905f90565b60018060a01b03165f52600960205260405f209060ff600483015460c01c161561258857565b638698bf3760e01b5f5260045ffd5b6001600160a01b03821691905f908315611844576125b481612562565b6003810180546001600160a01b0319811687179091556001909101546001600160a01b03918216949116803b1561127c575f8091602460405180948193633d82753160e11b83528b60048401525af1801561124f576126d9575b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b1561056c57604051635ad7fc1760e01b81526001600160a01b0384811660048301529190911660248201529083908290604490829084905af180156126ce579083916126b5575b50506001600160a01b0316907f308c390ed1ab5873392818e036cabdf408bc8ad042fbaead3108954ff75ba9809080a4565b816126bf91612177565b6126ca57815f612683565b5080fd5b6040513d85823e3d90fd5b6126e69193505f90612177565b5f915f61260e565b5f546001600160a01b031633036117ae57565b608061ffff60085460018060a01b0381168452818160a01c166020850152818160b01c166040850152818160c01c16606085015260d01c16910152565b801561275c57723880173480caadff41f996746e3000000000000490565b634e487b7160e01b5f52601260045260245ffd5b90915f19838309928083029283808610950394808603951461280157848311156127e95790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b50509150811561275c570490565b60025f5160206131ca5f395f51905f5254146128385760025f5160206131ca5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b90915f9361285484612198565b6101008401350361141f5760018060a01b0384165f52600e60205260405f20549460025434036114105761288a60c0850161253b565b61ffff60035491161180156130be575b6113d25760018060a01b0383165f52600d60205260405f206101208501355f5260205260ff60405f2054166113c35760206128d96101408601866130da565b9050116113b4576001600160a01b038381165f908152600d6020908152604080832061012089013584529091529020805460ff1916600117905561291f60a086016124e2565b166130ac5782945b61ffff60085460c01c169161293e60c0870161253b565b61ffff61294d60e0890161310f565b916040519561295b8761215c565b6001600160a01b0386811688528b16602088015260408088018d905260608801919091529116608086015290151560a085015251638dabdc8360e01b81526101e06004820152926129df6129d26129c56129b861098c8b80613130565b6109b460208c018c613130565b6109dc60408b018b613130565b610a0460608a018a613130565b90608088013588360392609e19840182121561127c578681036101e31901610264880152612a23918a0190610acb610ac0610aa5610a8a610a6f610a618780613130565b916001600160a01b03612a3860a08b0161205e565b1661028487015260c089013561ffff811680910361127c576102a4870152612a6260e08a016120d5565b15156102c48701526101008901356102e487015261012089013561030487015261014089013590601e190181121561127c578801602081359101926001600160401b03821161127c578160051b3603841361127c578681036101e3190161032488015281815291928692602001915f5b81811061307c57505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190612b3360e48301612701565b6001600160a01b038981166101848401526b033b2e3c9fd0803ce80000006101a48401525f6101c48401819052929091039183917f0000000000000000000000000000000000000000000000000000000000000000165af194851561124f5787915f945f9761302c575b5090600491848989612d32612bc060e0612bb960c0860161253b565b940161310f565b610de861ffff60405195612bd38761210a565b8d60018060a01b03169a878c809952602081019760018060a01b03169d8e8952604082018d60018060a01b03168152606083019160018060a01b03168252608083019b60018060a01b03168c528560a084019516855260c08301971515885260e08301995f8b5261010084019b60018d525f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790555f838152600a602052604090206007198101612fe2575b50600b54600160401b8110156112805786610e73826001612d989401600b5561254a565b612da66101408a018a6130da565b9b905060028c01809c11610f7d57612dbd8c613181565b9b6040519c612dcc908e612177565b808d52612dd890613181565b60208d019b90601f1901368d376001600160a01b038416612df88e613198565b526001600160a01b0316612e0b8d6131a5565b525f5b612e1c6101408c018c6130da565b9050811015612e7257612e336101408c018c6130da565b821015610f9157612e48908260051b016124e2565b906002810191828211610f7d57612e628f936001946131b5565b90838060a01b0316905201612e0e565b50929598509295989990939699863b1561127c576040805163251b648160e21b8152600481018890526024810191909152915160448301819052829160648301915f5b818110612fc05750505090805f920381838a5af1801561124f57612fab575b5060025480612f32575b50604080516001600160a01b0397881681526020810192909252810182905260608101919091529316927ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b90608090a49190565b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b15612fa757906024859260405194859384926301aba89b60e71b845260048401525af180156126ce5715612ede57612f9d838092612177565b6126ca575f612ede565b8480fd5b612fb89192505f90612177565b5f905f612ed4565b82516001600160a01b0316845285945060209384019390920191600101612eb5565b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155613026906112d4565b5f612d74565b9450955090506040833d604011613074575b8161304b60409383612177565b8101031261127c576004879161306c60206130658761311c565b960161311c565b969091612b9d565b3d915061303e565b919493509160019060209081906001600160a01b0361309a8961205e565b16815201950191019187939492612ad2565b6130b860a085016124e2565b94612927565b506107d06130d461ffff6113f960c0880161253b565b1161289a565b903590601e198136030182121561127c57018035906001600160401b03821161127c57602001918160051b3603831361127c57565b35801515810361127c5790565b51906001600160a01b038216820361127c57565b9035601e198236030181121561127c5701602081359101916001600160401b03821161127c57813603831361127c57565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b0381116112805760051b60200190565b805115610f915760200190565b805160011015610f915760400190565b8051821015610f915760209160051b01019056fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212203190683f5d6bc5abb39a655d737ec2428316f3ace65c6ab0d982473f4e38da5864736f6c634300082300336080806040523460395760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005561078c908161003e8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c806309ad4dd9146102015780631698755f146101d257806332f289cf14610187578063379607f5146101615780634e71d92d1461011a57806370a08231146100e3578063d5d44d80146100c55763f59e38b714610071575f80fd5b346100c15760403660031901126100c15761008a610249565b61009261025f565b6001600160a01b039182165f908152600160209081526040808320949093168252928352819020549051908152f35b5f80fd5b60203660031901126100c1576100e16100dc610249565b6104bd565b005b346100c15760203660031901126100c1576001600160a01b03610104610249565b165f525f602052602060405f2054604051908152f35b346100c1575f3660031901126100c15761013261051c565b335f525f602052602061014860405f2054610669565b60015f5160206107375f395f51905f5255604051908152f35b346100c15760203660031901126100c15761017a61051c565b6020610148600435610669565b346100c15760203660031901126100c15760206101486101a5610249565b6101ad61051c565b335f9081526001845260408082206001600160a01b0384168352855290205490610554565b346100c15760403660031901126100c15760206101486101f0610249565b6101f861051c565b60243590610554565b346100c15760603660031901126100c15761023661021d610249565b61022561025f565b61022d61051c565b604435916102d9565b60015f5160206107375f395f51905f5255005b600435906001600160a01b03821682036100c157565b602435906001600160a01b03821682036100c157565b90601f8019910116810190811067ffffffffffffffff82111761029757604052565b634e487b7160e01b5f52604160045260245ffd5b919082039182116102b857565b634e487b7160e01b5f52601160045260245ffd5b919082018092116102b857565b6001600160a01b03169190821580156104ac575b61049d5781156103f5576040516370a0823160e01b81523060048201526001600160a01b03919091169190602081602481865afa90811561042e575f9161046b575b50604051916323b872dd60e01b5f52336004523060245260445260205f60648180875af160015f511481161561044c575b826040525f60605215610439576370a0823160e01b8252306004830152602082602481865afa801561042e575f906103fa575b61039d92506102ab565b9182156103f557805f52600160205260405f20825f5260205260405f206103c58482546102cc565b90556040519283527f5d104c62f50449fadfe6f4013c8f36588d32737f94b5ac9b83ddad33b3e1ffdf60203394a4565b505050565b506020823d602011610426575b8161041460209383610275565b810103126100c15761039d9151610393565b3d9150610407565b6040513d5f823e3d90fd5b82635274afe760e01b5f5260045260245ffd5b600181151661046257833b15153d151616610360565b823d5f823e3d90fd5b90506020813d602011610495575b8161048660209383610275565b810103126100c157515f61032f565b3d9150610479565b63d92e233d60e01b5f5260045ffd5b506001600160a01b038116156102ed565b6001600160a01b0316801561049d57341561051957805f525f60205260405f206104e83482546102cc565b9055604051903482527f4e45da441832cf53bdaa69235704fc0575e68210f459ee1562911024b12967d560203393a3565b50565b60025f5160206107375f395f51905f5254146105455760025f5160206107375f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b811561065a57335f52600160205260405f2060018060a01b0382165f5260205260405f2054808311610644578261058a916102ab565b335f52600160205260405f2060018060a01b0383165f5260205260405f205560018060a01b031660405163a9059cbb60e01b5f52336004528260245260205f60448180865af160015f5114811615610625575b8160405215610612578281527fdbc1ea3a8459e4c7e11fb385b52bbb5cc8c8ab85eec5d883ac9aa78c171f514160203392a390565b50635274afe760e01b5f5260045260245ffd5b600181151661063b57823b15153d1516166105dd565b503d5f823e3d90fd5b8263cf47918160e01b5f5260045260245260445ffd5b636165515360e11b5f5260045ffd5b801561065a57335f525f60205260405f2054808211610720578161068c916102ab565b335f525f60205260405f20555f80808084335af13d1561071b573d67ffffffffffffffff811161029757604051906106ce601f8201601f191660200183610275565b81525f60203d92013e5b1561070c576040518181527fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a60203392a290565b6312171d8360e31b5f5260045ffd5b6106d8565b9063cf47918160e01b5f5260045260245260445ffdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220dbbc16195d46dd822a5bbc7c7a2c8ac6b3a2c13959882c7f071ff2c011021a2464736f6c6343000823003360c03461015f57601f6112db38819003918201601f19168301916001600160401b038311848410176101635780849260609460405283398101031261015f5780516001600160a01b038116919082900361015f5760208101516001600160a01b0381169182820361015f5760400151916001600160a01b0383169081840361015f57841561014c57600180546001600160a01b03199081169091555f80549182168717815560405196916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005515908115610143575b506101345760805260a05261116390816101788239608051816103cf015260a05181818161021301526107aa0152f35b63d92e233d60e01b5f5260045ffd5b9050155f610104565b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c908163032bbf4f146106235750806319165587146105df578063384711cc1461058f5780634cfc4d30146105715780635ad7fc171461053a5780635bb478081461049d578063715018a61461047e57806379ba5097146103fe57806382589038146103ba578063892823f7146103445780638da5cb5b1461031d578063a3f8eace146102cd578063b224cf641461026a578063c45a015514610242578063c4b7de97146101fe578063d79779b2146101c3578063d8fb93371461018b578063e30c3978146101635763f2fde38b146100ed575f80fd5b3461015f57602036600319011261015f5761010661065a565b61010e610e1b565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b5f80fd5b3461015f575f36600319011261015f576001546040516001600160a01b039091168152602090f35b3461015f57602036600319011261015f576001600160a01b036101ac61065a565b165f526003602052602060405f2054604051908152f35b3461015f57602036600319011261015f576001600160a01b036101e461065a565b165f5260036020526020600160405f200154604051908152f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576002546040516001600160a01b039091168152602090f35b3461015f57602036600319011261015f576001600160a01b0361028b61065a565b165f526003602052606060405f2061ffff600860018060a01b0360078401541692015460405192835260018060a01b038116602084015260a01c166040820152f35b3461015f57602036600319011261015f576001600160a01b036102ee61065a565b165f526003602052602061031560405f2061030f60038201549142906110b4565b90610670565b604051908152f35b3461015f575f36600319011261015f575f546040516001600160a01b039091168152602090f35b3461015f5760a036600319011261015f5761035d61065a565b6044356001600160a01b038116810361015f576064356001600160a01b038116810361015f576084359161ffff8316830361015f576103a79361039e610da6565b60243590610adc565b60015f51602061110e5f395f51905f5255005b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f57600154336001600160a01b0382160361046b576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461015f575f36600319011261015f576317d5c96560e11b5f5260045ffd5b3461015f57602036600319011261015f576104b661065a565b6104be610e1b565b600254906001600160a01b03821661052c576001600160a01b031690811561051d576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b3461015f57604036600319011261015f5761055361065a565b6024356001600160a01b038116810361015f5761056f91610a3d565b005b3461015f575f36600319011261015f57602060405163096601808152f35b3461015f57602036600319011261015f576001600160a01b036105b061065a565b165f526003602052602061031560405f2061030f6105d76001830154600384015490610670565b9142906110b4565b3461015f57602036600319011261015f57602061060a6105fd61065a565b610605610da6565b610705565b60015f51602061110e5f395f51905f5255604051908152f35b3461015f57602036600319011261015f576020906001600160a01b0361064761065a565b165f5260038252600260405f2001548152f35b600435906001600160a01b038216820361015f57565b9190820180921161067d57565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561067d57565b81156106ae570490565b634e487b7160e01b5f52601260045260245ffd5b9190820391821161067d57565b90601f8019910116810190811067ffffffffffffffff8211176106f157604052565b634e487b7160e01b5f52604160045260245ffd5b6002549091905f906001600160a01b031615610a2e576001600160a01b038381165f81815260036020526040902060078101805491969294909390911633141580610a17575b610a08576107594287610dde565b600386019586549687156109fd57905f600892556001810161077c898254610670565b90550161271061079461ffff835460a01c1689610691565b04926107a084896106c2565b9460018060a01b037f0000000000000000000000000000000000000000000000000000000000000000169260405163095ea7b360e01b5f52846004528a60245260205f604481808d5af19060015f51148216156109ee575b60405215610938575b856108c7575b5085610844575b505050507f82e416ba72d10e709b5de7ac16f5f49ff1d94f22d55bf582d353d3c313a1e8dd9160409182519182526020820152a2565b546001600160a01b0316823b156108c3576040516309ad4dd960e01b81526001600160a01b03918216600482015291166024820152604481018590529082908290606490829084905af180156108b8576108a0575b808061080e565b6108ab8280926106cf565b6108b55780610899565b80fd5b6040513d84823e3d90fd5b8380fd5b546001600160a01b0316833b1561015f576040516309ad4dd960e01b81526001600160a01b0391821660048201529083166024820152604481018690525f8160648183885af1801561092d5715610807576109259194505f906106cf565b5f925f610807565b6040513d5f823e3d90fd5b60405163095ea7b360e01b5f52846004525f60245260205f604481808d5af19060015f51148216156109d6575b604052156109a25760405163095ea7b360e01b5f52846004528a60245260205f604481808d5af19060015f51148216156109b5575b604052610801575b87635274afe760e01b5f5260045260245ffd5b9060018115166109cd57893b15153d1516169061099a565b503d5f823e3d90fd5b9060018115166109cd57893b15153d15161690610965565b90893b15153d151616906107f8565b505f96505050505050565b630da3333b60e01b5f5260045ffd5b5060088601546001600160a01b031633141561074b565b631966391b60e11b5f5260045ffd5b6002546001600160a01b03163303610a2e576001600160a01b03169081158015610acb575b61051d575f82815260036020526040902060070180546001600160a01b039283169392169190838314610ac55780546001600160a01b031916841790557f38f9c71383b6e3fe639172c6b3a3d4418fa722b4abf99bfd8e31f92bd5ea23f05f80a4565b50505050565b506001600160a01b03811615610a62565b92936001600160a01b038416939291841561051d576002546001600160a01b031615610a2e57610b0c3385610e4f565b15610d97578015610cc8576001600160a01b038316158015610d86575b8015610d77575b610d68576040516370a0823160e01b8152306004820152602081602481895afa90811561092d575f91610d36575b50604051916323b872dd60e01b5f52336004523060245260445260205f606481808a5af160015f5114811615610d17575b826040525f60605215610d04576370a0823160e01b8252306004830152602082602481895afa801561092d575f90610cd0575b610bcc92506106c2565b948515610cc857610bf492855f52600360205260405f2094610bee4287610dde565b85610fa3565b600481018054610c14610c078683610670565b9180610cb4575f90610691565b6309660180860286810463096601800361067d57610c368391610c3b93610670565b6106a4565b9155426005830155610c4d8142610670565b60068301556309660180036309660180811161067d57610c6d90426106c2565b90816002820155610c7f848254610670565b905560405192835260208301527f967ad762aa9070ada8db64577288e214771e89667066ae38e8750cb8a86c542960403393a3565b610cc24260068701546106c2565b90610691565b505050505050565b506020823d602011610cfc575b81610cea602093836106cf565b8101031261015f57610bcc9151610bc2565b3d9150610cdd565b85635274afe760e01b5f5260045260245ffd5b6001811516610d2d57863b15153d151616610b8f565b823d5f823e3d90fd5b90506020813d602011610d60575b81610d51602093836106cf565b8101031261015f57515f610b5e565b3d9150610d44565b63a7d7d0c560e01b5f5260045ffd5b5061271061ffff831611610b30565b506001600160a01b03861615610b29565b63ba13c3d960e01b5f5260045ffd5b60025f51602061110e5f395f51905f525414610dcf5760025f51602061110e5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b600590610deb83826110b4565b80610df557500155565b60048201610e048282546106c2565b9055610e1560038301918254610670565b90550155565b5f546001600160a01b0316330361046b57565b51906001600160a01b038216820361015f57565b5190811515820361015f57565b6002546001600160a01b0316908115610f9c57604051631e7945ad60e11b81526001600160a01b0390911660048201529061012090829060249082905afa90811561092d575f91610eb1575b50602001516001600160a01b0391821691161490565b9050610120813d8211610f94575b81610ecd61012093836106cf565b8101031261015f5760405190610120820182811067ffffffffffffffff8211176106f157604052610efd81610e2e565b8252610f0b60208201610e2e565b6020830152610f1c60408201610e2e565b6040830152610f2d60608201610e2e565b6060830152610f3e60808201610e2e565b608083015260a081015161ffff8116810361015f57610f88916101009160a0850152610f6c60c08201610e42565b60c0850152610f7d60e08201610e42565b60e085015201610e42565b6101008201525f610e9b565b3d9150610ebf565b5050505f90565b91600483015415806110a8575b611001575050600801546001600160a01b0380821692169190911480159290610feb575b5050610fdc57565b638a621fd960e01b5f5260045ffd5b61ffff91925081169160a01c1614155f80610fd4565b6007830180549295937fa92f5227e67257769e49f294586ea055f8d5714595dfdcc2d8a0cac8a3e50fbe93602093600892916001600160a01b031615611087575b500180546001600160b01b0319166001600160a01b0396871690811760a087901b61ffff60a01b1617909155905460405161ffff9590951685529095908516941692a4565b83546001600160a01b0319166001600160a01b03919091161783555f611042565b50600383015415610fb0565b90600482015491821580156110ff575b610f9c57600681015490818310156110f95792610cc2610c36926110f060056110f697015480926106c2565b946106c2565b90565b50505090565b5060058101548211156110c456fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220f824fefce66b4cf1569e7d371fa6370cdccc1c2f8a88bdedc443c0ce47e0831a64736f6c6343000823003360e0346100c157601f614e1938819003918201601f19168301916001600160401b038311848410176100c5578084926060946040528339810103126100c1578051906001600160a01b03821682036100c1576020810151906001600160a01b03821682036100c15760400151916001600160a01b03831683036100c15760805260a05260c052604051614d3f90816100da823960805181818160e90152610182015260a05181818160a5015261028d015260c051818181605d01526102b50152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c9081638dabdc831461011857508063c45a0155146100d4578063c4b7de97146100905763f1f5c99314610048575f80fd5b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5f80fd5b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461008c576101e036600319011261008c576004359067ffffffffffffffff821161008c578160040191610160600319823603011261008c5760c036602319011261008c5760a03660e319011261008c57610184356001600160a01b038116939084900361008c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316933385900361068e576101bd828061069d565b9050158015610679575b8015610663575b801561064b575b8015610632575b8015610619575b61057e5760848301916101006102026101fc85846106d0565b8061069d565b90501180156105f6575b80156105d3575b80156105b0575b801561058d575b61057e576020850194828652610124850135604082015260408152606081019581871067ffffffffffffffff88111761056a578660405281519020956128b1808301906060820183811067ffffffffffffffff82111761056a578a916107388539526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660808301527f0000000000000000000000000000000000000000000000000000000000000000811660a083015260e4359081169081900361008c5760c08201526101043561ffff811680910361008c5760e08201526101243561ffff811680910361008c576101008201526101443561ffff811680910361008c576101208201526101643561ffff811680910361008c576101408201526024356001600160a01b0381169081900361008c576101608201526044356001600160a01b0381169081900361008c576101808201526064356101a08201526084356101c082015260a4356101e082015260c43580151580910361008c5761020082015287926101c0910301905ff5801561055f576001600160a01b0316956103ce828061069d565b929060646103df602489018461069d565b9390976104076103ff6103f560448d018561069d565b95909c018461069d565b9290936106d0565b936040519a611d2194858d01998d8b1067ffffffffffffffff8c111761056a578d9c610515996104528f96610460948f6101409061047c9d61046e9b612fe9903981815201916106e5565b8d810360208f0152916106e5565b918a830360408c01526106e5565b9187830360608901526106e5565b84810360808601526105076104fc6104e16104c66104ab61049d8780610705565b60a0885260a08801916106e5565b6104b86020880188610705565b9087830360208901526106e5565b6104d36040870187610705565b9086830360408801526106e5565b6104ee6060860186610705565b9085830360608701526106e5565b926080810190610705565b9160808185039101526106e5565b9260a08301528660c083015260e08201526101a4356101008201526101206101c43591015203905ff5801561055f57604080516001600160a01b0390921682526020820192909252f35b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b635e765b2560e11b5f5260045ffd5b506101006105a861059e85846106d0565b608081019061069d565b905011610221565b506101006105cb6105c185846106d0565b606081019061069d565b90501161021a565b506101006105ee6105e485846106d0565b604081019061069d565b905011610213565b5061010061061161060785846106d0565b602081019061069d565b90501161020c565b5061080061062a606485018461069d565b9050116101e3565b50610200610643604485018461069d565b9050116101dc565b50601061065b602485018461069d565b9050116101d5565b50610671602484018361069d565b9050156101ce565b506040610686838061069d565b9050116101c7565b631966391b60e11b5f5260045ffd5b903590601e198136030182121561008c570180359067ffffffffffffffff821161008c5760200191813603831361008c57565b903590609e198136030182121561008c570190565b908060209392818452848401375f828201840152601f01601f1916010190565b9035601e198236030181121561008c57016020813591019167ffffffffffffffff821161008c57813603831361008c5756fe610220604052346104b1576040516128b138819003601f8101601f191683016001600160401b038111848210176104b557839282916040528339810103906101c082126104b15761004f816104c9565b602082015190916001600160a01b0382168083036104b15760408201516001600160a01b038116938482036104b15760a0605f198801126104b1576040519660a088016001600160401b038111898210176104b5576040526100b3606086016104c9565b88526100c1608086016104dd565b95602089019687526100d560a087016104dd565b60408a019081526100e860c088016104dd565b60608b015260c06100fb60e089016104dd565b60808c019081529360ff1901126104b1576040519860c08a016001600160401b0381118b8210176104b55760405261013661010089016104c9565b8a5261014561012089016104c9565b9860208b019a8a8c526101408a015197604082019889526101608b015199606083019a8b526101a06101808d01519c608085019d8e5201519c8d801515036104b15760a084019d8e5260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556001600160a01b0386169788159283156104a8575b50821561049f575b50811561048d575b5061047e578d516001600160a01b031615801561046e575b801561045e575b8015610451575b8015610440575b8015610415575b61040657885180159081156103f5575b506103e65761ffff978896879560a05260c05260e0526101005260018060a01b0390511660805260018060a01b038b51169a6001549c60018060a01b039051166101205260018060a01b039051166101405251166101605251166101805251166101a052516101c052516101e052516102005260ff60a01b9051151560a01b169160018060a81b03191617176001556040516123c490816104ed823960805181818161029e01528181610a7301528181610bd30152818161112301528181611eab0152611ff3015260a05181818161044801528181610605015281816106e90152610f7f015260c051818181610f350152611347015260e05181818161040401528181611edb0152611f6d01526101005181818161021c015261152c01526101205181818161104d015281816114e401526115be0152610140518181816111670152611596015261016051818181610b08015281816113b901526121760152610180518181816110cd01526121a701526101a051818181610aca01526116a401526101c0518181816103cc015281816105c1015261183e01526101e0518181816111f4015281816118850152611a1901526102005181818161048e015281816118b80152611a4f0152f35b63bc0ecfe360e01b5f5260045ffd5b6001600160801b031090505f61021b565b637a34030f60e01b5f5260045ffd5b5089518b51810180911161042c576107d01061020b565b634e487b7160e01b5f52601160045260245ffd5b5061271061ffff8851161015610204565b5061ffff875116156101fd565b5061271061ffff865116116101f6565b5061271061ffff845116116101ef565b63d92e233d60e01b5f5260045ffd5b6001600160a01b03161590505f6101d7565b1591505f6101cf565b1592505f6101c7565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036104b157565b519061ffff821682036104b15756fe60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f00000000000000000000000000000000000000000000000000000000000000006112ac565b3461020357602036600319011261020357600435801515809103610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000000166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f0000000000000000000000000000000000000000000000000000000000000000611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448401527f00000000000000000000000000000000000000000000000000000000000000001660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000000016101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f00000000000000000000000000000000000000000000000000000000000000009061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000000080612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000000090611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f00000000000000000000000000000000000000000000000000000000000000001682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c6343000823003361012060405234610ee557611d218038038061001a81610ee9565b92833981019061014081830312610ee55780516001600160401b038111610ee55782610047918301610f0e565b60208201519091906001600160401b038111610ee55783610069918301610f0e565b60408201519091906001600160401b038111610ee5578461008b918301610f0e565b60608201519094906001600160401b038111610ee557816100ad918401610f0e565b60808301519091906001600160401b038111610ee557830160a081830312610ee55760405160a081016001600160401b038111828210176107195760405281516001600160401b038111610ee55783610107918401610f0e565b815260208201516001600160401b038111610ee55783610128918401610f0e565b6020820190815260408301519091906001600160401b038111610ee55784610151918501610f0e565b6040820190815260608401519093906001600160401b038111610ee5578561017a918301610f0e565b6060830190815260808201519095906001600160401b038111610ee5576101a19201610f0e565b94608082019586526101b560a08801610f5f565b996101c260c08901610f5f565b986101cf60e08a01610f5f565b906101206101008b01519a01519b80519060018060401b0382116107195760035490600182811c92168015610edb575b60208310146106fb5781601f849311610e65575b50602090601f8311600114610dff575f92610df4575b50508160011b915f199060031b1c1916176003555b8051906001600160401b0382116107195760045490600182811c92168015610dea575b60208310146106fb5781601f849311610d74575b50602090601f8311600114610d0e575f92610d03575b50508160011b915f199060031b1c1916176004555b6001600160a01b038c16158015610cf2575b8015610ce1575b610cd2578b60805260a0528860c05287158015610cc6575b610cb75760e08890526101008a90528051906001600160401b0382116107195760055490600182811c92168015610cad575b60208310146106fb5781601f849311610c53575b50602090601f8311600114610bed575f92610be2575b50508160011b915f199060031b1c1916176005555b8051906001600160401b0382116107195760065490600182811c92168015610bd8575b60208310146106fb5781601f849311610b62575b50602090601f8311600114610afc575f92610af1575b50508160011b915f199060031b1c1916176006555b518051906001600160401b0382116107195760075490600182811c92168015610ae7575b60208310146106fb5781601f849311610a71575b50602090601f8311600114610a0b575f92610a00575b50508160011b915f199060031b1c1916176007555b518051906001600160401b0382116107195760085490600182811c921680156109f6575b60208310146106fb5781601f849311610980575b50602090601f831160011461091a575f9261090f575b50508160011b915f199060031b1c1916176008555b518051906001600160401b0382116107195760095490600182811c92168015610905575b60208310146106fb5781601f84931161088f575b50602090601f8311600114610829575f9261081e575b50508160011b915f199060031b1c1916176009555b518051906001600160401b03821161071957600a5490600182811c92168015610814575b60208310146106fb5781601f84931161079e575b50602090601f8311600114610738575f9261072d575b50508160011b915f199060031b1c191617600a555b518051906001600160401b03821161071957600b5490600182811c9216801561070f575b60208310146106fb5781601f849311610685575b50602090601f831160011461061f575f92610614575b50508160011b915f199060031b1c191617600b555b828103908111610600576105a691610f73565b806105f0575b604051610d3a9081610fe782396080518181816101cb0152610261015260a0518161059d015260c05181610496015260e05181610600015261010051816101430152f35b6105f991610f73565b5f806105ac565b634e487b7160e01b5f52601160045260245ffd5b015190505f8061057e565b600b5f9081528281209350601f198516905b81811061066d5750908460019594939210610655575b505050811b01600b55610593565b01515f1960f88460031b161c191690555f8080610647565b92936020600181928786015181550195019301610631565b8281111561056857600b5f52909150601f830160051c7f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9602085106106f3575b849392601f0160051c82900391015f5b8281106106e3575050610568565b5f818301558594506001016106d5565b5f91506106c5565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610554565b634e487b7160e01b5f52604160045260245ffd5b015190505f8061051b565b600a5f9081528281209350601f198516905b818110610786575090846001959493921061076e575b505050811b01600a55610530565b01515f1960f88460031b161c191690555f8080610760565b9293602060018192878601518155019501930161074a565b8281111561050557600a5f52909150601f830160051c7fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a86020851061080c575b849392601f0160051c82900391015f5b8281106107fc575050610505565b5f818301558594506001016107ee565b5f91506107de565b91607f16916104f1565b015190505f806104b8565b60095f9081528281209350601f198516905b818110610877575090846001959493921061085f575b505050811b016009556104cd565b01515f1960f88460031b161c191690555f8080610851565b9293602060018192878601518155019501930161083b565b828111156104a25760095f52909150601f830160051c7f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af602085106108fd575b849392601f0160051c82900391015f5b8281106108ed5750506104a2565b5f818301558594506001016108df565b5f91506108cf565b91607f169161048e565b015190505f80610455565b60085f9081528281209350601f198516905b8181106109685750908460019594939210610950575b505050811b0160085561046a565b01515f1960f88460031b161c191690555f8080610942565b9293602060018192878601518155019501930161092c565b8281111561043f5760085f52909150601f830160051c7ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3602085106109ee575b849392601f0160051c82900391015f5b8281106109de57505061043f565b5f818301558594506001016109d0565b5f91506109c0565b91607f169161042b565b015190505f806103f2565b60075f9081528281209350601f198516905b818110610a595750908460019594939210610a41575b505050811b01600755610407565b01515f1960f88460031b161c191690555f8080610a33565b92936020600181928786015181550195019301610a1d565b828111156103dc5760075f52909150601f830160051c7fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860208510610adf575b849392601f0160051c82900391015f5b828110610acf5750506103dc565b5f81830155859450600101610ac1565b5f9150610ab1565b91607f16916103c8565b015190505f8061038f565b60065f9081528281209350601f198516905b818110610b4a5750908460019594939210610b32575b505050811b016006556103a4565b01515f1960f88460031b161c191690555f8080610b24565b92936020600181928786015181550195019301610b0e565b828111156103795760065f52909150601f830160051c7ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f60208510610bd0575b849392601f0160051c82900391015f5b828110610bc0575050610379565b5f81830155859450600101610bb2565b5f9150610ba2565b91607f1691610365565b015190505f8061032d565b60055f9081528281209350601f198516905b818110610c3b5750908460019594939210610c23575b505050811b01600555610342565b01515f1960f88460031b161c191690555f8080610c15565b92936020600181928786015181550195019301610bff565b828111156103175790915060055f5260205f20601f840160051c9060208510610ca5575b849392601f0160051c82900391015f5b828110610c95575050610317565b5f81830155859450600101610c87565b5f9150610c77565b91607f1691610303565b6305d7ba1960e11b5f5260045ffd5b508760021c8a116102d1565b63d92e233d60e01b5f5260045ffd5b506001600160a01b038116156102b9565b506001600160a01b038a16156102b2565b015190505f8061028b565b60045f9081528281209350601f198516905b818110610d5c5750908460019594939210610d44575b505050811b016004556102a0565b01515f1960f88460031b161c191690555f8080610d36565b92936020600181928786015181550195019301610d20565b828111156102755760045f52909150601f830160051c7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b60208510610de2575b849392601f0160051c82900391015f5b828110610dd2575050610275565b5f81830155859450600101610dc4565b5f9150610db4565b91607f1691610261565b015190505f80610229565b60035f9081528281209350601f198516905b818110610e4d5750908460019594939210610e35575b505050811b0160035561023e565b01515f1960f88460031b161c191690555f8080610e27565b92936020600181928786015181550195019301610e11565b828111156102135760035f52909150601f830160051c7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b60208510610ed3575b849392601f0160051c82900391015f5b828110610ec3575050610213565b5f81830155859450600101610eb5565b5f9150610ea5565b91607f16916101ff565b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761071957604052565b81601f82011215610ee5578051906001600160401b03821161071957610f3d601f8301601f1916602001610ee9565b9282845260208383010111610ee557815f9260208093018386015e8301015290565b51906001600160a01b0382168203610ee557565b6001600160a01b0316908115610fd357600254908082018092116106005760207fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef915f9360025584845283825260408420818154019055604051908152a3565b63ec442f0560e01b5f525f60045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c806306fdde031461073b578063095ea7b31461069357806318160ddd1461067657806323b872dd1461063e578063313ce56714610623578063378dc3dc146105e957806342966c68146105cc578063536dac9b1461058857806353cd512a146104fc57806370a08231146104c55780637165485d146104815780637284e4161461046657806379cc67901461043457806395d89b4114610340578063a9059cbb1461030f578063abb1dc44146101fa578063d5f39488146101b6578063dd62ed3e14610166578063e029607c1461012c5763fb7f21eb146100f5575f80fd5b34610128575f36600319011261012857610124610110610966565b6040519182916020835260208301906107f6565b0390f35b5f80fd5b34610128575f3660031901126101285760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346101285760403660031901126101285761017f61081a565b610187610830565b6001600160a01b039182165f908152600160209081526040808320949093168252928352819020549051908152f35b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610128575f366003190112610128576060608060405161021a81610846565b8281528260208201528260408201528280820152015261029461023b610966565b610124610246610898565b6102a2610251610ac8565b9160405195869560018060a01b037f00000000000000000000000000000000000000000000000000000000000000001687526080602088015260808701906107f6565b9085820360408701526107f6565b838103606085015260806102fe6102ec6102da6102c8865160a0875260a08701906107f6565b602087015186820360208801526107f6565b604086015185820360408701526107f6565b606085015184820360608601526107f6565b9201519060808184039101526107f6565b346101285760403660031901126101285761033561032b61081a565b6024359033610bc3565b602060405160018152f35b34610128575f366003190112610128576040515f6004548060011c9060018116801561042a575b602083108114610416578285529081156103f25750600114610394575b6101248361011081850382610876565b60045f9081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b8082106103d857509091508101602001610110610384565b9192600181602092548385880101520191019092916103c0565b60ff191660208086019190915291151560051b840190910191506101109050610384565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610367565b346101285760403660031901126101285761046461045061081a565b6024359061045f823383610b20565b610c80565b005b34610128575f36600319011261012857610124610110610898565b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610128576020366003190112610128576001600160a01b036104e661081a565b165f525f602052602060405f2054604051908152f35b34610128575f36600319011261012857610550610517610ac8565b61012481519161057a60208201519161056c604082015161055e6080606085015194015195604051998a9960a08b5260a08b01906107f6565b9089820360208b01526107f6565b9087820360408901526107f6565b9085820360608701526107f6565b9083820360808501526107f6565b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346101285760203660031901126101285761046460043533610c80565b34610128575f3660031901126101285760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610128575f36600319011261012857602060405160128152f35b346101285760603660031901126101285761033561065a61081a565b610662610830565b60443591610671833383610b20565b610bc3565b34610128575f366003190112610128576020600254604051908152f35b34610128576040366003190112610128576106ac61081a565b602435903315610728576001600160a01b031690811561071557335f52600160205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b634a1406b160e11b5f525f60045260245ffd5b63e602df0560e01b5f525f60045260245ffd5b34610128575f366003190112610128576040515f6003548060011c906001811680156107ec575b602083108114610416578285529081156103f2575060011461078e576101248361011081850382610876565b60035f9081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b8082106107d257509091508101602001610110610384565b9192600181602092548385880101520191019092916107ba565b91607f1691610762565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361012857565b602435906001600160a01b038216820361012857565b60a0810190811067ffffffffffffffff82111761086257604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff82111761086257604052565b604051905f6006548060011c916001821691821561095c575b60208410831461041657838652859290811561093d57506001146108de575b6108dc92500383610876565b565b5060065f90815290917ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f5b8183106109215750509060206108dc928201016108d0565b6020919350806001915483858901015201910190918492610909565b602092506108dc94915060ff191682840152151560051b8201016108d0565b92607f16926108b1565b604051905f6005548060011c9160018216918215610a08575b60208410831461041657838652859290811561093d57506001146109a9576108dc92500383610876565b5060055f90815290917f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b8183106109ec5750509060206108dc928201016108d0565b60209193508060019154838589010152019101909184926109d4565b92607f169261097f565b90604051915f8154908160011c9260018316928315610abe575b602085108414610416578487528693908115610a9c5750600114610a58575b506108dc92500383610876565b90505f9291925260205f20905f915b818310610a805750509060206108dc928201015f610a4b565b6020919350806001915483858901015201910190918492610a67565b9050602092506108dc94915060ff191682840152151560051b8201015f610a4b565b93607f1693610a2c565b60405190610ad582610846565b81610ae06007610a12565b8152610aec6008610a12565b6020820152610afb6009610a12565b6040820152610b0a600a610a12565b60608201526080610b1b600b610a12565b910152565b6001600160a01b039081165f818152600160209081526040808320948616835293905291909120549291905f198410610b5a575b50505050565b828410610ba0578015610728576001600160a01b03821615610715575f52600160205260405f209060018060a01b03165f5260205260405f20910390555f808080610b54565b508290637dc7a0d960e11b5f5260018060a01b031660045260245260445260645ffd5b6001600160a01b0316908115610c6d576001600160a01b0316918215610c5a57815f525f60205260405f2054818110610c4157817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f525f84520360405f2055845f525f825260405f20818154019055604051908152a3565b8263391434e360e21b5f5260045260245260445260645ffd5b63ec442f0560e01b5f525f60045260245ffd5b634b637e8f60e11b5f525f60045260245ffd5b9091906001600160a01b03168015610c6d57805f525f60205260405f2054838110610cea576020845f94957fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef938587528684520360408620558060025403600255604051908152a3565b915063391434e360e21b5f5260045260245260445260645ffdfea26469706673582212201aca4a2b55465a13b08ec36674fca845ba424b771f3ea8c117e712cc7ec430c264736f6c63430008230033a2646970667358221220272ca8beeb8120e5fcea1f6abad3910174ee29119b3514eea8a2ceccb1bdce8764736f6c63430008230033","sourceMap":"1002:13720:23:-:0;;;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;1273:26:0;;1269:95;;1002:13720:23;;;-1:-1:-1;;;;;;1002:13720:23;;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;3052:40:0;;-1:-1:-1;3052:40:0;2093:20:1;1505:66:13;1002:13720:23;1433:12;;1002:13720;1485:5;1002:13720;;1530:5;;1002:13720;;1574:1;1002:13720;3914:25;;:30;3910:56;;1530:5;3976:17;1002:13720;3976:17;;;;;1002:13720;;;4021:15;;;;;;;;;-1:-1:-1;4021:15:23;;;-1:-1:-1;1002:13720:23;4062:2;1002:13720;;;4050:14;4046:47;;4103:26;;4139:31;1002:13720;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;4222:5;1002:13720;4190:55;;1002:13720;4229:5;4190:55;;;1002:13720;4236:3;4190:55;;;1002:13720;4241:3;4190:55;;;;1002:13720;;;;4180:65;1002:13720;;-1:-1:-1;;;;;;1002:13720:23;-1:-1:-1;;;;;;;;1002:13720:23;;;;;;;-1:-1:-1;;;1002:13720:23;;;;;4267:22;;;;;;;-1:-1:-1;;;;;4267:22:23;;;;;;;;;;;;-1:-1:-1;4267:22:23;;;;;4190:55;4255:34;;;1002:13720;;;4314:111;;;;-1:-1:-1;;;;;4314:111:23;;;;;;;;4190:55;4314:111;;;;;;4346:4;1002:13720;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;4314:111;;;-1:-1:-1;4314:111:23;;;;;1002:13720;4299:126;;;-1:-1:-1;;;;;1002:13720:23;4435:38;;;;;-1:-1:-1;1002:13720:23;;4435:38;1002:13720;;;;;;;;;4435:38;;4346:4;1530:5;4435:38;;1002:13720;4435:38;;;;;;;;-1:-1:-1;;4190:55:23;1002:13720;;;;;;4500:93;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;-1:-1:-1;;;;;4500:93:23;;;;;;;;;4190:55;4500:93;;;;;;;4346:4;1002:13720;;;;;;;;;;4500:93;;;;;;;;;1002:13720;4483:110;1002:13720;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;2093:20:1;1002:13720:23;;;1214:10;;;1002:13720;;4631:37;;1214:10;;;;;;;4603:13;1002:13720;1214:10;;;;1002:13720;;1214:10;;;;;1002:13720;1214:10;;;;;;;;;;1002:13720;;;;;;;;4190:55;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3976:17;1002:13720;;;;;;;;;;4103:26;1002:13720;;;;;;;;;;;;-1:-1:-1;;;1002:13720:23;;;1530:5;1002:13720;4435:38;1002:13720;;4500:93;1002:13720;;;;;;;;;;;4500:93;-1:-1:-1;;;1002:13720:23;;;1530:5;1002:13720;4435:38;1002:13720;;4435:38;;;;-1:-1:-1;4435:38:23;;:::i;:::-;-1:-1:-1;4435:38:23;;;;1002:13720;;;-1:-1:-1;1002:13720:23;;;;;4435:38;-1:-1:-1;1002:13720:23;;4314:111;1002:13720;;;-1:-1:-1;1002:13720:23;;1530:5;1002:13720;;-1:-1:-1;1002:13720:23;4046:47;4073:20;;;-1:-1:-1;4073:20:23;1530:5;-1:-1:-1;4073:20:23;4021:15;;;1002:13720;4021:15;;1002:13720;4021:15;;;;;;1002:13720;4021:15;;;:::i;:::-;;;1002:13720;;;;;;;;;;;;4021:15;;;;;;-1:-1:-1;4021:15:23;;3910:56;3953:13;;;-1:-1:-1;3953:13:23;1530:5;-1:-1:-1;3953:13:23;1269:95:0;1322:31;;;-1:-1:-1;1322:31:0;-1:-1:-1;1322:31:0;1002:13720:23;;-1:-1:-1;1322:31:0;1002:13720:23;;;;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;:::o","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa26469706673582212203190683f5d6bc5abb39a655d737ec2428316f3ace65c6ab0d982473f4e38da5864736f6c63430008230033","offset":13925},"2":{"value":"0xa2646970667358221220dbbc16195d46dd822a5bbc7c7a2c8ac6b3a2c13959882c7f071ff2c011021a2464736f6c63430008230033","offset":15919},"3":{"value":"0xa2646970667358221220f824fefce66b4cf1569e7d371fa6370cdccc1c2f8a88bdedc443c0ce47e0831a64736f6c63430008230033","offset":20746},"4":{"value":"0xa2646970667358221220272ca8beeb8120e5fcea1f6abad3910174ee29119b3514eea8a2ceccb1bdce8764736f6c63430008230033","offset":40739},"5":{"value":"0xa2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033","offset":33229},"6":{"value":"0xa26469706673582212201aca4a2b55465a13b08ec36674fca845ba424b771f3ea8c117e712cc7ec430c264736f6c63430008230033","offset":40686}},"transformations":[{"type":"insert","offset":40792,"reason":"constructorArguments"}],"transformationValues":{"constructorArguments":"0x00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d00000000000000000000000078f3556b67e17df817d51ef5a990cdaf09e8d3a9"}},"runtimeBytecode":{"onchainBytecode":"0x6080806040526004361015610012575f80fd5b5f905f3560e01c90816327cca59f14612018575080632931861b14611fc3578063315226d914611b9157806334fcaa3714611ec35780633cf28b5a14611d465780633d3d2d5814611c7257806345fb206314611c47578063470ef5fc14611bb357806350e25ac214611b96578063523af32814611b9157806354a4931c14611b7457806354faf9c314611b0357806358373f0414611ade5780636499386614611aad5780636783774b14611a905780636cd5bce4146119ff5780636dc97d6a146119885780636e47a1881461191b5780636f471f2d146118c5578063715018a614611862578063767b7c16146117c157806379ba50971461173c5780638009b7bd146116f8578063858f5964146116b457806389a69bd8146116455780638a36a6bb1461161d5780638da5cb5b146115f65780638e8d8ec5146114e55780639b924452146114bd5780639beacf4a1461145e5780639c5693eb146107cf578063abb918d814610786578063b18f1db114610684578063c4b7de971461063f578063c50497ae14610618578063cf3cf573146105fa578063df41ead2146105d7578063e30c3978146105ae578063e68b52e714610570578063e7ed38bd1461034a578063f1f5c99314610305578063f2fde38b14610298578063f325a5fb1461027a578063f9b3b8d9146102475763ffcb6e9f1461020d575f80fd5b3461024457602036600319011261024457602061022b60043561254a565b905460405160039290921b1c6001600160a01b03168152f35b80fd5b5034610244576020366003190112610244576020906004358152600c8252604060018060a01b0391205416604051908152f35b50346102445780600319360112610244576020600354604051908152f35b5034610244576020366003190112610244576102b2612032565b6102ba6126ee565b600180546001600160a01b0319166001600160a01b0392831690811790915582549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b50346102445780600319360112610244576040517f00000000000000000000000081ffb09b8abb42d0f6dc78a186ddf5e37b68e39b6001600160a01b03168152602090f35b5034610244576101203660031901126102445760643560443560243560a036608319011261056c5761037a6126ee565b6103e881118015610561575b8015610559575b801561054d575b8015610535575b801561051f575b8015610509575b80156104f3575b80156104e0575b80156104c9575b6104ba5760048035600255600391909155556005556001600160a01b036103e36124cc565b166001600160601b0360a01b60085416176008556103ff6124f6565b6008805461ffff60a01b191660a09290921b61ffff60a01b16919091179055610426612507565b6008805461ffff60b01b191660b09290921b61ffff60b01b1691909117905561044d612518565b6008805461ffff60c01b191660c09290921b61ffff60c01b16919091179055610474612529565b6008805461ffff60d01b191660d09290921b61ffff60d01b169190911790557f8f70233f68d766cfab4ff696858b5eba8fa61e09191134073df956473102569b8180a180f35b630256965f60e01b8452600484fd5b5061271061ffff6104d8612529565b1610156103be565b5061ffff6104ec612529565b16156103b7565b506103e861ffff610502612518565b16116103b0565b5061271061ffff610518612507565b16116103a9565b5061271061ffff61052e6124f6565b16116103a2565b506001600160a01b036105466124cc565b161561039b565b50620151808311610394565b50821561038d565b506126ac8211610386565b8380fd5b5034610244578060031936011261024457602060405160ff7f0000000000000000000000000000000000000000000000000000000000000008168152f35b50346102445780600319360112610244576001546040516001600160a01b039091168152602090f35b503461024457806003193601126102445760206040516717508f1956a800008152f35b50346102445780600319360112610244576020600254604051908152f35b503461024457806003193601126102445760206040516b033b2e3c9fd0803ce80000008152f35b50346102445780600319360112610244576040517f000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c6001600160a01b03168152602090f35b50346102445760403660031901126102445761069e612032565b906024359182151590818403610782576106b790612562565b60038101546001600160a01b031633141580610767575b6107585760048101805460ff60b01b191694151560b01b60ff60b01b16949094179093559091829190600101546001600160a01b031690813b15610754578291602483926040519485938492639a9b567d60e01b845260048401525af18015610749576107385750f35b8161074291612177565b6102445780f35b6040513d84823e3d90fd5b5050fd5b632e7e4e5160e21b8352600483fd5b5082546001600160a01b0316331415806106ce5750836106ce565b8280fd5b50346102445760403660031901126102445760209060ff906040906001600160a01b036107b1612032565b168152600d8452818120602435825284522054166040519015158152f35b50606036600319011261127c576001600160401b036004351161127c576101606004353603600319011261127c576108056126ee565b61080d61280f565b60243515801561143c575b61142e5761082760443561228f565b9161010460043501350361141f5760025434036114105761084c60c46004350161253b565b61ffff60035491161180156113e1575b6113d257335f52600d60205260405f2061012460043501355f5260205260ff60405f2054166113c357602061089c610144600435016004356004016130da565b9050116113b457335f52600d60205260405f2061012460043501355f5260205260405f20600160ff1982541617905560018060a01b036108e060a4600435016124e2565b166113a05733925b6acecb8f27f4200f3a0000009261ffff60085460c01c169161090e60c46004350161253b565b61ffff61091f60e46004350161310f565b916040519561092d8761215c565b5f875260018060a01b038a1660208801528760408801526060870152166080850152151560a084015260405192638dabdc8360e01b84526101e06004850152610a186109f06109c86109a061098c600435600401600435600401613130565b6101606101e48b01526103448a0191613161565b6109b4602460043501600435600401613130565b8983036101e319016102048b015290613161565b6109dc604460043501600435600401613130565b8883036101e319016102248a015290613161565b610a04606460043501600435600401613130565b8783036101e3190161024489015290613161565b60043560848101359190360360a2190182121561127c576004610ad99281350101906101e31987820301610264880152610acb610ac0610aa5610a8a610a6f610a618780613130565b60a0885260a0880191613161565b610a7c6020880188613130565b908783036020890152613161565b610a976040870187613130565b908683036040880152613161565b610ab26060860186613130565b908583036060870152613161565b926080810190613130565b916080818503910152613161565b906001600160a01b03610af060043560a40161205e565b1661028486015260c4600435013561ffff811680910361127c576102a4860152610b1e60e4600435016120d5565b15156102c48601526004356101048101356102e48701526101248101356103048701526101448101359036036022190181121561127c576004908135010160208101926001600160401b0382351161127c57813560051b3603841361127c578681036101e319016103248801528135815291928692602001915f5b8135811061137057505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190610bfb60e48301612701565b336101848301526b033b2e3c9fd0803ce80000006101a48301526101c4820189905203815f7f000000000000000000000000e39e27560a0c6bb38e54771bf3dc8e4c79928f936001600160a01b03165af193841561124f575f935f95611327575b50868486610e03610c7160c46004350161253b565b610de861ffff610c8560e46004350161310f565b926004604051610c948161210a565b60018060a01b0389168152602081019760018060a01b031688526040810199338b52606082019060018060a01b03168152608082019a5f8c528560a084019516855260c08301971515885260e083019960018b5261010084019b60018d5260018060a01b03165f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b51845460ff60b01b191690151560b01b60ff60b01b16178455565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790556001600160a01b0384165f908152600a602052604090206007198101611294575b50600b54600160401b8110156112805784610e73826001610e979401600b5561254a565b81546001600160a01b0393841660039290921b91821b9390911b1916919091179055565b610eac610144600435016004356004016130da565b979050600288018811610f7d57610ee06002610ec9818b01613181565b99610ed76040519b8c612177565b01808a52613181565b601f19013660208a013733610ef489613198565b526001600160a01b0316610f07886131a5565b525f5b610f1f610144600435016004356004016130da565b9050811015610fa557610f3d610144600435016004356004016130da565b821015610f9157610f52908260051b016124e2565b90600281018111610f7d57600191610f6d600283018b6131b5565b90838060a01b0316905201610f0a565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5085876001600160a01b0387163b1561127c576040805163251b648160e21b81526001600160a01b03881660048201526024810191909152815160448201819052909182916064830191602001905f5b81811061125a57505f93928390039150829050836001600160a01b038c165af1801561124f5761123a575b50600254806111ad575b506110f9916110b29160405190858252826020830152600160408301526060820152339060018060a01b038916907ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b608060018060a01b038b1692a46024358452600c6020526040842080546001600160a01b0319166001600160a01b03881617905561273e565b916001604051916110c283612126565b84835260406020840191838352838060a01b0389168152600e602052209251835551151591019060ff801983541691151516179055565b60408051918252600160208301526001600160a01b038416917fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79190a260408051604435815260208101929092526001600160a01b03831691602435917ff58d88bf88870587ec1fdf8ab973f10a093d9dc3c1a243e32f41fa5d73eda1b791a360015f5160206131ca5f395f51905f5255604080516001600160a01b039283168152929091166020830152819081015b0390f35b6008546001600160a01b037f000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c81169116813b1561123657906024869260405194859384926301aba89b60e71b845260048401525af1801561122b57908491611216575b5061102a565b8161122091612177565b610782578287611210565b6040513d86823e3d90fd5b8580fd5b6112479193505f90612177565b5f9186611020565b6040513d5f823e3d90fd5b82516001600160a01b0316845285945060209384019390920191600101610ff5565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155611321905b600854815461ffff60b01b191661ffff60b01b909116178155600854815461ffff60c01b191661ffff60c01b909116178155600854815461ffff60d01b191661ffff60d01b909116179055565b5f610e4f565b935093506040833d604011611368575b8161134460409383612177565b8101031261127c57611361602061135a8561311c565b940161311c565b935f610c5c565b3d9150611337565b919493509160019060209081906001600160a01b0361138e8961205e565b16815201950191019187939492610b99565b6113ae60a4600435016124e2565b926108e8565b630256965f60e01b5f5260045ffd5b630ced304360e01b5f5260045ffd5b6326b5197760e21b5f5260045ffd5b506107d061140a61ffff6113f960c46004350161253b565b1661ffff60085460c01c16906120e2565b1161085c565b637e6d78a560e01b5f5260045ffd5b631e5d0a3f60e11b5f5260045ffd5b62d532eb60e71b5f5260045ffd5b506024355f908152600c60205260409020546001600160a01b03161515610818565b3461127c57602036600319011261127c576001600160a01b0361147f612032565b165f908152600f60209081526040918290208054600182015460029092015484516001600160a01b0390921682529281019190915291820152606090f35b3461127c575f36600319011261127c576007546040516001600160a01b039091168152602090f35b3461127c57606036600319011261127c576114fe612032565b602435906044358015159182820361127c576115186126ee565b6001600160a01b031692831515806115d9575b6115ca57801580156115ba575b6113b4576115a07fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79360016040519161157083612126565b84835260208301908152875f52600e60205260405f209251835551151591019060ff801983541691151516179055565b60408051918252911515602082015290819081015b0390a2005b506001600160801b038111611538565b6349285dfb60e01b5f5260045ffd5b50835f52600960205260ff600460405f20015460b81c161561152b565b3461127c575f36600319011261127c575f546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c576006546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c5761165d61224e565b506111a960405161166d81612141565b61ffff60085460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c575f36600319011261127c576040517f000000000000000000000000e39e27560a0c6bb38e54771bf3dc8e4c79928f936001600160a01b03168152602090f35b3461127c575f36600319011261127c576040517f00000000000000000000000078f3556b67e17df817d51ef5a990cdaf09e8d3a96001600160a01b03168152602090f35b3461127c575f36600319011261127c57600154336001600160a01b03909116036117ae57600180546001600160a01b03199081169091555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461127c57602036600319011261127c576117da612032565b6117e26126ee565b600754906001600160a01b03821661185357803b15611844576001600160a01b03166001600160a01b03199190911681176007556040519081527f56b32d3633fed72f97c4df44a78b5fa04f1d662d4bddebcd8a9b216d26d093ad90602090a1005b63d92e233d60e01b5f5260045ffd5b63a741a04560e01b5f5260045ffd5b3461127c575f36600319011261127c5761187a6126ee565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461127c57602036600319011261127c576001600160a01b036118e6612032565b165f52600e60205260405f2060ff6001825492015416906111a960405192839283909291602090604083019483521515910152565b3461127c57602036600319011261127c57611934612032565b61193c6126ee565b6001600160a01b03165f818152600f60205260408120818155600181018290556002018190557f30241dede93b23e050576be65d204d53b18e8c6d9f75006095bfd422094d87569080a2005b604036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c576119d2906119c0612048565b6119c861280f565b3391600401612847565b60015f5160206131ca5f395f51905f5255604080516001600160a01b039384168152919092166020820152f35b606036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c57611a33612048565b604435906001600160a01b03821680830361127c57611a5061280f565b6007546001600160a01b0316331480159190611a87575b50611a78576119d292600401612847565b63754f554b60e11b5f5260045ffd5b90501584611a67565b3461127c575f36600319011261127c576020600554604051908152f35b3461127c57602036600319011261127c576060611acb60043561228f565b9060405192835260208301526040820152f35b3461127c57602036600319011261127c57611af7612032565b50602060405160018152f35b3461127c57602036600319011261127c57611b1c612032565b611b246126ee565b6001600160a01b03168015611844576020817fae994ca926e252e299c3df7516cb609272a57bf80b0e0715297e55939f873420926001600160601b0360a01b6006541617600655604051908152a1005b3461127c575f36600319011261127c576020604051620151808152f35b612072565b3461127c575f36600319011261127c576020600454604051908152f35b3461127c57602036600319011261127c57611bcc612032565b611bd461224e565b50611bde81612562565b5060018060a01b03165f52600a6020526111a960405f2061ffff60405191611c0583612141565b5460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c57602036600319011261127c576020611c6a611c65612032565b612198565b604051908152f35b3461127c57602036600319011261127c57611c8b612032565b611c936126ee565b60018060a01b03811690815f52600f60205260405f2060405190611cb6826120ef565b80546001600160a01b0316808352600182015460208401819052600290920154604084018190529015918215611d3c575b508115611d32575b50611d2357611d21925f52600f6020525f600260408220828155826001820155015560018060a01b0390511690612597565b005b63aa0b7b6160e01b5f5260045ffd5b9050421184611cef565b4210915085611ce7565b3461127c57602036600319011261127c57611d5f612032565b5f610100604051611d6f8161210a565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152015260018060a01b03165f52600960205261012060405f2060405190611dc18261210a565b60018060a01b038154169182815260018060a01b036001830154166020820190815261ffff60018060a01b0360028501541660408401908152600460018060a01b036003870154169560608601968752015494608085019060018060a01b038716825260a0860192848860a01c16845260c087019560ff8960b01c161515875260ff61010060e08a0199828c60b81c1615158b52019960c01c1615158952604051998a5260018060a01b0390511660208a015260018060a01b03905116604089015260018060a01b03905116606088015260018060a01b039051166080870152511660a085015251151560c084015251151560e0830152511515610100820152f35b3461127c57604036600319011261127c57611edc612032565b611ee4612048565b611eec6126ee565b611ef582612562565b506001600160a01b038116908115611844576203f480420190814211610f7d576207e900420192838311610f7d577f22b336cc3c163283ca94b8a02d1107b4485a820fa77cc12ea205640452d37b5e936115b59160405190611f56826120ef565b8152602080820186815260408084018581526001600160a01b039a8b165f818152600f8652839020955186546001600160a01b031916908d161786559251600186015551600294909401939093558251959098168552840194909452928201929092529081906060820190565b3461127c57604036600319011261127c57611fdc612032565b611fe4612048565b6001600160a01b036003611ff784612562565b015416330361200957611d2191612597565b632e7e4e5160e21b5f5260045ffd5b3461127c575f36600319011261127c57602090600b548152f35b600435906001600160a01b038216820361127c57565b602435906001600160a01b038216820361127c57565b35906001600160a01b038216820361127c57565b3461127c575f36600319011261127c5760206040516203f4808152f35b919091608061ffff8160a084019560018060a01b038151168552826020820151166020860152826040820151166040860152826060820151166060860152015116910152565b3590811515820361127c57565b91908201809211610f7d57565b606081019081106001600160401b0382111761128057604052565b61012081019081106001600160401b0382111761128057604052565b604081019081106001600160401b0382111761128057604052565b60a081019081106001600160401b0382111761128057604052565b60c081019081106001600160401b0382111761128057604052565b90601f801991011681019081106001600160401b0382111761128057604052565b60018060a01b0316805f52600e60205260405f2060ff6001604051926121bd84612126565b8054845201541615801560208301526115ca575160025460035460045490600554926040519460208601964688523060408801526b033b2e3c9fd0803ce80000006060880152608087015260a08601525f60c086015260e08501526101008401526101208301526101408201526122376101608201612701565b6101e0815261224861020082612177565b51902090565b6040519061225b82612141565b5f6080838281528260208201528260408201528260608201520152565b519069ffffffffffffffffffff8216820361127c57565b614650811080156124c1575b61241757604051633fabe5a360e21b815260a0816004817f00000000000000000000000078f3556b67e17df817d51ef5a990cdaf09e8d3a96001600160a01b03165afa801561124f575f915f9161246d575b505f821390811591612464575b811561245a575b8115612444575b50612436578091670de0b6b3a7640000810290808204670de0b6b3a76400001490151715610f7d5760ff7f000000000000000000000000000000000000000000000000000000000000000816604d8111610f7d57600a0a80600302906003820403610f7d576001600160fe1b0383168303610f7d5761238a9260021b91612770565b9081158015612426575b61241757600254600354600454600554906040519260208401944686523060408601526b033b2e3c9fd0803ce800000060608601525f60808601528760a0860152600160c086015260e08501526101008401526101208301526101408201526124006101608201612701565b6101e0815261241161020082612177565b51902092565b6330d7115160e11b5f5260045ffd5b506001600160801b038211612394565b62fc7cad60e51b5f5260045ffd5b90504203428111610f7d5762015180105f612308565b4281119150612301565b801591506122fa565b91505060a0813d60a0116124b9575b8161248960a09383612177565b8101031261127c5761249a81612278565b5060208101516124b1608060608401519301612278565b50905f6122ed565b3d915061247c565b506161a8811161229b565b6084356001600160a01b038116810361127c5790565b356001600160a01b038116810361127c5790565b60a43561ffff8116810361127c5790565b60c43561ffff8116810361127c5790565b60e43561ffff8116810361127c5790565b6101043561ffff8116810361127c5790565b3561ffff8116810361127c5790565b600b54811015610f9157600b5f5260205f2001905f90565b60018060a01b03165f52600960205260405f209060ff600483015460c01c161561258857565b638698bf3760e01b5f5260045ffd5b6001600160a01b03821691905f908315611844576125b481612562565b6003810180546001600160a01b0319811687179091556001909101546001600160a01b03918216949116803b1561127c575f8091602460405180948193633d82753160e11b83528b60048401525af1801561124f576126d9575b507f00000000000000000000000081ffb09b8abb42d0f6dc78a186ddf5e37b68e39b6001600160a01b031690813b1561056c57604051635ad7fc1760e01b81526001600160a01b0384811660048301529190911660248201529083908290604490829084905af180156126ce579083916126b5575b50506001600160a01b0316907f308c390ed1ab5873392818e036cabdf408bc8ad042fbaead3108954ff75ba9809080a4565b816126bf91612177565b6126ca57815f612683565b5080fd5b6040513d85823e3d90fd5b6126e69193505f90612177565b5f915f61260e565b5f546001600160a01b031633036117ae57565b608061ffff60085460018060a01b0381168452818160a01c166020850152818160b01c166040850152818160c01c16606085015260d01c16910152565b801561275c57723880173480caadff41f996746e3000000000000490565b634e487b7160e01b5f52601260045260245ffd5b90915f19838309928083029283808610950394808603951461280157848311156127e95790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b50509150811561275c570490565b60025f5160206131ca5f395f51905f5254146128385760025f5160206131ca5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b90915f9361285484612198565b6101008401350361141f5760018060a01b0384165f52600e60205260405f20549460025434036114105761288a60c0850161253b565b61ffff60035491161180156130be575b6113d25760018060a01b0383165f52600d60205260405f206101208501355f5260205260ff60405f2054166113c35760206128d96101408601866130da565b9050116113b4576001600160a01b038381165f908152600d6020908152604080832061012089013584529091529020805460ff1916600117905561291f60a086016124e2565b166130ac5782945b61ffff60085460c01c169161293e60c0870161253b565b61ffff61294d60e0890161310f565b916040519561295b8761215c565b6001600160a01b0386811688528b16602088015260408088018d905260608801919091529116608086015290151560a085015251638dabdc8360e01b81526101e06004820152926129df6129d26129c56129b861098c8b80613130565b6109b460208c018c613130565b6109dc60408b018b613130565b610a0460608a018a613130565b90608088013588360392609e19840182121561127c578681036101e31901610264880152612a23918a0190610acb610ac0610aa5610a8a610a6f610a618780613130565b916001600160a01b03612a3860a08b0161205e565b1661028487015260c089013561ffff811680910361127c576102a4870152612a6260e08a016120d5565b15156102c48701526101008901356102e487015261012089013561030487015261014089013590601e190181121561127c578801602081359101926001600160401b03821161127c578160051b3603841361127c578681036101e3190161032488015281815291928692602001915f5b81811061307c57505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190612b3360e48301612701565b6001600160a01b038981166101848401526b033b2e3c9fd0803ce80000006101a48401525f6101c48401819052929091039183917f000000000000000000000000e39e27560a0c6bb38e54771bf3dc8e4c79928f93165af194851561124f5787915f945f9761302c575b5090600491848989612d32612bc060e0612bb960c0860161253b565b940161310f565b610de861ffff60405195612bd38761210a565b8d60018060a01b03169a878c809952602081019760018060a01b03169d8e8952604082018d60018060a01b03168152606083019160018060a01b03168252608083019b60018060a01b03168c528560a084019516855260c08301971515885260e08301995f8b5261010084019b60018d525f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790555f838152600a602052604090206007198101612fe2575b50600b54600160401b8110156112805786610e73826001612d989401600b5561254a565b612da66101408a018a6130da565b9b905060028c01809c11610f7d57612dbd8c613181565b9b6040519c612dcc908e612177565b808d52612dd890613181565b60208d019b90601f1901368d376001600160a01b038416612df88e613198565b526001600160a01b0316612e0b8d6131a5565b525f5b612e1c6101408c018c6130da565b9050811015612e7257612e336101408c018c6130da565b821015610f9157612e48908260051b016124e2565b906002810191828211610f7d57612e628f936001946131b5565b90838060a01b0316905201612e0e565b50929598509295989990939699863b1561127c576040805163251b648160e21b8152600481018890526024810191909152915160448301819052829160648301915f5b818110612fc05750505090805f920381838a5af1801561124f57612fab575b5060025480612f32575b50604080516001600160a01b0397881681526020810192909252810182905260608101919091529316927ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b90608090a49190565b6008546001600160a01b037f000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c81169116813b15612fa757906024859260405194859384926301aba89b60e71b845260048401525af180156126ce5715612ede57612f9d838092612177565b6126ca575f612ede565b8480fd5b612fb89192505f90612177565b5f905f612ed4565b82516001600160a01b0316845285945060209384019390920191600101612eb5565b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155613026906112d4565b5f612d74565b9450955090506040833d604011613074575b8161304b60409383612177565b8101031261127c576004879161306c60206130658761311c565b960161311c565b969091612b9d565b3d915061303e565b919493509160019060209081906001600160a01b0361309a8961205e565b16815201950191019187939492612ad2565b6130b860a085016124e2565b94612927565b506107d06130d461ffff6113f960c0880161253b565b1161289a565b903590601e198136030182121561127c57018035906001600160401b03821161127c57602001918160051b3603831361127c57565b35801515810361127c5790565b51906001600160a01b038216820361127c57565b9035601e198236030181121561127c5701602081359101916001600160401b03821161127c57813603831361127c57565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b0381116112805760051b60200190565b805115610f915760200190565b805160011015610f915760400190565b8051821015610f915760209160051b01019056fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212203190683f5d6bc5abb39a655d737ec2428316f3ace65c6ab0d982473f4e38da5864736f6c63430008230033","recompiledBytecode":"0x6080806040526004361015610012575f80fd5b5f905f3560e01c90816327cca59f14612018575080632931861b14611fc3578063315226d914611b9157806334fcaa3714611ec35780633cf28b5a14611d465780633d3d2d5814611c7257806345fb206314611c47578063470ef5fc14611bb357806350e25ac214611b96578063523af32814611b9157806354a4931c14611b7457806354faf9c314611b0357806358373f0414611ade5780636499386614611aad5780636783774b14611a905780636cd5bce4146119ff5780636dc97d6a146119885780636e47a1881461191b5780636f471f2d146118c5578063715018a614611862578063767b7c16146117c157806379ba50971461173c5780638009b7bd146116f8578063858f5964146116b457806389a69bd8146116455780638a36a6bb1461161d5780638da5cb5b146115f65780638e8d8ec5146114e55780639b924452146114bd5780639beacf4a1461145e5780639c5693eb146107cf578063abb918d814610786578063b18f1db114610684578063c4b7de971461063f578063c50497ae14610618578063cf3cf573146105fa578063df41ead2146105d7578063e30c3978146105ae578063e68b52e714610570578063e7ed38bd1461034a578063f1f5c99314610305578063f2fde38b14610298578063f325a5fb1461027a578063f9b3b8d9146102475763ffcb6e9f1461020d575f80fd5b3461024457602036600319011261024457602061022b60043561254a565b905460405160039290921b1c6001600160a01b03168152f35b80fd5b5034610244576020366003190112610244576020906004358152600c8252604060018060a01b0391205416604051908152f35b50346102445780600319360112610244576020600354604051908152f35b5034610244576020366003190112610244576102b2612032565b6102ba6126ee565b600180546001600160a01b0319166001600160a01b0392831690811790915582549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610244576101203660031901126102445760643560443560243560a036608319011261056c5761037a6126ee565b6103e881118015610561575b8015610559575b801561054d575b8015610535575b801561051f575b8015610509575b80156104f3575b80156104e0575b80156104c9575b6104ba5760048035600255600391909155556005556001600160a01b036103e36124cc565b166001600160601b0360a01b60085416176008556103ff6124f6565b6008805461ffff60a01b191660a09290921b61ffff60a01b16919091179055610426612507565b6008805461ffff60b01b191660b09290921b61ffff60b01b1691909117905561044d612518565b6008805461ffff60c01b191660c09290921b61ffff60c01b16919091179055610474612529565b6008805461ffff60d01b191660d09290921b61ffff60d01b169190911790557f8f70233f68d766cfab4ff696858b5eba8fa61e09191134073df956473102569b8180a180f35b630256965f60e01b8452600484fd5b5061271061ffff6104d8612529565b1610156103be565b5061ffff6104ec612529565b16156103b7565b506103e861ffff610502612518565b16116103b0565b5061271061ffff610518612507565b16116103a9565b5061271061ffff61052e6124f6565b16116103a2565b506001600160a01b036105466124cc565b161561039b565b50620151808311610394565b50821561038d565b506126ac8211610386565b8380fd5b5034610244578060031936011261024457602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346102445780600319360112610244576001546040516001600160a01b039091168152602090f35b503461024457806003193601126102445760206040516717508f1956a800008152f35b50346102445780600319360112610244576020600254604051908152f35b503461024457806003193601126102445760206040516b033b2e3c9fd0803ce80000008152f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346102445760403660031901126102445761069e612032565b906024359182151590818403610782576106b790612562565b60038101546001600160a01b031633141580610767575b6107585760048101805460ff60b01b191694151560b01b60ff60b01b16949094179093559091829190600101546001600160a01b031690813b15610754578291602483926040519485938492639a9b567d60e01b845260048401525af18015610749576107385750f35b8161074291612177565b6102445780f35b6040513d84823e3d90fd5b5050fd5b632e7e4e5160e21b8352600483fd5b5082546001600160a01b0316331415806106ce5750836106ce565b8280fd5b50346102445760403660031901126102445760209060ff906040906001600160a01b036107b1612032565b168152600d8452818120602435825284522054166040519015158152f35b50606036600319011261127c576001600160401b036004351161127c576101606004353603600319011261127c576108056126ee565b61080d61280f565b60243515801561143c575b61142e5761082760443561228f565b9161010460043501350361141f5760025434036114105761084c60c46004350161253b565b61ffff60035491161180156113e1575b6113d257335f52600d60205260405f2061012460043501355f5260205260ff60405f2054166113c357602061089c610144600435016004356004016130da565b9050116113b457335f52600d60205260405f2061012460043501355f5260205260405f20600160ff1982541617905560018060a01b036108e060a4600435016124e2565b166113a05733925b6acecb8f27f4200f3a0000009261ffff60085460c01c169161090e60c46004350161253b565b61ffff61091f60e46004350161310f565b916040519561092d8761215c565b5f875260018060a01b038a1660208801528760408801526060870152166080850152151560a084015260405192638dabdc8360e01b84526101e06004850152610a186109f06109c86109a061098c600435600401600435600401613130565b6101606101e48b01526103448a0191613161565b6109b4602460043501600435600401613130565b8983036101e319016102048b015290613161565b6109dc604460043501600435600401613130565b8883036101e319016102248a015290613161565b610a04606460043501600435600401613130565b8783036101e3190161024489015290613161565b60043560848101359190360360a2190182121561127c576004610ad99281350101906101e31987820301610264880152610acb610ac0610aa5610a8a610a6f610a618780613130565b60a0885260a0880191613161565b610a7c6020880188613130565b908783036020890152613161565b610a976040870187613130565b908683036040880152613161565b610ab26060860186613130565b908583036060870152613161565b926080810190613130565b916080818503910152613161565b906001600160a01b03610af060043560a40161205e565b1661028486015260c4600435013561ffff811680910361127c576102a4860152610b1e60e4600435016120d5565b15156102c48601526004356101048101356102e48701526101248101356103048701526101448101359036036022190181121561127c576004908135010160208101926001600160401b0382351161127c57813560051b3603841361127c578681036101e319016103248801528135815291928692602001915f5b8135811061137057505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190610bfb60e48301612701565b336101848301526b033b2e3c9fd0803ce80000006101a48301526101c4820189905203815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af193841561124f575f935f95611327575b50868486610e03610c7160c46004350161253b565b610de861ffff610c8560e46004350161310f565b926004604051610c948161210a565b60018060a01b0389168152602081019760018060a01b031688526040810199338b52606082019060018060a01b03168152608082019a5f8c528560a084019516855260c08301971515885260e083019960018b5261010084019b60018d5260018060a01b03165f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b51845460ff60b01b191690151560b01b60ff60b01b16178455565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790556001600160a01b0384165f908152600a602052604090206007198101611294575b50600b54600160401b8110156112805784610e73826001610e979401600b5561254a565b81546001600160a01b0393841660039290921b91821b9390911b1916919091179055565b610eac610144600435016004356004016130da565b979050600288018811610f7d57610ee06002610ec9818b01613181565b99610ed76040519b8c612177565b01808a52613181565b601f19013660208a013733610ef489613198565b526001600160a01b0316610f07886131a5565b525f5b610f1f610144600435016004356004016130da565b9050811015610fa557610f3d610144600435016004356004016130da565b821015610f9157610f52908260051b016124e2565b90600281018111610f7d57600191610f6d600283018b6131b5565b90838060a01b0316905201610f0a565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5085876001600160a01b0387163b1561127c576040805163251b648160e21b81526001600160a01b03881660048201526024810191909152815160448201819052909182916064830191602001905f5b81811061125a57505f93928390039150829050836001600160a01b038c165af1801561124f5761123a575b50600254806111ad575b506110f9916110b29160405190858252826020830152600160408301526060820152339060018060a01b038916907ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b608060018060a01b038b1692a46024358452600c6020526040842080546001600160a01b0319166001600160a01b03881617905561273e565b916001604051916110c283612126565b84835260406020840191838352838060a01b0389168152600e602052209251835551151591019060ff801983541691151516179055565b60408051918252600160208301526001600160a01b038416917fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79190a260408051604435815260208101929092526001600160a01b03831691602435917ff58d88bf88870587ec1fdf8ab973f10a093d9dc3c1a243e32f41fa5d73eda1b791a360015f5160206131ca5f395f51905f5255604080516001600160a01b039283168152929091166020830152819081015b0390f35b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b1561123657906024869260405194859384926301aba89b60e71b845260048401525af1801561122b57908491611216575b5061102a565b8161122091612177565b610782578287611210565b6040513d86823e3d90fd5b8580fd5b6112479193505f90612177565b5f9186611020565b6040513d5f823e3d90fd5b82516001600160a01b0316845285945060209384019390920191600101610ff5565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155611321905b600854815461ffff60b01b191661ffff60b01b909116178155600854815461ffff60c01b191661ffff60c01b909116178155600854815461ffff60d01b191661ffff60d01b909116179055565b5f610e4f565b935093506040833d604011611368575b8161134460409383612177565b8101031261127c57611361602061135a8561311c565b940161311c565b935f610c5c565b3d9150611337565b919493509160019060209081906001600160a01b0361138e8961205e565b16815201950191019187939492610b99565b6113ae60a4600435016124e2565b926108e8565b630256965f60e01b5f5260045ffd5b630ced304360e01b5f5260045ffd5b6326b5197760e21b5f5260045ffd5b506107d061140a61ffff6113f960c46004350161253b565b1661ffff60085460c01c16906120e2565b1161085c565b637e6d78a560e01b5f5260045ffd5b631e5d0a3f60e11b5f5260045ffd5b62d532eb60e71b5f5260045ffd5b506024355f908152600c60205260409020546001600160a01b03161515610818565b3461127c57602036600319011261127c576001600160a01b0361147f612032565b165f908152600f60209081526040918290208054600182015460029092015484516001600160a01b0390921682529281019190915291820152606090f35b3461127c575f36600319011261127c576007546040516001600160a01b039091168152602090f35b3461127c57606036600319011261127c576114fe612032565b602435906044358015159182820361127c576115186126ee565b6001600160a01b031692831515806115d9575b6115ca57801580156115ba575b6113b4576115a07fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79360016040519161157083612126565b84835260208301908152875f52600e60205260405f209251835551151591019060ff801983541691151516179055565b60408051918252911515602082015290819081015b0390a2005b506001600160801b038111611538565b6349285dfb60e01b5f5260045ffd5b50835f52600960205260ff600460405f20015460b81c161561152b565b3461127c575f36600319011261127c575f546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c576006546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c5761165d61224e565b506111a960405161166d81612141565b61ffff60085460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c57600154336001600160a01b03909116036117ae57600180546001600160a01b03199081169091555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461127c57602036600319011261127c576117da612032565b6117e26126ee565b600754906001600160a01b03821661185357803b15611844576001600160a01b03166001600160a01b03199190911681176007556040519081527f56b32d3633fed72f97c4df44a78b5fa04f1d662d4bddebcd8a9b216d26d093ad90602090a1005b63d92e233d60e01b5f5260045ffd5b63a741a04560e01b5f5260045ffd5b3461127c575f36600319011261127c5761187a6126ee565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461127c57602036600319011261127c576001600160a01b036118e6612032565b165f52600e60205260405f2060ff6001825492015416906111a960405192839283909291602090604083019483521515910152565b3461127c57602036600319011261127c57611934612032565b61193c6126ee565b6001600160a01b03165f818152600f60205260408120818155600181018290556002018190557f30241dede93b23e050576be65d204d53b18e8c6d9f75006095bfd422094d87569080a2005b604036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c576119d2906119c0612048565b6119c861280f565b3391600401612847565b60015f5160206131ca5f395f51905f5255604080516001600160a01b039384168152919092166020820152f35b606036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c57611a33612048565b604435906001600160a01b03821680830361127c57611a5061280f565b6007546001600160a01b0316331480159190611a87575b50611a78576119d292600401612847565b63754f554b60e11b5f5260045ffd5b90501584611a67565b3461127c575f36600319011261127c576020600554604051908152f35b3461127c57602036600319011261127c576060611acb60043561228f565b9060405192835260208301526040820152f35b3461127c57602036600319011261127c57611af7612032565b50602060405160018152f35b3461127c57602036600319011261127c57611b1c612032565b611b246126ee565b6001600160a01b03168015611844576020817fae994ca926e252e299c3df7516cb609272a57bf80b0e0715297e55939f873420926001600160601b0360a01b6006541617600655604051908152a1005b3461127c575f36600319011261127c576020604051620151808152f35b612072565b3461127c575f36600319011261127c576020600454604051908152f35b3461127c57602036600319011261127c57611bcc612032565b611bd461224e565b50611bde81612562565b5060018060a01b03165f52600a6020526111a960405f2061ffff60405191611c0583612141565b5460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c57602036600319011261127c576020611c6a611c65612032565b612198565b604051908152f35b3461127c57602036600319011261127c57611c8b612032565b611c936126ee565b60018060a01b03811690815f52600f60205260405f2060405190611cb6826120ef565b80546001600160a01b0316808352600182015460208401819052600290920154604084018190529015918215611d3c575b508115611d32575b50611d2357611d21925f52600f6020525f600260408220828155826001820155015560018060a01b0390511690612597565b005b63aa0b7b6160e01b5f5260045ffd5b9050421184611cef565b4210915085611ce7565b3461127c57602036600319011261127c57611d5f612032565b5f610100604051611d6f8161210a565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152015260018060a01b03165f52600960205261012060405f2060405190611dc18261210a565b60018060a01b038154169182815260018060a01b036001830154166020820190815261ffff60018060a01b0360028501541660408401908152600460018060a01b036003870154169560608601968752015494608085019060018060a01b038716825260a0860192848860a01c16845260c087019560ff8960b01c161515875260ff61010060e08a0199828c60b81c1615158b52019960c01c1615158952604051998a5260018060a01b0390511660208a015260018060a01b03905116604089015260018060a01b03905116606088015260018060a01b039051166080870152511660a085015251151560c084015251151560e0830152511515610100820152f35b3461127c57604036600319011261127c57611edc612032565b611ee4612048565b611eec6126ee565b611ef582612562565b506001600160a01b038116908115611844576203f480420190814211610f7d576207e900420192838311610f7d577f22b336cc3c163283ca94b8a02d1107b4485a820fa77cc12ea205640452d37b5e936115b59160405190611f56826120ef565b8152602080820186815260408084018581526001600160a01b039a8b165f818152600f8652839020955186546001600160a01b031916908d161786559251600186015551600294909401939093558251959098168552840194909452928201929092529081906060820190565b3461127c57604036600319011261127c57611fdc612032565b611fe4612048565b6001600160a01b036003611ff784612562565b015416330361200957611d2191612597565b632e7e4e5160e21b5f5260045ffd5b3461127c575f36600319011261127c57602090600b548152f35b600435906001600160a01b038216820361127c57565b602435906001600160a01b038216820361127c57565b35906001600160a01b038216820361127c57565b3461127c575f36600319011261127c5760206040516203f4808152f35b919091608061ffff8160a084019560018060a01b038151168552826020820151166020860152826040820151166040860152826060820151166060860152015116910152565b3590811515820361127c57565b91908201809211610f7d57565b606081019081106001600160401b0382111761128057604052565b61012081019081106001600160401b0382111761128057604052565b604081019081106001600160401b0382111761128057604052565b60a081019081106001600160401b0382111761128057604052565b60c081019081106001600160401b0382111761128057604052565b90601f801991011681019081106001600160401b0382111761128057604052565b60018060a01b0316805f52600e60205260405f2060ff6001604051926121bd84612126565b8054845201541615801560208301526115ca575160025460035460045490600554926040519460208601964688523060408801526b033b2e3c9fd0803ce80000006060880152608087015260a08601525f60c086015260e08501526101008401526101208301526101408201526122376101608201612701565b6101e0815261224861020082612177565b51902090565b6040519061225b82612141565b5f6080838281528260208201528260408201528260608201520152565b519069ffffffffffffffffffff8216820361127c57565b614650811080156124c1575b61241757604051633fabe5a360e21b815260a0816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801561124f575f915f9161246d575b505f821390811591612464575b811561245a575b8115612444575b50612436578091670de0b6b3a7640000810290808204670de0b6b3a76400001490151715610f7d5760ff7f000000000000000000000000000000000000000000000000000000000000000016604d8111610f7d57600a0a80600302906003820403610f7d576001600160fe1b0383168303610f7d5761238a9260021b91612770565b9081158015612426575b61241757600254600354600454600554906040519260208401944686523060408601526b033b2e3c9fd0803ce800000060608601525f60808601528760a0860152600160c086015260e08501526101008401526101208301526101408201526124006101608201612701565b6101e0815261241161020082612177565b51902092565b6330d7115160e11b5f5260045ffd5b506001600160801b038211612394565b62fc7cad60e51b5f5260045ffd5b90504203428111610f7d5762015180105f612308565b4281119150612301565b801591506122fa565b91505060a0813d60a0116124b9575b8161248960a09383612177565b8101031261127c5761249a81612278565b5060208101516124b1608060608401519301612278565b50905f6122ed565b3d915061247c565b506161a8811161229b565b6084356001600160a01b038116810361127c5790565b356001600160a01b038116810361127c5790565b60a43561ffff8116810361127c5790565b60c43561ffff8116810361127c5790565b60e43561ffff8116810361127c5790565b6101043561ffff8116810361127c5790565b3561ffff8116810361127c5790565b600b54811015610f9157600b5f5260205f2001905f90565b60018060a01b03165f52600960205260405f209060ff600483015460c01c161561258857565b638698bf3760e01b5f5260045ffd5b6001600160a01b03821691905f908315611844576125b481612562565b6003810180546001600160a01b0319811687179091556001909101546001600160a01b03918216949116803b1561127c575f8091602460405180948193633d82753160e11b83528b60048401525af1801561124f576126d9575b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b1561056c57604051635ad7fc1760e01b81526001600160a01b0384811660048301529190911660248201529083908290604490829084905af180156126ce579083916126b5575b50506001600160a01b0316907f308c390ed1ab5873392818e036cabdf408bc8ad042fbaead3108954ff75ba9809080a4565b816126bf91612177565b6126ca57815f612683565b5080fd5b6040513d85823e3d90fd5b6126e69193505f90612177565b5f915f61260e565b5f546001600160a01b031633036117ae57565b608061ffff60085460018060a01b0381168452818160a01c166020850152818160b01c166040850152818160c01c16606085015260d01c16910152565b801561275c57723880173480caadff41f996746e3000000000000490565b634e487b7160e01b5f52601260045260245ffd5b90915f19838309928083029283808610950394808603951461280157848311156127e95790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b50509150811561275c570490565b60025f5160206131ca5f395f51905f5254146128385760025f5160206131ca5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b90915f9361285484612198565b6101008401350361141f5760018060a01b0384165f52600e60205260405f20549460025434036114105761288a60c0850161253b565b61ffff60035491161180156130be575b6113d25760018060a01b0383165f52600d60205260405f206101208501355f5260205260ff60405f2054166113c35760206128d96101408601866130da565b9050116113b4576001600160a01b038381165f908152600d6020908152604080832061012089013584529091529020805460ff1916600117905561291f60a086016124e2565b166130ac5782945b61ffff60085460c01c169161293e60c0870161253b565b61ffff61294d60e0890161310f565b916040519561295b8761215c565b6001600160a01b0386811688528b16602088015260408088018d905260608801919091529116608086015290151560a085015251638dabdc8360e01b81526101e06004820152926129df6129d26129c56129b861098c8b80613130565b6109b460208c018c613130565b6109dc60408b018b613130565b610a0460608a018a613130565b90608088013588360392609e19840182121561127c578681036101e31901610264880152612a23918a0190610acb610ac0610aa5610a8a610a6f610a618780613130565b916001600160a01b03612a3860a08b0161205e565b1661028487015260c089013561ffff811680910361127c576102a4870152612a6260e08a016120d5565b15156102c48701526101008901356102e487015261012089013561030487015261014089013590601e190181121561127c578801602081359101926001600160401b03821161127c578160051b3603841361127c578681036101e3190161032488015281815291928692602001915f5b81811061307c57505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190612b3360e48301612701565b6001600160a01b038981166101848401526b033b2e3c9fd0803ce80000006101a48401525f6101c48401819052929091039183917f0000000000000000000000000000000000000000000000000000000000000000165af194851561124f5787915f945f9761302c575b5090600491848989612d32612bc060e0612bb960c0860161253b565b940161310f565b610de861ffff60405195612bd38761210a565b8d60018060a01b03169a878c809952602081019760018060a01b03169d8e8952604082018d60018060a01b03168152606083019160018060a01b03168252608083019b60018060a01b03168c528560a084019516855260c08301971515885260e08301995f8b5261010084019b60018d525f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790555f838152600a602052604090206007198101612fe2575b50600b54600160401b8110156112805786610e73826001612d989401600b5561254a565b612da66101408a018a6130da565b9b905060028c01809c11610f7d57612dbd8c613181565b9b6040519c612dcc908e612177565b808d52612dd890613181565b60208d019b90601f1901368d376001600160a01b038416612df88e613198565b526001600160a01b0316612e0b8d6131a5565b525f5b612e1c6101408c018c6130da565b9050811015612e7257612e336101408c018c6130da565b821015610f9157612e48908260051b016124e2565b906002810191828211610f7d57612e628f936001946131b5565b90838060a01b0316905201612e0e565b50929598509295989990939699863b1561127c576040805163251b648160e21b8152600481018890526024810191909152915160448301819052829160648301915f5b818110612fc05750505090805f920381838a5af1801561124f57612fab575b5060025480612f32575b50604080516001600160a01b0397881681526020810192909252810182905260608101919091529316927ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b90608090a49190565b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b15612fa757906024859260405194859384926301aba89b60e71b845260048401525af180156126ce5715612ede57612f9d838092612177565b6126ca575f612ede565b8480fd5b612fb89192505f90612177565b5f905f612ed4565b82516001600160a01b0316845285945060209384019390920191600101612eb5565b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155613026906112d4565b5f612d74565b9450955090506040833d604011613074575b8161304b60409383612177565b8101031261127c576004879161306c60206130658761311c565b960161311c565b969091612b9d565b3d915061303e565b919493509160019060209081906001600160a01b0361309a8961205e565b16815201950191019187939492612ad2565b6130b860a085016124e2565b94612927565b506107d06130d461ffff6113f960c0880161253b565b1161289a565b903590601e198136030182121561127c57018035906001600160401b03821161127c57602001918160051b3603831361127c57565b35801515810361127c5790565b51906001600160a01b038216820361127c57565b9035601e198236030181121561127c5701602081359101916001600160401b03821161127c57813603831361127c57565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b0381116112805760051b60200190565b805115610f915760200190565b805160011015610f915760400190565b8051821015610f915760209160051b01019056fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212203190683f5d6bc5abb39a655d737ec2428316f3ace65c6ab0d982473f4e38da5864736f6c63430008230033","sourceMap":"1002:13720:23:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;5222:14;1002:13720;;5222:14;:::i;:::-;1002:13720;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;2099:48;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1451:39;1002:13720;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;1002:13720:23;;;-1:-1:-1;;;;;;1002:13720:23;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;1777:43:1;1002:13720:23;;1777:43:1;1002:13720:23;;;;;;;;;;;;;;;;;1703:49;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;1500:62:0;;:::i;:::-;11284:5:23;11268:21;;:43;;;;1002:13720;11268:63;;;;1002:13720;11268:87;;;;1002:13720;11268:132;;;;1002:13720;11268:171;;;;1002:13720;11268:205;;;;1002:13720;11268:234;;;;1002:13720;11268:275;;;;1002:13720;11268:321;;;;1002:13720;11264:348;;1002:13720;;;11622:24;1002:13720;11648:32;1002:13720;;;;;11713:29;1002:13720;-1:-1:-1;;;;;1002:13720:23;;:::i;:::-;;-1:-1:-1;;;;;1002:13720:23;;11744:16;1002:13720;;;11744:16;1002:13720;;;:::i;:::-;11744:16;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;;:::i;:::-;11744:16;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;;:::i;:::-;11744:16;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;;:::i;:::-;11744:16;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;11775:14;;;;1002:13720;;11264:348;-1:-1:-1;;;11598:14:23;;1002:13720;12082:14;11598;11268:321;11547:32;11583:6;1002:13720;11547:32;;:::i;:::-;1002:13720;11547:42;;11268:321;;:275;11506:32;1002:13720;11506:32;;:::i;:::-;1002:13720;11506:37;11268:275;;:234;11477:17;11284:5;1002:13720;11477:17;;:::i;:::-;1002:13720;11477:25;11268:234;;:205;11443:21;11467:6;1002:13720;11443:21;;:::i;:::-;1002:13720;11443:30;11268:205;;:171;11404:26;11433:6;1002:13720;11404:26;;:::i;:::-;1002:13720;11404:35;11268:171;;:132;-1:-1:-1;;;;;;11359:27:23;;:::i;:::-;1002:13720;11359:41;11268:132;;:87;11335:20;11349:6;11335:20;;11268:87;;:63;11315:16;;;11268:63;;:43;11293:18;11306:5;11293:18;;11268:43;;1002:13720;;;;;;;;;;;;;;;;;;;;;1862:37;1002:13720;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;1214:10;1002:13720;;;;;;;;;;;;;;;;;1406:39;1002:13720;;;;;;;;;;;;;;;;;;;;;;;1146:19;1002:13720;;;;;;;;;;;;;;;;;;1654:43;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;;;;;;;;;;12356:21;;;:::i;:::-;12405:26;;;1002:13720;-1:-1:-1;;;;;1002:13720:23;12391:10;:40;;;:78;;1002:13720;12387:115;;1002:13720;12512:21;;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;12512:21;;;;-1:-1:-1;12573:12:23;;1002:13720;-1:-1:-1;;;;;1002:13720:23;;12553:60;;;;;1002:13720;;;;;;;;;;;;;;;12553:60;;1002:13720;12553:60;;1002:13720;12553:60;;;;;;;;1002:13720;;12553:60;;;;;:::i;:::-;1002:13720;;12553:60;1002:13720;12553:60;1002:13720;;;;;;;;;12553:60;1002:13720;;;12387:115;-1:-1:-1;;;12478:24:23;;1002:13720;12830:24;12478;12391:78;-1:-1:-1;1002:13720:23;;-1:-1:-1;;;;;1002:13720:23;12391:10;12436:21;;;12391:78;12436:32;;;12391:78;;1002:13720;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;:::i;:::-;;;;2153:60;1002:13720;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;1500:62:0;;:::i;:::-;2989:103:13;;:::i;:::-;1002:13720:23;;8010:16;:51;;;;1002:13720;8006:86;;8161:41;1002:13720;;8161:41;:::i;:::-;1002:13720;8216:24;1002:13720;;8216:24;1002:13720;8216:37;8212:75;;8903:9;1002:13720;8890:9;:22;8886:53;;8953:20;;1002:13720;;8953:20;;:::i;:::-;1002:13720;8976:16;1002:13720;;;8953:39;:101;;;;1002:13720;8949:133;;8342:10;1002:13720;;9096:8;1002:13720;;;;;9114:11;1002:13720;;9114:11;1002:13720;;;;;;;;;;;9092:60;;1002:13720;9166:25;;1002:13720;;9166:25;1002:13720;;;;9166:25;:::i;:::-;:37;;;9162:64;;8342:10;1002:13720;;9096:8;1002:13720;;;;;9114:11;1002:13720;;9114:11;1002:13720;;;;;;;;;;;;;;;;;;;;;;9303:26;;1002:13720;;9303:26;;:::i;:::-;1002:13720;9303:79;;8342:10;9303:79;;1002:13720;;;9554:7;1002:13720;8953:20;1002:13720;;;9574:20;8953;1002:13720;;8953:20;9574;:::i;:::-;1002:13720;9596:21;;1002:13720;;9596:21;;:::i;:::-;1002:13720;;;;;;;:::i;:::-;;;;;;;;;;;;9492:126;;1002:13720;9492:126;1002:13720;9492:126;;1002:13720;;9492:126;;1002:13720;;9492:126;;;1002:13720;;;9303:26;9492:126;;1002:13720;;;;;;;9645:80;;1002:13720;;9645:80;;1002:13720;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1002:13720:23;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1002:13720:23;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1002:13720:23;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9303:26;1002:13720;;9303:26;1002:13720;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;9492:126;1002:13720;;;;:::i;:::-;;9492:126;1002:13720;;;;;;;:::i;:::-;;-1:-1:-1;;;;;1002:13720:23;;;9303:26;;1002:13720;:::i;:::-;;;;;;8953:20;1002:13720;;8953:20;1002:13720;;;;;;;;;;;;;;9596:21;1002:13720;;9596:21;1002:13720;:::i;:::-;;;;;;;;;8216:24;;;1002:13720;;;;;9114:11;;;1002:13720;;;;;9166:25;;;1002:13720;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;9492:126;;1002:13720;;;;;;-1:-1:-1;1002:13720:23;9492:126;;;1002:13720;;;;;;9492:126;;1002:13720;;;;;9492:126;;;1002:13720;;;;;9303:26;9492:126;;;1002:13720;;;;;;;;;;;;;;:::i;:::-;8342:10;1002:13720;;;;1146:19;1002:13720;;;;;;;;;;9645:80;1002:13720;-1:-1:-1;9645:14:23;-1:-1:-1;;;;;1002:13720:23;9645:80;;;;;;;1002:13720;;;9645:80;;;1002:13720;9628:97;1002:13720;;;;9813:20;8953;1002:13720;;8953:20;9813;:::i;:::-;1002:13720;;9835:21;9596;1002:13720;;9596:21;9835;:::i;:::-;1002:13720;;;;;;;:::i;:::-;;;;;;;;;;;9754:122;;1002:13720;;;;;;;;;;9754:122;;8342:10;;1002:13720;;;9754:122;;1002:13720;;;;;;;;;9492:126;9754:122;;1002:13720;;;;9754:122;9303:26;9754:122;;1002:13720;;;;8953:20;9754:122;;1002:13720;;;;;;9754:122;;1002:13720;;;;;9754:122;;1002:13720;;;;;;;;;;;;9735:9;1002:13720;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;8903:9;1002:13720;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;8976:16;1002:13720;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;;;;-1:-1:-1;;;;1002:13720:23;;;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;-1:-1:-1;;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;-1:-1:-1;1002:13720:23;;;9886:15;1002:13720;;;;;-1:-1:-1;;1002:13720:23;;;;;;9928:7;1002:13720;-1:-1:-1;;;1002:13720:23;;;;;;;;;;;;9928:7;1002:13720;;:::i;:::-;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;10001:25;9166;1002:13720;;9166:25;1002:13720;;;;10001:25;:::i;:::-;1002:13720;;;8903:9;1002:13720;;;;;;;8903:9;1002:13720;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;:::i;:::-;-1:-1:-1;;1002:13720:23;;;;;;8342:10;10048:23;;;:::i;:::-;1002:13720;-1:-1:-1;;;;;1002:13720:23;10081:25;;;:::i;:::-;1002:13720;;10170:3;10136:25;9166;1002:13720;;9166:25;1002:13720;;;;10136:25;:::i;:::-;10132:36;;;;;;;10195:25;9166;1002:13720;;9166:25;1002:13720;;;;10195:25;:::i;:::-;1002:13720;;;;;10195:28;1002:13720;;;;;10195:28;:::i;:::-;1002:13720;8903:9;1002:13720;;;;;;;;10175:48;8903:9;1002:13720;;10175:48;;:::i;:::-;1002:13720;;;;;;;;;;10121:9;;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;10132:36;-1:-1:-1;10132:36:23;;-1:-1:-1;;;;;1002:13720:23;;10233:56;;;;1002:13720;;;-1:-1:-1;;;10233:56:23;;-1:-1:-1;;;;;1002:13720:23;;;10233:56;;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;-1:-1:-1;1002:13720:23;;10233:56;;;;;-1:-1:-1;10233:56:23;;-1:-1:-1;1002:13720:23;-1:-1:-1;;;;;1002:13720:23;;10233:56;;;;;;;;1002:13720;;8903:9;1002:13720;10303:14;10299:84;;1002:13720;;;;8441:59;1002:13720;;;;;;;;;;;;;;;;;;;;;8342:10;1002:13720;;;;;;;;;10398:86;9492:126;1002:13720;;;;;;;10398:86;;1002:13720;;;;8383:13;1002:13720;;;;;;;-1:-1:-1;;;;;;1002:13720:23;-1:-1:-1;;;;;1002:13720:23;;;;;8441:59;:::i;:::-;1002:13720;;;;;;;;:::i;:::-;;;;;;8533:33;;1002:13720;;;;;;;;;;;;;8510:13;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;8581:47;;1002:13720;8581:47;1002:13720;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;8643:51;;;1002:13720;-1:-1:-1;;;;;;;;;;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;10299:84;9554:7;1002:13720;-1:-1:-1;;;;;10319:9:23;1002:13720;;;;10319:64;;;;;1002:13720;;;;;;;;;;;;;;10319:64;;1002:13720;10319:64;;1002:13720;10319:64;;;;;;;;;;;10299:84;;;;10319:64;;;;;:::i;:::-;1002:13720;;10319:64;;;;;1002:13720;;;;;;;;;10319:64;1002:13720;;;10233:56;;;;;1002:13720;10233:56;;:::i;:::-;1002:13720;10233:56;;;;;1002:13720;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;10233:56;1002:13720;;;;;;;;;;;;;;;;9554:7;1002:13720;;;;-1:-1:-1;;;;;1002:13720:23;;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;-1:-1:-1;;;1002:13720:23;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;;;;;9554:7;1002:13720;;;-1:-1:-1;;;;1002:13720:23;-1:-1:-1;;;1002:13720:23;;;;;;9554:7;1002:13720;;;-1:-1:-1;;;;1002:13720:23;-1:-1:-1;;;1002:13720:23;;;;;;9554:7;1002:13720;;;-1:-1:-1;;;;1002:13720:23;-1:-1:-1;;;1002:13720:23;;;;;;;;;;;9645:80;;;;;1002:13720;9645:80;;1002:13720;9645:80;;;;;;1002:13720;9645:80;;;:::i;:::-;;;1002:13720;;;;;;;;;:::i;:::-;;;;:::i;:::-;9645:80;;;;;;;-1:-1:-1;9645:80:23;;1002:13720;;;;-1:-1:-1;1002:13720:23;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;:::i;:::-;;;;;;;;;;;;;;;;9303:79;9356:26;9303;1002:13720;;9303:26;9356;:::i;:::-;9303:79;;;9162:64;12082:14;;;1002:13720;9212:14;1002:13720;;9212:14;9092:60;9135:17;;;1002:13720;9135:17;1002:13720;;9135:17;8949:133;9063:19;;;1002:13720;9063:19;1002:13720;;9063:19;8953:101;1002:13720;9049:5;8996:50;1002:13720;9004:20;8953;1002:13720;;8953:20;9004;:::i;:::-;1002:13720;;9028:7;1002:13720;8953:20;1002:13720;;8996:50;;:::i;:::-;:58;8953:101;;8886:53;8921:18;;;1002:13720;8921:18;1002:13720;;8921:18;8212:75;8262:25;;;1002:13720;8262:25;1002:13720;;8262:25;8006:86;8070:22;;;1002:13720;8070:22;1002:13720;;8070:22;8010:51;-1:-1:-1;1002:13720:23;;;;;;8030:13;1002:13720;;;;;;-1:-1:-1;;;;;1002:13720:23;8030:31;;8010:51;;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;:::i;:::-;;;;;;2435:70;1002:13720;;;;;;;;;;;;2435:70;;1002:13720;2435:70;;;;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;1618:30;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;;;;;;;;;;;1500:62:0;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;;11915:23;;;;:60;;1002:13720;11911:95;;12020:17;;:53;;;;1002:13720;12016:80;;1002:13720;12184:54;1002:13720;;;;;;;;:::i;:::-;;;;;12133:36;;1002:13720;;;;;;12106:13;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12184:54;;;;1002:13720;12020:53;12041:32;-1:-1:-1;;;;;12041:32:23;;12020:53;;11911:95;11984:22;;;1002:13720;11984:22;1002:13720;;11984:22;11915:60;1002:13720;;;;11943:9;1002:13720;;;;;;;11943:32;1002:13720;;;;11942:33;11915:60;;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;1581:31;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;4767:7;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;;;1758:53;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;1817:39;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;735:10:11;-1:-1:-1;;;;;1002:13720:23;;;2339:24:1;2335:96;;2093:20;1002:13720:23;;-1:-1:-1;;;;;;1002:13720:23;;;;;;-1:-1:-1;1002:13720:23;;735:10:11;1002:13720:23;;;;;;;-1:-1:-1;;;;;1002:13720:23;;3052:40:0;;-1:-1:-1;3052:40:0;1002:13720:23;2335:96:1;2386:34;;;1002:13720:23;2386:34:1;735:10:11;1002:13720:23;;;;2386:34:1;1002:13720:23;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;10577:15:23;1002:13720;;-1:-1:-1;;;;;1002:13720:23;;10573:54;;10641:21;;:26;10637:52;;-1:-1:-1;;;;;1002:13720:23;-1:-1:-1;;;;;;1002:13720:23;;;;;;10577:15;1002:13720;;;;;;10741:29;;1002:13720;;10741:29;1002:13720;10637:52;13076:13;;;1002:13720;10676:13;1002:13720;;10676:13;10573:54;10615:12;;;1002:13720;10615:12;1002:13720;;10615:12;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;1500:62:0;;:::i;:::-;2093:20:1;1002:13720:23;;-1:-1:-1;;;;;;1002:13720:23;;;;;;-1:-1:-1;1002:13720:23;;;;;;;-1:-1:-1;;;;;;1002:13720:23;3052:40:0;-1:-1:-1;;3052:40:0;1002:13720:23;;;;;;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;:::i;:::-;;;;2284:54;1002:13720;;;;;;2284:54;1002:13720;;2284:54;;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;;;;;13498:26;1002:13720;;;;;;;;;;;;;;;;;;;13546:41;;1002:13720;13546:41;1002:13720;;;;-1:-1:-1;;1002:13720:23;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;6917:47;1002:13720;;;:::i;:::-;2989:103:13;;:::i;:::-;6953:10:23;1002:13720;;;6917:47;:::i;:::-;2365:1:13;-1:-1:-1;;;;;;;;;;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;2989:103:13;;:::i;:::-;7162:15:23;1002:13720;-1:-1:-1;;;;;1002:13720:23;7148:10;:29;;;;;:54;;1002:13720;7144:87;;;7248:44;1002:13720;;;7248:44;:::i;7144:87::-;7211:20;;;1002:13720;7211:20;1002:13720;;7211:20;7148:54;7181:21;;;7148:54;;;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;;1541:34;1002:13720;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;5310:4;1002:13720;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;10862:22;;10858:48;;1002:13720;;10958:33;1002:13720;-1:-1:-1;;;;;1002:13720:23;;10916:27;1002:13720;;;10916:27;1002:13720;;;;;;10958:33;1002:13720;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;1394:6;1002:13720;;;;;:::i;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;:::i;:::-;;4876:21;;;:::i;:::-;;1002:13720;;;;;;;;4906:15;1002:13720;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;1002:13720:23;;;;;;;;;;;13719:26;1002:13720;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;13766:31;;;:72;;;;1002:13720;13766:111;;;;;1002:13720;13762:147;;;13993:17;1002:13720;;;13719:26;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;13993:17;;:::i;:::-;1002:13720;13762:147;13886:23;;;1002:13720;13886:23;1002:13720;;13886:23;13766:111;13842:15;;;:35;13766:111;;;:72;13801:15;:37;;-1:-1:-1;13766:72:23;;;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5031:9;1002:13720;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;:::i;:::-;1500:62:0;;:::i;:::-;13009:21:23;;;:::i;:::-;-1:-1:-1;;;;;;1002:13720:23;;;13044:23;;13040:49;;1341:6;13119:15;1002:13720;13119:15;;;1002:13720;;;;13119:15;1002:13720;;;;;;;13295:99;1002:13720;13295:99;1002:13720;;;;;;;:::i;:::-;;;;13205:75;;;1002:13720;;;;13205:75;;;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;-1:-1:-1;1002:13720:23;;;13169:26;1002:13720;;;;;;;;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;:::i;:::-;-1:-1:-1;;;;;12795:26:23;12746:21;;;:::i;:::-;12795:26;1002:13720;;12781:10;:40;12777:77;;12888:9;;;:::i;12777:77::-;12830:24;;;1002:13720;12830:24;1002:13720;;12830:24;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;;;5119:7;1002:13720;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;:::o;:::-;;;-1:-1:-1;;;;;1002:13720:23;;;;;;:::o;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;1341:6;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;8953:20;1002:13720;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;5323:276::-;1002:13720;;;;;;;-1:-1:-1;1002:13720:23;5442:13;1002:13720;;;-1:-1:-1;1002:13720:23;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;5476:48;;1002:13720;6676:9;1002:13720;6687:16;1002:13720;6705:16;1002:13720;;6723:15;1002:13720;;;;6589:159;1002:13720;6589:159;;6600:13;;1002:13720;;6623:4;1002:13720;;;;1146:19;1002:13720;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6589:159;;;;;;;:::i;:::-;1002:13720;6579:170;;5323:276;:::o;1002:13720::-;;;;;;;:::i;:::-;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;5605:837::-;5770:6;5755:21;;:46;;;;5605:837;5751:88;;1002:13720;;-1:-1:-1;;;5890:28:23;;;1002:13720;5890:28;1002:13720;5890:10;-1:-1:-1;;;;;1002:13720:23;5890:28;;;;;;-1:-1:-1;;;5890:28:23;;;5605:837;5932:11;-1:-1:-1;5932:11:23;;;;;:29;;;5605:837;5932:60;;;;5605:837;5932:108;;;;5605:837;5928:141;;;6079:23;1002:13720;6217:7;1002:13720;;;;;;6217:7;1002:13720;;;;;;;;6236:14;1002:13720;;;;;;;;;6226:1;1002:13720;;6226:1;1002:13720;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;6190:72;1002:13720;;;6190:72;;:::i;:::-;6276:17;;;:53;;;;5605:837;6272:95;;1002:13720;;6226:1;1002:13720;5890:28;1002:13720;6723:15;1002:13720;;;;6589:159;;;;6600:13;;1002:13720;;6623:4;1002:13720;;;;1146:19;1002:13720;;;;-1:-1:-1;1002:13720:23;;;;;5890:28;1002:13720;;;6430:4;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6589:159;;;;;;;:::i;:::-;1002:13720;6579:170;;5605:837;:::o;6272:95::-;5810:29;;;-1:-1:-1;6338:29:23;5890:28;-1:-1:-1;6338:29:23;6276:53;6297:32;-1:-1:-1;;;;;6297:32:23;;6276:53;;5928:141;6049:20;;;-1:-1:-1;6049:20:23;5890:28;-1:-1:-1;6049:20:23;5932:108;5996:15;;;1002:13720;5996:15;1002:13720;;;;1394:6;-1:-1:-1;5932:108:23;;;:60;5977:15;5965:27;;;-1:-1:-1;5932:60:23;;:29;5947:14;;;-1:-1:-1;5932:29:23;;5890:28;;;;;;;;;;;;;;;;;;:::i;:::-;;;1002:13720;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;;5890:28;;;;;;;-1:-1:-1;5890:28:23;;5755:46;5780:21;5795:6;5780:21;;5755:46;;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;11404:26;1002:13720;;;;;;;;;:::o;:::-;11443:21;1002:13720;;;;;;;;;:::o;:::-;11477:17;1002:13720;;;;;;;;;:::o;:::-;11506:32;1002:13720;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;5222:7;1002:13720;;;;;;5222:7;-1:-1:-1;1002:13720:23;;-1:-1:-1;1002:13720:23;;;-1:-1:-1;1002:13720:23;:::o;14536:184::-;1002:13720;;;;;;-1:-1:-1;1002:13720:23;14646:9;1002:13720;;;-1:-1:-1;1002:13720:23;14677:13;1002:13720;14677:13;;;1002:13720;;;;14676:14;14672:41;;14536:184::o;14672:41::-;14699:14;;;-1:-1:-1;14699:14:23;14677:13;-1:-1:-1;14699:14:23;14023:508;-1:-1:-1;;;;;1002:13720:23;;;14023:508;14126:1;;14105:23;;14101:49;;14191:21;;;:::i;:::-;14241:26;;;1002:13720;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;14345:12;;;1002:13720;-1:-1:-1;;;;;1002:13720:23;;;;14241:26;1002:13720;14325:67;;;;;14126:1;1002:13720;;14325:67;1002:13720;;;;;;;;;14325:67;;;;;;1002:13720;14325:67;;;;;;;;14023:508;-1:-1:-1;14402:12:23;-1:-1:-1;;;;;1002:13720:23;;14402:53;;;;;1002:13720;;-1:-1:-1;;;14402:53:23;;-1:-1:-1;;;;;1002:13720:23;;;14325:67;14402:53;;1002:13720;;;;;;;;;;;;;;;;;;;;14402:53;;;;;;;;;;;14023:508;-1:-1:-1;;;;;;;1002:13720:23;;14470:54;;;;14023:508::o;14402:53::-;;;;;:::i;:::-;1002:13720;;14402:53;;;;1002:13720;;;;14402:53;1002:13720;;;;;;;;;14325:67;;;;;14126:1;14325:67;;:::i;:::-;14126:1;14325:67;;;;1796:162:0;1710:6;1002:13720:23;-1:-1:-1;;;;;1002:13720:23;735:10:11;1855:23:0;1851:101;;1796:162::o;1002:13720:23:-;;;6740:7;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7296:3683:16:-;1002:13720:23;;;;1412:159:16;1002:13720:23;7296:3683:16;:::o;1002:13720:23:-;;;;;;;;;;;;7296:3683:16;;;-1:-1:-1;;7296:3683:16;;1412:159;;;;;;;;;;;;;;;;7552:9;;7548:365;;8023:19;;;;8019:142;;8444:308;;;;940:4:12;1002:13720:23;940:4:12;8971:31:16;;9016:384;;;9854:1;940:4:12;9835:1:16;940:4:12;9834:21:16;940:4:12;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;9016:384:16;;;;1002:13720:23;9016:384:16;;;8444:308;;;;;;940:4:12;8444:308:16;;9016:384;9463:18;940:4:12;7296:3683:16;:::o;8019:142::-;1829:135:12;;1002:13720:23;1829:135:12;8082:16:16;5328:5;940:4:12;;5322:42:16;1829:135:12;;;;;7548:365:16;7881:17;;;;1002:13720:23;;;;;7874:24:16;:::o;3749:292:13:-;2407:1;-1:-1:-1;;;;;;;;;;;1002:13720:23;4560:63:13;3644:93;;2407:1;-1:-1:-1;;;;;;;;;;;1002:13720:23;3749:292:13:o;3644:93::-;3696:30;;;-1:-1:-1;3696:30:13;;-1:-1:-1;3696:30:13;7304:352:23;;;-1:-1:-1;7484:33:23;;;;:::i;:::-;7456:24;;;1002:13720;7456:61;7452:99;;1002:13720;;;;;;;-1:-1:-1;1002:13720:23;7604:13;1002:13720;;;-1:-1:-1;1002:13720:23;;7568:81;8903:9;1002:13720;8890:9;:22;8886:53;;8953:20;;;;;:::i;:::-;1002:13720;8976:16;1002:13720;;;8953:39;:101;;;;7304:352;8949:133;;1002:13720;;;;;;;-1:-1:-1;1002:13720:23;9096:8;1002:13720;;;-1:-1:-1;1002:13720:23;9114:11;;;1002:13720;-1:-1:-1;1002:13720:23;;;;;-1:-1:-1;1002:13720:23;;;9092:60;;1002:13720;9166:25;;;;;;:::i;:::-;:37;;;9162:64;;-1:-1:-1;;;;;1002:13720:23;;;-1:-1:-1;1002:13720:23;;;9096:8;1002:13720;;;;;;;;9114:11;;;1002:13720;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;9303:26;1002:13720;9303:26;;;:::i;:::-;1002:13720;9303:79;;;;;1002:13720;9554:7;1002:13720;8953:20;1002:13720;;8953:20;9574;8953;;;9574;:::i;:::-;1002:13720;9596:21;;;;;:::i;:::-;1002:13720;;;;;;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;;;;;;;;9492:126;;1002:13720;;9492:126;;;1002:13720;;;9492:126;;;1002:13720;;;;;;9492:126;;;1002:13720;;;;;9492:126;;1002:13720;;-1:-1:-1;;;9645:80:23;;1002:13720;9645:80;;;1002:13720;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;9492:126;1002:13720;;;;:::i;:::-;;9492:126;1002:13720;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;;;;:::i;:::-;;-1:-1:-1;;;;;1002:13720:23;;9303:26;;1002:13720;:::i;:::-;;;;;;8953:20;;;1002:13720;;;;;;;;;;;;;;9596:21;;;1002:13720;:::i;:::-;;;;;;;7456:24;;;1002:13720;;;;;9114:11;;;1002:13720;;;;;9166:25;;;1002:13720;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;-1:-1:-1;;1002:13720:23;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;9492:126;;1002:13720;;;;;;-1:-1:-1;1002:13720:23;9492:126;;;1002:13720;;;;;9492:126;;;1002:13720;;;;;9492:126;;;1002:13720;;;;;9303:26;9492:126;;;1002:13720;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;;;;;;;1146:19;1002:13720;;;;-1:-1:-1;1002:13720:23;;;;;;9645:80;;;;;1002:13720;;9645:14;1002:13720;9645:80;;;;;;;;;-1:-1:-1;;;9645:80:23;;;1002:13720;9628:97;;9645:80;9628:97;8953:20;;;1002:13720;9835:21;9596;9813:20;8953;;;9813;:::i;:::-;9596:21;;9835;:::i;:::-;1002:13720;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;9754:122;;1002:13720;;;;;;;;;;;;9754:122;;1002:13720;;;;;;;;;9492:126;9754:122;;1002:13720;;;;;;;;;9492:126;9754:122;;1002:13720;;;;;;;;;9754:122;9303:26;9754:122;;1002:13720;;;;8953:20;9754:122;;1002:13720;;;;;9596:21;9754:122;;1002:13720;-1:-1:-1;1002:13720:23;;7456:24;9754:122;;1002:13720;;;;-1:-1:-1;1002:13720:23;9735:9;1002:13720;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;8903:9;1002:13720;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;8976:16;1002:13720;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1002:13720:23;;;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;-1:-1:-1;;;1002:13720:23;;;;-1:-1:-1;1002:13720:23;;;9886:15;1002:13720;;;;;-1:-1:-1;;1002:13720:23;;;;;;9928:7;1002:13720;-1:-1:-1;;;1002:13720:23;;;;;;;;;;;;9928:7;1002:13720;;:::i;:::-;10001:25;9166;;;10001;;:::i;:::-;1002:13720;;;8903:9;1002:13720;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;10048:23;1002:13720;10048:23;:::i;:::-;1002:13720;-1:-1:-1;;;;;1002:13720:23;10081:25;;;:::i;:::-;1002:13720;-1:-1:-1;10170:3:23;10136:25;9166;;;10136;;:::i;:::-;10132:36;;;;;;;10195:25;9166;;;10195;;:::i;:::-;1002:13720;;;;;10195:28;1002:13720;;;;;10195:28;:::i;:::-;1002:13720;8903:9;1002:13720;;;;;;;;10175:48;;;1002:13720;10175:48;;:::i;:::-;1002:13720;;;;;;;;;;10121:9;;10132:36;;;;;;;;;;;;;;10233:56;;;;;1002:13720;;;-1:-1:-1;;;10233:56:23;;9645:80;10233:56;;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;10233:56;;;;;-1:-1:-1;10233:56:23;;;;;;;;;;;;;1002:13720;;8903:9;1002:13720;10303:14;10299:84;;1002:13720;-1:-1:-1;1002:13720:23;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;9492:126;1002:13720;;;;;;;;;10398:86;;9492:126;;10398:86;7561:88;7304:352;:::o;10299:84::-;9554:7;1002:13720;-1:-1:-1;;;;;10319:9:23;1002:13720;;;;10319:64;;;;;1002:13720;;;;;;;;;;;;;;10319:64;;9645:80;10319:64;;1002:13720;10319:64;;;;;;;10299:84;10319:64;;;;;;:::i;:::-;1002:13720;;10319:64;10299:84;;10319:64;1002:13720;;;10233:56;;;;;-1:-1:-1;10233:56:23;;:::i;:::-;-1:-1:-1;10233:56:23;;;;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;9554:7;1002:13720;;;;-1:-1:-1;;;;;1002:13720:23;;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;-1:-1:-1;;;1002:13720:23;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;;;;;;;;;;9645:80;;;;;;;1002:13720;9645:80;;1002:13720;9645:80;;;;;;1002:13720;9645:80;;;:::i;:::-;;;1002:13720;;;;9645:80;1002:13720;;;;;;;:::i;:::-;;;;:::i;:::-;9645:80;;;;;;;;-1:-1:-1;9645:80:23;;1002:13720;;;;-1:-1:-1;1002:13720:23;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;:::i;:::-;;;;;;;;;;;;;;;;9303:79;9356:26;9303;;;9356;:::i;:::-;9303:79;;;8953:101;:20;9049:5;8996:50;1002:13720;9004:20;8953;;;9004;:::i;8996:50::-;:58;8953:101;;1002:13720;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;;;1002:13720:23;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;;;-1:-1:-1;;1002:13720:23;;;;:::o;:::-;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;:::o;:::-;;;;;;;;;:::o;:::-;;;9269:4;1002:13720;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa26469706673582212203190683f5d6bc5abb39a655d737ec2428316f3ace65c6ab0d982473f4e38da5864736f6c63430008230033","offset":12778}},"immutableReferences":{"8974":[{"start":1621,"length":32},{"start":4538,"length":32},{"start":12095,"length":32}],"8977":[{"start":795,"length":32},{"start":9745,"length":32}],"8980":[{"start":3106,"length":32},{"start":5833,"length":32},{"start":11113,"length":32}],"8983":[{"start":5901,"length":32},{"start":8884,"length":32}],"8985":[{"start":1418,"length":32},{"start":9012,"length":32}]},"transformations":[{"id":"8977","type":"replace","offset":795,"reason":"immutable"},{"id":"8985","type":"replace","offset":1418,"reason":"immutable"},{"id":"8974","type":"replace","offset":1621,"reason":"immutable"},{"id":"8980","type":"replace","offset":3106,"reason":"immutable"},{"id":"8974","type":"replace","offset":4538,"reason":"immutable"},{"id":"8980","type":"replace","offset":5833,"reason":"immutable"},{"id":"8983","type":"replace","offset":5901,"reason":"immutable"},{"id":"8983","type":"replace","offset":8884,"reason":"immutable"},{"id":"8985","type":"replace","offset":9012,"reason":"immutable"},{"id":"8977","type":"replace","offset":9745,"reason":"immutable"},{"id":"8980","type":"replace","offset":11113,"reason":"immutable"},{"id":"8974","type":"replace","offset":12095,"reason":"immutable"}],"transformationValues":{"immutables":{"8974":"0x000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c","8977":"0x00000000000000000000000081ffb09b8abb42d0f6dc78a186ddf5e37b68e39b","8980":"0x000000000000000000000000e39e27560a0c6bb38e54771bf3dc8e4c79928f93","8983":"0x00000000000000000000000078f3556b67e17df817d51ef5a990cdaf09e8d3a9","8985":"0x0000000000000000000000000000000000000000000000000000000000000008"}}},"deployment":{"transactionHash":"0xad71e345cc366ea1bbea7106710ca19d22a909f3fe8918a2e3e056f43bf13ad5","blockNumber":"57816681","transactionIndex":"9","deployer":"0x42939046CeE36C4cADaA4fa8be999C2d5037FE4D"},"sources":{"src/BrishopBondingCurve.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from PONS v2's verified curve; see ../NOTICE.md and upstream provenance.\npragma solidity ^0.8.26;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {BrishopBondingCurveMath} from \"./libraries/BrishopBondingCurveMath.sol\";\nimport {BrishopBuybackVault} from \"./BrishopBuybackVault.sol\";\nimport {FeePolicySnapshot, IBrishopFeeEscrow, IBrishopFeePolicy, IBrishopSnipeTax} from \"./interfaces/IBrishop.sol\";\n\n/// @notice Permanent constant-product market. Phantom quote sets pricing; only\n/// actual quote reserves, excluding earned fees, can fund a sell.\ncontract BrishopBondingCurve is ReentrancyGuard {\n    using SafeERC20 for IERC20;\n    uint256 private constant BPS = 10_000;\n    uint256 public constant MAX_RESERVE = type(uint128).max;\n\n    struct BuyQuote { uint256 tokensOut; uint256 fee; uint256 tax; uint256 snipeTax; }\n    struct SellQuote { uint256 quoteOut; uint256 grossQuoteOut; uint256 fee; uint256 tax; bool reserveSufficient; }\n    struct Terms {\n        address pairToken;\n        address creator;\n        uint256 phantomQuote;\n        uint256 feeBps;\n        uint256 creatorTaxBps;\n        bool buybackEnabled;\n    }\n    error ZeroAddress();\n    error ZeroAmount();\n    error NotFactory();\n    error AlreadyInitialized();\n    error NotInitialized();\n    error InvalidLaunchEconomics();\n    error InvalidFeePolicy();\n    error ReserveLimit();\n    error DeadlineExpired();\n    error SlippageExceeded(uint256 actual, uint256 minimum);\n    error InsufficientRealReserve(uint256 required, uint256 available);\n    error NativeValueMismatch(uint256 supplied, uint256 expected);\n    error UnexpectedNativeValue();\n    error TransferFailed();\n    error NotFeeSweepOperator();\n    error InternalSwapRequiresOperator();\n    error MinimumOutputRequired();\n\n    event Initialized(address token);\n    event CurveBuy(address indexed buyer, address indexed recipient, uint256 quoteIn, uint256 tokensOut, uint256 fee, uint256 tax);\n    event CurveSell(address indexed seller, address indexed recipient, uint256 tokensIn, uint256 quoteOut, uint256 fee, uint256 tax);\n    event ReservesUpdated(uint256 realQuote, uint256 tokens);\n    event SnipeTaxExempted(address indexed account);\n    event SnipeTaxCharged(address indexed recipient, uint256 amount);\n    event CreatorFeeRecipientUpdated(address indexed previousRecipient, address indexed newRecipient);\n    event BuybackEnabledUpdated(bool enabled);\n    event FeesSwept(uint256 protocolAmount, uint256 buybackAmount, uint256 creatorAmount);\n    event BuybackLocked(uint256 quoteSpent, uint256 tokensLocked);\n\n    address public token;\n    address public immutable pairToken;\n    address public deployer;\n    address public immutable factory;\n    IBrishopFeePolicy public immutable feePolicy;\n    IBrishopFeeEscrow public immutable feeEscrow;\n    BrishopBuybackVault public immutable buybackVault;\n    address public immutable protocolFeeRecipient;\n    address public immutable buybackCreatorRecipient;\n    uint16 public immutable protocolFeeShareBps;\n    uint16 public immutable buybackBurnBps;\n    uint16 public immutable maxInternalPriceImpactBps;\n    uint256 public immutable phantomQuote;\n    uint256 public immutable feeBps;\n    uint256 public immutable creatorTaxBps;\n    bool public buybackEnabled;\n    uint256 public quoteFeeBalance;\n    uint256 public buybackQuoteBalance;\n    uint256 public creatorTaxBalance;\n    uint256 public trackedQuote;\n    uint256 public trackedTokens;\n    uint256 public launchSupply;\n    uint256 public launchedAt;\n    uint256 public snipeTaxStartBps;\n    uint256 public snipeTaxSeconds;\n    mapping(address => bool) public snipeTaxExempt;\n\n    modifier onlyFactory() { if (msg.sender != factory) revert NotFactory(); _; }\n    modifier onlyInitialized() { if (token == address(0)) revert NotInitialized(); _; }\n\n    constructor(address factory_, IBrishopFeeEscrow escrow_, BrishopBuybackVault vault_, FeePolicySnapshot memory policy, Terms memory terms) {\n        if (factory_ == address(0) || address(escrow_) == address(0) || address(vault_) == address(0) || terms.creator == address(0)) revert ZeroAddress();\n        if (policy.protocolFeeRecipient == address(0) || policy.protocolFeeShareBps > BPS || policy.buybackBurnBps > BPS || policy.maxInternalPriceImpactBps == 0 || policy.maxInternalPriceImpactBps >= BPS || terms.feeBps + terms.creatorTaxBps > 2_000) revert InvalidFeePolicy();\n        if (terms.phantomQuote == 0 || terms.phantomQuote > MAX_RESERVE) revert InvalidLaunchEconomics();\n        factory = factory_;\n        feePolicy = IBrishopFeePolicy(factory_);\n        feeEscrow = escrow_;\n        buybackVault = vault_;\n        pairToken = terms.pairToken;\n        deployer = terms.creator;\n        protocolFeeRecipient = policy.protocolFeeRecipient;\n        buybackCreatorRecipient = terms.creator;\n        protocolFeeShareBps = policy.protocolFeeShareBps;\n        buybackBurnBps = policy.buybackBurnBps;\n        maxInternalPriceImpactBps = policy.maxInternalPriceImpactBps;\n        phantomQuote = terms.phantomQuote;\n        feeBps = terms.feeBps;\n        creatorTaxBps = terms.creatorTaxBps;\n        buybackEnabled = terms.buybackEnabled;\n    }\n\n    /// @dev The caller supplies the complete immutable exemption list atomically\n    /// at initialization. There is no way to add exemptions to a live pool.\n    function initialize(address token_, address[] calldata exemptions) external onlyFactory {\n        if (token != address(0)) revert AlreadyInitialized();\n        if (token_ == address(0) || token_ == pairToken) revert ZeroAddress();\n        uint256 received = IERC20(token_).balanceOf(address(this));\n        uint256 supply = IERC20(token_).totalSupply();\n        if (received == 0 || received > supply || supply > MAX_RESERVE || exemptions.length > 34) revert InvalidLaunchEconomics();\n        token = token_;\n        launchSupply = supply;\n        trackedTokens = received;\n        launchedAt = block.timestamp;\n        snipeTaxStartBps = IBrishopSnipeTax(factory).snipeTaxStartBps();\n        snipeTaxSeconds = IBrishopSnipeTax(factory).snipeTaxSeconds();\n        if (snipeTaxStartBps > 9_900 || snipeTaxSeconds == 0 || snipeTaxSeconds > 1 days) revert InvalidFeePolicy();\n        for (uint256 i; i < exemptions.length; ++i) {\n            if (exemptions[i] == address(0)) revert ZeroAddress();\n            snipeTaxExempt[exemptions[i]] = true;\n            emit SnipeTaxExempted(exemptions[i]);\n        }\n        emit Initialized(token_);\n        emit ReservesUpdated(0, received);\n    }\n\n    function isNativeQuote() public view returns (bool) { return pairToken == address(0); }\n    function realQuoteReserve() public view returns (uint256) { return trackedQuote - quoteFeeBalance - creatorTaxBalance; }\n    function getReserves() public view returns (uint256 quote, uint256 tokens) { return (phantomQuote + realQuoteReserve(), trackedTokens); }\n    function quoteReserve() external view returns (uint256) { return phantomQuote + realQuoteReserve(); }\n    function tokenReserve() external view returns (uint256) { return trackedTokens; }\n\n    /// @notice PONS's verified fourteen-halving decay; the live three-second\n    /// default produces 9900, 618, 19, 0 bps before the combined-fee cap.\n    function currentSnipeTaxBps(address recipient) public view returns (uint256) {\n        if (snipeTaxExempt[recipient] || snipeTaxStartBps == 0) return 0;\n        uint256 elapsed = block.timestamp - launchedAt;\n        if (elapsed >= snipeTaxSeconds) return 0;\n        return snipeTaxStartBps >> ((elapsed * 14) / snipeTaxSeconds);\n    }\n\n    function quoteBuy(uint256 quoteIn, address recipient) public view onlyInitialized returns (BuyQuote memory q) {\n        if (recipient == address(0)) revert ZeroAddress();\n        if (quoteIn == 0) revert ZeroAmount();\n        if (quoteIn > MAX_RESERVE - phantomQuote - trackedQuote) revert ReserveLimit();\n        uint256 snipeBps = currentSnipeTaxBps(recipient);\n        uint256 maxSnipe = BPS - feeBps - creatorTaxBps - 100;\n        if (snipeBps > maxSnipe) snipeBps = maxSnipe;\n        q.fee = Math.mulDiv(quoteIn, feeBps, BPS);\n        q.tax = Math.mulDiv(quoteIn, creatorTaxBps, BPS);\n        q.snipeTax = Math.mulDiv(quoteIn, snipeBps, BPS);\n        (uint256 quote, uint256 tokens) = getReserves();\n        q.tokensOut = BrishopBondingCurveMath.getAmountOut(quoteIn - q.fee - q.tax - q.snipeTax, quote, tokens, 0);\n    }\n\n    function quoteSell(uint256 tokensIn) public view onlyInitialized returns (SellQuote memory q) {\n        if (tokensIn == 0) revert ZeroAmount();\n        if (tokensIn > MAX_RESERVE - trackedTokens) revert ReserveLimit();\n        (uint256 quote, uint256 tokens) = getReserves();\n        q.grossQuoteOut = BrishopBondingCurveMath.getAmountOut(tokensIn, tokens, quote, 0);\n        q.fee = Math.mulDiv(q.grossQuoteOut, feeBps, BPS);\n        q.tax = Math.mulDiv(q.grossQuoteOut, creatorTaxBps, BPS);\n        q.quoteOut = q.grossQuoteOut - q.fee - q.tax;\n        q.reserveSufficient = q.grossQuoteOut <= realQuoteReserve();\n    }\n\n    function buy(uint256 quoteIn, uint256 minTokensOut, address recipient, uint256 deadline) external payable nonReentrant onlyInitialized returns (uint256 tokensOut) {\n        if (block.timestamp > deadline) revert DeadlineExpired();\n        uint256 received = _receiveQuote(quoteIn);\n        BuyQuote memory q = quoteBuy(received, recipient);\n        tokensOut = q.tokensOut;\n        if (tokensOut < minTokensOut) revert SlippageExceeded(tokensOut, minTokensOut);\n        _accrueFees(q.fee + q.snipeTax, q.tax);\n        trackedQuote += received;\n        trackedTokens -= tokensOut;\n        IERC20(token).safeTransfer(recipient, tokensOut);\n        if (q.snipeTax != 0) emit SnipeTaxCharged(recipient, q.snipeTax);\n        emit CurveBuy(msg.sender, recipient, received, tokensOut, q.fee + q.snipeTax, q.tax);\n        emit ReservesUpdated(realQuoteReserve(), trackedTokens);\n    }\n\n    function sell(uint256 tokensIn, uint256 minQuoteOut, address recipient, uint256 deadline) external nonReentrant onlyInitialized returns (uint256 quoteOut) {\n        if (block.timestamp > deadline) revert DeadlineExpired();\n        if (recipient == address(0)) revert ZeroAddress();\n        SellQuote memory q = quoteSell(tokensIn);\n        if (!q.reserveSufficient) revert InsufficientRealReserve(q.grossQuoteOut, realQuoteReserve());\n        quoteOut = q.quoteOut;\n        if (quoteOut < minQuoteOut) revert SlippageExceeded(quoteOut, minQuoteOut);\n        IERC20(token).safeTransferFrom(msg.sender, address(this), tokensIn);\n        _accrueFees(q.fee, q.tax);\n        trackedQuote -= quoteOut;\n        trackedTokens += tokensIn;\n        _sendQuote(recipient, quoteOut);\n        emit CurveSell(msg.sender, recipient, tokensIn, quoteOut, q.fee, q.tax);\n        emit ReservesUpdated(realQuoteReserve(), trackedTokens);\n    }\n\n    function setCreatorFeeRecipient(address recipient) external onlyFactory {\n        if (recipient == address(0)) revert ZeroAddress();\n        emit CreatorFeeRecipientUpdated(deployer, recipient);\n        deployer = recipient;\n    }\n    function setBuybackEnabled(bool enabled) external onlyFactory { buybackEnabled = enabled; emit BuybackEnabledUpdated(enabled); }\n\n    function _receiveQuote(uint256 amount) private returns (uint256) {\n        if (isNativeQuote()) {\n            if (msg.value != amount) revert NativeValueMismatch(msg.value, amount);\n            return amount;\n        }\n        if (msg.value != 0) revert UnexpectedNativeValue();\n        uint256 beforeBalance = IERC20(pairToken).balanceOf(address(this));\n        IERC20(pairToken).safeTransferFrom(msg.sender, address(this), amount);\n        return IERC20(pairToken).balanceOf(address(this)) - beforeBalance;\n    }\n    function _sendQuote(address recipient, uint256 amount) private {\n        if (isNativeQuote()) {\n            (bool sent,) = payable(recipient).call{value: amount}(\"\");\n            if (!sent) revert TransferFailed();\n        } else IERC20(pairToken).safeTransfer(recipient, amount);\n    }\n    function _creditQuote(address recipient, uint256 amount) private {\n        if (isNativeQuote()) feeEscrow.credit{value: amount}(recipient);\n        else {\n            IERC20(pairToken).forceApprove(address(feeEscrow), amount);\n            feeEscrow.creditToken(recipient, pairToken, amount);\n        }\n    }\n    function _accrueFees(uint256 fee, uint256 tax) private {\n        quoteFeeBalance += fee;\n        creatorTaxBalance += tax;\n        if (buybackEnabled && fee != 0) {\n            uint256 creatorSlice = fee - Math.mulDiv(fee, protocolFeeShareBps, BPS);\n            buybackQuoteBalance += Math.mulDiv(creatorSlice, buybackBurnBps, BPS);\n        }\n    }\n\n    /// @notice PONS fee sweep and five-year buyback behavior, with its former\n    /// graduation inventory limit removed. Minimum output bounds buyback swaps.\n    function sweepFees(uint256 minBuybackTokensOut) external nonReentrant onlyInitialized {\n        bool operator = msg.sender == feePolicy.feeSweepOperator();\n        if (!operator && msg.sender != deployer) revert NotFeeSweepOperator();\n        if (!operator && buybackQuoteBalance != 0) revert InternalSwapRequiresOperator();\n        uint256 pending = quoteFeeBalance;\n        uint256 tax = creatorTaxBalance;\n        if (pending == 0 && tax == 0) return;\n        uint256 protocolAmount = Math.mulDiv(pending, protocolFeeShareBps, BPS);\n        uint256 creatorBucket = pending - protocolAmount;\n        uint256 buybackAmount = Math.min(buybackQuoteBalance, creatorBucket);\n        uint256 creatorAmount = creatorBucket - buybackAmount + tax;\n        uint256 tokensLocked;\n        if (buybackAmount != 0) {\n            if (minBuybackTokensOut == 0) revert MinimumOutputRequired();\n            (uint256 quote, uint256 tokens) = getReserves();\n            uint256 movementBps = Math.mulDiv(buybackAmount, BPS, quote + buybackAmount);\n            if (movementBps <= maxInternalPriceImpactBps) tokensLocked = BrishopBondingCurveMath.quoteAmountOut(buybackAmount, quote, tokens, 0);\n            if (tokensLocked == 0) { creatorAmount += buybackAmount; buybackAmount = 0; }\n            else if (tokensLocked < minBuybackTokensOut) revert SlippageExceeded(tokensLocked, minBuybackTokensOut);\n        }\n        quoteFeeBalance = 0;\n        creatorTaxBalance = 0;\n        buybackQuoteBalance = 0;\n        trackedQuote -= protocolAmount + creatorAmount;\n        if (tokensLocked != 0) {\n            trackedTokens -= tokensLocked;\n            IERC20(token).forceApprove(address(buybackVault), tokensLocked);\n            buybackVault.lock(token, tokensLocked, buybackCreatorRecipient, protocolFeeRecipient, protocolFeeShareBps);\n            emit BuybackLocked(buybackAmount, tokensLocked);\n        }\n        if (protocolAmount != 0) _creditQuote(protocolFeeRecipient, protocolAmount);\n        if (creatorAmount != 0) _creditQuote(deployer, creatorAmount);\n        emit FeesSwept(protocolAmount, buybackAmount, creatorAmount);\n        emit ReservesUpdated(realQuoteReserve(), trackedTokens);\n    }\n}\n"},"src/BrishopBuybackVault.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from the MIT PONS v2 verified source. See ../NOTICE.md.\npragma solidity ^0.8.26;\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IBrishopFeeEscrow, IBrishopFeePolicy, IBrishopLaunchFactory} from \"./interfaces/IBrishop.sol\";\n\n/**\n * @title BrishopBuybackVault\n * @notice Holds every launch's bought-back memecoin supply and releases it\n * linearly over five years instead of burning it immediately, splitting\n * every release between the creator and the protocol on the launch's\n * recorded fee shares. One shared deployment serves every launch, the same\n * \"single deployment for every token\" pattern BrishopFeeEscrow already uses.\n *\n * Note that the split applies to the release, not to the funding. The\n * permanent curve carves the buyback slice out of the creator's share of\n * the fees alone, so the creator funds the entire lock and then receives\n * only their fee share of it back. Enabling a buyback therefore moves value\n * from the creator to the protocol relative to taking the fees directly,\n * by an amount that grows with `buybackBurnBps`.\n *\n * Deposits use a weighted-average vesting clock instead of per-deposit\n * tranches: a launch's fee sweep can add to its lock on every single sweep,\n * and tracking an unbounded array of tranches would make `release()`'s gas\n * cost grow forever. Instead, each new deposit shifts the launch's single\n * `vestingStart` forward by an amount proportional to the deposit's share\n * of the new total, so a large existing lock is barely disturbed by a small\n * top-up, and a small existing lock is pulled close to the new deposit's own\n * clock. `vestedAmount` at any time reflects a fair, size-weighted blend\n * across every deposit made so far.\n */\ncontract BrishopBuybackVault is Ownable2Step, ReentrancyGuard {\n    using SafeERC20 for IERC20;\n\n    struct LaunchVest {\n        uint256 totalLocked;\n        uint256 totalReleased;\n        uint256 vestingStart;\n        uint256 vestedUnreleased;\n        uint256 unvestedAmount;\n        uint256 lastUpdate;\n        uint256 vestingEnd;\n        address creatorRecipient;\n        address protocolRecipient;\n        uint16 protocolFeeShareBps;\n    }\n\n    uint256 private constant BASIS_POINTS = 10_000;\n    uint256 public constant VESTING_DURATION = 5 * 365 days;\n\n    error ZeroAddress();\n    error AlreadyInitialized();\n    error NotFactory();\n    error NotAuthorizedLocker();\n    error NotVestBeneficiary();\n    error InvalidVestingTerms();\n    error VestingTermsMismatch();\n    error OwnershipCannotBeRenounced();\n\n    event FactorySet(address factory);\n    event Locked(address indexed token, address indexed depositor, uint256 amount, uint256 newVestingStart);\n    event VestingTermsSnapshotted(\n        address indexed token,\n        address indexed creatorRecipient,\n        address indexed protocolRecipient,\n        uint256 protocolFeeShareBps\n    );\n    event Released(address indexed token, uint256 creatorAmount, uint256 protocolAmount);\n    event CreatorRecipientUpdated(\n        address indexed token, address indexed previousRecipient, address indexed newRecipient\n    );\n\n    IBrishopFeePolicy public immutable feePolicy;\n    IBrishopFeeEscrow public immutable feeEscrow;\n    address public factory;\n\n    mapping(address token => LaunchVest) private _vaults;\n\n    /**\n     * @param initialOwner Administrative owner; only used to wire the factory once.\n     * @param feePolicy_ Shared Brishop protocol/creator fee policy.\n     * @param feeEscrow_ Shared claimable balance ledger releases are paid through.\n     */\n    constructor(address initialOwner, IBrishopFeePolicy feePolicy_, IBrishopFeeEscrow feeEscrow_) Ownable(initialOwner) {\n        if (address(feePolicy_) == address(0) || address(feeEscrow_) == address(0)) revert ZeroAddress();\n        feePolicy = feePolicy_;\n        feeEscrow = feeEscrow_;\n    }\n\n    /**\n     * @notice One-time wiring of the v2 factory, set after both are\n     * deployed, used to authorize each launch's bonding curve as a locker.\n     */\n    function setFactory(address factory_) external onlyOwner {\n        if (factory != address(0)) revert AlreadyInitialized();\n        if (factory_ == address(0)) revert ZeroAddress();\n        factory = factory_;\n        emit FactorySet(factory_);\n    }\n\n    /**\n     * @notice Permanently disabled. Ownership here exists only to perform the\n     * one-time factory wiring, and renouncing before that wiring would strand\n     * every future buyback lock.\n     */\n    function renounceOwnership() public pure override {\n        revert OwnershipCannotBeRenounced();\n    }\n\n    /**\n     * @notice Locks `amount` of `token` into its five-year vest, preserving\n     * the supplied beneficiaries and split for the active vesting epoch.\n     * Restricted to this token's registered Brishop curve, looked up live\n     * from the factory.\n     */\n    function lock(\n        address token,\n        uint256 amount,\n        address creatorRecipient,\n        address protocolRecipient,\n        uint16 protocolFeeShareBps\n    ) external nonReentrant {\n        if (token == address(0)) revert ZeroAddress();\n        if (factory == address(0)) revert NotFactory();\n        if (!_isAuthorizedLocker(token, msg.sender)) revert NotAuthorizedLocker();\n        if (amount == 0) return;\n        if (creatorRecipient == address(0) || protocolRecipient == address(0) || protocolFeeShareBps > BASIS_POINTS) {\n            revert InvalidVestingTerms();\n        }\n\n        // Schedule against what arrived, not what was asked for. Recording a\n        // nominal amount the vault never received would make the final\n        // release of the epoch revert on its own balance, stranding the tail\n        // of the vest. Every other ERC-20 boundary in the protocol measures\n        // this delta; this one is no different for being fed by our own\n        // launcher token today.\n        uint256 balanceBefore = IERC20(token).balanceOf(address(this));\n        IERC20(token).safeTransferFrom(msg.sender, address(this), amount);\n        amount = IERC20(token).balanceOf(address(this)) - balanceBefore;\n        if (amount == 0) return;\n\n        LaunchVest storage v = _vaults[token];\n        uint256 nowTs = block.timestamp;\n        _checkpoint(v, nowTs);\n        _setOrValidateVestingTerms(v, token, creatorRecipient, protocolRecipient, protocolFeeShareBps);\n\n        uint256 existingUnvested = v.unvestedAmount;\n        uint256 combinedAmount = existingUnvested + amount;\n        uint256 remainingDuration = existingUnvested == 0 ? 0 : v.vestingEnd - nowTs;\n        uint256 combinedDuration = (existingUnvested * remainingDuration + amount * VESTING_DURATION) / combinedAmount;\n\n        v.unvestedAmount = combinedAmount;\n        v.lastUpdate = nowTs;\n        v.vestingEnd = nowTs + combinedDuration;\n        v.vestingStart = nowTs - (VESTING_DURATION - combinedDuration);\n        v.totalLocked += amount;\n\n        emit Locked(token, msg.sender, amount, v.vestingStart);\n    }\n\n    /**\n     * @notice Releases every currently vested, not-yet-released token for\n     * `token`, using the beneficiaries and split frozen for its active\n     * vesting epoch.\n     * @dev Restricted to the two parties a release pays. Letting anyone\n     * choose when value leaves the vest is harmful in two ways. A caller can\n     * time a release inside the protocol owner's creator-recipient recovery\n     * window, flushing vested tokens to the very address the recovery exists\n     * to abandon. A caller can also advance the checkpoint every second, so\n     * each step rounds its newly vested amount down to zero and the vest\n     * stalls without ever paying out.\n     */\n    function release(address token) external nonReentrant returns (uint256 released) {\n        if (factory == address(0)) revert NotFactory();\n\n        LaunchVest storage v = _vaults[token];\n        if (msg.sender != v.creatorRecipient && msg.sender != v.protocolRecipient) revert NotVestBeneficiary();\n\n        _checkpoint(v, block.timestamp);\n        released = v.vestedUnreleased;\n        if (released == 0) return 0;\n        v.vestedUnreleased = 0;\n        v.totalReleased += released;\n\n        uint256 protocolAmount = (released * v.protocolFeeShareBps) / BASIS_POINTS;\n        uint256 creatorAmount = released - protocolAmount;\n\n        IERC20(token).forceApprove(address(feeEscrow), released);\n        if (protocolAmount != 0) feeEscrow.creditToken(v.protocolRecipient, token, protocolAmount);\n        if (creatorAmount != 0) feeEscrow.creditToken(v.creatorRecipient, token, creatorAmount);\n\n        emit Released(token, creatorAmount, protocolAmount);\n    }\n\n    /**\n     * @notice Redirects a launch's buyback vest to a new creator recipient.\n     * Restricted to the factory, which forwards both self-service creator\n     * transfers and protocol-owner recovery overrides here, so vested\n     * buyback tokens track the same recipient as immediate creator fees\n     * rather than remaining stranded on the launch-time address. Vested but\n     * not-yet-released tokens follow the new recipient too, matching the\n     * intent of wallet recovery. Only the protocol split terms stay bound to\n     * the launch snapshot; the creator identity is managed here instead.\n     */\n    function updateCreatorRecipient(address token, address newRecipient) external {\n        if (msg.sender != factory) revert NotFactory();\n        if (token == address(0) || newRecipient == address(0)) revert ZeroAddress();\n\n        LaunchVest storage v = _vaults[token];\n        address previousRecipient = v.creatorRecipient;\n        if (previousRecipient == newRecipient) return;\n        v.creatorRecipient = newRecipient;\n        emit CreatorRecipientUpdated(token, previousRecipient, newRecipient);\n    }\n\n    /**\n     * @notice Total amount of `token` ever locked into this vault.\n     */\n    function totalLocked(address token) external view returns (uint256) {\n        return _vaults[token].totalLocked;\n    }\n\n    /**\n     * @notice Total amount of `token` already released from this vault.\n     */\n    function totalReleased(address token) external view returns (uint256) {\n        return _vaults[token].totalReleased;\n    }\n\n    /**\n     * @notice The launch's current weighted-average vesting start time.\n     * @dev Reporting only. Vesting is accounted from `vestedUnreleased`,\n     * `unvestedAmount`, `lastUpdate` and `vestingEnd`, which are settled on\n     * every lock and release. Interpolating this value against\n     * `VESTING_DURATION` will not reproduce `vestedAmount`, because already\n     * vested tokens are banked at each deposit rather than recomputed from\n     * the shifted clock. Read `vestedAmount` for the authoritative figure.\n     */\n    function vestingStart(address token) external view returns (uint256) {\n        return _vaults[token].vestingStart;\n    }\n\n    /**\n     * @notice Amount of `token` vested so far, released or not.\n     */\n    function vestedAmount(address token) external view returns (uint256) {\n        return _vestedAmount(_vaults[token]);\n    }\n\n    /**\n     * @notice Amount of `token` currently releasable: vested but not yet released.\n     */\n    function releasable(address token) external view returns (uint256) {\n        LaunchVest storage v = _vaults[token];\n        return v.vestedUnreleased + _previewNewlyVested(v, block.timestamp);\n    }\n\n    /**\n     * @notice Returns the immutable terms for the token's active vesting epoch.\n     */\n    function vestingTerms(address token)\n        external\n        view\n        returns (address creatorRecipient, address protocolRecipient, uint16 protocolFeeShareBps)\n    {\n        LaunchVest storage v = _vaults[token];\n        return (v.creatorRecipient, v.protocolRecipient, v.protocolFeeShareBps);\n    }\n\n    /**\n     * @dev Linear vest over VESTING_DURATION from the launch's current\n     * weighted-average start time, capped at the total ever locked.\n     */\n    function _vestedAmount(LaunchVest storage v) private view returns (uint256) {\n        return v.totalReleased + v.vestedUnreleased + _previewNewlyVested(v, block.timestamp);\n    }\n\n    /**\n     * @dev Crystallizes the linear portion vested since the previous state\n     * update while preserving the existing schedule's maturity.\n     */\n    function _checkpoint(LaunchVest storage v, uint256 nowTs) private {\n        uint256 newlyVested = _previewNewlyVested(v, nowTs);\n        if (newlyVested != 0) {\n            v.unvestedAmount -= newlyVested;\n            v.vestedUnreleased += newlyVested;\n        }\n        v.lastUpdate = nowTs;\n    }\n\n    /**\n     * @dev Previews how much of the active schedule vested since lastUpdate.\n     */\n    function _previewNewlyVested(LaunchVest storage v, uint256 nowTs) private view returns (uint256) {\n        if (v.unvestedAmount == 0 || nowTs <= v.lastUpdate) return 0;\n        if (nowTs >= v.vestingEnd) return v.unvestedAmount;\n\n        uint256 remainingDuration = v.vestingEnd - v.lastUpdate;\n        uint256 elapsed = nowTs - v.lastUpdate;\n        return (v.unvestedAmount * elapsed) / remainingDuration;\n    }\n\n    /**\n     * @dev A new epoch begins only after every token in the prior epoch has\n     * been released. This keeps every active weighted-average vest bound to\n     * one immutable set of beneficiaries without unbounded tranche storage.\n     */\n    function _setOrValidateVestingTerms(\n        LaunchVest storage v,\n        address token,\n        address creatorRecipient,\n        address protocolRecipient,\n        uint16 protocolFeeShareBps\n    ) private {\n        bool newEpoch = v.unvestedAmount == 0 && v.vestedUnreleased == 0;\n        if (newEpoch) {\n            // Seed the buyback beneficiary only when it has never been set.\n            // Once the factory has redirected the vest through\n            // updateCreatorRecipient (a creator transfer or a protocol\n            // recovery override), a later lock must not silently reset it\n            // back to the launch-time recipient, even across a fresh epoch.\n            if (v.creatorRecipient == address(0)) {\n                v.creatorRecipient = creatorRecipient;\n            }\n            v.protocolRecipient = protocolRecipient;\n            v.protocolFeeShareBps = protocolFeeShareBps;\n            emit VestingTermsSnapshotted(token, v.creatorRecipient, protocolRecipient, protocolFeeShareBps);\n            return;\n        }\n\n        // The creator recipient is deliberately excluded from this check: it\n        // is managed independently through updateCreatorRecipient, so recovery\n        // can move the vest without ever bricking a subsequent lock on a terms\n        // mismatch. The protocol split terms remain immutable per launch.\n        if (v.protocolRecipient != protocolRecipient || v.protocolFeeShareBps != protocolFeeShareBps) {\n            revert VestingTermsMismatch();\n        }\n    }\n\n    /**\n     * @dev Only the token's own registered curve may lock its buybacks.\n     * No per-launch administrator action or shared external hook is needed.\n     */\n    function _isAuthorizedLocker(address token, address caller) private view returns (bool) {\n        if (factory == address(0)) return false;\n        return caller == IBrishopLaunchFactory(factory).getLaunchedToken(token).curve;\n    }\n}\n"},"src/BrishopFeeEscrow.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from the MIT PONS v2 verified source. See ../NOTICE.md.\npragma solidity ^0.8.26;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IBrishopFeeEscrow} from \"./interfaces/IBrishop.sol\";\n\n/**\n * @title BrishopFeeEscrow\n * @notice Holds every v2 recipient's claimable balance in one place, so\n * protocol and creators claim revenue from across all of their pools in a\n * single transaction instead of collecting per position. Revenue arrives in\n * whichever asset the launch trades against: native ETH for a native launch,\n * and the launch's ERC-20 quote asset otherwise. Brishop's permanent curves\n * and buyback vault credit this same ledger.\n */\ncontract BrishopFeeEscrow is ReentrancyGuard, IBrishopFeeEscrow {\n    using SafeERC20 for IERC20;\n\n    error ZeroAddress();\n    error NoBalance();\n    error TransferFailed();\n    error InsufficientBalance(uint256 requested, uint256 available);\n\n    event Credited(address indexed recipient, address indexed depositor, uint256 amount);\n    event CreditedToken(address indexed recipient, address indexed token, address indexed depositor, uint256 amount);\n    event Claimed(address indexed recipient, uint256 amount);\n    event ClaimedToken(address indexed recipient, address indexed token, uint256 amount);\n\n    mapping(address recipient => uint256 amount) private _balances;\n    mapping(address recipient => mapping(address token => uint256 amount)) private _tokenBalances;\n\n    /**\n     * @notice Credits `msg.value` to `recipient`'s claimable native ETH balance.\n     * @dev Permissionless by design: the caller can only ever add value they\n     * already attached to the call, so there is no privilege to gate.\n     */\n    function credit(address recipient) external payable {\n        if (recipient == address(0)) revert ZeroAddress();\n        if (msg.value == 0) return;\n        _balances[recipient] += msg.value;\n        emit Credited(recipient, msg.sender, msg.value);\n    }\n\n    /**\n     * @notice Pulls `amount` of `token` from the caller and credits it to `recipient`.\n     * @dev Permissionless by design: the caller can only credit tokens they\n     * already hold and approve, so there is no privilege to gate. Credits\n     * the actual balance delta rather than the nominal `amount`, so a\n     * fee-on-transfer or deflationary pairToken can never make this\n     * contract record more credited liability than it actually holds,\n     * which would otherwise starve whichever recipient claims that token\n     * last.\n     */\n    function creditToken(address recipient, address token, uint256 amount) external nonReentrant {\n        if (recipient == address(0) || token == address(0)) revert ZeroAddress();\n        if (amount == 0) return;\n        uint256 balanceBefore = IERC20(token).balanceOf(address(this));\n        IERC20(token).safeTransferFrom(msg.sender, address(this), amount);\n        uint256 received = IERC20(token).balanceOf(address(this)) - balanceBefore;\n        if (received == 0) return;\n        _tokenBalances[recipient][token] += received;\n        emit CreditedToken(recipient, token, msg.sender, received);\n    }\n\n    /**\n     * @notice Pays out the caller's entire claimable native ETH balance.\n     */\n    function claim() external nonReentrant returns (uint256 amount) {\n        amount = _claim(_balances[msg.sender]);\n    }\n\n    /**\n     * @notice Pays out `amount` of the caller's claimable native ETH balance.\n     */\n    function claim(uint256 amount) external nonReentrant returns (uint256) {\n        return _claim(amount);\n    }\n\n    /**\n     * @notice Pays out the caller's entire claimable balance of `token`.\n     */\n    function claimToken(address token) external nonReentrant returns (uint256 amount) {\n        amount = _claimToken(token, _tokenBalances[msg.sender][token]);\n    }\n\n    /**\n     * @notice Pays out `amount` of the caller's claimable balance of `token`.\n     * @dev A recipient's balance aggregates credits from every launch, curve,\n     * curve and buyback release, and `creditToken` is permissionless, so a\n     * third party can enlarge that figure at will. Against a token with a\n     * fixed maximum per transfer, a single full-balance claim would then\n     * revert and leave the recipient unable to draw any of it. Choosing the\n     * amount keeps the aggregate from being a single point of failure, and\n     * lets a recipient work around any per-transfer limit its quote asset\n     * imposes.\n     */\n    function claimToken(address token, uint256 amount) external nonReentrant returns (uint256) {\n        return _claimToken(token, amount);\n    }\n\n    /**\n     * @dev Shared debit path for both native claim entry points.\n     */\n    function _claim(uint256 amount) private returns (uint256) {\n        if (amount == 0) revert NoBalance();\n        uint256 balance = _balances[msg.sender];\n        if (amount > balance) revert InsufficientBalance(amount, balance);\n\n        _balances[msg.sender] = balance - amount;\n        (bool sent,) = payable(msg.sender).call{value: amount}(\"\");\n        if (!sent) revert TransferFailed();\n\n        emit Claimed(msg.sender, amount);\n        return amount;\n    }\n\n    /**\n     * @dev Shared debit path for both ERC-20 claim entry points.\n     */\n    function _claimToken(address token, uint256 amount) private returns (uint256) {\n        if (amount == 0) revert NoBalance();\n        uint256 balance = _tokenBalances[msg.sender][token];\n        if (amount > balance) revert InsufficientBalance(amount, balance);\n\n        _tokenBalances[msg.sender][token] = balance - amount;\n        IERC20(token).safeTransfer(msg.sender, amount);\n\n        emit ClaimedToken(msg.sender, token, amount);\n        return amount;\n    }\n\n    /**\n     * @notice Returns the claimable native ETH balance for `recipient`.\n     */\n    function balanceOf(address recipient) external view returns (uint256) {\n        return _balances[recipient];\n    }\n\n    /**\n     * @notice Returns the claimable balance of `token` for `recipient`.\n     */\n    function balanceOfToken(address recipient, address token) external view returns (uint256) {\n        return _tokenBalances[recipient][token];\n    }\n}\n"},"src/BrishopLaunchDeployer.sol":{"content":"// SPDX-License-Identifier: MIT\n// Deployment/metadata pattern derived from PONS v2; see ../NOTICE.md.\npragma solidity ^0.8.26;\nimport {BrishopLauncherToken} from \"./BrishopLauncherToken.sol\";\nimport {BrishopBondingCurve} from \"./BrishopBondingCurve.sol\";\nimport {BrishopBuybackVault} from \"./BrishopBuybackVault.sol\";\nimport {FeePolicySnapshot, IBrishopFeeEscrow} from \"./interfaces/IBrishop.sol\";\n\nstruct TokenParams {\n    string name;\n    string symbol;\n    string logo;\n    string description;\n    BrishopLauncherToken.Socials socials;\n    address creatorFeeRecipient;\n    uint16 creatorTaxBps;\n    bool buybackEnabled;\n    bytes32 expectedEconomics;\n    bytes32 salt;\n    address[] snipeTaxExemptions;\n}\n\ncontract BrishopLaunchDeployer {\n    error NotFactory();\n    error InvalidMetadata();\n    address public immutable factory;\n    IBrishopFeeEscrow public immutable feeEscrow;\n    BrishopBuybackVault public immutable buybackVault;\n    constructor(address factory_, IBrishopFeeEscrow escrow_, BrishopBuybackVault vault_) {\n        factory = factory_; feeEscrow = escrow_; buybackVault = vault_;\n    }\n    function deployLaunch(TokenParams calldata params, BrishopBondingCurve.Terms calldata terms, FeePolicySnapshot calldata policy, address creator, uint256 supply, uint256 creatorAllocation) external returns (address token, address curve) {\n        if (msg.sender != factory) revert NotFactory();\n        _checkMetadata(params);\n        bytes32 salt = keccak256(abi.encode(creator, params.salt));\n        curve = address(new BrishopBondingCurve{salt: salt}(factory, feeEscrow, buybackVault, policy, terms));\n        token = address(new BrishopLauncherToken{salt: salt}(params.name, params.symbol, params.logo, params.description, params.socials, creator, curve, factory, supply, creatorAllocation));\n    }\n    function _checkMetadata(TokenParams calldata p) private pure {\n        if (bytes(p.name).length == 0 || bytes(p.name).length > 64 || bytes(p.symbol).length == 0 || bytes(p.symbol).length > 16 || bytes(p.logo).length > 512 || bytes(p.description).length > 2048) revert InvalidMetadata();\n        if (bytes(p.socials.twitter).length > 256 || bytes(p.socials.telegram).length > 256 || bytes(p.socials.discord).length > 256 || bytes(p.socials.website).length > 256 || bytes(p.socials.farcaster).length > 256) revert InvalidMetadata();\n    }\n}\n"},"src/BrishopLauncherToken.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from the MIT PONS v2 verified source. See ../NOTICE.md.\npragma solidity ^0.8.26;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\n/**\n * @title BrishopLauncherToken\n * @notice Fixed-supply ERC-20 deployed by BrishopLaunchFactory for a v2 launch.\n * Community supply mints to the curve. An administrator personality launch\n * assigns 25% to its creator and 75% to the curve. Purchases are limited by\n * curve pricing and inventory. `deployer` is carried here\n * as immutable reference data for off-chain attribution only, and confers no\n * privileges over the token.\n * `ERC20Burnable` lets any holder voluntarily burn their own balance; the\n * protocol's buyback mechanism does not use it, bought-back tokens are\n * locked into `BrishopBuybackVault` for a five-year vest instead of being\n * burned.\n */\ncontract BrishopLauncherToken is ERC20, ERC20Burnable {\n    struct Socials {\n        string twitter;\n        string telegram;\n        string discord;\n        string website;\n        string farcaster;\n    }\n\n    error ZeroAddress();\n    error InvalidAllocation();\n\n    address public immutable deployer;\n    address public immutable launchFactory;\n    address public immutable curve;\n    uint256 public immutable initialSupply;\n    uint256 public immutable initialCreatorAllocation;\n\n    string public logo;\n    string public description;\n\n    Socials private _socials;\n\n    /**\n     * @notice Mints the fixed initial supply between the curve and creator allocation.\n     */\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        string memory logo_,\n        string memory description_,\n        Socials memory socials_,\n        address deployer_,\n        address curve_,\n        address launchFactory_,\n        uint256 supply_,\n        uint256 creatorAllocation_\n    ) ERC20(name_, symbol_) {\n        if (deployer_ == address(0) || curve_ == address(0) || launchFactory_ == address(0)) {\n            revert ZeroAddress();\n        }\n\n        deployer = deployer_;\n        // Passed explicitly rather than read from msg.sender: BrishopLaunchFactory\n        // deploys this token indirectly through BrishopLaunchDeployer to keep its\n        // own bytecode under EIP-170's size limit, so msg.sender at construction\n        // time would otherwise resolve to that deployer helper, not the factory.\n        launchFactory = launchFactory_;\n        curve = curve_;\n        if (supply_ == 0 || creatorAllocation_ > supply_ / 4) revert InvalidAllocation();\n        initialSupply = supply_;\n        initialCreatorAllocation = creatorAllocation_;\n        logo = logo_;\n        description = description_;\n        _socials = socials_;\n\n        _mint(curve_, supply_ - creatorAllocation_);\n        if (creatorAllocation_ != 0) _mint(deployer_, creatorAllocation_);\n    }\n\n    /**\n     * @notice Returns the launch token's five social metadata fields.\n     */\n    function socials()\n        external\n        view\n        returns (\n            string memory twitter,\n            string memory telegram,\n            string memory discord,\n            string memory website,\n            string memory farcaster\n        )\n    {\n        Socials memory values = _socials;\n        return (values.twitter, values.telegram, values.discord, values.website, values.farcaster);\n    }\n\n    /**\n     * @notice Returns creator and metadata in the launcher-compatible tuple.\n     */\n    function getTokenInfo()\n        external\n        view\n        returns (\n            address tokenDeployer,\n            string memory tokenLogo,\n            string memory tokenDescription,\n            Socials memory tokenSocials\n        )\n    {\n        return (deployer, logo, description, _socials);\n    }\n}\n"},"src/BrishopLaunchFactory.sol":{"content":"// SPDX-License-Identifier: MIT\n// PONS-derived launch/fee policy, with permanent Brishop markets. See ../NOTICE.md.\npragma solidity ^0.8.26;\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {BrishopFeeEscrow} from \"./BrishopFeeEscrow.sol\";\nimport {BrishopBuybackVault} from \"./BrishopBuybackVault.sol\";\nimport {BrishopLaunchDeployer, TokenParams} from \"./BrishopLaunchDeployer.sol\";\nimport {BrishopBondingCurve} from \"./BrishopBondingCurve.sol\";\nimport {FeePolicySnapshot, IBrishopFeePolicy, IBrishopFeeEscrow, IBrishopLaunchFactory} from \"./interfaces/IBrishop.sol\";\n\ninterface IEthUsdFeed {\n    function decimals() external view returns (uint8);\n    function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80);\n}\n\ncontract BrishopLaunchFactory is Ownable2Step, ReentrancyGuard, IBrishopFeePolicy, IBrishopLaunchFactory {\n    uint256 public constant SUPPLY = 1_000_000_000 ether;\n    uint256 public constant BASE_PHANTOM_ETH = 1.68 ether;\n    uint256 public constant CREATOR_RECOVERY_DELAY = 3 days;\n    uint256 public constant CREATOR_RECOVERY_WINDOW = 3 days;\n    uint256 public constant ORACLE_MAX_AGE = 1 days;\n    uint256 public launchFee = 0.0005 ether;\n    uint256 public maxCreatorTaxBps = 1_000;\n    uint256 public snipeTaxStartBps = 9_900;\n    uint256 public snipeTaxSeconds = 3;\n    address public feeSweepOperator;\n    address public launchForwarder;\n    BrishopFeeEscrow public immutable feeEscrow;\n    BrishopBuybackVault public immutable buybackVault;\n    BrishopLaunchDeployer public immutable launchDeployer;\n    IEthUsdFeed public immutable ethUsdFeed;\n    uint8 public immutable oracleDecimals;\n    FeePolicySnapshot private _policy;\n    mapping(address => LaunchedToken) private _launches;\n    mapping(address => FeePolicySnapshot) private _launchPolicies;\n    address[] private _tokens;\n    mapping(bytes32 => address) public personalities;\n    mapping(address => mapping(bytes32 => bool)) public usedSalt;\n    struct PairEconomics { uint256 phantomQuote; bool enabled; }\n    mapping(address => PairEconomics) public pairEconomics;\n    struct PendingRecipient { address recipient; uint256 effectiveAt; uint256 expiresAt; }\n    mapping(address => PendingRecipient) public pendingCreatorFeeRecipient;\n\n    error ZeroAddress();\n    error AlreadySet();\n    error PairTokenNotApproved();\n    error LaunchEconomicsMismatch();\n    error LaunchFeeNotPaid();\n    error CreatorTaxTooHigh();\n    error InvalidTerms();\n    error SaltAlreadyUsed();\n    error UnknownToken();\n    error NotLaunchForwarder();\n    error NotCreatorFeeRecipient();\n    error InvalidOraclePrice();\n    error InvalidPersonalityValuation();\n    error DuplicatePersonality();\n    error RecoveryNotExecutable();\n    event TokenLaunched(address indexed token, address indexed curve, address indexed deployer, address pairToken, uint256 phantomQuote, bool personality, uint256 creatorAllocation);\n    event PersonalityLaunched(bytes32 indexed id, address indexed token, uint256 targetFdvUsd, uint256 ethUsdAnswer);\n    event PairEconomicsUpdated(address indexed pairToken, uint256 phantomQuote, bool enabled);\n    event LaunchForwarderSet(address forwarder);\n    event TermsUpdated();\n    event FeeSweepOperatorUpdated(address operator);\n    event CreatorFeeRecipientUpdated(address indexed token, address indexed oldRecipient, address indexed newRecipient);\n    event CreatorFeeRecipientChangeProposed(address indexed token, address recipient, uint256 effectiveAt, uint256 expiresAt);\n    event CreatorFeeRecipientChangeCancelled(address indexed token);\n\n    constructor(address initialOwner, IEthUsdFeed feed) Ownable(initialOwner) {\n        if (address(feed).code.length == 0) revert ZeroAddress();\n        ethUsdFeed = feed;\n        uint8 decimals_ = feed.decimals();\n        if (decimals_ > 18) revert InvalidOraclePrice();\n        oracleDecimals = decimals_;\n        feeSweepOperator = initialOwner;\n        _policy = FeePolicySnapshot(initialOwner, 3_000, 5_000, 100, 300);\n        feeEscrow = new BrishopFeeEscrow();\n        buybackVault = new BrishopBuybackVault(address(this), IBrishopFeePolicy(address(this)), IBrishopFeeEscrow(address(feeEscrow)));\n        buybackVault.setFactory(address(this));\n        launchDeployer = new BrishopLaunchDeployer(address(this), IBrishopFeeEscrow(address(feeEscrow)), buybackVault);\n        pairEconomics[address(0)] = PairEconomics(BASE_PHANTOM_ETH, true);\n    }\n\n    function currentFeePolicy() external view returns (FeePolicySnapshot memory) { return _policy; }\n    function getLaunchFeePolicy(address token) external view returns (FeePolicySnapshot memory) { _requireLaunch(token); return _launchPolicies[token]; }\n    function getLaunchedToken(address token) external view returns (LaunchedToken memory) { return _launches[token]; }\n    function launchCount() external view returns (uint256) { return _tokens.length; }\n    function launchedTokenAt(uint256 index) external view returns (address) { return _tokens[index]; }\n    function canLaunch(address) external pure returns (bool) { return true; }\n\n    function previewLaunchEconomics(address pairToken) public view returns (bytes32) {\n        PairEconomics memory pair = pairEconomics[pairToken];\n        if (!pair.enabled) revert PairTokenNotApproved();\n        return _economicsHash(pairToken, pair.phantomQuote, false);\n    }\n\n    function previewPersonalityEconomics(uint256 targetFdvUsd) public view returns (bytes32 economics, uint256 phantomQuote, uint256 price) {\n        if (targetFdvUsd < 18_000 || targetFdvUsd > 25_000) revert InvalidPersonalityValuation();\n        (, int256 answer,, uint256 updatedAt,) = ethUsdFeed.latestRoundData();\n        if (answer <= 0 || updatedAt == 0 || updatedAt > block.timestamp || block.timestamp - updatedAt > ORACLE_MAX_AGE) revert InvalidOraclePrice();\n        price = uint256(answer);\n        // 75% inventory: FDV = phantomQuote / 0.75 * ETH/USD.\n        phantomQuote = Math.mulDiv(targetFdvUsd * 1 ether, 3 * 10 ** oracleDecimals, 4 * price);\n        if (phantomQuote == 0 || phantomQuote > type(uint128).max) revert InvalidPersonalityValuation();\n        economics = _economicsHash(address(0), phantomQuote, true);\n    }\n\n    function _economicsHash(address pairToken, uint256 phantomQuote, bool personality) private view returns (bytes32) {\n        return keccak256(abi.encode(block.chainid, address(this), SUPPLY, pairToken, phantomQuote, personality, launchFee, maxCreatorTaxBps, snipeTaxStartBps, snipeTaxSeconds, _policy));\n    }\n\n    function launchToken(TokenParams calldata params, address pairToken) external payable nonReentrant returns (address token, address curve) {\n        return _launchCommunity(params, pairToken, msg.sender);\n    }\n    function launchTokenFor(TokenParams calldata params, address pairToken, address creator) external payable nonReentrant returns (address token, address curve) {\n        if (msg.sender != launchForwarder || creator == address(0)) revert NotLaunchForwarder();\n        return _launchCommunity(params, pairToken, creator);\n    }\n    function _launchCommunity(TokenParams calldata params, address pairToken, address creator) private returns (address token, address curve) {\n        if (params.expectedEconomics != previewLaunchEconomics(pairToken)) revert LaunchEconomicsMismatch();\n        return _launch(params, pairToken, creator, pairEconomics[pairToken].phantomQuote, false);\n    }\n\n    /// @notice Only the administrator may mint a personality. The 25% allocation\n    /// goes directly to that administrator, is transferable, and receives no ETH.\n    function launchPersonality(TokenParams calldata params, bytes32 id, uint256 targetFdvUsd) external payable onlyOwner nonReentrant returns (address token, address curve) {\n        if (id == bytes32(0) || personalities[id] != address(0)) revert DuplicatePersonality();\n        (bytes32 economics, uint256 phantomQuote, uint256 price) = previewPersonalityEconomics(targetFdvUsd);\n        if (params.expectedEconomics != economics) revert LaunchEconomicsMismatch();\n        (token, curve) = _launch(params, address(0), msg.sender, phantomQuote, true);\n        personalities[id] = token;\n        uint256 quotePhantom = Math.mulDiv(BASE_PHANTOM_ETH, SUPPLY * 3 / 4, phantomQuote);\n        pairEconomics[token] = PairEconomics(quotePhantom, true);\n        emit PairEconomicsUpdated(token, quotePhantom, true);\n        emit PersonalityLaunched(id, token, targetFdvUsd, price);\n    }\n\n    function _launch(TokenParams calldata params, address pairToken, address creator, uint256 phantomQuote, bool personality) private returns (address token, address curve) {\n        if (msg.value != launchFee) revert LaunchFeeNotPaid();\n        if (params.creatorTaxBps > maxCreatorTaxBps || uint256(params.creatorTaxBps) + _policy.hookFeeBps > 2_000) revert CreatorTaxTooHigh();\n        if (usedSalt[creator][params.salt]) revert SaltAlreadyUsed();\n        if (params.snipeTaxExemptions.length > 32) revert InvalidTerms();\n        usedSalt[creator][params.salt] = true;\n        address recipient = params.creatorFeeRecipient == address(0) ? creator : params.creatorFeeRecipient;\n        uint256 allocation = personality ? SUPPLY / 4 : 0;\n        BrishopBondingCurve.Terms memory terms = BrishopBondingCurve.Terms(pairToken, recipient, phantomQuote, _policy.hookFeeBps, params.creatorTaxBps, params.buybackEnabled);\n        (token, curve) = launchDeployer.deployLaunch(params, terms, _policy, creator, SUPPLY, allocation);\n        _launches[token] = LaunchedToken(token, curve, creator, recipient, pairToken, params.creatorTaxBps, params.buybackEnabled, personality, true);\n        _launchPolicies[token] = _policy;\n        _tokens.push(token);\n        address[] memory exemptions = new address[](params.snipeTaxExemptions.length + 2);\n        exemptions[0] = creator;\n        exemptions[1] = recipient;\n        for (uint256 i; i < params.snipeTaxExemptions.length; ++i) exemptions[i + 2] = params.snipeTaxExemptions[i];\n        BrishopBondingCurve(curve).initialize(token, exemptions);\n        if (launchFee != 0) feeEscrow.credit{value: launchFee}(_policy.protocolFeeRecipient);\n        emit TokenLaunched(token, curve, creator, pairToken, phantomQuote, personality, allocation);\n    }\n\n    function setLaunchForwarder(address forwarder) external onlyOwner {\n        if (launchForwarder != address(0)) revert AlreadySet();\n        if (forwarder.code.length == 0) revert ZeroAddress();\n        launchForwarder = forwarder;\n        emit LaunchForwarderSet(forwarder);\n    }\n    function setFeeSweepOperator(address operator) external onlyOwner {\n        if (operator == address(0)) revert ZeroAddress();\n        feeSweepOperator = operator;\n        emit FeeSweepOperatorUpdated(operator);\n    }\n    /// @notice Updates terms for future launches only; existing curves snapshot them.\n    function setLaunchTerms(uint256 newLaunchFee, uint256 creatorTaxMax, uint256 snipeStart, uint256 snipeWindow, FeePolicySnapshot calldata policy) external onlyOwner {\n        if (creatorTaxMax > 1_000 || snipeStart > 9_900 || snipeWindow == 0 || snipeWindow > 1 days || policy.protocolFeeRecipient == address(0) || policy.protocolFeeShareBps > 10_000 || policy.buybackBurnBps > 10_000 || policy.hookFeeBps > 1_000 || policy.maxInternalPriceImpactBps == 0 || policy.maxInternalPriceImpactBps >= 10_000) revert InvalidTerms();\n        launchFee = newLaunchFee; maxCreatorTaxBps = creatorTaxMax; snipeTaxStartBps = snipeStart; snipeTaxSeconds = snipeWindow; _policy = policy;\n        emit TermsUpdated();\n    }\n    function setPairEconomics(address pairToken, uint256 phantomQuote, bool enabled) external onlyOwner {\n        if (pairToken != address(0) && !_launches[pairToken].personality) revert PairTokenNotApproved();\n        if (phantomQuote == 0 || phantomQuote > type(uint128).max) revert InvalidTerms();\n        pairEconomics[pairToken] = PairEconomics(phantomQuote, enabled);\n        emit PairEconomicsUpdated(pairToken, phantomQuote, enabled);\n    }\n    function setBuybackEnabled(address token, bool enabled) external {\n        LaunchedToken storage launch = _requireLaunch(token);\n        if (msg.sender != launch.creatorFeeRecipient && (msg.sender != owner() || enabled)) revert NotCreatorFeeRecipient();\n        launch.buybackEnabled = enabled;\n        BrishopBondingCurve(launch.curve).setBuybackEnabled(enabled);\n    }\n    function transferCreatorFeeRecipient(address token, address recipient) external {\n        LaunchedToken storage launch = _requireLaunch(token);\n        if (msg.sender != launch.creatorFeeRecipient) revert NotCreatorFeeRecipient();\n        _updateRecipient(token, recipient);\n    }\n    function proposeCreatorFeeRecipient(address token, address recipient) external onlyOwner {\n        _requireLaunch(token);\n        if (recipient == address(0)) revert ZeroAddress();\n        uint256 effective = block.timestamp + CREATOR_RECOVERY_DELAY;\n        pendingCreatorFeeRecipient[token] = PendingRecipient(recipient, effective, effective + CREATOR_RECOVERY_WINDOW);\n        emit CreatorFeeRecipientChangeProposed(token, recipient, effective, effective + CREATOR_RECOVERY_WINDOW);\n    }\n    function cancelCreatorFeeRecipientChange(address token) external onlyOwner {\n        delete pendingCreatorFeeRecipient[token];\n        emit CreatorFeeRecipientChangeCancelled(token);\n    }\n    function executeCreatorFeeRecipientChange(address token) external onlyOwner {\n        PendingRecipient memory pending = pendingCreatorFeeRecipient[token];\n        if (pending.recipient == address(0) || block.timestamp < pending.effectiveAt || block.timestamp > pending.expiresAt) revert RecoveryNotExecutable();\n        delete pendingCreatorFeeRecipient[token];\n        _updateRecipient(token, pending.recipient);\n    }\n    function _updateRecipient(address token, address recipient) private {\n        if (recipient == address(0)) revert ZeroAddress();\n        LaunchedToken storage launch = _requireLaunch(token);\n        address previous = launch.creatorFeeRecipient;\n        launch.creatorFeeRecipient = recipient;\n        BrishopBondingCurve(launch.curve).setCreatorFeeRecipient(recipient);\n        buybackVault.updateCreatorRecipient(token, recipient);\n        emit CreatorFeeRecipientUpdated(token, previous, recipient);\n    }\n    function _requireLaunch(address token) private view returns (LaunchedToken storage launch) {\n        launch = _launches[token];\n        if (!launch.exists) revert UnknownToken();\n    }\n}\n"},"src/interfaces/IBrishop.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\ninterface IBrishopFeeEscrow {\n    function credit(address recipient) external payable;\n    function creditToken(address recipient, address token, uint256 amount) external;\n    function claim() external returns (uint256);\n    function claim(uint256 amount) external returns (uint256);\n    function claimToken(address token) external returns (uint256);\n    function claimToken(address token, uint256 amount) external returns (uint256);\n    function balanceOf(address recipient) external view returns (uint256);\n    function balanceOfToken(address recipient, address token) external view returns (uint256);\n}\n\n// Names retained from PONS for fee-policy compatibility. buybackBurnBps funds\n// purchases locked in the five-year vault; it does not burn those tokens.\nstruct FeePolicySnapshot {\n    address protocolFeeRecipient;\n    uint16 protocolFeeShareBps;\n    uint16 buybackBurnBps;\n    uint16 hookFeeBps;\n    uint16 maxInternalPriceImpactBps;\n}\n\ninterface IBrishopFeePolicy {\n    function feeSweepOperator() external view returns (address);\n    function currentFeePolicy() external view returns (FeePolicySnapshot memory);\n}\n\ninterface IBrishopSnipeTax {\n    function snipeTaxStartBps() external view returns (uint256);\n    function snipeTaxSeconds() external view returns (uint256);\n}\n\ninterface IBrishopLaunchFactory {\n    struct LaunchedToken {\n        address token;\n        address curve;\n        address deployer;\n        address creatorFeeRecipient;\n        address pairToken;\n        uint16 creatorTaxBps;\n        bool buybackEnabled;\n        bool personality;\n        bool exists;\n    }\n    function getLaunchedToken(address token) external view returns (LaunchedToken memory);\n}\n"},"src/libraries/BrishopBondingCurveMath.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from the MIT PONS v2 verified source. See ../NOTICE.md.\npragma solidity ^0.8.26;\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title BrishopBondingCurveMath\n * @notice Constant-product bonding curve math shared by BrishopBondingCurve, adapted\n * from the BootstrapPool.sol reference (code-423n4/2025-01-iq-ai). Reserves and fee\n * are passed explicitly so the same formula prices trades in either direction and can\n * also price the curve's internal buyback swap.\n */\nlibrary BrishopBondingCurveMath {\n    uint256 internal constant BASIS_POINTS = 10_000;\n\n    error InsufficientInputAmount();\n    error InsufficientOutputAmount();\n    error InsufficientLiquidity();\n    error ReserveLimit();\n\n    /**\n     * @notice Quotes the output amount for an exact input amount, net of the trade fee.\n     * @param amountIn Exact amount of the input asset being sold into the curve.\n     * @param reserveIn Curve reserve of the input asset before this trade.\n     * @param reserveOut Curve reserve of the output asset before this trade.\n     * @param feeBps Fee charged on the input amount, in basis points.\n     */\n    function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeBps)\n        internal\n        pure\n        returns (uint256 amountOut)\n    {\n        if (amountIn == 0) revert InsufficientInputAmount();\n        if (reserveIn == 0 || reserveOut == 0) revert InsufficientLiquidity();\n\n        amountOut = _amountOut(amountIn, reserveIn, reserveOut, feeBps);\n        if (amountOut == 0) revert InsufficientOutputAmount();\n    }\n\n    /**\n     * @notice Same quote as `getAmountOut`, returning zero where that reverts.\n     * @dev For callers that treat an unpriceable trade as a condition to\n     * handle rather than an error, such as the curve's internal buyback,\n     * which folds the slice back into the creator's payout when the curve is\n     * too thin to execute against. Routing that case through the reverting\n     * variant would take the whole fee sweep down with it, stranding fees\n     * exactly when the curve cannot support a buyback.\n     */\n    function quoteAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeBps)\n        internal\n        pure\n        returns (uint256 amountOut)\n    {\n        if (amountIn == 0 || reserveIn == 0 || reserveOut == 0 || feeBps >= BASIS_POINTS) return 0;\n        return _amountOut(amountIn, reserveIn, reserveOut, feeBps);\n    }\n\n    function _amountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeBps)\n        private\n        pure\n        returns (uint256)\n    {\n        if (amountIn > type(uint128).max || reserveIn > type(uint128).max || reserveOut > type(uint128).max) revert ReserveLimit();\n        uint256 amountInWithFee = amountIn * (BASIS_POINTS - feeBps);\n        uint256 denominator = reserveIn * BASIS_POINTS + amountInWithFee;\n        return Math.mulDiv(amountInWithFee, reserveOut, denominator);\n    }\n\n    /**\n     * @notice Quotes the input amount required for an exact output amount, net of the trade fee.\n     * @param amountOut Exact amount of the output asset requested from the curve.\n     * @param reserveIn Curve reserve of the input asset before this trade.\n     * @param reserveOut Curve reserve of the output asset before this trade.\n     * @param feeBps Fee charged on the input amount, in basis points.\n     */\n    function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut, uint256 feeBps)\n        internal\n        pure\n        returns (uint256 amountIn)\n    {\n        if (amountOut == 0) revert InsufficientOutputAmount();\n        if (reserveIn == 0 || reserveOut <= amountOut) revert InsufficientLiquidity();\n        // A full-fee trade has no input that produces output, and the\n        // denominator below would divide by zero rather than say so.\n        if (feeBps >= BASIS_POINTS) revert InsufficientLiquidity();\n\n        if (amountOut > type(uint128).max || reserveIn > type(uint128).max || reserveOut > type(uint128).max) revert ReserveLimit();\n        uint256 denominator = (reserveOut - amountOut) * (BASIS_POINTS - feeBps);\n        amountIn = Math.mulDiv(amountOut, reserveIn * BASIS_POINTS, denominator) + 1;\n    }\n}\n"},"@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\nimport {StorageSlot} from \"./StorageSlot.sol\";\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 *\n * IMPORTANT: Deprecated. This storage-based reentrancy guard will be removed and replaced\n * by the {ReentrancyGuardTransient} variant in v6.0.\n *\n * @custom:stateless\n */\nabstract contract ReentrancyGuard {\n    using StorageSlot for bytes32;\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant REENTRANCY_GUARD_STORAGE =\n        0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\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    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _reentrancyGuardStorageSlot().getUint256Slot().value = 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    /**\n     * @dev A `view` only version of {nonReentrant}. Use to block view functions\n     * from being called, preventing reading from inconsistent contract state.\n     *\n     * CAUTION: This is a \"view\" modifier and does not change the reentrancy\n     * status. Use it only on view functions. For payable or non-payable functions,\n     * use the standard {nonReentrant} modifier instead.\n     */\n    modifier nonReentrantView() {\n        _nonReentrantBeforeView();\n        _;\n    }\n\n    function _nonReentrantBeforeView() private view {\n        if (_reentrancyGuardEntered()) {\n            revert ReentrancyGuardReentrantCall();\n        }\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        _nonReentrantBeforeView();\n\n        // Any calls to nonReentrant after this point will fail\n        _reentrancyGuardStorageSlot().getUint256Slot().value = 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        _reentrancyGuardStorageSlot().getUint256Slot().value = 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 _reentrancyGuardStorageSlot().getUint256Slot().value == ENTERED;\n    }\n\n    function _reentrancyGuardStorageSlot() internal pure virtual returns (bytes32) {\n        return REENTRANCY_GUARD_STORAGE;\n    }\n}\n"},"@openzeppelin/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.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 Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = 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 = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a 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            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\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            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\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            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `condition ? a : b`. 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. `condition ? a : b`) 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        unchecked {\n            // (a + b) / 2 can overflow.\n            return (a & b) + (a ^ b) / 2;\n        }\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            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 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 low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\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 [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, 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 (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, 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 high into low.\n            low |= high * 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 high\n            // is no longer required.\n            result = low * 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 Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 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 buffer) private pure returns (bool) {\n        uint256 chunk;\n        for (uint256 i = 0; i < buffer.length; i += 0x20) {\n            // See _unsafeReadBytesOffset from utils/Bytes.sol\n            assembly (\"memory-safe\") {\n                chunk := mload(add(add(buffer, 0x20), i))\n            }\n            if (chunk >> (8 * saturatingSub(i + 0x20, buffer.length)) != 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 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the first 16 bytes (most significant half).\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\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 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\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    /**\n     * @dev Counts the number of leading zero bits in a uint256.\n     */\n    function clz(uint256 x) internal pure returns (uint256) {\n        return ternary(x == 0, 256, 255 - log2(x));\n    }\n}\n"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\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"},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _safeTransfer(token, to, value, false);\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _safeTransferFrom(token, from, to, value, false);\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},"@openzeppelin/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"},"@openzeppelin/contracts/interfaces/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},"@openzeppelin/contracts/interfaces/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"@openzeppelin/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"},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.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     * Both values are immutable: they can only be set once during 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    /// @inheritdoc IERC20\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /// @inheritdoc IERC20\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    /// @inheritdoc IERC20\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 sets 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"},"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ERC20} from \"../ERC20.sol\";\nimport {Context} from \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n    /**\n     * @dev Destroys a `value` amount of tokens from the caller.\n     *\n     * See {ERC20-_burn}.\n     */\n    function burn(uint256 value) public virtual {\n        _burn(_msgSender(), value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, deducting from\n     * the caller's allowance.\n     *\n     * See {ERC20-_burn} and {ERC20-allowance}.\n     *\n     * Requirements:\n     *\n     * - the caller must have allowance for ``accounts``'s tokens of at least\n     * `value`.\n     */\n    function burnFrom(address account, uint256 value) public virtual {\n        _spendAllowance(account, _msgSender(), value);\n        _burn(account, value);\n    }\n}\n"},"@openzeppelin/contracts/interfaces/IERC1363.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},"@openzeppelin/contracts/utils/StorageSlot.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},"@openzeppelin/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"},"@openzeppelin/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.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 a uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in a 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 A 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"},"@openzeppelin/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"},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\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"},"@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (interfaces/draft-IERC6093.sol)\n\npragma solidity >=0.8.4;\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-721.\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"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.8.35+commit.47b9dedd","compilerSettings":{"viaIR":true,"optimizer":{"runs":200,"enabled":true},"evmVersion":"cancun"},"name":"BrishopLaunchFactory","fullyQualifiedName":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"},{"name":"feed","type":"address","internalType":"contract IEthUsdFeed"}],"stateMutability":"nonpayable"},{"name":"AlreadySet","type":"error","inputs":[]},{"name":"CreatorTaxTooHigh","type":"error","inputs":[]},{"name":"DuplicatePersonality","type":"error","inputs":[]},{"name":"InvalidOraclePrice","type":"error","inputs":[]},{"name":"InvalidPersonalityValuation","type":"error","inputs":[]},{"name":"InvalidTerms","type":"error","inputs":[]},{"name":"LaunchEconomicsMismatch","type":"error","inputs":[]},{"name":"LaunchFeeNotPaid","type":"error","inputs":[]},{"name":"NotCreatorFeeRecipient","type":"error","inputs":[]},{"name":"NotLaunchForwarder","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":"PairTokenNotApproved","type":"error","inputs":[]},{"name":"RecoveryNotExecutable","type":"error","inputs":[]},{"name":"ReentrancyGuardReentrantCall","type":"error","inputs":[]},{"name":"SaltAlreadyUsed","type":"error","inputs":[]},{"name":"UnknownToken","type":"error","inputs":[]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"CreatorFeeRecipientChangeCancelled","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"CreatorFeeRecipientChangeProposed","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"recipient","type":"address","indexed":false,"internalType":"address"},{"name":"effectiveAt","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"expiresAt","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"CreatorFeeRecipientUpdated","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"oldRecipient","type":"address","indexed":true,"internalType":"address"},{"name":"newRecipient","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"FeeSweepOperatorUpdated","type":"event","inputs":[{"name":"operator","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"LaunchForwarderSet","type":"event","inputs":[{"name":"forwarder","type":"address","indexed":false,"internalType":"address"}],"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":"PairEconomicsUpdated","type":"event","inputs":[{"name":"pairToken","type":"address","indexed":true,"internalType":"address"},{"name":"phantomQuote","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"enabled","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"PersonalityLaunched","type":"event","inputs":[{"name":"id","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"targetFdvUsd","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"ethUsdAnswer","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"TermsUpdated","type":"event","inputs":[],"anonymous":false},{"name":"TokenLaunched","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"curve","type":"address","indexed":true,"internalType":"address"},{"name":"deployer","type":"address","indexed":true,"internalType":"address"},{"name":"pairToken","type":"address","indexed":false,"internalType":"address"},{"name":"phantomQuote","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"personality","type":"bool","indexed":false,"internalType":"bool"},{"name":"creatorAllocation","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"BASE_PHANTOM_ETH","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"CREATOR_RECOVERY_DELAY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"CREATOR_RECOVERY_WINDOW","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"ORACLE_MAX_AGE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"acceptOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"buybackVault","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract BrishopBuybackVault"}],"stateMutability":"view"},{"name":"canLaunch","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"pure"},{"name":"cancelCreatorFeeRecipientChange","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"currentFeePolicy","type":"function","inputs":[],"outputs":[{"name":"","type":"tuple","components":[{"name":"protocolFeeRecipient","type":"address","internalType":"address"},{"name":"protocolFeeShareBps","type":"uint16","internalType":"uint16"},{"name":"buybackBurnBps","type":"uint16","internalType":"uint16"},{"name":"hookFeeBps","type":"uint16","internalType":"uint16"},{"name":"maxInternalPriceImpactBps","type":"uint16","internalType":"uint16"}],"internalType":"struct FeePolicySnapshot"}],"stateMutability":"view"},{"name":"ethUsdFeed","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IEthUsdFeed"}],"stateMutability":"view"},{"name":"executeCreatorFeeRecipientChange","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"feeEscrow","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract BrishopFeeEscrow"}],"stateMutability":"view"},{"name":"feeSweepOperator","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"getLaunchFeePolicy","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"protocolFeeRecipient","type":"address","internalType":"address"},{"name":"protocolFeeShareBps","type":"uint16","internalType":"uint16"},{"name":"buybackBurnBps","type":"uint16","internalType":"uint16"},{"name":"hookFeeBps","type":"uint16","internalType":"uint16"},{"name":"maxInternalPriceImpactBps","type":"uint16","internalType":"uint16"}],"internalType":"struct FeePolicySnapshot"}],"stateMutability":"view"},{"name":"getLaunchedToken","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"token","type":"address","internalType":"address"},{"name":"curve","type":"address","internalType":"address"},{"name":"deployer","type":"address","internalType":"address"},{"name":"creatorFeeRecipient","type":"address","internalType":"address"},{"name":"pairToken","type":"address","internalType":"address"},{"name":"creatorTaxBps","type":"uint16","internalType":"uint16"},{"name":"buybackEnabled","type":"bool","internalType":"bool"},{"name":"personality","type":"bool","internalType":"bool"},{"name":"exists","type":"bool","internalType":"bool"}],"internalType":"struct IBrishopLaunchFactory.LaunchedToken"}],"stateMutability":"view"},{"name":"launchCount","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"launchDeployer","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract BrishopLaunchDeployer"}],"stateMutability":"view"},{"name":"launchFee","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"launchForwarder","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"launchPersonality","type":"function","inputs":[{"name":"params","type":"tuple","components":[{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"logo","type":"string","internalType":"string"},{"name":"description","type":"string","internalType":"string"},{"name":"socials","type":"tuple","components":[{"name":"twitter","type":"string","internalType":"string"},{"name":"telegram","type":"string","internalType":"string"},{"name":"discord","type":"string","internalType":"string"},{"name":"website","type":"string","internalType":"string"},{"name":"farcaster","type":"string","internalType":"string"}],"internalType":"struct BrishopLauncherToken.Socials"},{"name":"creatorFeeRecipient","type":"address","internalType":"address"},{"name":"creatorTaxBps","type":"uint16","internalType":"uint16"},{"name":"buybackEnabled","type":"bool","internalType":"bool"},{"name":"expectedEconomics","type":"bytes32","internalType":"bytes32"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"snipeTaxExemptions","type":"address[]","internalType":"address[]"}],"internalType":"struct TokenParams"},{"name":"id","type":"bytes32","internalType":"bytes32"},{"name":"targetFdvUsd","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"token","type":"address","internalType":"address"},{"name":"curve","type":"address","internalType":"address"}],"stateMutability":"payable"},{"name":"launchToken","type":"function","inputs":[{"name":"params","type":"tuple","components":[{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"logo","type":"string","internalType":"string"},{"name":"description","type":"string","internalType":"string"},{"name":"socials","type":"tuple","components":[{"name":"twitter","type":"string","internalType":"string"},{"name":"telegram","type":"string","internalType":"string"},{"name":"discord","type":"string","internalType":"string"},{"name":"website","type":"string","internalType":"string"},{"name":"farcaster","type":"string","internalType":"string"}],"internalType":"struct BrishopLauncherToken.Socials"},{"name":"creatorFeeRecipient","type":"address","internalType":"address"},{"name":"creatorTaxBps","type":"uint16","internalType":"uint16"},{"name":"buybackEnabled","type":"bool","internalType":"bool"},{"name":"expectedEconomics","type":"bytes32","internalType":"bytes32"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"snipeTaxExemptions","type":"address[]","internalType":"address[]"}],"internalType":"struct TokenParams"},{"name":"pairToken","type":"address","internalType":"address"}],"outputs":[{"name":"token","type":"address","internalType":"address"},{"name":"curve","type":"address","internalType":"address"}],"stateMutability":"payable"},{"name":"launchTokenFor","type":"function","inputs":[{"name":"params","type":"tuple","components":[{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"logo","type":"string","internalType":"string"},{"name":"description","type":"string","internalType":"string"},{"name":"socials","type":"tuple","components":[{"name":"twitter","type":"string","internalType":"string"},{"name":"telegram","type":"string","internalType":"string"},{"name":"discord","type":"string","internalType":"string"},{"name":"website","type":"string","internalType":"string"},{"name":"farcaster","type":"string","internalType":"string"}],"internalType":"struct BrishopLauncherToken.Socials"},{"name":"creatorFeeRecipient","type":"address","internalType":"address"},{"name":"creatorTaxBps","type":"uint16","internalType":"uint16"},{"name":"buybackEnabled","type":"bool","internalType":"bool"},{"name":"expectedEconomics","type":"bytes32","internalType":"bytes32"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"snipeTaxExemptions","type":"address[]","internalType":"address[]"}],"internalType":"struct TokenParams"},{"name":"pairToken","type":"address","internalType":"address"},{"name":"creator","type":"address","internalType":"address"}],"outputs":[{"name":"token","type":"address","internalType":"address"},{"name":"curve","type":"address","internalType":"address"}],"stateMutability":"payable"},{"name":"launchedTokenAt","type":"function","inputs":[{"name":"index","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"maxCreatorTaxBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"oracleDecimals","type":"function","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pairEconomics","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"phantomQuote","type":"uint256","internalType":"uint256"},{"name":"enabled","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"pendingCreatorFeeRecipient","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"recipient","type":"address","internalType":"address"},{"name":"effectiveAt","type":"uint256","internalType":"uint256"},{"name":"expiresAt","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"pendingOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"personalities","type":"function","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"previewLaunchEconomics","type":"function","inputs":[{"name":"pairToken","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"name":"previewPersonalityEconomics","type":"function","inputs":[{"name":"targetFdvUsd","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"economics","type":"bytes32","internalType":"bytes32"},{"name":"phantomQuote","type":"uint256","internalType":"uint256"},{"name":"price","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"proposeCreatorFeeRecipient","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"recipient","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"setBuybackEnabled","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"enabled","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setFeeSweepOperator","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setLaunchForwarder","type":"function","inputs":[{"name":"forwarder","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setLaunchTerms","type":"function","inputs":[{"name":"newLaunchFee","type":"uint256","internalType":"uint256"},{"name":"creatorTaxMax","type":"uint256","internalType":"uint256"},{"name":"snipeStart","type":"uint256","internalType":"uint256"},{"name":"snipeWindow","type":"uint256","internalType":"uint256"},{"name":"policy","type":"tuple","components":[{"name":"protocolFeeRecipient","type":"address","internalType":"address"},{"name":"protocolFeeShareBps","type":"uint16","internalType":"uint16"},{"name":"buybackBurnBps","type":"uint16","internalType":"uint16"},{"name":"hookFeeBps","type":"uint16","internalType":"uint16"},{"name":"maxInternalPriceImpactBps","type":"uint16","internalType":"uint16"}],"internalType":"struct FeePolicySnapshot"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setPairEconomics","type":"function","inputs":[{"name":"pairToken","type":"address","internalType":"address"},{"name":"phantomQuote","type":"uint256","internalType":"uint256"},{"name":"enabled","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"snipeTaxSeconds","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"snipeTaxStartBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferCreatorFeeRecipient","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"recipient","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"usedSalt","type":"function","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"}],"metadata":{"compiler":{"version":"0.8.35+commit.47b9dedd"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"contract IEthUsdFeed","name":"feed","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadySet","type":"error"},{"inputs":[],"name":"CreatorTaxTooHigh","type":"error"},{"inputs":[],"name":"DuplicatePersonality","type":"error"},{"inputs":[],"name":"InvalidOraclePrice","type":"error"},{"inputs":[],"name":"InvalidPersonalityValuation","type":"error"},{"inputs":[],"name":"InvalidTerms","type":"error"},{"inputs":[],"name":"LaunchEconomicsMismatch","type":"error"},{"inputs":[],"name":"LaunchFeeNotPaid","type":"error"},{"inputs":[],"name":"NotCreatorFeeRecipient","type":"error"},{"inputs":[],"name":"NotLaunchForwarder","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":"PairTokenNotApproved","type":"error"},{"inputs":[],"name":"RecoveryNotExecutable","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"SaltAlreadyUsed","type":"error"},{"inputs":[],"name":"UnknownToken","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"CreatorFeeRecipientChangeCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"effectiveAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expiresAt","type":"uint256"}],"name":"CreatorFeeRecipientChangeProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"oldRecipient","type":"address"},{"indexed":true,"internalType":"address","name":"newRecipient","type":"address"}],"name":"CreatorFeeRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"FeeSweepOperatorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"forwarder","type":"address"}],"name":"LaunchForwarderSet","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":"pairToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"phantomQuote","type":"uint256"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"PairEconomicsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"targetFdvUsd","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethUsdAnswer","type":"uint256"}],"name":"PersonalityLaunched","type":"event"},{"anonymous":false,"inputs":[],"name":"TermsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"curve","type":"address"},{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"address","name":"pairToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"phantomQuote","type":"uint256"},{"indexed":false,"internalType":"bool","name":"personality","type":"bool"},{"indexed":false,"internalType":"uint256","name":"creatorAllocation","type":"uint256"}],"name":"TokenLaunched","type":"event"},{"inputs":[],"name":"BASE_PHANTOM_ETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CREATOR_RECOVERY_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CREATOR_RECOVERY_WINDOW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_MAX_AGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buybackVault","outputs":[{"internalType":"contract BrishopBuybackVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"canLaunch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"cancelCreatorFeeRecipientChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentFeePolicy","outputs":[{"components":[{"internalType":"address","name":"protocolFeeRecipient","type":"address"},{"internalType":"uint16","name":"protocolFeeShareBps","type":"uint16"},{"internalType":"uint16","name":"buybackBurnBps","type":"uint16"},{"internalType":"uint16","name":"hookFeeBps","type":"uint16"},{"internalType":"uint16","name":"maxInternalPriceImpactBps","type":"uint16"}],"internalType":"struct FeePolicySnapshot","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethUsdFeed","outputs":[{"internalType":"contract IEthUsdFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"executeCreatorFeeRecipientChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeEscrow","outputs":[{"internalType":"contract BrishopFeeEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeSweepOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getLaunchFeePolicy","outputs":[{"components":[{"internalType":"address","name":"protocolFeeRecipient","type":"address"},{"internalType":"uint16","name":"protocolFeeShareBps","type":"uint16"},{"internalType":"uint16","name":"buybackBurnBps","type":"uint16"},{"internalType":"uint16","name":"hookFeeBps","type":"uint16"},{"internalType":"uint16","name":"maxInternalPriceImpactBps","type":"uint16"}],"internalType":"struct FeePolicySnapshot","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getLaunchedToken","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"curve","type":"address"},{"internalType":"address","name":"deployer","type":"address"},{"internalType":"address","name":"creatorFeeRecipient","type":"address"},{"internalType":"address","name":"pairToken","type":"address"},{"internalType":"uint16","name":"creatorTaxBps","type":"uint16"},{"internalType":"bool","name":"buybackEnabled","type":"bool"},{"internalType":"bool","name":"personality","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"internalType":"struct IBrishopLaunchFactory.LaunchedToken","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchDeployer","outputs":[{"internalType":"contract BrishopLaunchDeployer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"string","name":"twitter","type":"string"},{"internalType":"string","name":"telegram","type":"string"},{"internalType":"string","name":"discord","type":"string"},{"internalType":"string","name":"website","type":"string"},{"internalType":"string","name":"farcaster","type":"string"}],"internalType":"struct BrishopLauncherToken.Socials","name":"socials","type":"tuple"},{"internalType":"address","name":"creatorFeeRecipient","type":"address"},{"internalType":"uint16","name":"creatorTaxBps","type":"uint16"},{"internalType":"bool","name":"buybackEnabled","type":"bool"},{"internalType":"bytes32","name":"expectedEconomics","type":"bytes32"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address[]","name":"snipeTaxExemptions","type":"address[]"}],"internalType":"struct TokenParams","name":"params","type":"tuple"},{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint256","name":"targetFdvUsd","type":"uint256"}],"name":"launchPersonality","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"curve","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"string","name":"twitter","type":"string"},{"internalType":"string","name":"telegram","type":"string"},{"internalType":"string","name":"discord","type":"string"},{"internalType":"string","name":"website","type":"string"},{"internalType":"string","name":"farcaster","type":"string"}],"internalType":"struct BrishopLauncherToken.Socials","name":"socials","type":"tuple"},{"internalType":"address","name":"creatorFeeRecipient","type":"address"},{"internalType":"uint16","name":"creatorTaxBps","type":"uint16"},{"internalType":"bool","name":"buybackEnabled","type":"bool"},{"internalType":"bytes32","name":"expectedEconomics","type":"bytes32"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address[]","name":"snipeTaxExemptions","type":"address[]"}],"internalType":"struct TokenParams","name":"params","type":"tuple"},{"internalType":"address","name":"pairToken","type":"address"}],"name":"launchToken","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"curve","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"logo","type":"string"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"string","name":"twitter","type":"string"},{"internalType":"string","name":"telegram","type":"string"},{"internalType":"string","name":"discord","type":"string"},{"internalType":"string","name":"website","type":"string"},{"internalType":"string","name":"farcaster","type":"string"}],"internalType":"struct BrishopLauncherToken.Socials","name":"socials","type":"tuple"},{"internalType":"address","name":"creatorFeeRecipient","type":"address"},{"internalType":"uint16","name":"creatorTaxBps","type":"uint16"},{"internalType":"bool","name":"buybackEnabled","type":"bool"},{"internalType":"bytes32","name":"expectedEconomics","type":"bytes32"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address[]","name":"snipeTaxExemptions","type":"address[]"}],"internalType":"struct TokenParams","name":"params","type":"tuple"},{"internalType":"address","name":"pairToken","type":"address"},{"internalType":"address","name":"creator","type":"address"}],"name":"launchTokenFor","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"curve","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"launchedTokenAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxCreatorTaxBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pairEconomics","outputs":[{"internalType":"uint256","name":"phantomQuote","type":"uint256"},{"internalType":"bool","name":"enabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pendingCreatorFeeRecipient","outputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"effectiveAt","type":"uint256"},{"internalType":"uint256","name":"expiresAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"personalities","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pairToken","type":"address"}],"name":"previewLaunchEconomics","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"targetFdvUsd","type":"uint256"}],"name":"previewPersonalityEconomics","outputs":[{"internalType":"bytes32","name":"economics","type":"bytes32"},{"internalType":"uint256","name":"phantomQuote","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"proposeCreatorFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setBuybackEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"setFeeSweepOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"setLaunchForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLaunchFee","type":"uint256"},{"internalType":"uint256","name":"creatorTaxMax","type":"uint256"},{"internalType":"uint256","name":"snipeStart","type":"uint256"},{"internalType":"uint256","name":"snipeWindow","type":"uint256"},{"components":[{"internalType":"address","name":"protocolFeeRecipient","type":"address"},{"internalType":"uint16","name":"protocolFeeShareBps","type":"uint16"},{"internalType":"uint16","name":"buybackBurnBps","type":"uint16"},{"internalType":"uint16","name":"hookFeeBps","type":"uint16"},{"internalType":"uint16","name":"maxInternalPriceImpactBps","type":"uint16"}],"internalType":"struct FeePolicySnapshot","name":"policy","type":"tuple"}],"name":"setLaunchTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pairToken","type":"address"},{"internalType":"uint256","name":"phantomQuote","type":"uint256"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setPairEconomics","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snipeTaxSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"snipeTaxStartBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"transferCreatorFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"usedSalt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"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."}],"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}]},"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."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the 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":{"launchPersonality((string,string,string,string,(string,string,string,string,string),address,uint16,bool,bytes32,bytes32,address[]),bytes32,uint256)":{"notice":"Only the administrator may mint a personality. The 25% allocation goes directly to that administrator, is transferable, and receives no ETH."},"setLaunchTerms(uint256,uint256,uint256,uint256,(address,uint16,uint16,uint16,uint16))":{"notice":"Updates terms for future launches only; existing curves snapshot them."}},"version":1}},"settings":{"compilationTarget":{"src/BrishopLaunchFactory.sol":"BrishopLaunchFactory"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":200},"remappings":[],"viaIR":true},"sources":{"@openzeppelin/contracts/access/Ownable.sol":{"keccak256":"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb","license":"MIT","urls":["bzz-raw://8ed324d3920bb545059d66ab97d43e43ee85fd3bd52e03e401f020afb0b120f6","dweb:/ipfs/QmfEckWLmZkDDcoWrkEvMWhms66xwTLff9DDhegYpvHo1a"]},"@openzeppelin/contracts/access/Ownable2Step.sol":{"keccak256":"0xdcad8898fda432696597752e8ec361b87d85c82cb258115427af006dacf7128c","license":"MIT","urls":["bzz-raw://e2c9d517f0c136d54bd00cd57959d25681d4d6273f5bbbc263afe228303772f0","dweb:/ipfs/QmReNFjXBiufByiAAzfSQ2SM5r3qeUErn46BmN3yVRvrek"]},"@openzeppelin/contracts/interfaces/IERC1363.sol":{"keccak256":"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d","license":"MIT","urls":["bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100","dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d"]},"@openzeppelin/contracts/interfaces/IERC165.sol":{"keccak256":"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc","license":"MIT","urls":["bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037","dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ"]},"@openzeppelin/contracts/interfaces/IERC20.sol":{"keccak256":"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44","license":"MIT","urls":["bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d","dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF"]},"@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"keccak256":"0x1b88b3fb3d85ba5496d7d5f396f83ee1fddcdd6762059ff65992655b67920998","license":"MIT","urls":["bzz-raw://89393bb3212da1c0889601b9706a07b39419ddc4d2faab9eaf6e7f9152cf6a1c","dweb:/ipfs/QmcCfzzxv1Bkdz1c1yF4gQCeYb6Us5BJANnzTFqawfd1HL"]},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"keccak256":"0x669464167428061ee0f8618b73b3ee90aff8405683e7ddde8cd77dadaa1afe29","license":"MIT","urls":["bzz-raw://0dda78587a7358b4fdf6b9fca0fde5a5e34930f36d5268a16028627fc0170195","dweb:/ipfs/QmQ1b6cCceDRWNxti9HifsTCzmVP25Haxs1bWugm52vTqH"]},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"keccak256":"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2","license":"MIT","urls":["bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303","dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV"]},"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol":{"keccak256":"0x2659248df25e34000ed214b3dc8da2160bc39874c992b477d9e2b1b3283dc073","license":"MIT","urls":["bzz-raw://c345af1b0e7ea28d1216d6a04ab28f5534a5229b9edf9ca3cd0e84950ae58d26","dweb:/ipfs/QmY63jtSrYpLRe8Gj1ep2vMDCKxGNNG3hnNVKBVnrs2nmA"]},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"keccak256":"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f","license":"MIT","urls":["bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e","dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR"]},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"keccak256":"0x304d732678032a9781ae85c8f204c8fba3d3a5e31c02616964e75cfdc5049098","license":"MIT","urls":["bzz-raw://299ced486011781dc98f638059678323c03079fefae1482abaa2135b22fa92d0","dweb:/ipfs/QmbZNbcPTBxNvwChavN2kkZZs7xHhYL7mv51KrxMhsMs3j"]},"@openzeppelin/contracts/utils/Context.sol":{"keccak256":"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2","license":"MIT","urls":["bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12","dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF"]},"@openzeppelin/contracts/utils/Panic.sol":{"keccak256":"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a","license":"MIT","urls":["bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a","dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG"]},"@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"keccak256":"0xa516cbf1c7d15d3517c2d668601ce016c54395bf5171918a14e2686977465f53","license":"MIT","urls":["bzz-raw://1e1d079e8edfb58efd23a311e315a4807b01b5d1cf153f8fa2d0608b9dec3e99","dweb:/ipfs/QmTBExeX2SDTkn5xbk5ssbYSx7VqRp9H4Ux1CY4uQM4b9N"]},"@openzeppelin/contracts/utils/StorageSlot.sol":{"keccak256":"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97","license":"MIT","urls":["bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b","dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM"]},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c","license":"MIT","urls":["bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617","dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u"]},"@openzeppelin/contracts/utils/math/Math.sol":{"keccak256":"0x59973a93b1f983f94e10529f46ca46544a9fec2b5f56fb1390bbe9e0dc79f857","license":"MIT","urls":["bzz-raw://c55ef8f0b9719790c2ae6f81d80a59ffb89f2f0abe6bc065585bd79edce058c5","dweb:/ipfs/QmNNmCbX9NjPXKqHJN8R1WC2rNeZSQrPZLd6FF6AKLyH5Y"]},"@openzeppelin/contracts/utils/math/SafeCast.sol":{"keccak256":"0xc8cae21c9ae4a46e5162ff9bf5b351d6fa6a6eba72d515f3bc1bdfeda7fdf083","license":"MIT","urls":["bzz-raw://ce830ebcf28e31643caba318996db3763c36d52cd0f23798ba83c135355d45e9","dweb:/ipfs/QmdGPcvptHN7UBCbUYBbRX3hiRVRFLRwno8b4uga6uFNif"]},"src/BrishopBondingCurve.sol":{"keccak256":"0x37fcd3f1b4529a9f0dbc316d071e1edf11ce3fafe2546c4ecc6f365c844f3db7","license":"MIT","urls":["bzz-raw://32a9404f802a8eb3efd56548240f9abdddb6c0f936bb95d9e05df54b0e4c0e26","dweb:/ipfs/QmTZCdLsbkGLMXAuRFY8mRf9VU5XX24K8x3qjCbpQh7nLm"]},"src/BrishopBuybackVault.sol":{"keccak256":"0x0becf05283bc8b8964a8d100e23b887a188c82c95fcad98e22f5217ffc9e58c9","license":"MIT","urls":["bzz-raw://137a6aaded4724a3474b3c08067693245523ed517a84aafc5c146353852bb32d","dweb:/ipfs/QmQ4JfAQYR3eqhowQgibERLGiTfowSnH1QRWY6D1983eFW"]},"src/BrishopFeeEscrow.sol":{"keccak256":"0x361a29a736f82d65989960e20cc37d80e5f0ec1ee909a4799df91bcef1141ca0","license":"MIT","urls":["bzz-raw://27624435e94dd282fc36e0d39ceceff413cbcf314b9c38350168b4accb739988","dweb:/ipfs/QmT73E2hkE4UKyy6ZqujJsNEjHLYvMnnQSyw2Xhcin4UU4"]},"src/BrishopLaunchDeployer.sol":{"keccak256":"0x0f81d31836aa2a5d416979c07a14635bf3d182e2a2e955e631cae8d0afe1d544","license":"MIT","urls":["bzz-raw://f6c655be8bfc3007ed89e0734a9a27d26bcd3ce27483c10648d605304b2f3526","dweb:/ipfs/QmUChkKtVzv31TgNXQY8FGaZqeajBj7QhPXXSHep9kj5pe"]},"src/BrishopLaunchFactory.sol":{"keccak256":"0x4bf1ae68473202a8688fc818b97fbd6ed91fe27574e60859a8bf68b345b91ef9","license":"MIT","urls":["bzz-raw://c48a43af297f76683a83c086b05cbe5cfeeae87098c78ad8b228e2d9558a9f53","dweb:/ipfs/QmboPttLauLG6HzvRznmgGA7QRsodv6CoLtUDK5iej48sC"]},"src/BrishopLauncherToken.sol":{"keccak256":"0x1ebcf1534c80df8734078c6d29f4d03dc5ca76c762788065a845ea390452e428","license":"MIT","urls":["bzz-raw://41c43b23dc334d33209865364b3493cd9c44286868a9c94d97934bda862626f8","dweb:/ipfs/QmS7qZ19vCfUCYJEgLoKKG7hbpkHpP2Dps9SH6WMh52xt6"]},"src/interfaces/IBrishop.sol":{"keccak256":"0x329d57dfed260932f89ed7a9f0b91ed7236e12777f41ebf8599495ce294a8d2f","license":"MIT","urls":["bzz-raw://dd6053f039743beb42223b3228361129753dce8717c96291dba5820e52ef9892","dweb:/ipfs/QmeSF8Mo9XyXb3ZGp8ns6h2cLo1G8n4f8UyyUoHe8w4piF"]},"src/libraries/BrishopBondingCurveMath.sol":{"keccak256":"0x0d3088350d2c58adce273486980851b3a34b6a85705ca2b681846fca118fc75b","license":"MIT","urls":["bzz-raw://76441b39e6db97858be47e1d98ae0fde65f2060b4089f8a8395776c976ed28f5","dweb:/ipfs/QmcmmXMjzzRKKJbLJUo9tjpeikd65iGCG8Q1hdR19jjGDt"]}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_uint16":{"label":"uint16","encoding":"inplace","numberOfBytes":"2"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_bytes32":{"label":"bytes32","encoding":"inplace","numberOfBytes":"32"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_bytes32,t_bool)":{"key":"t_bytes32","label":"mapping(bytes32 => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"},"t_array(t_address)dyn_storage":{"base":"t_address","label":"address[]","encoding":"dynamic_array","numberOfBytes":"32"},"t_mapping(t_bytes32,t_address)":{"key":"t_bytes32","label":"mapping(bytes32 => address)","value":"t_address","encoding":"mapping","numberOfBytes":"32"},"t_struct(PairEconomics)9016_storage":{"label":"struct BrishopLaunchFactory.PairEconomics","members":[{"slot":"0","type":"t_uint256","astId":9013,"label":"phantomQuote","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"1","type":"t_bool","astId":9015,"label":"enabled","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}],"encoding":"inplace","numberOfBytes":"64"},"t_struct(LaunchedToken)10755_storage":{"label":"struct IBrishopLaunchFactory.LaunchedToken","members":[{"slot":"0","type":"t_address","astId":10738,"label":"token","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"1","type":"t_address","astId":10740,"label":"curve","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"2","type":"t_address","astId":10742,"label":"deployer","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"3","type":"t_address","astId":10744,"label":"creatorFeeRecipient","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_address","astId":10746,"label":"pairToken","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_uint16","astId":10748,"label":"creatorTaxBps","offset":20,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_bool","astId":10750,"label":"buybackEnabled","offset":22,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_bool","astId":10752,"label":"personality","offset":23,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_bool","astId":10754,"label":"exists","offset":24,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}],"encoding":"inplace","numberOfBytes":"160"},"t_struct(PendingRecipient)9028_storage":{"label":"struct BrishopLaunchFactory.PendingRecipient","members":[{"slot":"0","type":"t_address","astId":9023,"label":"recipient","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"1","type":"t_uint256","astId":9025,"label":"effectiveAt","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"2","type":"t_uint256","astId":9027,"label":"expiresAt","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}],"encoding":"inplace","numberOfBytes":"96"},"t_struct(FeePolicySnapshot)10713_storage":{"label":"struct FeePolicySnapshot","members":[{"slot":"0","type":"t_address","astId":10704,"label":"protocolFeeRecipient","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"0","type":"t_uint16","astId":10706,"label":"protocolFeeShareBps","offset":20,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"0","type":"t_uint16","astId":10708,"label":"buybackBurnBps","offset":22,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"0","type":"t_uint16","astId":10710,"label":"hookFeeBps","offset":24,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"0","type":"t_uint16","astId":10712,"label":"maxInternalPriceImpactBps","offset":26,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}],"encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_address,t_mapping(t_bytes32,t_bool))":{"key":"t_address","label":"mapping(address => mapping(bytes32 => bool))","value":"t_mapping(t_bytes32,t_bool)","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_struct(PairEconomics)9016_storage)":{"key":"t_address","label":"mapping(address => struct BrishopLaunchFactory.PairEconomics)","value":"t_struct(PairEconomics)9016_storage","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_struct(LaunchedToken)10755_storage)":{"key":"t_address","label":"mapping(address => struct IBrishopLaunchFactory.LaunchedToken)","value":"t_struct(LaunchedToken)10755_storage","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_struct(PendingRecipient)9028_storage)":{"key":"t_address","label":"mapping(address => struct BrishopLaunchFactory.PendingRecipient)","value":"t_struct(PendingRecipient)9028_storage","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_struct(FeePolicySnapshot)10713_storage)":{"key":"t_address","label":"mapping(address => struct FeePolicySnapshot)","value":"t_struct(FeePolicySnapshot)10713_storage","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":8,"label":"_owner","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"1","type":"t_address","astId":156,"label":"_pendingOwner","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"2","type":"t_uint256","astId":8958,"label":"launchFee","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"3","type":"t_uint256","astId":8961,"label":"maxCreatorTaxBps","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_uint256","astId":8964,"label":"snipeTaxStartBps","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"5","type":"t_uint256","astId":8967,"label":"snipeTaxSeconds","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"6","type":"t_address","astId":8969,"label":"feeSweepOperator","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"7","type":"t_address","astId":8971,"label":"launchForwarder","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"8","type":"t_struct(FeePolicySnapshot)10713_storage","astId":8988,"label":"_policy","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"9","type":"t_mapping(t_address,t_struct(LaunchedToken)10755_storage)","astId":8993,"label":"_launches","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"10","type":"t_mapping(t_address,t_struct(FeePolicySnapshot)10713_storage)","astId":8998,"label":"_launchPolicies","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"11","type":"t_array(t_address)dyn_storage","astId":9001,"label":"_tokens","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"12","type":"t_mapping(t_bytes32,t_address)","astId":9005,"label":"personalities","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"13","type":"t_mapping(t_address,t_mapping(t_bytes32,t_bool))","astId":9011,"label":"usedSalt","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"14","type":"t_mapping(t_address,t_struct(PairEconomics)9016_storage)","astId":9021,"label":"pairEconomics","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"15","type":"t_mapping(t_address,t_struct(PendingRecipient)9028_storage)","astId":9033,"label":"pendingCreatorFeeRecipient","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}]},"transientStorageLayout":{"types":null,"storage":[]},"userdoc":{"kind":"user","methods":{"setLaunchTerms(uint256,uint256,uint256,uint256,(address,uint16,uint16,uint16,uint16))":{"notice":"Updates terms for future launches only; existing curves snapshot them."},"launchPersonality((string,string,string,string,(string,string,string,string,string),address,uint16,bool,bytes32,bytes32,address[]),bytes32,uint256)":{"notice":"Only the administrator may mint a personality. The 25% allocation goes directly to that administrator, is transferable, and receives no ETH."}},"version":1},"devdoc":{"kind":"dev","errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}],"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."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the 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},"sourceIds":{"src/BrishopFeeEscrow.sol":{"id":20},"src/BrishopBondingCurve.sol":{"id":18},"src/BrishopBuybackVault.sol":{"id":19},"src/interfaces/IBrishop.sol":{"id":25},"src/BrishopLaunchFactory.sol":{"id":23},"src/BrishopLauncherToken.sol":{"id":24},"src/BrishopLaunchDeployer.sol":{"id":22},"@openzeppelin/contracts/utils/Panic.sol":{"id":12},"@openzeppelin/contracts/utils/Context.sol":{"id":11},"src/libraries/BrishopBondingCurveMath.sol":{"id":26},"@openzeppelin/contracts/access/Ownable.sol":{"id":0},"@openzeppelin/contracts/utils/math/Math.sol":{"id":16},"@openzeppelin/contracts/interfaces/IERC20.sol":{"id":4},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"id":6},"@openzeppelin/contracts/utils/StorageSlot.sol":{"id":14},"@openzeppelin/contracts/interfaces/IERC165.sol":{"id":3},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"id":7},"@openzeppelin/contracts/access/Ownable2Step.sol":{"id":1},"@openzeppelin/contracts/interfaces/IERC1363.sol":{"id":2},"@openzeppelin/contracts/utils/math/SafeCast.sol":{"id":17},"@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"id":13},"@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"id":5},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"id":10},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"id":15},"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol":{"id":8},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":9}},"additionalInput":null,"stdJsonInput":{"sources":{"src/BrishopFeeEscrow.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from the MIT PONS v2 verified source. See ../NOTICE.md.\npragma solidity ^0.8.26;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IBrishopFeeEscrow} from \"./interfaces/IBrishop.sol\";\n\n/**\n * @title BrishopFeeEscrow\n * @notice Holds every v2 recipient's claimable balance in one place, so\n * protocol and creators claim revenue from across all of their pools in a\n * single transaction instead of collecting per position. Revenue arrives in\n * whichever asset the launch trades against: native ETH for a native launch,\n * and the launch's ERC-20 quote asset otherwise. Brishop's permanent curves\n * and buyback vault credit this same ledger.\n */\ncontract BrishopFeeEscrow is ReentrancyGuard, IBrishopFeeEscrow {\n    using SafeERC20 for IERC20;\n\n    error ZeroAddress();\n    error NoBalance();\n    error TransferFailed();\n    error InsufficientBalance(uint256 requested, uint256 available);\n\n    event Credited(address indexed recipient, address indexed depositor, uint256 amount);\n    event CreditedToken(address indexed recipient, address indexed token, address indexed depositor, uint256 amount);\n    event Claimed(address indexed recipient, uint256 amount);\n    event ClaimedToken(address indexed recipient, address indexed token, uint256 amount);\n\n    mapping(address recipient => uint256 amount) private _balances;\n    mapping(address recipient => mapping(address token => uint256 amount)) private _tokenBalances;\n\n    /**\n     * @notice Credits `msg.value` to `recipient`'s claimable native ETH balance.\n     * @dev Permissionless by design: the caller can only ever add value they\n     * already attached to the call, so there is no privilege to gate.\n     */\n    function credit(address recipient) external payable {\n        if (recipient == address(0)) revert ZeroAddress();\n        if (msg.value == 0) return;\n        _balances[recipient] += msg.value;\n        emit Credited(recipient, msg.sender, msg.value);\n    }\n\n    /**\n     * @notice Pulls `amount` of `token` from the caller and credits it to `recipient`.\n     * @dev Permissionless by design: the caller can only credit tokens they\n     * already hold and approve, so there is no privilege to gate. Credits\n     * the actual balance delta rather than the nominal `amount`, so a\n     * fee-on-transfer or deflationary pairToken can never make this\n     * contract record more credited liability than it actually holds,\n     * which would otherwise starve whichever recipient claims that token\n     * last.\n     */\n    function creditToken(address recipient, address token, uint256 amount) external nonReentrant {\n        if (recipient == address(0) || token == address(0)) revert ZeroAddress();\n        if (amount == 0) return;\n        uint256 balanceBefore = IERC20(token).balanceOf(address(this));\n        IERC20(token).safeTransferFrom(msg.sender, address(this), amount);\n        uint256 received = IERC20(token).balanceOf(address(this)) - balanceBefore;\n        if (received == 0) return;\n        _tokenBalances[recipient][token] += received;\n        emit CreditedToken(recipient, token, msg.sender, received);\n    }\n\n    /**\n     * @notice Pays out the caller's entire claimable native ETH balance.\n     */\n    function claim() external nonReentrant returns (uint256 amount) {\n        amount = _claim(_balances[msg.sender]);\n    }\n\n    /**\n     * @notice Pays out `amount` of the caller's claimable native ETH balance.\n     */\n    function claim(uint256 amount) external nonReentrant returns (uint256) {\n        return _claim(amount);\n    }\n\n    /**\n     * @notice Pays out the caller's entire claimable balance of `token`.\n     */\n    function claimToken(address token) external nonReentrant returns (uint256 amount) {\n        amount = _claimToken(token, _tokenBalances[msg.sender][token]);\n    }\n\n    /**\n     * @notice Pays out `amount` of the caller's claimable balance of `token`.\n     * @dev A recipient's balance aggregates credits from every launch, curve,\n     * curve and buyback release, and `creditToken` is permissionless, so a\n     * third party can enlarge that figure at will. Against a token with a\n     * fixed maximum per transfer, a single full-balance claim would then\n     * revert and leave the recipient unable to draw any of it. Choosing the\n     * amount keeps the aggregate from being a single point of failure, and\n     * lets a recipient work around any per-transfer limit its quote asset\n     * imposes.\n     */\n    function claimToken(address token, uint256 amount) external nonReentrant returns (uint256) {\n        return _claimToken(token, amount);\n    }\n\n    /**\n     * @dev Shared debit path for both native claim entry points.\n     */\n    function _claim(uint256 amount) private returns (uint256) {\n        if (amount == 0) revert NoBalance();\n        uint256 balance = _balances[msg.sender];\n        if (amount > balance) revert InsufficientBalance(amount, balance);\n\n        _balances[msg.sender] = balance - amount;\n        (bool sent,) = payable(msg.sender).call{value: amount}(\"\");\n        if (!sent) revert TransferFailed();\n\n        emit Claimed(msg.sender, amount);\n        return amount;\n    }\n\n    /**\n     * @dev Shared debit path for both ERC-20 claim entry points.\n     */\n    function _claimToken(address token, uint256 amount) private returns (uint256) {\n        if (amount == 0) revert NoBalance();\n        uint256 balance = _tokenBalances[msg.sender][token];\n        if (amount > balance) revert InsufficientBalance(amount, balance);\n\n        _tokenBalances[msg.sender][token] = balance - amount;\n        IERC20(token).safeTransfer(msg.sender, amount);\n\n        emit ClaimedToken(msg.sender, token, amount);\n        return amount;\n    }\n\n    /**\n     * @notice Returns the claimable native ETH balance for `recipient`.\n     */\n    function balanceOf(address recipient) external view returns (uint256) {\n        return _balances[recipient];\n    }\n\n    /**\n     * @notice Returns the claimable balance of `token` for `recipient`.\n     */\n    function balanceOfToken(address recipient, address token) external view returns (uint256) {\n        return _tokenBalances[recipient][token];\n    }\n}\n"},"src/BrishopBondingCurve.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from PONS v2's verified curve; see ../NOTICE.md and upstream provenance.\npragma solidity ^0.8.26;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {BrishopBondingCurveMath} from \"./libraries/BrishopBondingCurveMath.sol\";\nimport {BrishopBuybackVault} from \"./BrishopBuybackVault.sol\";\nimport {FeePolicySnapshot, IBrishopFeeEscrow, IBrishopFeePolicy, IBrishopSnipeTax} from \"./interfaces/IBrishop.sol\";\n\n/// @notice Permanent constant-product market. Phantom quote sets pricing; only\n/// actual quote reserves, excluding earned fees, can fund a sell.\ncontract BrishopBondingCurve is ReentrancyGuard {\n    using SafeERC20 for IERC20;\n    uint256 private constant BPS = 10_000;\n    uint256 public constant MAX_RESERVE = type(uint128).max;\n\n    struct BuyQuote { uint256 tokensOut; uint256 fee; uint256 tax; uint256 snipeTax; }\n    struct SellQuote { uint256 quoteOut; uint256 grossQuoteOut; uint256 fee; uint256 tax; bool reserveSufficient; }\n    struct Terms {\n        address pairToken;\n        address creator;\n        uint256 phantomQuote;\n        uint256 feeBps;\n        uint256 creatorTaxBps;\n        bool buybackEnabled;\n    }\n    error ZeroAddress();\n    error ZeroAmount();\n    error NotFactory();\n    error AlreadyInitialized();\n    error NotInitialized();\n    error InvalidLaunchEconomics();\n    error InvalidFeePolicy();\n    error ReserveLimit();\n    error DeadlineExpired();\n    error SlippageExceeded(uint256 actual, uint256 minimum);\n    error InsufficientRealReserve(uint256 required, uint256 available);\n    error NativeValueMismatch(uint256 supplied, uint256 expected);\n    error UnexpectedNativeValue();\n    error TransferFailed();\n    error NotFeeSweepOperator();\n    error InternalSwapRequiresOperator();\n    error MinimumOutputRequired();\n\n    event Initialized(address token);\n    event CurveBuy(address indexed buyer, address indexed recipient, uint256 quoteIn, uint256 tokensOut, uint256 fee, uint256 tax);\n    event CurveSell(address indexed seller, address indexed recipient, uint256 tokensIn, uint256 quoteOut, uint256 fee, uint256 tax);\n    event ReservesUpdated(uint256 realQuote, uint256 tokens);\n    event SnipeTaxExempted(address indexed account);\n    event SnipeTaxCharged(address indexed recipient, uint256 amount);\n    event CreatorFeeRecipientUpdated(address indexed previousRecipient, address indexed newRecipient);\n    event BuybackEnabledUpdated(bool enabled);\n    event FeesSwept(uint256 protocolAmount, uint256 buybackAmount, uint256 creatorAmount);\n    event BuybackLocked(uint256 quoteSpent, uint256 tokensLocked);\n\n    address public token;\n    address public immutable pairToken;\n    address public deployer;\n    address public immutable factory;\n    IBrishopFeePolicy public immutable feePolicy;\n    IBrishopFeeEscrow public immutable feeEscrow;\n    BrishopBuybackVault public immutable buybackVault;\n    address public immutable protocolFeeRecipient;\n    address public immutable buybackCreatorRecipient;\n    uint16 public immutable protocolFeeShareBps;\n    uint16 public immutable buybackBurnBps;\n    uint16 public immutable maxInternalPriceImpactBps;\n    uint256 public immutable phantomQuote;\n    uint256 public immutable feeBps;\n    uint256 public immutable creatorTaxBps;\n    bool public buybackEnabled;\n    uint256 public quoteFeeBalance;\n    uint256 public buybackQuoteBalance;\n    uint256 public creatorTaxBalance;\n    uint256 public trackedQuote;\n    uint256 public trackedTokens;\n    uint256 public launchSupply;\n    uint256 public launchedAt;\n    uint256 public snipeTaxStartBps;\n    uint256 public snipeTaxSeconds;\n    mapping(address => bool) public snipeTaxExempt;\n\n    modifier onlyFactory() { if (msg.sender != factory) revert NotFactory(); _; }\n    modifier onlyInitialized() { if (token == address(0)) revert NotInitialized(); _; }\n\n    constructor(address factory_, IBrishopFeeEscrow escrow_, BrishopBuybackVault vault_, FeePolicySnapshot memory policy, Terms memory terms) {\n        if (factory_ == address(0) || address(escrow_) == address(0) || address(vault_) == address(0) || terms.creator == address(0)) revert ZeroAddress();\n        if (policy.protocolFeeRecipient == address(0) || policy.protocolFeeShareBps > BPS || policy.buybackBurnBps > BPS || policy.maxInternalPriceImpactBps == 0 || policy.maxInternalPriceImpactBps >= BPS || terms.feeBps + terms.creatorTaxBps > 2_000) revert InvalidFeePolicy();\n        if (terms.phantomQuote == 0 || terms.phantomQuote > MAX_RESERVE) revert InvalidLaunchEconomics();\n        factory = factory_;\n        feePolicy = IBrishopFeePolicy(factory_);\n        feeEscrow = escrow_;\n        buybackVault = vault_;\n        pairToken = terms.pairToken;\n        deployer = terms.creator;\n        protocolFeeRecipient = policy.protocolFeeRecipient;\n        buybackCreatorRecipient = terms.creator;\n        protocolFeeShareBps = policy.protocolFeeShareBps;\n        buybackBurnBps = policy.buybackBurnBps;\n        maxInternalPriceImpactBps = policy.maxInternalPriceImpactBps;\n        phantomQuote = terms.phantomQuote;\n        feeBps = terms.feeBps;\n        creatorTaxBps = terms.creatorTaxBps;\n        buybackEnabled = terms.buybackEnabled;\n    }\n\n    /// @dev The caller supplies the complete immutable exemption list atomically\n    /// at initialization. There is no way to add exemptions to a live pool.\n    function initialize(address token_, address[] calldata exemptions) external onlyFactory {\n        if (token != address(0)) revert AlreadyInitialized();\n        if (token_ == address(0) || token_ == pairToken) revert ZeroAddress();\n        uint256 received = IERC20(token_).balanceOf(address(this));\n        uint256 supply = IERC20(token_).totalSupply();\n        if (received == 0 || received > supply || supply > MAX_RESERVE || exemptions.length > 34) revert InvalidLaunchEconomics();\n        token = token_;\n        launchSupply = supply;\n        trackedTokens = received;\n        launchedAt = block.timestamp;\n        snipeTaxStartBps = IBrishopSnipeTax(factory).snipeTaxStartBps();\n        snipeTaxSeconds = IBrishopSnipeTax(factory).snipeTaxSeconds();\n        if (snipeTaxStartBps > 9_900 || snipeTaxSeconds == 0 || snipeTaxSeconds > 1 days) revert InvalidFeePolicy();\n        for (uint256 i; i < exemptions.length; ++i) {\n            if (exemptions[i] == address(0)) revert ZeroAddress();\n            snipeTaxExempt[exemptions[i]] = true;\n            emit SnipeTaxExempted(exemptions[i]);\n        }\n        emit Initialized(token_);\n        emit ReservesUpdated(0, received);\n    }\n\n    function isNativeQuote() public view returns (bool) { return pairToken == address(0); }\n    function realQuoteReserve() public view returns (uint256) { return trackedQuote - quoteFeeBalance - creatorTaxBalance; }\n    function getReserves() public view returns (uint256 quote, uint256 tokens) { return (phantomQuote + realQuoteReserve(), trackedTokens); }\n    function quoteReserve() external view returns (uint256) { return phantomQuote + realQuoteReserve(); }\n    function tokenReserve() external view returns (uint256) { return trackedTokens; }\n\n    /// @notice PONS's verified fourteen-halving decay; the live three-second\n    /// default produces 9900, 618, 19, 0 bps before the combined-fee cap.\n    function currentSnipeTaxBps(address recipient) public view returns (uint256) {\n        if (snipeTaxExempt[recipient] || snipeTaxStartBps == 0) return 0;\n        uint256 elapsed = block.timestamp - launchedAt;\n        if (elapsed >= snipeTaxSeconds) return 0;\n        return snipeTaxStartBps >> ((elapsed * 14) / snipeTaxSeconds);\n    }\n\n    function quoteBuy(uint256 quoteIn, address recipient) public view onlyInitialized returns (BuyQuote memory q) {\n        if (recipient == address(0)) revert ZeroAddress();\n        if (quoteIn == 0) revert ZeroAmount();\n        if (quoteIn > MAX_RESERVE - phantomQuote - trackedQuote) revert ReserveLimit();\n        uint256 snipeBps = currentSnipeTaxBps(recipient);\n        uint256 maxSnipe = BPS - feeBps - creatorTaxBps - 100;\n        if (snipeBps > maxSnipe) snipeBps = maxSnipe;\n        q.fee = Math.mulDiv(quoteIn, feeBps, BPS);\n        q.tax = Math.mulDiv(quoteIn, creatorTaxBps, BPS);\n        q.snipeTax = Math.mulDiv(quoteIn, snipeBps, BPS);\n        (uint256 quote, uint256 tokens) = getReserves();\n        q.tokensOut = BrishopBondingCurveMath.getAmountOut(quoteIn - q.fee - q.tax - q.snipeTax, quote, tokens, 0);\n    }\n\n    function quoteSell(uint256 tokensIn) public view onlyInitialized returns (SellQuote memory q) {\n        if (tokensIn == 0) revert ZeroAmount();\n        if (tokensIn > MAX_RESERVE - trackedTokens) revert ReserveLimit();\n        (uint256 quote, uint256 tokens) = getReserves();\n        q.grossQuoteOut = BrishopBondingCurveMath.getAmountOut(tokensIn, tokens, quote, 0);\n        q.fee = Math.mulDiv(q.grossQuoteOut, feeBps, BPS);\n        q.tax = Math.mulDiv(q.grossQuoteOut, creatorTaxBps, BPS);\n        q.quoteOut = q.grossQuoteOut - q.fee - q.tax;\n        q.reserveSufficient = q.grossQuoteOut <= realQuoteReserve();\n    }\n\n    function buy(uint256 quoteIn, uint256 minTokensOut, address recipient, uint256 deadline) external payable nonReentrant onlyInitialized returns (uint256 tokensOut) {\n        if (block.timestamp > deadline) revert DeadlineExpired();\n        uint256 received = _receiveQuote(quoteIn);\n        BuyQuote memory q = quoteBuy(received, recipient);\n        tokensOut = q.tokensOut;\n        if (tokensOut < minTokensOut) revert SlippageExceeded(tokensOut, minTokensOut);\n        _accrueFees(q.fee + q.snipeTax, q.tax);\n        trackedQuote += received;\n        trackedTokens -= tokensOut;\n        IERC20(token).safeTransfer(recipient, tokensOut);\n        if (q.snipeTax != 0) emit SnipeTaxCharged(recipient, q.snipeTax);\n        emit CurveBuy(msg.sender, recipient, received, tokensOut, q.fee + q.snipeTax, q.tax);\n        emit ReservesUpdated(realQuoteReserve(), trackedTokens);\n    }\n\n    function sell(uint256 tokensIn, uint256 minQuoteOut, address recipient, uint256 deadline) external nonReentrant onlyInitialized returns (uint256 quoteOut) {\n        if (block.timestamp > deadline) revert DeadlineExpired();\n        if (recipient == address(0)) revert ZeroAddress();\n        SellQuote memory q = quoteSell(tokensIn);\n        if (!q.reserveSufficient) revert InsufficientRealReserve(q.grossQuoteOut, realQuoteReserve());\n        quoteOut = q.quoteOut;\n        if (quoteOut < minQuoteOut) revert SlippageExceeded(quoteOut, minQuoteOut);\n        IERC20(token).safeTransferFrom(msg.sender, address(this), tokensIn);\n        _accrueFees(q.fee, q.tax);\n        trackedQuote -= quoteOut;\n        trackedTokens += tokensIn;\n        _sendQuote(recipient, quoteOut);\n        emit CurveSell(msg.sender, recipient, tokensIn, quoteOut, q.fee, q.tax);\n        emit ReservesUpdated(realQuoteReserve(), trackedTokens);\n    }\n\n    function setCreatorFeeRecipient(address recipient) external onlyFactory {\n        if (recipient == address(0)) revert ZeroAddress();\n        emit CreatorFeeRecipientUpdated(deployer, recipient);\n        deployer = recipient;\n    }\n    function setBuybackEnabled(bool enabled) external onlyFactory { buybackEnabled = enabled; emit BuybackEnabledUpdated(enabled); }\n\n    function _receiveQuote(uint256 amount) private returns (uint256) {\n        if (isNativeQuote()) {\n            if (msg.value != amount) revert NativeValueMismatch(msg.value, amount);\n            return amount;\n        }\n        if (msg.value != 0) revert UnexpectedNativeValue();\n        uint256 beforeBalance = IERC20(pairToken).balanceOf(address(this));\n        IERC20(pairToken).safeTransferFrom(msg.sender, address(this), amount);\n        return IERC20(pairToken).balanceOf(address(this)) - beforeBalance;\n    }\n    function _sendQuote(address recipient, uint256 amount) private {\n        if (isNativeQuote()) {\n            (bool sent,) = payable(recipient).call{value: amount}(\"\");\n            if (!sent) revert TransferFailed();\n        } else IERC20(pairToken).safeTransfer(recipient, amount);\n    }\n    function _creditQuote(address recipient, uint256 amount) private {\n        if (isNativeQuote()) feeEscrow.credit{value: amount}(recipient);\n        else {\n            IERC20(pairToken).forceApprove(address(feeEscrow), amount);\n            feeEscrow.creditToken(recipient, pairToken, amount);\n        }\n    }\n    function _accrueFees(uint256 fee, uint256 tax) private {\n        quoteFeeBalance += fee;\n        creatorTaxBalance += tax;\n        if (buybackEnabled && fee != 0) {\n            uint256 creatorSlice = fee - Math.mulDiv(fee, protocolFeeShareBps, BPS);\n            buybackQuoteBalance += Math.mulDiv(creatorSlice, buybackBurnBps, BPS);\n        }\n    }\n\n    /// @notice PONS fee sweep and five-year buyback behavior, with its former\n    /// graduation inventory limit removed. Minimum output bounds buyback swaps.\n    function sweepFees(uint256 minBuybackTokensOut) external nonReentrant onlyInitialized {\n        bool operator = msg.sender == feePolicy.feeSweepOperator();\n        if (!operator && msg.sender != deployer) revert NotFeeSweepOperator();\n        if (!operator && buybackQuoteBalance != 0) revert InternalSwapRequiresOperator();\n        uint256 pending = quoteFeeBalance;\n        uint256 tax = creatorTaxBalance;\n        if (pending == 0 && tax == 0) return;\n        uint256 protocolAmount = Math.mulDiv(pending, protocolFeeShareBps, BPS);\n        uint256 creatorBucket = pending - protocolAmount;\n        uint256 buybackAmount = Math.min(buybackQuoteBalance, creatorBucket);\n        uint256 creatorAmount = creatorBucket - buybackAmount + tax;\n        uint256 tokensLocked;\n        if (buybackAmount != 0) {\n            if (minBuybackTokensOut == 0) revert MinimumOutputRequired();\n            (uint256 quote, uint256 tokens) = getReserves();\n            uint256 movementBps = Math.mulDiv(buybackAmount, BPS, quote + buybackAmount);\n            if (movementBps <= maxInternalPriceImpactBps) tokensLocked = BrishopBondingCurveMath.quoteAmountOut(buybackAmount, quote, tokens, 0);\n            if (tokensLocked == 0) { creatorAmount += buybackAmount; buybackAmount = 0; }\n            else if (tokensLocked < minBuybackTokensOut) revert SlippageExceeded(tokensLocked, minBuybackTokensOut);\n        }\n        quoteFeeBalance = 0;\n        creatorTaxBalance = 0;\n        buybackQuoteBalance = 0;\n        trackedQuote -= protocolAmount + creatorAmount;\n        if (tokensLocked != 0) {\n            trackedTokens -= tokensLocked;\n            IERC20(token).forceApprove(address(buybackVault), tokensLocked);\n            buybackVault.lock(token, tokensLocked, buybackCreatorRecipient, protocolFeeRecipient, protocolFeeShareBps);\n            emit BuybackLocked(buybackAmount, tokensLocked);\n        }\n        if (protocolAmount != 0) _creditQuote(protocolFeeRecipient, protocolAmount);\n        if (creatorAmount != 0) _creditQuote(deployer, creatorAmount);\n        emit FeesSwept(protocolAmount, buybackAmount, creatorAmount);\n        emit ReservesUpdated(realQuoteReserve(), trackedTokens);\n    }\n}\n"},"src/BrishopBuybackVault.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from the MIT PONS v2 verified source. See ../NOTICE.md.\npragma solidity ^0.8.26;\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {IBrishopFeeEscrow, IBrishopFeePolicy, IBrishopLaunchFactory} from \"./interfaces/IBrishop.sol\";\n\n/**\n * @title BrishopBuybackVault\n * @notice Holds every launch's bought-back memecoin supply and releases it\n * linearly over five years instead of burning it immediately, splitting\n * every release between the creator and the protocol on the launch's\n * recorded fee shares. One shared deployment serves every launch, the same\n * \"single deployment for every token\" pattern BrishopFeeEscrow already uses.\n *\n * Note that the split applies to the release, not to the funding. The\n * permanent curve carves the buyback slice out of the creator's share of\n * the fees alone, so the creator funds the entire lock and then receives\n * only their fee share of it back. Enabling a buyback therefore moves value\n * from the creator to the protocol relative to taking the fees directly,\n * by an amount that grows with `buybackBurnBps`.\n *\n * Deposits use a weighted-average vesting clock instead of per-deposit\n * tranches: a launch's fee sweep can add to its lock on every single sweep,\n * and tracking an unbounded array of tranches would make `release()`'s gas\n * cost grow forever. Instead, each new deposit shifts the launch's single\n * `vestingStart` forward by an amount proportional to the deposit's share\n * of the new total, so a large existing lock is barely disturbed by a small\n * top-up, and a small existing lock is pulled close to the new deposit's own\n * clock. `vestedAmount` at any time reflects a fair, size-weighted blend\n * across every deposit made so far.\n */\ncontract BrishopBuybackVault is Ownable2Step, ReentrancyGuard {\n    using SafeERC20 for IERC20;\n\n    struct LaunchVest {\n        uint256 totalLocked;\n        uint256 totalReleased;\n        uint256 vestingStart;\n        uint256 vestedUnreleased;\n        uint256 unvestedAmount;\n        uint256 lastUpdate;\n        uint256 vestingEnd;\n        address creatorRecipient;\n        address protocolRecipient;\n        uint16 protocolFeeShareBps;\n    }\n\n    uint256 private constant BASIS_POINTS = 10_000;\n    uint256 public constant VESTING_DURATION = 5 * 365 days;\n\n    error ZeroAddress();\n    error AlreadyInitialized();\n    error NotFactory();\n    error NotAuthorizedLocker();\n    error NotVestBeneficiary();\n    error InvalidVestingTerms();\n    error VestingTermsMismatch();\n    error OwnershipCannotBeRenounced();\n\n    event FactorySet(address factory);\n    event Locked(address indexed token, address indexed depositor, uint256 amount, uint256 newVestingStart);\n    event VestingTermsSnapshotted(\n        address indexed token,\n        address indexed creatorRecipient,\n        address indexed protocolRecipient,\n        uint256 protocolFeeShareBps\n    );\n    event Released(address indexed token, uint256 creatorAmount, uint256 protocolAmount);\n    event CreatorRecipientUpdated(\n        address indexed token, address indexed previousRecipient, address indexed newRecipient\n    );\n\n    IBrishopFeePolicy public immutable feePolicy;\n    IBrishopFeeEscrow public immutable feeEscrow;\n    address public factory;\n\n    mapping(address token => LaunchVest) private _vaults;\n\n    /**\n     * @param initialOwner Administrative owner; only used to wire the factory once.\n     * @param feePolicy_ Shared Brishop protocol/creator fee policy.\n     * @param feeEscrow_ Shared claimable balance ledger releases are paid through.\n     */\n    constructor(address initialOwner, IBrishopFeePolicy feePolicy_, IBrishopFeeEscrow feeEscrow_) Ownable(initialOwner) {\n        if (address(feePolicy_) == address(0) || address(feeEscrow_) == address(0)) revert ZeroAddress();\n        feePolicy = feePolicy_;\n        feeEscrow = feeEscrow_;\n    }\n\n    /**\n     * @notice One-time wiring of the v2 factory, set after both are\n     * deployed, used to authorize each launch's bonding curve as a locker.\n     */\n    function setFactory(address factory_) external onlyOwner {\n        if (factory != address(0)) revert AlreadyInitialized();\n        if (factory_ == address(0)) revert ZeroAddress();\n        factory = factory_;\n        emit FactorySet(factory_);\n    }\n\n    /**\n     * @notice Permanently disabled. Ownership here exists only to perform the\n     * one-time factory wiring, and renouncing before that wiring would strand\n     * every future buyback lock.\n     */\n    function renounceOwnership() public pure override {\n        revert OwnershipCannotBeRenounced();\n    }\n\n    /**\n     * @notice Locks `amount` of `token` into its five-year vest, preserving\n     * the supplied beneficiaries and split for the active vesting epoch.\n     * Restricted to this token's registered Brishop curve, looked up live\n     * from the factory.\n     */\n    function lock(\n        address token,\n        uint256 amount,\n        address creatorRecipient,\n        address protocolRecipient,\n        uint16 protocolFeeShareBps\n    ) external nonReentrant {\n        if (token == address(0)) revert ZeroAddress();\n        if (factory == address(0)) revert NotFactory();\n        if (!_isAuthorizedLocker(token, msg.sender)) revert NotAuthorizedLocker();\n        if (amount == 0) return;\n        if (creatorRecipient == address(0) || protocolRecipient == address(0) || protocolFeeShareBps > BASIS_POINTS) {\n            revert InvalidVestingTerms();\n        }\n\n        // Schedule against what arrived, not what was asked for. Recording a\n        // nominal amount the vault never received would make the final\n        // release of the epoch revert on its own balance, stranding the tail\n        // of the vest. Every other ERC-20 boundary in the protocol measures\n        // this delta; this one is no different for being fed by our own\n        // launcher token today.\n        uint256 balanceBefore = IERC20(token).balanceOf(address(this));\n        IERC20(token).safeTransferFrom(msg.sender, address(this), amount);\n        amount = IERC20(token).balanceOf(address(this)) - balanceBefore;\n        if (amount == 0) return;\n\n        LaunchVest storage v = _vaults[token];\n        uint256 nowTs = block.timestamp;\n        _checkpoint(v, nowTs);\n        _setOrValidateVestingTerms(v, token, creatorRecipient, protocolRecipient, protocolFeeShareBps);\n\n        uint256 existingUnvested = v.unvestedAmount;\n        uint256 combinedAmount = existingUnvested + amount;\n        uint256 remainingDuration = existingUnvested == 0 ? 0 : v.vestingEnd - nowTs;\n        uint256 combinedDuration = (existingUnvested * remainingDuration + amount * VESTING_DURATION) / combinedAmount;\n\n        v.unvestedAmount = combinedAmount;\n        v.lastUpdate = nowTs;\n        v.vestingEnd = nowTs + combinedDuration;\n        v.vestingStart = nowTs - (VESTING_DURATION - combinedDuration);\n        v.totalLocked += amount;\n\n        emit Locked(token, msg.sender, amount, v.vestingStart);\n    }\n\n    /**\n     * @notice Releases every currently vested, not-yet-released token for\n     * `token`, using the beneficiaries and split frozen for its active\n     * vesting epoch.\n     * @dev Restricted to the two parties a release pays. Letting anyone\n     * choose when value leaves the vest is harmful in two ways. A caller can\n     * time a release inside the protocol owner's creator-recipient recovery\n     * window, flushing vested tokens to the very address the recovery exists\n     * to abandon. A caller can also advance the checkpoint every second, so\n     * each step rounds its newly vested amount down to zero and the vest\n     * stalls without ever paying out.\n     */\n    function release(address token) external nonReentrant returns (uint256 released) {\n        if (factory == address(0)) revert NotFactory();\n\n        LaunchVest storage v = _vaults[token];\n        if (msg.sender != v.creatorRecipient && msg.sender != v.protocolRecipient) revert NotVestBeneficiary();\n\n        _checkpoint(v, block.timestamp);\n        released = v.vestedUnreleased;\n        if (released == 0) return 0;\n        v.vestedUnreleased = 0;\n        v.totalReleased += released;\n\n        uint256 protocolAmount = (released * v.protocolFeeShareBps) / BASIS_POINTS;\n        uint256 creatorAmount = released - protocolAmount;\n\n        IERC20(token).forceApprove(address(feeEscrow), released);\n        if (protocolAmount != 0) feeEscrow.creditToken(v.protocolRecipient, token, protocolAmount);\n        if (creatorAmount != 0) feeEscrow.creditToken(v.creatorRecipient, token, creatorAmount);\n\n        emit Released(token, creatorAmount, protocolAmount);\n    }\n\n    /**\n     * @notice Redirects a launch's buyback vest to a new creator recipient.\n     * Restricted to the factory, which forwards both self-service creator\n     * transfers and protocol-owner recovery overrides here, so vested\n     * buyback tokens track the same recipient as immediate creator fees\n     * rather than remaining stranded on the launch-time address. Vested but\n     * not-yet-released tokens follow the new recipient too, matching the\n     * intent of wallet recovery. Only the protocol split terms stay bound to\n     * the launch snapshot; the creator identity is managed here instead.\n     */\n    function updateCreatorRecipient(address token, address newRecipient) external {\n        if (msg.sender != factory) revert NotFactory();\n        if (token == address(0) || newRecipient == address(0)) revert ZeroAddress();\n\n        LaunchVest storage v = _vaults[token];\n        address previousRecipient = v.creatorRecipient;\n        if (previousRecipient == newRecipient) return;\n        v.creatorRecipient = newRecipient;\n        emit CreatorRecipientUpdated(token, previousRecipient, newRecipient);\n    }\n\n    /**\n     * @notice Total amount of `token` ever locked into this vault.\n     */\n    function totalLocked(address token) external view returns (uint256) {\n        return _vaults[token].totalLocked;\n    }\n\n    /**\n     * @notice Total amount of `token` already released from this vault.\n     */\n    function totalReleased(address token) external view returns (uint256) {\n        return _vaults[token].totalReleased;\n    }\n\n    /**\n     * @notice The launch's current weighted-average vesting start time.\n     * @dev Reporting only. Vesting is accounted from `vestedUnreleased`,\n     * `unvestedAmount`, `lastUpdate` and `vestingEnd`, which are settled on\n     * every lock and release. Interpolating this value against\n     * `VESTING_DURATION` will not reproduce `vestedAmount`, because already\n     * vested tokens are banked at each deposit rather than recomputed from\n     * the shifted clock. Read `vestedAmount` for the authoritative figure.\n     */\n    function vestingStart(address token) external view returns (uint256) {\n        return _vaults[token].vestingStart;\n    }\n\n    /**\n     * @notice Amount of `token` vested so far, released or not.\n     */\n    function vestedAmount(address token) external view returns (uint256) {\n        return _vestedAmount(_vaults[token]);\n    }\n\n    /**\n     * @notice Amount of `token` currently releasable: vested but not yet released.\n     */\n    function releasable(address token) external view returns (uint256) {\n        LaunchVest storage v = _vaults[token];\n        return v.vestedUnreleased + _previewNewlyVested(v, block.timestamp);\n    }\n\n    /**\n     * @notice Returns the immutable terms for the token's active vesting epoch.\n     */\n    function vestingTerms(address token)\n        external\n        view\n        returns (address creatorRecipient, address protocolRecipient, uint16 protocolFeeShareBps)\n    {\n        LaunchVest storage v = _vaults[token];\n        return (v.creatorRecipient, v.protocolRecipient, v.protocolFeeShareBps);\n    }\n\n    /**\n     * @dev Linear vest over VESTING_DURATION from the launch's current\n     * weighted-average start time, capped at the total ever locked.\n     */\n    function _vestedAmount(LaunchVest storage v) private view returns (uint256) {\n        return v.totalReleased + v.vestedUnreleased + _previewNewlyVested(v, block.timestamp);\n    }\n\n    /**\n     * @dev Crystallizes the linear portion vested since the previous state\n     * update while preserving the existing schedule's maturity.\n     */\n    function _checkpoint(LaunchVest storage v, uint256 nowTs) private {\n        uint256 newlyVested = _previewNewlyVested(v, nowTs);\n        if (newlyVested != 0) {\n            v.unvestedAmount -= newlyVested;\n            v.vestedUnreleased += newlyVested;\n        }\n        v.lastUpdate = nowTs;\n    }\n\n    /**\n     * @dev Previews how much of the active schedule vested since lastUpdate.\n     */\n    function _previewNewlyVested(LaunchVest storage v, uint256 nowTs) private view returns (uint256) {\n        if (v.unvestedAmount == 0 || nowTs <= v.lastUpdate) return 0;\n        if (nowTs >= v.vestingEnd) return v.unvestedAmount;\n\n        uint256 remainingDuration = v.vestingEnd - v.lastUpdate;\n        uint256 elapsed = nowTs - v.lastUpdate;\n        return (v.unvestedAmount * elapsed) / remainingDuration;\n    }\n\n    /**\n     * @dev A new epoch begins only after every token in the prior epoch has\n     * been released. This keeps every active weighted-average vest bound to\n     * one immutable set of beneficiaries without unbounded tranche storage.\n     */\n    function _setOrValidateVestingTerms(\n        LaunchVest storage v,\n        address token,\n        address creatorRecipient,\n        address protocolRecipient,\n        uint16 protocolFeeShareBps\n    ) private {\n        bool newEpoch = v.unvestedAmount == 0 && v.vestedUnreleased == 0;\n        if (newEpoch) {\n            // Seed the buyback beneficiary only when it has never been set.\n            // Once the factory has redirected the vest through\n            // updateCreatorRecipient (a creator transfer or a protocol\n            // recovery override), a later lock must not silently reset it\n            // back to the launch-time recipient, even across a fresh epoch.\n            if (v.creatorRecipient == address(0)) {\n                v.creatorRecipient = creatorRecipient;\n            }\n            v.protocolRecipient = protocolRecipient;\n            v.protocolFeeShareBps = protocolFeeShareBps;\n            emit VestingTermsSnapshotted(token, v.creatorRecipient, protocolRecipient, protocolFeeShareBps);\n            return;\n        }\n\n        // The creator recipient is deliberately excluded from this check: it\n        // is managed independently through updateCreatorRecipient, so recovery\n        // can move the vest without ever bricking a subsequent lock on a terms\n        // mismatch. The protocol split terms remain immutable per launch.\n        if (v.protocolRecipient != protocolRecipient || v.protocolFeeShareBps != protocolFeeShareBps) {\n            revert VestingTermsMismatch();\n        }\n    }\n\n    /**\n     * @dev Only the token's own registered curve may lock its buybacks.\n     * No per-launch administrator action or shared external hook is needed.\n     */\n    function _isAuthorizedLocker(address token, address caller) private view returns (bool) {\n        if (factory == address(0)) return false;\n        return caller == IBrishopLaunchFactory(factory).getLaunchedToken(token).curve;\n    }\n}\n"},"src/interfaces/IBrishop.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\ninterface IBrishopFeeEscrow {\n    function credit(address recipient) external payable;\n    function creditToken(address recipient, address token, uint256 amount) external;\n    function claim() external returns (uint256);\n    function claim(uint256 amount) external returns (uint256);\n    function claimToken(address token) external returns (uint256);\n    function claimToken(address token, uint256 amount) external returns (uint256);\n    function balanceOf(address recipient) external view returns (uint256);\n    function balanceOfToken(address recipient, address token) external view returns (uint256);\n}\n\n// Names retained from PONS for fee-policy compatibility. buybackBurnBps funds\n// purchases locked in the five-year vault; it does not burn those tokens.\nstruct FeePolicySnapshot {\n    address protocolFeeRecipient;\n    uint16 protocolFeeShareBps;\n    uint16 buybackBurnBps;\n    uint16 hookFeeBps;\n    uint16 maxInternalPriceImpactBps;\n}\n\ninterface IBrishopFeePolicy {\n    function feeSweepOperator() external view returns (address);\n    function currentFeePolicy() external view returns (FeePolicySnapshot memory);\n}\n\ninterface IBrishopSnipeTax {\n    function snipeTaxStartBps() external view returns (uint256);\n    function snipeTaxSeconds() external view returns (uint256);\n}\n\ninterface IBrishopLaunchFactory {\n    struct LaunchedToken {\n        address token;\n        address curve;\n        address deployer;\n        address creatorFeeRecipient;\n        address pairToken;\n        uint16 creatorTaxBps;\n        bool buybackEnabled;\n        bool personality;\n        bool exists;\n    }\n    function getLaunchedToken(address token) external view returns (LaunchedToken memory);\n}\n"},"src/BrishopLaunchFactory.sol":{"content":"// SPDX-License-Identifier: MIT\n// PONS-derived launch/fee policy, with permanent Brishop markets. See ../NOTICE.md.\npragma solidity ^0.8.26;\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {BrishopFeeEscrow} from \"./BrishopFeeEscrow.sol\";\nimport {BrishopBuybackVault} from \"./BrishopBuybackVault.sol\";\nimport {BrishopLaunchDeployer, TokenParams} from \"./BrishopLaunchDeployer.sol\";\nimport {BrishopBondingCurve} from \"./BrishopBondingCurve.sol\";\nimport {FeePolicySnapshot, IBrishopFeePolicy, IBrishopFeeEscrow, IBrishopLaunchFactory} from \"./interfaces/IBrishop.sol\";\n\ninterface IEthUsdFeed {\n    function decimals() external view returns (uint8);\n    function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80);\n}\n\ncontract BrishopLaunchFactory is Ownable2Step, ReentrancyGuard, IBrishopFeePolicy, IBrishopLaunchFactory {\n    uint256 public constant SUPPLY = 1_000_000_000 ether;\n    uint256 public constant BASE_PHANTOM_ETH = 1.68 ether;\n    uint256 public constant CREATOR_RECOVERY_DELAY = 3 days;\n    uint256 public constant CREATOR_RECOVERY_WINDOW = 3 days;\n    uint256 public constant ORACLE_MAX_AGE = 1 days;\n    uint256 public launchFee = 0.0005 ether;\n    uint256 public maxCreatorTaxBps = 1_000;\n    uint256 public snipeTaxStartBps = 9_900;\n    uint256 public snipeTaxSeconds = 3;\n    address public feeSweepOperator;\n    address public launchForwarder;\n    BrishopFeeEscrow public immutable feeEscrow;\n    BrishopBuybackVault public immutable buybackVault;\n    BrishopLaunchDeployer public immutable launchDeployer;\n    IEthUsdFeed public immutable ethUsdFeed;\n    uint8 public immutable oracleDecimals;\n    FeePolicySnapshot private _policy;\n    mapping(address => LaunchedToken) private _launches;\n    mapping(address => FeePolicySnapshot) private _launchPolicies;\n    address[] private _tokens;\n    mapping(bytes32 => address) public personalities;\n    mapping(address => mapping(bytes32 => bool)) public usedSalt;\n    struct PairEconomics { uint256 phantomQuote; bool enabled; }\n    mapping(address => PairEconomics) public pairEconomics;\n    struct PendingRecipient { address recipient; uint256 effectiveAt; uint256 expiresAt; }\n    mapping(address => PendingRecipient) public pendingCreatorFeeRecipient;\n\n    error ZeroAddress();\n    error AlreadySet();\n    error PairTokenNotApproved();\n    error LaunchEconomicsMismatch();\n    error LaunchFeeNotPaid();\n    error CreatorTaxTooHigh();\n    error InvalidTerms();\n    error SaltAlreadyUsed();\n    error UnknownToken();\n    error NotLaunchForwarder();\n    error NotCreatorFeeRecipient();\n    error InvalidOraclePrice();\n    error InvalidPersonalityValuation();\n    error DuplicatePersonality();\n    error RecoveryNotExecutable();\n    event TokenLaunched(address indexed token, address indexed curve, address indexed deployer, address pairToken, uint256 phantomQuote, bool personality, uint256 creatorAllocation);\n    event PersonalityLaunched(bytes32 indexed id, address indexed token, uint256 targetFdvUsd, uint256 ethUsdAnswer);\n    event PairEconomicsUpdated(address indexed pairToken, uint256 phantomQuote, bool enabled);\n    event LaunchForwarderSet(address forwarder);\n    event TermsUpdated();\n    event FeeSweepOperatorUpdated(address operator);\n    event CreatorFeeRecipientUpdated(address indexed token, address indexed oldRecipient, address indexed newRecipient);\n    event CreatorFeeRecipientChangeProposed(address indexed token, address recipient, uint256 effectiveAt, uint256 expiresAt);\n    event CreatorFeeRecipientChangeCancelled(address indexed token);\n\n    constructor(address initialOwner, IEthUsdFeed feed) Ownable(initialOwner) {\n        if (address(feed).code.length == 0) revert ZeroAddress();\n        ethUsdFeed = feed;\n        uint8 decimals_ = feed.decimals();\n        if (decimals_ > 18) revert InvalidOraclePrice();\n        oracleDecimals = decimals_;\n        feeSweepOperator = initialOwner;\n        _policy = FeePolicySnapshot(initialOwner, 3_000, 5_000, 100, 300);\n        feeEscrow = new BrishopFeeEscrow();\n        buybackVault = new BrishopBuybackVault(address(this), IBrishopFeePolicy(address(this)), IBrishopFeeEscrow(address(feeEscrow)));\n        buybackVault.setFactory(address(this));\n        launchDeployer = new BrishopLaunchDeployer(address(this), IBrishopFeeEscrow(address(feeEscrow)), buybackVault);\n        pairEconomics[address(0)] = PairEconomics(BASE_PHANTOM_ETH, true);\n    }\n\n    function currentFeePolicy() external view returns (FeePolicySnapshot memory) { return _policy; }\n    function getLaunchFeePolicy(address token) external view returns (FeePolicySnapshot memory) { _requireLaunch(token); return _launchPolicies[token]; }\n    function getLaunchedToken(address token) external view returns (LaunchedToken memory) { return _launches[token]; }\n    function launchCount() external view returns (uint256) { return _tokens.length; }\n    function launchedTokenAt(uint256 index) external view returns (address) { return _tokens[index]; }\n    function canLaunch(address) external pure returns (bool) { return true; }\n\n    function previewLaunchEconomics(address pairToken) public view returns (bytes32) {\n        PairEconomics memory pair = pairEconomics[pairToken];\n        if (!pair.enabled) revert PairTokenNotApproved();\n        return _economicsHash(pairToken, pair.phantomQuote, false);\n    }\n\n    function previewPersonalityEconomics(uint256 targetFdvUsd) public view returns (bytes32 economics, uint256 phantomQuote, uint256 price) {\n        if (targetFdvUsd < 18_000 || targetFdvUsd > 25_000) revert InvalidPersonalityValuation();\n        (, int256 answer,, uint256 updatedAt,) = ethUsdFeed.latestRoundData();\n        if (answer <= 0 || updatedAt == 0 || updatedAt > block.timestamp || block.timestamp - updatedAt > ORACLE_MAX_AGE) revert InvalidOraclePrice();\n        price = uint256(answer);\n        // 75% inventory: FDV = phantomQuote / 0.75 * ETH/USD.\n        phantomQuote = Math.mulDiv(targetFdvUsd * 1 ether, 3 * 10 ** oracleDecimals, 4 * price);\n        if (phantomQuote == 0 || phantomQuote > type(uint128).max) revert InvalidPersonalityValuation();\n        economics = _economicsHash(address(0), phantomQuote, true);\n    }\n\n    function _economicsHash(address pairToken, uint256 phantomQuote, bool personality) private view returns (bytes32) {\n        return keccak256(abi.encode(block.chainid, address(this), SUPPLY, pairToken, phantomQuote, personality, launchFee, maxCreatorTaxBps, snipeTaxStartBps, snipeTaxSeconds, _policy));\n    }\n\n    function launchToken(TokenParams calldata params, address pairToken) external payable nonReentrant returns (address token, address curve) {\n        return _launchCommunity(params, pairToken, msg.sender);\n    }\n    function launchTokenFor(TokenParams calldata params, address pairToken, address creator) external payable nonReentrant returns (address token, address curve) {\n        if (msg.sender != launchForwarder || creator == address(0)) revert NotLaunchForwarder();\n        return _launchCommunity(params, pairToken, creator);\n    }\n    function _launchCommunity(TokenParams calldata params, address pairToken, address creator) private returns (address token, address curve) {\n        if (params.expectedEconomics != previewLaunchEconomics(pairToken)) revert LaunchEconomicsMismatch();\n        return _launch(params, pairToken, creator, pairEconomics[pairToken].phantomQuote, false);\n    }\n\n    /// @notice Only the administrator may mint a personality. The 25% allocation\n    /// goes directly to that administrator, is transferable, and receives no ETH.\n    function launchPersonality(TokenParams calldata params, bytes32 id, uint256 targetFdvUsd) external payable onlyOwner nonReentrant returns (address token, address curve) {\n        if (id == bytes32(0) || personalities[id] != address(0)) revert DuplicatePersonality();\n        (bytes32 economics, uint256 phantomQuote, uint256 price) = previewPersonalityEconomics(targetFdvUsd);\n        if (params.expectedEconomics != economics) revert LaunchEconomicsMismatch();\n        (token, curve) = _launch(params, address(0), msg.sender, phantomQuote, true);\n        personalities[id] = token;\n        uint256 quotePhantom = Math.mulDiv(BASE_PHANTOM_ETH, SUPPLY * 3 / 4, phantomQuote);\n        pairEconomics[token] = PairEconomics(quotePhantom, true);\n        emit PairEconomicsUpdated(token, quotePhantom, true);\n        emit PersonalityLaunched(id, token, targetFdvUsd, price);\n    }\n\n    function _launch(TokenParams calldata params, address pairToken, address creator, uint256 phantomQuote, bool personality) private returns (address token, address curve) {\n        if (msg.value != launchFee) revert LaunchFeeNotPaid();\n        if (params.creatorTaxBps > maxCreatorTaxBps || uint256(params.creatorTaxBps) + _policy.hookFeeBps > 2_000) revert CreatorTaxTooHigh();\n        if (usedSalt[creator][params.salt]) revert SaltAlreadyUsed();\n        if (params.snipeTaxExemptions.length > 32) revert InvalidTerms();\n        usedSalt[creator][params.salt] = true;\n        address recipient = params.creatorFeeRecipient == address(0) ? creator : params.creatorFeeRecipient;\n        uint256 allocation = personality ? SUPPLY / 4 : 0;\n        BrishopBondingCurve.Terms memory terms = BrishopBondingCurve.Terms(pairToken, recipient, phantomQuote, _policy.hookFeeBps, params.creatorTaxBps, params.buybackEnabled);\n        (token, curve) = launchDeployer.deployLaunch(params, terms, _policy, creator, SUPPLY, allocation);\n        _launches[token] = LaunchedToken(token, curve, creator, recipient, pairToken, params.creatorTaxBps, params.buybackEnabled, personality, true);\n        _launchPolicies[token] = _policy;\n        _tokens.push(token);\n        address[] memory exemptions = new address[](params.snipeTaxExemptions.length + 2);\n        exemptions[0] = creator;\n        exemptions[1] = recipient;\n        for (uint256 i; i < params.snipeTaxExemptions.length; ++i) exemptions[i + 2] = params.snipeTaxExemptions[i];\n        BrishopBondingCurve(curve).initialize(token, exemptions);\n        if (launchFee != 0) feeEscrow.credit{value: launchFee}(_policy.protocolFeeRecipient);\n        emit TokenLaunched(token, curve, creator, pairToken, phantomQuote, personality, allocation);\n    }\n\n    function setLaunchForwarder(address forwarder) external onlyOwner {\n        if (launchForwarder != address(0)) revert AlreadySet();\n        if (forwarder.code.length == 0) revert ZeroAddress();\n        launchForwarder = forwarder;\n        emit LaunchForwarderSet(forwarder);\n    }\n    function setFeeSweepOperator(address operator) external onlyOwner {\n        if (operator == address(0)) revert ZeroAddress();\n        feeSweepOperator = operator;\n        emit FeeSweepOperatorUpdated(operator);\n    }\n    /// @notice Updates terms for future launches only; existing curves snapshot them.\n    function setLaunchTerms(uint256 newLaunchFee, uint256 creatorTaxMax, uint256 snipeStart, uint256 snipeWindow, FeePolicySnapshot calldata policy) external onlyOwner {\n        if (creatorTaxMax > 1_000 || snipeStart > 9_900 || snipeWindow == 0 || snipeWindow > 1 days || policy.protocolFeeRecipient == address(0) || policy.protocolFeeShareBps > 10_000 || policy.buybackBurnBps > 10_000 || policy.hookFeeBps > 1_000 || policy.maxInternalPriceImpactBps == 0 || policy.maxInternalPriceImpactBps >= 10_000) revert InvalidTerms();\n        launchFee = newLaunchFee; maxCreatorTaxBps = creatorTaxMax; snipeTaxStartBps = snipeStart; snipeTaxSeconds = snipeWindow; _policy = policy;\n        emit TermsUpdated();\n    }\n    function setPairEconomics(address pairToken, uint256 phantomQuote, bool enabled) external onlyOwner {\n        if (pairToken != address(0) && !_launches[pairToken].personality) revert PairTokenNotApproved();\n        if (phantomQuote == 0 || phantomQuote > type(uint128).max) revert InvalidTerms();\n        pairEconomics[pairToken] = PairEconomics(phantomQuote, enabled);\n        emit PairEconomicsUpdated(pairToken, phantomQuote, enabled);\n    }\n    function setBuybackEnabled(address token, bool enabled) external {\n        LaunchedToken storage launch = _requireLaunch(token);\n        if (msg.sender != launch.creatorFeeRecipient && (msg.sender != owner() || enabled)) revert NotCreatorFeeRecipient();\n        launch.buybackEnabled = enabled;\n        BrishopBondingCurve(launch.curve).setBuybackEnabled(enabled);\n    }\n    function transferCreatorFeeRecipient(address token, address recipient) external {\n        LaunchedToken storage launch = _requireLaunch(token);\n        if (msg.sender != launch.creatorFeeRecipient) revert NotCreatorFeeRecipient();\n        _updateRecipient(token, recipient);\n    }\n    function proposeCreatorFeeRecipient(address token, address recipient) external onlyOwner {\n        _requireLaunch(token);\n        if (recipient == address(0)) revert ZeroAddress();\n        uint256 effective = block.timestamp + CREATOR_RECOVERY_DELAY;\n        pendingCreatorFeeRecipient[token] = PendingRecipient(recipient, effective, effective + CREATOR_RECOVERY_WINDOW);\n        emit CreatorFeeRecipientChangeProposed(token, recipient, effective, effective + CREATOR_RECOVERY_WINDOW);\n    }\n    function cancelCreatorFeeRecipientChange(address token) external onlyOwner {\n        delete pendingCreatorFeeRecipient[token];\n        emit CreatorFeeRecipientChangeCancelled(token);\n    }\n    function executeCreatorFeeRecipientChange(address token) external onlyOwner {\n        PendingRecipient memory pending = pendingCreatorFeeRecipient[token];\n        if (pending.recipient == address(0) || block.timestamp < pending.effectiveAt || block.timestamp > pending.expiresAt) revert RecoveryNotExecutable();\n        delete pendingCreatorFeeRecipient[token];\n        _updateRecipient(token, pending.recipient);\n    }\n    function _updateRecipient(address token, address recipient) private {\n        if (recipient == address(0)) revert ZeroAddress();\n        LaunchedToken storage launch = _requireLaunch(token);\n        address previous = launch.creatorFeeRecipient;\n        launch.creatorFeeRecipient = recipient;\n        BrishopBondingCurve(launch.curve).setCreatorFeeRecipient(recipient);\n        buybackVault.updateCreatorRecipient(token, recipient);\n        emit CreatorFeeRecipientUpdated(token, previous, recipient);\n    }\n    function _requireLaunch(address token) private view returns (LaunchedToken storage launch) {\n        launch = _launches[token];\n        if (!launch.exists) revert UnknownToken();\n    }\n}\n"},"src/BrishopLauncherToken.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from the MIT PONS v2 verified source. See ../NOTICE.md.\npragma solidity ^0.8.26;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {ERC20Burnable} from \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\n\n/**\n * @title BrishopLauncherToken\n * @notice Fixed-supply ERC-20 deployed by BrishopLaunchFactory for a v2 launch.\n * Community supply mints to the curve. An administrator personality launch\n * assigns 25% to its creator and 75% to the curve. Purchases are limited by\n * curve pricing and inventory. `deployer` is carried here\n * as immutable reference data for off-chain attribution only, and confers no\n * privileges over the token.\n * `ERC20Burnable` lets any holder voluntarily burn their own balance; the\n * protocol's buyback mechanism does not use it, bought-back tokens are\n * locked into `BrishopBuybackVault` for a five-year vest instead of being\n * burned.\n */\ncontract BrishopLauncherToken is ERC20, ERC20Burnable {\n    struct Socials {\n        string twitter;\n        string telegram;\n        string discord;\n        string website;\n        string farcaster;\n    }\n\n    error ZeroAddress();\n    error InvalidAllocation();\n\n    address public immutable deployer;\n    address public immutable launchFactory;\n    address public immutable curve;\n    uint256 public immutable initialSupply;\n    uint256 public immutable initialCreatorAllocation;\n\n    string public logo;\n    string public description;\n\n    Socials private _socials;\n\n    /**\n     * @notice Mints the fixed initial supply between the curve and creator allocation.\n     */\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        string memory logo_,\n        string memory description_,\n        Socials memory socials_,\n        address deployer_,\n        address curve_,\n        address launchFactory_,\n        uint256 supply_,\n        uint256 creatorAllocation_\n    ) ERC20(name_, symbol_) {\n        if (deployer_ == address(0) || curve_ == address(0) || launchFactory_ == address(0)) {\n            revert ZeroAddress();\n        }\n\n        deployer = deployer_;\n        // Passed explicitly rather than read from msg.sender: BrishopLaunchFactory\n        // deploys this token indirectly through BrishopLaunchDeployer to keep its\n        // own bytecode under EIP-170's size limit, so msg.sender at construction\n        // time would otherwise resolve to that deployer helper, not the factory.\n        launchFactory = launchFactory_;\n        curve = curve_;\n        if (supply_ == 0 || creatorAllocation_ > supply_ / 4) revert InvalidAllocation();\n        initialSupply = supply_;\n        initialCreatorAllocation = creatorAllocation_;\n        logo = logo_;\n        description = description_;\n        _socials = socials_;\n\n        _mint(curve_, supply_ - creatorAllocation_);\n        if (creatorAllocation_ != 0) _mint(deployer_, creatorAllocation_);\n    }\n\n    /**\n     * @notice Returns the launch token's five social metadata fields.\n     */\n    function socials()\n        external\n        view\n        returns (\n            string memory twitter,\n            string memory telegram,\n            string memory discord,\n            string memory website,\n            string memory farcaster\n        )\n    {\n        Socials memory values = _socials;\n        return (values.twitter, values.telegram, values.discord, values.website, values.farcaster);\n    }\n\n    /**\n     * @notice Returns creator and metadata in the launcher-compatible tuple.\n     */\n    function getTokenInfo()\n        external\n        view\n        returns (\n            address tokenDeployer,\n            string memory tokenLogo,\n            string memory tokenDescription,\n            Socials memory tokenSocials\n        )\n    {\n        return (deployer, logo, description, _socials);\n    }\n}\n"},"src/BrishopLaunchDeployer.sol":{"content":"// SPDX-License-Identifier: MIT\n// Deployment/metadata pattern derived from PONS v2; see ../NOTICE.md.\npragma solidity ^0.8.26;\nimport {BrishopLauncherToken} from \"./BrishopLauncherToken.sol\";\nimport {BrishopBondingCurve} from \"./BrishopBondingCurve.sol\";\nimport {BrishopBuybackVault} from \"./BrishopBuybackVault.sol\";\nimport {FeePolicySnapshot, IBrishopFeeEscrow} from \"./interfaces/IBrishop.sol\";\n\nstruct TokenParams {\n    string name;\n    string symbol;\n    string logo;\n    string description;\n    BrishopLauncherToken.Socials socials;\n    address creatorFeeRecipient;\n    uint16 creatorTaxBps;\n    bool buybackEnabled;\n    bytes32 expectedEconomics;\n    bytes32 salt;\n    address[] snipeTaxExemptions;\n}\n\ncontract BrishopLaunchDeployer {\n    error NotFactory();\n    error InvalidMetadata();\n    address public immutable factory;\n    IBrishopFeeEscrow public immutable feeEscrow;\n    BrishopBuybackVault public immutable buybackVault;\n    constructor(address factory_, IBrishopFeeEscrow escrow_, BrishopBuybackVault vault_) {\n        factory = factory_; feeEscrow = escrow_; buybackVault = vault_;\n    }\n    function deployLaunch(TokenParams calldata params, BrishopBondingCurve.Terms calldata terms, FeePolicySnapshot calldata policy, address creator, uint256 supply, uint256 creatorAllocation) external returns (address token, address curve) {\n        if (msg.sender != factory) revert NotFactory();\n        _checkMetadata(params);\n        bytes32 salt = keccak256(abi.encode(creator, params.salt));\n        curve = address(new BrishopBondingCurve{salt: salt}(factory, feeEscrow, buybackVault, policy, terms));\n        token = address(new BrishopLauncherToken{salt: salt}(params.name, params.symbol, params.logo, params.description, params.socials, creator, curve, factory, supply, creatorAllocation));\n    }\n    function _checkMetadata(TokenParams calldata p) private pure {\n        if (bytes(p.name).length == 0 || bytes(p.name).length > 64 || bytes(p.symbol).length == 0 || bytes(p.symbol).length > 16 || bytes(p.logo).length > 512 || bytes(p.description).length > 2048) revert InvalidMetadata();\n        if (bytes(p.socials.twitter).length > 256 || bytes(p.socials.telegram).length > 256 || bytes(p.socials.discord).length > 256 || bytes(p.socials.website).length > 256 || bytes(p.socials.farcaster).length > 256) revert InvalidMetadata();\n    }\n}\n"},"@openzeppelin/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"},"@openzeppelin/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"},"src/libraries/BrishopBondingCurveMath.sol":{"content":"// SPDX-License-Identifier: MIT\n// Derived from the MIT PONS v2 verified source. See ../NOTICE.md.\npragma solidity ^0.8.26;\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/**\n * @title BrishopBondingCurveMath\n * @notice Constant-product bonding curve math shared by BrishopBondingCurve, adapted\n * from the BootstrapPool.sol reference (code-423n4/2025-01-iq-ai). Reserves and fee\n * are passed explicitly so the same formula prices trades in either direction and can\n * also price the curve's internal buyback swap.\n */\nlibrary BrishopBondingCurveMath {\n    uint256 internal constant BASIS_POINTS = 10_000;\n\n    error InsufficientInputAmount();\n    error InsufficientOutputAmount();\n    error InsufficientLiquidity();\n    error ReserveLimit();\n\n    /**\n     * @notice Quotes the output amount for an exact input amount, net of the trade fee.\n     * @param amountIn Exact amount of the input asset being sold into the curve.\n     * @param reserveIn Curve reserve of the input asset before this trade.\n     * @param reserveOut Curve reserve of the output asset before this trade.\n     * @param feeBps Fee charged on the input amount, in basis points.\n     */\n    function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeBps)\n        internal\n        pure\n        returns (uint256 amountOut)\n    {\n        if (amountIn == 0) revert InsufficientInputAmount();\n        if (reserveIn == 0 || reserveOut == 0) revert InsufficientLiquidity();\n\n        amountOut = _amountOut(amountIn, reserveIn, reserveOut, feeBps);\n        if (amountOut == 0) revert InsufficientOutputAmount();\n    }\n\n    /**\n     * @notice Same quote as `getAmountOut`, returning zero where that reverts.\n     * @dev For callers that treat an unpriceable trade as a condition to\n     * handle rather than an error, such as the curve's internal buyback,\n     * which folds the slice back into the creator's payout when the curve is\n     * too thin to execute against. Routing that case through the reverting\n     * variant would take the whole fee sweep down with it, stranding fees\n     * exactly when the curve cannot support a buyback.\n     */\n    function quoteAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeBps)\n        internal\n        pure\n        returns (uint256 amountOut)\n    {\n        if (amountIn == 0 || reserveIn == 0 || reserveOut == 0 || feeBps >= BASIS_POINTS) return 0;\n        return _amountOut(amountIn, reserveIn, reserveOut, feeBps);\n    }\n\n    function _amountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeBps)\n        private\n        pure\n        returns (uint256)\n    {\n        if (amountIn > type(uint128).max || reserveIn > type(uint128).max || reserveOut > type(uint128).max) revert ReserveLimit();\n        uint256 amountInWithFee = amountIn * (BASIS_POINTS - feeBps);\n        uint256 denominator = reserveIn * BASIS_POINTS + amountInWithFee;\n        return Math.mulDiv(amountInWithFee, reserveOut, denominator);\n    }\n\n    /**\n     * @notice Quotes the input amount required for an exact output amount, net of the trade fee.\n     * @param amountOut Exact amount of the output asset requested from the curve.\n     * @param reserveIn Curve reserve of the input asset before this trade.\n     * @param reserveOut Curve reserve of the output asset before this trade.\n     * @param feeBps Fee charged on the input amount, in basis points.\n     */\n    function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut, uint256 feeBps)\n        internal\n        pure\n        returns (uint256 amountIn)\n    {\n        if (amountOut == 0) revert InsufficientOutputAmount();\n        if (reserveIn == 0 || reserveOut <= amountOut) revert InsufficientLiquidity();\n        // A full-fee trade has no input that produces output, and the\n        // denominator below would divide by zero rather than say so.\n        if (feeBps >= BASIS_POINTS) revert InsufficientLiquidity();\n\n        if (amountOut > type(uint128).max || reserveIn > type(uint128).max || reserveOut > type(uint128).max) revert ReserveLimit();\n        uint256 denominator = (reserveOut - amountOut) * (BASIS_POINTS - feeBps);\n        amountIn = Math.mulDiv(amountOut, reserveIn * BASIS_POINTS, denominator) + 1;\n    }\n}\n"},"@openzeppelin/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"},"@openzeppelin/contracts/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.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 Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = 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 = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a 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            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\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            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\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            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `condition ? a : b`. 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. `condition ? a : b`) 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        unchecked {\n            // (a + b) / 2 can overflow.\n            return (a & b) + (a ^ b) / 2;\n        }\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            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 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 low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\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 [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, 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 (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, 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 high into low.\n            low |= high * 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 high\n            // is no longer required.\n            result = low * 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 Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 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 buffer) private pure returns (bool) {\n        uint256 chunk;\n        for (uint256 i = 0; i < buffer.length; i += 0x20) {\n            // See _unsafeReadBytesOffset from utils/Bytes.sol\n            assembly (\"memory-safe\") {\n                chunk := mload(add(add(buffer, 0x20), i))\n            }\n            if (chunk >> (8 * saturatingSub(i + 0x20, buffer.length)) != 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 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the first 16 bytes (most significant half).\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\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 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\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    /**\n     * @dev Counts the number of leading zero bits in a uint256.\n     */\n    function clz(uint256 x) internal pure returns (uint256) {\n        return ternary(x == 0, 256, 255 - log2(x));\n    }\n}\n"},"@openzeppelin/contracts/interfaces/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\n"},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.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     * Both values are immutable: they can only be set once during 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    /// @inheritdoc IERC20\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /// @inheritdoc IERC20\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    /// @inheritdoc IERC20\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 sets 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"},"@openzeppelin/contracts/utils/StorageSlot.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},"@openzeppelin/contracts/interfaces/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)\n\npragma solidity >=0.4.16;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\n"},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)\n\npragma solidity >=0.4.16;\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"},"@openzeppelin/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"},"@openzeppelin/contracts/interfaces/IERC1363.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)\n\npragma solidity >=0.6.2;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n"},"@openzeppelin/contracts/utils/math/SafeCast.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.6.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 a uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in a 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 A 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"},"@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\nimport {StorageSlot} from \"./StorageSlot.sol\";\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 *\n * IMPORTANT: Deprecated. This storage-based reentrancy guard will be removed and replaced\n * by the {ReentrancyGuardTransient} variant in v6.0.\n *\n * @custom:stateless\n */\nabstract contract ReentrancyGuard {\n    using StorageSlot for bytes32;\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant REENTRANCY_GUARD_STORAGE =\n        0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\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    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _reentrancyGuardStorageSlot().getUint256Slot().value = 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    /**\n     * @dev A `view` only version of {nonReentrant}. Use to block view functions\n     * from being called, preventing reading from inconsistent contract state.\n     *\n     * CAUTION: This is a \"view\" modifier and does not change the reentrancy\n     * status. Use it only on view functions. For payable or non-payable functions,\n     * use the standard {nonReentrant} modifier instead.\n     */\n    modifier nonReentrantView() {\n        _nonReentrantBeforeView();\n        _;\n    }\n\n    function _nonReentrantBeforeView() private view {\n        if (_reentrancyGuardEntered()) {\n            revert ReentrancyGuardReentrantCall();\n        }\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        _nonReentrantBeforeView();\n\n        // Any calls to nonReentrant after this point will fail\n        _reentrancyGuardStorageSlot().getUint256Slot().value = 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        _reentrancyGuardStorageSlot().getUint256Slot().value = 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 _reentrancyGuardStorageSlot().getUint256Slot().value == ENTERED;\n    }\n\n    function _reentrancyGuardStorageSlot() internal pure virtual returns (bytes32) {\n        return REENTRANCY_GUARD_STORAGE;\n    }\n}\n"},"@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (interfaces/draft-IERC6093.sol)\n\npragma solidity >=0.8.4;\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-721.\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"},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        if (!_safeTransfer(token, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        if (!_safeTransferFrom(token, from, to, value, true)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _safeTransfer(token, to, value, false);\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _safeTransferFrom(token, from, to, value, false);\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        if (!_safeApprove(token, spender, value, false)) {\n            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));\n            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the\n     * return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.transfer.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(to, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return\n     * value: the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param from The sender of the tokens\n     * @param to The recipient of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value,\n        bool bubble\n    ) private returns (bool success) {\n        bytes4 selector = IERC20.transferFrom.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(from, shr(96, not(0))))\n            mstore(0x24, and(to, shr(96, not(0))))\n            mstore(0x44, value)\n            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n            mstore(0x60, 0)\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:\n     * the return value is optional (but if data is returned, it must not be false).\n     *\n     * @param token The token targeted by the call.\n     * @param spender The spender of the tokens\n     * @param value The amount of token to transfer\n     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.\n     */\n    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {\n        bytes4 selector = IERC20.approve.selector;\n\n        assembly (\"memory-safe\") {\n            let fmp := mload(0x40)\n            mstore(0x00, selector)\n            mstore(0x04, and(spender, shr(96, not(0))))\n            mstore(0x24, value)\n            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)\n            // if call success and return is true, all is good.\n            // otherwise (not success or return is not true), we need to perform further checks\n            if iszero(and(success, eq(mload(0x00), 1))) {\n                // if the call was a failure and bubble is enabled, bubble the error\n                if and(iszero(success), bubble) {\n                    returndatacopy(fmp, 0x00, returndatasize())\n                    revert(fmp, returndatasize())\n                }\n                // if the return value is not true, then the call is only successful if:\n                // - the token address has code\n                // - the returndata is empty\n                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))\n            }\n            mstore(0x40, fmp)\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ERC20} from \"../ERC20.sol\";\nimport {Context} from \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n    /**\n     * @dev Destroys a `value` amount of tokens from the caller.\n     *\n     * See {ERC20-_burn}.\n     */\n    function burn(uint256 value) public virtual {\n        _burn(_msgSender(), value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, deducting from\n     * the caller's allowance.\n     *\n     * See {ERC20-_burn} and {ERC20-allowance}.\n     *\n     * Requirements:\n     *\n     * - the caller must have allowance for ``accounts``'s tokens of at least\n     * `value`.\n     */\n    function burnFrom(address account, uint256 value) public virtual {\n        _spendAllowance(account, _msgSender(), value);\n        _burn(account, value);\n    }\n}\n"},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity >=0.6.2;\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":true,"optimizer":{"runs":200,"enabled":true},"evmVersion":"cancun"}},"stdJsonOutput":{"sources":{"src/BrishopFeeEscrow.sol":{"id":20},"src/BrishopBondingCurve.sol":{"id":18},"src/BrishopBuybackVault.sol":{"id":19},"src/interfaces/IBrishop.sol":{"id":25},"src/BrishopLaunchFactory.sol":{"id":23},"src/BrishopLauncherToken.sol":{"id":24},"src/BrishopLaunchDeployer.sol":{"id":22},"@openzeppelin/contracts/utils/Panic.sol":{"id":12},"@openzeppelin/contracts/utils/Context.sol":{"id":11},"src/libraries/BrishopBondingCurveMath.sol":{"id":26},"@openzeppelin/contracts/access/Ownable.sol":{"id":0},"@openzeppelin/contracts/utils/math/Math.sol":{"id":16},"@openzeppelin/contracts/interfaces/IERC20.sol":{"id":4},"@openzeppelin/contracts/token/ERC20/ERC20.sol":{"id":6},"@openzeppelin/contracts/utils/StorageSlot.sol":{"id":14},"@openzeppelin/contracts/interfaces/IERC165.sol":{"id":3},"@openzeppelin/contracts/token/ERC20/IERC20.sol":{"id":7},"@openzeppelin/contracts/access/Ownable2Step.sol":{"id":1},"@openzeppelin/contracts/interfaces/IERC1363.sol":{"id":2},"@openzeppelin/contracts/utils/math/SafeCast.sol":{"id":17},"@openzeppelin/contracts/utils/ReentrancyGuard.sol":{"id":13},"@openzeppelin/contracts/interfaces/draft-IERC6093.sol":{"id":5},"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol":{"id":10},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"id":15},"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol":{"id":8},"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol":{"id":9}},"contracts":{"src/BrishopLaunchFactory.sol":{"BrishopLaunchFactory":{"abi":[{"type":"constructor","inputs":[{"name":"initialOwner","type":"address","internalType":"address"},{"name":"feed","type":"address","internalType":"contract IEthUsdFeed"}],"stateMutability":"nonpayable"},{"name":"AlreadySet","type":"error","inputs":[]},{"name":"CreatorTaxTooHigh","type":"error","inputs":[]},{"name":"DuplicatePersonality","type":"error","inputs":[]},{"name":"InvalidOraclePrice","type":"error","inputs":[]},{"name":"InvalidPersonalityValuation","type":"error","inputs":[]},{"name":"InvalidTerms","type":"error","inputs":[]},{"name":"LaunchEconomicsMismatch","type":"error","inputs":[]},{"name":"LaunchFeeNotPaid","type":"error","inputs":[]},{"name":"NotCreatorFeeRecipient","type":"error","inputs":[]},{"name":"NotLaunchForwarder","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":"PairTokenNotApproved","type":"error","inputs":[]},{"name":"RecoveryNotExecutable","type":"error","inputs":[]},{"name":"ReentrancyGuardReentrantCall","type":"error","inputs":[]},{"name":"SaltAlreadyUsed","type":"error","inputs":[]},{"name":"UnknownToken","type":"error","inputs":[]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"CreatorFeeRecipientChangeCancelled","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"CreatorFeeRecipientChangeProposed","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"recipient","type":"address","indexed":false,"internalType":"address"},{"name":"effectiveAt","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"expiresAt","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"CreatorFeeRecipientUpdated","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"oldRecipient","type":"address","indexed":true,"internalType":"address"},{"name":"newRecipient","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"FeeSweepOperatorUpdated","type":"event","inputs":[{"name":"operator","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"LaunchForwarderSet","type":"event","inputs":[{"name":"forwarder","type":"address","indexed":false,"internalType":"address"}],"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":"PairEconomicsUpdated","type":"event","inputs":[{"name":"pairToken","type":"address","indexed":true,"internalType":"address"},{"name":"phantomQuote","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"enabled","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"PersonalityLaunched","type":"event","inputs":[{"name":"id","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"targetFdvUsd","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"ethUsdAnswer","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"TermsUpdated","type":"event","inputs":[],"anonymous":false},{"name":"TokenLaunched","type":"event","inputs":[{"name":"token","type":"address","indexed":true,"internalType":"address"},{"name":"curve","type":"address","indexed":true,"internalType":"address"},{"name":"deployer","type":"address","indexed":true,"internalType":"address"},{"name":"pairToken","type":"address","indexed":false,"internalType":"address"},{"name":"phantomQuote","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"personality","type":"bool","indexed":false,"internalType":"bool"},{"name":"creatorAllocation","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"BASE_PHANTOM_ETH","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"CREATOR_RECOVERY_DELAY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"CREATOR_RECOVERY_WINDOW","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"ORACLE_MAX_AGE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"acceptOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"buybackVault","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract BrishopBuybackVault"}],"stateMutability":"view"},{"name":"canLaunch","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"pure"},{"name":"cancelCreatorFeeRecipientChange","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"currentFeePolicy","type":"function","inputs":[],"outputs":[{"name":"","type":"tuple","components":[{"name":"protocolFeeRecipient","type":"address","internalType":"address"},{"name":"protocolFeeShareBps","type":"uint16","internalType":"uint16"},{"name":"buybackBurnBps","type":"uint16","internalType":"uint16"},{"name":"hookFeeBps","type":"uint16","internalType":"uint16"},{"name":"maxInternalPriceImpactBps","type":"uint16","internalType":"uint16"}],"internalType":"struct FeePolicySnapshot"}],"stateMutability":"view"},{"name":"ethUsdFeed","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IEthUsdFeed"}],"stateMutability":"view"},{"name":"executeCreatorFeeRecipientChange","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"feeEscrow","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract BrishopFeeEscrow"}],"stateMutability":"view"},{"name":"feeSweepOperator","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"getLaunchFeePolicy","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"protocolFeeRecipient","type":"address","internalType":"address"},{"name":"protocolFeeShareBps","type":"uint16","internalType":"uint16"},{"name":"buybackBurnBps","type":"uint16","internalType":"uint16"},{"name":"hookFeeBps","type":"uint16","internalType":"uint16"},{"name":"maxInternalPriceImpactBps","type":"uint16","internalType":"uint16"}],"internalType":"struct FeePolicySnapshot"}],"stateMutability":"view"},{"name":"getLaunchedToken","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"token","type":"address","internalType":"address"},{"name":"curve","type":"address","internalType":"address"},{"name":"deployer","type":"address","internalType":"address"},{"name":"creatorFeeRecipient","type":"address","internalType":"address"},{"name":"pairToken","type":"address","internalType":"address"},{"name":"creatorTaxBps","type":"uint16","internalType":"uint16"},{"name":"buybackEnabled","type":"bool","internalType":"bool"},{"name":"personality","type":"bool","internalType":"bool"},{"name":"exists","type":"bool","internalType":"bool"}],"internalType":"struct IBrishopLaunchFactory.LaunchedToken"}],"stateMutability":"view"},{"name":"launchCount","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"launchDeployer","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract BrishopLaunchDeployer"}],"stateMutability":"view"},{"name":"launchFee","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"launchForwarder","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"launchPersonality","type":"function","inputs":[{"name":"params","type":"tuple","components":[{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"logo","type":"string","internalType":"string"},{"name":"description","type":"string","internalType":"string"},{"name":"socials","type":"tuple","components":[{"name":"twitter","type":"string","internalType":"string"},{"name":"telegram","type":"string","internalType":"string"},{"name":"discord","type":"string","internalType":"string"},{"name":"website","type":"string","internalType":"string"},{"name":"farcaster","type":"string","internalType":"string"}],"internalType":"struct BrishopLauncherToken.Socials"},{"name":"creatorFeeRecipient","type":"address","internalType":"address"},{"name":"creatorTaxBps","type":"uint16","internalType":"uint16"},{"name":"buybackEnabled","type":"bool","internalType":"bool"},{"name":"expectedEconomics","type":"bytes32","internalType":"bytes32"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"snipeTaxExemptions","type":"address[]","internalType":"address[]"}],"internalType":"struct TokenParams"},{"name":"id","type":"bytes32","internalType":"bytes32"},{"name":"targetFdvUsd","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"token","type":"address","internalType":"address"},{"name":"curve","type":"address","internalType":"address"}],"stateMutability":"payable"},{"name":"launchToken","type":"function","inputs":[{"name":"params","type":"tuple","components":[{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"logo","type":"string","internalType":"string"},{"name":"description","type":"string","internalType":"string"},{"name":"socials","type":"tuple","components":[{"name":"twitter","type":"string","internalType":"string"},{"name":"telegram","type":"string","internalType":"string"},{"name":"discord","type":"string","internalType":"string"},{"name":"website","type":"string","internalType":"string"},{"name":"farcaster","type":"string","internalType":"string"}],"internalType":"struct BrishopLauncherToken.Socials"},{"name":"creatorFeeRecipient","type":"address","internalType":"address"},{"name":"creatorTaxBps","type":"uint16","internalType":"uint16"},{"name":"buybackEnabled","type":"bool","internalType":"bool"},{"name":"expectedEconomics","type":"bytes32","internalType":"bytes32"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"snipeTaxExemptions","type":"address[]","internalType":"address[]"}],"internalType":"struct TokenParams"},{"name":"pairToken","type":"address","internalType":"address"}],"outputs":[{"name":"token","type":"address","internalType":"address"},{"name":"curve","type":"address","internalType":"address"}],"stateMutability":"payable"},{"name":"launchTokenFor","type":"function","inputs":[{"name":"params","type":"tuple","components":[{"name":"name","type":"string","internalType":"string"},{"name":"symbol","type":"string","internalType":"string"},{"name":"logo","type":"string","internalType":"string"},{"name":"description","type":"string","internalType":"string"},{"name":"socials","type":"tuple","components":[{"name":"twitter","type":"string","internalType":"string"},{"name":"telegram","type":"string","internalType":"string"},{"name":"discord","type":"string","internalType":"string"},{"name":"website","type":"string","internalType":"string"},{"name":"farcaster","type":"string","internalType":"string"}],"internalType":"struct BrishopLauncherToken.Socials"},{"name":"creatorFeeRecipient","type":"address","internalType":"address"},{"name":"creatorTaxBps","type":"uint16","internalType":"uint16"},{"name":"buybackEnabled","type":"bool","internalType":"bool"},{"name":"expectedEconomics","type":"bytes32","internalType":"bytes32"},{"name":"salt","type":"bytes32","internalType":"bytes32"},{"name":"snipeTaxExemptions","type":"address[]","internalType":"address[]"}],"internalType":"struct TokenParams"},{"name":"pairToken","type":"address","internalType":"address"},{"name":"creator","type":"address","internalType":"address"}],"outputs":[{"name":"token","type":"address","internalType":"address"},{"name":"curve","type":"address","internalType":"address"}],"stateMutability":"payable"},{"name":"launchedTokenAt","type":"function","inputs":[{"name":"index","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"maxCreatorTaxBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"oracleDecimals","type":"function","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pairEconomics","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"phantomQuote","type":"uint256","internalType":"uint256"},{"name":"enabled","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"pendingCreatorFeeRecipient","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"recipient","type":"address","internalType":"address"},{"name":"effectiveAt","type":"uint256","internalType":"uint256"},{"name":"expiresAt","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"pendingOwner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"personalities","type":"function","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"previewLaunchEconomics","type":"function","inputs":[{"name":"pairToken","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"name":"previewPersonalityEconomics","type":"function","inputs":[{"name":"targetFdvUsd","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"economics","type":"bytes32","internalType":"bytes32"},{"name":"phantomQuote","type":"uint256","internalType":"uint256"},{"name":"price","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"proposeCreatorFeeRecipient","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"recipient","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"renounceOwnership","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"setBuybackEnabled","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"enabled","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setFeeSweepOperator","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setLaunchForwarder","type":"function","inputs":[{"name":"forwarder","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setLaunchTerms","type":"function","inputs":[{"name":"newLaunchFee","type":"uint256","internalType":"uint256"},{"name":"creatorTaxMax","type":"uint256","internalType":"uint256"},{"name":"snipeStart","type":"uint256","internalType":"uint256"},{"name":"snipeWindow","type":"uint256","internalType":"uint256"},{"name":"policy","type":"tuple","components":[{"name":"protocolFeeRecipient","type":"address","internalType":"address"},{"name":"protocolFeeShareBps","type":"uint16","internalType":"uint16"},{"name":"buybackBurnBps","type":"uint16","internalType":"uint16"},{"name":"hookFeeBps","type":"uint16","internalType":"uint16"},{"name":"maxInternalPriceImpactBps","type":"uint16","internalType":"uint16"}],"internalType":"struct FeePolicySnapshot"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setPairEconomics","type":"function","inputs":[{"name":"pairToken","type":"address","internalType":"address"},{"name":"phantomQuote","type":"uint256","internalType":"uint256"},{"name":"enabled","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"snipeTaxSeconds","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"snipeTaxStartBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferCreatorFeeRecipient","type":"function","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"recipient","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"usedSalt","type":"function","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"}],"metadata":"{\"compiler\":{\"version\":\"0.8.35+commit.47b9dedd\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"},{\"internalType\":\"contract IEthUsdFeed\",\"name\":\"feed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CreatorTaxTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicatePersonality\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidOraclePrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPersonalityValuation\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTerms\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LaunchEconomicsMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LaunchFeeNotPaid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotCreatorFeeRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotLaunchForwarder\",\"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\":\"PairTokenNotApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecoveryNotExecutable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SaltAlreadyUsed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnknownToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"CreatorFeeRecipientChangeCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"effectiveAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiresAt\",\"type\":\"uint256\"}],\"name\":\"CreatorFeeRecipientChangeProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldRecipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newRecipient\",\"type\":\"address\"}],\"name\":\"CreatorFeeRecipientUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"FeeSweepOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"LaunchForwarderSet\",\"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\":\"pairToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"phantomQuote\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"PairEconomicsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"targetFdvUsd\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"ethUsdAnswer\",\"type\":\"uint256\"}],\"name\":\"PersonalityLaunched\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"TermsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"curve\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pairToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"phantomQuote\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"personality\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"creatorAllocation\",\"type\":\"uint256\"}],\"name\":\"TokenLaunched\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PHANTOM_ETH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CREATOR_RECOVERY_DELAY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CREATOR_RECOVERY_WINDOW\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ORACLE_MAX_AGE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUPPLY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"buybackVault\",\"outputs\":[{\"internalType\":\"contract BrishopBuybackVault\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"canLaunch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"cancelCreatorFeeRecipientChange\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentFeePolicy\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"protocolFeeRecipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"protocolFeeShareBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"buybackBurnBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"hookFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"maxInternalPriceImpactBps\",\"type\":\"uint16\"}],\"internalType\":\"struct FeePolicySnapshot\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ethUsdFeed\",\"outputs\":[{\"internalType\":\"contract IEthUsdFeed\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"executeCreatorFeeRecipientChange\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeEscrow\",\"outputs\":[{\"internalType\":\"contract BrishopFeeEscrow\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeSweepOperator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getLaunchFeePolicy\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"protocolFeeRecipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"protocolFeeShareBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"buybackBurnBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"hookFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"maxInternalPriceImpactBps\",\"type\":\"uint16\"}],\"internalType\":\"struct FeePolicySnapshot\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getLaunchedToken\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curve\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"creatorFeeRecipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pairToken\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"creatorTaxBps\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"buybackEnabled\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"personality\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"}],\"internalType\":\"struct IBrishopLaunchFactory.LaunchedToken\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"launchCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"launchDeployer\",\"outputs\":[{\"internalType\":\"contract BrishopLaunchDeployer\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"launchFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"launchForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"logo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"twitter\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"telegram\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"discord\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"website\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"farcaster\",\"type\":\"string\"}],\"internalType\":\"struct BrishopLauncherToken.Socials\",\"name\":\"socials\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"creatorFeeRecipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"creatorTaxBps\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"buybackEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"expectedEconomics\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"snipeTaxExemptions\",\"type\":\"address[]\"}],\"internalType\":\"struct TokenParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"targetFdvUsd\",\"type\":\"uint256\"}],\"name\":\"launchPersonality\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curve\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"logo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"twitter\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"telegram\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"discord\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"website\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"farcaster\",\"type\":\"string\"}],\"internalType\":\"struct BrishopLauncherToken.Socials\",\"name\":\"socials\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"creatorFeeRecipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"creatorTaxBps\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"buybackEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"expectedEconomics\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"snipeTaxExemptions\",\"type\":\"address[]\"}],\"internalType\":\"struct TokenParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"pairToken\",\"type\":\"address\"}],\"name\":\"launchToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curve\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"logo\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"twitter\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"telegram\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"discord\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"website\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"farcaster\",\"type\":\"string\"}],\"internalType\":\"struct BrishopLauncherToken.Socials\",\"name\":\"socials\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"creatorFeeRecipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"creatorTaxBps\",\"type\":\"uint16\"},{\"internalType\":\"bool\",\"name\":\"buybackEnabled\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"expectedEconomics\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"snipeTaxExemptions\",\"type\":\"address[]\"}],\"internalType\":\"struct TokenParams\",\"name\":\"params\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"pairToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"launchTokenFor\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"curve\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"launchedTokenAt\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxCreatorTaxBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleDecimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pairEconomics\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"phantomQuote\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pendingCreatorFeeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"effectiveAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiresAt\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"personalities\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pairToken\",\"type\":\"address\"}],\"name\":\"previewLaunchEconomics\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"targetFdvUsd\",\"type\":\"uint256\"}],\"name\":\"previewPersonalityEconomics\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"economics\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"phantomQuote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"proposeCreatorFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"setBuybackEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"setFeeSweepOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"setLaunchForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newLaunchFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creatorTaxMax\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"snipeStart\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"snipeWindow\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"protocolFeeRecipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"protocolFeeShareBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"buybackBurnBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"hookFeeBps\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"maxInternalPriceImpactBps\",\"type\":\"uint16\"}],\"internalType\":\"struct FeePolicySnapshot\",\"name\":\"policy\",\"type\":\"tuple\"}],\"name\":\"setLaunchTerms\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"pairToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"phantomQuote\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"setPairEconomics\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"snipeTaxSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"snipeTaxStartBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"transferCreatorFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"usedSalt\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"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.\"}],\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}]},\"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.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the 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\":{\"launchPersonality((string,string,string,string,(string,string,string,string,string),address,uint16,bool,bytes32,bytes32,address[]),bytes32,uint256)\":{\"notice\":\"Only the administrator may mint a personality. The 25% allocation goes directly to that administrator, is transferable, and receives no ETH.\"},\"setLaunchTerms(uint256,uint256,uint256,uint256,(address,uint16,uint16,uint16,uint16))\":{\"notice\":\"Updates terms for future launches only; existing curves snapshot them.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/BrishopLaunchFactory.sol\":\"BrishopLaunchFactory\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"keccak256\":\"0xff6d0bb2e285473e5311d9d3caacb525ae3538a80758c10649a4d61029b017bb\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8ed324d3920bb545059d66ab97d43e43ee85fd3bd52e03e401f020afb0b120f6\",\"dweb:/ipfs/QmfEckWLmZkDDcoWrkEvMWhms66xwTLff9DDhegYpvHo1a\"]},\"@openzeppelin/contracts/access/Ownable2Step.sol\":{\"keccak256\":\"0xdcad8898fda432696597752e8ec361b87d85c82cb258115427af006dacf7128c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e2c9d517f0c136d54bd00cd57959d25681d4d6273f5bbbc263afe228303772f0\",\"dweb:/ipfs/QmReNFjXBiufByiAAzfSQ2SM5r3qeUErn46BmN3yVRvrek\"]},\"@openzeppelin/contracts/interfaces/IERC1363.sol\":{\"keccak256\":\"0xd5ea07362ab630a6a3dee4285a74cf2377044ca2e4be472755ad64d7c5d4b69d\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://da5e832b40fc5c3145d3781e2e5fa60ac2052c9d08af7e300dc8ab80c4343100\",\"dweb:/ipfs/QmTzf7N5ZUdh5raqtzbM11yexiUoLC9z3Ws632MCuycq1d\"]},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"keccak256\":\"0x0afcb7e740d1537b252cb2676f600465ce6938398569f09ba1b9ca240dde2dfc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1c299900ac4ec268d4570ecef0d697a3013cd11a6eb74e295ee3fbc945056037\",\"dweb:/ipfs/Qmab9owJoxcA7vJT5XNayCMaUR1qxqj1NDzzisduwaJMcZ\"]},\"@openzeppelin/contracts/interfaces/IERC20.sol\":{\"keccak256\":\"0x1a6221315ce0307746c2c4827c125d821ee796c74a676787762f4778671d4f44\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1bb2332a7ee26dd0b0de9b7fe266749f54820c99ab6a3bcb6f7e6b751d47ee2d\",\"dweb:/ipfs/QmcRWpaBeCYkhy68PR3B4AgD7asuQk7PwkWxrvJbZcikLF\"]},\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"keccak256\":\"0x1b88b3fb3d85ba5496d7d5f396f83ee1fddcdd6762059ff65992655b67920998\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://89393bb3212da1c0889601b9706a07b39419ddc4d2faab9eaf6e7f9152cf6a1c\",\"dweb:/ipfs/QmcCfzzxv1Bkdz1c1yF4gQCeYb6Us5BJANnzTFqawfd1HL\"]},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"keccak256\":\"0x669464167428061ee0f8618b73b3ee90aff8405683e7ddde8cd77dadaa1afe29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0dda78587a7358b4fdf6b9fca0fde5a5e34930f36d5268a16028627fc0170195\",\"dweb:/ipfs/QmQ1b6cCceDRWNxti9HifsTCzmVP25Haxs1bWugm52vTqH\"]},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303\",\"dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV\"]},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\":{\"keccak256\":\"0x2659248df25e34000ed214b3dc8da2160bc39874c992b477d9e2b1b3283dc073\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c345af1b0e7ea28d1216d6a04ab28f5534a5229b9edf9ca3cd0e84950ae58d26\",\"dweb:/ipfs/QmY63jtSrYpLRe8Gj1ep2vMDCKxGNNG3hnNVKBVnrs2nmA\"]},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0xd6fa4088198f04eef10c5bce8a2f4d60554b7ec4b987f684393c01bf79b94d9f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f95ee0bbd4dd3ac730d066ba3e785ded4565e890dbec2fa7d3b9fe3bad9d0d6e\",\"dweb:/ipfs/QmSLr6bHkPFWT7ntj34jmwfyskpwo97T9jZUrk5sz3sdtR\"]},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x304d732678032a9781ae85c8f204c8fba3d3a5e31c02616964e75cfdc5049098\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://299ced486011781dc98f638059678323c03079fefae1482abaa2135b22fa92d0\",\"dweb:/ipfs/QmbZNbcPTBxNvwChavN2kkZZs7xHhYL7mv51KrxMhsMs3j\"]},\"@openzeppelin/contracts/utils/Context.sol\":{\"keccak256\":\"0x493033a8d1b176a037b2cc6a04dad01a5c157722049bbecf632ca876224dd4b2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6a708e8a5bdb1011c2c381c9a5cfd8a9a956d7d0a9dc1bd8bcdaf52f76ef2f12\",\"dweb:/ipfs/Qmax9WHBnVsZP46ZxEMNRQpLQnrdE4dK8LehML1Py8FowF\"]},\"@openzeppelin/contracts/utils/Panic.sol\":{\"keccak256\":\"0xf7fe324703a64fc51702311dc51562d5cb1497734f074e4f483bfb6717572d7a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c6a5ff4f9fd8649b7ee20800b7fa387d3465bd77cf20c2d1068cd5c98e1ed57a\",\"dweb:/ipfs/QmVSaVJf9FXFhdYEYeCEfjMVHrxDh5qL4CGkxdMWpQCrqG\"]},\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\":{\"keccak256\":\"0xa516cbf1c7d15d3517c2d668601ce016c54395bf5171918a14e2686977465f53\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1e1d079e8edfb58efd23a311e315a4807b01b5d1cf153f8fa2d0608b9dec3e99\",\"dweb:/ipfs/QmTBExeX2SDTkn5xbk5ssbYSx7VqRp9H4Ux1CY4uQM4b9N\"]},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"keccak256\":\"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9f660b1f351b757dfe01438e59888f31f33ded3afcf5cb5b0d9bf9aa6f320a8b\",\"dweb:/ipfs/QmarDJ5hZEgBtCmmrVzEZWjub9769eD686jmzb2XpSU1cM\"]},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"]},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"keccak256\":\"0x59973a93b1f983f94e10529f46ca46544a9fec2b5f56fb1390bbe9e0dc79f857\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c55ef8f0b9719790c2ae6f81d80a59ffb89f2f0abe6bc065585bd79edce058c5\",\"dweb:/ipfs/QmNNmCbX9NjPXKqHJN8R1WC2rNeZSQrPZLd6FF6AKLyH5Y\"]},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0xc8cae21c9ae4a46e5162ff9bf5b351d6fa6a6eba72d515f3bc1bdfeda7fdf083\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ce830ebcf28e31643caba318996db3763c36d52cd0f23798ba83c135355d45e9\",\"dweb:/ipfs/QmdGPcvptHN7UBCbUYBbRX3hiRVRFLRwno8b4uga6uFNif\"]},\"src/BrishopBondingCurve.sol\":{\"keccak256\":\"0x37fcd3f1b4529a9f0dbc316d071e1edf11ce3fafe2546c4ecc6f365c844f3db7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://32a9404f802a8eb3efd56548240f9abdddb6c0f936bb95d9e05df54b0e4c0e26\",\"dweb:/ipfs/QmTZCdLsbkGLMXAuRFY8mRf9VU5XX24K8x3qjCbpQh7nLm\"]},\"src/BrishopBuybackVault.sol\":{\"keccak256\":\"0x0becf05283bc8b8964a8d100e23b887a188c82c95fcad98e22f5217ffc9e58c9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://137a6aaded4724a3474b3c08067693245523ed517a84aafc5c146353852bb32d\",\"dweb:/ipfs/QmQ4JfAQYR3eqhowQgibERLGiTfowSnH1QRWY6D1983eFW\"]},\"src/BrishopFeeEscrow.sol\":{\"keccak256\":\"0x361a29a736f82d65989960e20cc37d80e5f0ec1ee909a4799df91bcef1141ca0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://27624435e94dd282fc36e0d39ceceff413cbcf314b9c38350168b4accb739988\",\"dweb:/ipfs/QmT73E2hkE4UKyy6ZqujJsNEjHLYvMnnQSyw2Xhcin4UU4\"]},\"src/BrishopLaunchDeployer.sol\":{\"keccak256\":\"0x0f81d31836aa2a5d416979c07a14635bf3d182e2a2e955e631cae8d0afe1d544\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f6c655be8bfc3007ed89e0734a9a27d26bcd3ce27483c10648d605304b2f3526\",\"dweb:/ipfs/QmUChkKtVzv31TgNXQY8FGaZqeajBj7QhPXXSHep9kj5pe\"]},\"src/BrishopLaunchFactory.sol\":{\"keccak256\":\"0x4bf1ae68473202a8688fc818b97fbd6ed91fe27574e60859a8bf68b345b91ef9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c48a43af297f76683a83c086b05cbe5cfeeae87098c78ad8b228e2d9558a9f53\",\"dweb:/ipfs/QmboPttLauLG6HzvRznmgGA7QRsodv6CoLtUDK5iej48sC\"]},\"src/BrishopLauncherToken.sol\":{\"keccak256\":\"0x1ebcf1534c80df8734078c6d29f4d03dc5ca76c762788065a845ea390452e428\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://41c43b23dc334d33209865364b3493cd9c44286868a9c94d97934bda862626f8\",\"dweb:/ipfs/QmS7qZ19vCfUCYJEgLoKKG7hbpkHpP2Dps9SH6WMh52xt6\"]},\"src/interfaces/IBrishop.sol\":{\"keccak256\":\"0x329d57dfed260932f89ed7a9f0b91ed7236e12777f41ebf8599495ce294a8d2f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://dd6053f039743beb42223b3228361129753dce8717c96291dba5820e52ef9892\",\"dweb:/ipfs/QmeSF8Mo9XyXb3ZGp8ns6h2cLo1G8n4f8UyyUoHe8w4piF\"]},\"src/libraries/BrishopBondingCurveMath.sol\":{\"keccak256\":\"0x0d3088350d2c58adce273486980851b3a34b6a85705ca2b681846fca118fc75b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://76441b39e6db97858be47e1d98ae0fde65f2060b4089f8a8395776c976ed28f5\",\"dweb:/ipfs/QmcmmXMjzzRKKJbLJUo9tjpeikd65iGCG8Q1hdR19jjGDt\"]}},\"version\":1}","userdoc":{"kind":"user","methods":{"setLaunchTerms(uint256,uint256,uint256,uint256,(address,uint16,uint16,uint16,uint16))":{"notice":"Updates terms for future launches only; existing curves snapshot them."},"launchPersonality((string,string,string,string,(string,string,string,string,string),address,uint16,bool,bytes32,bytes32,address[]),bytes32,uint256)":{"notice":"Only the administrator may mint a personality. The 25% allocation goes directly to that administrator, is transferable, and receives no ETH."}},"version":1},"devdoc":{"kind":"dev","errors":{"OwnableInvalidOwner(address)":[{"details":"The owner is not a valid owner account. (eg. `address(0)`)"}],"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}],"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."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the 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},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_uint16":{"label":"uint16","encoding":"inplace","numberOfBytes":"2"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_bytes32":{"label":"bytes32","encoding":"inplace","numberOfBytes":"32"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_bytes32,t_bool)":{"key":"t_bytes32","label":"mapping(bytes32 => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"},"t_array(t_address)dyn_storage":{"base":"t_address","label":"address[]","encoding":"dynamic_array","numberOfBytes":"32"},"t_mapping(t_bytes32,t_address)":{"key":"t_bytes32","label":"mapping(bytes32 => address)","value":"t_address","encoding":"mapping","numberOfBytes":"32"},"t_struct(PairEconomics)9016_storage":{"label":"struct BrishopLaunchFactory.PairEconomics","members":[{"slot":"0","type":"t_uint256","astId":9013,"label":"phantomQuote","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"1","type":"t_bool","astId":9015,"label":"enabled","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}],"encoding":"inplace","numberOfBytes":"64"},"t_struct(LaunchedToken)10755_storage":{"label":"struct IBrishopLaunchFactory.LaunchedToken","members":[{"slot":"0","type":"t_address","astId":10738,"label":"token","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"1","type":"t_address","astId":10740,"label":"curve","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"2","type":"t_address","astId":10742,"label":"deployer","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"3","type":"t_address","astId":10744,"label":"creatorFeeRecipient","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_address","astId":10746,"label":"pairToken","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_uint16","astId":10748,"label":"creatorTaxBps","offset":20,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_bool","astId":10750,"label":"buybackEnabled","offset":22,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_bool","astId":10752,"label":"personality","offset":23,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_bool","astId":10754,"label":"exists","offset":24,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}],"encoding":"inplace","numberOfBytes":"160"},"t_struct(PendingRecipient)9028_storage":{"label":"struct BrishopLaunchFactory.PendingRecipient","members":[{"slot":"0","type":"t_address","astId":9023,"label":"recipient","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"1","type":"t_uint256","astId":9025,"label":"effectiveAt","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"2","type":"t_uint256","astId":9027,"label":"expiresAt","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}],"encoding":"inplace","numberOfBytes":"96"},"t_struct(FeePolicySnapshot)10713_storage":{"label":"struct FeePolicySnapshot","members":[{"slot":"0","type":"t_address","astId":10704,"label":"protocolFeeRecipient","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"0","type":"t_uint16","astId":10706,"label":"protocolFeeShareBps","offset":20,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"0","type":"t_uint16","astId":10708,"label":"buybackBurnBps","offset":22,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"0","type":"t_uint16","astId":10710,"label":"hookFeeBps","offset":24,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"0","type":"t_uint16","astId":10712,"label":"maxInternalPriceImpactBps","offset":26,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}],"encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_address,t_mapping(t_bytes32,t_bool))":{"key":"t_address","label":"mapping(address => mapping(bytes32 => bool))","value":"t_mapping(t_bytes32,t_bool)","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_struct(PairEconomics)9016_storage)":{"key":"t_address","label":"mapping(address => struct BrishopLaunchFactory.PairEconomics)","value":"t_struct(PairEconomics)9016_storage","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_struct(LaunchedToken)10755_storage)":{"key":"t_address","label":"mapping(address => struct IBrishopLaunchFactory.LaunchedToken)","value":"t_struct(LaunchedToken)10755_storage","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_struct(PendingRecipient)9028_storage)":{"key":"t_address","label":"mapping(address => struct BrishopLaunchFactory.PendingRecipient)","value":"t_struct(PendingRecipient)9028_storage","encoding":"mapping","numberOfBytes":"32"},"t_mapping(t_address,t_struct(FeePolicySnapshot)10713_storage)":{"key":"t_address","label":"mapping(address => struct FeePolicySnapshot)","value":"t_struct(FeePolicySnapshot)10713_storage","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":8,"label":"_owner","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"1","type":"t_address","astId":156,"label":"_pendingOwner","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"2","type":"t_uint256","astId":8958,"label":"launchFee","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"3","type":"t_uint256","astId":8961,"label":"maxCreatorTaxBps","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"4","type":"t_uint256","astId":8964,"label":"snipeTaxStartBps","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"5","type":"t_uint256","astId":8967,"label":"snipeTaxSeconds","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"6","type":"t_address","astId":8969,"label":"feeSweepOperator","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"7","type":"t_address","astId":8971,"label":"launchForwarder","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"8","type":"t_struct(FeePolicySnapshot)10713_storage","astId":8988,"label":"_policy","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"9","type":"t_mapping(t_address,t_struct(LaunchedToken)10755_storage)","astId":8993,"label":"_launches","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"10","type":"t_mapping(t_address,t_struct(FeePolicySnapshot)10713_storage)","astId":8998,"label":"_launchPolicies","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"11","type":"t_array(t_address)dyn_storage","astId":9001,"label":"_tokens","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"12","type":"t_mapping(t_bytes32,t_address)","astId":9005,"label":"personalities","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"13","type":"t_mapping(t_address,t_mapping(t_bytes32,t_bool))","astId":9011,"label":"usedSalt","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"14","type":"t_mapping(t_address,t_struct(PairEconomics)9016_storage)","astId":9021,"label":"pairEconomics","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"},{"slot":"15","type":"t_mapping(t_address,t_struct(PendingRecipient)9028_storage)","astId":9033,"label":"pendingCreatorFeeRecipient","offset":0,"contract":"src/BrishopLaunchFactory.sol:BrishopLaunchFactory"}]},"transientStorageLayout":{"types":null,"storage":[]},"evm":{"bytecode":{"object":"61012080604052346103d3575f90604081619f5880380380916100228285610457565b8339810103126103d35780516001600160a01b03811691908290036103d357602001516001600160a01b0381168082036103d357821561044457600180546001600160a01b03199081169091555f805491821685178155604051939185916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556601c6bf526340006002556103e86003556126ac6004556003600555813b1561043557600483602093819360e05263313ce56760e01b82525afa9081156103c8575f916103f9575b50601260ff8216116103eb5761010052600680546001600160a01b0319168217905560405160a081016001600160401b038111828210176103d7576040908152828252610bb86020830152611388828201526064606083015261012c608090920191909152600880546001600160e01b031916600160a01b600160e01b0319909316929092176625800c8271017760a31b17909155516107ca8082018281106001600160401b038211176103d757829161369a833903905ff080156103c8576080819052604051906112db8083016001600160401b038111848210176103d7576060928492613e6484393080835260208301526001600160a01b031660408201520301905ff080156103c85760a08190526001600160a01b0316803b156103d3575f8091602460405180948193630b768f0160e31b83523060048401525af180156103c8576103b5575b5060805160a05160405191614e19808401926001600160a01b039081169216906001600160401b038411858510176103a1579160609391859361513f85393083526020830152604082015203019082f080156103945760c052604080519081016001600160401b0381118282101761038057906001916040526717508f1956a80000815260406020820193838552808052600e6020522090518155019051151560ff8019835416911617905560405161321f908161047b8239608051818181610655015281816111ba0152612f3f015260a05181818161031b0152612611015260c051818181610c22015281816116c90152612b69015260e05181818161170d01526122b401526101005181818161058a01526123340152f35b634e487b7160e01b83526041600452602483fd5b50604051903d90823e3d90fd5b634e487b7160e01b86526041600452602486fd5b6103c191505f90610457565b5f5f610266565b6040513d5f823e3d90fd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b62fc7cad60e51b5f5260045ffd5b90506020813d60201161042d575b8161041460209383610457565b810103126103d3575160ff811681036103d3575f61011c565b3d9150610407565b63d92e233d60e01b5f5260045ffd5b631e4fbdf760e01b5f525f60045260245ffd5b601f909101601f19168101906001600160401b038211908210176103d75760405256fe6080806040526004361015610012575f80fd5b5f905f3560e01c90816327cca59f14612018575080632931861b14611fc3578063315226d914611b9157806334fcaa3714611ec35780633cf28b5a14611d465780633d3d2d5814611c7257806345fb206314611c47578063470ef5fc14611bb357806350e25ac214611b96578063523af32814611b9157806354a4931c14611b7457806354faf9c314611b0357806358373f0414611ade5780636499386614611aad5780636783774b14611a905780636cd5bce4146119ff5780636dc97d6a146119885780636e47a1881461191b5780636f471f2d146118c5578063715018a614611862578063767b7c16146117c157806379ba50971461173c5780638009b7bd146116f8578063858f5964146116b457806389a69bd8146116455780638a36a6bb1461161d5780638da5cb5b146115f65780638e8d8ec5146114e55780639b924452146114bd5780639beacf4a1461145e5780639c5693eb146107cf578063abb918d814610786578063b18f1db114610684578063c4b7de971461063f578063c50497ae14610618578063cf3cf573146105fa578063df41ead2146105d7578063e30c3978146105ae578063e68b52e714610570578063e7ed38bd1461034a578063f1f5c99314610305578063f2fde38b14610298578063f325a5fb1461027a578063f9b3b8d9146102475763ffcb6e9f1461020d575f80fd5b3461024457602036600319011261024457602061022b60043561254a565b905460405160039290921b1c6001600160a01b03168152f35b80fd5b5034610244576020366003190112610244576020906004358152600c8252604060018060a01b0391205416604051908152f35b50346102445780600319360112610244576020600354604051908152f35b5034610244576020366003190112610244576102b2612032565b6102ba6126ee565b600180546001600160a01b0319166001600160a01b0392831690811790915582549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610244576101203660031901126102445760643560443560243560a036608319011261056c5761037a6126ee565b6103e881118015610561575b8015610559575b801561054d575b8015610535575b801561051f575b8015610509575b80156104f3575b80156104e0575b80156104c9575b6104ba5760048035600255600391909155556005556001600160a01b036103e36124cc565b166001600160601b0360a01b60085416176008556103ff6124f6565b6008805461ffff60a01b191660a09290921b61ffff60a01b16919091179055610426612507565b6008805461ffff60b01b191660b09290921b61ffff60b01b1691909117905561044d612518565b6008805461ffff60c01b191660c09290921b61ffff60c01b16919091179055610474612529565b6008805461ffff60d01b191660d09290921b61ffff60d01b169190911790557f8f70233f68d766cfab4ff696858b5eba8fa61e09191134073df956473102569b8180a180f35b630256965f60e01b8452600484fd5b5061271061ffff6104d8612529565b1610156103be565b5061ffff6104ec612529565b16156103b7565b506103e861ffff610502612518565b16116103b0565b5061271061ffff610518612507565b16116103a9565b5061271061ffff61052e6124f6565b16116103a2565b506001600160a01b036105466124cc565b161561039b565b50620151808311610394565b50821561038d565b506126ac8211610386565b8380fd5b5034610244578060031936011261024457602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346102445780600319360112610244576001546040516001600160a01b039091168152602090f35b503461024457806003193601126102445760206040516717508f1956a800008152f35b50346102445780600319360112610244576020600254604051908152f35b503461024457806003193601126102445760206040516b033b2e3c9fd0803ce80000008152f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346102445760403660031901126102445761069e612032565b906024359182151590818403610782576106b790612562565b60038101546001600160a01b031633141580610767575b6107585760048101805460ff60b01b191694151560b01b60ff60b01b16949094179093559091829190600101546001600160a01b031690813b15610754578291602483926040519485938492639a9b567d60e01b845260048401525af18015610749576107385750f35b8161074291612177565b6102445780f35b6040513d84823e3d90fd5b5050fd5b632e7e4e5160e21b8352600483fd5b5082546001600160a01b0316331415806106ce5750836106ce565b8280fd5b50346102445760403660031901126102445760209060ff906040906001600160a01b036107b1612032565b168152600d8452818120602435825284522054166040519015158152f35b50606036600319011261127c576001600160401b036004351161127c576101606004353603600319011261127c576108056126ee565b61080d61280f565b60243515801561143c575b61142e5761082760443561228f565b9161010460043501350361141f5760025434036114105761084c60c46004350161253b565b61ffff60035491161180156113e1575b6113d257335f52600d60205260405f2061012460043501355f5260205260ff60405f2054166113c357602061089c610144600435016004356004016130da565b9050116113b457335f52600d60205260405f2061012460043501355f5260205260405f20600160ff1982541617905560018060a01b036108e060a4600435016124e2565b166113a05733925b6acecb8f27f4200f3a0000009261ffff60085460c01c169161090e60c46004350161253b565b61ffff61091f60e46004350161310f565b916040519561092d8761215c565b5f875260018060a01b038a1660208801528760408801526060870152166080850152151560a084015260405192638dabdc8360e01b84526101e06004850152610a186109f06109c86109a061098c600435600401600435600401613130565b6101606101e48b01526103448a0191613161565b6109b4602460043501600435600401613130565b8983036101e319016102048b015290613161565b6109dc604460043501600435600401613130565b8883036101e319016102248a015290613161565b610a04606460043501600435600401613130565b8783036101e3190161024489015290613161565b60043560848101359190360360a2190182121561127c576004610ad99281350101906101e31987820301610264880152610acb610ac0610aa5610a8a610a6f610a618780613130565b60a0885260a0880191613161565b610a7c6020880188613130565b908783036020890152613161565b610a976040870187613130565b908683036040880152613161565b610ab26060860186613130565b908583036060870152613161565b926080810190613130565b916080818503910152613161565b906001600160a01b03610af060043560a40161205e565b1661028486015260c4600435013561ffff811680910361127c576102a4860152610b1e60e4600435016120d5565b15156102c48601526004356101048101356102e48701526101248101356103048701526101448101359036036022190181121561127c576004908135010160208101926001600160401b0382351161127c57813560051b3603841361127c578681036101e319016103248801528135815291928692602001915f5b8135811061137057505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190610bfb60e48301612701565b336101848301526b033b2e3c9fd0803ce80000006101a48301526101c4820189905203815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af193841561124f575f935f95611327575b50868486610e03610c7160c46004350161253b565b610de861ffff610c8560e46004350161310f565b926004604051610c948161210a565b60018060a01b0389168152602081019760018060a01b031688526040810199338b52606082019060018060a01b03168152608082019a5f8c528560a084019516855260c08301971515885260e083019960018b5261010084019b60018d5260018060a01b03165f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b51845460ff60b01b191690151560b01b60ff60b01b16178455565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790556001600160a01b0384165f908152600a602052604090206007198101611294575b50600b54600160401b8110156112805784610e73826001610e979401600b5561254a565b81546001600160a01b0393841660039290921b91821b9390911b1916919091179055565b610eac610144600435016004356004016130da565b979050600288018811610f7d57610ee06002610ec9818b01613181565b99610ed76040519b8c612177565b01808a52613181565b601f19013660208a013733610ef489613198565b526001600160a01b0316610f07886131a5565b525f5b610f1f610144600435016004356004016130da565b9050811015610fa557610f3d610144600435016004356004016130da565b821015610f9157610f52908260051b016124e2565b90600281018111610f7d57600191610f6d600283018b6131b5565b90838060a01b0316905201610f0a565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5085876001600160a01b0387163b1561127c576040805163251b648160e21b81526001600160a01b03881660048201526024810191909152815160448201819052909182916064830191602001905f5b81811061125a57505f93928390039150829050836001600160a01b038c165af1801561124f5761123a575b50600254806111ad575b506110f9916110b29160405190858252826020830152600160408301526060820152339060018060a01b038916907ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b608060018060a01b038b1692a46024358452600c6020526040842080546001600160a01b0319166001600160a01b03881617905561273e565b916001604051916110c283612126565b84835260406020840191838352838060a01b0389168152600e602052209251835551151591019060ff801983541691151516179055565b60408051918252600160208301526001600160a01b038416917fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79190a260408051604435815260208101929092526001600160a01b03831691602435917ff58d88bf88870587ec1fdf8ab973f10a093d9dc3c1a243e32f41fa5d73eda1b791a360015f5160206131ca5f395f51905f5255604080516001600160a01b039283168152929091166020830152819081015b0390f35b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b1561123657906024869260405194859384926301aba89b60e71b845260048401525af1801561122b57908491611216575b5061102a565b8161122091612177565b610782578287611210565b6040513d86823e3d90fd5b8580fd5b6112479193505f90612177565b5f9186611020565b6040513d5f823e3d90fd5b82516001600160a01b0316845285945060209384019390920191600101610ff5565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155611321905b600854815461ffff60b01b191661ffff60b01b909116178155600854815461ffff60c01b191661ffff60c01b909116178155600854815461ffff60d01b191661ffff60d01b909116179055565b5f610e4f565b935093506040833d604011611368575b8161134460409383612177565b8101031261127c57611361602061135a8561311c565b940161311c565b935f610c5c565b3d9150611337565b919493509160019060209081906001600160a01b0361138e8961205e565b16815201950191019187939492610b99565b6113ae60a4600435016124e2565b926108e8565b630256965f60e01b5f5260045ffd5b630ced304360e01b5f5260045ffd5b6326b5197760e21b5f5260045ffd5b506107d061140a61ffff6113f960c46004350161253b565b1661ffff60085460c01c16906120e2565b1161085c565b637e6d78a560e01b5f5260045ffd5b631e5d0a3f60e11b5f5260045ffd5b62d532eb60e71b5f5260045ffd5b506024355f908152600c60205260409020546001600160a01b03161515610818565b3461127c57602036600319011261127c576001600160a01b0361147f612032565b165f908152600f60209081526040918290208054600182015460029092015484516001600160a01b0390921682529281019190915291820152606090f35b3461127c575f36600319011261127c576007546040516001600160a01b039091168152602090f35b3461127c57606036600319011261127c576114fe612032565b602435906044358015159182820361127c576115186126ee565b6001600160a01b031692831515806115d9575b6115ca57801580156115ba575b6113b4576115a07fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79360016040519161157083612126565b84835260208301908152875f52600e60205260405f209251835551151591019060ff801983541691151516179055565b60408051918252911515602082015290819081015b0390a2005b506001600160801b038111611538565b6349285dfb60e01b5f5260045ffd5b50835f52600960205260ff600460405f20015460b81c161561152b565b3461127c575f36600319011261127c575f546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c576006546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c5761165d61224e565b506111a960405161166d81612141565b61ffff60085460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c57600154336001600160a01b03909116036117ae57600180546001600160a01b03199081169091555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461127c57602036600319011261127c576117da612032565b6117e26126ee565b600754906001600160a01b03821661185357803b15611844576001600160a01b03166001600160a01b03199190911681176007556040519081527f56b32d3633fed72f97c4df44a78b5fa04f1d662d4bddebcd8a9b216d26d093ad90602090a1005b63d92e233d60e01b5f5260045ffd5b63a741a04560e01b5f5260045ffd5b3461127c575f36600319011261127c5761187a6126ee565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461127c57602036600319011261127c576001600160a01b036118e6612032565b165f52600e60205260405f2060ff6001825492015416906111a960405192839283909291602090604083019483521515910152565b3461127c57602036600319011261127c57611934612032565b61193c6126ee565b6001600160a01b03165f818152600f60205260408120818155600181018290556002018190557f30241dede93b23e050576be65d204d53b18e8c6d9f75006095bfd422094d87569080a2005b604036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c576119d2906119c0612048565b6119c861280f565b3391600401612847565b60015f5160206131ca5f395f51905f5255604080516001600160a01b039384168152919092166020820152f35b606036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c57611a33612048565b604435906001600160a01b03821680830361127c57611a5061280f565b6007546001600160a01b0316331480159190611a87575b50611a78576119d292600401612847565b63754f554b60e11b5f5260045ffd5b90501584611a67565b3461127c575f36600319011261127c576020600554604051908152f35b3461127c57602036600319011261127c576060611acb60043561228f565b9060405192835260208301526040820152f35b3461127c57602036600319011261127c57611af7612032565b50602060405160018152f35b3461127c57602036600319011261127c57611b1c612032565b611b246126ee565b6001600160a01b03168015611844576020817fae994ca926e252e299c3df7516cb609272a57bf80b0e0715297e55939f873420926001600160601b0360a01b6006541617600655604051908152a1005b3461127c575f36600319011261127c576020604051620151808152f35b612072565b3461127c575f36600319011261127c576020600454604051908152f35b3461127c57602036600319011261127c57611bcc612032565b611bd461224e565b50611bde81612562565b5060018060a01b03165f52600a6020526111a960405f2061ffff60405191611c0583612141565b5460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c57602036600319011261127c576020611c6a611c65612032565b612198565b604051908152f35b3461127c57602036600319011261127c57611c8b612032565b611c936126ee565b60018060a01b03811690815f52600f60205260405f2060405190611cb6826120ef565b80546001600160a01b0316808352600182015460208401819052600290920154604084018190529015918215611d3c575b508115611d32575b50611d2357611d21925f52600f6020525f600260408220828155826001820155015560018060a01b0390511690612597565b005b63aa0b7b6160e01b5f5260045ffd5b9050421184611cef565b4210915085611ce7565b3461127c57602036600319011261127c57611d5f612032565b5f610100604051611d6f8161210a565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152015260018060a01b03165f52600960205261012060405f2060405190611dc18261210a565b60018060a01b038154169182815260018060a01b036001830154166020820190815261ffff60018060a01b0360028501541660408401908152600460018060a01b036003870154169560608601968752015494608085019060018060a01b038716825260a0860192848860a01c16845260c087019560ff8960b01c161515875260ff61010060e08a0199828c60b81c1615158b52019960c01c1615158952604051998a5260018060a01b0390511660208a015260018060a01b03905116604089015260018060a01b03905116606088015260018060a01b039051166080870152511660a085015251151560c084015251151560e0830152511515610100820152f35b3461127c57604036600319011261127c57611edc612032565b611ee4612048565b611eec6126ee565b611ef582612562565b506001600160a01b038116908115611844576203f480420190814211610f7d576207e900420192838311610f7d577f22b336cc3c163283ca94b8a02d1107b4485a820fa77cc12ea205640452d37b5e936115b59160405190611f56826120ef565b8152602080820186815260408084018581526001600160a01b039a8b165f818152600f8652839020955186546001600160a01b031916908d161786559251600186015551600294909401939093558251959098168552840194909452928201929092529081906060820190565b3461127c57604036600319011261127c57611fdc612032565b611fe4612048565b6001600160a01b036003611ff784612562565b015416330361200957611d2191612597565b632e7e4e5160e21b5f5260045ffd5b3461127c575f36600319011261127c57602090600b548152f35b600435906001600160a01b038216820361127c57565b602435906001600160a01b038216820361127c57565b35906001600160a01b038216820361127c57565b3461127c575f36600319011261127c5760206040516203f4808152f35b919091608061ffff8160a084019560018060a01b038151168552826020820151166020860152826040820151166040860152826060820151166060860152015116910152565b3590811515820361127c57565b91908201809211610f7d57565b606081019081106001600160401b0382111761128057604052565b61012081019081106001600160401b0382111761128057604052565b604081019081106001600160401b0382111761128057604052565b60a081019081106001600160401b0382111761128057604052565b60c081019081106001600160401b0382111761128057604052565b90601f801991011681019081106001600160401b0382111761128057604052565b60018060a01b0316805f52600e60205260405f2060ff6001604051926121bd84612126565b8054845201541615801560208301526115ca575160025460035460045490600554926040519460208601964688523060408801526b033b2e3c9fd0803ce80000006060880152608087015260a08601525f60c086015260e08501526101008401526101208301526101408201526122376101608201612701565b6101e0815261224861020082612177565b51902090565b6040519061225b82612141565b5f6080838281528260208201528260408201528260608201520152565b519069ffffffffffffffffffff8216820361127c57565b614650811080156124c1575b61241757604051633fabe5a360e21b815260a0816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801561124f575f915f9161246d575b505f821390811591612464575b811561245a575b8115612444575b50612436578091670de0b6b3a7640000810290808204670de0b6b3a76400001490151715610f7d5760ff7f000000000000000000000000000000000000000000000000000000000000000016604d8111610f7d57600a0a80600302906003820403610f7d576001600160fe1b0383168303610f7d5761238a9260021b91612770565b9081158015612426575b61241757600254600354600454600554906040519260208401944686523060408601526b033b2e3c9fd0803ce800000060608601525f60808601528760a0860152600160c086015260e08501526101008401526101208301526101408201526124006101608201612701565b6101e0815261241161020082612177565b51902092565b6330d7115160e11b5f5260045ffd5b506001600160801b038211612394565b62fc7cad60e51b5f5260045ffd5b90504203428111610f7d5762015180105f612308565b4281119150612301565b801591506122fa565b91505060a0813d60a0116124b9575b8161248960a09383612177565b8101031261127c5761249a81612278565b5060208101516124b1608060608401519301612278565b50905f6122ed565b3d915061247c565b506161a8811161229b565b6084356001600160a01b038116810361127c5790565b356001600160a01b038116810361127c5790565b60a43561ffff8116810361127c5790565b60c43561ffff8116810361127c5790565b60e43561ffff8116810361127c5790565b6101043561ffff8116810361127c5790565b3561ffff8116810361127c5790565b600b54811015610f9157600b5f5260205f2001905f90565b60018060a01b03165f52600960205260405f209060ff600483015460c01c161561258857565b638698bf3760e01b5f5260045ffd5b6001600160a01b03821691905f908315611844576125b481612562565b6003810180546001600160a01b0319811687179091556001909101546001600160a01b03918216949116803b1561127c575f8091602460405180948193633d82753160e11b83528b60048401525af1801561124f576126d9575b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b1561056c57604051635ad7fc1760e01b81526001600160a01b0384811660048301529190911660248201529083908290604490829084905af180156126ce579083916126b5575b50506001600160a01b0316907f308c390ed1ab5873392818e036cabdf408bc8ad042fbaead3108954ff75ba9809080a4565b816126bf91612177565b6126ca57815f612683565b5080fd5b6040513d85823e3d90fd5b6126e69193505f90612177565b5f915f61260e565b5f546001600160a01b031633036117ae57565b608061ffff60085460018060a01b0381168452818160a01c166020850152818160b01c166040850152818160c01c16606085015260d01c16910152565b801561275c57723880173480caadff41f996746e3000000000000490565b634e487b7160e01b5f52601260045260245ffd5b90915f19838309928083029283808610950394808603951461280157848311156127e95790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b50509150811561275c570490565b60025f5160206131ca5f395f51905f5254146128385760025f5160206131ca5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b90915f9361285484612198565b6101008401350361141f5760018060a01b0384165f52600e60205260405f20549460025434036114105761288a60c0850161253b565b61ffff60035491161180156130be575b6113d25760018060a01b0383165f52600d60205260405f206101208501355f5260205260ff60405f2054166113c35760206128d96101408601866130da565b9050116113b4576001600160a01b038381165f908152600d6020908152604080832061012089013584529091529020805460ff1916600117905561291f60a086016124e2565b166130ac5782945b61ffff60085460c01c169161293e60c0870161253b565b61ffff61294d60e0890161310f565b916040519561295b8761215c565b6001600160a01b0386811688528b16602088015260408088018d905260608801919091529116608086015290151560a085015251638dabdc8360e01b81526101e06004820152926129df6129d26129c56129b861098c8b80613130565b6109b460208c018c613130565b6109dc60408b018b613130565b610a0460608a018a613130565b90608088013588360392609e19840182121561127c578681036101e31901610264880152612a23918a0190610acb610ac0610aa5610a8a610a6f610a618780613130565b916001600160a01b03612a3860a08b0161205e565b1661028487015260c089013561ffff811680910361127c576102a4870152612a6260e08a016120d5565b15156102c48701526101008901356102e487015261012089013561030487015261014089013590601e190181121561127c578801602081359101926001600160401b03821161127c578160051b3603841361127c578681036101e3190161032488015281815291928692602001915f5b81811061307c57505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190612b3360e48301612701565b6001600160a01b038981166101848401526b033b2e3c9fd0803ce80000006101a48401525f6101c48401819052929091039183917f0000000000000000000000000000000000000000000000000000000000000000165af194851561124f5787915f945f9761302c575b5090600491848989612d32612bc060e0612bb960c0860161253b565b940161310f565b610de861ffff60405195612bd38761210a565b8d60018060a01b03169a878c809952602081019760018060a01b03169d8e8952604082018d60018060a01b03168152606083019160018060a01b03168252608083019b60018060a01b03168c528560a084019516855260c08301971515885260e08301995f8b5261010084019b60018d525f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790555f838152600a602052604090206007198101612fe2575b50600b54600160401b8110156112805786610e73826001612d989401600b5561254a565b612da66101408a018a6130da565b9b905060028c01809c11610f7d57612dbd8c613181565b9b6040519c612dcc908e612177565b808d52612dd890613181565b60208d019b90601f1901368d376001600160a01b038416612df88e613198565b526001600160a01b0316612e0b8d6131a5565b525f5b612e1c6101408c018c6130da565b9050811015612e7257612e336101408c018c6130da565b821015610f9157612e48908260051b016124e2565b906002810191828211610f7d57612e628f936001946131b5565b90838060a01b0316905201612e0e565b50929598509295989990939699863b1561127c576040805163251b648160e21b8152600481018890526024810191909152915160448301819052829160648301915f5b818110612fc05750505090805f920381838a5af1801561124f57612fab575b5060025480612f32575b50604080516001600160a01b0397881681526020810192909252810182905260608101919091529316927ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b90608090a49190565b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b15612fa757906024859260405194859384926301aba89b60e71b845260048401525af180156126ce5715612ede57612f9d838092612177565b6126ca575f612ede565b8480fd5b612fb89192505f90612177565b5f905f612ed4565b82516001600160a01b0316845285945060209384019390920191600101612eb5565b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155613026906112d4565b5f612d74565b9450955090506040833d604011613074575b8161304b60409383612177565b8101031261127c576004879161306c60206130658761311c565b960161311c565b969091612b9d565b3d915061303e565b919493509160019060209081906001600160a01b0361309a8961205e565b16815201950191019187939492612ad2565b6130b860a085016124e2565b94612927565b506107d06130d461ffff6113f960c0880161253b565b1161289a565b903590601e198136030182121561127c57018035906001600160401b03821161127c57602001918160051b3603831361127c57565b35801515810361127c5790565b51906001600160a01b038216820361127c57565b9035601e198236030181121561127c5701602081359101916001600160401b03821161127c57813603831361127c57565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b0381116112805760051b60200190565b805115610f915760200190565b805160011015610f915760400190565b8051821015610f915760209160051b01019056fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212203190683f5d6bc5abb39a655d737ec2428316f3ace65c6ab0d982473f4e38da5864736f6c634300082300336080806040523460395760017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005561078c908161003e8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c806309ad4dd9146102015780631698755f146101d257806332f289cf14610187578063379607f5146101615780634e71d92d1461011a57806370a08231146100e3578063d5d44d80146100c55763f59e38b714610071575f80fd5b346100c15760403660031901126100c15761008a610249565b61009261025f565b6001600160a01b039182165f908152600160209081526040808320949093168252928352819020549051908152f35b5f80fd5b60203660031901126100c1576100e16100dc610249565b6104bd565b005b346100c15760203660031901126100c1576001600160a01b03610104610249565b165f525f602052602060405f2054604051908152f35b346100c1575f3660031901126100c15761013261051c565b335f525f602052602061014860405f2054610669565b60015f5160206107375f395f51905f5255604051908152f35b346100c15760203660031901126100c15761017a61051c565b6020610148600435610669565b346100c15760203660031901126100c15760206101486101a5610249565b6101ad61051c565b335f9081526001845260408082206001600160a01b0384168352855290205490610554565b346100c15760403660031901126100c15760206101486101f0610249565b6101f861051c565b60243590610554565b346100c15760603660031901126100c15761023661021d610249565b61022561025f565b61022d61051c565b604435916102d9565b60015f5160206107375f395f51905f5255005b600435906001600160a01b03821682036100c157565b602435906001600160a01b03821682036100c157565b90601f8019910116810190811067ffffffffffffffff82111761029757604052565b634e487b7160e01b5f52604160045260245ffd5b919082039182116102b857565b634e487b7160e01b5f52601160045260245ffd5b919082018092116102b857565b6001600160a01b03169190821580156104ac575b61049d5781156103f5576040516370a0823160e01b81523060048201526001600160a01b03919091169190602081602481865afa90811561042e575f9161046b575b50604051916323b872dd60e01b5f52336004523060245260445260205f60648180875af160015f511481161561044c575b826040525f60605215610439576370a0823160e01b8252306004830152602082602481865afa801561042e575f906103fa575b61039d92506102ab565b9182156103f557805f52600160205260405f20825f5260205260405f206103c58482546102cc565b90556040519283527f5d104c62f50449fadfe6f4013c8f36588d32737f94b5ac9b83ddad33b3e1ffdf60203394a4565b505050565b506020823d602011610426575b8161041460209383610275565b810103126100c15761039d9151610393565b3d9150610407565b6040513d5f823e3d90fd5b82635274afe760e01b5f5260045260245ffd5b600181151661046257833b15153d151616610360565b823d5f823e3d90fd5b90506020813d602011610495575b8161048660209383610275565b810103126100c157515f61032f565b3d9150610479565b63d92e233d60e01b5f5260045ffd5b506001600160a01b038116156102ed565b6001600160a01b0316801561049d57341561051957805f525f60205260405f206104e83482546102cc565b9055604051903482527f4e45da441832cf53bdaa69235704fc0575e68210f459ee1562911024b12967d560203393a3565b50565b60025f5160206107375f395f51905f5254146105455760025f5160206107375f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b811561065a57335f52600160205260405f2060018060a01b0382165f5260205260405f2054808311610644578261058a916102ab565b335f52600160205260405f2060018060a01b0383165f5260205260405f205560018060a01b031660405163a9059cbb60e01b5f52336004528260245260205f60448180865af160015f5114811615610625575b8160405215610612578281527fdbc1ea3a8459e4c7e11fb385b52bbb5cc8c8ab85eec5d883ac9aa78c171f514160203392a390565b50635274afe760e01b5f5260045260245ffd5b600181151661063b57823b15153d1516166105dd565b503d5f823e3d90fd5b8263cf47918160e01b5f5260045260245260445ffd5b636165515360e11b5f5260045ffd5b801561065a57335f525f60205260405f2054808211610720578161068c916102ab565b335f525f60205260405f20555f80808084335af13d1561071b573d67ffffffffffffffff811161029757604051906106ce601f8201601f191660200183610275565b81525f60203d92013e5b1561070c576040518181527fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a60203392a290565b6312171d8360e31b5f5260045ffd5b6106d8565b9063cf47918160e01b5f5260045260245260445ffdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220dbbc16195d46dd822a5bbc7c7a2c8ac6b3a2c13959882c7f071ff2c011021a2464736f6c6343000823003360c03461015f57601f6112db38819003918201601f19168301916001600160401b038311848410176101635780849260609460405283398101031261015f5780516001600160a01b038116919082900361015f5760208101516001600160a01b0381169182820361015f5760400151916001600160a01b0383169081840361015f57841561014c57600180546001600160a01b03199081169091555f80549182168717815560405196916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005515908115610143575b506101345760805260a05261116390816101788239608051816103cf015260a05181818161021301526107aa0152f35b63d92e233d60e01b5f5260045ffd5b9050155f610104565b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c908163032bbf4f146106235750806319165587146105df578063384711cc1461058f5780634cfc4d30146105715780635ad7fc171461053a5780635bb478081461049d578063715018a61461047e57806379ba5097146103fe57806382589038146103ba578063892823f7146103445780638da5cb5b1461031d578063a3f8eace146102cd578063b224cf641461026a578063c45a015514610242578063c4b7de97146101fe578063d79779b2146101c3578063d8fb93371461018b578063e30c3978146101635763f2fde38b146100ed575f80fd5b3461015f57602036600319011261015f5761010661065a565b61010e610e1b565b60018060a01b0316806bffffffffffffffffffffffff60a01b600154161760015560018060a01b035f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b5f80fd5b3461015f575f36600319011261015f576001546040516001600160a01b039091168152602090f35b3461015f57602036600319011261015f576001600160a01b036101ac61065a565b165f526003602052602060405f2054604051908152f35b3461015f57602036600319011261015f576001600160a01b036101e461065a565b165f5260036020526020600160405f200154604051908152f35b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f576002546040516001600160a01b039091168152602090f35b3461015f57602036600319011261015f576001600160a01b0361028b61065a565b165f526003602052606060405f2061ffff600860018060a01b0360078401541692015460405192835260018060a01b038116602084015260a01c166040820152f35b3461015f57602036600319011261015f576001600160a01b036102ee61065a565b165f526003602052602061031560405f2061030f60038201549142906110b4565b90610670565b604051908152f35b3461015f575f36600319011261015f575f546040516001600160a01b039091168152602090f35b3461015f5760a036600319011261015f5761035d61065a565b6044356001600160a01b038116810361015f576064356001600160a01b038116810361015f576084359161ffff8316830361015f576103a79361039e610da6565b60243590610adc565b60015f51602061110e5f395f51905f5255005b3461015f575f36600319011261015f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461015f575f36600319011261015f57600154336001600160a01b0382160361046b576001600160a01b03199081166001555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461015f575f36600319011261015f576317d5c96560e11b5f5260045ffd5b3461015f57602036600319011261015f576104b661065a565b6104be610e1b565b600254906001600160a01b03821661052c576001600160a01b031690811561051d576001600160a01b03191681176002556040519081527f1edf3afd4ac789736e00d216cd88be164ddcef26a6eedcc30cdb0cb62f3741b190602090a1005b63d92e233d60e01b5f5260045ffd5b62dc149f60e41b5f5260045ffd5b3461015f57604036600319011261015f5761055361065a565b6024356001600160a01b038116810361015f5761056f91610a3d565b005b3461015f575f36600319011261015f57602060405163096601808152f35b3461015f57602036600319011261015f576001600160a01b036105b061065a565b165f526003602052602061031560405f2061030f6105d76001830154600384015490610670565b9142906110b4565b3461015f57602036600319011261015f57602061060a6105fd61065a565b610605610da6565b610705565b60015f51602061110e5f395f51905f5255604051908152f35b3461015f57602036600319011261015f576020906001600160a01b0361064761065a565b165f5260038252600260405f2001548152f35b600435906001600160a01b038216820361015f57565b9190820180921161067d57565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561067d57565b81156106ae570490565b634e487b7160e01b5f52601260045260245ffd5b9190820391821161067d57565b90601f8019910116810190811067ffffffffffffffff8211176106f157604052565b634e487b7160e01b5f52604160045260245ffd5b6002549091905f906001600160a01b031615610a2e576001600160a01b038381165f81815260036020526040902060078101805491969294909390911633141580610a17575b610a08576107594287610dde565b600386019586549687156109fd57905f600892556001810161077c898254610670565b90550161271061079461ffff835460a01c1689610691565b04926107a084896106c2565b9460018060a01b037f0000000000000000000000000000000000000000000000000000000000000000169260405163095ea7b360e01b5f52846004528a60245260205f604481808d5af19060015f51148216156109ee575b60405215610938575b856108c7575b5085610844575b505050507f82e416ba72d10e709b5de7ac16f5f49ff1d94f22d55bf582d353d3c313a1e8dd9160409182519182526020820152a2565b546001600160a01b0316823b156108c3576040516309ad4dd960e01b81526001600160a01b03918216600482015291166024820152604481018590529082908290606490829084905af180156108b8576108a0575b808061080e565b6108ab8280926106cf565b6108b55780610899565b80fd5b6040513d84823e3d90fd5b8380fd5b546001600160a01b0316833b1561015f576040516309ad4dd960e01b81526001600160a01b0391821660048201529083166024820152604481018690525f8160648183885af1801561092d5715610807576109259194505f906106cf565b5f925f610807565b6040513d5f823e3d90fd5b60405163095ea7b360e01b5f52846004525f60245260205f604481808d5af19060015f51148216156109d6575b604052156109a25760405163095ea7b360e01b5f52846004528a60245260205f604481808d5af19060015f51148216156109b5575b604052610801575b87635274afe760e01b5f5260045260245ffd5b9060018115166109cd57893b15153d1516169061099a565b503d5f823e3d90fd5b9060018115166109cd57893b15153d15161690610965565b90893b15153d151616906107f8565b505f96505050505050565b630da3333b60e01b5f5260045ffd5b5060088601546001600160a01b031633141561074b565b631966391b60e11b5f5260045ffd5b6002546001600160a01b03163303610a2e576001600160a01b03169081158015610acb575b61051d575f82815260036020526040902060070180546001600160a01b039283169392169190838314610ac55780546001600160a01b031916841790557f38f9c71383b6e3fe639172c6b3a3d4418fa722b4abf99bfd8e31f92bd5ea23f05f80a4565b50505050565b506001600160a01b03811615610a62565b92936001600160a01b038416939291841561051d576002546001600160a01b031615610a2e57610b0c3385610e4f565b15610d97578015610cc8576001600160a01b038316158015610d86575b8015610d77575b610d68576040516370a0823160e01b8152306004820152602081602481895afa90811561092d575f91610d36575b50604051916323b872dd60e01b5f52336004523060245260445260205f606481808a5af160015f5114811615610d17575b826040525f60605215610d04576370a0823160e01b8252306004830152602082602481895afa801561092d575f90610cd0575b610bcc92506106c2565b948515610cc857610bf492855f52600360205260405f2094610bee4287610dde565b85610fa3565b600481018054610c14610c078683610670565b9180610cb4575f90610691565b6309660180860286810463096601800361067d57610c368391610c3b93610670565b6106a4565b9155426005830155610c4d8142610670565b60068301556309660180036309660180811161067d57610c6d90426106c2565b90816002820155610c7f848254610670565b905560405192835260208301527f967ad762aa9070ada8db64577288e214771e89667066ae38e8750cb8a86c542960403393a3565b610cc24260068701546106c2565b90610691565b505050505050565b506020823d602011610cfc575b81610cea602093836106cf565b8101031261015f57610bcc9151610bc2565b3d9150610cdd565b85635274afe760e01b5f5260045260245ffd5b6001811516610d2d57863b15153d151616610b8f565b823d5f823e3d90fd5b90506020813d602011610d60575b81610d51602093836106cf565b8101031261015f57515f610b5e565b3d9150610d44565b63a7d7d0c560e01b5f5260045ffd5b5061271061ffff831611610b30565b506001600160a01b03861615610b29565b63ba13c3d960e01b5f5260045ffd5b60025f51602061110e5f395f51905f525414610dcf5760025f51602061110e5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b600590610deb83826110b4565b80610df557500155565b60048201610e048282546106c2565b9055610e1560038301918254610670565b90550155565b5f546001600160a01b0316330361046b57565b51906001600160a01b038216820361015f57565b5190811515820361015f57565b6002546001600160a01b0316908115610f9c57604051631e7945ad60e11b81526001600160a01b0390911660048201529061012090829060249082905afa90811561092d575f91610eb1575b50602001516001600160a01b0391821691161490565b9050610120813d8211610f94575b81610ecd61012093836106cf565b8101031261015f5760405190610120820182811067ffffffffffffffff8211176106f157604052610efd81610e2e565b8252610f0b60208201610e2e565b6020830152610f1c60408201610e2e565b6040830152610f2d60608201610e2e565b6060830152610f3e60808201610e2e565b608083015260a081015161ffff8116810361015f57610f88916101009160a0850152610f6c60c08201610e42565b60c0850152610f7d60e08201610e42565b60e085015201610e42565b6101008201525f610e9b565b3d9150610ebf565b5050505f90565b91600483015415806110a8575b611001575050600801546001600160a01b0380821692169190911480159290610feb575b5050610fdc57565b638a621fd960e01b5f5260045ffd5b61ffff91925081169160a01c1614155f80610fd4565b6007830180549295937fa92f5227e67257769e49f294586ea055f8d5714595dfdcc2d8a0cac8a3e50fbe93602093600892916001600160a01b031615611087575b500180546001600160b01b0319166001600160a01b0396871690811760a087901b61ffff60a01b1617909155905460405161ffff9590951685529095908516941692a4565b83546001600160a01b0319166001600160a01b03919091161783555f611042565b50600383015415610fb0565b90600482015491821580156110ff575b610f9c57600681015490818310156110f95792610cc2610c36926110f060056110f697015480926106c2565b946106c2565b90565b50505090565b5060058101548211156110c456fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220f824fefce66b4cf1569e7d371fa6370cdccc1c2f8a88bdedc443c0ce47e0831a64736f6c6343000823003360e0346100c157601f614e1938819003918201601f19168301916001600160401b038311848410176100c5578084926060946040528339810103126100c1578051906001600160a01b03821682036100c1576020810151906001600160a01b03821682036100c15760400151916001600160a01b03831683036100c15760805260a05260c052604051614d3f90816100da823960805181818160e90152610182015260a05181818160a5015261028d015260c051818181605d01526102b50152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c9081638dabdc831461011857508063c45a0155146100d4578063c4b7de97146100905763f1f5c99314610048575f80fd5b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5f80fd5b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461008c575f36600319011261008c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461008c576101e036600319011261008c576004359067ffffffffffffffff821161008c578160040191610160600319823603011261008c5760c036602319011261008c5760a03660e319011261008c57610184356001600160a01b038116939084900361008c577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316933385900361068e576101bd828061069d565b9050158015610679575b8015610663575b801561064b575b8015610632575b8015610619575b61057e5760848301916101006102026101fc85846106d0565b8061069d565b90501180156105f6575b80156105d3575b80156105b0575b801561058d575b61057e576020850194828652610124850135604082015260408152606081019581871067ffffffffffffffff88111761056a578660405281519020956128b1808301906060820183811067ffffffffffffffff82111761056a578a916107388539526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660808301527f0000000000000000000000000000000000000000000000000000000000000000811660a083015260e4359081169081900361008c5760c08201526101043561ffff811680910361008c5760e08201526101243561ffff811680910361008c576101008201526101443561ffff811680910361008c576101208201526101643561ffff811680910361008c576101408201526024356001600160a01b0381169081900361008c576101608201526044356001600160a01b0381169081900361008c576101808201526064356101a08201526084356101c082015260a4356101e082015260c43580151580910361008c5761020082015287926101c0910301905ff5801561055f576001600160a01b0316956103ce828061069d565b929060646103df602489018461069d565b9390976104076103ff6103f560448d018561069d565b95909c018461069d565b9290936106d0565b936040519a611d2194858d01998d8b1067ffffffffffffffff8c111761056a578d9c610515996104528f96610460948f6101409061047c9d61046e9b612fe9903981815201916106e5565b8d810360208f0152916106e5565b918a830360408c01526106e5565b9187830360608901526106e5565b84810360808601526105076104fc6104e16104c66104ab61049d8780610705565b60a0885260a08801916106e5565b6104b86020880188610705565b9087830360208901526106e5565b6104d36040870187610705565b9086830360408801526106e5565b6104ee6060860186610705565b9085830360608701526106e5565b926080810190610705565b9160808185039101526106e5565b9260a08301528660c083015260e08201526101a4356101008201526101206101c43591015203905ff5801561055f57604080516001600160a01b0390921682526020820192909252f35b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b635e765b2560e11b5f5260045ffd5b506101006105a861059e85846106d0565b608081019061069d565b905011610221565b506101006105cb6105c185846106d0565b606081019061069d565b90501161021a565b506101006105ee6105e485846106d0565b604081019061069d565b905011610213565b5061010061061161060785846106d0565b602081019061069d565b90501161020c565b5061080061062a606485018461069d565b9050116101e3565b50610200610643604485018461069d565b9050116101dc565b50601061065b602485018461069d565b9050116101d5565b50610671602484018361069d565b9050156101ce565b506040610686838061069d565b9050116101c7565b631966391b60e11b5f5260045ffd5b903590601e198136030182121561008c570180359067ffffffffffffffff821161008c5760200191813603831361008c57565b903590609e198136030182121561008c570190565b908060209392818452848401375f828201840152601f01601f1916010190565b9035601e198236030181121561008c57016020813591019167ffffffffffffffff821161008c57813603831361008c5756fe610220604052346104b1576040516128b138819003601f8101601f191683016001600160401b038111848210176104b557839282916040528339810103906101c082126104b15761004f816104c9565b602082015190916001600160a01b0382168083036104b15760408201516001600160a01b038116938482036104b15760a0605f198801126104b1576040519660a088016001600160401b038111898210176104b5576040526100b3606086016104c9565b88526100c1608086016104dd565b95602089019687526100d560a087016104dd565b60408a019081526100e860c088016104dd565b60608b015260c06100fb60e089016104dd565b60808c019081529360ff1901126104b1576040519860c08a016001600160401b0381118b8210176104b55760405261013661010089016104c9565b8a5261014561012089016104c9565b9860208b019a8a8c526101408a015197604082019889526101608b015199606083019a8b526101a06101808d01519c608085019d8e5201519c8d801515036104b15760a084019d8e5260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556001600160a01b0386169788159283156104a8575b50821561049f575b50811561048d575b5061047e578d516001600160a01b031615801561046e575b801561045e575b8015610451575b8015610440575b8015610415575b61040657885180159081156103f5575b506103e65761ffff978896879560a05260c05260e0526101005260018060a01b0390511660805260018060a01b038b51169a6001549c60018060a01b039051166101205260018060a01b039051166101405251166101605251166101805251166101a052516101c052516101e052516102005260ff60a01b9051151560a01b169160018060a81b03191617176001556040516123c490816104ed823960805181818161029e01528181610a7301528181610bd30152818161112301528181611eab0152611ff3015260a05181818161044801528181610605015281816106e90152610f7f015260c051818181610f350152611347015260e05181818161040401528181611edb0152611f6d01526101005181818161021c015261152c01526101205181818161104d015281816114e401526115be0152610140518181816111670152611596015261016051818181610b08015281816113b901526121760152610180518181816110cd01526121a701526101a051818181610aca01526116a401526101c0518181816103cc015281816105c1015261183e01526101e0518181816111f4015281816118850152611a1901526102005181818161048e015281816118b80152611a4f0152f35b63bc0ecfe360e01b5f5260045ffd5b6001600160801b031090505f61021b565b637a34030f60e01b5f5260045ffd5b5089518b51810180911161042c576107d01061020b565b634e487b7160e01b5f52601160045260245ffd5b5061271061ffff8851161015610204565b5061ffff875116156101fd565b5061271061ffff865116116101f6565b5061271061ffff845116116101ef565b63d92e233d60e01b5f5260045ffd5b6001600160a01b03161590505f6101d7565b1591505f6101cf565b1592505f6101c7565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036104b157565b519061ffff821682036104b15756fe60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f00000000000000000000000000000000000000000000000000000000000000006112ac565b3461020357602036600319011261020357600435801515809103610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000000166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f0000000000000000000000000000000000000000000000000000000000000000611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448401527f00000000000000000000000000000000000000000000000000000000000000001660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000000016101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f00000000000000000000000000000000000000000000000000000000000000009061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000000080612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000000090611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f00000000000000000000000000000000000000000000000000000000000000001682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c6343000823003361012060405234610ee557611d218038038061001a81610ee9565b92833981019061014081830312610ee55780516001600160401b038111610ee55782610047918301610f0e565b60208201519091906001600160401b038111610ee55783610069918301610f0e565b60408201519091906001600160401b038111610ee5578461008b918301610f0e565b60608201519094906001600160401b038111610ee557816100ad918401610f0e565b60808301519091906001600160401b038111610ee557830160a081830312610ee55760405160a081016001600160401b038111828210176107195760405281516001600160401b038111610ee55783610107918401610f0e565b815260208201516001600160401b038111610ee55783610128918401610f0e565b6020820190815260408301519091906001600160401b038111610ee55784610151918501610f0e565b6040820190815260608401519093906001600160401b038111610ee5578561017a918301610f0e565b6060830190815260808201519095906001600160401b038111610ee5576101a19201610f0e565b94608082019586526101b560a08801610f5f565b996101c260c08901610f5f565b986101cf60e08a01610f5f565b906101206101008b01519a01519b80519060018060401b0382116107195760035490600182811c92168015610edb575b60208310146106fb5781601f849311610e65575b50602090601f8311600114610dff575f92610df4575b50508160011b915f199060031b1c1916176003555b8051906001600160401b0382116107195760045490600182811c92168015610dea575b60208310146106fb5781601f849311610d74575b50602090601f8311600114610d0e575f92610d03575b50508160011b915f199060031b1c1916176004555b6001600160a01b038c16158015610cf2575b8015610ce1575b610cd2578b60805260a0528860c05287158015610cc6575b610cb75760e08890526101008a90528051906001600160401b0382116107195760055490600182811c92168015610cad575b60208310146106fb5781601f849311610c53575b50602090601f8311600114610bed575f92610be2575b50508160011b915f199060031b1c1916176005555b8051906001600160401b0382116107195760065490600182811c92168015610bd8575b60208310146106fb5781601f849311610b62575b50602090601f8311600114610afc575f92610af1575b50508160011b915f199060031b1c1916176006555b518051906001600160401b0382116107195760075490600182811c92168015610ae7575b60208310146106fb5781601f849311610a71575b50602090601f8311600114610a0b575f92610a00575b50508160011b915f199060031b1c1916176007555b518051906001600160401b0382116107195760085490600182811c921680156109f6575b60208310146106fb5781601f849311610980575b50602090601f831160011461091a575f9261090f575b50508160011b915f199060031b1c1916176008555b518051906001600160401b0382116107195760095490600182811c92168015610905575b60208310146106fb5781601f84931161088f575b50602090601f8311600114610829575f9261081e575b50508160011b915f199060031b1c1916176009555b518051906001600160401b03821161071957600a5490600182811c92168015610814575b60208310146106fb5781601f84931161079e575b50602090601f8311600114610738575f9261072d575b50508160011b915f199060031b1c191617600a555b518051906001600160401b03821161071957600b5490600182811c9216801561070f575b60208310146106fb5781601f849311610685575b50602090601f831160011461061f575f92610614575b50508160011b915f199060031b1c191617600b555b828103908111610600576105a691610f73565b806105f0575b604051610d3a9081610fe782396080518181816101cb0152610261015260a0518161059d015260c05181610496015260e05181610600015261010051816101430152f35b6105f991610f73565b5f806105ac565b634e487b7160e01b5f52601160045260245ffd5b015190505f8061057e565b600b5f9081528281209350601f198516905b81811061066d5750908460019594939210610655575b505050811b01600b55610593565b01515f1960f88460031b161c191690555f8080610647565b92936020600181928786015181550195019301610631565b8281111561056857600b5f52909150601f830160051c7f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9602085106106f3575b849392601f0160051c82900391015f5b8281106106e3575050610568565b5f818301558594506001016106d5565b5f91506106c5565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610554565b634e487b7160e01b5f52604160045260245ffd5b015190505f8061051b565b600a5f9081528281209350601f198516905b818110610786575090846001959493921061076e575b505050811b01600a55610530565b01515f1960f88460031b161c191690555f8080610760565b9293602060018192878601518155019501930161074a565b8281111561050557600a5f52909150601f830160051c7fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a86020851061080c575b849392601f0160051c82900391015f5b8281106107fc575050610505565b5f818301558594506001016107ee565b5f91506107de565b91607f16916104f1565b015190505f806104b8565b60095f9081528281209350601f198516905b818110610877575090846001959493921061085f575b505050811b016009556104cd565b01515f1960f88460031b161c191690555f8080610851565b9293602060018192878601518155019501930161083b565b828111156104a25760095f52909150601f830160051c7f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af602085106108fd575b849392601f0160051c82900391015f5b8281106108ed5750506104a2565b5f818301558594506001016108df565b5f91506108cf565b91607f169161048e565b015190505f80610455565b60085f9081528281209350601f198516905b8181106109685750908460019594939210610950575b505050811b0160085561046a565b01515f1960f88460031b161c191690555f8080610942565b9293602060018192878601518155019501930161092c565b8281111561043f5760085f52909150601f830160051c7ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3602085106109ee575b849392601f0160051c82900391015f5b8281106109de57505061043f565b5f818301558594506001016109d0565b5f91506109c0565b91607f169161042b565b015190505f806103f2565b60075f9081528281209350601f198516905b818110610a595750908460019594939210610a41575b505050811b01600755610407565b01515f1960f88460031b161c191690555f8080610a33565b92936020600181928786015181550195019301610a1d565b828111156103dc5760075f52909150601f830160051c7fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860208510610adf575b849392601f0160051c82900391015f5b828110610acf5750506103dc565b5f81830155859450600101610ac1565b5f9150610ab1565b91607f16916103c8565b015190505f8061038f565b60065f9081528281209350601f198516905b818110610b4a5750908460019594939210610b32575b505050811b016006556103a4565b01515f1960f88460031b161c191690555f8080610b24565b92936020600181928786015181550195019301610b0e565b828111156103795760065f52909150601f830160051c7ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f60208510610bd0575b849392601f0160051c82900391015f5b828110610bc0575050610379565b5f81830155859450600101610bb2565b5f9150610ba2565b91607f1691610365565b015190505f8061032d565b60055f9081528281209350601f198516905b818110610c3b5750908460019594939210610c23575b505050811b01600555610342565b01515f1960f88460031b161c191690555f8080610c15565b92936020600181928786015181550195019301610bff565b828111156103175790915060055f5260205f20601f840160051c9060208510610ca5575b849392601f0160051c82900391015f5b828110610c95575050610317565b5f81830155859450600101610c87565b5f9150610c77565b91607f1691610303565b6305d7ba1960e11b5f5260045ffd5b508760021c8a116102d1565b63d92e233d60e01b5f5260045ffd5b506001600160a01b038116156102b9565b506001600160a01b038a16156102b2565b015190505f8061028b565b60045f9081528281209350601f198516905b818110610d5c5750908460019594939210610d44575b505050811b016004556102a0565b01515f1960f88460031b161c191690555f8080610d36565b92936020600181928786015181550195019301610d20565b828111156102755760045f52909150601f830160051c7f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b60208510610de2575b849392601f0160051c82900391015f5b828110610dd2575050610275565b5f81830155859450600101610dc4565b5f9150610db4565b91607f1691610261565b015190505f80610229565b60035f9081528281209350601f198516905b818110610e4d5750908460019594939210610e35575b505050811b0160035561023e565b01515f1960f88460031b161c191690555f8080610e27565b92936020600181928786015181550195019301610e11565b828111156102135760035f52909150601f830160051c7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b60208510610ed3575b849392601f0160051c82900391015f5b828110610ec3575050610213565b5f81830155859450600101610eb5565b5f9150610ea5565b91607f16916101ff565b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761071957604052565b81601f82011215610ee5578051906001600160401b03821161071957610f3d601f8301601f1916602001610ee9565b9282845260208383010111610ee557815f9260208093018386015e8301015290565b51906001600160a01b0382168203610ee557565b6001600160a01b0316908115610fd357600254908082018092116106005760207fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef915f9360025584845283825260408420818154019055604051908152a3565b63ec442f0560e01b5f525f60045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c806306fdde031461073b578063095ea7b31461069357806318160ddd1461067657806323b872dd1461063e578063313ce56714610623578063378dc3dc146105e957806342966c68146105cc578063536dac9b1461058857806353cd512a146104fc57806370a08231146104c55780637165485d146104815780637284e4161461046657806379cc67901461043457806395d89b4114610340578063a9059cbb1461030f578063abb1dc44146101fa578063d5f39488146101b6578063dd62ed3e14610166578063e029607c1461012c5763fb7f21eb146100f5575f80fd5b34610128575f36600319011261012857610124610110610966565b6040519182916020835260208301906107f6565b0390f35b5f80fd5b34610128575f3660031901126101285760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346101285760403660031901126101285761017f61081a565b610187610830565b6001600160a01b039182165f908152600160209081526040808320949093168252928352819020549051908152f35b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610128575f366003190112610128576060608060405161021a81610846565b8281528260208201528260408201528280820152015261029461023b610966565b610124610246610898565b6102a2610251610ac8565b9160405195869560018060a01b037f00000000000000000000000000000000000000000000000000000000000000001687526080602088015260808701906107f6565b9085820360408701526107f6565b838103606085015260806102fe6102ec6102da6102c8865160a0875260a08701906107f6565b602087015186820360208801526107f6565b604086015185820360408701526107f6565b606085015184820360608601526107f6565b9201519060808184039101526107f6565b346101285760403660031901126101285761033561032b61081a565b6024359033610bc3565b602060405160018152f35b34610128575f366003190112610128576040515f6004548060011c9060018116801561042a575b602083108114610416578285529081156103f25750600114610394575b6101248361011081850382610876565b60045f9081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b8082106103d857509091508101602001610110610384565b9192600181602092548385880101520191019092916103c0565b60ff191660208086019190915291151560051b840190910191506101109050610384565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610367565b346101285760403660031901126101285761046461045061081a565b6024359061045f823383610b20565b610c80565b005b34610128575f36600319011261012857610124610110610898565b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610128576020366003190112610128576001600160a01b036104e661081a565b165f525f602052602060405f2054604051908152f35b34610128575f36600319011261012857610550610517610ac8565b61012481519161057a60208201519161056c604082015161055e6080606085015194015195604051998a9960a08b5260a08b01906107f6565b9089820360208b01526107f6565b9087820360408901526107f6565b9085820360608701526107f6565b9083820360808501526107f6565b34610128575f366003190112610128576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346101285760203660031901126101285761046460043533610c80565b34610128575f3660031901126101285760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610128575f36600319011261012857602060405160128152f35b346101285760603660031901126101285761033561065a61081a565b610662610830565b60443591610671833383610b20565b610bc3565b34610128575f366003190112610128576020600254604051908152f35b34610128576040366003190112610128576106ac61081a565b602435903315610728576001600160a01b031690811561071557335f52600160205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b634a1406b160e11b5f525f60045260245ffd5b63e602df0560e01b5f525f60045260245ffd5b34610128575f366003190112610128576040515f6003548060011c906001811680156107ec575b602083108114610416578285529081156103f2575060011461078e576101248361011081850382610876565b60035f9081527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b8082106107d257509091508101602001610110610384565b9192600181602092548385880101520191019092916107ba565b91607f1691610762565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361012857565b602435906001600160a01b038216820361012857565b60a0810190811067ffffffffffffffff82111761086257604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff82111761086257604052565b604051905f6006548060011c916001821691821561095c575b60208410831461041657838652859290811561093d57506001146108de575b6108dc92500383610876565b565b5060065f90815290917ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f5b8183106109215750509060206108dc928201016108d0565b6020919350806001915483858901015201910190918492610909565b602092506108dc94915060ff191682840152151560051b8201016108d0565b92607f16926108b1565b604051905f6005548060011c9160018216918215610a08575b60208410831461041657838652859290811561093d57506001146109a9576108dc92500383610876565b5060055f90815290917f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b8183106109ec5750509060206108dc928201016108d0565b60209193508060019154838589010152019101909184926109d4565b92607f169261097f565b90604051915f8154908160011c9260018316928315610abe575b602085108414610416578487528693908115610a9c5750600114610a58575b506108dc92500383610876565b90505f9291925260205f20905f915b818310610a805750509060206108dc928201015f610a4b565b6020919350806001915483858901015201910190918492610a67565b9050602092506108dc94915060ff191682840152151560051b8201015f610a4b565b93607f1693610a2c565b60405190610ad582610846565b81610ae06007610a12565b8152610aec6008610a12565b6020820152610afb6009610a12565b6040820152610b0a600a610a12565b60608201526080610b1b600b610a12565b910152565b6001600160a01b039081165f818152600160209081526040808320948616835293905291909120549291905f198410610b5a575b50505050565b828410610ba0578015610728576001600160a01b03821615610715575f52600160205260405f209060018060a01b03165f5260205260405f20910390555f808080610b54565b508290637dc7a0d960e11b5f5260018060a01b031660045260245260445260645ffd5b6001600160a01b0316908115610c6d576001600160a01b0316918215610c5a57815f525f60205260405f2054818110610c4157817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f525f84520360405f2055845f525f825260405f20818154019055604051908152a3565b8263391434e360e21b5f5260045260245260445260645ffd5b63ec442f0560e01b5f525f60045260245ffd5b634b637e8f60e11b5f525f60045260245ffd5b9091906001600160a01b03168015610c6d57805f525f60205260405f2054838110610cea576020845f94957fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef938587528684520360408620558060025403600255604051908152a3565b915063391434e360e21b5f5260045260245260445260645ffdfea26469706673582212201aca4a2b55465a13b08ec36674fca845ba424b771f3ea8c117e712cc7ec430c264736f6c63430008230033a2646970667358221220272ca8beeb8120e5fcea1f6abad3910174ee29119b3514eea8a2ceccb1bdce8764736f6c63430008230033","sourceMap":"1002:13720:23:-:0;;;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;1273:26:0;;1269:95;;1002:13720:23;;;-1:-1:-1;;;;;;1002:13720:23;;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;3052:40:0;;-1:-1:-1;3052:40:0;2093:20:1;1505:66:13;1002:13720:23;1433:12;;1002:13720;1485:5;1002:13720;;1530:5;;1002:13720;;1574:1;1002:13720;3914:25;;:30;3910:56;;1530:5;3976:17;1002:13720;3976:17;;;;;1002:13720;;;4021:15;;;;;;;;;-1:-1:-1;4021:15:23;;;-1:-1:-1;1002:13720:23;4062:2;1002:13720;;;4050:14;4046:47;;4103:26;;4139:31;1002:13720;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;4222:5;1002:13720;4190:55;;1002:13720;4229:5;4190:55;;;1002:13720;4236:3;4190:55;;;1002:13720;4241:3;4190:55;;;;1002:13720;;;;4180:65;1002:13720;;-1:-1:-1;;;;;;1002:13720:23;-1:-1:-1;;;;;;;;1002:13720:23;;;;;;;-1:-1:-1;;;1002:13720:23;;;;;4267:22;;;;;;;-1:-1:-1;;;;;4267:22:23;;;;;;;;;;;;-1:-1:-1;4267:22:23;;;;;4190:55;4255:34;;;1002:13720;;;4314:111;;;;-1:-1:-1;;;;;4314:111:23;;;;;;;;4190:55;4314:111;;;;;;4346:4;1002:13720;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;4314:111;;;-1:-1:-1;4314:111:23;;;;;1002:13720;4299:126;;;-1:-1:-1;;;;;1002:13720:23;4435:38;;;;;-1:-1:-1;1002:13720:23;;4435:38;1002:13720;;;;;;;;;4435:38;;4346:4;1530:5;4435:38;;1002:13720;4435:38;;;;;;;;-1:-1:-1;;4190:55:23;1002:13720;;;;;;4500:93;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;-1:-1:-1;;;;;4500:93:23;;;;;;;;;4190:55;4500:93;;;;;;;4346:4;1002:13720;;;;;;;;;;4500:93;;;;;;;;;1002:13720;4483:110;1002:13720;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;2093:20:1;1002:13720:23;;;1214:10;;;1002:13720;;4631:37;;1214:10;;;;;;;4603:13;1002:13720;1214:10;;;;1002:13720;;1214:10;;;;;1002:13720;1214:10;;;;;;;;;;1002:13720;;;;;;;;4190:55;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3976:17;1002:13720;;;;;;;;;;4103:26;1002:13720;;;;;;;;;;;;-1:-1:-1;;;1002:13720:23;;;1530:5;1002:13720;4435:38;1002:13720;;4500:93;1002:13720;;;;;;;;;;;4500:93;-1:-1:-1;;;1002:13720:23;;;1530:5;1002:13720;4435:38;1002:13720;;4435:38;;;;-1:-1:-1;4435:38:23;;:::i;:::-;-1:-1:-1;4435:38:23;;;;1002:13720;;;-1:-1:-1;1002:13720:23;;;;;4435:38;-1:-1:-1;1002:13720:23;;4314:111;1002:13720;;;-1:-1:-1;1002:13720:23;;1530:5;1002:13720;;-1:-1:-1;1002:13720:23;4046:47;4073:20;;;-1:-1:-1;4073:20:23;1530:5;-1:-1:-1;4073:20:23;4021:15;;;1002:13720;4021:15;;1002:13720;4021:15;;;;;;1002:13720;4021:15;;;:::i;:::-;;;1002:13720;;;;;;;;;;;;4021:15;;;;;;-1:-1:-1;4021:15:23;;3910:56;3953:13;;;-1:-1:-1;3953:13:23;1530:5;-1:-1:-1;3953:13:23;1269:95:0;1322:31;;;-1:-1:-1;1322:31:0;-1:-1:-1;1322:31:0;1002:13720:23;;-1:-1:-1;1322:31:0;1002:13720:23;;;;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;:::o","linkReferences":{}},"deployedBytecode":{"object":"6080806040526004361015610012575f80fd5b5f905f3560e01c90816327cca59f14612018575080632931861b14611fc3578063315226d914611b9157806334fcaa3714611ec35780633cf28b5a14611d465780633d3d2d5814611c7257806345fb206314611c47578063470ef5fc14611bb357806350e25ac214611b96578063523af32814611b9157806354a4931c14611b7457806354faf9c314611b0357806358373f0414611ade5780636499386614611aad5780636783774b14611a905780636cd5bce4146119ff5780636dc97d6a146119885780636e47a1881461191b5780636f471f2d146118c5578063715018a614611862578063767b7c16146117c157806379ba50971461173c5780638009b7bd146116f8578063858f5964146116b457806389a69bd8146116455780638a36a6bb1461161d5780638da5cb5b146115f65780638e8d8ec5146114e55780639b924452146114bd5780639beacf4a1461145e5780639c5693eb146107cf578063abb918d814610786578063b18f1db114610684578063c4b7de971461063f578063c50497ae14610618578063cf3cf573146105fa578063df41ead2146105d7578063e30c3978146105ae578063e68b52e714610570578063e7ed38bd1461034a578063f1f5c99314610305578063f2fde38b14610298578063f325a5fb1461027a578063f9b3b8d9146102475763ffcb6e9f1461020d575f80fd5b3461024457602036600319011261024457602061022b60043561254a565b905460405160039290921b1c6001600160a01b03168152f35b80fd5b5034610244576020366003190112610244576020906004358152600c8252604060018060a01b0391205416604051908152f35b50346102445780600319360112610244576020600354604051908152f35b5034610244576020366003190112610244576102b2612032565b6102ba6126ee565b600180546001600160a01b0319166001600160a01b0392831690811790915582549091167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5034610244576101203660031901126102445760643560443560243560a036608319011261056c5761037a6126ee565b6103e881118015610561575b8015610559575b801561054d575b8015610535575b801561051f575b8015610509575b80156104f3575b80156104e0575b80156104c9575b6104ba5760048035600255600391909155556005556001600160a01b036103e36124cc565b166001600160601b0360a01b60085416176008556103ff6124f6565b6008805461ffff60a01b191660a09290921b61ffff60a01b16919091179055610426612507565b6008805461ffff60b01b191660b09290921b61ffff60b01b1691909117905561044d612518565b6008805461ffff60c01b191660c09290921b61ffff60c01b16919091179055610474612529565b6008805461ffff60d01b191660d09290921b61ffff60d01b169190911790557f8f70233f68d766cfab4ff696858b5eba8fa61e09191134073df956473102569b8180a180f35b630256965f60e01b8452600484fd5b5061271061ffff6104d8612529565b1610156103be565b5061ffff6104ec612529565b16156103b7565b506103e861ffff610502612518565b16116103b0565b5061271061ffff610518612507565b16116103a9565b5061271061ffff61052e6124f6565b16116103a2565b506001600160a01b036105466124cc565b161561039b565b50620151808311610394565b50821561038d565b506126ac8211610386565b8380fd5b5034610244578060031936011261024457602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346102445780600319360112610244576001546040516001600160a01b039091168152602090f35b503461024457806003193601126102445760206040516717508f1956a800008152f35b50346102445780600319360112610244576020600254604051908152f35b503461024457806003193601126102445760206040516b033b2e3c9fd0803ce80000008152f35b50346102445780600319360112610244576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346102445760403660031901126102445761069e612032565b906024359182151590818403610782576106b790612562565b60038101546001600160a01b031633141580610767575b6107585760048101805460ff60b01b191694151560b01b60ff60b01b16949094179093559091829190600101546001600160a01b031690813b15610754578291602483926040519485938492639a9b567d60e01b845260048401525af18015610749576107385750f35b8161074291612177565b6102445780f35b6040513d84823e3d90fd5b5050fd5b632e7e4e5160e21b8352600483fd5b5082546001600160a01b0316331415806106ce5750836106ce565b8280fd5b50346102445760403660031901126102445760209060ff906040906001600160a01b036107b1612032565b168152600d8452818120602435825284522054166040519015158152f35b50606036600319011261127c576001600160401b036004351161127c576101606004353603600319011261127c576108056126ee565b61080d61280f565b60243515801561143c575b61142e5761082760443561228f565b9161010460043501350361141f5760025434036114105761084c60c46004350161253b565b61ffff60035491161180156113e1575b6113d257335f52600d60205260405f2061012460043501355f5260205260ff60405f2054166113c357602061089c610144600435016004356004016130da565b9050116113b457335f52600d60205260405f2061012460043501355f5260205260405f20600160ff1982541617905560018060a01b036108e060a4600435016124e2565b166113a05733925b6acecb8f27f4200f3a0000009261ffff60085460c01c169161090e60c46004350161253b565b61ffff61091f60e46004350161310f565b916040519561092d8761215c565b5f875260018060a01b038a1660208801528760408801526060870152166080850152151560a084015260405192638dabdc8360e01b84526101e06004850152610a186109f06109c86109a061098c600435600401600435600401613130565b6101606101e48b01526103448a0191613161565b6109b4602460043501600435600401613130565b8983036101e319016102048b015290613161565b6109dc604460043501600435600401613130565b8883036101e319016102248a015290613161565b610a04606460043501600435600401613130565b8783036101e3190161024489015290613161565b60043560848101359190360360a2190182121561127c576004610ad99281350101906101e31987820301610264880152610acb610ac0610aa5610a8a610a6f610a618780613130565b60a0885260a0880191613161565b610a7c6020880188613130565b908783036020890152613161565b610a976040870187613130565b908683036040880152613161565b610ab26060860186613130565b908583036060870152613161565b926080810190613130565b916080818503910152613161565b906001600160a01b03610af060043560a40161205e565b1661028486015260c4600435013561ffff811680910361127c576102a4860152610b1e60e4600435016120d5565b15156102c48601526004356101048101356102e48701526101248101356103048701526101448101359036036022190181121561127c576004908135010160208101926001600160401b0382351161127c57813560051b3603841361127c578681036101e319016103248801528135815291928692602001915f5b8135811061137057505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190610bfb60e48301612701565b336101848301526b033b2e3c9fd0803ce80000006101a48301526101c4820189905203815f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af193841561124f575f935f95611327575b50868486610e03610c7160c46004350161253b565b610de861ffff610c8560e46004350161310f565b926004604051610c948161210a565b60018060a01b0389168152602081019760018060a01b031688526040810199338b52606082019060018060a01b03168152608082019a5f8c528560a084019516855260c08301971515885260e083019960018b5261010084019b60018d5260018060a01b03165f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b51845460ff60b01b191690151560b01b60ff60b01b16178455565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790556001600160a01b0384165f908152600a602052604090206007198101611294575b50600b54600160401b8110156112805784610e73826001610e979401600b5561254a565b81546001600160a01b0393841660039290921b91821b9390911b1916919091179055565b610eac610144600435016004356004016130da565b979050600288018811610f7d57610ee06002610ec9818b01613181565b99610ed76040519b8c612177565b01808a52613181565b601f19013660208a013733610ef489613198565b526001600160a01b0316610f07886131a5565b525f5b610f1f610144600435016004356004016130da565b9050811015610fa557610f3d610144600435016004356004016130da565b821015610f9157610f52908260051b016124e2565b90600281018111610f7d57600191610f6d600283018b6131b5565b90838060a01b0316905201610f0a565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5085876001600160a01b0387163b1561127c576040805163251b648160e21b81526001600160a01b03881660048201526024810191909152815160448201819052909182916064830191602001905f5b81811061125a57505f93928390039150829050836001600160a01b038c165af1801561124f5761123a575b50600254806111ad575b506110f9916110b29160405190858252826020830152600160408301526060820152339060018060a01b038916907ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b608060018060a01b038b1692a46024358452600c6020526040842080546001600160a01b0319166001600160a01b03881617905561273e565b916001604051916110c283612126565b84835260406020840191838352838060a01b0389168152600e602052209251835551151591019060ff801983541691151516179055565b60408051918252600160208301526001600160a01b038416917fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79190a260408051604435815260208101929092526001600160a01b03831691602435917ff58d88bf88870587ec1fdf8ab973f10a093d9dc3c1a243e32f41fa5d73eda1b791a360015f5160206131ca5f395f51905f5255604080516001600160a01b039283168152929091166020830152819081015b0390f35b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b1561123657906024869260405194859384926301aba89b60e71b845260048401525af1801561122b57908491611216575b5061102a565b8161122091612177565b610782578287611210565b6040513d86823e3d90fd5b8580fd5b6112479193505f90612177565b5f9186611020565b6040513d5f823e3d90fd5b82516001600160a01b0316845285945060209384019390920191600101610ff5565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155611321905b600854815461ffff60b01b191661ffff60b01b909116178155600854815461ffff60c01b191661ffff60c01b909116178155600854815461ffff60d01b191661ffff60d01b909116179055565b5f610e4f565b935093506040833d604011611368575b8161134460409383612177565b8101031261127c57611361602061135a8561311c565b940161311c565b935f610c5c565b3d9150611337565b919493509160019060209081906001600160a01b0361138e8961205e565b16815201950191019187939492610b99565b6113ae60a4600435016124e2565b926108e8565b630256965f60e01b5f5260045ffd5b630ced304360e01b5f5260045ffd5b6326b5197760e21b5f5260045ffd5b506107d061140a61ffff6113f960c46004350161253b565b1661ffff60085460c01c16906120e2565b1161085c565b637e6d78a560e01b5f5260045ffd5b631e5d0a3f60e11b5f5260045ffd5b62d532eb60e71b5f5260045ffd5b506024355f908152600c60205260409020546001600160a01b03161515610818565b3461127c57602036600319011261127c576001600160a01b0361147f612032565b165f908152600f60209081526040918290208054600182015460029092015484516001600160a01b0390921682529281019190915291820152606090f35b3461127c575f36600319011261127c576007546040516001600160a01b039091168152602090f35b3461127c57606036600319011261127c576114fe612032565b602435906044358015159182820361127c576115186126ee565b6001600160a01b031692831515806115d9575b6115ca57801580156115ba575b6113b4576115a07fb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e79360016040519161157083612126565b84835260208301908152875f52600e60205260405f209251835551151591019060ff801983541691151516179055565b60408051918252911515602082015290819081015b0390a2005b506001600160801b038111611538565b6349285dfb60e01b5f5260045ffd5b50835f52600960205260ff600460405f20015460b81c161561152b565b3461127c575f36600319011261127c575f546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c576006546040516001600160a01b039091168152602090f35b3461127c575f36600319011261127c5761165d61224e565b506111a960405161166d81612141565b61ffff60085460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461127c575f36600319011261127c57600154336001600160a01b03909116036117ae57600180546001600160a01b03199081169091555f805433928116831782556001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b63118cdaa760e01b5f523360045260245ffd5b3461127c57602036600319011261127c576117da612032565b6117e26126ee565b600754906001600160a01b03821661185357803b15611844576001600160a01b03166001600160a01b03199190911681176007556040519081527f56b32d3633fed72f97c4df44a78b5fa04f1d662d4bddebcd8a9b216d26d093ad90602090a1005b63d92e233d60e01b5f5260045ffd5b63a741a04560e01b5f5260045ffd5b3461127c575f36600319011261127c5761187a6126ee565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461127c57602036600319011261127c576001600160a01b036118e6612032565b165f52600e60205260405f2060ff6001825492015416906111a960405192839283909291602090604083019483521515910152565b3461127c57602036600319011261127c57611934612032565b61193c6126ee565b6001600160a01b03165f818152600f60205260408120818155600181018290556002018190557f30241dede93b23e050576be65d204d53b18e8c6d9f75006095bfd422094d87569080a2005b604036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c576119d2906119c0612048565b6119c861280f565b3391600401612847565b60015f5160206131ca5f395f51905f5255604080516001600160a01b039384168152919092166020820152f35b606036600319011261127c576004356001600160401b03811161127c57610160600319823603011261127c57611a33612048565b604435906001600160a01b03821680830361127c57611a5061280f565b6007546001600160a01b0316331480159190611a87575b50611a78576119d292600401612847565b63754f554b60e11b5f5260045ffd5b90501584611a67565b3461127c575f36600319011261127c576020600554604051908152f35b3461127c57602036600319011261127c576060611acb60043561228f565b9060405192835260208301526040820152f35b3461127c57602036600319011261127c57611af7612032565b50602060405160018152f35b3461127c57602036600319011261127c57611b1c612032565b611b246126ee565b6001600160a01b03168015611844576020817fae994ca926e252e299c3df7516cb609272a57bf80b0e0715297e55939f873420926001600160601b0360a01b6006541617600655604051908152a1005b3461127c575f36600319011261127c576020604051620151808152f35b612072565b3461127c575f36600319011261127c576020600454604051908152f35b3461127c57602036600319011261127c57611bcc612032565b611bd461224e565b50611bde81612562565b5060018060a01b03165f52600a6020526111a960405f2061ffff60405191611c0583612141565b5460018060a01b0381168352818160a01c166020840152818160b01c166040840152818160c01c16606084015260d01c1660808201526040519182918261208f565b3461127c57602036600319011261127c576020611c6a611c65612032565b612198565b604051908152f35b3461127c57602036600319011261127c57611c8b612032565b611c936126ee565b60018060a01b03811690815f52600f60205260405f2060405190611cb6826120ef565b80546001600160a01b0316808352600182015460208401819052600290920154604084018190529015918215611d3c575b508115611d32575b50611d2357611d21925f52600f6020525f600260408220828155826001820155015560018060a01b0390511690612597565b005b63aa0b7b6160e01b5f5260045ffd5b9050421184611cef565b4210915085611ce7565b3461127c57602036600319011261127c57611d5f612032565b5f610100604051611d6f8161210a565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152015260018060a01b03165f52600960205261012060405f2060405190611dc18261210a565b60018060a01b038154169182815260018060a01b036001830154166020820190815261ffff60018060a01b0360028501541660408401908152600460018060a01b036003870154169560608601968752015494608085019060018060a01b038716825260a0860192848860a01c16845260c087019560ff8960b01c161515875260ff61010060e08a0199828c60b81c1615158b52019960c01c1615158952604051998a5260018060a01b0390511660208a015260018060a01b03905116604089015260018060a01b03905116606088015260018060a01b039051166080870152511660a085015251151560c084015251151560e0830152511515610100820152f35b3461127c57604036600319011261127c57611edc612032565b611ee4612048565b611eec6126ee565b611ef582612562565b506001600160a01b038116908115611844576203f480420190814211610f7d576207e900420192838311610f7d577f22b336cc3c163283ca94b8a02d1107b4485a820fa77cc12ea205640452d37b5e936115b59160405190611f56826120ef565b8152602080820186815260408084018581526001600160a01b039a8b165f818152600f8652839020955186546001600160a01b031916908d161786559251600186015551600294909401939093558251959098168552840194909452928201929092529081906060820190565b3461127c57604036600319011261127c57611fdc612032565b611fe4612048565b6001600160a01b036003611ff784612562565b015416330361200957611d2191612597565b632e7e4e5160e21b5f5260045ffd5b3461127c575f36600319011261127c57602090600b548152f35b600435906001600160a01b038216820361127c57565b602435906001600160a01b038216820361127c57565b35906001600160a01b038216820361127c57565b3461127c575f36600319011261127c5760206040516203f4808152f35b919091608061ffff8160a084019560018060a01b038151168552826020820151166020860152826040820151166040860152826060820151166060860152015116910152565b3590811515820361127c57565b91908201809211610f7d57565b606081019081106001600160401b0382111761128057604052565b61012081019081106001600160401b0382111761128057604052565b604081019081106001600160401b0382111761128057604052565b60a081019081106001600160401b0382111761128057604052565b60c081019081106001600160401b0382111761128057604052565b90601f801991011681019081106001600160401b0382111761128057604052565b60018060a01b0316805f52600e60205260405f2060ff6001604051926121bd84612126565b8054845201541615801560208301526115ca575160025460035460045490600554926040519460208601964688523060408801526b033b2e3c9fd0803ce80000006060880152608087015260a08601525f60c086015260e08501526101008401526101208301526101408201526122376101608201612701565b6101e0815261224861020082612177565b51902090565b6040519061225b82612141565b5f6080838281528260208201528260408201528260608201520152565b519069ffffffffffffffffffff8216820361127c57565b614650811080156124c1575b61241757604051633fabe5a360e21b815260a0816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa801561124f575f915f9161246d575b505f821390811591612464575b811561245a575b8115612444575b50612436578091670de0b6b3a7640000810290808204670de0b6b3a76400001490151715610f7d5760ff7f000000000000000000000000000000000000000000000000000000000000000016604d8111610f7d57600a0a80600302906003820403610f7d576001600160fe1b0383168303610f7d5761238a9260021b91612770565b9081158015612426575b61241757600254600354600454600554906040519260208401944686523060408601526b033b2e3c9fd0803ce800000060608601525f60808601528760a0860152600160c086015260e08501526101008401526101208301526101408201526124006101608201612701565b6101e0815261241161020082612177565b51902092565b6330d7115160e11b5f5260045ffd5b506001600160801b038211612394565b62fc7cad60e51b5f5260045ffd5b90504203428111610f7d5762015180105f612308565b4281119150612301565b801591506122fa565b91505060a0813d60a0116124b9575b8161248960a09383612177565b8101031261127c5761249a81612278565b5060208101516124b1608060608401519301612278565b50905f6122ed565b3d915061247c565b506161a8811161229b565b6084356001600160a01b038116810361127c5790565b356001600160a01b038116810361127c5790565b60a43561ffff8116810361127c5790565b60c43561ffff8116810361127c5790565b60e43561ffff8116810361127c5790565b6101043561ffff8116810361127c5790565b3561ffff8116810361127c5790565b600b54811015610f9157600b5f5260205f2001905f90565b60018060a01b03165f52600960205260405f209060ff600483015460c01c161561258857565b638698bf3760e01b5f5260045ffd5b6001600160a01b03821691905f908315611844576125b481612562565b6003810180546001600160a01b0319811687179091556001909101546001600160a01b03918216949116803b1561127c575f8091602460405180948193633d82753160e11b83528b60048401525af1801561124f576126d9575b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b1561056c57604051635ad7fc1760e01b81526001600160a01b0384811660048301529190911660248201529083908290604490829084905af180156126ce579083916126b5575b50506001600160a01b0316907f308c390ed1ab5873392818e036cabdf408bc8ad042fbaead3108954ff75ba9809080a4565b816126bf91612177565b6126ca57815f612683565b5080fd5b6040513d85823e3d90fd5b6126e69193505f90612177565b5f915f61260e565b5f546001600160a01b031633036117ae57565b608061ffff60085460018060a01b0381168452818160a01c166020850152818160b01c166040850152818160c01c16606085015260d01c16910152565b801561275c57723880173480caadff41f996746e3000000000000490565b634e487b7160e01b5f52601260045260245ffd5b90915f19838309928083029283808610950394808603951461280157848311156127e95790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b50509150811561275c570490565b60025f5160206131ca5f395f51905f5254146128385760025f5160206131ca5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b90915f9361285484612198565b6101008401350361141f5760018060a01b0384165f52600e60205260405f20549460025434036114105761288a60c0850161253b565b61ffff60035491161180156130be575b6113d25760018060a01b0383165f52600d60205260405f206101208501355f5260205260ff60405f2054166113c35760206128d96101408601866130da565b9050116113b4576001600160a01b038381165f908152600d6020908152604080832061012089013584529091529020805460ff1916600117905561291f60a086016124e2565b166130ac5782945b61ffff60085460c01c169161293e60c0870161253b565b61ffff61294d60e0890161310f565b916040519561295b8761215c565b6001600160a01b0386811688528b16602088015260408088018d905260608801919091529116608086015290151560a085015251638dabdc8360e01b81526101e06004820152926129df6129d26129c56129b861098c8b80613130565b6109b460208c018c613130565b6109dc60408b018b613130565b610a0460608a018a613130565b90608088013588360392609e19840182121561127c578681036101e31901610264880152612a23918a0190610acb610ac0610aa5610a8a610a6f610a618780613130565b916001600160a01b03612a3860a08b0161205e565b1661028487015260c089013561ffff811680910361127c576102a4870152612a6260e08a016120d5565b15156102c48701526101008901356102e487015261012089013561030487015261014089013590601e190181121561127c578801602081359101926001600160401b03821161127c578160051b3603841361127c578681036101e3190161032488015281815291928692602001915f5b81811061307c57505083516001600160a01b039081166024850152602085015116604484015250604080840151606484015260608401516084840152608084015160a484015260a090930151151560c48301528190612b3360e48301612701565b6001600160a01b038981166101848401526b033b2e3c9fd0803ce80000006101a48401525f6101c48401819052929091039183917f0000000000000000000000000000000000000000000000000000000000000000165af194851561124f5787915f945f9761302c575b5090600491848989612d32612bc060e0612bb960c0860161253b565b940161310f565b610de861ffff60405195612bd38761210a565b8d60018060a01b03169a878c809952602081019760018060a01b03169d8e8952604082018d60018060a01b03168152606083019160018060a01b03168252608083019b60018060a01b03168c528560a084019516855260c08301971515885260e08301995f8b5261010084019b60018d525f52600960205260405f209360018060a01b039060018060a01b03905116166001600160601b0360a01b85541617845560018060a01b03905116600184019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600283019060018060a01b03166001600160601b0360a01b82541617905560018060a01b03905116600382019060018060a01b03166001600160601b0360a01b825416179055019760018060a01b039060018060a01b03905116166001600160601b0360a01b8954161788555116869081549061ffff60a01b9060a01b169061ffff60a01b1916179055565b518254915161ffff60b81b1990921690151560b81b60ff60b81b161790151560c01b60ff60c01b161790555f838152600a602052604090206007198101612fe2575b50600b54600160401b8110156112805786610e73826001612d989401600b5561254a565b612da66101408a018a6130da565b9b905060028c01809c11610f7d57612dbd8c613181565b9b6040519c612dcc908e612177565b808d52612dd890613181565b60208d019b90601f1901368d376001600160a01b038416612df88e613198565b526001600160a01b0316612e0b8d6131a5565b525f5b612e1c6101408c018c6130da565b9050811015612e7257612e336101408c018c6130da565b821015610f9157612e48908260051b016124e2565b906002810191828211610f7d57612e628f936001946131b5565b90838060a01b0316905201612e0e565b50929598509295989990939699863b1561127c576040805163251b648160e21b8152600481018890526024810191909152915160448301819052829160648301915f5b818110612fc05750505090805f920381838a5af1801561124f57612fab575b5060025480612f32575b50604080516001600160a01b0397881681526020810192909252810182905260608101919091529316927ff5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b90608090a49190565b6008546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116813b15612fa757906024859260405194859384926301aba89b60e71b845260048401525af180156126ce5715612ede57612f9d838092612177565b6126ca575f612ede565b8480fd5b612fb89192505f90612177565b5f905f612ed4565b82516001600160a01b0316845285945060209384019390920191600101612eb5565b6008805482546001600160a01b039091166001600160a01b0319821681178455915461ffff60a01b166001600160b01b0319909116909117178155613026906112d4565b5f612d74565b9450955090506040833d604011613074575b8161304b60409383612177565b8101031261127c576004879161306c60206130658761311c565b960161311c565b969091612b9d565b3d915061303e565b919493509160019060209081906001600160a01b0361309a8961205e565b16815201950191019187939492612ad2565b6130b860a085016124e2565b94612927565b506107d06130d461ffff6113f960c0880161253b565b1161289a565b903590601e198136030182121561127c57018035906001600160401b03821161127c57602001918160051b3603831361127c57565b35801515810361127c5790565b51906001600160a01b038216820361127c57565b9035601e198236030181121561127c5701602081359101916001600160401b03821161127c57813603831361127c57565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b0381116112805760051b60200190565b805115610f915760200190565b805160011015610f915760400190565b8051821015610f915760209160051b01019056fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212203190683f5d6bc5abb39a655d737ec2428316f3ace65c6ab0d982473f4e38da5864736f6c63430008230033","sourceMap":"1002:13720:23:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;5222:14;1002:13720;;5222:14;:::i;:::-;1002:13720;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;2099:48;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1451:39;1002:13720;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;1002:13720:23;;;-1:-1:-1;;;;;;1002:13720:23;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;1777:43:1;1002:13720:23;;1777:43:1;1002:13720:23;;;;;;;;;;;;;;;;;1703:49;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;1500:62:0;;:::i;:::-;11284:5:23;11268:21;;:43;;;;1002:13720;11268:63;;;;1002:13720;11268:87;;;;1002:13720;11268:132;;;;1002:13720;11268:171;;;;1002:13720;11268:205;;;;1002:13720;11268:234;;;;1002:13720;11268:275;;;;1002:13720;11268:321;;;;1002:13720;11264:348;;1002:13720;;;11622:24;1002:13720;11648:32;1002:13720;;;;;11713:29;1002:13720;-1:-1:-1;;;;;1002:13720:23;;:::i;:::-;;-1:-1:-1;;;;;1002:13720:23;;11744:16;1002:13720;;;11744:16;1002:13720;;;:::i;:::-;11744:16;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;;:::i;:::-;11744:16;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;;:::i;:::-;11744:16;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;;:::i;:::-;11744:16;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;11775:14;;;;1002:13720;;11264:348;-1:-1:-1;;;11598:14:23;;1002:13720;12082:14;11598;11268:321;11547:32;11583:6;1002:13720;11547:32;;:::i;:::-;1002:13720;11547:42;;11268:321;;:275;11506:32;1002:13720;11506:32;;:::i;:::-;1002:13720;11506:37;11268:275;;:234;11477:17;11284:5;1002:13720;11477:17;;:::i;:::-;1002:13720;11477:25;11268:234;;:205;11443:21;11467:6;1002:13720;11443:21;;:::i;:::-;1002:13720;11443:30;11268:205;;:171;11404:26;11433:6;1002:13720;11404:26;;:::i;:::-;1002:13720;11404:35;11268:171;;:132;-1:-1:-1;;;;;;11359:27:23;;:::i;:::-;1002:13720;11359:41;11268:132;;:87;11335:20;11349:6;11335:20;;11268:87;;:63;11315:16;;;11268:63;;:43;11293:18;11306:5;11293:18;;11268:43;;1002:13720;;;;;;;;;;;;;;;;;;;;;1862:37;1002:13720;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;1214:10;1002:13720;;;;;;;;;;;;;;;;;1406:39;1002:13720;;;;;;;;;;;;;;;;;;;;;;;1146:19;1002:13720;;;;;;;;;;;;;;;;;;1654:43;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;;;;;;;;;;12356:21;;;:::i;:::-;12405:26;;;1002:13720;-1:-1:-1;;;;;1002:13720:23;12391:10;:40;;;:78;;1002:13720;12387:115;;1002:13720;12512:21;;1002:13720;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;12512:21;;;;-1:-1:-1;12573:12:23;;1002:13720;-1:-1:-1;;;;;1002:13720:23;;12553:60;;;;;1002:13720;;;;;;;;;;;;;;;12553:60;;1002:13720;12553:60;;1002:13720;12553:60;;;;;;;;1002:13720;;12553:60;;;;;:::i;:::-;1002:13720;;12553:60;1002:13720;12553:60;1002:13720;;;;;;;;;12553:60;1002:13720;;;12387:115;-1:-1:-1;;;12478:24:23;;1002:13720;12830:24;12478;12391:78;-1:-1:-1;1002:13720:23;;-1:-1:-1;;;;;1002:13720:23;12391:10;12436:21;;;12391:78;12436:32;;;12391:78;;1002:13720;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;:::i;:::-;;;;2153:60;1002:13720;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;1500:62:0;;:::i;:::-;2989:103:13;;:::i;:::-;1002:13720:23;;8010:16;:51;;;;1002:13720;8006:86;;8161:41;1002:13720;;8161:41;:::i;:::-;1002:13720;8216:24;1002:13720;;8216:24;1002:13720;8216:37;8212:75;;8903:9;1002:13720;8890:9;:22;8886:53;;8953:20;;1002:13720;;8953:20;;:::i;:::-;1002:13720;8976:16;1002:13720;;;8953:39;:101;;;;1002:13720;8949:133;;8342:10;1002:13720;;9096:8;1002:13720;;;;;9114:11;1002:13720;;9114:11;1002:13720;;;;;;;;;;;9092:60;;1002:13720;9166:25;;1002:13720;;9166:25;1002:13720;;;;9166:25;:::i;:::-;:37;;;9162:64;;8342:10;1002:13720;;9096:8;1002:13720;;;;;9114:11;1002:13720;;9114:11;1002:13720;;;;;;;;;;;;;;;;;;;;;;9303:26;;1002:13720;;9303:26;;:::i;:::-;1002:13720;9303:79;;8342:10;9303:79;;1002:13720;;;9554:7;1002:13720;8953:20;1002:13720;;;9574:20;8953;1002:13720;;8953:20;9574;:::i;:::-;1002:13720;9596:21;;1002:13720;;9596:21;;:::i;:::-;1002:13720;;;;;;;:::i;:::-;;;;;;;;;;;;9492:126;;1002:13720;9492:126;1002:13720;9492:126;;1002:13720;;9492:126;;1002:13720;;9492:126;;;1002:13720;;;9303:26;9492:126;;1002:13720;;;;;;;9645:80;;1002:13720;;9645:80;;1002:13720;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1002:13720:23;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1002:13720:23;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1002:13720:23;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9303:26;1002:13720;;9303:26;1002:13720;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;9492:126;1002:13720;;;;:::i;:::-;;9492:126;1002:13720;;;;;;;:::i;:::-;;-1:-1:-1;;;;;1002:13720:23;;;9303:26;;1002:13720;:::i;:::-;;;;;;8953:20;1002:13720;;8953:20;1002:13720;;;;;;;;;;;;;;9596:21;1002:13720;;9596:21;1002:13720;:::i;:::-;;;;;;;;;8216:24;;;1002:13720;;;;;9114:11;;;1002:13720;;;;;9166:25;;;1002:13720;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;9492:126;;1002:13720;;;;;;-1:-1:-1;1002:13720:23;9492:126;;;1002:13720;;;;;;9492:126;;1002:13720;;;;;9492:126;;;1002:13720;;;;;9303:26;9492:126;;;1002:13720;;;;;;;;;;;;;;:::i;:::-;8342:10;1002:13720;;;;1146:19;1002:13720;;;;;;;;;;9645:80;1002:13720;-1:-1:-1;9645:14:23;-1:-1:-1;;;;;1002:13720:23;9645:80;;;;;;;1002:13720;;;9645:80;;;1002:13720;9628:97;1002:13720;;;;9813:20;8953;1002:13720;;8953:20;9813;:::i;:::-;1002:13720;;9835:21;9596;1002:13720;;9596:21;9835;:::i;:::-;1002:13720;;;;;;;:::i;:::-;;;;;;;;;;;9754:122;;1002:13720;;;;;;;;;;9754:122;;8342:10;;1002:13720;;;9754:122;;1002:13720;;;;;;;;;9492:126;9754:122;;1002:13720;;;;9754:122;9303:26;9754:122;;1002:13720;;;;8953:20;9754:122;;1002:13720;;;;;;9754:122;;1002:13720;;;;;9754:122;;1002:13720;;;;;;;;;;;;9735:9;1002:13720;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;8903:9;1002:13720;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;8976:16;1002:13720;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1002:13720:23;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;;;;;-1:-1:-1;;;;1002:13720:23;;;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;-1:-1:-1;;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;-1:-1:-1;1002:13720:23;;;9886:15;1002:13720;;;;;-1:-1:-1;;1002:13720:23;;;;;;9928:7;1002:13720;-1:-1:-1;;;1002:13720:23;;;;;;;;;;;;9928:7;1002:13720;;:::i;:::-;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;10001:25;9166;1002:13720;;9166:25;1002:13720;;;;10001:25;:::i;:::-;1002:13720;;;8903:9;1002:13720;;;;;;;8903:9;1002:13720;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;:::i;:::-;-1:-1:-1;;1002:13720:23;;;;;;8342:10;10048:23;;;:::i;:::-;1002:13720;-1:-1:-1;;;;;1002:13720:23;10081:25;;;:::i;:::-;1002:13720;;10170:3;10136:25;9166;1002:13720;;9166:25;1002:13720;;;;10136:25;:::i;:::-;10132:36;;;;;;;10195:25;9166;1002:13720;;9166:25;1002:13720;;;;10195:25;:::i;:::-;1002:13720;;;;;10195:28;1002:13720;;;;;10195:28;:::i;:::-;1002:13720;8903:9;1002:13720;;;;;;;;10175:48;8903:9;1002:13720;;10175:48;;:::i;:::-;1002:13720;;;;;;;;;;10121:9;;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;10132:36;-1:-1:-1;10132:36:23;;-1:-1:-1;;;;;1002:13720:23;;10233:56;;;;1002:13720;;;-1:-1:-1;;;10233:56:23;;-1:-1:-1;;;;;1002:13720:23;;;10233:56;;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;-1:-1:-1;1002:13720:23;;10233:56;;;;;-1:-1:-1;10233:56:23;;-1:-1:-1;1002:13720:23;-1:-1:-1;;;;;1002:13720:23;;10233:56;;;;;;;;1002:13720;;8903:9;1002:13720;10303:14;10299:84;;1002:13720;;;;8441:59;1002:13720;;;;;;;;;;;;;;;;;;;;;8342:10;1002:13720;;;;;;;;;10398:86;9492:126;1002:13720;;;;;;;10398:86;;1002:13720;;;;8383:13;1002:13720;;;;;;;-1:-1:-1;;;;;;1002:13720:23;-1:-1:-1;;;;;1002:13720:23;;;;;8441:59;:::i;:::-;1002:13720;;;;;;;;:::i;:::-;;;;;;8533:33;;1002:13720;;;;;;;;;;;;;8510:13;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;8581:47;;1002:13720;8581:47;1002:13720;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;8643:51;;;1002:13720;-1:-1:-1;;;;;;;;;;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;10299:84;9554:7;1002:13720;-1:-1:-1;;;;;10319:9:23;1002:13720;;;;10319:64;;;;;1002:13720;;;;;;;;;;;;;;10319:64;;1002:13720;10319:64;;1002:13720;10319:64;;;;;;;;;;;10299:84;;;;10319:64;;;;;:::i;:::-;1002:13720;;10319:64;;;;;1002:13720;;;;;;;;;10319:64;1002:13720;;;10233:56;;;;;1002:13720;10233:56;;:::i;:::-;1002:13720;10233:56;;;;;1002:13720;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;10233:56;1002:13720;;;;;;;;;;;;;;;;9554:7;1002:13720;;;;-1:-1:-1;;;;;1002:13720:23;;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;-1:-1:-1;;;1002:13720:23;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;;;;;9554:7;1002:13720;;;-1:-1:-1;;;;1002:13720:23;-1:-1:-1;;;1002:13720:23;;;;;;9554:7;1002:13720;;;-1:-1:-1;;;;1002:13720:23;-1:-1:-1;;;1002:13720:23;;;;;;9554:7;1002:13720;;;-1:-1:-1;;;;1002:13720:23;-1:-1:-1;;;1002:13720:23;;;;;;;;;;;9645:80;;;;;1002:13720;9645:80;;1002:13720;9645:80;;;;;;1002:13720;9645:80;;;:::i;:::-;;;1002:13720;;;;;;;;;:::i;:::-;;;;:::i;:::-;9645:80;;;;;;;-1:-1:-1;9645:80:23;;1002:13720;;;;-1:-1:-1;1002:13720:23;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;:::i;:::-;;;;;;;;;;;;;;;;9303:79;9356:26;9303;1002:13720;;9303:26;9356;:::i;:::-;9303:79;;;9162:64;12082:14;;;1002:13720;9212:14;1002:13720;;9212:14;9092:60;9135:17;;;1002:13720;9135:17;1002:13720;;9135:17;8949:133;9063:19;;;1002:13720;9063:19;1002:13720;;9063:19;8953:101;1002:13720;9049:5;8996:50;1002:13720;9004:20;8953;1002:13720;;8953:20;9004;:::i;:::-;1002:13720;;9028:7;1002:13720;8953:20;1002:13720;;8996:50;;:::i;:::-;:58;8953:101;;8886:53;8921:18;;;1002:13720;8921:18;1002:13720;;8921:18;8212:75;8262:25;;;1002:13720;8262:25;1002:13720;;8262:25;8006:86;8070:22;;;1002:13720;8070:22;1002:13720;;8070:22;8010:51;-1:-1:-1;1002:13720:23;;;;;;8030:13;1002:13720;;;;;;-1:-1:-1;;;;;1002:13720:23;8030:31;;8010:51;;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;:::i;:::-;;;;;;2435:70;1002:13720;;;;;;;;;;;;2435:70;;1002:13720;2435:70;;;;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;1618:30;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;;;;;;;;;;;1500:62:0;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;;11915:23;;;;:60;;1002:13720;11911:95;;12020:17;;:53;;;;1002:13720;12016:80;;1002:13720;12184:54;1002:13720;;;;;;;;:::i;:::-;;;;;12133:36;;1002:13720;;;;;;12106:13;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12184:54;;;;1002:13720;12020:53;12041:32;-1:-1:-1;;;;;12041:32:23;;12020:53;;11911:95;11984:22;;;1002:13720;11984:22;1002:13720;;11984:22;11915:60;1002:13720;;;;11943:9;1002:13720;;;;;;;11943:32;1002:13720;;;;11942:33;11915:60;;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;1581:31;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;4767:7;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;;;1758:53;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;1817:39;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;735:10:11;-1:-1:-1;;;;;1002:13720:23;;;2339:24:1;2335:96;;2093:20;1002:13720:23;;-1:-1:-1;;;;;;1002:13720:23;;;;;;-1:-1:-1;1002:13720:23;;735:10:11;1002:13720:23;;;;;;;-1:-1:-1;;;;;1002:13720:23;;3052:40:0;;-1:-1:-1;3052:40:0;1002:13720:23;2335:96:1;2386:34;;;1002:13720:23;2386:34:1;735:10:11;1002:13720:23;;;;2386:34:1;1002:13720:23;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;10577:15:23;1002:13720;;-1:-1:-1;;;;;1002:13720:23;;10573:54;;10641:21;;:26;10637:52;;-1:-1:-1;;;;;1002:13720:23;-1:-1:-1;;;;;;1002:13720:23;;;;;;10577:15;1002:13720;;;;;;10741:29;;1002:13720;;10741:29;1002:13720;10637:52;13076:13;;;1002:13720;10676:13;1002:13720;;10676:13;10573:54;10615:12;;;1002:13720;10615:12;1002:13720;;10615:12;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;1500:62:0;;:::i;:::-;2093:20:1;1002:13720:23;;-1:-1:-1;;;;;;1002:13720:23;;;;;;-1:-1:-1;1002:13720:23;;;;;;;-1:-1:-1;;;;;;1002:13720:23;3052:40:0;-1:-1:-1;;3052:40:0;1002:13720:23;;;;;;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;:::i;:::-;;;;2284:54;1002:13720;;;;;;2284:54;1002:13720;;2284:54;;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;;;;;13498:26;1002:13720;;;;;;;;;;;;;;;;;;;13546:41;;1002:13720;13546:41;1002:13720;;;;-1:-1:-1;;1002:13720:23;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;6917:47;1002:13720;;;:::i;:::-;2989:103:13;;:::i;:::-;6953:10:23;1002:13720;;;6917:47;:::i;:::-;2365:1:13;-1:-1:-1;;;;;;;;;;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;2989:103:13;;:::i;:::-;7162:15:23;1002:13720;-1:-1:-1;;;;;1002:13720:23;7148:10;:29;;;;;:54;;1002:13720;7144:87;;;7248:44;1002:13720;;;7248:44;:::i;7144:87::-;7211:20;;;1002:13720;7211:20;1002:13720;;7211:20;7148:54;7181:21;;;7148:54;;;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;;1541:34;1002:13720;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;5310:4;1002:13720;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;10862:22;;10858:48;;1002:13720;;10958:33;1002:13720;-1:-1:-1;;;;;1002:13720:23;;10916:27;1002:13720;;;10916:27;1002:13720;;;;;;10958:33;1002:13720;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;1394:6;1002:13720;;;;;:::i;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;:::i;:::-;;4876:21;;;:::i;:::-;;1002:13720;;;;;;;;4906:15;1002:13720;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;1500:62:0;;:::i;:::-;1002:13720:23;;;;;;;;;;;13719:26;1002:13720;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;13766:31;;;:72;;;;1002:13720;13766:111;;;;;1002:13720;13762:147;;;13993:17;1002:13720;;;13719:26;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;13993:17;;:::i;:::-;1002:13720;13762:147;13886:23;;;1002:13720;13886:23;1002:13720;;13886:23;13766:111;13842:15;;;:35;13766:111;;;:72;13801:15;:37;;-1:-1:-1;13766:72:23;;;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5031:9;1002:13720;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;:::i;:::-;1500:62:0;;:::i;:::-;13009:21:23;;;:::i;:::-;-1:-1:-1;;;;;;1002:13720:23;;;13044:23;;13040:49;;1341:6;13119:15;1002:13720;13119:15;;;1002:13720;;;;13119:15;1002:13720;;;;;;;13295:99;1002:13720;13295:99;1002:13720;;;;;;;:::i;:::-;;;;13205:75;;;1002:13720;;;;13205:75;;;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;-1:-1:-1;1002:13720:23;;;13169:26;1002:13720;;;;;;;;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;:::i;:::-;;;:::i;:::-;-1:-1:-1;;;;;12795:26:23;12746:21;;;:::i;:::-;12795:26;1002:13720;;12781:10;:40;12777:77;;12888:9;;;:::i;12777:77::-;12830:24;;;1002:13720;12830:24;1002:13720;;12830:24;1002:13720;;;;;;-1:-1:-1;;1002:13720:23;;;;;;5119:7;1002:13720;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;:::o;:::-;;;-1:-1:-1;;;;;1002:13720:23;;;;;;:::o;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;1341:6;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;8953:20;1002:13720;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;5323:276::-;1002:13720;;;;;;;-1:-1:-1;1002:13720:23;5442:13;1002:13720;;;-1:-1:-1;1002:13720:23;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;5476:48;;1002:13720;6676:9;1002:13720;6687:16;1002:13720;6705:16;1002:13720;;6723:15;1002:13720;;;;6589:159;1002:13720;6589:159;;6600:13;;1002:13720;;6623:4;1002:13720;;;;1146:19;1002:13720;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6589:159;;;;;;;:::i;:::-;1002:13720;6579:170;;5323:276;:::o;1002:13720::-;;;;;;;:::i;:::-;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;5605:837::-;5770:6;5755:21;;:46;;;;5605:837;5751:88;;1002:13720;;-1:-1:-1;;;5890:28:23;;;1002:13720;5890:28;1002:13720;5890:10;-1:-1:-1;;;;;1002:13720:23;5890:28;;;;;;-1:-1:-1;;;5890:28:23;;;5605:837;5932:11;-1:-1:-1;5932:11:23;;;;;:29;;;5605:837;5932:60;;;;5605:837;5932:108;;;;5605:837;5928:141;;;6079:23;1002:13720;6217:7;1002:13720;;;;;;6217:7;1002:13720;;;;;;;;6236:14;1002:13720;;;;;;;;;6226:1;1002:13720;;6226:1;1002:13720;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;6190:72;1002:13720;;;6190:72;;:::i;:::-;6276:17;;;:53;;;;5605:837;6272:95;;1002:13720;;6226:1;1002:13720;5890:28;1002:13720;6723:15;1002:13720;;;;6589:159;;;;6600:13;;1002:13720;;6623:4;1002:13720;;;;1146:19;1002:13720;;;;-1:-1:-1;1002:13720:23;;;;;5890:28;1002:13720;;;6430:4;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6589:159;;;;;;;:::i;:::-;1002:13720;6579:170;;5605:837;:::o;6272:95::-;5810:29;;;-1:-1:-1;6338:29:23;5890:28;-1:-1:-1;6338:29:23;6276:53;6297:32;-1:-1:-1;;;;;6297:32:23;;6276:53;;5928:141;6049:20;;;-1:-1:-1;6049:20:23;5890:28;-1:-1:-1;6049:20:23;5932:108;5996:15;;;1002:13720;5996:15;1002:13720;;;;1394:6;-1:-1:-1;5932:108:23;;;:60;5977:15;5965:27;;;-1:-1:-1;5932:60:23;;:29;5947:14;;;-1:-1:-1;5932:29:23;;5890:28;;;;;;;;;;;;;;;;;;:::i;:::-;;;1002:13720;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;;5890:28;;;;;;;-1:-1:-1;5890:28:23;;5755:46;5780:21;5795:6;5780:21;;5755:46;;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;;-1:-1:-1;;;;;1002:13720:23;;;;;;;:::o;:::-;11404:26;1002:13720;;;;;;;;;:::o;:::-;11443:21;1002:13720;;;;;;;;;:::o;:::-;11477:17;1002:13720;;;;;;;;;:::o;:::-;11506:32;1002:13720;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;5222:7;1002:13720;;;;;;5222:7;-1:-1:-1;1002:13720:23;;-1:-1:-1;1002:13720:23;;;-1:-1:-1;1002:13720:23;:::o;14536:184::-;1002:13720;;;;;;-1:-1:-1;1002:13720:23;14646:9;1002:13720;;;-1:-1:-1;1002:13720:23;14677:13;1002:13720;14677:13;;;1002:13720;;;;14676:14;14672:41;;14536:184::o;14672:41::-;14699:14;;;-1:-1:-1;14699:14:23;14677:13;-1:-1:-1;14699:14:23;14023:508;-1:-1:-1;;;;;1002:13720:23;;;14023:508;14126:1;;14105:23;;14101:49;;14191:21;;;:::i;:::-;14241:26;;;1002:13720;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;14345:12;;;1002:13720;-1:-1:-1;;;;;1002:13720:23;;;;14241:26;1002:13720;14325:67;;;;;14126:1;1002:13720;;14325:67;1002:13720;;;;;;;;;14325:67;;;;;;1002:13720;14325:67;;;;;;;;14023:508;-1:-1:-1;14402:12:23;-1:-1:-1;;;;;1002:13720:23;;14402:53;;;;;1002:13720;;-1:-1:-1;;;14402:53:23;;-1:-1:-1;;;;;1002:13720:23;;;14325:67;14402:53;;1002:13720;;;;;;;;;;;;;;;;;;;;14402:53;;;;;;;;;;;14023:508;-1:-1:-1;;;;;;;1002:13720:23;;14470:54;;;;14023:508::o;14402:53::-;;;;;:::i;:::-;1002:13720;;14402:53;;;;1002:13720;;;;14402:53;1002:13720;;;;;;;;;14325:67;;;;;14126:1;14325:67;;:::i;:::-;14126:1;14325:67;;;;1796:162:0;1710:6;1002:13720:23;-1:-1:-1;;;;;1002:13720:23;735:10:11;1855:23:0;1851:101;;1796:162::o;1002:13720:23:-;;;6740:7;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7296:3683:16:-;1002:13720:23;;;;1412:159:16;1002:13720:23;7296:3683:16;:::o;1002:13720:23:-;;;;;;;;;;;;7296:3683:16;;;-1:-1:-1;;7296:3683:16;;1412:159;;;;;;;;;;;;;;;;7552:9;;7548:365;;8023:19;;;;8019:142;;8444:308;;;;940:4:12;1002:13720:23;940:4:12;8971:31:16;;9016:384;;;9854:1;940:4:12;9835:1:16;940:4:12;9834:21:16;940:4:12;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;;;;9854:1:16;940:4:12;;9016:384:16;;;;1002:13720:23;9016:384:16;;;8444:308;;;;;;940:4:12;8444:308:16;;9016:384;9463:18;940:4:12;7296:3683:16;:::o;8019:142::-;1829:135:12;;1002:13720:23;1829:135:12;8082:16:16;5328:5;940:4:12;;5322:42:16;1829:135:12;;;;;7548:365:16;7881:17;;;;1002:13720:23;;;;;7874:24:16;:::o;3749:292:13:-;2407:1;-1:-1:-1;;;;;;;;;;;1002:13720:23;4560:63:13;3644:93;;2407:1;-1:-1:-1;;;;;;;;;;;1002:13720:23;3749:292:13:o;3644:93::-;3696:30;;;-1:-1:-1;3696:30:13;;-1:-1:-1;3696:30:13;7304:352:23;;;-1:-1:-1;7484:33:23;;;;:::i;:::-;7456:24;;;1002:13720;7456:61;7452:99;;1002:13720;;;;;;;-1:-1:-1;1002:13720:23;7604:13;1002:13720;;;-1:-1:-1;1002:13720:23;;7568:81;8903:9;1002:13720;8890:9;:22;8886:53;;8953:20;;;;;:::i;:::-;1002:13720;8976:16;1002:13720;;;8953:39;:101;;;;7304:352;8949:133;;1002:13720;;;;;;;-1:-1:-1;1002:13720:23;9096:8;1002:13720;;;-1:-1:-1;1002:13720:23;9114:11;;;1002:13720;-1:-1:-1;1002:13720:23;;;;;-1:-1:-1;1002:13720:23;;;9092:60;;1002:13720;9166:25;;;;;;:::i;:::-;:37;;;9162:64;;-1:-1:-1;;;;;1002:13720:23;;;-1:-1:-1;1002:13720:23;;;9096:8;1002:13720;;;;;;;;9114:11;;;1002:13720;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;9303:26;1002:13720;9303:26;;;:::i;:::-;1002:13720;9303:79;;;;;1002:13720;9554:7;1002:13720;8953:20;1002:13720;;8953:20;9574;8953;;;9574;:::i;:::-;1002:13720;9596:21;;;;;:::i;:::-;1002:13720;;;;;;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;;;;;;;;9492:126;;1002:13720;;9492:126;;;1002:13720;;;9492:126;;;1002:13720;;;;;;9492:126;;;1002:13720;;;;;9492:126;;1002:13720;;-1:-1:-1;;;9645:80:23;;1002:13720;9645:80;;;1002:13720;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;9492:126;1002:13720;;;;:::i;:::-;;9492:126;1002:13720;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;;;;;:::i;:::-;;-1:-1:-1;;;;;1002:13720:23;;9303:26;;1002:13720;:::i;:::-;;;;;;8953:20;;;1002:13720;;;;;;;;;;;;;;9596:21;;;1002:13720;:::i;:::-;;;;;;;7456:24;;;1002:13720;;;;;9114:11;;;1002:13720;;;;;9166:25;;;1002:13720;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;-1:-1:-1;;1002:13720:23;;;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;-1:-1:-1;;1002:13720:23;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;9492:126;;1002:13720;;;;;;-1:-1:-1;1002:13720:23;9492:126;;;1002:13720;;;;;9492:126;;;1002:13720;;;;;9492:126;;;1002:13720;;;;;9303:26;9492:126;;;1002:13720;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1002:13720:23;;;;;;;1146:19;1002:13720;;;;-1:-1:-1;1002:13720:23;;;;;;9645:80;;;;;1002:13720;;9645:14;1002:13720;9645:80;;;;;;;;;-1:-1:-1;;;9645:80:23;;;1002:13720;9628:97;;9645:80;9628:97;8953:20;;;1002:13720;9835:21;9596;9813:20;8953;;;9813;:::i;:::-;9596:21;;9835;:::i;:::-;1002:13720;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;9754:122;;1002:13720;;;;;;;;;;;;9754:122;;1002:13720;;;;;;;;;9492:126;9754:122;;1002:13720;;;;;;;;;9492:126;9754:122;;1002:13720;;;;;;;;;9754:122;9303:26;9754:122;;1002:13720;;;;8953:20;9754:122;;1002:13720;;;;;9596:21;9754:122;;1002:13720;-1:-1:-1;1002:13720:23;;7456:24;9754:122;;1002:13720;;;;-1:-1:-1;1002:13720:23;9735:9;1002:13720;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;8903:9;1002:13720;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;8976:16;1002:13720;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;1002:13720:23;;;;;;;;-1:-1:-1;;;1002:13720:23;;;;;;;-1:-1:-1;;;1002:13720:23;;;;-1:-1:-1;1002:13720:23;;;9886:15;1002:13720;;;;;-1:-1:-1;;1002:13720:23;;;;;;9928:7;1002:13720;-1:-1:-1;;;1002:13720:23;;;;;;;;;;;;9928:7;1002:13720;;:::i;:::-;10001:25;9166;;;10001;;:::i;:::-;1002:13720;;;8903:9;1002:13720;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;1002:13720:23;;;;-1:-1:-1;;;;;1002:13720:23;;10048:23;1002:13720;10048:23;:::i;:::-;1002:13720;-1:-1:-1;;;;;1002:13720:23;10081:25;;;:::i;:::-;1002:13720;-1:-1:-1;10170:3:23;10136:25;9166;;;10136;;:::i;:::-;10132:36;;;;;;;10195:25;9166;;;10195;;:::i;:::-;1002:13720;;;;;10195:28;1002:13720;;;;;10195:28;:::i;:::-;1002:13720;8903:9;1002:13720;;;;;;;;10175:48;;;1002:13720;10175:48;;:::i;:::-;1002:13720;;;;;;;;;;10121:9;;10132:36;;;;;;;;;;;;;;10233:56;;;;;1002:13720;;;-1:-1:-1;;;10233:56:23;;9645:80;10233:56;;1002:13720;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;10233:56;;;;;-1:-1:-1;10233:56:23;;;;;;;;;;;;;1002:13720;;8903:9;1002:13720;10303:14;10299:84;;1002:13720;-1:-1:-1;1002:13720:23;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;;9492:126;1002:13720;;;;;;;;;10398:86;;9492:126;;10398:86;7561:88;7304:352;:::o;10299:84::-;9554:7;1002:13720;-1:-1:-1;;;;;10319:9:23;1002:13720;;;;10319:64;;;;;1002:13720;;;;;;;;;;;;;;10319:64;;9645:80;10319:64;;1002:13720;10319:64;;;;;;;10299:84;10319:64;;;;;;:::i;:::-;1002:13720;;10319:64;10299:84;;10319:64;1002:13720;;;10233:56;;;;;-1:-1:-1;10233:56:23;;:::i;:::-;-1:-1:-1;10233:56:23;;;;1002:13720;;;-1:-1:-1;;;;;1002:13720:23;;;;;-1:-1:-1;1002:13720:23;;;;;;;;;;;;;;9554:7;1002:13720;;;;-1:-1:-1;;;;;1002:13720:23;;;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;-1:-1:-1;;;1002:13720:23;-1:-1:-1;;;;;;1002:13720:23;;;;;;;;;;;;;;;;;9645:80;;;;;;;1002:13720;9645:80;;1002:13720;9645:80;;;;;;1002:13720;9645:80;;;:::i;:::-;;;1002:13720;;;;9645:80;1002:13720;;;;;;;:::i;:::-;;;;:::i;:::-;9645:80;;;;;;;;-1:-1:-1;9645:80:23;;1002:13720;;;;-1:-1:-1;1002:13720:23;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;:::i;:::-;;;;;;;;;;;;;;;;9303:79;9356:26;9303;;;9356;:::i;:::-;9303:79;;;8953:101;:20;9049:5;8996:50;1002:13720;9004:20;8953;;;9004;:::i;8996:50::-;:58;8953:101;;1002:13720;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;;;1002:13720:23;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;1002:13720:23;;;;;;;;-1:-1:-1;;1002:13720:23;;;;:::o;:::-;-1:-1:-1;;;;;1002:13720:23;;;;;;;;;:::o;:::-;;;;;;;;;:::o;:::-;;;9269:4;1002:13720;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o","linkReferences":{},"immutableReferences":{"8974":[{"start":1621,"length":32},{"start":4538,"length":32},{"start":12095,"length":32}],"8977":[{"start":795,"length":32},{"start":9745,"length":32}],"8980":[{"start":3106,"length":32},{"start":5833,"length":32},{"start":11113,"length":32}],"8983":[{"start":5901,"length":32},{"start":8884,"length":32}],"8985":[{"start":1418,"length":32},{"start":9012,"length":32}]}}}}}}},"signatures":{"function":[{"signature":"acceptOwnership()","signatureHash4":"0x79ba5097","signatureHash32":"0x79ba5097e5519a381a52113cdcc59540d13f73fd9d26abc0453484a096cc96f2"},{"signature":"BASE_PHANTOM_ETH()","signatureHash4":"0xdf41ead2","signatureHash32":"0xdf41ead29e7b2fd998d77106a43e65ea365ccac7508e94f890cc18ce86d525cd"},{"signature":"buybackVault()","signatureHash4":"0xf1f5c993","signatureHash32":"0xf1f5c993ccb3f93b450c0d36b9999158ea17a56907576709d04c9a76cf5f7d06"},{"signature":"cancelCreatorFeeRecipientChange(address)","signatureHash4":"0x6e47a188","signatureHash32":"0x6e47a188a32fa9de3bbf65b4987837062128630517f312b81ecd9b00196f0a9e"},{"signature":"canLaunch(address)","signatureHash4":"0x58373f04","signatureHash32":"0x58373f0469daa3fc0947dedcf425cac05d7c6cb45826edb6b48f4e0caf75a87d"},{"signature":"CREATOR_RECOVERY_DELAY()","signatureHash4":"0x523af328","signatureHash32":"0x523af328dbbc2bcbf30734d5627e2031c7a11df36fb9196141262b737afb6592"},{"signature":"CREATOR_RECOVERY_WINDOW()","signatureHash4":"0x315226d9","signatureHash32":"0x315226d9489e41c4e1a41fb6f525ae090ebc595674e94474ad02bdd782d5562d"},{"signature":"currentFeePolicy()","signatureHash4":"0x89a69bd8","signatureHash32":"0x89a69bd877d749b8b53107d468159c4e0936b4af39aa8fe136b31c9852efeb51"},{"signature":"ethUsdFeed()","signatureHash4":"0x8009b7bd","signatureHash32":"0x8009b7bdf33e7cf0e8faf4498247300ec1979781bb4d42074ec548ff9c73ce60"},{"signature":"executeCreatorFeeRecipientChange(address)","signatureHash4":"0x3d3d2d58","signatureHash32":"0x3d3d2d584794442bd070375ec86d064a28defb0a7b05a4b4db909250c9b8b825"},{"signature":"feeEscrow()","signatureHash4":"0xc4b7de97","signatureHash32":"0xc4b7de97cd4ac57ef574c54dc88537fe05d3734b2fab89e3bb031fccc9d91d6d"},{"signature":"feeSweepOperator()","signatureHash4":"0x8a36a6bb","signatureHash32":"0x8a36a6bb10b0a86bf1557f7ea648dcec8028197fd9844a7e9a0bdef08e3dfaf1"},{"signature":"getLaunchedToken(address)","signatureHash4":"0x3cf28b5a","signatureHash32":"0x3cf28b5a3844992c1c67a0e5eeb78a0c7baadfe87d378f2ec6ce644e5315ed49"},{"signature":"getLaunchFeePolicy(address)","signatureHash4":"0x470ef5fc","signatureHash32":"0x470ef5fca825ec03ad71a2bbd7ad61001800a060e6cbbb3460f6526ecbbbb334"},{"signature":"launchCount()","signatureHash4":"0x27cca59f","signatureHash32":"0x27cca59fbc2d23a372f26f09feddeb9a3223bf9d037df4f19d5058494808e911"},{"signature":"launchDeployer()","signatureHash4":"0x858f5964","signatureHash32":"0x858f5964e72ff9fb9b2f5bc1429c781c81ce750675ee9476bf6d94c71ad607fc"},{"signature":"launchedTokenAt(uint256)","signatureHash4":"0xffcb6e9f","signatureHash32":"0xffcb6e9fef0e5412694244f04f4997ac255b57cd62b32761012d9ddf7d625399"},{"signature":"launchFee()","signatureHash4":"0xcf3cf573","signatureHash32":"0xcf3cf573567260a691751233ec71bb7b1e18d383922c7c402e4991c719c5e344"},{"signature":"launchForwarder()","signatureHash4":"0x9b924452","signatureHash32":"0x9b92445270d20d393b647d0a54af5e0b6f765df108be3ff7bb64c5912cf5e7f9"},{"signature":"launchPersonality((string,string,string,string,(string,string,string,string,string),address,uint16,bool,bytes32,bytes32,address[]),bytes32,uint256)","signatureHash4":"0x9c5693eb","signatureHash32":"0x9c5693eb008d2d7a6acad787cc8a3f7fa45dcbede6231e8844013667d7054822"},{"signature":"launchTokenFor((string,string,string,string,(string,string,string,string,string),address,uint16,bool,bytes32,bytes32,address[]),address,address)","signatureHash4":"0x6cd5bce4","signatureHash32":"0x6cd5bce4e3d1b14ea846dcf33a3b7d21ec4f21cdfb60221470e43e0ef3fab449"},{"signature":"launchToken((string,string,string,string,(string,string,string,string,string),address,uint16,bool,bytes32,bytes32,address[]),address)","signatureHash4":"0x6dc97d6a","signatureHash32":"0x6dc97d6a96b347d7875cd8d233ea6fdf892f1078f86e5cc8055ec65daf2da6a4"},{"signature":"maxCreatorTaxBps()","signatureHash4":"0xf325a5fb","signatureHash32":"0xf325a5fb0c354b8736228af81cae9fc18b17c4629d94442f63906977c59c3837"},{"signature":"oracleDecimals()","signatureHash4":"0xe68b52e7","signatureHash32":"0xe68b52e79d83bd6f6f72ef39c68bf2416a362033df23d50d8f5383fa748e192d"},{"signature":"ORACLE_MAX_AGE()","signatureHash4":"0x54a4931c","signatureHash32":"0x54a4931c436ad70a630df5601b45d7e19851bc7d3b532a48f7d9c49a7a3243da"},{"signature":"owner()","signatureHash4":"0x8da5cb5b","signatureHash32":"0x8da5cb5b36e7f68c1d2e56001220cdbdd3ba2616072f718acfda4a06441a807d"},{"signature":"pairEconomics(address)","signatureHash4":"0x6f471f2d","signatureHash32":"0x6f471f2d40f29e5d33dbcceedfaa513787dfb5eaba5942c59395635eeb71ecb4"},{"signature":"pendingCreatorFeeRecipient(address)","signatureHash4":"0x9beacf4a","signatureHash32":"0x9beacf4af4dd7ee43ce487e1664dc2f74a9aff25c40f4ecf2ee05448ff553294"},{"signature":"pendingOwner()","signatureHash4":"0xe30c3978","signatureHash32":"0xe30c3978ddd82956a01b5cb08d17f1a2d73e636aeefb7b36f896e41d4c2aab90"},{"signature":"personalities(bytes32)","signatureHash4":"0xf9b3b8d9","signatureHash32":"0xf9b3b8d9d46bd1ae7938d63ef023da9da717796d800187a8b1d014bdbf19c4bd"},{"signature":"previewLaunchEconomics(address)","signatureHash4":"0x45fb2063","signatureHash32":"0x45fb2063435535b55715975ac5455d1a16a8eacfb8a64720eb179377915d754d"},{"signature":"previewPersonalityEconomics(uint256)","signatureHash4":"0x64993866","signatureHash32":"0x64993866cb9bceb487705c9cce1ac54683ee11ce63198e94402788f147b97e0a"},{"signature":"proposeCreatorFeeRecipient(address,address)","signatureHash4":"0x34fcaa37","signatureHash32":"0x34fcaa37fbfc57a7e2f53af98a37b65f0ee0be46f57b393fd25e08c4d0682caa"},{"signature":"renounceOwnership()","signatureHash4":"0x715018a6","signatureHash32":"0x715018a616b5f2044428f6fadb7deef4ce9ca76ef60ea57978964ad137bbe7ae"},{"signature":"setBuybackEnabled(address,bool)","signatureHash4":"0xb18f1db1","signatureHash32":"0xb18f1db1b0ad217b039a6badb5bf3f3184d293fe8332eee8ee73a24f4f61e18a"},{"signature":"setFeeSweepOperator(address)","signatureHash4":"0x54faf9c3","signatureHash32":"0x54faf9c37d8ef684ee40d8895f54d87ebdce387780f1788966bb4fe373d7d295"},{"signature":"setLaunchForwarder(address)","signatureHash4":"0x767b7c16","signatureHash32":"0x767b7c16513081debb659f4afd268411a46e74c83d3c2c78d4a162350085cb4f"},{"signature":"setLaunchTerms(uint256,uint256,uint256,uint256,(address,uint16,uint16,uint16,uint16))","signatureHash4":"0xe7ed38bd","signatureHash32":"0xe7ed38bd9d3afc899facc0b9e1e37a92400d3a89d6e412d910c718e20de2c5b4"},{"signature":"setPairEconomics(address,uint256,bool)","signatureHash4":"0x8e8d8ec5","signatureHash32":"0x8e8d8ec5125d7ea98ffc9605416c38f2a2cae11520e7595fcd0ad91a420dfffa"},{"signature":"snipeTaxSeconds()","signatureHash4":"0x6783774b","signatureHash32":"0x6783774bda489553c5cf047da01368ed4643c07039c4f5d4a47dc4fc83552017"},{"signature":"snipeTaxStartBps()","signatureHash4":"0x50e25ac2","signatureHash32":"0x50e25ac2c81280d0af740e4f35b99f9321b5d2cef97dcfc10d4bfdb40ad2ef62"},{"signature":"SUPPLY()","signatureHash4":"0xc50497ae","signatureHash32":"0xc50497ae87301033a0f7645c3be60c327568c45887ee8590c0700946ffa3594e"},{"signature":"transferCreatorFeeRecipient(address,address)","signatureHash4":"0x2931861b","signatureHash32":"0x2931861b4cb767b5a9d00cb3c9fe2fc0d80eab21efaab3facbc74b465a5e8a70"},{"signature":"transferOwnership(address)","signatureHash4":"0xf2fde38b","signatureHash32":"0xf2fde38b092330466c661fc723d5289b90272a3e580e3187d1d7ef788506c557"},{"signature":"usedSalt(address,bytes32)","signatureHash4":"0xabb918d8","signatureHash32":"0xabb918d8973730bef7def5d820a5529dc524ec8dafc6e822386ffe433384746d"}],"event":[{"signature":"CreatorFeeRecipientChangeCancelled(address)","signatureHash4":"0x30241ded","signatureHash32":"0x30241dede93b23e050576be65d204d53b18e8c6d9f75006095bfd422094d8756"},{"signature":"CreatorFeeRecipientChangeProposed(address,address,uint256,uint256)","signatureHash4":"0x22b336cc","signatureHash32":"0x22b336cc3c163283ca94b8a02d1107b4485a820fa77cc12ea205640452d37b5e"},{"signature":"CreatorFeeRecipientUpdated(address,address,address)","signatureHash4":"0x308c390e","signatureHash32":"0x308c390ed1ab5873392818e036cabdf408bc8ad042fbaead3108954ff75ba980"},{"signature":"FeeSweepOperatorUpdated(address)","signatureHash4":"0xae994ca9","signatureHash32":"0xae994ca926e252e299c3df7516cb609272a57bf80b0e0715297e55939f873420"},{"signature":"LaunchForwarderSet(address)","signatureHash4":"0x56b32d36","signatureHash32":"0x56b32d3633fed72f97c4df44a78b5fa04f1d662d4bddebcd8a9b216d26d093ad"},{"signature":"OwnershipTransferred(address,address)","signatureHash4":"0x8be0079c","signatureHash32":"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0"},{"signature":"OwnershipTransferStarted(address,address)","signatureHash4":"0x38d16b8c","signatureHash32":"0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700"},{"signature":"PairEconomicsUpdated(address,uint256,bool)","signatureHash4":"0xb09a6234","signatureHash32":"0xb09a6234cd2453c8706211e0505ab46ba15fc2781beff4bcabce1e904414a8e7"},{"signature":"PersonalityLaunched(bytes32,address,uint256,uint256)","signatureHash4":"0xf58d88bf","signatureHash32":"0xf58d88bf88870587ec1fdf8ab973f10a093d9dc3c1a243e32f41fa5d73eda1b7"},{"signature":"TermsUpdated()","signatureHash4":"0x8f70233f","signatureHash32":"0x8f70233f68d766cfab4ff696858b5eba8fa61e09191134073df956473102569b"},{"signature":"TokenLaunched(address,address,address,address,uint256,bool,uint256)","signatureHash4":"0xf5fcbe59","signatureHash32":"0xf5fcbe596c3bf9ee9656ad0fd944810181b024583df2331100851b18dd37863b"}],"error":[{"signature":"AlreadySet()","signatureHash4":"0xa741a045","signatureHash32":"0xa741a0456e52b90bd22850f10558d4a38cdc2876b51fbd4ffc1b587676dbc61c"},{"signature":"CreatorTaxTooHigh()","signatureHash4":"0x9ad465dc","signatureHash32":"0x9ad465dcf7724dc5643ee0cfcca3e7f82fc8f426c74f87e7c24367ae09ba383c"},{"signature":"DuplicatePersonality()","signatureHash4":"0x6a997580","signatureHash32":"0x6a99758074a5c39e50bca4f94066f07dceaa54488d344d54dd930d064cef4831"},{"signature":"InvalidOraclePrice()","signatureHash4":"0x1f8f95a0","signatureHash32":"0x1f8f95a08ad25e751450104113aba3390a0f4f942b3683ff917e141292741212"},{"signature":"InvalidPersonalityValuation()","signatureHash4":"0x61ae22a2","signatureHash32":"0x61ae22a2e898bf6f7bf87860b96d3c2360f5373986b8307c6f78a0c4d27e727e"},{"signature":"InvalidTerms()","signatureHash4":"0x0256965f","signatureHash32":"0x0256965f9b387bc8ec6c98cf0ff582eaf117751bcb03b5eac94f4b122d4a5fc9"},{"signature":"LaunchEconomicsMismatch()","signatureHash4":"0x3cba147e","signatureHash32":"0x3cba147e85f4c8f847e51a4b1af7f5e4dd031578d543873c7c2bd409f865b131"},{"signature":"LaunchFeeNotPaid()","signatureHash4":"0x7e6d78a5","signatureHash32":"0x7e6d78a5fab7d0b6c1cb3b12775106b5423500eb9da90fd839b7c9e0d9d02f74"},{"signature":"NotCreatorFeeRecipient()","signatureHash4":"0xb9f93944","signatureHash32":"0xb9f93944a69da1ebb0762d373960e4081e0dd260c3be082998072fe50ad860e2"},{"signature":"NotLaunchForwarder()","signatureHash4":"0xea9eaa96","signatureHash32":"0xea9eaa96aea0ba14076131581c967846fbf867a8d8a3ebfee45b8745efbb541a"},{"signature":"OwnableInvalidOwner(address)","signatureHash4":"0x1e4fbdf7","signatureHash32":"0x1e4fbdf7f3ef8bcaa855599e3abf48b232380f183f08f6f813d9ffa5bd585188"},{"signature":"OwnableUnauthorizedAccount(address)","signatureHash4":"0x118cdaa7","signatureHash32":"0x118cdaa7a341953d1887a2245fd6665d741c67c8c50581daa59e1d03373fa188"},{"signature":"PairTokenNotApproved()","signatureHash4":"0x49285dfb","signatureHash32":"0x49285dfbe5abe7e82c5639154f2c7a3a37543bf4bdd5770d96d2311e71e466ae"},{"signature":"RecoveryNotExecutable()","signatureHash4":"0xaa0b7b61","signatureHash32":"0xaa0b7b616288c64348ea0e91fc326fd9296c041ed849725713e42b81c8e45ce5"},{"signature":"ReentrancyGuardReentrantCall()","signatureHash4":"0x3ee5aeb5","signatureHash32":"0x3ee5aeb571de7fc460830b4d0017439a1ca56fb0bc39062227ade4fe4a24c1ca"},{"signature":"SaltAlreadyUsed()","signatureHash4":"0x0ced3043","signatureHash32":"0x0ced3043c51095269d47304f006b0d7a2b34bef781061b595b1851ab3b20c9a8"},{"signature":"UnknownToken()","signatureHash4":"0x8698bf37","signatureHash32":"0x8698bf372c3832551b76614de4edaa060e8cf9dac0b26e1a9012affc437e5fd2"},{"signature":"ZeroAddress()","signatureHash4":"0xd92e233d","signatureHash32":"0xd92e233df2717d4a40030e20904abd27b68fcbeede117eaaccbbdac9618c8c73"}]},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"match":"exact_match","chainId":"4663","address":"0xb60EA6a621613ff22263BA160E0E8accaca704B0"}