{"matchId":"47533039","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-09-08T16:11:34Z","creationBytecode":{"onchainBytecode":"0x610220604052346104b1576040516128b138819003601f8101601f191683016001600160401b038111848210176104b557839282916040528339810103906101c082126104b15761004f816104c9565b602082015190916001600160a01b0382168083036104b15760408201516001600160a01b038116938482036104b15760a0605f198801126104b1576040519660a088016001600160401b038111898210176104b5576040526100b3606086016104c9565b88526100c1608086016104dd565b95602089019687526100d560a087016104dd565b60408a019081526100e860c088016104dd565b60608b015260c06100fb60e089016104dd565b60808c019081529360ff1901126104b1576040519860c08a016001600160401b0381118b8210176104b55760405261013661010089016104c9565b8a5261014561012089016104c9565b9860208b019a8a8c526101408a015197604082019889526101608b015199606083019a8b526101a06101808d01519c608085019d8e5201519c8d801515036104b15760a084019d8e5260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556001600160a01b0386169788159283156104a8575b50821561049f575b50811561048d575b5061047e578d516001600160a01b031615801561046e575b801561045e575b8015610451575b8015610440575b8015610415575b61040657885180159081156103f5575b506103e65761ffff978896879560a05260c05260e0526101005260018060a01b0390511660805260018060a01b038b51169a6001549c60018060a01b039051166101205260018060a01b039051166101405251166101605251166101805251166101a052516101c052516101e052516102005260ff60a01b9051151560a01b169160018060a81b03191617176001556040516123c490816104ed823960805181818161029e01528181610a7301528181610bd30152818161112301528181611eab0152611ff3015260a05181818161044801528181610605015281816106e90152610f7f015260c051818181610f350152611347015260e05181818161040401528181611edb0152611f6d01526101005181818161021c015261152c01526101205181818161104d015281816114e401526115be0152610140518181816111670152611596015261016051818181610b08015281816113b901526121760152610180518181816110cd01526121a701526101a051818181610aca01526116a401526101c0518181816103cc015281816105c1015261183e01526101e0518181816111f4015281816118850152611a1901526102005181818161048e015281816118b80152611a4f0152f35b63bc0ecfe360e01b5f5260045ffd5b6001600160801b031090505f61021b565b637a34030f60e01b5f5260045ffd5b5089518b51810180911161042c576107d01061020b565b634e487b7160e01b5f52601160045260245ffd5b5061271061ffff8851161015610204565b5061ffff875116156101fd565b5061271061ffff865116116101f6565b5061271061ffff845116116101ef565b63d92e233d60e01b5f5260045ffd5b6001600160a01b03161590505f6101d7565b1591505f6101cf565b1592505f6101c7565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036104b157565b519061ffff821682036104b15756fe60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f00000000000000000000000000000000000000000000000000000000000000006112ac565b3461020357602036600319011261020357600435801515809103610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000000166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f0000000000000000000000000000000000000000000000000000000000000000611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448401527f00000000000000000000000000000000000000000000000000000000000000001660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000000016101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f00000000000000000000000000000000000000000000000000000000000000009061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000000080612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000000090611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f00000000000000000000000000000000000000000000000000000000000000001682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b0000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c00000000000000000000000081ffb09b8abb42d0f6dc78a186ddf5e37b68e39b00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d0000000000000000000000000000000000000000000000000000000000000bb800000000000000000000000000000000000000000000000000000000000013880000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d000000000000000000000000000000000000000000000000537f761870183a3b000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","recompiledBytecode":"0x610220604052346104b1576040516128b138819003601f8101601f191683016001600160401b038111848210176104b557839282916040528339810103906101c082126104b15761004f816104c9565b602082015190916001600160a01b0382168083036104b15760408201516001600160a01b038116938482036104b15760a0605f198801126104b1576040519660a088016001600160401b038111898210176104b5576040526100b3606086016104c9565b88526100c1608086016104dd565b95602089019687526100d560a087016104dd565b60408a019081526100e860c088016104dd565b60608b015260c06100fb60e089016104dd565b60808c019081529360ff1901126104b1576040519860c08a016001600160401b0381118b8210176104b55760405261013661010089016104c9565b8a5261014561012089016104c9565b9860208b019a8a8c526101408a015197604082019889526101608b015199606083019a8b526101a06101808d01519c608085019d8e5201519c8d801515036104b15760a084019d8e5260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556001600160a01b0386169788159283156104a8575b50821561049f575b50811561048d575b5061047e578d516001600160a01b031615801561046e575b801561045e575b8015610451575b8015610440575b8015610415575b61040657885180159081156103f5575b506103e65761ffff978896879560a05260c05260e0526101005260018060a01b0390511660805260018060a01b038b51169a6001549c60018060a01b039051166101205260018060a01b039051166101405251166101605251166101805251166101a052516101c052516101e052516102005260ff60a01b9051151560a01b169160018060a81b03191617176001556040516123c490816104ed823960805181818161029e01528181610a7301528181610bd30152818161112301528181611eab0152611ff3015260a05181818161044801528181610605015281816106e90152610f7f015260c051818181610f350152611347015260e05181818161040401528181611edb0152611f6d01526101005181818161021c015261152c01526101205181818161104d015281816114e401526115be0152610140518181816111670152611596015261016051818181610b08015281816113b901526121760152610180518181816110cd01526121a701526101a051818181610aca01526116a401526101c0518181816103cc015281816105c1015261183e01526101e0518181816111f4015281816118850152611a1901526102005181818161048e015281816118b80152611a4f0152f35b63bc0ecfe360e01b5f5260045ffd5b6001600160801b031090505f61021b565b637a34030f60e01b5f5260045ffd5b5089518b51810180911161042c576107d01061020b565b634e487b7160e01b5f52601160045260245ffd5b5061271061ffff8851161015610204565b5061ffff875116156101fd565b5061271061ffff865116116101f6565b5061271061ffff845116116101ef565b63d92e233d60e01b5f5260045ffd5b6001600160a01b03161590505f6101d7565b1591505f6101cf565b1592505f6101c7565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036104b157565b519061ffff821682036104b15756fe60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f00000000000000000000000000000000000000000000000000000000000000006112ac565b3461020357602036600319011261020357600435801515809103610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000000166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f0000000000000000000000000000000000000000000000000000000000000000611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448401527f00000000000000000000000000000000000000000000000000000000000000001660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000000016101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f00000000000000000000000000000000000000000000000000000000000000009061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000000080612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000000090611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f00000000000000000000000000000000000000000000000000000000000000001682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033","sourceMap":"854:14457:18:-:0;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1505:66:13;2365:1;-1:-1:-1;;;;;854:14457:18;;;4256:22;;;:56;;;;-1:-1:-1;4256:89:18;;;;;-1:-1:-1;4256:120:18;;;;;-1:-1:-1;4252:146:18;;;854:14457;;-1:-1:-1;;;;;854:14457:18;4412:41;:77;;;;-1:-1:-1;4412:108:18;;;;-1:-1:-1;4412:149:18;;;;-1:-1:-1;4412:192:18;;;;-1:-1:-1;4412:238:18;;;;-1:-1:-1;4408:269:18;;971:6;;4691:23;;:59;;;;;-1:-1:-1;4687:96:18;;;854:14457;4793:18;;;;;854:14457;4793:18;854:14457;4821:39;854:14457;4870:19;854:14457;4899:21;854:14457;;;;;;;;;4930:27;854:14457;;;;;;;;1021:17;854:14457;1021:17;854:14457;;;;;;;;;;5001:50;854:14457;;;;;;;;;5061:39;854:14457;;;5110:48;854:14457;;;5168:38;854:14457;;;5216:60;971:6;854:14457;5286:33;971:6;5329:21;;971:6;5360:35;;854:14457;1021:17;;;;854:14457;;;1021:17;;;854:14457;1021:17;;;;;;;;854:14457;1021:17;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5329:21;854:14457;;;;;;;;;;;;;;;5360:35;854:14457;;;;;;;;;;;;;;;;4687:96;4759:24;;;-1:-1:-1;4759:24:18;;-1:-1:-1;4759:24:18;4691:59;-1:-1:-1;;;;;;;;4691:59:18;;;4408:269;4659:18;;;-1:-1:-1;4659:18:18;;-1:-1:-1;4659:18:18;4412:238;971:6;;;;;;;;;;;;4645:5;-1:-1:-1;4412:238:18;;971:6;854:14457;;;-1:-1:-1;971:6:18;;;;;-1:-1:-1;971:6:18;4412:192;854:14457;971:6;854:14457;;;;4565:39;;4412:192;;:149;854:14457;;;;;4524:37;4412:149;;:108;854:14457;971:6;854:14457;;;;4493:27;4412:108;;:77;854:14457;971:6;854:14457;;;;4457:32;4412:77;;4252:146;4385:13;;;-1:-1:-1;4385:13:18;;-1:-1:-1;4385:13:18;4256:120;-1:-1:-1;;;;;854:14457:18;4349:27;;-1:-1:-1;4256:120:18;;;:89;4316:29;;-1:-1:-1;4256:89:18;;;:56;4282:30;;-1:-1:-1;4256:56:18;;;854:14457;-1:-1:-1;854:14457:18;;;;;;-1:-1:-1;854:14457:18;;;;;-1:-1:-1;854:14457:18;;;;-1:-1:-1;;;;;854:14457:18;;;;;;:::o;:::-;;;;;;;;;;:::o","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033","offset":10364}},"transformations":[{"type":"insert","offset":10417,"reason":"constructorArguments"}],"transformationValues":{"constructorArguments":"0x000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b0000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c00000000000000000000000081ffb09b8abb42d0f6dc78a186ddf5e37b68e39b00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d0000000000000000000000000000000000000000000000000000000000000bb800000000000000000000000000000000000000000000000000000000000013880000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000012c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d000000000000000000000000000000000000000000000000537f761870183a3b000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}},"runtimeBytecode":{"onchainBytecode":"0x60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000081ffb09b8abb42d0f6dc78a186ddf5e37b68e39b6001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f000000000000000000000000000000000000000000000000537f761870183a3b8152f35b34610203575f366003190112610203576040517f000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c6001600160a01b03168152602090f35b34610203575f366003190112610203576040517f000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b06001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f000000000000000000000000000000000000000000000000537f761870183a3b6112ac565b3461020357602036600319011261020357600435801515809103610203577f000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b06001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b06001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f000000000000000000000000000000000000000000000000000000000000012c168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000bb8168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b06001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b06001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d6001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000001388168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d6001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000648152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b06001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000bb8166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000081ffb09b8abb42d0f6dc78a186ddf5e37b68e39b8116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d811660448401527f00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d1660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000012c16101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f000000000000000000000000000000000000000000000000537f761870183a3b9061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000006480612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000006490611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c6001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c6001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f0000000000000000000000000000000000000000000000000000000000000bb81682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000013881690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033","recompiledBytecode":"0x60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f00000000000000000000000000000000000000000000000000000000000000006112ac565b3461020357602036600319011261020357600435801515809103610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000000166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f0000000000000000000000000000000000000000000000000000000000000000611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448401527f00000000000000000000000000000000000000000000000000000000000000001660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000000016101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f00000000000000000000000000000000000000000000000000000000000000009061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000000080612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000000090611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f00000000000000000000000000000000000000000000000000000000000000001682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033","sourceMap":"854:14457:18:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3098:49;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3562:30;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;6867:9;-1:-1:-1;;;;;854:14457:18;6867:23;854:14457;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;-1:-1:-1;;;;;854:14457:18;;:::i;:::-;;;;3880:46;854:14457;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;7336:13;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3676:27;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;3406:37;854:14457;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3048:44;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;2960:32;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;3486:38;854:14457;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3776:25;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;8758:18;854:14457;;;;:::i;:::-;8758:18;:::i;:::-;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;7943:17;854:14457;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;7943:17;;:::i;:::-;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;7230:33;7245:18;;:::i;:::-;7230:12;:33;:::i;854:14457::-;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;;;;;;;3976:7;-1:-1:-1;;;;;854:14457:18;3962:10;:21;3958:46;;11421:24;854:14457;;-1:-1:-1;;;;854:14457:18;;;;;-1:-1:-1;;;854:14457:18;;;;;;;;;11452:30;;854:14457;;11452:30;854:14457;3958:46;3992:12;;;854:14457;3992:12;854:14457;;3992:12;854:14457;;;;;;-1:-1:-1;;854:14457:18;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3976:7;-1:-1:-1;;;;;854:14457:18;;3962:10;:21;;;3958:46;;854:14457;;;-1:-1:-1;;;;;854:14457:18;;5712:52;;-1:-1:-1;;;;;854:14457:18;;5778:20;;:43;;;;854:14457;5774:69;;854:14457;;-1:-1:-1;;;5872:39:18;;5905:4;854:14457;5872:39;;854:14457;;;;;;5872:39;;;;;;;;854:14457;5872:39;;;854:14457;-1:-1:-1;854:14457:18;;-1:-1:-1;;;5938:28:18;;854:14457;;;;;5938:28;;;;;;;;854:14457;5938:28;;;854:14457;5980:13;;;:34;;;;854:14457;5980:58;;;;854:14457;5980:84;;;;854:14457;5976:121;;-1:-1:-1;;;;;;854:14457:18;;;;;6131:21;971:6;6162:24;971:6;;;6209:15;6196:28;971:6;854:14457;;-1:-1:-1;;;6253:44:18;;854:14457;;;;;;6253:44;;;;;;;854:14457;6253:44;;;854:14457;971:6;;854:14457;;971:6;;6234:63;971:6;854:14457;;;;;;;;;6325:43;;;;;;;;;854:14457;6325:43;;;854:14457;971:6;6401:5;971:6;;6307:61;971:6;6382:24;:48;;;;;854:14457;6382:76;;;;854:14457;6378:107;;;854:14457;6511:21;;;;;;6765:28;854:14457;;6731:19;854:14457;;;;;;;6731:19;854:14457;;;;;;;;;;6765:28;854:14457;6534:3;-1:-1:-1;;;;;6557:13:18;;;;;;:::i;:::-;;:::i;:::-;854:14457;6557:27;6553:53;;854:14457;;-1:-1:-1;;;;;6635:13:18;;854:14457;6635:13;;;:::i;:::-;854:14457;;;6620:14;854:14457;;;;;;;;;;;;;;;;;;;6692:13;;;;;;:::i;:::-;854:14457;6675:31;854:14457;6675:31;;854:14457;6500:9;;6553:53;11240:13;;;854:14457;6593:13;854:14457;;6593:13;6378:107;6467:18;;;854:14457;6467:18;854:14457;;6467:18;6382:76;6452:6;6434:24;;;6382:76;;;:48;6410:20;;;-1:-1:-1;6382:48:18;;6325:43;;;;854:14457;6325:43;;854:14457;6325:43;;;;;;854:14457;6325:43;;;:::i;:::-;;;854:14457;;;;;;6401:5;6325:43;;;;;-1:-1:-1;6325:43:18;;;854:14457;;;;;;;;;6253:44;;;854:14457;6253:44;;854:14457;6253:44;;;;;;854:14457;6253:44;;;:::i;:::-;;;854:14457;;;;;;;;6253:44;;;;;-1:-1:-1;6253:44:18;;5976:121;6073:24;;;854:14457;6073:24;854:14457;;6073:24;5980:84;6042:22;6062:2;6042:22;;5980:84;;:58;6018:20;-1:-1:-1;;;;;6018:20:18;;5980:58;;:34;5997:17;;;;5980:34;;5938:28;;;;854:14457;5938:28;;854:14457;5938:28;;;;;;854:14457;5938:28;;;:::i;:::-;;;854:14457;;;;;5938:28;;;;;;;-1:-1:-1;5938:28:18;;5872:39;;;;854:14457;5872:39;;854:14457;5872:39;;;;;;854:14457;5872:39;;;:::i;:::-;;;854:14457;;;;;5872:39;;;;;;;-1:-1:-1;5872:39:18;;5778:43;-1:-1:-1;5812:9:18;-1:-1:-1;;;;;854:14457:18;5802:19;;5778:43;;5712:52;5744:20;;;854:14457;5744:20;854:14457;;5744:20;854:14457;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;3351:49;854:14457;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;3258:43;854:14457;;;;;;;;;;;:::i;:::-;2989:103:13;;;:::i;:::-;854:14457:18;;-1:-1:-1;;;;;854:14457:18;;4048:19;;4044:48;;10362:15;:26;10358:56;;-1:-1:-1;;;;;854:14457:18;;;10428:23;;10424:49;;8758:18;854:14457;;;:::i;8758:18::-;10538:19;;;;854:14457;;10533:93;;854:14457;;10671:22;;;;10667:74;;10802:4;;10809:8;10802:4;;10782:10;;10809:8;;:::i;:::-;854:14457;10840:5;;854:14457;10847:5;;854:14457;;10847:5;;854:14457;;;10847:5;;:::i;:::-;10863:24;854:14457;10863:24;854:14457;10863:24;:::i;:::-;;971:6;10897:25;854:14457;10897:25;854:14457;10897:25;:::i;:::-;;971:6;6867:9;-1:-1:-1;;;;;854:14457:18;6867:23;854:14457;;12133:42;;854:14457;12133:42;;;;;;;854:14457;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;:::i;:::-;;;;;;;;;;12193:5;12189:34;;854:14457;12083:206;10978:66;12083:206;;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;10782:10;;854:14457;;;;10978:66;;;;11059:50;854:14457;11075:18;;:::i;:::-;10897:25;854:14457;;;;;;;;;;11059:50;2365:1:13;-1:-1:-1;;;;;;;;;;;971:6:18;854:14457;;;;;;12189:34;12207:16;;;854:14457;12207:16;854:14457;;12207:16;854:14457;;;;;;;;;;;;;;;12083:206;12282:6;;;854:14457;12282:6;;10978:66;12282:6;;:::i;:::-;12083:206;;10667:74;9730:41;;;;854:14457;10702:39;854:14457;;;;;;10702:39;10533:93;10590:15;;;854:14457;10607:18;;:::i;:::-;10566:60;;;;854:14457;10566:60;854:14457;;;;;;10566:60;10358:56;9523:17;;;854:14457;10397:17;854:14457;;10397:17;4044:48;4076:16;;;854:14457;4076:16;854:14457;;4076:16;854:14457;;;;:::i;:::-;2989:103:13;;;;;:::i;:::-;854:14457:18;;-1:-1:-1;;;;;854:14457:18;4048:19;4044:48;;9488:15;:26;9484:56;;9569:22;;;:::i;:::-;7943:17;854:14457;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;7943:17;:::i;:::-;854:14457;;;9697:24;;;;9693:78;;9793:5;10036:79;854:14457;9793:5;10089:18;9793:5;;;854:14457;;9801:10;9813:5;854:14457;9793:18;854:14457;9801:10;;854:14457;;;9793:18;;:::i;:::-;9813:5;;854:14457;;;9813:5;;:::i;:::-;9829:24;854:14457;9829:24;854:14457;9829:24;:::i;:::-;;971:6;9863:26;854:14457;9863:26;854:14457;9863:26;:::i;:::-;;971:6;854:14457;;9937:9;;854:14457;;;;-1:-1:-1;;;;;854:14457:18;9937:9;:::i;:::-;854:14457;;9961:15;9957:64;;854:14457;;;;;10089:18;;:::i;:::-;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;10045:10;;854:14457;;;;10036:79;854:14457;9957:64;854:14457;;;;;-1:-1:-1;;;;;854:14457:18;;;9983:38;;854:14457;;9983:38;9957:64;;;9693:78;9730:41;;;;854:14457;9730:41;854:14457;;;;;;9730:41;854:14457;;;;;;-1:-1:-1;;854:14457:18;;;;;;2998:44;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;:::i;:::-;3976:7;-1:-1:-1;;;;;854:14457:18;3962:10;:21;3958:46;;-1:-1:-1;;;;;854:14457:18;11208:23;;11204:49;;11295:8;854:14457;;-1:-1:-1;;;;;854:14457:18;;11268:47;854:14457;;11268:47;-1:-1:-1;;;;;;854:14457:18;;11295:8;854:14457;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3598:34;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3844:30;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3153:45;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3807:31;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;3307:38;854:14457;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3743:27;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;2891:34;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3204:48;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;2989:103:13;;:::i;:::-;854:14457:18;;-1:-1:-1;;;;;854:14457:18;4048:19;4044:48;;4094:1;854:14457;;4094:1;:::i;:::-;854:14457;-1:-1:-1;;;;;;;;;;;971:6:18;854:14457;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;3449:31;854:14457;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3530:26;854:14457;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;7108:33;7123:18;;:::i;7108:33::-;7143:13;854:14457;;;;;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;971:6::-;-1:-1:-1;;;;;971:6:18;;-1:-1:-1;;;;;971:6:18;;;;:::o;:::-;;;;;;;;;;:::o;13127:2182::-;854:14457;;-1:-1:-1;;;13253:28:18;;;854:14457;13253:28;854:14457;13253:9;-1:-1:-1;;;;;854:14457:18;13253:28;;;;;;;-1:-1:-1;13253:28:18;;;13127:2182;-1:-1:-1;;;;;;854:14457:18;13239:10;:42;13295:9;;;:35;;13127:2182;13291:69;;13374:37;;;13127:2182;13370:80;;13478:15;854:14457;;13253:28;854:14457;13548:12;;:24;;;13127:2182;13544:37;;854:14457;13636:19;854:14457;13695:24;13615:46;;;;:::i;:::-;13695:24;;;:::i;:::-;13762:19;854:14457;5725:5:16;;;;5328;;940:4:12;5322:42:16;13831:35:18;5322:42:16;;;13831:29:18;;;;;:::i;:::-;:35;:::i;:::-;13876:20;-1:-1:-1;13910:18:18;;13906:613;;13127:2182;971:6;-1:-1:-1;13478:15:18;971:6;-1:-1:-1;13253:28:18;971:6;-1:-1:-1;13762:19:18;971:6;14621:46;14637:30;;;;:::i;:::-;14621:46;854:14457;14621:46;:::i;:::-;;971:6;14681:17;14677:335;;13127:2182;15025:19;;;971:6;15025:19;15182:55;15025:19;;15021:75;;13127:2182;15110:18;15106:61;;13127:2182;854:14457;;;;;13253:28;971:6;;854:14457;;971:6;;854:14457;15182:55;15252:50;854:14457;15268:18;;:::i;:::-;15288:13;854:14457;;;;;;13253:28;854:14457;;;15252:50;13127:2182::o;15106:61::-;854:14457;;15153:13;;854:14457;;-1:-1:-1;;;;;854:14457:18;15153:13;:::i;:::-;15106:61;;15021:75;15081:14;15059:20;;15081:14;:::i;:::-;15021:75;;14677:335;854:14457;;;;14714:29;854:14457;14714:29;854:14457;14714:29;:::i;:::-;;971:6;-1:-1:-1;854:14457:18;-1:-1:-1;;;;;14792:12:18;854:14457;;;;14807:12;;854:14457;;;;;14807:12;:::i;:::-;-1:-1:-1;854:14457:18;-1:-1:-1;;;;;854:14457:18;;14834:106;;;;;854:14457;;-1:-1:-1;;;14834:106:18;;13253:28;14834:106;;854:14457;;;;971:6;;;854:14457;;;-1:-1:-1;;;;;14873:23:18;854:14457;;971:6;;;854:14457;14898:20;854:14457;971:6;;;854:14457;971:6;;;854:14457;;-1:-1:-1;;854:14457:18;;14834:106;;854:14457;;-1:-1:-1;;14834:106:18;;;;;;;854:14457;971:6;14834:106;14959:42;14834:106;15182:55;14834:106;;;14677:335;854:14457;;;;;;;13253:28;854:14457;;;14959:42;14677:335;;;;;;;14834:106;-1:-1:-1;14834:106:18;;;:::i;:::-;-1:-1:-1;14834:106:18;;13906:613;13948:24;;;;;;;13944:60;;7108:33;7123:18;;:::i;7108:33::-;7143:13;854:14457;14133:21;14101:54;14133:21;;;;:::i;:::-;14101:54;;:::i;:::-;854:14457;14188:25;854:14457;-1:-1:-1;14173:40:18;14169:132;;13906:613;-1:-1:-1;;14319:17:18;;;14340:30;;;;;:::i;:::-;14372:17;-1:-1:-1;14315:193:18;;13906:613;;;14315:193;14414:34;;;;;;;14410:98;;14315:193;;;14410:98;9730:41;;;;-1:-1:-1;14457:51:18;13253:28;854:14457;;;;-1:-1:-1;14457:51:18;14169:132;14230:71;;;;;;:::i;:::-;14169:132;;;;;13944:60;13981:23;;;-1:-1:-1;13981:23:18;13253:28;-1:-1:-1;13981:23:18;13544:37;13574:7;;;:::o;13548:24::-;13564:8;;;13548:24;;13370:80;13420:30;;;-1:-1:-1;13420:30:18;13253:28;-1:-1:-1;13420:30:18;13374:37;854:14457;13387:19;854:14457;13387:24;;13374:37;;13291:69;13339:21;;;-1:-1:-1;13339:21:18;13253:28;-1:-1:-1;13339:21:18;13295:35;-1:-1:-1;854:14457:18;;-1:-1:-1;;;;;854:14457:18;13239:10;13308:22;;13295:35;;13253:28;;;;;;;;;;;;;;;;;:::i;:::-;;;854:14457;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;13253:28;;;;;;-1:-1:-1;13253:28:18;;6898:120;6965:50;:30;:12;854:14457;6980:15;854:14457;6965:30;;:::i;:::-;6998:17;854:14457;6965:50;;:::i;:::-;6898:120;:::o;854:14457::-;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;:::o;4015:83::-;4048:5;854:14457;4015:83;;;-1:-1:-1;;;;;854:14457:18;4048:19;4044:48;;-1:-1:-1;;;;;854:14457:18;;7976:23;7972:49;;8035:12;;8031:37;;8106:12;8092:26;:41;:26;;;:::i;:::-;8121:12;854:14457;8092:41;;:::i;:::-;8082:51;;8078:78;;8185:29;;;:::i;:::-;8249:6;;971;;;;;;;;;8243:28;8258:13;8243:28;;;:::i;:::-;-1:-1:-1;;971:6:18;;;;;;;8291:19;8616:36;8291:19;;8616:23;8291:19;8579:92;8291:19;;8287:44;;4015:83;8349:33;7108;8463:35;8400:40;8349:33;8616:15;8349:33;;;:::i;:::-;8341:5;;;;854:14457;;;8400:40;;:::i;:::-;8392:5;;;;854:14457;;;8463:35;;:::i;:::-;8450:10;;;;854:14457;;;7123:18;;:::i;:::-;7108:33;;:::i;:::-;854:14457;7143:13;854:14457;;;8616:15;;:::i;:::-;854:14457;;8616:23;;:::i;:36::-;8579:92;:::i;:::-;854:14457;;4015:83;:::o;8287:44::-;8312:19;-1:-1:-1;7108:33:18;8287:44;;8078:78;8142:14;;;4048:5;8142:14;;4048:5;8142:14;8031:37;8056:12;;;4048:5;8056:12;;4048:5;8056:12;854:14457;;;;;;;;;;;;;;;;;;-1:-1:-1;854:14457:18;;;;;;;;;;;;;;;;;;;;;;:::o;4015:83::-;4048:5;854:14457;4015:83;;;-1:-1:-1;;;;;854:14457:18;4048:19;4044:48;;8792:13;;8788:38;;8865:13;854:14457;8851:27;;;;:::i;:::-;8840:38;;8836:65;;8986:64;7123:18;7108:33;7123:18;;:::i;7108:33::-;8986:64;;:::i;:::-;9198:31;9068:41;8968:15;;;854:14457;;;;9097:6;9068:41;;:::i;:::-;9060:5;;;854:14457;;;9198:23;9127:48;854:14457;;9156:13;9127:48;;:::i;:::-;9119:5;;;;854:14457;;;;;;;9198:23;;:::i;:31::-;854:14457;;;9280:18;;:::i;:::-;-1:-1:-1;9261:37:18;9239:19;;;854:14457;4015:83;:::o;854:14457::-;;;;;;;:::o;:::-;;;;;;;;;;;;7511:335;-1:-1:-1;;;;;854:14457:18;;;;;7602:14;854:14457;;;;;;;;7602:50;;;;7511:335;7598:64;;7690:28;7708:10;854:14457;7690:15;:28;:::i;:::-;7743:15;854:14457;7732:26;;;;;7728:40;;7785:16;854:14457;;7817:2;854:14457;;;;;;7817:2;854:14457;;;;;;;7806:32;;;:::i;:::-;854:14457;7511:335;:::o;7728:40::-;7760:8;;854:14457;7760:8;:::o;7598:64::-;854:14457;7654:8;:::o;7602:50::-;854:14457;7631:16;854:14457;7631:21;7602:50;;3749:292:13;2407:1;-1:-1:-1;;;;;;;;;;;854:14457:18;4560:63:13;3644:93;;2407:1;-1:-1:-1;;;;;;;;;;;971:6:18;3749:292:13:o;3644:93::-;3696:30;;;-1:-1:-1;3696:30:13;;-1:-1:-1;3696:30:13;7296:3683:16;;;;854:14457:18;;-1:-1:-1;;7296:3683:16;;1412:159;;;;;;;;;;;;;;;;7552:9;;7548:365;;8023:19;971:6:18;8023:19:16;;8019:142;;8444:308;940:4:12;8444:308:16;;971:6:18;8444:308:16;;;;;;;;940:4:12;;8444:308:16;;9016:384;;9463:18;940:4:12;7296:3683:16;:::o;8019:142::-;1829:135:12;;;940:4;1829:135;;;;;7548:365:16;7881:17;;;971:6:18;7881:17:16;;;854:14457:18;7874:24:16;:::o;7296:3683::-;-1:-1:-1;;971:6:18;1412:159:16;;;971:6:18;1412:159:16;;;;;;;;;;;;;7552:9;;7548:365;;8023:19;;;;8019:142;;971:6:18;8444:308:16;;;940:4:12;854:14457:18;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;;;;854:14457:18;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;;854:14457:18;1829:135:12;8082:16:16;5328:5;940:4:12;;5322:42:16;1829:135:12;;;;;7548:365:16;7881:17;;;;;;:::i;7296:3683::-;;;-1:-1:-1;;7296:3683:16;;1412:159;;;;;;;;;;;;;;;;7552:9;;7548:365;;8023:19;;;;8019:142;;8444:308;;;;940:4:12;854:14457:18;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;;;;854:14457:18;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;;854:14457:18;1829:135:12;8082:16:16;5328:5;940:4:12;;5322:42:16;1829:135:12;;;;;7548:365:16;7881:17;;;;;;;:::i;2165:342:26:-;;;2346:13;;:31;;;;2165:342;2346:50;;;;2165:342;2346:76;;;;2165:342;2342:90;;2449:51;;-1:-1:-1;2449:51:26;;:::i;2342:90::-;2424:8;;;-1:-1:-1;2424:8:26;:::o;2346:76::-;;-1:-1:-1;2346:76:26;;:50;2381:15;;;2346:50;;:31;2363:14;;;2346:31;;5098:367:10;;12233:1072;;12199:23;;;;5226:5;12233:1072;854:14457:18;;;;;12233:1072:10;;;;;;;;;5226:5;12233:1072;;;;;;;;5226:5;12233:1072;;;;;;;5098:367;12233:1072;;5189:43;5185:274;;5098:367;;;:::o;5185:274::-;12233:1072;;12199:23;;;5226:5;12233:1072;;;;5226:5;12233:1072;;;5226:5;12233:1072;;;;;;;;5226:5;12233:1072;;;;;;;5185:274;12233:1072;;5252:38;5248:91;;12233:1072;;12199:23;;;;5226:5;12233:1072;;;;;;5226:5;12233:1072;;;;;;;;5226:5;12233:1072;;;;;;;5185:274;12233:1072;;5357:42;5353:95;;5098:367;:::o;5353:95::-;-1:-1:-1;;;5226:5:10;5408:40;;;-1:-1:-1;;;;;854:14457:18;;;;12233:1072:10;854:14457:18;12233:1072:10;;5408:40;12233:1072;;;;;;;;;;;;;;;;;;;;;;5226:5;12233:1072;;;;;5248:91;-1:-1:-1;;;5226:5:10;5299:40;;;-1:-1:-1;;;;;854:14457:18;;12233:1072:10;854:14457:18;12233:1072:10;;5299:40;12233:1072;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12301:307:18;-1:-1:-1;;12301:307:18;6867:9;-1:-1:-1;;;;;854:14457:18;6867:23;854:14457;;-1:-1:-1;12397:9:18;-1:-1:-1;;;;;854:14457:18;;12397:42;;;;;854:14457;;-1:-1:-1;;;12397:42:18;;-1:-1:-1;;;;;854:14457:18;;;12397:42;;;854:14457;;;;;;12397:42;;854:14457;;;12397:42;;;;;;;;12376:226;;12301:307::o;12397:42::-;;;;;;:::i;:::-;854:14457;;12376:226;12301:307::o;854:14457::-;;;12397:42;854:14457;;;;;;;;;12397:42;854:14457;;;12376:226;854:14457;;-1:-1:-1;854:14457:18;12507:9;-1:-1:-1;;;;;854:14457:18;12519:6;854:14457;;;12519:6;:::i;:::-;12540:51;;;;;-1:-1:-1;854:14457:18;;12540:51;854:14457;;;;;;;;;;;12540:51;;854:14457;;;;;;12540:51;;;854:14457;;;;;;;;;12540:51;;;;;;;;12376:226;12301:307::o;12540:51::-;-1:-1:-1;12540:51:18;;;:::i;:::-;12301:307::o;11491:514::-;6867:9;-1:-1:-1;;;;;854:14457:18;;6867:23;;11566:143;;11722:9;11718:50;;854:14457;;-1:-1:-1;;;11802:42:18;;11838:4;11802:42;;;854:14457;;;;11802:42;854:14457;11802:42;;;;;;;;854:14457;11802:42;;;11491:514;11838:4;11802:42;11838:4;11916:6;854:14457;11838:4;;11889:10;11916:6;;:::i;:::-;854:14457;;-1:-1:-1;;;11940:42:18;;11838:4;11802:42;11940;;854:14457;;;;;;11940:42;;;;;;854:14457;11940:42;;;11491:514;11940:58;;;;:::i;:42::-;;854:14457;11940:42;;854:14457;11940:42;;;;;;854:14457;11940:42;;;:::i;:::-;;;854:14457;;;;11940:58;854:14457;;11940:42;;;;;-1:-1:-1;11940:42:18;;11802;;;;854:14457;11802:42;;854:14457;11802:42;;;;;;854:14457;11802:42;;;:::i;:::-;;;854:14457;;;;;;11802:42;;;;;;-1:-1:-1;11802:42:18;;11718:50;11745:23;;;854:14457;11745:23;;854:14457;11745:23;11566:143;11605:9;;;;:19;11601:70;;11685:13;:::o;11601:70::-;11633:38;;;854:14457;11633:38;11605:9;11633:38;854:14457;;;;;11633:38;12613:348;;12710:24;12613:348;12678:22;854:14457;12678:22;854:14457;12678:22;:::i;:::-;;971:6;12710:24;854:14457;12710:24;:::i;:::-;;971:6;854:14457;12748:14;854:14457;;;;12748:26;;;12613:348;12744:211;;12613:348;:::o;12744:211::-;12898:46;12813:48;12875:69;12836:19;12819:42;854:14457;12836:19;854:14457;12819:42;;:::i;:::-;12813:48;;:::i;:::-;854:14457;12924:14;854:14457;12898:46;;:::i;:::-;12875:69;854:14457;12875:69;:::i;:::-;;971:6;12613:348::o;12748:26::-;12766:8;;;;12748:26;;1219:204:10;;8544:1067;;8509:24;;;;-1:-1:-1;8544:1067:10;854:14457:18;;;;;8544:1067:10;;;;;;-1:-1:-1;8544:1067:10;;;;;;;1338:4;-1:-1:-1;8544:1067:10;;;;;;;;;1305:38;1301:116;;1219:204;:::o;1662:232::-;10404:1148;;-1:-1:-1;;;;10404:1148:10;;;-1:-1:-1;;;;;10404:1148:10;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1662:232:10;10404:1148;;;1809:4;-1:-1:-1;10404:1148:10;;;;;;;1662:232;10404:1148;;-1:-1:-1;10404:1148:10;;1766:48;1762:126;;1662:232;:::o;10404:1148::-;;1809:4;10404:1148;;;;;;;;;;;;;;;;1181:449:26;;;1360:13;;1356:51;;1421:14;;:33;;;;1181:449;1417:69;;1509:51;;4048:5:18;1509:51:26;;:::i;:::-;1574:14;;;1570:53;;1181:449::o;1570:53::-;1597:26;;;4048:5:18;1597:26:26;;4048:5:18;1597:26:26;1417:69;1463:23;;;4048:5:18;1463:23:26;;4048:5:18;1463:23:26;1421:33;1439:15;;;1421:33;;1356:51;1382:25;;;4048:5:18;1382:25:26;;4048:5:18;1382:25:26;2513:505;;;;-1:-1:-1;;;;;2679:28:26;;:61;;;;2513:505;2679:95;;;;2513:505;2675:122;;971:6:18;;;;;;;;854:14457;;;;;;;;;;;;;;971:6;854:14457;;;;;;971:6;854:14457;;;;;;;2899:42:26;;2958:53;2899:42;;:::i;:::-;2958:53;;:::i;2679:95::-;2744:30;-1:-1:-1;;;;;2744:30:26;;2679:95;;:61;2711:29;-1:-1:-1;;;;;2711:29:26;;2679:61;","linkReferences":{},"cborAuxdata":{"1":{"value":"0xa2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033","offset":9103}},"immutableReferences":{"5524":[{"start":670,"length":32},{"start":2675,"length":32},{"start":3027,"length":32},{"start":4387,"length":32},{"start":7851,"length":32},{"start":8179,"length":32}],"5528":[{"start":1096,"length":32},{"start":1541,"length":32},{"start":1769,"length":32},{"start":3967,"length":32}],"5531":[{"start":3893,"length":32},{"start":4935,"length":32}],"5534":[{"start":1028,"length":32},{"start":7899,"length":32},{"start":8045,"length":32}],"5537":[{"start":540,"length":32},{"start":5420,"length":32}],"5539":[{"start":4173,"length":32},{"start":5348,"length":32},{"start":5566,"length":32}],"5541":[{"start":4455,"length":32},{"start":5526,"length":32}],"5543":[{"start":2824,"length":32},{"start":5049,"length":32},{"start":8566,"length":32}],"5545":[{"start":4301,"length":32},{"start":8615,"length":32}],"5547":[{"start":2762,"length":32},{"start":5796,"length":32}],"5549":[{"start":972,"length":32},{"start":1473,"length":32},{"start":6206,"length":32}],"5551":[{"start":4596,"length":32},{"start":6277,"length":32},{"start":6681,"length":32}],"5553":[{"start":1166,"length":32},{"start":6328,"length":32},{"start":6735,"length":32}]},"transformations":[{"id":"5537","type":"replace","offset":540,"reason":"immutable"},{"id":"5524","type":"replace","offset":670,"reason":"immutable"},{"id":"5549","type":"replace","offset":972,"reason":"immutable"},{"id":"5534","type":"replace","offset":1028,"reason":"immutable"},{"id":"5528","type":"replace","offset":1096,"reason":"immutable"},{"id":"5553","type":"replace","offset":1166,"reason":"immutable"},{"id":"5549","type":"replace","offset":1473,"reason":"immutable"},{"id":"5528","type":"replace","offset":1541,"reason":"immutable"},{"id":"5528","type":"replace","offset":1769,"reason":"immutable"},{"id":"5524","type":"replace","offset":2675,"reason":"immutable"},{"id":"5547","type":"replace","offset":2762,"reason":"immutable"},{"id":"5543","type":"replace","offset":2824,"reason":"immutable"},{"id":"5524","type":"replace","offset":3027,"reason":"immutable"},{"id":"5531","type":"replace","offset":3893,"reason":"immutable"},{"id":"5528","type":"replace","offset":3967,"reason":"immutable"},{"id":"5539","type":"replace","offset":4173,"reason":"immutable"},{"id":"5545","type":"replace","offset":4301,"reason":"immutable"},{"id":"5524","type":"replace","offset":4387,"reason":"immutable"},{"id":"5541","type":"replace","offset":4455,"reason":"immutable"},{"id":"5551","type":"replace","offset":4596,"reason":"immutable"},{"id":"5531","type":"replace","offset":4935,"reason":"immutable"},{"id":"5543","type":"replace","offset":5049,"reason":"immutable"},{"id":"5539","type":"replace","offset":5348,"reason":"immutable"},{"id":"5537","type":"replace","offset":5420,"reason":"immutable"},{"id":"5541","type":"replace","offset":5526,"reason":"immutable"},{"id":"5539","type":"replace","offset":5566,"reason":"immutable"},{"id":"5547","type":"replace","offset":5796,"reason":"immutable"},{"id":"5549","type":"replace","offset":6206,"reason":"immutable"},{"id":"5551","type":"replace","offset":6277,"reason":"immutable"},{"id":"5553","type":"replace","offset":6328,"reason":"immutable"},{"id":"5551","type":"replace","offset":6681,"reason":"immutable"},{"id":"5553","type":"replace","offset":6735,"reason":"immutable"},{"id":"5524","type":"replace","offset":7851,"reason":"immutable"},{"id":"5534","type":"replace","offset":7899,"reason":"immutable"},{"id":"5534","type":"replace","offset":8045,"reason":"immutable"},{"id":"5524","type":"replace","offset":8179,"reason":"immutable"},{"id":"5543","type":"replace","offset":8566,"reason":"immutable"},{"id":"5545","type":"replace","offset":8615,"reason":"immutable"}],"transformationValues":{"immutables":{"5524":"0x0000000000000000000000000000000000000000000000000000000000000000","5528":"0x000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b0","5531":"0x000000000000000000000000b60ea6a621613ff22263ba160e0e8accaca704b0","5534":"0x000000000000000000000000899ecd0bb962d674da4f4b1916200b70a7d37d1c","5537":"0x00000000000000000000000081ffb09b8abb42d0f6dc78a186ddf5e37b68e39b","5539":"0x00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d","5541":"0x00000000000000000000000042939046cee36c4cadaa4fa8be999c2d5037fe4d","5543":"0x0000000000000000000000000000000000000000000000000000000000000bb8","5545":"0x0000000000000000000000000000000000000000000000000000000000001388","5547":"0x000000000000000000000000000000000000000000000000000000000000012c","5549":"0x000000000000000000000000000000000000000000000000537f761870183a3b","5551":"0x0000000000000000000000000000000000000000000000000000000000000064","5553":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"deployment":{"transactionHash":"0x2f891b6bdd19713f759f19b03250dedf196b501fb14d55ca950c42d0025acab1","blockNumber":"57816827","transactionIndex":"6","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/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/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/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/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"}},"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.8.35+commit.47b9dedd","compilerSettings":{"viaIR":true,"optimizer":{"runs":200,"enabled":true},"evmVersion":"cancun"},"name":"BrishopBondingCurve","fullyQualifiedName":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},"abi":[{"type":"constructor","inputs":[{"name":"factory_","type":"address","internalType":"address"},{"name":"escrow_","type":"address","internalType":"contract IBrishopFeeEscrow"},{"name":"vault_","type":"address","internalType":"contract BrishopBuybackVault"},{"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"},{"name":"terms","type":"tuple","components":[{"name":"pairToken","type":"address","internalType":"address"},{"name":"creator","type":"address","internalType":"address"},{"name":"phantomQuote","type":"uint256","internalType":"uint256"},{"name":"feeBps","type":"uint256","internalType":"uint256"},{"name":"creatorTaxBps","type":"uint256","internalType":"uint256"},{"name":"buybackEnabled","type":"bool","internalType":"bool"}],"internalType":"struct BrishopBondingCurve.Terms"}],"stateMutability":"nonpayable"},{"name":"AlreadyInitialized","type":"error","inputs":[]},{"name":"DeadlineExpired","type":"error","inputs":[]},{"name":"InsufficientInputAmount","type":"error","inputs":[]},{"name":"InsufficientLiquidity","type":"error","inputs":[]},{"name":"InsufficientOutputAmount","type":"error","inputs":[]},{"name":"InsufficientRealReserve","type":"error","inputs":[{"name":"required","type":"uint256","internalType":"uint256"},{"name":"available","type":"uint256","internalType":"uint256"}]},{"name":"InternalSwapRequiresOperator","type":"error","inputs":[]},{"name":"InvalidFeePolicy","type":"error","inputs":[]},{"name":"InvalidLaunchEconomics","type":"error","inputs":[]},{"name":"MinimumOutputRequired","type":"error","inputs":[]},{"name":"NativeValueMismatch","type":"error","inputs":[{"name":"supplied","type":"uint256","internalType":"uint256"},{"name":"expected","type":"uint256","internalType":"uint256"}]},{"name":"NotFactory","type":"error","inputs":[]},{"name":"NotFeeSweepOperator","type":"error","inputs":[]},{"name":"NotInitialized","type":"error","inputs":[]},{"name":"ReentrancyGuardReentrantCall","type":"error","inputs":[]},{"name":"ReserveLimit","type":"error","inputs":[]},{"name":"ReserveLimit","type":"error","inputs":[]},{"name":"SafeERC20FailedOperation","type":"error","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"name":"SlippageExceeded","type":"error","inputs":[{"name":"actual","type":"uint256","internalType":"uint256"},{"name":"minimum","type":"uint256","internalType":"uint256"}]},{"name":"TransferFailed","type":"error","inputs":[]},{"name":"UnexpectedNativeValue","type":"error","inputs":[]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"ZeroAmount","type":"error","inputs":[]},{"name":"BuybackEnabledUpdated","type":"event","inputs":[{"name":"enabled","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"BuybackLocked","type":"event","inputs":[{"name":"quoteSpent","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tokensLocked","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"CreatorFeeRecipientUpdated","type":"event","inputs":[{"name":"previousRecipient","type":"address","indexed":true,"internalType":"address"},{"name":"newRecipient","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"CurveBuy","type":"event","inputs":[{"name":"buyer","type":"address","indexed":true,"internalType":"address"},{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"quoteIn","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tokensOut","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"fee","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tax","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"CurveSell","type":"event","inputs":[{"name":"seller","type":"address","indexed":true,"internalType":"address"},{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"tokensIn","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"quoteOut","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"fee","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tax","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"FeesSwept","type":"event","inputs":[{"name":"protocolAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"buybackAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"creatorAmount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Initialized","type":"event","inputs":[{"name":"token","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"ReservesUpdated","type":"event","inputs":[{"name":"realQuote","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tokens","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"SnipeTaxCharged","type":"event","inputs":[{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"SnipeTaxExempted","type":"event","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"MAX_RESERVE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"buy","type":"function","inputs":[{"name":"quoteIn","type":"uint256","internalType":"uint256"},{"name":"minTokensOut","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address"},{"name":"deadline","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"tokensOut","type":"uint256","internalType":"uint256"}],"stateMutability":"payable"},{"name":"buybackBurnBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"name":"buybackCreatorRecipient","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"buybackEnabled","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"buybackQuoteBalance","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"buybackVault","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract BrishopBuybackVault"}],"stateMutability":"view"},{"name":"creatorTaxBalance","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"creatorTaxBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"currentSnipeTaxBps","type":"function","inputs":[{"name":"recipient","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"deployer","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"feeBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"feeEscrow","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IBrishopFeeEscrow"}],"stateMutability":"view"},{"name":"feePolicy","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IBrishopFeePolicy"}],"stateMutability":"view"},{"name":"getReserves","type":"function","inputs":[],"outputs":[{"name":"quote","type":"uint256","internalType":"uint256"},{"name":"tokens","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"initialize","type":"function","inputs":[{"name":"token_","type":"address","internalType":"address"},{"name":"exemptions","type":"address[]","internalType":"address[]"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"isNativeQuote","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"launchSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"launchedAt","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"maxInternalPriceImpactBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"name":"pairToken","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"phantomQuote","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"protocolFeeRecipient","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"protocolFeeShareBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"name":"quoteBuy","type":"function","inputs":[{"name":"quoteIn","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address"}],"outputs":[{"name":"q","type":"tuple","components":[{"name":"tokensOut","type":"uint256","internalType":"uint256"},{"name":"fee","type":"uint256","internalType":"uint256"},{"name":"tax","type":"uint256","internalType":"uint256"},{"name":"snipeTax","type":"uint256","internalType":"uint256"}],"internalType":"struct BrishopBondingCurve.BuyQuote"}],"stateMutability":"view"},{"name":"quoteFeeBalance","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quoteReserve","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quoteSell","type":"function","inputs":[{"name":"tokensIn","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"q","type":"tuple","components":[{"name":"quoteOut","type":"uint256","internalType":"uint256"},{"name":"grossQuoteOut","type":"uint256","internalType":"uint256"},{"name":"fee","type":"uint256","internalType":"uint256"},{"name":"tax","type":"uint256","internalType":"uint256"},{"name":"reserveSufficient","type":"bool","internalType":"bool"}],"internalType":"struct BrishopBondingCurve.SellQuote"}],"stateMutability":"view"},{"name":"realQuoteReserve","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"sell","type":"function","inputs":[{"name":"tokensIn","type":"uint256","internalType":"uint256"},{"name":"minQuoteOut","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address"},{"name":"deadline","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"quoteOut","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"setBuybackEnabled","type":"function","inputs":[{"name":"enabled","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setCreatorFeeRecipient","type":"function","inputs":[{"name":"recipient","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"snipeTaxExempt","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"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":"sweepFees","type":"function","inputs":[{"name":"minBuybackTokensOut","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"token","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"tokenReserve","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"trackedQuote","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"trackedTokens","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"metadata":{"compiler":{"version":"0.8.35+commit.47b9dedd"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"factory_","type":"address"},{"internalType":"contract IBrishopFeeEscrow","name":"escrow_","type":"address"},{"internalType":"contract BrishopBuybackVault","name":"vault_","type":"address"},{"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"},{"components":[{"internalType":"address","name":"pairToken","type":"address"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"phantomQuote","type":"uint256"},{"internalType":"uint256","name":"feeBps","type":"uint256"},{"internalType":"uint256","name":"creatorTaxBps","type":"uint256"},{"internalType":"bool","name":"buybackEnabled","type":"bool"}],"internalType":"struct BrishopBondingCurve.Terms","name":"terms","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"DeadlineExpired","type":"error"},{"inputs":[],"name":"InsufficientInputAmount","type":"error"},{"inputs":[],"name":"InsufficientLiquidity","type":"error"},{"inputs":[],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"name":"InsufficientRealReserve","type":"error"},{"inputs":[],"name":"InternalSwapRequiresOperator","type":"error"},{"inputs":[],"name":"InvalidFeePolicy","type":"error"},{"inputs":[],"name":"InvalidLaunchEconomics","type":"error"},{"inputs":[],"name":"MinimumOutputRequired","type":"error"},{"inputs":[{"internalType":"uint256","name":"supplied","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"NativeValueMismatch","type":"error"},{"inputs":[],"name":"NotFactory","type":"error"},{"inputs":[],"name":"NotFeeSweepOperator","type":"error"},{"inputs":[],"name":"NotInitialized","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"ReserveLimit","type":"error"},{"inputs":[],"name":"ReserveLimit","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"minimum","type":"uint256"}],"name":"SlippageExceeded","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"UnexpectedNativeValue","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"BuybackEnabledUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"quoteSpent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensLocked","type":"uint256"}],"name":"BuybackLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousRecipient","type":"address"},{"indexed":true,"internalType":"address","name":"newRecipient","type":"address"}],"name":"CreatorFeeRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"quoteIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tax","type":"uint256"}],"name":"CurveBuy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokensIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quoteOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tax","type":"uint256"}],"name":"CurveSell","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"protocolAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"buybackAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"creatorAmount","type":"uint256"}],"name":"FeesSwept","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"realQuote","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"ReservesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SnipeTaxCharged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"SnipeTaxExempted","type":"event"},{"inputs":[],"name":"MAX_RESERVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quoteIn","type":"uint256"},{"internalType":"uint256","name":"minTokensOut","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"buy","outputs":[{"internalType":"uint256","name":"tokensOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"buybackBurnBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buybackCreatorRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buybackEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buybackQuoteBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buybackVault","outputs":[{"internalType":"contract BrishopBuybackVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creatorTaxBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creatorTaxBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"currentSnipeTaxBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeEscrow","outputs":[{"internalType":"contract IBrishopFeeEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feePolicy","outputs":[{"internalType":"contract IBrishopFeePolicy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint256","name":"quote","type":"uint256"},{"internalType":"uint256","name":"tokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address[]","name":"exemptions","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isNativeQuote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxInternalPriceImpactBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phantomQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeShareBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quoteIn","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"quoteBuy","outputs":[{"components":[{"internalType":"uint256","name":"tokensOut","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"tax","type":"uint256"},{"internalType":"uint256","name":"snipeTax","type":"uint256"}],"internalType":"struct BrishopBondingCurve.BuyQuote","name":"q","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteFeeBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensIn","type":"uint256"}],"name":"quoteSell","outputs":[{"components":[{"internalType":"uint256","name":"quoteOut","type":"uint256"},{"internalType":"uint256","name":"grossQuoteOut","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"tax","type":"uint256"},{"internalType":"bool","name":"reserveSufficient","type":"bool"}],"internalType":"struct BrishopBondingCurve.SellQuote","name":"q","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"realQuoteReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensIn","type":"uint256"},{"internalType":"uint256","name":"minQuoteOut","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"sell","outputs":[{"internalType":"uint256","name":"quoteOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setBuybackEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"setCreatorFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"snipeTaxExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"uint256","name":"minBuybackTokensOut","type":"uint256"}],"name":"sweepFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trackedQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trackedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"devdoc":{"errors":{"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}]},"kind":"dev","methods":{"initialize(address,address[])":{"details":"The caller supplies the complete immutable exemption list atomically at initialization. There is no way to add exemptions to a live pool."}},"version":1},"userdoc":{"kind":"user","methods":{"currentSnipeTaxBps(address)":{"notice":"PONS's verified fourteen-halving decay; the live three-second default produces 9900, 618, 19, 0 bps before the combined-fee cap."},"sweepFees(uint256)":{"notice":"PONS fee sweep and five-year buyback behavior, with its former graduation inventory limit removed. Minimum output bounds buyback swaps."}},"notice":"Permanent constant-product market. Phantom quote sets pricing; only actual quote reserves, excluding earned fees, can fund a sell.","version":1}},"settings":{"compilationTarget":{"src/BrishopBondingCurve.sol":"BrishopBondingCurve"},"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/token/ERC20/IERC20.sol":{"keccak256":"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2","license":"MIT","urls":["bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303","dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV"]},"@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/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_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_address,t_bool)":{"key":"t_address","label":"mapping(address => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":5522,"label":"token","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"1","type":"t_address","astId":5526,"label":"deployer","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"1","type":"t_bool","astId":5555,"label":"buybackEnabled","offset":20,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"2","type":"t_uint256","astId":5557,"label":"quoteFeeBalance","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"3","type":"t_uint256","astId":5559,"label":"buybackQuoteBalance","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"4","type":"t_uint256","astId":5561,"label":"creatorTaxBalance","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"5","type":"t_uint256","astId":5563,"label":"trackedQuote","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"6","type":"t_uint256","astId":5565,"label":"trackedTokens","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"7","type":"t_uint256","astId":5567,"label":"launchSupply","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"8","type":"t_uint256","astId":5569,"label":"launchedAt","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"9","type":"t_uint256","astId":5571,"label":"snipeTaxStartBps","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"10","type":"t_uint256","astId":5573,"label":"snipeTaxSeconds","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"11","type":"t_mapping(t_address,t_bool)","astId":5577,"label":"snipeTaxExempt","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"}]},"transientStorageLayout":{"types":null,"storage":[]},"userdoc":{"kind":"user","notice":"Permanent constant-product market. Phantom quote sets pricing; only actual quote reserves, excluding earned fees, can fund a sell.","methods":{"sweepFees(uint256)":{"notice":"PONS fee sweep and five-year buyback behavior, with its former graduation inventory limit removed. Minimum output bounds buyback swaps."},"currentSnipeTaxBps(address)":{"notice":"PONS's verified fourteen-halving decay; the live three-second default produces 9900, 618, 19, 0 bps before the combined-fee cap."}},"version":1},"devdoc":{"kind":"dev","errors":{"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}]},"methods":{"initialize(address,address[])":{"details":"The caller supplies the complete immutable exemption list atomically at initialization. There is no way to add exemptions to a live pool."}},"version":1},"sourceIds":{"src/BrishopBondingCurve.sol":{"id":18},"src/BrishopBuybackVault.sol":{"id":19},"src/interfaces/IBrishop.sol":{"id":25},"@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/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/token/ERC20/utils/SafeERC20.sol":{"id":10},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"id":15}},"additionalInput":null,"stdJsonInput":{"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/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"},"@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/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/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"}},"language":"Solidity","settings":{"viaIR":true,"optimizer":{"runs":200,"enabled":true},"evmVersion":"cancun"}},"stdJsonOutput":{"sources":{"src/BrishopBondingCurve.sol":{"id":18},"src/BrishopBuybackVault.sol":{"id":19},"src/interfaces/IBrishop.sol":{"id":25},"@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/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/token/ERC20/utils/SafeERC20.sol":{"id":10},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"id":15}},"contracts":{"src/BrishopBondingCurve.sol":{"BrishopBondingCurve":{"abi":[{"type":"constructor","inputs":[{"name":"factory_","type":"address","internalType":"address"},{"name":"escrow_","type":"address","internalType":"contract IBrishopFeeEscrow"},{"name":"vault_","type":"address","internalType":"contract BrishopBuybackVault"},{"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"},{"name":"terms","type":"tuple","components":[{"name":"pairToken","type":"address","internalType":"address"},{"name":"creator","type":"address","internalType":"address"},{"name":"phantomQuote","type":"uint256","internalType":"uint256"},{"name":"feeBps","type":"uint256","internalType":"uint256"},{"name":"creatorTaxBps","type":"uint256","internalType":"uint256"},{"name":"buybackEnabled","type":"bool","internalType":"bool"}],"internalType":"struct BrishopBondingCurve.Terms"}],"stateMutability":"nonpayable"},{"name":"AlreadyInitialized","type":"error","inputs":[]},{"name":"DeadlineExpired","type":"error","inputs":[]},{"name":"InsufficientInputAmount","type":"error","inputs":[]},{"name":"InsufficientLiquidity","type":"error","inputs":[]},{"name":"InsufficientOutputAmount","type":"error","inputs":[]},{"name":"InsufficientRealReserve","type":"error","inputs":[{"name":"required","type":"uint256","internalType":"uint256"},{"name":"available","type":"uint256","internalType":"uint256"}]},{"name":"InternalSwapRequiresOperator","type":"error","inputs":[]},{"name":"InvalidFeePolicy","type":"error","inputs":[]},{"name":"InvalidLaunchEconomics","type":"error","inputs":[]},{"name":"MinimumOutputRequired","type":"error","inputs":[]},{"name":"NativeValueMismatch","type":"error","inputs":[{"name":"supplied","type":"uint256","internalType":"uint256"},{"name":"expected","type":"uint256","internalType":"uint256"}]},{"name":"NotFactory","type":"error","inputs":[]},{"name":"NotFeeSweepOperator","type":"error","inputs":[]},{"name":"NotInitialized","type":"error","inputs":[]},{"name":"ReentrancyGuardReentrantCall","type":"error","inputs":[]},{"name":"ReserveLimit","type":"error","inputs":[]},{"name":"ReserveLimit","type":"error","inputs":[]},{"name":"SafeERC20FailedOperation","type":"error","inputs":[{"name":"token","type":"address","internalType":"address"}]},{"name":"SlippageExceeded","type":"error","inputs":[{"name":"actual","type":"uint256","internalType":"uint256"},{"name":"minimum","type":"uint256","internalType":"uint256"}]},{"name":"TransferFailed","type":"error","inputs":[]},{"name":"UnexpectedNativeValue","type":"error","inputs":[]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"ZeroAmount","type":"error","inputs":[]},{"name":"BuybackEnabledUpdated","type":"event","inputs":[{"name":"enabled","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"BuybackLocked","type":"event","inputs":[{"name":"quoteSpent","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tokensLocked","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"CreatorFeeRecipientUpdated","type":"event","inputs":[{"name":"previousRecipient","type":"address","indexed":true,"internalType":"address"},{"name":"newRecipient","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"CurveBuy","type":"event","inputs":[{"name":"buyer","type":"address","indexed":true,"internalType":"address"},{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"quoteIn","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tokensOut","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"fee","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tax","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"CurveSell","type":"event","inputs":[{"name":"seller","type":"address","indexed":true,"internalType":"address"},{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"tokensIn","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"quoteOut","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"fee","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tax","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"FeesSwept","type":"event","inputs":[{"name":"protocolAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"buybackAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"creatorAmount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Initialized","type":"event","inputs":[{"name":"token","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"name":"ReservesUpdated","type":"event","inputs":[{"name":"realQuote","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"tokens","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"SnipeTaxCharged","type":"event","inputs":[{"name":"recipient","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"SnipeTaxExempted","type":"event","inputs":[{"name":"account","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"name":"MAX_RESERVE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"buy","type":"function","inputs":[{"name":"quoteIn","type":"uint256","internalType":"uint256"},{"name":"minTokensOut","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address"},{"name":"deadline","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"tokensOut","type":"uint256","internalType":"uint256"}],"stateMutability":"payable"},{"name":"buybackBurnBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"name":"buybackCreatorRecipient","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"buybackEnabled","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"buybackQuoteBalance","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"buybackVault","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract BrishopBuybackVault"}],"stateMutability":"view"},{"name":"creatorTaxBalance","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"creatorTaxBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"currentSnipeTaxBps","type":"function","inputs":[{"name":"recipient","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"deployer","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"factory","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"feeBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"feeEscrow","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IBrishopFeeEscrow"}],"stateMutability":"view"},{"name":"feePolicy","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IBrishopFeePolicy"}],"stateMutability":"view"},{"name":"getReserves","type":"function","inputs":[],"outputs":[{"name":"quote","type":"uint256","internalType":"uint256"},{"name":"tokens","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"initialize","type":"function","inputs":[{"name":"token_","type":"address","internalType":"address"},{"name":"exemptions","type":"address[]","internalType":"address[]"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"isNativeQuote","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"launchSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"launchedAt","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"maxInternalPriceImpactBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"name":"pairToken","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"phantomQuote","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"protocolFeeRecipient","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"protocolFeeShareBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint16","internalType":"uint16"}],"stateMutability":"view"},{"name":"quoteBuy","type":"function","inputs":[{"name":"quoteIn","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address"}],"outputs":[{"name":"q","type":"tuple","components":[{"name":"tokensOut","type":"uint256","internalType":"uint256"},{"name":"fee","type":"uint256","internalType":"uint256"},{"name":"tax","type":"uint256","internalType":"uint256"},{"name":"snipeTax","type":"uint256","internalType":"uint256"}],"internalType":"struct BrishopBondingCurve.BuyQuote"}],"stateMutability":"view"},{"name":"quoteFeeBalance","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quoteReserve","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quoteSell","type":"function","inputs":[{"name":"tokensIn","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"q","type":"tuple","components":[{"name":"quoteOut","type":"uint256","internalType":"uint256"},{"name":"grossQuoteOut","type":"uint256","internalType":"uint256"},{"name":"fee","type":"uint256","internalType":"uint256"},{"name":"tax","type":"uint256","internalType":"uint256"},{"name":"reserveSufficient","type":"bool","internalType":"bool"}],"internalType":"struct BrishopBondingCurve.SellQuote"}],"stateMutability":"view"},{"name":"realQuoteReserve","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"sell","type":"function","inputs":[{"name":"tokensIn","type":"uint256","internalType":"uint256"},{"name":"minQuoteOut","type":"uint256","internalType":"uint256"},{"name":"recipient","type":"address","internalType":"address"},{"name":"deadline","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"quoteOut","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"name":"setBuybackEnabled","type":"function","inputs":[{"name":"enabled","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setCreatorFeeRecipient","type":"function","inputs":[{"name":"recipient","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"snipeTaxExempt","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"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":"sweepFees","type":"function","inputs":[{"name":"minBuybackTokensOut","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"token","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"tokenReserve","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"trackedQuote","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"trackedTokens","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"metadata":"{\"compiler\":{\"version\":\"0.8.35+commit.47b9dedd\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"factory_\",\"type\":\"address\"},{\"internalType\":\"contract IBrishopFeeEscrow\",\"name\":\"escrow_\",\"type\":\"address\"},{\"internalType\":\"contract BrishopBuybackVault\",\"name\":\"vault_\",\"type\":\"address\"},{\"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\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"pairToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"phantomQuote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeBps\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creatorTaxBps\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"buybackEnabled\",\"type\":\"bool\"}],\"internalType\":\"struct BrishopBondingCurve.Terms\",\"name\":\"terms\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientInputAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientOutputAmount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"required\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientRealReserve\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InternalSwapRequiresOperator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidFeePolicy\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidLaunchEconomics\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MinimumOutputRequired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"supplied\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"}],\"name\":\"NativeValueMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotFactory\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotFeeSweepOperator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReserveLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReserveLimit\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minimum\",\"type\":\"uint256\"}],\"name\":\"SlippageExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransferFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedNativeValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAmount\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"BuybackEnabledUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quoteSpent\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokensLocked\",\"type\":\"uint256\"}],\"name\":\"BuybackLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousRecipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newRecipient\",\"type\":\"address\"}],\"name\":\"CreatorFeeRecipientUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"buyer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quoteIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokensOut\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tax\",\"type\":\"uint256\"}],\"name\":\"CurveBuy\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"seller\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokensIn\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quoteOut\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tax\",\"type\":\"uint256\"}],\"name\":\"CurveSell\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"protocolAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"buybackAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"}],\"name\":\"FeesSwept\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"realQuote\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"name\":\"ReservesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"SnipeTaxCharged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"SnipeTaxExempted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_RESERVE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"quoteIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTokensOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"name\":\"buy\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"tokensOut\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"buybackBurnBps\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"buybackCreatorRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"buybackEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"buybackQuoteBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"buybackVault\",\"outputs\":[{\"internalType\":\"contract BrishopBuybackVault\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"creatorTaxBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"creatorTaxBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"currentSnipeTaxBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deployer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeEscrow\",\"outputs\":[{\"internalType\":\"contract IBrishopFeeEscrow\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePolicy\",\"outputs\":[{\"internalType\":\"contract IBrishopFeePolicy\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getReserves\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"quote\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token_\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"exemptions\",\"type\":\"address[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isNativeQuote\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"launchSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"launchedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxInternalPriceImpactBps\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pairToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"phantomQuote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFeeRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFeeShareBps\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"quoteIn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"quoteBuy\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"tokensOut\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tax\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"snipeTax\",\"type\":\"uint256\"}],\"internalType\":\"struct BrishopBondingCurve.BuyQuote\",\"name\":\"q\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quoteFeeBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"quoteReserve\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokensIn\",\"type\":\"uint256\"}],\"name\":\"quoteSell\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"quoteOut\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"grossQuoteOut\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"tax\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"reserveSufficient\",\"type\":\"bool\"}],\"internalType\":\"struct BrishopBondingCurve.SellQuote\",\"name\":\"q\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"realQuoteReserve\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokensIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minQuoteOut\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"name\":\"sell\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"quoteOut\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"setBuybackEnabled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"setCreatorFeeRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"snipeTaxExempt\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\":\"uint256\",\"name\":\"minBuybackTokensOut\",\"type\":\"uint256\"}],\"name\":\"sweepFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tokenReserve\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trackedQuote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trackedTokens\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"errors\":{\"ReentrancyGuardReentrantCall()\":[{\"details\":\"Unauthorized reentrant call.\"}],\"SafeERC20FailedOperation(address)\":[{\"details\":\"An operation with an ERC-20 token failed.\"}]},\"kind\":\"dev\",\"methods\":{\"initialize(address,address[])\":{\"details\":\"The caller supplies the complete immutable exemption list atomically at initialization. There is no way to add exemptions to a live pool.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"currentSnipeTaxBps(address)\":{\"notice\":\"PONS's verified fourteen-halving decay; the live three-second default produces 9900, 618, 19, 0 bps before the combined-fee cap.\"},\"sweepFees(uint256)\":{\"notice\":\"PONS fee sweep and five-year buyback behavior, with its former graduation inventory limit removed. Minimum output bounds buyback swaps.\"}},\"notice\":\"Permanent constant-product market. Phantom quote sets pricing; only actual quote reserves, excluding earned fees, can fund a sell.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/BrishopBondingCurve.sol\":\"BrishopBondingCurve\"},\"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/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x74ed01eb66b923d0d0cfe3be84604ac04b76482a55f9dd655e1ef4d367f95bc2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5282825a626cfe924e504274b864a652b0023591fa66f06a067b25b51ba9b303\",\"dweb:/ipfs/QmeCfPykghhMc81VJTrHTC7sF6CRvaA1FXVq2pJhwYp1dV\"]},\"@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/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","notice":"Permanent constant-product market. Phantom quote sets pricing; only actual quote reserves, excluding earned fees, can fund a sell.","methods":{"sweepFees(uint256)":{"notice":"PONS fee sweep and five-year buyback behavior, with its former graduation inventory limit removed. Minimum output bounds buyback swaps."},"currentSnipeTaxBps(address)":{"notice":"PONS's verified fourteen-halving decay; the live three-second default produces 9900, 618, 19, 0 bps before the combined-fee cap."}},"version":1},"devdoc":{"kind":"dev","errors":{"ReentrancyGuardReentrantCall()":[{"details":"Unauthorized reentrant call."}],"SafeERC20FailedOperation(address)":[{"details":"An operation with an ERC-20 token failed."}]},"methods":{"initialize(address,address[])":{"details":"The caller supplies the complete immutable exemption list atomically at initialization. There is no way to add exemptions to a live pool."}},"version":1},"storageLayout":{"types":{"t_bool":{"label":"bool","encoding":"inplace","numberOfBytes":"1"},"t_address":{"label":"address","encoding":"inplace","numberOfBytes":"20"},"t_uint256":{"label":"uint256","encoding":"inplace","numberOfBytes":"32"},"t_mapping(t_address,t_bool)":{"key":"t_address","label":"mapping(address => bool)","value":"t_bool","encoding":"mapping","numberOfBytes":"32"}},"storage":[{"slot":"0","type":"t_address","astId":5522,"label":"token","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"1","type":"t_address","astId":5526,"label":"deployer","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"1","type":"t_bool","astId":5555,"label":"buybackEnabled","offset":20,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"2","type":"t_uint256","astId":5557,"label":"quoteFeeBalance","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"3","type":"t_uint256","astId":5559,"label":"buybackQuoteBalance","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"4","type":"t_uint256","astId":5561,"label":"creatorTaxBalance","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"5","type":"t_uint256","astId":5563,"label":"trackedQuote","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"6","type":"t_uint256","astId":5565,"label":"trackedTokens","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"7","type":"t_uint256","astId":5567,"label":"launchSupply","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"8","type":"t_uint256","astId":5569,"label":"launchedAt","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"9","type":"t_uint256","astId":5571,"label":"snipeTaxStartBps","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"10","type":"t_uint256","astId":5573,"label":"snipeTaxSeconds","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"},{"slot":"11","type":"t_mapping(t_address,t_bool)","astId":5577,"label":"snipeTaxExempt","offset":0,"contract":"src/BrishopBondingCurve.sol:BrishopBondingCurve"}]},"transientStorageLayout":{"types":null,"storage":[]},"evm":{"bytecode":{"object":"610220604052346104b1576040516128b138819003601f8101601f191683016001600160401b038111848210176104b557839282916040528339810103906101c082126104b15761004f816104c9565b602082015190916001600160a01b0382168083036104b15760408201516001600160a01b038116938482036104b15760a0605f198801126104b1576040519660a088016001600160401b038111898210176104b5576040526100b3606086016104c9565b88526100c1608086016104dd565b95602089019687526100d560a087016104dd565b60408a019081526100e860c088016104dd565b60608b015260c06100fb60e089016104dd565b60808c019081529360ff1901126104b1576040519860c08a016001600160401b0381118b8210176104b55760405261013661010089016104c9565b8a5261014561012089016104c9565b9860208b019a8a8c526101408a015197604082019889526101608b015199606083019a8b526101a06101808d01519c608085019d8e5201519c8d801515036104b15760a084019d8e5260017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00556001600160a01b0386169788159283156104a8575b50821561049f575b50811561048d575b5061047e578d516001600160a01b031615801561046e575b801561045e575b8015610451575b8015610440575b8015610415575b61040657885180159081156103f5575b506103e65761ffff978896879560a05260c05260e0526101005260018060a01b0390511660805260018060a01b038b51169a6001549c60018060a01b039051166101205260018060a01b039051166101405251166101605251166101805251166101a052516101c052516101e052516102005260ff60a01b9051151560a01b169160018060a81b03191617176001556040516123c490816104ed823960805181818161029e01528181610a7301528181610bd30152818161112301528181611eab0152611ff3015260a05181818161044801528181610605015281816106e90152610f7f015260c051818181610f350152611347015260e05181818161040401528181611edb0152611f6d01526101005181818161021c015261152c01526101205181818161104d015281816114e401526115be0152610140518181816111670152611596015261016051818181610b08015281816113b901526121760152610180518181816110cd01526121a701526101a051818181610aca01526116a401526101c0518181816103cc015281816105c1015261183e01526101e0518181816111f4015281816118850152611a1901526102005181818161048e015281816118b80152611a4f0152f35b63bc0ecfe360e01b5f5260045ffd5b6001600160801b031090505f61021b565b637a34030f60e01b5f5260045ffd5b5089518b51810180911161042c576107d01061020b565b634e487b7160e01b5f52601160045260245ffd5b5061271061ffff8851161015610204565b5061ffff875116156101fd565b5061271061ffff865116116101f6565b5061271061ffff845116116101ef565b63d92e233d60e01b5f5260045ffd5b6001600160a01b03161590505f6101d7565b1591505f6101cf565b1592505f6101c7565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036104b157565b519061ffff821682036104b15756fe60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f00000000000000000000000000000000000000000000000000000000000000006112ac565b3461020357602036600319011261020357600435801515809103610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000000166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f0000000000000000000000000000000000000000000000000000000000000000611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448401527f00000000000000000000000000000000000000000000000000000000000000001660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000000016101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f00000000000000000000000000000000000000000000000000000000000000009061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000000080612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000000090611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f00000000000000000000000000000000000000000000000000000000000000001682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033","sourceMap":"854:14457:18:-:0;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1505:66:13;2365:1;-1:-1:-1;;;;;854:14457:18;;;4256:22;;;:56;;;;-1:-1:-1;4256:89:18;;;;;-1:-1:-1;4256:120:18;;;;;-1:-1:-1;4252:146:18;;;854:14457;;-1:-1:-1;;;;;854:14457:18;4412:41;:77;;;;-1:-1:-1;4412:108:18;;;;-1:-1:-1;4412:149:18;;;;-1:-1:-1;4412:192:18;;;;-1:-1:-1;4412:238:18;;;;-1:-1:-1;4408:269:18;;971:6;;4691:23;;:59;;;;;-1:-1:-1;4687:96:18;;;854:14457;4793:18;;;;;854:14457;4793:18;854:14457;4821:39;854:14457;4870:19;854:14457;4899:21;854:14457;;;;;;;;;4930:27;854:14457;;;;;;;;1021:17;854:14457;1021:17;854:14457;;;;;;;;;;5001:50;854:14457;;;;;;;;;5061:39;854:14457;;;5110:48;854:14457;;;5168:38;854:14457;;;5216:60;971:6;854:14457;5286:33;971:6;5329:21;;971:6;5360:35;;854:14457;1021:17;;;;854:14457;;;1021:17;;;854:14457;1021:17;;;;;;;;854:14457;1021:17;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5329:21;854:14457;;;;;;;;;;;;;;;5360:35;854:14457;;;;;;;;;;;;;;;;4687:96;4759:24;;;-1:-1:-1;4759:24:18;;-1:-1:-1;4759:24:18;4691:59;-1:-1:-1;;;;;;;;4691:59:18;;;4408:269;4659:18;;;-1:-1:-1;4659:18:18;;-1:-1:-1;4659:18:18;4412:238;971:6;;;;;;;;;;;;4645:5;-1:-1:-1;4412:238:18;;971:6;854:14457;;;-1:-1:-1;971:6:18;;;;;-1:-1:-1;971:6:18;4412:192;854:14457;971:6;854:14457;;;;4565:39;;4412:192;;:149;854:14457;;;;;4524:37;4412:149;;:108;854:14457;971:6;854:14457;;;;4493:27;4412:108;;:77;854:14457;971:6;854:14457;;;;4457:32;4412:77;;4252:146;4385:13;;;-1:-1:-1;4385:13:18;;-1:-1:-1;4385:13:18;4256:120;-1:-1:-1;;;;;854:14457:18;4349:27;;-1:-1:-1;4256:120:18;;;:89;4316:29;;-1:-1:-1;4256:89:18;;;:56;4282:30;;-1:-1:-1;4256:56:18;;;854:14457;-1:-1:-1;854:14457:18;;;;;;-1:-1:-1;854:14457:18;;;;;-1:-1:-1;854:14457:18;;;;-1:-1:-1;;;;;854:14457:18;;;;;;:::o;:::-;;;;;;;;;;:::o","linkReferences":{}},"deployedBytecode":{"object":"60806040526004361015610011575f80fd5b5f3560e01c80630902f1ac1461123c578063160d0da51461121757806324a9d853146111dd5780633729bb9a146111965780633cd1fb8f146111525780633de35b791461110e5780633f7ed6b7146110f157806349127e2a146110b35780634c37ef231461037b5780634f1f58fd1461109957806350e25ac21461107c57806364df049e146110385780636783774b1461101b5780637809452a14610ffe5780637b04ea6214610f645780638258903814610f205780638945257c14610d995780638a038a5414610b2c5780639040f86614610aee57806390addc1e14610ab0578063946d9204146106895780639a9b567d146105e55780639da771f4146105a2578063a4afe0bf14610527578063a64190c4146104ce578063bf56b371146104b1578063c1bb890114610477578063c45a015514610433578063c4b7de97146103ef578063c57eadfc146103b5578063ca52b0b714610398578063cbcb31711461037b578063d44bdfe71461033e578063d5f3948814610316578063d7e1ef39146102eb578063db2bd533146102ce578063dc08e09414610289578063ed479c471461026c578063eff31e9e1461024b578063f1f5c993146102075763fc0c546a146101dc575f80fd5b34610203575f366003190112610203575f546040516001600160a01b039091168152602090f35b5f80fd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040516001600160801b038152f35b34610203575f366003190112610203576020600254604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316158152602090f35b34610203575f366003190112610203576020600454604051908152f35b3461020357602036600319011261020357602061030e610309611268565b611ab9565b604051908152f35b34610203575f366003190112610203576001546040516001600160a01b039091168152602090f35b34610203576020366003190112610203576001600160a01b0361035f611268565b165f52600b602052602060ff60405f2054166040519015158152f35b34610203575f366003190112610203576020600654604051908152f35b34610203575f366003190112610203576020600554604051908152f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f366003190112610203576020600854604051908152f35b346102035760203660031901126102035760a06104f46004356104ef61198d565b6119c8565b60806040519180518352602081015160208401526040810151604084015260608101516060840152015115156080820152f35b34610203576040366003190112610203576024356001600160a01b03811681036102035761057b60809160405161055d816112cd565b5f81525f60208201525f60408201525f606082015260043590611814565b60606040519180518352602081015160208401526040810151604084015201516060820152f35b34610203575f36600319011261020357602061030e6105bf6117be565b7f00000000000000000000000000000000000000000000000000000000000000006112ac565b3461020357602036600319011261020357600435801515809103610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001805460ff60a01b191660a083901b60ff60a01b161790556040519081527fbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a090602090a1005b631966391b60e11b5f5260045ffd5b34610203576040366003190112610203576106a2611268565b60243567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203576024820191602436918360051b010111610203577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316913383900361067a575f54936001600160a01b038516610aa2576001600160a01b03169283158015610a70575b61092c576040516370a0823160e01b815230600482015294602086602481885afa958615610996575f96610a3c575b506040516318160ddd60e01b815290602082600481895afa918215610996575f92610a08575b50861580156109ff575b80156109ef575b80156109e5575b6109d6576001600160a01b03191685175f556007556006859055426008556040516328712d6160e11b815290602082600481845afa918215610996575f926109a1575b509060206004928260095560405193848092636783774b60e01b82525afa918215610996575f92610960575b506126ac9082600a5511908115610957575b811561094a575b5061093b575f5b82811061089d577f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040867f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e66020888451908152a18151905f82526020820152a1005b6001600160a01b036108b86108b38386866117dc565b611800565b161561092c576001906001600160a01b036108d76108b38387876117dc565b165f52600b60205260405f208260ff19825416179055818060a01b036109016108b38387876117dc565b167fe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c75f80a20161083a565b63d92e233d60e01b5f5260045ffd5b637a34030f60e01b5f5260045ffd5b6201518091501185610833565b8015915061082c565b9091506020813d60201161098e575b8161097c602093836112e9565b810103126102035751906126ac61081a565b3d915061096f565b6040513d5f823e3d90fd5b91506020823d6020116109ce575b816109bc602093836112e9565b810103126102035790519060206107ee565b3d91506109af565b63bc0ecfe360e01b5f5260045ffd5b50602285116107ab565b506001600160801b0382116107a4565b5081871161079d565b9091506020813d602011610a34575b81610a24602093836112e9565b8101031261020357519087610793565b3d9150610a17565b9095506020813d602011610a68575b81610a58602093836112e9565b810103126102035751948661076d565b3d9150610a4b565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316841461073e565b62dc149f60e41b5f5260045ffd5b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461020357610b3a3661127e565b92610b43611b2e565b5f546001600160a01b0316938415610d8a574211610d7b576001600160a01b03821691821561092c57610b78826104ef61198d565b94608086015115610d5857855194808610610d42575082610b9c9130903390612222565b6040850190610bb36060835197019687519061212f565b610bbf85600554611325565b600555610bce836006546112ac565b6006557f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680610d0d5750505f80808087875af13d15610d08573d67ffffffffffffffff8111610cf45760405190610c38601f8201601f1916602001836112e9565b81525f60203d92013e5b15610ce5576020947f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df915b51905160408051948552602085018790528401919091526060830152339180608081015b0390a37f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e6040610cbf6117be565b600654825191825285820152a160015f51602061236f5f395f51905f5255604051908152f35b6312171d8360e31b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b610c42565b91610d3d86602098937f8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df956121e3565b610c6d565b856371c4efed60e01b5f5260045260245260445ffd5b6020860151610d656117be565b90630865175560e11b5f5260045260245260445ffd5b631ab7da6b60e01b5f5260045ffd5b6321c4e35760e21b5f5260045ffd5b610da23661127e565b610dad939193611b2e565b5f546001600160a01b031615610d8a574211610d7b57610dcc90611ff1565b610df78382604051610ddd816112cd565b5f81525f60208201525f60408201525f6060820152611814565b90815192808410610f0a57507fec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455602094610e98868501805190610e506040610e4560608a01948551906112ac565b98019788519061212f565b610e5c866005546112ac565b600555610e6b88600654611325565b6006555f54610e8690899086906001600160a01b03166121e3565b815180610ece575b50519051906112ac565b9351604080519485526020850187905284019490945260608301939093526001600160a01b039092169133918060808101610c91565b6040519081526001600160a01b038516907f3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934908b90a289610e8e565b836371c4efed60e01b5f5260045260245260445ffd5b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461020357602036600319011261020357610f7d611268565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361067a576001600160a01b0316801561092c57600154816001600160a01b0382167f2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd195f80a36001600160a01b03191617600155005b34610203575f366003190112610203576020600354604051908152f35b34610203575f366003190112610203576020600a54604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576020600954604051908152f35b34610203575f36600319011261020357602061030e6117be565b34610203575f36600319011261020357602060405161ffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610203575f366003190112610203576020600754604051908152f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203575f366003190112610203576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610203576020366003190112610203576111af611b2e565b5f546001600160a01b031615610d8a576111ca600435611332565b60015f51602061236f5f395f51905f5255005b34610203575f3660031901126102035760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610203575f36600319011261020357602060ff60015460a01c166040519015158152f35b34610203575f3660031901126102035760406112596105bf6117be565b60065482519182526020820152f35b600435906001600160a01b038216820361020357565b60809060031901126102035760043590602435906044356001600160a01b0381168103610203579060643590565b919082018092116112b957565b634e487b7160e01b5f52601160045260245ffd5b6080810190811067ffffffffffffffff821117610cf457604052565b90601f8019910116810190811067ffffffffffffffff821117610cf457604052565b6001600160801b0303906001600160801b0382116112b957565b919082039182116112b957565b604051638a36a6bb60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610996575f9161177c575b506001600160a01b03163314158080611767575b611758578061174d575b61173e5760025490600454821580611736575b6117315761ffff7f0000000000000000000000000000000000000000000000000000000000000000166113ed6113e68286611b66565b8095611325565b600354818082109118029361140e858318946114098685611325565b6112ac565b945f9203611672575b505f6002555f6004555f60035561143961143185876112ac565b600554611325565b6005558061150d575b5050916060917f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f93826114de575b816114c2575b60405192835260208301526040820152a17f5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e60406114b26117be565b60065482519182526020820152a1565b6001546114d99083906001600160a01b0316611ea6565b611476565b611508837f0000000000000000000000000000000000000000000000000000000000000000611ea6565b611470565b9290939161151d84600654611325565b6006555f546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116969161155d918791899116611d6f565b5f546001600160a01b031690863b156102035760405163892823f760e01b81526004810192909252602482018690526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660448401527f00000000000000000000000000000000000000000000000000000000000000001660648301526084820152945f90869060a490829084905af19485156109965760406060957f5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff927f9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f98611662575b508151908482526020820152a19193819350611442565b5f61166c916112e9565b5f61164b565b80949193929415611722576116886105bf6117be565b6006549061169f61169986836112ac565b86611bea565b61ffff7f000000000000000000000000000000000000000000000000000000000000000016101561170e575b5050836116e75750906116dd916112ac565b915f915b5f611417565b808492959394106116f857506116e1565b906371c4efed60e01b5f5260045260245260445ffd5b61171a92955084611d29565b925f806116cb565b633672d25f60e01b5f5260045ffd5b505050565b5080156113b0565b630c736d4160e21b5f5260045ffd5b50600354151561139d565b63235084c360e21b5f5260045ffd5b506001546001600160a01b0316331415611393565b90506020813d6020116117b6575b81611797602093836112e9565b8101031261020357516001600160a01b0381168103610203575f61137f565b3d915061178a565b6117d96117d060055460025490611325565b60045490611325565b90565b91908110156117ec5760051b0190565b634e487b7160e01b5f52603260045260245ffd5b356001600160a01b03811681036102035790565b5f549092906001600160a01b031615610d8a576001600160a01b0381161561092c57811561197e577f00000000000000000000000000000000000000000000000000000000000000009061187361186a8361130b565b60055490611325565b831161196f5761188290611ab9565b917f000000000000000000000000000000000000000000000000000000000000000080612710039261271084116112b9576118de7f00000000000000000000000000000000000000000000000000000000000000008095611325565b60631981019081116112b9578561195b9382611953936119609911611965575b50611947611931611923611915611953948a611b66565b9960208d019a8b5289611b66565b9360408c0194855288611b66565b9460608b019586526119416117be565b906112ac565b95600654975190611325565b905190611325565b61228b565b815290565b91506119476118fe565b63b026649f60e01b5f5260045ffd5b631f2a200560e01b5f5260045ffd5b6040519060a0820182811067ffffffffffffffff821117610cf4576040525f6080838281528260208201528260408201528260608201520152565b5f549091906001600160a01b031615610d8a57801561197e57600654906119ee8261130b565b811161196f57611a0991611a036105bf6117be565b9161228b565b611a86611a3e60208401928084527f000000000000000000000000000000000000000000000000000000000000000090611b66565b60408401908152611953611a7484517f000000000000000000000000000000000000000000000000000000000000000090611b66565b91606086019283528451905190611325565b825251611a916117be565b1015608082015290565b8115611aa5570490565b634e487b7160e01b5f52601260045260245ffd5b6001600160a01b03165f908152600b602052604090205460ff168015611b24575b611b2057611aea60085442611325565b600a549081811015611b1a5760095491600e820291808304600e14901517156112b957611b1691611a9b565b1c90565b50505f90565b5f90565b5060095415611ada565b60025f51602061236f5f395f51905f525414611b575760025f51602061236f5f395f51905f5255565b633ee5aeb560e01b5f5260045ffd5b9091905f905f198482099084810292838084109303928084039314611bdd57826127101115611bcb57507fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e919394612710910990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b5050506127109192500490565b5f19612710820991612710820291828085109403938085039414611c7f5783821115611c6757612710829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b50634e487b715f52156003026011186020526024601cfd5b50906117d99250611a9b565b90915f198383099280830292838086109503948086039514611d1c5784831115611d045790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b5050906117d99250611a9b565b909181158015611d67575b8015611d5f575b8015611d58575b611d51576117d9925f926122e9565b5050505f90565b505f611d42565b508015611d3b565b508215611d34565b916040519163095ea7b360e01b5f5260018060a01b031691826004528160245260205f60448180885af19060015f5114821615611e97575b60405215611db457505050565b60405163095ea7b360e01b5f52826004525f60245260205f60448180885af19060015f5114821615611e7f575b60405215611e61576040519163095ea7b360e01b5f5260045260245260205f60448180865af19060015f5114821615611e40575b60405215611e205750565b635274afe760e01b5f9081526001600160a01b0391909116600452602490fd5b906001811516611e5857823b15153d15161690611e15565b503d5f823e3d90fd5b635274afe760e01b5f9081526001600160a01b038416600452602490fd5b906001811516611e5857843b15153d15161690611de1565b90843b15153d15161690611da7565b5f91907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031680611f6757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690813b15611f63576040516301aba89b60e71b81526001600160a01b03909116600482015291839183916024918391905af18015611f5857611f43575050565b611f4e8280926112e9565b611f555750565b80fd5b6040513d84823e3d90fd5b8380fd5b919250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611fa0848284611d6f565b803b15610203575f928360649260405196879586946309ad4dd960e01b865260018060a01b03166004860152602485015260448401525af1801561099657611fe55750565b5f611fef916112e9565b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690811561210d57346120fe576040516370a0823160e01b815230600482015290602082602481865afa918215610996575f926120c9575b50602492612064602092303384612222565b6040516370a0823160e01b815230600482015293849182905afa8015610996575f90612095575b6117d99250611325565b506020823d6020116120c1575b816120af602093836112e9565b81010312610203576117d9915161208b565b3d91506120a2565b9091506020813d6020116120f6575b816120e5602093836112e9565b810103126102035751906024612052565b3d91506120d8565b63e0aeda7d60e01b5f5260045ffd5b80915034036121195790565b635e3b067f60e11b5f523460045260245260445ffd5b9061214b90612140836002546112ac565b6002556004546112ac565b60045560ff60015460a01c16806121da575b6121645750565b6121cd6121a26121d59261219c61ffff7f00000000000000000000000000000000000000000000000000000000000000001682611b66565b90611325565b61ffff7f00000000000000000000000000000000000000000000000000000000000000001690611b66565b6003546112ac565b600355565b5080151561215d565b916040519163a9059cbb60e01b5f5260018060a01b031660045260245260205f60448180865af19060015f5114821615611e405760405215611e205750565b6040516323b872dd60e01b5f9081526001600160a01b039384166004529290931660245260449390935260209060648180865af19060015f5114821615612273575b6040525f60605215611e205750565b906001811516611e5857823b15153d15161690612264565b909181156122da57821580156122d2575b6122c3576122ab925f926122e9565b9081156122b457565b6342301c2360e01b5f5260045ffd5b63bb55fd2760e01b5f5260045ffd5b50801561229c565b63098fb56160e01b5f5260045ffd5b9190926001600160801b038311801561235e575b801561234e575b61196f57612710039161271083116112b9578281029281840414901517156112b95761271083029280840461271014901517156112b957612348826117d9946112ac565b91611c8b565b506001600160801b038211612304565b506001600160801b0384116122fd56fe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220c396fb92a5ef51329f53b3c8ce5519ab28c8758717be69300871383bbaf4223064736f6c63430008230033","sourceMap":"854:14457:18:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3098:49;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3562:30;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;6867:9;-1:-1:-1;;;;;854:14457:18;6867:23;854:14457;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;-1:-1:-1;;;;;854:14457:18;;:::i;:::-;;;;3880:46;854:14457;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;7336:13;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3676:27;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;3406:37;854:14457;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3048:44;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;2960:32;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;3486:38;854:14457;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3776:25;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;8758:18;854:14457;;;;:::i;:::-;8758:18;:::i;:::-;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;7943:17;854:14457;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;7943:17;;:::i;:::-;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;7230:33;7245:18;;:::i;:::-;7230:12;:33;:::i;854:14457::-;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;;;;;;;3976:7;-1:-1:-1;;;;;854:14457:18;3962:10;:21;3958:46;;11421:24;854:14457;;-1:-1:-1;;;;854:14457:18;;;;;-1:-1:-1;;;854:14457:18;;;;;;;;;11452:30;;854:14457;;11452:30;854:14457;3958:46;3992:12;;;854:14457;3992:12;854:14457;;3992:12;854:14457;;;;;;-1:-1:-1;;854:14457:18;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3976:7;-1:-1:-1;;;;;854:14457:18;;3962:10;:21;;;3958:46;;854:14457;;;-1:-1:-1;;;;;854:14457:18;;5712:52;;-1:-1:-1;;;;;854:14457:18;;5778:20;;:43;;;;854:14457;5774:69;;854:14457;;-1:-1:-1;;;5872:39:18;;5905:4;854:14457;5872:39;;854:14457;;;;;;5872:39;;;;;;;;854:14457;5872:39;;;854:14457;-1:-1:-1;854:14457:18;;-1:-1:-1;;;5938:28:18;;854:14457;;;;;5938:28;;;;;;;;854:14457;5938:28;;;854:14457;5980:13;;;:34;;;;854:14457;5980:58;;;;854:14457;5980:84;;;;854:14457;5976:121;;-1:-1:-1;;;;;;854:14457:18;;;;;6131:21;971:6;6162:24;971:6;;;6209:15;6196:28;971:6;854:14457;;-1:-1:-1;;;6253:44:18;;854:14457;;;;;;6253:44;;;;;;;854:14457;6253:44;;;854:14457;971:6;;854:14457;;971:6;;6234:63;971:6;854:14457;;;;;;;;;6325:43;;;;;;;;;854:14457;6325:43;;;854:14457;971:6;6401:5;971:6;;6307:61;971:6;6382:24;:48;;;;;854:14457;6382:76;;;;854:14457;6378:107;;;854:14457;6511:21;;;;;;6765:28;854:14457;;6731:19;854:14457;;;;;;;6731:19;854:14457;;;;;;;;;;6765:28;854:14457;6534:3;-1:-1:-1;;;;;6557:13:18;;;;;;:::i;:::-;;:::i;:::-;854:14457;6557:27;6553:53;;854:14457;;-1:-1:-1;;;;;6635:13:18;;854:14457;6635:13;;;:::i;:::-;854:14457;;;6620:14;854:14457;;;;;;;;;;;;;;;;;;;6692:13;;;;;;:::i;:::-;854:14457;6675:31;854:14457;6675:31;;854:14457;6500:9;;6553:53;11240:13;;;854:14457;6593:13;854:14457;;6593:13;6378:107;6467:18;;;854:14457;6467:18;854:14457;;6467:18;6382:76;6452:6;6434:24;;;6382:76;;;:48;6410:20;;;-1:-1:-1;6382:48:18;;6325:43;;;;854:14457;6325:43;;854:14457;6325:43;;;;;;854:14457;6325:43;;;:::i;:::-;;;854:14457;;;;;;6401:5;6325:43;;;;;-1:-1:-1;6325:43:18;;;854:14457;;;;;;;;;6253:44;;;854:14457;6253:44;;854:14457;6253:44;;;;;;854:14457;6253:44;;;:::i;:::-;;;854:14457;;;;;;;;6253:44;;;;;-1:-1:-1;6253:44:18;;5976:121;6073:24;;;854:14457;6073:24;854:14457;;6073:24;5980:84;6042:22;6062:2;6042:22;;5980:84;;:58;6018:20;-1:-1:-1;;;;;6018:20:18;;5980:58;;:34;5997:17;;;;5980:34;;5938:28;;;;854:14457;5938:28;;854:14457;5938:28;;;;;;854:14457;5938:28;;;:::i;:::-;;;854:14457;;;;;5938:28;;;;;;;-1:-1:-1;5938:28:18;;5872:39;;;;854:14457;5872:39;;854:14457;5872:39;;;;;;854:14457;5872:39;;;:::i;:::-;;;854:14457;;;;;5872:39;;;;;;;-1:-1:-1;5872:39:18;;5778:43;-1:-1:-1;5812:9:18;-1:-1:-1;;;;;854:14457:18;5802:19;;5778:43;;5712:52;5744:20;;;854:14457;5744:20;854:14457;;5744:20;854:14457;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;3351:49;854:14457;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;3258:43;854:14457;;;;;;;;;;;:::i;:::-;2989:103:13;;;:::i;:::-;854:14457:18;;-1:-1:-1;;;;;854:14457:18;;4048:19;;4044:48;;10362:15;:26;10358:56;;-1:-1:-1;;;;;854:14457:18;;;10428:23;;10424:49;;8758:18;854:14457;;;:::i;8758:18::-;10538:19;;;;854:14457;;10533:93;;854:14457;;10671:22;;;;10667:74;;10802:4;;10809:8;10802:4;;10782:10;;10809:8;;:::i;:::-;854:14457;10840:5;;854:14457;10847:5;;854:14457;;10847:5;;854:14457;;;10847:5;;:::i;:::-;10863:24;854:14457;10863:24;854:14457;10863:24;:::i;:::-;;971:6;10897:25;854:14457;10897:25;854:14457;10897:25;:::i;:::-;;971:6;6867:9;-1:-1:-1;;;;;854:14457:18;6867:23;854:14457;;12133:42;;854:14457;12133:42;;;;;;;854:14457;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;:::i;:::-;;;;;;;;;;12193:5;12189:34;;854:14457;12083:206;10978:66;12083:206;;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;10782:10;;854:14457;;;;10978:66;;;;11059:50;854:14457;11075:18;;:::i;:::-;10897:25;854:14457;;;;;;;;;;11059:50;2365:1:13;-1:-1:-1;;;;;;;;;;;971:6:18;854:14457;;;;;;12189:34;12207:16;;;854:14457;12207:16;854:14457;;12207:16;854:14457;;;;;;;;;;;;;;;12083:206;12282:6;;;854:14457;12282:6;;10978:66;12282:6;;:::i;:::-;12083:206;;10667:74;9730:41;;;;854:14457;10702:39;854:14457;;;;;;10702:39;10533:93;10590:15;;;854:14457;10607:18;;:::i;:::-;10566:60;;;;854:14457;10566:60;854:14457;;;;;;10566:60;10358:56;9523:17;;;854:14457;10397:17;854:14457;;10397:17;4044:48;4076:16;;;854:14457;4076:16;854:14457;;4076:16;854:14457;;;;:::i;:::-;2989:103:13;;;;;:::i;:::-;854:14457:18;;-1:-1:-1;;;;;854:14457:18;4048:19;4044:48;;9488:15;:26;9484:56;;9569:22;;;:::i;:::-;7943:17;854:14457;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;7943:17;:::i;:::-;854:14457;;;9697:24;;;;9693:78;;9793:5;10036:79;854:14457;9793:5;10089:18;9793:5;;;854:14457;;9801:10;9813:5;854:14457;9793:18;854:14457;9801:10;;854:14457;;;9793:18;;:::i;:::-;9813:5;;854:14457;;;9813:5;;:::i;:::-;9829:24;854:14457;9829:24;854:14457;9829:24;:::i;:::-;;971:6;9863:26;854:14457;9863:26;854:14457;9863:26;:::i;:::-;;971:6;854:14457;;9937:9;;854:14457;;;;-1:-1:-1;;;;;854:14457:18;9937:9;:::i;:::-;854:14457;;9961:15;9957:64;;854:14457;;;;;10089:18;;:::i;:::-;854:14457;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;10045:10;;854:14457;;;;10036:79;854:14457;9957:64;854:14457;;;;;-1:-1:-1;;;;;854:14457:18;;;9983:38;;854:14457;;9983:38;9957:64;;;9693:78;9730:41;;;;854:14457;9730:41;854:14457;;;;;;9730:41;854:14457;;;;;;-1:-1:-1;;854:14457:18;;;;;;2998:44;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;:::i;:::-;3976:7;-1:-1:-1;;;;;854:14457:18;3962:10;:21;3958:46;;-1:-1:-1;;;;;854:14457:18;11208:23;;11204:49;;11295:8;854:14457;;-1:-1:-1;;;;;854:14457:18;;11268:47;854:14457;;11268:47;-1:-1:-1;;;;;;854:14457:18;;11295:8;854:14457;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3598:34;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3844:30;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3153:45;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3807:31;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;854:14457:18;;;;;;;;3307:38;854:14457;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;3743:27;854:14457;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;2891:34;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3204:48;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;2989:103:13;;:::i;:::-;854:14457:18;;-1:-1:-1;;;;;854:14457:18;4048:19;4044:48;;4094:1;854:14457;;4094:1;:::i;:::-;854:14457;-1:-1:-1;;;;;;;;;;;971:6:18;854:14457;;;;;;;-1:-1:-1;;854:14457:18;;;;;;;3449:31;854:14457;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;;3530:26;854:14457;;;;;;;;;;;;;;;;;;-1:-1:-1;;854:14457:18;;;;;7108:33;7123:18;;:::i;7108:33::-;7143:13;854:14457;;;;;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;971:6::-;-1:-1:-1;;;;;971:6:18;;-1:-1:-1;;;;;971:6:18;;;;:::o;:::-;;;;;;;;;;:::o;13127:2182::-;854:14457;;-1:-1:-1;;;13253:28:18;;;854:14457;13253:28;854:14457;13253:9;-1:-1:-1;;;;;854:14457:18;13253:28;;;;;;;-1:-1:-1;13253:28:18;;;13127:2182;-1:-1:-1;;;;;;854:14457:18;13239:10;:42;13295:9;;;:35;;13127:2182;13291:69;;13374:37;;;13127:2182;13370:80;;13478:15;854:14457;;13253:28;854:14457;13548:12;;:24;;;13127:2182;13544:37;;854:14457;13636:19;854:14457;13695:24;13615:46;;;;:::i;:::-;13695:24;;;:::i;:::-;13762:19;854:14457;5725:5:16;;;;5328;;940:4:12;5322:42:16;13831:35:18;5322:42:16;;;13831:29:18;;;;;:::i;:::-;:35;:::i;:::-;13876:20;-1:-1:-1;13910:18:18;;13906:613;;13127:2182;971:6;-1:-1:-1;13478:15:18;971:6;-1:-1:-1;13253:28:18;971:6;-1:-1:-1;13762:19:18;971:6;14621:46;14637:30;;;;:::i;:::-;14621:46;854:14457;14621:46;:::i;:::-;;971:6;14681:17;14677:335;;13127:2182;15025:19;;;971:6;15025:19;15182:55;15025:19;;15021:75;;13127:2182;15110:18;15106:61;;13127:2182;854:14457;;;;;13253:28;971:6;;854:14457;;971:6;;854:14457;15182:55;15252:50;854:14457;15268:18;;:::i;:::-;15288:13;854:14457;;;;;;13253:28;854:14457;;;15252:50;13127:2182::o;15106:61::-;854:14457;;15153:13;;854:14457;;-1:-1:-1;;;;;854:14457:18;15153:13;:::i;:::-;15106:61;;15021:75;15081:14;15059:20;;15081:14;:::i;:::-;15021:75;;14677:335;854:14457;;;;14714:29;854:14457;14714:29;854:14457;14714:29;:::i;:::-;;971:6;-1:-1:-1;854:14457:18;-1:-1:-1;;;;;14792:12:18;854:14457;;;;14807:12;;854:14457;;;;;14807:12;:::i;:::-;-1:-1:-1;854:14457:18;-1:-1:-1;;;;;854:14457:18;;14834:106;;;;;854:14457;;-1:-1:-1;;;14834:106:18;;13253:28;14834:106;;854:14457;;;;971:6;;;854:14457;;;-1:-1:-1;;;;;14873:23:18;854:14457;;971:6;;;854:14457;14898:20;854:14457;971:6;;;854:14457;971:6;;;854:14457;;-1:-1:-1;;854:14457:18;;14834:106;;854:14457;;-1:-1:-1;;14834:106:18;;;;;;;854:14457;971:6;14834:106;14959:42;14834:106;15182:55;14834:106;;;14677:335;854:14457;;;;;;;13253:28;854:14457;;;14959:42;14677:335;;;;;;;14834:106;-1:-1:-1;14834:106:18;;;:::i;:::-;-1:-1:-1;14834:106:18;;13906:613;13948:24;;;;;;;13944:60;;7108:33;7123:18;;:::i;7108:33::-;7143:13;854:14457;14133:21;14101:54;14133:21;;;;:::i;:::-;14101:54;;:::i;:::-;854:14457;14188:25;854:14457;-1:-1:-1;14173:40:18;14169:132;;13906:613;-1:-1:-1;;14319:17:18;;;14340:30;;;;;:::i;:::-;14372:17;-1:-1:-1;14315:193:18;;13906:613;;;14315:193;14414:34;;;;;;;14410:98;;14315:193;;;14410:98;9730:41;;;;-1:-1:-1;14457:51:18;13253:28;854:14457;;;;-1:-1:-1;14457:51:18;14169:132;14230:71;;;;;;:::i;:::-;14169:132;;;;;13944:60;13981:23;;;-1:-1:-1;13981:23:18;13253:28;-1:-1:-1;13981:23:18;13544:37;13574:7;;;:::o;13548:24::-;13564:8;;;13548:24;;13370:80;13420:30;;;-1:-1:-1;13420:30:18;13253:28;-1:-1:-1;13420:30:18;13374:37;854:14457;13387:19;854:14457;13387:24;;13374:37;;13291:69;13339:21;;;-1:-1:-1;13339:21:18;13253:28;-1:-1:-1;13339:21:18;13295:35;-1:-1:-1;854:14457:18;;-1:-1:-1;;;;;854:14457:18;13239:10;13308:22;;13295:35;;13253:28;;;;;;;;;;;;;;;;;:::i;:::-;;;854:14457;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;13253:28;;;;;;-1:-1:-1;13253:28:18;;6898:120;6965:50;:30;:12;854:14457;6980:15;854:14457;6965:30;;:::i;:::-;6998:17;854:14457;6965:50;;:::i;:::-;6898:120;:::o;854:14457::-;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;854:14457:18;;;;;;;:::o;4015:83::-;4048:5;854:14457;4015:83;;;-1:-1:-1;;;;;854:14457:18;4048:19;4044:48;;-1:-1:-1;;;;;854:14457:18;;7976:23;7972:49;;8035:12;;8031:37;;8106:12;8092:26;:41;:26;;;:::i;:::-;8121:12;854:14457;8092:41;;:::i;:::-;8082:51;;8078:78;;8185:29;;;:::i;:::-;8249:6;;971;;;;;;;;;8243:28;8258:13;8243:28;;;:::i;:::-;-1:-1:-1;;971:6:18;;;;;;;8291:19;8616:36;8291:19;;8616:23;8291:19;8579:92;8291:19;;8287:44;;4015:83;8349:33;7108;8463:35;8400:40;8349:33;8616:15;8349:33;;;:::i;:::-;8341:5;;;;854:14457;;;8400:40;;:::i;:::-;8392:5;;;;854:14457;;;8463:35;;:::i;:::-;8450:10;;;;854:14457;;;7123:18;;:::i;:::-;7108:33;;:::i;:::-;854:14457;7143:13;854:14457;;;8616:15;;:::i;:::-;854:14457;;8616:23;;:::i;:36::-;8579:92;:::i;:::-;854:14457;;4015:83;:::o;8287:44::-;8312:19;-1:-1:-1;7108:33:18;8287:44;;8078:78;8142:14;;;4048:5;8142:14;;4048:5;8142:14;8031:37;8056:12;;;4048:5;8056:12;;4048:5;8056:12;854:14457;;;;;;;;;;;;;;;;;;-1:-1:-1;854:14457:18;;;;;;;;;;;;;;;;;;;;;;:::o;4015:83::-;4048:5;854:14457;4015:83;;;-1:-1:-1;;;;;854:14457:18;4048:19;4044:48;;8792:13;;8788:38;;8865:13;854:14457;8851:27;;;;:::i;:::-;8840:38;;8836:65;;8986:64;7123:18;7108:33;7123:18;;:::i;7108:33::-;8986:64;;:::i;:::-;9198:31;9068:41;8968:15;;;854:14457;;;;9097:6;9068:41;;:::i;:::-;9060:5;;;854:14457;;;9198:23;9127:48;854:14457;;9156:13;9127:48;;:::i;:::-;9119:5;;;;854:14457;;;;;;;9198:23;;:::i;:31::-;854:14457;;;9280:18;;:::i;:::-;-1:-1:-1;9261:37:18;9239:19;;;854:14457;4015:83;:::o;854:14457::-;;;;;;;:::o;:::-;;;;;;;;;;;;7511:335;-1:-1:-1;;;;;854:14457:18;;;;;7602:14;854:14457;;;;;;;;7602:50;;;;7511:335;7598:64;;7690:28;7708:10;854:14457;7690:15;:28;:::i;:::-;7743:15;854:14457;7732:26;;;;;7728:40;;7785:16;854:14457;;7817:2;854:14457;;;;;;7817:2;854:14457;;;;;;;7806:32;;;:::i;:::-;854:14457;7511:335;:::o;7728:40::-;7760:8;;854:14457;7760:8;:::o;7598:64::-;854:14457;7654:8;:::o;7602:50::-;854:14457;7631:16;854:14457;7631:21;7602:50;;3749:292:13;2407:1;-1:-1:-1;;;;;;;;;;;854:14457:18;4560:63:13;3644:93;;2407:1;-1:-1:-1;;;;;;;;;;;971:6:18;3749:292:13:o;3644:93::-;3696:30;;;-1:-1:-1;3696:30:13;;-1:-1:-1;3696:30:13;7296:3683:16;;;;854:14457:18;;-1:-1:-1;;7296:3683:16;;1412:159;;;;;;;;;;;;;;;;7552:9;;7548:365;;8023:19;971:6:18;8023:19:16;;8019:142;;8444:308;940:4:12;8444:308:16;;971:6:18;8444:308:16;;;;;;;;940:4:12;;8444:308:16;;9016:384;;9463:18;940:4:12;7296:3683:16;:::o;8019:142::-;1829:135:12;;;940:4;1829:135;;;;;7548:365:16;7881:17;;;971:6:18;7881:17:16;;;854:14457:18;7874:24:16;:::o;7296:3683::-;-1:-1:-1;;971:6:18;1412:159:16;;;971:6:18;1412:159:16;;;;;;;;;;;;;7552:9;;7548:365;;8023:19;;;;8019:142;;971:6:18;8444:308:16;;;940:4:12;854:14457:18;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;;;;854:14457:18;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;;854:14457:18;1829:135:12;8082:16:16;5328:5;940:4:12;;5322:42:16;1829:135:12;;;;;7548:365:16;7881:17;;;;;;:::i;7296:3683::-;;;-1:-1:-1;;7296:3683:16;;1412:159;;;;;;;;;;;;;;;;7552:9;;7548:365;;8023:19;;;;8019:142;;8444:308;;;;940:4:12;854:14457:18;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;;;;854:14457:18;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;;854:14457:18;1829:135:12;8082:16:16;5328:5;940:4:12;;5322:42:16;1829:135:12;;;;;7548:365:16;7881:17;;;;;;;:::i;2165:342:26:-;;;2346:13;;:31;;;;2165:342;2346:50;;;;2165:342;2346:76;;;;2165:342;2342:90;;2449:51;;-1:-1:-1;2449:51:26;;:::i;2342:90::-;2424:8;;;-1:-1:-1;2424:8:26;:::o;2346:76::-;;-1:-1:-1;2346:76:26;;:50;2381:15;;;2346:50;;:31;2363:14;;;2346:31;;5098:367:10;;12233:1072;;12199:23;;;;5226:5;12233:1072;854:14457:18;;;;;12233:1072:10;;;;;;;;;5226:5;12233:1072;;;;;;;;5226:5;12233:1072;;;;;;;5098:367;12233:1072;;5189:43;5185:274;;5098:367;;;:::o;5185:274::-;12233:1072;;12199:23;;;5226:5;12233:1072;;;;5226:5;12233:1072;;;5226:5;12233:1072;;;;;;;;5226:5;12233:1072;;;;;;;5185:274;12233:1072;;5252:38;5248:91;;12233:1072;;12199:23;;;;5226:5;12233:1072;;;;;;5226:5;12233:1072;;;;;;;;5226:5;12233:1072;;;;;;;5185:274;12233:1072;;5357:42;5353:95;;5098:367;:::o;5353:95::-;-1:-1:-1;;;5226:5:10;5408:40;;;-1:-1:-1;;;;;854:14457:18;;;;12233:1072:10;854:14457:18;12233:1072:10;;5408:40;12233:1072;;;;;;;;;;;;;;;;;;;;;;5226:5;12233:1072;;;;;5248:91;-1:-1:-1;;;5226:5:10;5299:40;;;-1:-1:-1;;;;;854:14457:18;;12233:1072:10;854:14457:18;12233:1072:10;;5299:40;12233:1072;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12301:307:18;-1:-1:-1;;12301:307:18;6867:9;-1:-1:-1;;;;;854:14457:18;6867:23;854:14457;;-1:-1:-1;12397:9:18;-1:-1:-1;;;;;854:14457:18;;12397:42;;;;;854:14457;;-1:-1:-1;;;12397:42:18;;-1:-1:-1;;;;;854:14457:18;;;12397:42;;;854:14457;;;;;;12397:42;;854:14457;;;12397:42;;;;;;;;12376:226;;12301:307::o;12397:42::-;;;;;;:::i;:::-;854:14457;;12376:226;12301:307::o;854:14457::-;;;12397:42;854:14457;;;;;;;;;12397:42;854:14457;;;12376:226;854:14457;;-1:-1:-1;854:14457:18;12507:9;-1:-1:-1;;;;;854:14457:18;12519:6;854:14457;;;12519:6;:::i;:::-;12540:51;;;;;-1:-1:-1;854:14457:18;;12540:51;854:14457;;;;;;;;;;;12540:51;;854:14457;;;;;;12540:51;;;854:14457;;;;;;;;;12540:51;;;;;;;;12376:226;12301:307::o;12540:51::-;-1:-1:-1;12540:51:18;;;:::i;:::-;12301:307::o;11491:514::-;6867:9;-1:-1:-1;;;;;854:14457:18;;6867:23;;11566:143;;11722:9;11718:50;;854:14457;;-1:-1:-1;;;11802:42:18;;11838:4;11802:42;;;854:14457;;;;11802:42;854:14457;11802:42;;;;;;;;854:14457;11802:42;;;11491:514;11838:4;11802:42;11838:4;11916:6;854:14457;11838:4;;11889:10;11916:6;;:::i;:::-;854:14457;;-1:-1:-1;;;11940:42:18;;11838:4;11802:42;11940;;854:14457;;;;;;11940:42;;;;;;854:14457;11940:42;;;11491:514;11940:58;;;;:::i;:42::-;;854:14457;11940:42;;854:14457;11940:42;;;;;;854:14457;11940:42;;;:::i;:::-;;;854:14457;;;;11940:58;854:14457;;11940:42;;;;;-1:-1:-1;11940:42:18;;11802;;;;854:14457;11802:42;;854:14457;11802:42;;;;;;854:14457;11802:42;;;:::i;:::-;;;854:14457;;;;;;11802:42;;;;;;-1:-1:-1;11802:42:18;;11718:50;11745:23;;;854:14457;11745:23;;854:14457;11745:23;11566:143;11605:9;;;;:19;11601:70;;11685:13;:::o;11601:70::-;11633:38;;;854:14457;11633:38;11605:9;11633:38;854:14457;;;;;11633:38;12613:348;;12710:24;12613:348;12678:22;854:14457;12678:22;854:14457;12678:22;:::i;:::-;;971:6;12710:24;854:14457;12710:24;:::i;:::-;;971:6;854:14457;12748:14;854:14457;;;;12748:26;;;12613:348;12744:211;;12613:348;:::o;12744:211::-;12898:46;12813:48;12875:69;12836:19;12819:42;854:14457;12836:19;854:14457;12819:42;;:::i;:::-;12813:48;;:::i;:::-;854:14457;12924:14;854:14457;12898:46;;:::i;:::-;12875:69;854:14457;12875:69;:::i;:::-;;971:6;12613:348::o;12748:26::-;12766:8;;;;12748:26;;1219:204:10;;8544:1067;;8509:24;;;;-1:-1:-1;8544:1067:10;854:14457:18;;;;;8544:1067:10;;;;;;-1:-1:-1;8544:1067:10;;;;;;;1338:4;-1:-1:-1;8544:1067:10;;;;;;;;;1305:38;1301:116;;1219:204;:::o;1662:232::-;10404:1148;;-1:-1:-1;;;;10404:1148:10;;;-1:-1:-1;;;;;10404:1148:10;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1662:232:10;10404:1148;;;1809:4;-1:-1:-1;10404:1148:10;;;;;;;1662:232;10404:1148;;-1:-1:-1;10404:1148:10;;1766:48;1762:126;;1662:232;:::o;10404:1148::-;;1809:4;10404:1148;;;;;;;;;;;;;;;;1181:449:26;;;1360:13;;1356:51;;1421:14;;:33;;;;1181:449;1417:69;;1509:51;;4048:5:18;1509:51:26;;:::i;:::-;1574:14;;;1570:53;;1181:449::o;1570:53::-;1597:26;;;4048:5:18;1597:26:26;;4048:5:18;1597:26:26;1417:69;1463:23;;;4048:5:18;1463:23:26;;4048:5:18;1463:23:26;1421:33;1439:15;;;1421:33;;1356:51;1382:25;;;4048:5:18;1382:25:26;;4048:5:18;1382:25:26;2513:505;;;;-1:-1:-1;;;;;2679:28:26;;:61;;;;2513:505;2679:95;;;;2513:505;2675:122;;971:6:18;;;;;;;;854:14457;;;;;;;;;;;;;;971:6;854:14457;;;;;;971:6;854:14457;;;;;;;2899:42:26;;2958:53;2899:42;;:::i;:::-;2958:53;;:::i;2679:95::-;2744:30;-1:-1:-1;;;;;2744:30:26;;2679:95;;:61;2711:29;-1:-1:-1;;;;;2711:29:26;;2679:61;","linkReferences":{},"immutableReferences":{"5524":[{"start":670,"length":32},{"start":2675,"length":32},{"start":3027,"length":32},{"start":4387,"length":32},{"start":7851,"length":32},{"start":8179,"length":32}],"5528":[{"start":1096,"length":32},{"start":1541,"length":32},{"start":1769,"length":32},{"start":3967,"length":32}],"5531":[{"start":3893,"length":32},{"start":4935,"length":32}],"5534":[{"start":1028,"length":32},{"start":7899,"length":32},{"start":8045,"length":32}],"5537":[{"start":540,"length":32},{"start":5420,"length":32}],"5539":[{"start":4173,"length":32},{"start":5348,"length":32},{"start":5566,"length":32}],"5541":[{"start":4455,"length":32},{"start":5526,"length":32}],"5543":[{"start":2824,"length":32},{"start":5049,"length":32},{"start":8566,"length":32}],"5545":[{"start":4301,"length":32},{"start":8615,"length":32}],"5547":[{"start":2762,"length":32},{"start":5796,"length":32}],"5549":[{"start":972,"length":32},{"start":1473,"length":32},{"start":6206,"length":32}],"5551":[{"start":4596,"length":32},{"start":6277,"length":32},{"start":6681,"length":32}],"5553":[{"start":1166,"length":32},{"start":6328,"length":32},{"start":6735,"length":32}]}}}}}}},"signatures":{"function":[{"signature":"buybackBurnBps()","signatureHash4":"0x49127e2a","signatureHash32":"0x49127e2a996a1ed8dc40580b4988b8330a10d72e1b8eb56329a512448589153e"},{"signature":"buybackCreatorRecipient()","signatureHash4":"0x3cd1fb8f","signatureHash32":"0x3cd1fb8f8408d3bbf0671ad00dd9c9e04d2021289bf4c0b888050ba50431cacd"},{"signature":"buybackEnabled()","signatureHash4":"0x160d0da5","signatureHash32":"0x160d0da515437b146182242f0ae0accc363d1b8b386496e8f8f4e092b8cdd0e0"},{"signature":"buybackQuoteBalance()","signatureHash4":"0x7809452a","signatureHash32":"0x7809452a0f55378251499876f030fb530c3825cb397efbad87954cb616a50168"},{"signature":"buybackVault()","signatureHash4":"0xf1f5c993","signatureHash32":"0xf1f5c993ccb3f93b450c0d36b9999158ea17a56907576709d04c9a76cf5f7d06"},{"signature":"buy(uint256,uint256,address,uint256)","signatureHash4":"0x8945257c","signatureHash32":"0x8945257cd98ccbd38cf481491657347062630ade6b58ce8ae31c196df7324e7e"},{"signature":"creatorTaxBalance()","signatureHash4":"0xdb2bd533","signatureHash32":"0xdb2bd533f7d57d5c82b08f48d6093ab850722beb9529bf468b7b4079f0155ce4"},{"signature":"creatorTaxBps()","signatureHash4":"0xc1bb8901","signatureHash32":"0xc1bb89012a8cf14cd2a75c3c217b4e3c14d96fb734efedc9b73374a90ffe4e05"},{"signature":"currentSnipeTaxBps(address)","signatureHash4":"0xd7e1ef39","signatureHash32":"0xd7e1ef39133c8d22157b8ff22df59aa19fce8df0568aa59f4375142965232ce0"},{"signature":"deployer()","signatureHash4":"0xd5f39488","signatureHash32":"0xd5f39488f54e32975711ebf8f895091063a3a4953e442c37b83f4e804a13ef4e"},{"signature":"factory()","signatureHash4":"0xc45a0155","signatureHash32":"0xc45a01550ceb4bc5c6b2e6f722b5033a03078f9bd6673457375ba94c26ac1cf0"},{"signature":"feeBps()","signatureHash4":"0x24a9d853","signatureHash32":"0x24a9d85381176ce7f0b1b3841f92299cc755d72f01089960d8178157468b9368"},{"signature":"feeEscrow()","signatureHash4":"0xc4b7de97","signatureHash32":"0xc4b7de97cd4ac57ef574c54dc88537fe05d3734b2fab89e3bb031fccc9d91d6d"},{"signature":"feePolicy()","signatureHash4":"0x82589038","signatureHash32":"0x82589038801a2392f29fb666d0a5e5ffe046fbed3dc17c1d1cc3aec9ec1f5f65"},{"signature":"getReserves()","signatureHash4":"0x0902f1ac","signatureHash32":"0x0902f1ac5dbaeedd3217f11b3cbaf929216c9c5abc2d69da89d54964bead575d"},{"signature":"initialize(address,address[])","signatureHash4":"0x946d9204","signatureHash32":"0x946d92043ae53a69508daa86bce0e9f33933dbe375636b58f65d53dbbe74706d"},{"signature":"isNativeQuote()","signatureHash4":"0xdc08e094","signatureHash32":"0xdc08e0945865d2387ee7333409556dc8986b6cb6eaf39eddd06c01487e6d688b"},{"signature":"launchedAt()","signatureHash4":"0xbf56b371","signatureHash32":"0xbf56b371b5acb80beea42e4a57f23d4725e8632e2eb65a8e25edaf2100fd38ad"},{"signature":"launchSupply()","signatureHash4":"0x3f7ed6b7","signatureHash32":"0x3f7ed6b728c96404aa9ac7cef142d6c0e31ea0302ac22f89e524a4220fbf8f88"},{"signature":"maxInternalPriceImpactBps()","signatureHash4":"0x90addc1e","signatureHash32":"0x90addc1e55ad5ab161a74caaad23d71d2bf1b3ff2336e031e6b0ec7f001df8d8"},{"signature":"MAX_RESERVE()","signatureHash4":"0xeff31e9e","signatureHash32":"0xeff31e9e62e43086e826a5e37cb2ea711368912919cea8e86186e29aa602540b"},{"signature":"pairToken()","signatureHash4":"0x3de35b79","signatureHash32":"0x3de35b796b7297cf81cd91a071be82666ffa523854d6d54552129d12951115ad"},{"signature":"phantomQuote()","signatureHash4":"0xc57eadfc","signatureHash32":"0xc57eadfc88853ba8662f1072c2c7cd5bfd2eae2e504fd3c6ff447dc18e31afdc"},{"signature":"protocolFeeRecipient()","signatureHash4":"0x64df049e","signatureHash32":"0x64df049ee593aa50a43f96c2ef469ffdea0d195cc25e9e238b06469e0b440e99"},{"signature":"protocolFeeShareBps()","signatureHash4":"0x9040f866","signatureHash32":"0x9040f8669d130912399a715df282fbe9b1a8f7a131f7d250fb1e76b5b53c6681"},{"signature":"quoteBuy(uint256,address)","signatureHash4":"0xa4afe0bf","signatureHash32":"0xa4afe0bf87c99f7608b0ffaaaf44d995ad66940d06f833f2335282abf8690cdc"},{"signature":"quoteFeeBalance()","signatureHash4":"0xed479c47","signatureHash32":"0xed479c47e8bdfa5c8b3a19ba039625986b6b380763faec03397db14f268210e5"},{"signature":"quoteReserve()","signatureHash4":"0x9da771f4","signatureHash32":"0x9da771f4d4593c1c1b2402117209dfdc130bc6075e5512c146772842c5a623a3"},{"signature":"quoteSell(uint256)","signatureHash4":"0xa64190c4","signatureHash32":"0xa64190c48f97a6e0fa65491bf75816697dfd29ca8b4174c27003e430f10bf0b3"},{"signature":"realQuoteReserve()","signatureHash4":"0x4f1f58fd","signatureHash32":"0x4f1f58fd884161137b1fe24319eba069376e818190e0ceb917e3364cce214f7e"},{"signature":"sell(uint256,uint256,address,uint256)","signatureHash4":"0x8a038a54","signatureHash32":"0x8a038a54624b55cadf2a2604f62085edd56e8df9a7185225f07f81ef8268ac22"},{"signature":"setBuybackEnabled(bool)","signatureHash4":"0x9a9b567d","signatureHash32":"0x9a9b567dc1e0a7d3075213a2a43ba6962b06ba1b64669e361a10677512463910"},{"signature":"setCreatorFeeRecipient(address)","signatureHash4":"0x7b04ea62","signatureHash32":"0x7b04ea62bb81a7fafd890f481fe45edfee03e20b4e3623e04743e3fb5ebec2b4"},{"signature":"snipeTaxExempt(address)","signatureHash4":"0xd44bdfe7","signatureHash32":"0xd44bdfe7c31a3bed470a17c2ab0c89d016360a69237bee9d8a97e0380c8bb971"},{"signature":"snipeTaxSeconds()","signatureHash4":"0x6783774b","signatureHash32":"0x6783774bda489553c5cf047da01368ed4643c07039c4f5d4a47dc4fc83552017"},{"signature":"snipeTaxStartBps()","signatureHash4":"0x50e25ac2","signatureHash32":"0x50e25ac2c81280d0af740e4f35b99f9321b5d2cef97dcfc10d4bfdb40ad2ef62"},{"signature":"sweepFees(uint256)","signatureHash4":"0x3729bb9a","signatureHash32":"0x3729bb9a444e0eca2eb4578c21532c4d15a99ce58f70c963ffa903b7cea454b4"},{"signature":"token()","signatureHash4":"0xfc0c546a","signatureHash32":"0xfc0c546a8dce9d6e9b97c086302918c9106d97a17809f6bcacfe02124763cb39"},{"signature":"tokenReserve()","signatureHash4":"0xcbcb3171","signatureHash32":"0xcbcb3171701b7015d7ac256aa17c63200ee73f2a2b4cb0a30a9c251644828d2b"},{"signature":"trackedQuote()","signatureHash4":"0xca52b0b7","signatureHash32":"0xca52b0b71acb4c1f6fc2e70e36177036567ca9ac1b6b4261d8d85ac09e332e90"},{"signature":"trackedTokens()","signatureHash4":"0x4c37ef23","signatureHash32":"0x4c37ef23e03b719e55d9e19689491d031ba19938d41c454d40fa9a829b80b5a5"}],"event":[{"signature":"BuybackEnabledUpdated(bool)","signatureHash4":"0xbfe799fb","signatureHash32":"0xbfe799fb5e0148a5f2590ff531306d42a5d512b74a5029ceb805abb808b0f1a0"},{"signature":"BuybackLocked(uint256,uint256)","signatureHash4":"0x5feba9b0","signatureHash32":"0x5feba9b0d52c92ada4b9c571c2bee52390c54f2947208ab250221e6ee32f12ff"},{"signature":"CreatorFeeRecipientUpdated(address,address)","signatureHash4":"0x2cc664e1","signatureHash32":"0x2cc664e1ac1e2d05c0d4637bb63ec8189113b6ac39276be8977e26216a8cdd19"},{"signature":"CurveBuy(address,address,uint256,uint256,uint256,uint256)","signatureHash4":"0xec36bf57","signatureHash32":"0xec36bf571f136799e8dc0b0b8bea4b04d8bd3d43de838aab0d5fc21d4cbfc455"},{"signature":"CurveSell(address,address,uint256,uint256,uint256,uint256)","signatureHash4":"0x8113d738","signatureHash32":"0x8113d738abdcb6b38357e9d53a54a7157861a09031b453651f0fe7fe151f59df"},{"signature":"FeesSwept(uint256,uint256,uint256)","signatureHash4":"0x9f4cd7c4","signatureHash32":"0x9f4cd7c4ed99d08a797804560c9c5d71d2cf7e101f2e3b5e7d1ca8a24c370e4f"},{"signature":"Initialized(address)","signatureHash4":"0x908408e3","signatureHash32":"0x908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6"},{"signature":"ReservesUpdated(uint256,uint256)","signatureHash4":"0x5141ecc8","signatureHash32":"0x5141ecc84a35c12ca2bf76bb33d393bd2fc22f906da0743534beef4ae63c6c8e"},{"signature":"SnipeTaxCharged(address,uint256)","signatureHash4":"0x3bc39a55","signatureHash32":"0x3bc39a5562b28f5fe8f36cecabfbaa12bb969acf05717994709225fc412a9934"},{"signature":"SnipeTaxExempted(address)","signatureHash4":"0xe4b7e48f","signatureHash32":"0xe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c7"}],"error":[{"signature":"AlreadyInitialized()","signatureHash4":"0x0dc149f0","signatureHash32":"0x0dc149f07762891dbcea3fe72770f3d63a1863fc54b2f084e8c59ec476996927"},{"signature":"DeadlineExpired()","signatureHash4":"0x1ab7da6b","signatureHash32":"0x1ab7da6b04cf80fcc6534c1f63ce7b24fd7488ab40444b4e5271ccc1c7f64567"},{"signature":"InsufficientInputAmount()","signatureHash4":"0x098fb561","signatureHash32":"0x098fb561b214e40e1e2f3f75a32a74ad8612ca9e387347a879ac04251bbf57f8"},{"signature":"InsufficientLiquidity()","signatureHash4":"0xbb55fd27","signatureHash32":"0xbb55fd27c46b5ba9f88ff2cb2222216afeb0f193423b26615497b3020ab61f8e"},{"signature":"InsufficientOutputAmount()","signatureHash4":"0x42301c23","signatureHash32":"0x42301c237a29c3e090da1b147e7b504f08db56c9600985b34af188477d350fa7"},{"signature":"InsufficientRealReserve(uint256,uint256)","signatureHash4":"0x10ca2eaa","signatureHash32":"0x10ca2eaa7c73a9f258f881b5c543520fac8c6b544822a9c01ecc36b95354d83a"},{"signature":"InternalSwapRequiresOperator()","signatureHash4":"0x31cdb504","signatureHash32":"0x31cdb504c95851aa711b060e0872389fad286bf4aea62958ef52bf8941cbf4fb"},{"signature":"InvalidFeePolicy()","signatureHash4":"0x7a34030f","signatureHash32":"0x7a34030f4c1cd9f3ca6fadc1cd985b53df7b970dadf50c4ed0d041df2ec753ca"},{"signature":"InvalidLaunchEconomics()","signatureHash4":"0xbc0ecfe3","signatureHash32":"0xbc0ecfe32231186b81da75da96195e4cce228f1a384b3641faa9da4a72ed0b7a"},{"signature":"MinimumOutputRequired()","signatureHash4":"0x3672d25f","signatureHash32":"0x3672d25fdb04f6c3c5436bac0eb5f7538e2b95c1fb51a90a1ab18e29400201d7"},{"signature":"NativeValueMismatch(uint256,uint256)","signatureHash4":"0xbc760cfe","signatureHash32":"0xbc760cfeb6534cbb0b47fcc24f83186f2cd5fe83250cdf7f98fa47d3bfa7737f"},{"signature":"NotFactory()","signatureHash4":"0x32cc7236","signatureHash32":"0x32cc723614e775fc4a8386492bc9a860c12fe98d5f5f28ec17e265818645b229"},{"signature":"NotFeeSweepOperator()","signatureHash4":"0x8d42130c","signatureHash32":"0x8d42130c5100579d9c35d2bffedb5820b0f709a76a9086ead65a090d8ad022ce"},{"signature":"NotInitialized()","signatureHash4":"0x87138d5c","signatureHash32":"0x87138d5c8c2e77cb9f25c07b03277aad63d22f6a05255580ec55d2c21666e734"},{"signature":"ReentrancyGuardReentrantCall()","signatureHash4":"0x3ee5aeb5","signatureHash32":"0x3ee5aeb571de7fc460830b4d0017439a1ca56fb0bc39062227ade4fe4a24c1ca"},{"signature":"ReserveLimit()","signatureHash4":"0xb026649f","signatureHash32":"0xb026649fc829d2d11e93b2e5f9728f1f4e1fc3345c62e95392adab9964cf1605"},{"signature":"SafeERC20FailedOperation(address)","signatureHash4":"0x5274afe7","signatureHash32":"0x5274afe73c98b4749fc91ffae6b7b574e7842cb2144a159e9377a5f20b32edf9"},{"signature":"SlippageExceeded(uint256,uint256)","signatureHash4":"0x71c4efed","signatureHash32":"0x71c4efeda0c103f56fd5ac9b173756384c66cbbbc480b0ad4255bc219a9b6a66"},{"signature":"TransferFailed()","signatureHash4":"0x90b8ec18","signatureHash32":"0x90b8ec1877afffd816d05d9b13947f3ff18ec5851c38bad15ec2b710f92391b1"},{"signature":"UnexpectedNativeValue()","signatureHash4":"0xe0aeda7d","signatureHash32":"0xe0aeda7d0ec327a28120070649cbc2849a565ba88207f9dd36142b7ab63be7bf"},{"signature":"ZeroAddress()","signatureHash4":"0xd92e233d","signatureHash32":"0xd92e233df2717d4a40030e20904abd27b68fcbeede117eaaccbbdac9618c8c73"},{"signature":"ZeroAmount()","signatureHash4":"0x1f2a2005","signatureHash32":"0x1f2a2005cb66a8e145327e8814e243a0996aec9bfe1e15a495778b1236dbd485"}]},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"match":"exact_match","chainId":"4663","address":"0xd461AF2bf555add5Be8cCcD7bA437179a900d330"}