mango-v4/rs/doc/src/mango_v4_client/client.rs.html

5427 lines
242 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `lib/client/src/client.rs`."><title>client.rs - source</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/FiraSans-Regular-018c141bf0843ffd.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/FiraSans-Medium-8f9a781e4970d388.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2"><link rel="stylesheet" href="../../static.files/normalize-76eba96aa4d2e634.css"><link rel="stylesheet" href="../../static.files/rustdoc-ba5701c5741a7b69.css" id="mainThemeStyle"><div id="rustdoc-vars" data-root-path="../../" data-static-root-path="../../static.files/" data-current-crate="mango_v4_client" data-themes="" data-resource-suffix="" data-rustdoc-version="1.70.0 (90c541806 2023-05-31)" data-search-js="search-e077946657036a58.js" data-settings-js="settings-298e1ea74db45b39.js" data-settings-css="settings-7bfb4c59cc6bc502.css" data-theme-light-css="light-0f8c037637f9eb3e.css" data-theme-dark-css="dark-1097f8e92a01e3cf.css" data-theme-ayu-css="ayu-614652228113ac93.css" ></div><script src="../../static.files/storage-62ce34ea385b278a.js"></script><script defer src="../../static.files/source-script-905937fbbdc8e9ea.js"></script><script defer src="../../source-files.js"></script><script defer src="../../static.files/main-f61008743c98d196.js"></script><noscript><link rel="stylesheet" media="(prefers-color-scheme:light)" href="../../static.files/light-0f8c037637f9eb3e.css"><link rel="stylesheet" media="(prefers-color-scheme:dark)" href="../../static.files/dark-1097f8e92a01e3cf.css"><link rel="stylesheet" href="../../static.files/noscript-13285aec31fa243e.css"></noscript><link rel="alternate icon" type="image/png" href="../../static.files/favicon-16x16-8b506e7a72182f1c.png"><link rel="alternate icon" type="image/png" href="../../static.files/favicon-32x32-422f7d1d52889060.png"><link rel="icon" type="image/svg+xml" href="../../static.files/favicon-2c020d218678b618.svg"></head><body class="rustdoc source"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"></nav><main><nav class="sub"><a class="sub-logo-container" href="../../mango_v4_client/index.html"><img class="rust-logo" src="../../static.files/rust-logo-151179464ae7ed46.svg" alt="logo"></a><form class="search-form"><span></span><input class="search-input" name="search" aria-label="Run search in the documentation" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../static.files/wheel-7b819b6101059cd0.svg"></a></div></form></nav><section id="main-content" class="content"><div class="example-wrap"><div data-nosnippet><pre class="src-line-numbers"><a href="#1" id="1">1</a>
<a href="#2" id="2">2</a>
<a href="#3" id="3">3</a>
<a href="#4" id="4">4</a>
<a href="#5" id="5">5</a>
<a href="#6" id="6">6</a>
<a href="#7" id="7">7</a>
<a href="#8" id="8">8</a>
<a href="#9" id="9">9</a>
<a href="#10" id="10">10</a>
<a href="#11" id="11">11</a>
<a href="#12" id="12">12</a>
<a href="#13" id="13">13</a>
<a href="#14" id="14">14</a>
<a href="#15" id="15">15</a>
<a href="#16" id="16">16</a>
<a href="#17" id="17">17</a>
<a href="#18" id="18">18</a>
<a href="#19" id="19">19</a>
<a href="#20" id="20">20</a>
<a href="#21" id="21">21</a>
<a href="#22" id="22">22</a>
<a href="#23" id="23">23</a>
<a href="#24" id="24">24</a>
<a href="#25" id="25">25</a>
<a href="#26" id="26">26</a>
<a href="#27" id="27">27</a>
<a href="#28" id="28">28</a>
<a href="#29" id="29">29</a>
<a href="#30" id="30">30</a>
<a href="#31" id="31">31</a>
<a href="#32" id="32">32</a>
<a href="#33" id="33">33</a>
<a href="#34" id="34">34</a>
<a href="#35" id="35">35</a>
<a href="#36" id="36">36</a>
<a href="#37" id="37">37</a>
<a href="#38" id="38">38</a>
<a href="#39" id="39">39</a>
<a href="#40" id="40">40</a>
<a href="#41" id="41">41</a>
<a href="#42" id="42">42</a>
<a href="#43" id="43">43</a>
<a href="#44" id="44">44</a>
<a href="#45" id="45">45</a>
<a href="#46" id="46">46</a>
<a href="#47" id="47">47</a>
<a href="#48" id="48">48</a>
<a href="#49" id="49">49</a>
<a href="#50" id="50">50</a>
<a href="#51" id="51">51</a>
<a href="#52" id="52">52</a>
<a href="#53" id="53">53</a>
<a href="#54" id="54">54</a>
<a href="#55" id="55">55</a>
<a href="#56" id="56">56</a>
<a href="#57" id="57">57</a>
<a href="#58" id="58">58</a>
<a href="#59" id="59">59</a>
<a href="#60" id="60">60</a>
<a href="#61" id="61">61</a>
<a href="#62" id="62">62</a>
<a href="#63" id="63">63</a>
<a href="#64" id="64">64</a>
<a href="#65" id="65">65</a>
<a href="#66" id="66">66</a>
<a href="#67" id="67">67</a>
<a href="#68" id="68">68</a>
<a href="#69" id="69">69</a>
<a href="#70" id="70">70</a>
<a href="#71" id="71">71</a>
<a href="#72" id="72">72</a>
<a href="#73" id="73">73</a>
<a href="#74" id="74">74</a>
<a href="#75" id="75">75</a>
<a href="#76" id="76">76</a>
<a href="#77" id="77">77</a>
<a href="#78" id="78">78</a>
<a href="#79" id="79">79</a>
<a href="#80" id="80">80</a>
<a href="#81" id="81">81</a>
<a href="#82" id="82">82</a>
<a href="#83" id="83">83</a>
<a href="#84" id="84">84</a>
<a href="#85" id="85">85</a>
<a href="#86" id="86">86</a>
<a href="#87" id="87">87</a>
<a href="#88" id="88">88</a>
<a href="#89" id="89">89</a>
<a href="#90" id="90">90</a>
<a href="#91" id="91">91</a>
<a href="#92" id="92">92</a>
<a href="#93" id="93">93</a>
<a href="#94" id="94">94</a>
<a href="#95" id="95">95</a>
<a href="#96" id="96">96</a>
<a href="#97" id="97">97</a>
<a href="#98" id="98">98</a>
<a href="#99" id="99">99</a>
<a href="#100" id="100">100</a>
<a href="#101" id="101">101</a>
<a href="#102" id="102">102</a>
<a href="#103" id="103">103</a>
<a href="#104" id="104">104</a>
<a href="#105" id="105">105</a>
<a href="#106" id="106">106</a>
<a href="#107" id="107">107</a>
<a href="#108" id="108">108</a>
<a href="#109" id="109">109</a>
<a href="#110" id="110">110</a>
<a href="#111" id="111">111</a>
<a href="#112" id="112">112</a>
<a href="#113" id="113">113</a>
<a href="#114" id="114">114</a>
<a href="#115" id="115">115</a>
<a href="#116" id="116">116</a>
<a href="#117" id="117">117</a>
<a href="#118" id="118">118</a>
<a href="#119" id="119">119</a>
<a href="#120" id="120">120</a>
<a href="#121" id="121">121</a>
<a href="#122" id="122">122</a>
<a href="#123" id="123">123</a>
<a href="#124" id="124">124</a>
<a href="#125" id="125">125</a>
<a href="#126" id="126">126</a>
<a href="#127" id="127">127</a>
<a href="#128" id="128">128</a>
<a href="#129" id="129">129</a>
<a href="#130" id="130">130</a>
<a href="#131" id="131">131</a>
<a href="#132" id="132">132</a>
<a href="#133" id="133">133</a>
<a href="#134" id="134">134</a>
<a href="#135" id="135">135</a>
<a href="#136" id="136">136</a>
<a href="#137" id="137">137</a>
<a href="#138" id="138">138</a>
<a href="#139" id="139">139</a>
<a href="#140" id="140">140</a>
<a href="#141" id="141">141</a>
<a href="#142" id="142">142</a>
<a href="#143" id="143">143</a>
<a href="#144" id="144">144</a>
<a href="#145" id="145">145</a>
<a href="#146" id="146">146</a>
<a href="#147" id="147">147</a>
<a href="#148" id="148">148</a>
<a href="#149" id="149">149</a>
<a href="#150" id="150">150</a>
<a href="#151" id="151">151</a>
<a href="#152" id="152">152</a>
<a href="#153" id="153">153</a>
<a href="#154" id="154">154</a>
<a href="#155" id="155">155</a>
<a href="#156" id="156">156</a>
<a href="#157" id="157">157</a>
<a href="#158" id="158">158</a>
<a href="#159" id="159">159</a>
<a href="#160" id="160">160</a>
<a href="#161" id="161">161</a>
<a href="#162" id="162">162</a>
<a href="#163" id="163">163</a>
<a href="#164" id="164">164</a>
<a href="#165" id="165">165</a>
<a href="#166" id="166">166</a>
<a href="#167" id="167">167</a>
<a href="#168" id="168">168</a>
<a href="#169" id="169">169</a>
<a href="#170" id="170">170</a>
<a href="#171" id="171">171</a>
<a href="#172" id="172">172</a>
<a href="#173" id="173">173</a>
<a href="#174" id="174">174</a>
<a href="#175" id="175">175</a>
<a href="#176" id="176">176</a>
<a href="#177" id="177">177</a>
<a href="#178" id="178">178</a>
<a href="#179" id="179">179</a>
<a href="#180" id="180">180</a>
<a href="#181" id="181">181</a>
<a href="#182" id="182">182</a>
<a href="#183" id="183">183</a>
<a href="#184" id="184">184</a>
<a href="#185" id="185">185</a>
<a href="#186" id="186">186</a>
<a href="#187" id="187">187</a>
<a href="#188" id="188">188</a>
<a href="#189" id="189">189</a>
<a href="#190" id="190">190</a>
<a href="#191" id="191">191</a>
<a href="#192" id="192">192</a>
<a href="#193" id="193">193</a>
<a href="#194" id="194">194</a>
<a href="#195" id="195">195</a>
<a href="#196" id="196">196</a>
<a href="#197" id="197">197</a>
<a href="#198" id="198">198</a>
<a href="#199" id="199">199</a>
<a href="#200" id="200">200</a>
<a href="#201" id="201">201</a>
<a href="#202" id="202">202</a>
<a href="#203" id="203">203</a>
<a href="#204" id="204">204</a>
<a href="#205" id="205">205</a>
<a href="#206" id="206">206</a>
<a href="#207" id="207">207</a>
<a href="#208" id="208">208</a>
<a href="#209" id="209">209</a>
<a href="#210" id="210">210</a>
<a href="#211" id="211">211</a>
<a href="#212" id="212">212</a>
<a href="#213" id="213">213</a>
<a href="#214" id="214">214</a>
<a href="#215" id="215">215</a>
<a href="#216" id="216">216</a>
<a href="#217" id="217">217</a>
<a href="#218" id="218">218</a>
<a href="#219" id="219">219</a>
<a href="#220" id="220">220</a>
<a href="#221" id="221">221</a>
<a href="#222" id="222">222</a>
<a href="#223" id="223">223</a>
<a href="#224" id="224">224</a>
<a href="#225" id="225">225</a>
<a href="#226" id="226">226</a>
<a href="#227" id="227">227</a>
<a href="#228" id="228">228</a>
<a href="#229" id="229">229</a>
<a href="#230" id="230">230</a>
<a href="#231" id="231">231</a>
<a href="#232" id="232">232</a>
<a href="#233" id="233">233</a>
<a href="#234" id="234">234</a>
<a href="#235" id="235">235</a>
<a href="#236" id="236">236</a>
<a href="#237" id="237">237</a>
<a href="#238" id="238">238</a>
<a href="#239" id="239">239</a>
<a href="#240" id="240">240</a>
<a href="#241" id="241">241</a>
<a href="#242" id="242">242</a>
<a href="#243" id="243">243</a>
<a href="#244" id="244">244</a>
<a href="#245" id="245">245</a>
<a href="#246" id="246">246</a>
<a href="#247" id="247">247</a>
<a href="#248" id="248">248</a>
<a href="#249" id="249">249</a>
<a href="#250" id="250">250</a>
<a href="#251" id="251">251</a>
<a href="#252" id="252">252</a>
<a href="#253" id="253">253</a>
<a href="#254" id="254">254</a>
<a href="#255" id="255">255</a>
<a href="#256" id="256">256</a>
<a href="#257" id="257">257</a>
<a href="#258" id="258">258</a>
<a href="#259" id="259">259</a>
<a href="#260" id="260">260</a>
<a href="#261" id="261">261</a>
<a href="#262" id="262">262</a>
<a href="#263" id="263">263</a>
<a href="#264" id="264">264</a>
<a href="#265" id="265">265</a>
<a href="#266" id="266">266</a>
<a href="#267" id="267">267</a>
<a href="#268" id="268">268</a>
<a href="#269" id="269">269</a>
<a href="#270" id="270">270</a>
<a href="#271" id="271">271</a>
<a href="#272" id="272">272</a>
<a href="#273" id="273">273</a>
<a href="#274" id="274">274</a>
<a href="#275" id="275">275</a>
<a href="#276" id="276">276</a>
<a href="#277" id="277">277</a>
<a href="#278" id="278">278</a>
<a href="#279" id="279">279</a>
<a href="#280" id="280">280</a>
<a href="#281" id="281">281</a>
<a href="#282" id="282">282</a>
<a href="#283" id="283">283</a>
<a href="#284" id="284">284</a>
<a href="#285" id="285">285</a>
<a href="#286" id="286">286</a>
<a href="#287" id="287">287</a>
<a href="#288" id="288">288</a>
<a href="#289" id="289">289</a>
<a href="#290" id="290">290</a>
<a href="#291" id="291">291</a>
<a href="#292" id="292">292</a>
<a href="#293" id="293">293</a>
<a href="#294" id="294">294</a>
<a href="#295" id="295">295</a>
<a href="#296" id="296">296</a>
<a href="#297" id="297">297</a>
<a href="#298" id="298">298</a>
<a href="#299" id="299">299</a>
<a href="#300" id="300">300</a>
<a href="#301" id="301">301</a>
<a href="#302" id="302">302</a>
<a href="#303" id="303">303</a>
<a href="#304" id="304">304</a>
<a href="#305" id="305">305</a>
<a href="#306" id="306">306</a>
<a href="#307" id="307">307</a>
<a href="#308" id="308">308</a>
<a href="#309" id="309">309</a>
<a href="#310" id="310">310</a>
<a href="#311" id="311">311</a>
<a href="#312" id="312">312</a>
<a href="#313" id="313">313</a>
<a href="#314" id="314">314</a>
<a href="#315" id="315">315</a>
<a href="#316" id="316">316</a>
<a href="#317" id="317">317</a>
<a href="#318" id="318">318</a>
<a href="#319" id="319">319</a>
<a href="#320" id="320">320</a>
<a href="#321" id="321">321</a>
<a href="#322" id="322">322</a>
<a href="#323" id="323">323</a>
<a href="#324" id="324">324</a>
<a href="#325" id="325">325</a>
<a href="#326" id="326">326</a>
<a href="#327" id="327">327</a>
<a href="#328" id="328">328</a>
<a href="#329" id="329">329</a>
<a href="#330" id="330">330</a>
<a href="#331" id="331">331</a>
<a href="#332" id="332">332</a>
<a href="#333" id="333">333</a>
<a href="#334" id="334">334</a>
<a href="#335" id="335">335</a>
<a href="#336" id="336">336</a>
<a href="#337" id="337">337</a>
<a href="#338" id="338">338</a>
<a href="#339" id="339">339</a>
<a href="#340" id="340">340</a>
<a href="#341" id="341">341</a>
<a href="#342" id="342">342</a>
<a href="#343" id="343">343</a>
<a href="#344" id="344">344</a>
<a href="#345" id="345">345</a>
<a href="#346" id="346">346</a>
<a href="#347" id="347">347</a>
<a href="#348" id="348">348</a>
<a href="#349" id="349">349</a>
<a href="#350" id="350">350</a>
<a href="#351" id="351">351</a>
<a href="#352" id="352">352</a>
<a href="#353" id="353">353</a>
<a href="#354" id="354">354</a>
<a href="#355" id="355">355</a>
<a href="#356" id="356">356</a>
<a href="#357" id="357">357</a>
<a href="#358" id="358">358</a>
<a href="#359" id="359">359</a>
<a href="#360" id="360">360</a>
<a href="#361" id="361">361</a>
<a href="#362" id="362">362</a>
<a href="#363" id="363">363</a>
<a href="#364" id="364">364</a>
<a href="#365" id="365">365</a>
<a href="#366" id="366">366</a>
<a href="#367" id="367">367</a>
<a href="#368" id="368">368</a>
<a href="#369" id="369">369</a>
<a href="#370" id="370">370</a>
<a href="#371" id="371">371</a>
<a href="#372" id="372">372</a>
<a href="#373" id="373">373</a>
<a href="#374" id="374">374</a>
<a href="#375" id="375">375</a>
<a href="#376" id="376">376</a>
<a href="#377" id="377">377</a>
<a href="#378" id="378">378</a>
<a href="#379" id="379">379</a>
<a href="#380" id="380">380</a>
<a href="#381" id="381">381</a>
<a href="#382" id="382">382</a>
<a href="#383" id="383">383</a>
<a href="#384" id="384">384</a>
<a href="#385" id="385">385</a>
<a href="#386" id="386">386</a>
<a href="#387" id="387">387</a>
<a href="#388" id="388">388</a>
<a href="#389" id="389">389</a>
<a href="#390" id="390">390</a>
<a href="#391" id="391">391</a>
<a href="#392" id="392">392</a>
<a href="#393" id="393">393</a>
<a href="#394" id="394">394</a>
<a href="#395" id="395">395</a>
<a href="#396" id="396">396</a>
<a href="#397" id="397">397</a>
<a href="#398" id="398">398</a>
<a href="#399" id="399">399</a>
<a href="#400" id="400">400</a>
<a href="#401" id="401">401</a>
<a href="#402" id="402">402</a>
<a href="#403" id="403">403</a>
<a href="#404" id="404">404</a>
<a href="#405" id="405">405</a>
<a href="#406" id="406">406</a>
<a href="#407" id="407">407</a>
<a href="#408" id="408">408</a>
<a href="#409" id="409">409</a>
<a href="#410" id="410">410</a>
<a href="#411" id="411">411</a>
<a href="#412" id="412">412</a>
<a href="#413" id="413">413</a>
<a href="#414" id="414">414</a>
<a href="#415" id="415">415</a>
<a href="#416" id="416">416</a>
<a href="#417" id="417">417</a>
<a href="#418" id="418">418</a>
<a href="#419" id="419">419</a>
<a href="#420" id="420">420</a>
<a href="#421" id="421">421</a>
<a href="#422" id="422">422</a>
<a href="#423" id="423">423</a>
<a href="#424" id="424">424</a>
<a href="#425" id="425">425</a>
<a href="#426" id="426">426</a>
<a href="#427" id="427">427</a>
<a href="#428" id="428">428</a>
<a href="#429" id="429">429</a>
<a href="#430" id="430">430</a>
<a href="#431" id="431">431</a>
<a href="#432" id="432">432</a>
<a href="#433" id="433">433</a>
<a href="#434" id="434">434</a>
<a href="#435" id="435">435</a>
<a href="#436" id="436">436</a>
<a href="#437" id="437">437</a>
<a href="#438" id="438">438</a>
<a href="#439" id="439">439</a>
<a href="#440" id="440">440</a>
<a href="#441" id="441">441</a>
<a href="#442" id="442">442</a>
<a href="#443" id="443">443</a>
<a href="#444" id="444">444</a>
<a href="#445" id="445">445</a>
<a href="#446" id="446">446</a>
<a href="#447" id="447">447</a>
<a href="#448" id="448">448</a>
<a href="#449" id="449">449</a>
<a href="#450" id="450">450</a>
<a href="#451" id="451">451</a>
<a href="#452" id="452">452</a>
<a href="#453" id="453">453</a>
<a href="#454" id="454">454</a>
<a href="#455" id="455">455</a>
<a href="#456" id="456">456</a>
<a href="#457" id="457">457</a>
<a href="#458" id="458">458</a>
<a href="#459" id="459">459</a>
<a href="#460" id="460">460</a>
<a href="#461" id="461">461</a>
<a href="#462" id="462">462</a>
<a href="#463" id="463">463</a>
<a href="#464" id="464">464</a>
<a href="#465" id="465">465</a>
<a href="#466" id="466">466</a>
<a href="#467" id="467">467</a>
<a href="#468" id="468">468</a>
<a href="#469" id="469">469</a>
<a href="#470" id="470">470</a>
<a href="#471" id="471">471</a>
<a href="#472" id="472">472</a>
<a href="#473" id="473">473</a>
<a href="#474" id="474">474</a>
<a href="#475" id="475">475</a>
<a href="#476" id="476">476</a>
<a href="#477" id="477">477</a>
<a href="#478" id="478">478</a>
<a href="#479" id="479">479</a>
<a href="#480" id="480">480</a>
<a href="#481" id="481">481</a>
<a href="#482" id="482">482</a>
<a href="#483" id="483">483</a>
<a href="#484" id="484">484</a>
<a href="#485" id="485">485</a>
<a href="#486" id="486">486</a>
<a href="#487" id="487">487</a>
<a href="#488" id="488">488</a>
<a href="#489" id="489">489</a>
<a href="#490" id="490">490</a>
<a href="#491" id="491">491</a>
<a href="#492" id="492">492</a>
<a href="#493" id="493">493</a>
<a href="#494" id="494">494</a>
<a href="#495" id="495">495</a>
<a href="#496" id="496">496</a>
<a href="#497" id="497">497</a>
<a href="#498" id="498">498</a>
<a href="#499" id="499">499</a>
<a href="#500" id="500">500</a>
<a href="#501" id="501">501</a>
<a href="#502" id="502">502</a>
<a href="#503" id="503">503</a>
<a href="#504" id="504">504</a>
<a href="#505" id="505">505</a>
<a href="#506" id="506">506</a>
<a href="#507" id="507">507</a>
<a href="#508" id="508">508</a>
<a href="#509" id="509">509</a>
<a href="#510" id="510">510</a>
<a href="#511" id="511">511</a>
<a href="#512" id="512">512</a>
<a href="#513" id="513">513</a>
<a href="#514" id="514">514</a>
<a href="#515" id="515">515</a>
<a href="#516" id="516">516</a>
<a href="#517" id="517">517</a>
<a href="#518" id="518">518</a>
<a href="#519" id="519">519</a>
<a href="#520" id="520">520</a>
<a href="#521" id="521">521</a>
<a href="#522" id="522">522</a>
<a href="#523" id="523">523</a>
<a href="#524" id="524">524</a>
<a href="#525" id="525">525</a>
<a href="#526" id="526">526</a>
<a href="#527" id="527">527</a>
<a href="#528" id="528">528</a>
<a href="#529" id="529">529</a>
<a href="#530" id="530">530</a>
<a href="#531" id="531">531</a>
<a href="#532" id="532">532</a>
<a href="#533" id="533">533</a>
<a href="#534" id="534">534</a>
<a href="#535" id="535">535</a>
<a href="#536" id="536">536</a>
<a href="#537" id="537">537</a>
<a href="#538" id="538">538</a>
<a href="#539" id="539">539</a>
<a href="#540" id="540">540</a>
<a href="#541" id="541">541</a>
<a href="#542" id="542">542</a>
<a href="#543" id="543">543</a>
<a href="#544" id="544">544</a>
<a href="#545" id="545">545</a>
<a href="#546" id="546">546</a>
<a href="#547" id="547">547</a>
<a href="#548" id="548">548</a>
<a href="#549" id="549">549</a>
<a href="#550" id="550">550</a>
<a href="#551" id="551">551</a>
<a href="#552" id="552">552</a>
<a href="#553" id="553">553</a>
<a href="#554" id="554">554</a>
<a href="#555" id="555">555</a>
<a href="#556" id="556">556</a>
<a href="#557" id="557">557</a>
<a href="#558" id="558">558</a>
<a href="#559" id="559">559</a>
<a href="#560" id="560">560</a>
<a href="#561" id="561">561</a>
<a href="#562" id="562">562</a>
<a href="#563" id="563">563</a>
<a href="#564" id="564">564</a>
<a href="#565" id="565">565</a>
<a href="#566" id="566">566</a>
<a href="#567" id="567">567</a>
<a href="#568" id="568">568</a>
<a href="#569" id="569">569</a>
<a href="#570" id="570">570</a>
<a href="#571" id="571">571</a>
<a href="#572" id="572">572</a>
<a href="#573" id="573">573</a>
<a href="#574" id="574">574</a>
<a href="#575" id="575">575</a>
<a href="#576" id="576">576</a>
<a href="#577" id="577">577</a>
<a href="#578" id="578">578</a>
<a href="#579" id="579">579</a>
<a href="#580" id="580">580</a>
<a href="#581" id="581">581</a>
<a href="#582" id="582">582</a>
<a href="#583" id="583">583</a>
<a href="#584" id="584">584</a>
<a href="#585" id="585">585</a>
<a href="#586" id="586">586</a>
<a href="#587" id="587">587</a>
<a href="#588" id="588">588</a>
<a href="#589" id="589">589</a>
<a href="#590" id="590">590</a>
<a href="#591" id="591">591</a>
<a href="#592" id="592">592</a>
<a href="#593" id="593">593</a>
<a href="#594" id="594">594</a>
<a href="#595" id="595">595</a>
<a href="#596" id="596">596</a>
<a href="#597" id="597">597</a>
<a href="#598" id="598">598</a>
<a href="#599" id="599">599</a>
<a href="#600" id="600">600</a>
<a href="#601" id="601">601</a>
<a href="#602" id="602">602</a>
<a href="#603" id="603">603</a>
<a href="#604" id="604">604</a>
<a href="#605" id="605">605</a>
<a href="#606" id="606">606</a>
<a href="#607" id="607">607</a>
<a href="#608" id="608">608</a>
<a href="#609" id="609">609</a>
<a href="#610" id="610">610</a>
<a href="#611" id="611">611</a>
<a href="#612" id="612">612</a>
<a href="#613" id="613">613</a>
<a href="#614" id="614">614</a>
<a href="#615" id="615">615</a>
<a href="#616" id="616">616</a>
<a href="#617" id="617">617</a>
<a href="#618" id="618">618</a>
<a href="#619" id="619">619</a>
<a href="#620" id="620">620</a>
<a href="#621" id="621">621</a>
<a href="#622" id="622">622</a>
<a href="#623" id="623">623</a>
<a href="#624" id="624">624</a>
<a href="#625" id="625">625</a>
<a href="#626" id="626">626</a>
<a href="#627" id="627">627</a>
<a href="#628" id="628">628</a>
<a href="#629" id="629">629</a>
<a href="#630" id="630">630</a>
<a href="#631" id="631">631</a>
<a href="#632" id="632">632</a>
<a href="#633" id="633">633</a>
<a href="#634" id="634">634</a>
<a href="#635" id="635">635</a>
<a href="#636" id="636">636</a>
<a href="#637" id="637">637</a>
<a href="#638" id="638">638</a>
<a href="#639" id="639">639</a>
<a href="#640" id="640">640</a>
<a href="#641" id="641">641</a>
<a href="#642" id="642">642</a>
<a href="#643" id="643">643</a>
<a href="#644" id="644">644</a>
<a href="#645" id="645">645</a>
<a href="#646" id="646">646</a>
<a href="#647" id="647">647</a>
<a href="#648" id="648">648</a>
<a href="#649" id="649">649</a>
<a href="#650" id="650">650</a>
<a href="#651" id="651">651</a>
<a href="#652" id="652">652</a>
<a href="#653" id="653">653</a>
<a href="#654" id="654">654</a>
<a href="#655" id="655">655</a>
<a href="#656" id="656">656</a>
<a href="#657" id="657">657</a>
<a href="#658" id="658">658</a>
<a href="#659" id="659">659</a>
<a href="#660" id="660">660</a>
<a href="#661" id="661">661</a>
<a href="#662" id="662">662</a>
<a href="#663" id="663">663</a>
<a href="#664" id="664">664</a>
<a href="#665" id="665">665</a>
<a href="#666" id="666">666</a>
<a href="#667" id="667">667</a>
<a href="#668" id="668">668</a>
<a href="#669" id="669">669</a>
<a href="#670" id="670">670</a>
<a href="#671" id="671">671</a>
<a href="#672" id="672">672</a>
<a href="#673" id="673">673</a>
<a href="#674" id="674">674</a>
<a href="#675" id="675">675</a>
<a href="#676" id="676">676</a>
<a href="#677" id="677">677</a>
<a href="#678" id="678">678</a>
<a href="#679" id="679">679</a>
<a href="#680" id="680">680</a>
<a href="#681" id="681">681</a>
<a href="#682" id="682">682</a>
<a href="#683" id="683">683</a>
<a href="#684" id="684">684</a>
<a href="#685" id="685">685</a>
<a href="#686" id="686">686</a>
<a href="#687" id="687">687</a>
<a href="#688" id="688">688</a>
<a href="#689" id="689">689</a>
<a href="#690" id="690">690</a>
<a href="#691" id="691">691</a>
<a href="#692" id="692">692</a>
<a href="#693" id="693">693</a>
<a href="#694" id="694">694</a>
<a href="#695" id="695">695</a>
<a href="#696" id="696">696</a>
<a href="#697" id="697">697</a>
<a href="#698" id="698">698</a>
<a href="#699" id="699">699</a>
<a href="#700" id="700">700</a>
<a href="#701" id="701">701</a>
<a href="#702" id="702">702</a>
<a href="#703" id="703">703</a>
<a href="#704" id="704">704</a>
<a href="#705" id="705">705</a>
<a href="#706" id="706">706</a>
<a href="#707" id="707">707</a>
<a href="#708" id="708">708</a>
<a href="#709" id="709">709</a>
<a href="#710" id="710">710</a>
<a href="#711" id="711">711</a>
<a href="#712" id="712">712</a>
<a href="#713" id="713">713</a>
<a href="#714" id="714">714</a>
<a href="#715" id="715">715</a>
<a href="#716" id="716">716</a>
<a href="#717" id="717">717</a>
<a href="#718" id="718">718</a>
<a href="#719" id="719">719</a>
<a href="#720" id="720">720</a>
<a href="#721" id="721">721</a>
<a href="#722" id="722">722</a>
<a href="#723" id="723">723</a>
<a href="#724" id="724">724</a>
<a href="#725" id="725">725</a>
<a href="#726" id="726">726</a>
<a href="#727" id="727">727</a>
<a href="#728" id="728">728</a>
<a href="#729" id="729">729</a>
<a href="#730" id="730">730</a>
<a href="#731" id="731">731</a>
<a href="#732" id="732">732</a>
<a href="#733" id="733">733</a>
<a href="#734" id="734">734</a>
<a href="#735" id="735">735</a>
<a href="#736" id="736">736</a>
<a href="#737" id="737">737</a>
<a href="#738" id="738">738</a>
<a href="#739" id="739">739</a>
<a href="#740" id="740">740</a>
<a href="#741" id="741">741</a>
<a href="#742" id="742">742</a>
<a href="#743" id="743">743</a>
<a href="#744" id="744">744</a>
<a href="#745" id="745">745</a>
<a href="#746" id="746">746</a>
<a href="#747" id="747">747</a>
<a href="#748" id="748">748</a>
<a href="#749" id="749">749</a>
<a href="#750" id="750">750</a>
<a href="#751" id="751">751</a>
<a href="#752" id="752">752</a>
<a href="#753" id="753">753</a>
<a href="#754" id="754">754</a>
<a href="#755" id="755">755</a>
<a href="#756" id="756">756</a>
<a href="#757" id="757">757</a>
<a href="#758" id="758">758</a>
<a href="#759" id="759">759</a>
<a href="#760" id="760">760</a>
<a href="#761" id="761">761</a>
<a href="#762" id="762">762</a>
<a href="#763" id="763">763</a>
<a href="#764" id="764">764</a>
<a href="#765" id="765">765</a>
<a href="#766" id="766">766</a>
<a href="#767" id="767">767</a>
<a href="#768" id="768">768</a>
<a href="#769" id="769">769</a>
<a href="#770" id="770">770</a>
<a href="#771" id="771">771</a>
<a href="#772" id="772">772</a>
<a href="#773" id="773">773</a>
<a href="#774" id="774">774</a>
<a href="#775" id="775">775</a>
<a href="#776" id="776">776</a>
<a href="#777" id="777">777</a>
<a href="#778" id="778">778</a>
<a href="#779" id="779">779</a>
<a href="#780" id="780">780</a>
<a href="#781" id="781">781</a>
<a href="#782" id="782">782</a>
<a href="#783" id="783">783</a>
<a href="#784" id="784">784</a>
<a href="#785" id="785">785</a>
<a href="#786" id="786">786</a>
<a href="#787" id="787">787</a>
<a href="#788" id="788">788</a>
<a href="#789" id="789">789</a>
<a href="#790" id="790">790</a>
<a href="#791" id="791">791</a>
<a href="#792" id="792">792</a>
<a href="#793" id="793">793</a>
<a href="#794" id="794">794</a>
<a href="#795" id="795">795</a>
<a href="#796" id="796">796</a>
<a href="#797" id="797">797</a>
<a href="#798" id="798">798</a>
<a href="#799" id="799">799</a>
<a href="#800" id="800">800</a>
<a href="#801" id="801">801</a>
<a href="#802" id="802">802</a>
<a href="#803" id="803">803</a>
<a href="#804" id="804">804</a>
<a href="#805" id="805">805</a>
<a href="#806" id="806">806</a>
<a href="#807" id="807">807</a>
<a href="#808" id="808">808</a>
<a href="#809" id="809">809</a>
<a href="#810" id="810">810</a>
<a href="#811" id="811">811</a>
<a href="#812" id="812">812</a>
<a href="#813" id="813">813</a>
<a href="#814" id="814">814</a>
<a href="#815" id="815">815</a>
<a href="#816" id="816">816</a>
<a href="#817" id="817">817</a>
<a href="#818" id="818">818</a>
<a href="#819" id="819">819</a>
<a href="#820" id="820">820</a>
<a href="#821" id="821">821</a>
<a href="#822" id="822">822</a>
<a href="#823" id="823">823</a>
<a href="#824" id="824">824</a>
<a href="#825" id="825">825</a>
<a href="#826" id="826">826</a>
<a href="#827" id="827">827</a>
<a href="#828" id="828">828</a>
<a href="#829" id="829">829</a>
<a href="#830" id="830">830</a>
<a href="#831" id="831">831</a>
<a href="#832" id="832">832</a>
<a href="#833" id="833">833</a>
<a href="#834" id="834">834</a>
<a href="#835" id="835">835</a>
<a href="#836" id="836">836</a>
<a href="#837" id="837">837</a>
<a href="#838" id="838">838</a>
<a href="#839" id="839">839</a>
<a href="#840" id="840">840</a>
<a href="#841" id="841">841</a>
<a href="#842" id="842">842</a>
<a href="#843" id="843">843</a>
<a href="#844" id="844">844</a>
<a href="#845" id="845">845</a>
<a href="#846" id="846">846</a>
<a href="#847" id="847">847</a>
<a href="#848" id="848">848</a>
<a href="#849" id="849">849</a>
<a href="#850" id="850">850</a>
<a href="#851" id="851">851</a>
<a href="#852" id="852">852</a>
<a href="#853" id="853">853</a>
<a href="#854" id="854">854</a>
<a href="#855" id="855">855</a>
<a href="#856" id="856">856</a>
<a href="#857" id="857">857</a>
<a href="#858" id="858">858</a>
<a href="#859" id="859">859</a>
<a href="#860" id="860">860</a>
<a href="#861" id="861">861</a>
<a href="#862" id="862">862</a>
<a href="#863" id="863">863</a>
<a href="#864" id="864">864</a>
<a href="#865" id="865">865</a>
<a href="#866" id="866">866</a>
<a href="#867" id="867">867</a>
<a href="#868" id="868">868</a>
<a href="#869" id="869">869</a>
<a href="#870" id="870">870</a>
<a href="#871" id="871">871</a>
<a href="#872" id="872">872</a>
<a href="#873" id="873">873</a>
<a href="#874" id="874">874</a>
<a href="#875" id="875">875</a>
<a href="#876" id="876">876</a>
<a href="#877" id="877">877</a>
<a href="#878" id="878">878</a>
<a href="#879" id="879">879</a>
<a href="#880" id="880">880</a>
<a href="#881" id="881">881</a>
<a href="#882" id="882">882</a>
<a href="#883" id="883">883</a>
<a href="#884" id="884">884</a>
<a href="#885" id="885">885</a>
<a href="#886" id="886">886</a>
<a href="#887" id="887">887</a>
<a href="#888" id="888">888</a>
<a href="#889" id="889">889</a>
<a href="#890" id="890">890</a>
<a href="#891" id="891">891</a>
<a href="#892" id="892">892</a>
<a href="#893" id="893">893</a>
<a href="#894" id="894">894</a>
<a href="#895" id="895">895</a>
<a href="#896" id="896">896</a>
<a href="#897" id="897">897</a>
<a href="#898" id="898">898</a>
<a href="#899" id="899">899</a>
<a href="#900" id="900">900</a>
<a href="#901" id="901">901</a>
<a href="#902" id="902">902</a>
<a href="#903" id="903">903</a>
<a href="#904" id="904">904</a>
<a href="#905" id="905">905</a>
<a href="#906" id="906">906</a>
<a href="#907" id="907">907</a>
<a href="#908" id="908">908</a>
<a href="#909" id="909">909</a>
<a href="#910" id="910">910</a>
<a href="#911" id="911">911</a>
<a href="#912" id="912">912</a>
<a href="#913" id="913">913</a>
<a href="#914" id="914">914</a>
<a href="#915" id="915">915</a>
<a href="#916" id="916">916</a>
<a href="#917" id="917">917</a>
<a href="#918" id="918">918</a>
<a href="#919" id="919">919</a>
<a href="#920" id="920">920</a>
<a href="#921" id="921">921</a>
<a href="#922" id="922">922</a>
<a href="#923" id="923">923</a>
<a href="#924" id="924">924</a>
<a href="#925" id="925">925</a>
<a href="#926" id="926">926</a>
<a href="#927" id="927">927</a>
<a href="#928" id="928">928</a>
<a href="#929" id="929">929</a>
<a href="#930" id="930">930</a>
<a href="#931" id="931">931</a>
<a href="#932" id="932">932</a>
<a href="#933" id="933">933</a>
<a href="#934" id="934">934</a>
<a href="#935" id="935">935</a>
<a href="#936" id="936">936</a>
<a href="#937" id="937">937</a>
<a href="#938" id="938">938</a>
<a href="#939" id="939">939</a>
<a href="#940" id="940">940</a>
<a href="#941" id="941">941</a>
<a href="#942" id="942">942</a>
<a href="#943" id="943">943</a>
<a href="#944" id="944">944</a>
<a href="#945" id="945">945</a>
<a href="#946" id="946">946</a>
<a href="#947" id="947">947</a>
<a href="#948" id="948">948</a>
<a href="#949" id="949">949</a>
<a href="#950" id="950">950</a>
<a href="#951" id="951">951</a>
<a href="#952" id="952">952</a>
<a href="#953" id="953">953</a>
<a href="#954" id="954">954</a>
<a href="#955" id="955">955</a>
<a href="#956" id="956">956</a>
<a href="#957" id="957">957</a>
<a href="#958" id="958">958</a>
<a href="#959" id="959">959</a>
<a href="#960" id="960">960</a>
<a href="#961" id="961">961</a>
<a href="#962" id="962">962</a>
<a href="#963" id="963">963</a>
<a href="#964" id="964">964</a>
<a href="#965" id="965">965</a>
<a href="#966" id="966">966</a>
<a href="#967" id="967">967</a>
<a href="#968" id="968">968</a>
<a href="#969" id="969">969</a>
<a href="#970" id="970">970</a>
<a href="#971" id="971">971</a>
<a href="#972" id="972">972</a>
<a href="#973" id="973">973</a>
<a href="#974" id="974">974</a>
<a href="#975" id="975">975</a>
<a href="#976" id="976">976</a>
<a href="#977" id="977">977</a>
<a href="#978" id="978">978</a>
<a href="#979" id="979">979</a>
<a href="#980" id="980">980</a>
<a href="#981" id="981">981</a>
<a href="#982" id="982">982</a>
<a href="#983" id="983">983</a>
<a href="#984" id="984">984</a>
<a href="#985" id="985">985</a>
<a href="#986" id="986">986</a>
<a href="#987" id="987">987</a>
<a href="#988" id="988">988</a>
<a href="#989" id="989">989</a>
<a href="#990" id="990">990</a>
<a href="#991" id="991">991</a>
<a href="#992" id="992">992</a>
<a href="#993" id="993">993</a>
<a href="#994" id="994">994</a>
<a href="#995" id="995">995</a>
<a href="#996" id="996">996</a>
<a href="#997" id="997">997</a>
<a href="#998" id="998">998</a>
<a href="#999" id="999">999</a>
<a href="#1000" id="1000">1000</a>
<a href="#1001" id="1001">1001</a>
<a href="#1002" id="1002">1002</a>
<a href="#1003" id="1003">1003</a>
<a href="#1004" id="1004">1004</a>
<a href="#1005" id="1005">1005</a>
<a href="#1006" id="1006">1006</a>
<a href="#1007" id="1007">1007</a>
<a href="#1008" id="1008">1008</a>
<a href="#1009" id="1009">1009</a>
<a href="#1010" id="1010">1010</a>
<a href="#1011" id="1011">1011</a>
<a href="#1012" id="1012">1012</a>
<a href="#1013" id="1013">1013</a>
<a href="#1014" id="1014">1014</a>
<a href="#1015" id="1015">1015</a>
<a href="#1016" id="1016">1016</a>
<a href="#1017" id="1017">1017</a>
<a href="#1018" id="1018">1018</a>
<a href="#1019" id="1019">1019</a>
<a href="#1020" id="1020">1020</a>
<a href="#1021" id="1021">1021</a>
<a href="#1022" id="1022">1022</a>
<a href="#1023" id="1023">1023</a>
<a href="#1024" id="1024">1024</a>
<a href="#1025" id="1025">1025</a>
<a href="#1026" id="1026">1026</a>
<a href="#1027" id="1027">1027</a>
<a href="#1028" id="1028">1028</a>
<a href="#1029" id="1029">1029</a>
<a href="#1030" id="1030">1030</a>
<a href="#1031" id="1031">1031</a>
<a href="#1032" id="1032">1032</a>
<a href="#1033" id="1033">1033</a>
<a href="#1034" id="1034">1034</a>
<a href="#1035" id="1035">1035</a>
<a href="#1036" id="1036">1036</a>
<a href="#1037" id="1037">1037</a>
<a href="#1038" id="1038">1038</a>
<a href="#1039" id="1039">1039</a>
<a href="#1040" id="1040">1040</a>
<a href="#1041" id="1041">1041</a>
<a href="#1042" id="1042">1042</a>
<a href="#1043" id="1043">1043</a>
<a href="#1044" id="1044">1044</a>
<a href="#1045" id="1045">1045</a>
<a href="#1046" id="1046">1046</a>
<a href="#1047" id="1047">1047</a>
<a href="#1048" id="1048">1048</a>
<a href="#1049" id="1049">1049</a>
<a href="#1050" id="1050">1050</a>
<a href="#1051" id="1051">1051</a>
<a href="#1052" id="1052">1052</a>
<a href="#1053" id="1053">1053</a>
<a href="#1054" id="1054">1054</a>
<a href="#1055" id="1055">1055</a>
<a href="#1056" id="1056">1056</a>
<a href="#1057" id="1057">1057</a>
<a href="#1058" id="1058">1058</a>
<a href="#1059" id="1059">1059</a>
<a href="#1060" id="1060">1060</a>
<a href="#1061" id="1061">1061</a>
<a href="#1062" id="1062">1062</a>
<a href="#1063" id="1063">1063</a>
<a href="#1064" id="1064">1064</a>
<a href="#1065" id="1065">1065</a>
<a href="#1066" id="1066">1066</a>
<a href="#1067" id="1067">1067</a>
<a href="#1068" id="1068">1068</a>
<a href="#1069" id="1069">1069</a>
<a href="#1070" id="1070">1070</a>
<a href="#1071" id="1071">1071</a>
<a href="#1072" id="1072">1072</a>
<a href="#1073" id="1073">1073</a>
<a href="#1074" id="1074">1074</a>
<a href="#1075" id="1075">1075</a>
<a href="#1076" id="1076">1076</a>
<a href="#1077" id="1077">1077</a>
<a href="#1078" id="1078">1078</a>
<a href="#1079" id="1079">1079</a>
<a href="#1080" id="1080">1080</a>
<a href="#1081" id="1081">1081</a>
<a href="#1082" id="1082">1082</a>
<a href="#1083" id="1083">1083</a>
<a href="#1084" id="1084">1084</a>
<a href="#1085" id="1085">1085</a>
<a href="#1086" id="1086">1086</a>
<a href="#1087" id="1087">1087</a>
<a href="#1088" id="1088">1088</a>
<a href="#1089" id="1089">1089</a>
<a href="#1090" id="1090">1090</a>
<a href="#1091" id="1091">1091</a>
<a href="#1092" id="1092">1092</a>
<a href="#1093" id="1093">1093</a>
<a href="#1094" id="1094">1094</a>
<a href="#1095" id="1095">1095</a>
<a href="#1096" id="1096">1096</a>
<a href="#1097" id="1097">1097</a>
<a href="#1098" id="1098">1098</a>
<a href="#1099" id="1099">1099</a>
<a href="#1100" id="1100">1100</a>
<a href="#1101" id="1101">1101</a>
<a href="#1102" id="1102">1102</a>
<a href="#1103" id="1103">1103</a>
<a href="#1104" id="1104">1104</a>
<a href="#1105" id="1105">1105</a>
<a href="#1106" id="1106">1106</a>
<a href="#1107" id="1107">1107</a>
<a href="#1108" id="1108">1108</a>
<a href="#1109" id="1109">1109</a>
<a href="#1110" id="1110">1110</a>
<a href="#1111" id="1111">1111</a>
<a href="#1112" id="1112">1112</a>
<a href="#1113" id="1113">1113</a>
<a href="#1114" id="1114">1114</a>
<a href="#1115" id="1115">1115</a>
<a href="#1116" id="1116">1116</a>
<a href="#1117" id="1117">1117</a>
<a href="#1118" id="1118">1118</a>
<a href="#1119" id="1119">1119</a>
<a href="#1120" id="1120">1120</a>
<a href="#1121" id="1121">1121</a>
<a href="#1122" id="1122">1122</a>
<a href="#1123" id="1123">1123</a>
<a href="#1124" id="1124">1124</a>
<a href="#1125" id="1125">1125</a>
<a href="#1126" id="1126">1126</a>
<a href="#1127" id="1127">1127</a>
<a href="#1128" id="1128">1128</a>
<a href="#1129" id="1129">1129</a>
<a href="#1130" id="1130">1130</a>
<a href="#1131" id="1131">1131</a>
<a href="#1132" id="1132">1132</a>
<a href="#1133" id="1133">1133</a>
<a href="#1134" id="1134">1134</a>
<a href="#1135" id="1135">1135</a>
<a href="#1136" id="1136">1136</a>
<a href="#1137" id="1137">1137</a>
<a href="#1138" id="1138">1138</a>
<a href="#1139" id="1139">1139</a>
<a href="#1140" id="1140">1140</a>
<a href="#1141" id="1141">1141</a>
<a href="#1142" id="1142">1142</a>
<a href="#1143" id="1143">1143</a>
<a href="#1144" id="1144">1144</a>
<a href="#1145" id="1145">1145</a>
<a href="#1146" id="1146">1146</a>
<a href="#1147" id="1147">1147</a>
<a href="#1148" id="1148">1148</a>
<a href="#1149" id="1149">1149</a>
<a href="#1150" id="1150">1150</a>
<a href="#1151" id="1151">1151</a>
<a href="#1152" id="1152">1152</a>
<a href="#1153" id="1153">1153</a>
<a href="#1154" id="1154">1154</a>
<a href="#1155" id="1155">1155</a>
<a href="#1156" id="1156">1156</a>
<a href="#1157" id="1157">1157</a>
<a href="#1158" id="1158">1158</a>
<a href="#1159" id="1159">1159</a>
<a href="#1160" id="1160">1160</a>
<a href="#1161" id="1161">1161</a>
<a href="#1162" id="1162">1162</a>
<a href="#1163" id="1163">1163</a>
<a href="#1164" id="1164">1164</a>
<a href="#1165" id="1165">1165</a>
<a href="#1166" id="1166">1166</a>
<a href="#1167" id="1167">1167</a>
<a href="#1168" id="1168">1168</a>
<a href="#1169" id="1169">1169</a>
<a href="#1170" id="1170">1170</a>
<a href="#1171" id="1171">1171</a>
<a href="#1172" id="1172">1172</a>
<a href="#1173" id="1173">1173</a>
<a href="#1174" id="1174">1174</a>
<a href="#1175" id="1175">1175</a>
<a href="#1176" id="1176">1176</a>
<a href="#1177" id="1177">1177</a>
<a href="#1178" id="1178">1178</a>
<a href="#1179" id="1179">1179</a>
<a href="#1180" id="1180">1180</a>
<a href="#1181" id="1181">1181</a>
<a href="#1182" id="1182">1182</a>
<a href="#1183" id="1183">1183</a>
<a href="#1184" id="1184">1184</a>
<a href="#1185" id="1185">1185</a>
<a href="#1186" id="1186">1186</a>
<a href="#1187" id="1187">1187</a>
<a href="#1188" id="1188">1188</a>
<a href="#1189" id="1189">1189</a>
<a href="#1190" id="1190">1190</a>
<a href="#1191" id="1191">1191</a>
<a href="#1192" id="1192">1192</a>
<a href="#1193" id="1193">1193</a>
<a href="#1194" id="1194">1194</a>
<a href="#1195" id="1195">1195</a>
<a href="#1196" id="1196">1196</a>
<a href="#1197" id="1197">1197</a>
<a href="#1198" id="1198">1198</a>
<a href="#1199" id="1199">1199</a>
<a href="#1200" id="1200">1200</a>
<a href="#1201" id="1201">1201</a>
<a href="#1202" id="1202">1202</a>
<a href="#1203" id="1203">1203</a>
<a href="#1204" id="1204">1204</a>
<a href="#1205" id="1205">1205</a>
<a href="#1206" id="1206">1206</a>
<a href="#1207" id="1207">1207</a>
<a href="#1208" id="1208">1208</a>
<a href="#1209" id="1209">1209</a>
<a href="#1210" id="1210">1210</a>
<a href="#1211" id="1211">1211</a>
<a href="#1212" id="1212">1212</a>
<a href="#1213" id="1213">1213</a>
<a href="#1214" id="1214">1214</a>
<a href="#1215" id="1215">1215</a>
<a href="#1216" id="1216">1216</a>
<a href="#1217" id="1217">1217</a>
<a href="#1218" id="1218">1218</a>
<a href="#1219" id="1219">1219</a>
<a href="#1220" id="1220">1220</a>
<a href="#1221" id="1221">1221</a>
<a href="#1222" id="1222">1222</a>
<a href="#1223" id="1223">1223</a>
<a href="#1224" id="1224">1224</a>
<a href="#1225" id="1225">1225</a>
<a href="#1226" id="1226">1226</a>
<a href="#1227" id="1227">1227</a>
<a href="#1228" id="1228">1228</a>
<a href="#1229" id="1229">1229</a>
<a href="#1230" id="1230">1230</a>
<a href="#1231" id="1231">1231</a>
<a href="#1232" id="1232">1232</a>
<a href="#1233" id="1233">1233</a>
<a href="#1234" id="1234">1234</a>
<a href="#1235" id="1235">1235</a>
<a href="#1236" id="1236">1236</a>
<a href="#1237" id="1237">1237</a>
<a href="#1238" id="1238">1238</a>
<a href="#1239" id="1239">1239</a>
<a href="#1240" id="1240">1240</a>
<a href="#1241" id="1241">1241</a>
<a href="#1242" id="1242">1242</a>
<a href="#1243" id="1243">1243</a>
<a href="#1244" id="1244">1244</a>
<a href="#1245" id="1245">1245</a>
<a href="#1246" id="1246">1246</a>
<a href="#1247" id="1247">1247</a>
<a href="#1248" id="1248">1248</a>
<a href="#1249" id="1249">1249</a>
<a href="#1250" id="1250">1250</a>
<a href="#1251" id="1251">1251</a>
<a href="#1252" id="1252">1252</a>
<a href="#1253" id="1253">1253</a>
<a href="#1254" id="1254">1254</a>
<a href="#1255" id="1255">1255</a>
<a href="#1256" id="1256">1256</a>
<a href="#1257" id="1257">1257</a>
<a href="#1258" id="1258">1258</a>
<a href="#1259" id="1259">1259</a>
<a href="#1260" id="1260">1260</a>
<a href="#1261" id="1261">1261</a>
<a href="#1262" id="1262">1262</a>
<a href="#1263" id="1263">1263</a>
<a href="#1264" id="1264">1264</a>
<a href="#1265" id="1265">1265</a>
<a href="#1266" id="1266">1266</a>
<a href="#1267" id="1267">1267</a>
<a href="#1268" id="1268">1268</a>
<a href="#1269" id="1269">1269</a>
<a href="#1270" id="1270">1270</a>
<a href="#1271" id="1271">1271</a>
<a href="#1272" id="1272">1272</a>
<a href="#1273" id="1273">1273</a>
<a href="#1274" id="1274">1274</a>
<a href="#1275" id="1275">1275</a>
<a href="#1276" id="1276">1276</a>
<a href="#1277" id="1277">1277</a>
<a href="#1278" id="1278">1278</a>
<a href="#1279" id="1279">1279</a>
<a href="#1280" id="1280">1280</a>
<a href="#1281" id="1281">1281</a>
<a href="#1282" id="1282">1282</a>
<a href="#1283" id="1283">1283</a>
<a href="#1284" id="1284">1284</a>
<a href="#1285" id="1285">1285</a>
<a href="#1286" id="1286">1286</a>
<a href="#1287" id="1287">1287</a>
<a href="#1288" id="1288">1288</a>
<a href="#1289" id="1289">1289</a>
<a href="#1290" id="1290">1290</a>
<a href="#1291" id="1291">1291</a>
<a href="#1292" id="1292">1292</a>
<a href="#1293" id="1293">1293</a>
<a href="#1294" id="1294">1294</a>
<a href="#1295" id="1295">1295</a>
<a href="#1296" id="1296">1296</a>
<a href="#1297" id="1297">1297</a>
<a href="#1298" id="1298">1298</a>
<a href="#1299" id="1299">1299</a>
<a href="#1300" id="1300">1300</a>
<a href="#1301" id="1301">1301</a>
<a href="#1302" id="1302">1302</a>
<a href="#1303" id="1303">1303</a>
<a href="#1304" id="1304">1304</a>
<a href="#1305" id="1305">1305</a>
<a href="#1306" id="1306">1306</a>
<a href="#1307" id="1307">1307</a>
<a href="#1308" id="1308">1308</a>
<a href="#1309" id="1309">1309</a>
<a href="#1310" id="1310">1310</a>
<a href="#1311" id="1311">1311</a>
<a href="#1312" id="1312">1312</a>
<a href="#1313" id="1313">1313</a>
<a href="#1314" id="1314">1314</a>
<a href="#1315" id="1315">1315</a>
<a href="#1316" id="1316">1316</a>
<a href="#1317" id="1317">1317</a>
<a href="#1318" id="1318">1318</a>
<a href="#1319" id="1319">1319</a>
<a href="#1320" id="1320">1320</a>
<a href="#1321" id="1321">1321</a>
<a href="#1322" id="1322">1322</a>
<a href="#1323" id="1323">1323</a>
<a href="#1324" id="1324">1324</a>
<a href="#1325" id="1325">1325</a>
<a href="#1326" id="1326">1326</a>
<a href="#1327" id="1327">1327</a>
<a href="#1328" id="1328">1328</a>
<a href="#1329" id="1329">1329</a>
<a href="#1330" id="1330">1330</a>
<a href="#1331" id="1331">1331</a>
<a href="#1332" id="1332">1332</a>
<a href="#1333" id="1333">1333</a>
<a href="#1334" id="1334">1334</a>
<a href="#1335" id="1335">1335</a>
<a href="#1336" id="1336">1336</a>
<a href="#1337" id="1337">1337</a>
<a href="#1338" id="1338">1338</a>
<a href="#1339" id="1339">1339</a>
<a href="#1340" id="1340">1340</a>
<a href="#1341" id="1341">1341</a>
<a href="#1342" id="1342">1342</a>
<a href="#1343" id="1343">1343</a>
<a href="#1344" id="1344">1344</a>
<a href="#1345" id="1345">1345</a>
<a href="#1346" id="1346">1346</a>
<a href="#1347" id="1347">1347</a>
<a href="#1348" id="1348">1348</a>
<a href="#1349" id="1349">1349</a>
<a href="#1350" id="1350">1350</a>
<a href="#1351" id="1351">1351</a>
<a href="#1352" id="1352">1352</a>
<a href="#1353" id="1353">1353</a>
<a href="#1354" id="1354">1354</a>
<a href="#1355" id="1355">1355</a>
<a href="#1356" id="1356">1356</a>
<a href="#1357" id="1357">1357</a>
<a href="#1358" id="1358">1358</a>
<a href="#1359" id="1359">1359</a>
<a href="#1360" id="1360">1360</a>
<a href="#1361" id="1361">1361</a>
<a href="#1362" id="1362">1362</a>
<a href="#1363" id="1363">1363</a>
<a href="#1364" id="1364">1364</a>
<a href="#1365" id="1365">1365</a>
<a href="#1366" id="1366">1366</a>
<a href="#1367" id="1367">1367</a>
<a href="#1368" id="1368">1368</a>
<a href="#1369" id="1369">1369</a>
<a href="#1370" id="1370">1370</a>
<a href="#1371" id="1371">1371</a>
<a href="#1372" id="1372">1372</a>
<a href="#1373" id="1373">1373</a>
<a href="#1374" id="1374">1374</a>
<a href="#1375" id="1375">1375</a>
<a href="#1376" id="1376">1376</a>
<a href="#1377" id="1377">1377</a>
<a href="#1378" id="1378">1378</a>
<a href="#1379" id="1379">1379</a>
<a href="#1380" id="1380">1380</a>
<a href="#1381" id="1381">1381</a>
<a href="#1382" id="1382">1382</a>
<a href="#1383" id="1383">1383</a>
<a href="#1384" id="1384">1384</a>
<a href="#1385" id="1385">1385</a>
<a href="#1386" id="1386">1386</a>
<a href="#1387" id="1387">1387</a>
<a href="#1388" id="1388">1388</a>
<a href="#1389" id="1389">1389</a>
<a href="#1390" id="1390">1390</a>
<a href="#1391" id="1391">1391</a>
<a href="#1392" id="1392">1392</a>
<a href="#1393" id="1393">1393</a>
<a href="#1394" id="1394">1394</a>
<a href="#1395" id="1395">1395</a>
<a href="#1396" id="1396">1396</a>
<a href="#1397" id="1397">1397</a>
<a href="#1398" id="1398">1398</a>
<a href="#1399" id="1399">1399</a>
<a href="#1400" id="1400">1400</a>
<a href="#1401" id="1401">1401</a>
<a href="#1402" id="1402">1402</a>
<a href="#1403" id="1403">1403</a>
<a href="#1404" id="1404">1404</a>
<a href="#1405" id="1405">1405</a>
<a href="#1406" id="1406">1406</a>
<a href="#1407" id="1407">1407</a>
<a href="#1408" id="1408">1408</a>
<a href="#1409" id="1409">1409</a>
<a href="#1410" id="1410">1410</a>
<a href="#1411" id="1411">1411</a>
<a href="#1412" id="1412">1412</a>
<a href="#1413" id="1413">1413</a>
<a href="#1414" id="1414">1414</a>
<a href="#1415" id="1415">1415</a>
<a href="#1416" id="1416">1416</a>
<a href="#1417" id="1417">1417</a>
<a href="#1418" id="1418">1418</a>
<a href="#1419" id="1419">1419</a>
<a href="#1420" id="1420">1420</a>
<a href="#1421" id="1421">1421</a>
<a href="#1422" id="1422">1422</a>
<a href="#1423" id="1423">1423</a>
<a href="#1424" id="1424">1424</a>
<a href="#1425" id="1425">1425</a>
<a href="#1426" id="1426">1426</a>
<a href="#1427" id="1427">1427</a>
<a href="#1428" id="1428">1428</a>
<a href="#1429" id="1429">1429</a>
<a href="#1430" id="1430">1430</a>
<a href="#1431" id="1431">1431</a>
<a href="#1432" id="1432">1432</a>
<a href="#1433" id="1433">1433</a>
<a href="#1434" id="1434">1434</a>
<a href="#1435" id="1435">1435</a>
<a href="#1436" id="1436">1436</a>
<a href="#1437" id="1437">1437</a>
<a href="#1438" id="1438">1438</a>
<a href="#1439" id="1439">1439</a>
<a href="#1440" id="1440">1440</a>
<a href="#1441" id="1441">1441</a>
<a href="#1442" id="1442">1442</a>
<a href="#1443" id="1443">1443</a>
<a href="#1444" id="1444">1444</a>
<a href="#1445" id="1445">1445</a>
<a href="#1446" id="1446">1446</a>
<a href="#1447" id="1447">1447</a>
<a href="#1448" id="1448">1448</a>
<a href="#1449" id="1449">1449</a>
<a href="#1450" id="1450">1450</a>
<a href="#1451" id="1451">1451</a>
<a href="#1452" id="1452">1452</a>
<a href="#1453" id="1453">1453</a>
<a href="#1454" id="1454">1454</a>
<a href="#1455" id="1455">1455</a>
<a href="#1456" id="1456">1456</a>
<a href="#1457" id="1457">1457</a>
<a href="#1458" id="1458">1458</a>
<a href="#1459" id="1459">1459</a>
<a href="#1460" id="1460">1460</a>
<a href="#1461" id="1461">1461</a>
<a href="#1462" id="1462">1462</a>
<a href="#1463" id="1463">1463</a>
<a href="#1464" id="1464">1464</a>
<a href="#1465" id="1465">1465</a>
<a href="#1466" id="1466">1466</a>
<a href="#1467" id="1467">1467</a>
<a href="#1468" id="1468">1468</a>
<a href="#1469" id="1469">1469</a>
<a href="#1470" id="1470">1470</a>
<a href="#1471" id="1471">1471</a>
<a href="#1472" id="1472">1472</a>
<a href="#1473" id="1473">1473</a>
<a href="#1474" id="1474">1474</a>
<a href="#1475" id="1475">1475</a>
<a href="#1476" id="1476">1476</a>
<a href="#1477" id="1477">1477</a>
<a href="#1478" id="1478">1478</a>
<a href="#1479" id="1479">1479</a>
<a href="#1480" id="1480">1480</a>
<a href="#1481" id="1481">1481</a>
<a href="#1482" id="1482">1482</a>
<a href="#1483" id="1483">1483</a>
<a href="#1484" id="1484">1484</a>
<a href="#1485" id="1485">1485</a>
<a href="#1486" id="1486">1486</a>
<a href="#1487" id="1487">1487</a>
<a href="#1488" id="1488">1488</a>
<a href="#1489" id="1489">1489</a>
<a href="#1490" id="1490">1490</a>
<a href="#1491" id="1491">1491</a>
<a href="#1492" id="1492">1492</a>
<a href="#1493" id="1493">1493</a>
<a href="#1494" id="1494">1494</a>
<a href="#1495" id="1495">1495</a>
<a href="#1496" id="1496">1496</a>
<a href="#1497" id="1497">1497</a>
<a href="#1498" id="1498">1498</a>
<a href="#1499" id="1499">1499</a>
<a href="#1500" id="1500">1500</a>
<a href="#1501" id="1501">1501</a>
<a href="#1502" id="1502">1502</a>
<a href="#1503" id="1503">1503</a>
<a href="#1504" id="1504">1504</a>
<a href="#1505" id="1505">1505</a>
<a href="#1506" id="1506">1506</a>
<a href="#1507" id="1507">1507</a>
<a href="#1508" id="1508">1508</a>
<a href="#1509" id="1509">1509</a>
<a href="#1510" id="1510">1510</a>
<a href="#1511" id="1511">1511</a>
<a href="#1512" id="1512">1512</a>
<a href="#1513" id="1513">1513</a>
<a href="#1514" id="1514">1514</a>
<a href="#1515" id="1515">1515</a>
<a href="#1516" id="1516">1516</a>
<a href="#1517" id="1517">1517</a>
<a href="#1518" id="1518">1518</a>
<a href="#1519" id="1519">1519</a>
<a href="#1520" id="1520">1520</a>
<a href="#1521" id="1521">1521</a>
<a href="#1522" id="1522">1522</a>
<a href="#1523" id="1523">1523</a>
<a href="#1524" id="1524">1524</a>
<a href="#1525" id="1525">1525</a>
<a href="#1526" id="1526">1526</a>
<a href="#1527" id="1527">1527</a>
<a href="#1528" id="1528">1528</a>
<a href="#1529" id="1529">1529</a>
<a href="#1530" id="1530">1530</a>
<a href="#1531" id="1531">1531</a>
<a href="#1532" id="1532">1532</a>
<a href="#1533" id="1533">1533</a>
<a href="#1534" id="1534">1534</a>
<a href="#1535" id="1535">1535</a>
<a href="#1536" id="1536">1536</a>
<a href="#1537" id="1537">1537</a>
<a href="#1538" id="1538">1538</a>
<a href="#1539" id="1539">1539</a>
<a href="#1540" id="1540">1540</a>
<a href="#1541" id="1541">1541</a>
<a href="#1542" id="1542">1542</a>
<a href="#1543" id="1543">1543</a>
<a href="#1544" id="1544">1544</a>
<a href="#1545" id="1545">1545</a>
<a href="#1546" id="1546">1546</a>
<a href="#1547" id="1547">1547</a>
<a href="#1548" id="1548">1548</a>
<a href="#1549" id="1549">1549</a>
<a href="#1550" id="1550">1550</a>
<a href="#1551" id="1551">1551</a>
<a href="#1552" id="1552">1552</a>
<a href="#1553" id="1553">1553</a>
<a href="#1554" id="1554">1554</a>
<a href="#1555" id="1555">1555</a>
<a href="#1556" id="1556">1556</a>
<a href="#1557" id="1557">1557</a>
<a href="#1558" id="1558">1558</a>
<a href="#1559" id="1559">1559</a>
<a href="#1560" id="1560">1560</a>
<a href="#1561" id="1561">1561</a>
<a href="#1562" id="1562">1562</a>
<a href="#1563" id="1563">1563</a>
<a href="#1564" id="1564">1564</a>
<a href="#1565" id="1565">1565</a>
<a href="#1566" id="1566">1566</a>
<a href="#1567" id="1567">1567</a>
<a href="#1568" id="1568">1568</a>
<a href="#1569" id="1569">1569</a>
<a href="#1570" id="1570">1570</a>
<a href="#1571" id="1571">1571</a>
<a href="#1572" id="1572">1572</a>
<a href="#1573" id="1573">1573</a>
<a href="#1574" id="1574">1574</a>
<a href="#1575" id="1575">1575</a>
<a href="#1576" id="1576">1576</a>
<a href="#1577" id="1577">1577</a>
<a href="#1578" id="1578">1578</a>
<a href="#1579" id="1579">1579</a>
<a href="#1580" id="1580">1580</a>
<a href="#1581" id="1581">1581</a>
<a href="#1582" id="1582">1582</a>
<a href="#1583" id="1583">1583</a>
<a href="#1584" id="1584">1584</a>
<a href="#1585" id="1585">1585</a>
<a href="#1586" id="1586">1586</a>
<a href="#1587" id="1587">1587</a>
<a href="#1588" id="1588">1588</a>
<a href="#1589" id="1589">1589</a>
<a href="#1590" id="1590">1590</a>
<a href="#1591" id="1591">1591</a>
<a href="#1592" id="1592">1592</a>
<a href="#1593" id="1593">1593</a>
<a href="#1594" id="1594">1594</a>
<a href="#1595" id="1595">1595</a>
<a href="#1596" id="1596">1596</a>
<a href="#1597" id="1597">1597</a>
<a href="#1598" id="1598">1598</a>
<a href="#1599" id="1599">1599</a>
<a href="#1600" id="1600">1600</a>
<a href="#1601" id="1601">1601</a>
<a href="#1602" id="1602">1602</a>
<a href="#1603" id="1603">1603</a>
<a href="#1604" id="1604">1604</a>
<a href="#1605" id="1605">1605</a>
<a href="#1606" id="1606">1606</a>
<a href="#1607" id="1607">1607</a>
<a href="#1608" id="1608">1608</a>
<a href="#1609" id="1609">1609</a>
<a href="#1610" id="1610">1610</a>
<a href="#1611" id="1611">1611</a>
<a href="#1612" id="1612">1612</a>
<a href="#1613" id="1613">1613</a>
<a href="#1614" id="1614">1614</a>
<a href="#1615" id="1615">1615</a>
<a href="#1616" id="1616">1616</a>
<a href="#1617" id="1617">1617</a>
<a href="#1618" id="1618">1618</a>
<a href="#1619" id="1619">1619</a>
<a href="#1620" id="1620">1620</a>
<a href="#1621" id="1621">1621</a>
<a href="#1622" id="1622">1622</a>
<a href="#1623" id="1623">1623</a>
<a href="#1624" id="1624">1624</a>
<a href="#1625" id="1625">1625</a>
<a href="#1626" id="1626">1626</a>
<a href="#1627" id="1627">1627</a>
<a href="#1628" id="1628">1628</a>
<a href="#1629" id="1629">1629</a>
<a href="#1630" id="1630">1630</a>
<a href="#1631" id="1631">1631</a>
<a href="#1632" id="1632">1632</a>
<a href="#1633" id="1633">1633</a>
<a href="#1634" id="1634">1634</a>
<a href="#1635" id="1635">1635</a>
<a href="#1636" id="1636">1636</a>
<a href="#1637" id="1637">1637</a>
<a href="#1638" id="1638">1638</a>
<a href="#1639" id="1639">1639</a>
<a href="#1640" id="1640">1640</a>
<a href="#1641" id="1641">1641</a>
<a href="#1642" id="1642">1642</a>
<a href="#1643" id="1643">1643</a>
<a href="#1644" id="1644">1644</a>
<a href="#1645" id="1645">1645</a>
<a href="#1646" id="1646">1646</a>
<a href="#1647" id="1647">1647</a>
<a href="#1648" id="1648">1648</a>
<a href="#1649" id="1649">1649</a>
<a href="#1650" id="1650">1650</a>
<a href="#1651" id="1651">1651</a>
<a href="#1652" id="1652">1652</a>
<a href="#1653" id="1653">1653</a>
<a href="#1654" id="1654">1654</a>
<a href="#1655" id="1655">1655</a>
<a href="#1656" id="1656">1656</a>
<a href="#1657" id="1657">1657</a>
<a href="#1658" id="1658">1658</a>
<a href="#1659" id="1659">1659</a>
<a href="#1660" id="1660">1660</a>
<a href="#1661" id="1661">1661</a>
<a href="#1662" id="1662">1662</a>
<a href="#1663" id="1663">1663</a>
<a href="#1664" id="1664">1664</a>
<a href="#1665" id="1665">1665</a>
<a href="#1666" id="1666">1666</a>
<a href="#1667" id="1667">1667</a>
<a href="#1668" id="1668">1668</a>
<a href="#1669" id="1669">1669</a>
<a href="#1670" id="1670">1670</a>
<a href="#1671" id="1671">1671</a>
<a href="#1672" id="1672">1672</a>
<a href="#1673" id="1673">1673</a>
<a href="#1674" id="1674">1674</a>
<a href="#1675" id="1675">1675</a>
<a href="#1676" id="1676">1676</a>
<a href="#1677" id="1677">1677</a>
<a href="#1678" id="1678">1678</a>
<a href="#1679" id="1679">1679</a>
<a href="#1680" id="1680">1680</a>
<a href="#1681" id="1681">1681</a>
<a href="#1682" id="1682">1682</a>
<a href="#1683" id="1683">1683</a>
<a href="#1684" id="1684">1684</a>
<a href="#1685" id="1685">1685</a>
<a href="#1686" id="1686">1686</a>
<a href="#1687" id="1687">1687</a>
<a href="#1688" id="1688">1688</a>
<a href="#1689" id="1689">1689</a>
<a href="#1690" id="1690">1690</a>
<a href="#1691" id="1691">1691</a>
<a href="#1692" id="1692">1692</a>
<a href="#1693" id="1693">1693</a>
<a href="#1694" id="1694">1694</a>
<a href="#1695" id="1695">1695</a>
<a href="#1696" id="1696">1696</a>
<a href="#1697" id="1697">1697</a>
<a href="#1698" id="1698">1698</a>
<a href="#1699" id="1699">1699</a>
<a href="#1700" id="1700">1700</a>
<a href="#1701" id="1701">1701</a>
<a href="#1702" id="1702">1702</a>
<a href="#1703" id="1703">1703</a>
<a href="#1704" id="1704">1704</a>
<a href="#1705" id="1705">1705</a>
<a href="#1706" id="1706">1706</a>
<a href="#1707" id="1707">1707</a>
<a href="#1708" id="1708">1708</a>
<a href="#1709" id="1709">1709</a>
<a href="#1710" id="1710">1710</a>
<a href="#1711" id="1711">1711</a>
<a href="#1712" id="1712">1712</a>
<a href="#1713" id="1713">1713</a>
<a href="#1714" id="1714">1714</a>
<a href="#1715" id="1715">1715</a>
<a href="#1716" id="1716">1716</a>
<a href="#1717" id="1717">1717</a>
<a href="#1718" id="1718">1718</a>
<a href="#1719" id="1719">1719</a>
<a href="#1720" id="1720">1720</a>
<a href="#1721" id="1721">1721</a>
<a href="#1722" id="1722">1722</a>
<a href="#1723" id="1723">1723</a>
<a href="#1724" id="1724">1724</a>
<a href="#1725" id="1725">1725</a>
<a href="#1726" id="1726">1726</a>
<a href="#1727" id="1727">1727</a>
<a href="#1728" id="1728">1728</a>
<a href="#1729" id="1729">1729</a>
<a href="#1730" id="1730">1730</a>
<a href="#1731" id="1731">1731</a>
<a href="#1732" id="1732">1732</a>
<a href="#1733" id="1733">1733</a>
<a href="#1734" id="1734">1734</a>
<a href="#1735" id="1735">1735</a>
<a href="#1736" id="1736">1736</a>
<a href="#1737" id="1737">1737</a>
<a href="#1738" id="1738">1738</a>
<a href="#1739" id="1739">1739</a>
<a href="#1740" id="1740">1740</a>
<a href="#1741" id="1741">1741</a>
<a href="#1742" id="1742">1742</a>
<a href="#1743" id="1743">1743</a>
<a href="#1744" id="1744">1744</a>
<a href="#1745" id="1745">1745</a>
<a href="#1746" id="1746">1746</a>
<a href="#1747" id="1747">1747</a>
<a href="#1748" id="1748">1748</a>
<a href="#1749" id="1749">1749</a>
<a href="#1750" id="1750">1750</a>
<a href="#1751" id="1751">1751</a>
<a href="#1752" id="1752">1752</a>
<a href="#1753" id="1753">1753</a>
<a href="#1754" id="1754">1754</a>
<a href="#1755" id="1755">1755</a>
<a href="#1756" id="1756">1756</a>
<a href="#1757" id="1757">1757</a>
<a href="#1758" id="1758">1758</a>
<a href="#1759" id="1759">1759</a>
<a href="#1760" id="1760">1760</a>
<a href="#1761" id="1761">1761</a>
<a href="#1762" id="1762">1762</a>
<a href="#1763" id="1763">1763</a>
<a href="#1764" id="1764">1764</a>
<a href="#1765" id="1765">1765</a>
<a href="#1766" id="1766">1766</a>
<a href="#1767" id="1767">1767</a>
<a href="#1768" id="1768">1768</a>
<a href="#1769" id="1769">1769</a>
<a href="#1770" id="1770">1770</a>
<a href="#1771" id="1771">1771</a>
<a href="#1772" id="1772">1772</a>
<a href="#1773" id="1773">1773</a>
<a href="#1774" id="1774">1774</a>
<a href="#1775" id="1775">1775</a>
<a href="#1776" id="1776">1776</a>
<a href="#1777" id="1777">1777</a>
<a href="#1778" id="1778">1778</a>
<a href="#1779" id="1779">1779</a>
<a href="#1780" id="1780">1780</a>
<a href="#1781" id="1781">1781</a>
<a href="#1782" id="1782">1782</a>
<a href="#1783" id="1783">1783</a>
<a href="#1784" id="1784">1784</a>
<a href="#1785" id="1785">1785</a>
<a href="#1786" id="1786">1786</a>
<a href="#1787" id="1787">1787</a>
<a href="#1788" id="1788">1788</a>
<a href="#1789" id="1789">1789</a>
<a href="#1790" id="1790">1790</a>
<a href="#1791" id="1791">1791</a>
<a href="#1792" id="1792">1792</a>
<a href="#1793" id="1793">1793</a>
<a href="#1794" id="1794">1794</a>
<a href="#1795" id="1795">1795</a>
<a href="#1796" id="1796">1796</a>
<a href="#1797" id="1797">1797</a>
<a href="#1798" id="1798">1798</a>
<a href="#1799" id="1799">1799</a>
<a href="#1800" id="1800">1800</a>
<a href="#1801" id="1801">1801</a>
<a href="#1802" id="1802">1802</a>
<a href="#1803" id="1803">1803</a>
<a href="#1804" id="1804">1804</a>
<a href="#1805" id="1805">1805</a>
<a href="#1806" id="1806">1806</a>
<a href="#1807" id="1807">1807</a>
<a href="#1808" id="1808">1808</a>
<a href="#1809" id="1809">1809</a>
<a href="#1810" id="1810">1810</a>
<a href="#1811" id="1811">1811</a>
<a href="#1812" id="1812">1812</a>
<a href="#1813" id="1813">1813</a>
<a href="#1814" id="1814">1814</a>
<a href="#1815" id="1815">1815</a>
<a href="#1816" id="1816">1816</a>
<a href="#1817" id="1817">1817</a>
<a href="#1818" id="1818">1818</a>
<a href="#1819" id="1819">1819</a>
<a href="#1820" id="1820">1820</a>
<a href="#1821" id="1821">1821</a>
<a href="#1822" id="1822">1822</a>
<a href="#1823" id="1823">1823</a>
<a href="#1824" id="1824">1824</a>
<a href="#1825" id="1825">1825</a>
<a href="#1826" id="1826">1826</a>
<a href="#1827" id="1827">1827</a>
<a href="#1828" id="1828">1828</a>
<a href="#1829" id="1829">1829</a>
<a href="#1830" id="1830">1830</a>
<a href="#1831" id="1831">1831</a>
<a href="#1832" id="1832">1832</a>
<a href="#1833" id="1833">1833</a>
<a href="#1834" id="1834">1834</a>
<a href="#1835" id="1835">1835</a>
<a href="#1836" id="1836">1836</a>
<a href="#1837" id="1837">1837</a>
<a href="#1838" id="1838">1838</a>
<a href="#1839" id="1839">1839</a>
<a href="#1840" id="1840">1840</a>
<a href="#1841" id="1841">1841</a>
<a href="#1842" id="1842">1842</a>
<a href="#1843" id="1843">1843</a>
<a href="#1844" id="1844">1844</a>
<a href="#1845" id="1845">1845</a>
<a href="#1846" id="1846">1846</a>
<a href="#1847" id="1847">1847</a>
<a href="#1848" id="1848">1848</a>
<a href="#1849" id="1849">1849</a>
<a href="#1850" id="1850">1850</a>
<a href="#1851" id="1851">1851</a>
<a href="#1852" id="1852">1852</a>
<a href="#1853" id="1853">1853</a>
<a href="#1854" id="1854">1854</a>
<a href="#1855" id="1855">1855</a>
<a href="#1856" id="1856">1856</a>
<a href="#1857" id="1857">1857</a>
<a href="#1858" id="1858">1858</a>
<a href="#1859" id="1859">1859</a>
<a href="#1860" id="1860">1860</a>
<a href="#1861" id="1861">1861</a>
<a href="#1862" id="1862">1862</a>
<a href="#1863" id="1863">1863</a>
<a href="#1864" id="1864">1864</a>
<a href="#1865" id="1865">1865</a>
<a href="#1866" id="1866">1866</a>
<a href="#1867" id="1867">1867</a>
<a href="#1868" id="1868">1868</a>
<a href="#1869" id="1869">1869</a>
<a href="#1870" id="1870">1870</a>
<a href="#1871" id="1871">1871</a>
<a href="#1872" id="1872">1872</a>
<a href="#1873" id="1873">1873</a>
<a href="#1874" id="1874">1874</a>
<a href="#1875" id="1875">1875</a>
<a href="#1876" id="1876">1876</a>
<a href="#1877" id="1877">1877</a>
<a href="#1878" id="1878">1878</a>
<a href="#1879" id="1879">1879</a>
<a href="#1880" id="1880">1880</a>
<a href="#1881" id="1881">1881</a>
<a href="#1882" id="1882">1882</a>
<a href="#1883" id="1883">1883</a>
<a href="#1884" id="1884">1884</a>
<a href="#1885" id="1885">1885</a>
<a href="#1886" id="1886">1886</a>
<a href="#1887" id="1887">1887</a>
<a href="#1888" id="1888">1888</a>
<a href="#1889" id="1889">1889</a>
<a href="#1890" id="1890">1890</a>
<a href="#1891" id="1891">1891</a>
<a href="#1892" id="1892">1892</a>
<a href="#1893" id="1893">1893</a>
<a href="#1894" id="1894">1894</a>
<a href="#1895" id="1895">1895</a>
<a href="#1896" id="1896">1896</a>
<a href="#1897" id="1897">1897</a>
<a href="#1898" id="1898">1898</a>
<a href="#1899" id="1899">1899</a>
<a href="#1900" id="1900">1900</a>
<a href="#1901" id="1901">1901</a>
<a href="#1902" id="1902">1902</a>
<a href="#1903" id="1903">1903</a>
<a href="#1904" id="1904">1904</a>
<a href="#1905" id="1905">1905</a>
<a href="#1906" id="1906">1906</a>
<a href="#1907" id="1907">1907</a>
<a href="#1908" id="1908">1908</a>
<a href="#1909" id="1909">1909</a>
<a href="#1910" id="1910">1910</a>
<a href="#1911" id="1911">1911</a>
<a href="#1912" id="1912">1912</a>
<a href="#1913" id="1913">1913</a>
<a href="#1914" id="1914">1914</a>
<a href="#1915" id="1915">1915</a>
<a href="#1916" id="1916">1916</a>
<a href="#1917" id="1917">1917</a>
<a href="#1918" id="1918">1918</a>
<a href="#1919" id="1919">1919</a>
<a href="#1920" id="1920">1920</a>
<a href="#1921" id="1921">1921</a>
<a href="#1922" id="1922">1922</a>
<a href="#1923" id="1923">1923</a>
<a href="#1924" id="1924">1924</a>
<a href="#1925" id="1925">1925</a>
<a href="#1926" id="1926">1926</a>
<a href="#1927" id="1927">1927</a>
<a href="#1928" id="1928">1928</a>
<a href="#1929" id="1929">1929</a>
<a href="#1930" id="1930">1930</a>
<a href="#1931" id="1931">1931</a>
<a href="#1932" id="1932">1932</a>
<a href="#1933" id="1933">1933</a>
<a href="#1934" id="1934">1934</a>
<a href="#1935" id="1935">1935</a>
<a href="#1936" id="1936">1936</a>
<a href="#1937" id="1937">1937</a>
<a href="#1938" id="1938">1938</a>
<a href="#1939" id="1939">1939</a>
<a href="#1940" id="1940">1940</a>
<a href="#1941" id="1941">1941</a>
<a href="#1942" id="1942">1942</a>
<a href="#1943" id="1943">1943</a>
<a href="#1944" id="1944">1944</a>
<a href="#1945" id="1945">1945</a>
<a href="#1946" id="1946">1946</a>
<a href="#1947" id="1947">1947</a>
<a href="#1948" id="1948">1948</a>
<a href="#1949" id="1949">1949</a>
<a href="#1950" id="1950">1950</a>
<a href="#1951" id="1951">1951</a>
<a href="#1952" id="1952">1952</a>
<a href="#1953" id="1953">1953</a>
<a href="#1954" id="1954">1954</a>
<a href="#1955" id="1955">1955</a>
<a href="#1956" id="1956">1956</a>
<a href="#1957" id="1957">1957</a>
<a href="#1958" id="1958">1958</a>
<a href="#1959" id="1959">1959</a>
<a href="#1960" id="1960">1960</a>
<a href="#1961" id="1961">1961</a>
<a href="#1962" id="1962">1962</a>
<a href="#1963" id="1963">1963</a>
<a href="#1964" id="1964">1964</a>
<a href="#1965" id="1965">1965</a>
<a href="#1966" id="1966">1966</a>
<a href="#1967" id="1967">1967</a>
<a href="#1968" id="1968">1968</a>
<a href="#1969" id="1969">1969</a>
<a href="#1970" id="1970">1970</a>
<a href="#1971" id="1971">1971</a>
<a href="#1972" id="1972">1972</a>
<a href="#1973" id="1973">1973</a>
<a href="#1974" id="1974">1974</a>
<a href="#1975" id="1975">1975</a>
<a href="#1976" id="1976">1976</a>
<a href="#1977" id="1977">1977</a>
<a href="#1978" id="1978">1978</a>
<a href="#1979" id="1979">1979</a>
<a href="#1980" id="1980">1980</a>
<a href="#1981" id="1981">1981</a>
<a href="#1982" id="1982">1982</a>
<a href="#1983" id="1983">1983</a>
<a href="#1984" id="1984">1984</a>
<a href="#1985" id="1985">1985</a>
<a href="#1986" id="1986">1986</a>
<a href="#1987" id="1987">1987</a>
<a href="#1988" id="1988">1988</a>
<a href="#1989" id="1989">1989</a>
<a href="#1990" id="1990">1990</a>
<a href="#1991" id="1991">1991</a>
<a href="#1992" id="1992">1992</a>
<a href="#1993" id="1993">1993</a>
<a href="#1994" id="1994">1994</a>
<a href="#1995" id="1995">1995</a>
<a href="#1996" id="1996">1996</a>
<a href="#1997" id="1997">1997</a>
<a href="#1998" id="1998">1998</a>
<a href="#1999" id="1999">1999</a>
<a href="#2000" id="2000">2000</a>
<a href="#2001" id="2001">2001</a>
<a href="#2002" id="2002">2002</a>
<a href="#2003" id="2003">2003</a>
<a href="#2004" id="2004">2004</a>
<a href="#2005" id="2005">2005</a>
<a href="#2006" id="2006">2006</a>
<a href="#2007" id="2007">2007</a>
<a href="#2008" id="2008">2008</a>
<a href="#2009" id="2009">2009</a>
<a href="#2010" id="2010">2010</a>
<a href="#2011" id="2011">2011</a>
<a href="#2012" id="2012">2012</a>
<a href="#2013" id="2013">2013</a>
<a href="#2014" id="2014">2014</a>
<a href="#2015" id="2015">2015</a>
<a href="#2016" id="2016">2016</a>
<a href="#2017" id="2017">2017</a>
<a href="#2018" id="2018">2018</a>
<a href="#2019" id="2019">2019</a>
<a href="#2020" id="2020">2020</a>
<a href="#2021" id="2021">2021</a>
<a href="#2022" id="2022">2022</a>
<a href="#2023" id="2023">2023</a>
<a href="#2024" id="2024">2024</a>
<a href="#2025" id="2025">2025</a>
<a href="#2026" id="2026">2026</a>
<a href="#2027" id="2027">2027</a>
<a href="#2028" id="2028">2028</a>
<a href="#2029" id="2029">2029</a>
<a href="#2030" id="2030">2030</a>
<a href="#2031" id="2031">2031</a>
<a href="#2032" id="2032">2032</a>
<a href="#2033" id="2033">2033</a>
<a href="#2034" id="2034">2034</a>
<a href="#2035" id="2035">2035</a>
<a href="#2036" id="2036">2036</a>
<a href="#2037" id="2037">2037</a>
<a href="#2038" id="2038">2038</a>
<a href="#2039" id="2039">2039</a>
<a href="#2040" id="2040">2040</a>
<a href="#2041" id="2041">2041</a>
<a href="#2042" id="2042">2042</a>
<a href="#2043" id="2043">2043</a>
<a href="#2044" id="2044">2044</a>
<a href="#2045" id="2045">2045</a>
<a href="#2046" id="2046">2046</a>
<a href="#2047" id="2047">2047</a>
<a href="#2048" id="2048">2048</a>
<a href="#2049" id="2049">2049</a>
<a href="#2050" id="2050">2050</a>
<a href="#2051" id="2051">2051</a>
<a href="#2052" id="2052">2052</a>
<a href="#2053" id="2053">2053</a>
<a href="#2054" id="2054">2054</a>
<a href="#2055" id="2055">2055</a>
<a href="#2056" id="2056">2056</a>
<a href="#2057" id="2057">2057</a>
<a href="#2058" id="2058">2058</a>
<a href="#2059" id="2059">2059</a>
<a href="#2060" id="2060">2060</a>
<a href="#2061" id="2061">2061</a>
<a href="#2062" id="2062">2062</a>
<a href="#2063" id="2063">2063</a>
<a href="#2064" id="2064">2064</a>
<a href="#2065" id="2065">2065</a>
<a href="#2066" id="2066">2066</a>
<a href="#2067" id="2067">2067</a>
<a href="#2068" id="2068">2068</a>
<a href="#2069" id="2069">2069</a>
<a href="#2070" id="2070">2070</a>
<a href="#2071" id="2071">2071</a>
<a href="#2072" id="2072">2072</a>
<a href="#2073" id="2073">2073</a>
<a href="#2074" id="2074">2074</a>
<a href="#2075" id="2075">2075</a>
<a href="#2076" id="2076">2076</a>
<a href="#2077" id="2077">2077</a>
<a href="#2078" id="2078">2078</a>
<a href="#2079" id="2079">2079</a>
<a href="#2080" id="2080">2080</a>
<a href="#2081" id="2081">2081</a>
<a href="#2082" id="2082">2082</a>
<a href="#2083" id="2083">2083</a>
<a href="#2084" id="2084">2084</a>
<a href="#2085" id="2085">2085</a>
<a href="#2086" id="2086">2086</a>
<a href="#2087" id="2087">2087</a>
<a href="#2088" id="2088">2088</a>
<a href="#2089" id="2089">2089</a>
<a href="#2090" id="2090">2090</a>
<a href="#2091" id="2091">2091</a>
<a href="#2092" id="2092">2092</a>
<a href="#2093" id="2093">2093</a>
<a href="#2094" id="2094">2094</a>
<a href="#2095" id="2095">2095</a>
<a href="#2096" id="2096">2096</a>
<a href="#2097" id="2097">2097</a>
<a href="#2098" id="2098">2098</a>
<a href="#2099" id="2099">2099</a>
<a href="#2100" id="2100">2100</a>
<a href="#2101" id="2101">2101</a>
<a href="#2102" id="2102">2102</a>
<a href="#2103" id="2103">2103</a>
<a href="#2104" id="2104">2104</a>
<a href="#2105" id="2105">2105</a>
<a href="#2106" id="2106">2106</a>
<a href="#2107" id="2107">2107</a>
<a href="#2108" id="2108">2108</a>
<a href="#2109" id="2109">2109</a>
<a href="#2110" id="2110">2110</a>
<a href="#2111" id="2111">2111</a>
<a href="#2112" id="2112">2112</a>
<a href="#2113" id="2113">2113</a>
<a href="#2114" id="2114">2114</a>
<a href="#2115" id="2115">2115</a>
<a href="#2116" id="2116">2116</a>
<a href="#2117" id="2117">2117</a>
<a href="#2118" id="2118">2118</a>
<a href="#2119" id="2119">2119</a>
<a href="#2120" id="2120">2120</a>
<a href="#2121" id="2121">2121</a>
<a href="#2122" id="2122">2122</a>
<a href="#2123" id="2123">2123</a>
<a href="#2124" id="2124">2124</a>
<a href="#2125" id="2125">2125</a>
<a href="#2126" id="2126">2126</a>
<a href="#2127" id="2127">2127</a>
<a href="#2128" id="2128">2128</a>
<a href="#2129" id="2129">2129</a>
<a href="#2130" id="2130">2130</a>
<a href="#2131" id="2131">2131</a>
<a href="#2132" id="2132">2132</a>
<a href="#2133" id="2133">2133</a>
<a href="#2134" id="2134">2134</a>
<a href="#2135" id="2135">2135</a>
<a href="#2136" id="2136">2136</a>
<a href="#2137" id="2137">2137</a>
<a href="#2138" id="2138">2138</a>
<a href="#2139" id="2139">2139</a>
<a href="#2140" id="2140">2140</a>
<a href="#2141" id="2141">2141</a>
<a href="#2142" id="2142">2142</a>
<a href="#2143" id="2143">2143</a>
<a href="#2144" id="2144">2144</a>
<a href="#2145" id="2145">2145</a>
<a href="#2146" id="2146">2146</a>
<a href="#2147" id="2147">2147</a>
<a href="#2148" id="2148">2148</a>
<a href="#2149" id="2149">2149</a>
<a href="#2150" id="2150">2150</a>
<a href="#2151" id="2151">2151</a>
<a href="#2152" id="2152">2152</a>
<a href="#2153" id="2153">2153</a>
<a href="#2154" id="2154">2154</a>
<a href="#2155" id="2155">2155</a>
<a href="#2156" id="2156">2156</a>
<a href="#2157" id="2157">2157</a>
<a href="#2158" id="2158">2158</a>
<a href="#2159" id="2159">2159</a>
<a href="#2160" id="2160">2160</a>
<a href="#2161" id="2161">2161</a>
<a href="#2162" id="2162">2162</a>
<a href="#2163" id="2163">2163</a>
<a href="#2164" id="2164">2164</a>
<a href="#2165" id="2165">2165</a>
<a href="#2166" id="2166">2166</a>
<a href="#2167" id="2167">2167</a>
<a href="#2168" id="2168">2168</a>
<a href="#2169" id="2169">2169</a>
<a href="#2170" id="2170">2170</a>
<a href="#2171" id="2171">2171</a>
<a href="#2172" id="2172">2172</a>
<a href="#2173" id="2173">2173</a>
<a href="#2174" id="2174">2174</a>
<a href="#2175" id="2175">2175</a>
<a href="#2176" id="2176">2176</a>
<a href="#2177" id="2177">2177</a>
<a href="#2178" id="2178">2178</a>
<a href="#2179" id="2179">2179</a>
<a href="#2180" id="2180">2180</a>
<a href="#2181" id="2181">2181</a>
<a href="#2182" id="2182">2182</a>
<a href="#2183" id="2183">2183</a>
<a href="#2184" id="2184">2184</a>
<a href="#2185" id="2185">2185</a>
<a href="#2186" id="2186">2186</a>
<a href="#2187" id="2187">2187</a>
<a href="#2188" id="2188">2188</a>
<a href="#2189" id="2189">2189</a>
<a href="#2190" id="2190">2190</a>
<a href="#2191" id="2191">2191</a>
<a href="#2192" id="2192">2192</a>
<a href="#2193" id="2193">2193</a>
<a href="#2194" id="2194">2194</a>
<a href="#2195" id="2195">2195</a>
<a href="#2196" id="2196">2196</a>
<a href="#2197" id="2197">2197</a>
<a href="#2198" id="2198">2198</a>
<a href="#2199" id="2199">2199</a>
<a href="#2200" id="2200">2200</a>
<a href="#2201" id="2201">2201</a>
<a href="#2202" id="2202">2202</a>
<a href="#2203" id="2203">2203</a>
<a href="#2204" id="2204">2204</a>
<a href="#2205" id="2205">2205</a>
<a href="#2206" id="2206">2206</a>
<a href="#2207" id="2207">2207</a>
<a href="#2208" id="2208">2208</a>
<a href="#2209" id="2209">2209</a>
<a href="#2210" id="2210">2210</a>
<a href="#2211" id="2211">2211</a>
<a href="#2212" id="2212">2212</a>
<a href="#2213" id="2213">2213</a>
<a href="#2214" id="2214">2214</a>
<a href="#2215" id="2215">2215</a>
<a href="#2216" id="2216">2216</a>
<a href="#2217" id="2217">2217</a>
<a href="#2218" id="2218">2218</a>
<a href="#2219" id="2219">2219</a>
<a href="#2220" id="2220">2220</a>
<a href="#2221" id="2221">2221</a>
<a href="#2222" id="2222">2222</a>
<a href="#2223" id="2223">2223</a>
<a href="#2224" id="2224">2224</a>
<a href="#2225" id="2225">2225</a>
<a href="#2226" id="2226">2226</a>
<a href="#2227" id="2227">2227</a>
<a href="#2228" id="2228">2228</a>
<a href="#2229" id="2229">2229</a>
<a href="#2230" id="2230">2230</a>
<a href="#2231" id="2231">2231</a>
<a href="#2232" id="2232">2232</a>
<a href="#2233" id="2233">2233</a>
<a href="#2234" id="2234">2234</a>
<a href="#2235" id="2235">2235</a>
<a href="#2236" id="2236">2236</a>
<a href="#2237" id="2237">2237</a>
<a href="#2238" id="2238">2238</a>
<a href="#2239" id="2239">2239</a>
<a href="#2240" id="2240">2240</a>
<a href="#2241" id="2241">2241</a>
<a href="#2242" id="2242">2242</a>
<a href="#2243" id="2243">2243</a>
<a href="#2244" id="2244">2244</a>
<a href="#2245" id="2245">2245</a>
<a href="#2246" id="2246">2246</a>
<a href="#2247" id="2247">2247</a>
<a href="#2248" id="2248">2248</a>
<a href="#2249" id="2249">2249</a>
<a href="#2250" id="2250">2250</a>
<a href="#2251" id="2251">2251</a>
<a href="#2252" id="2252">2252</a>
<a href="#2253" id="2253">2253</a>
<a href="#2254" id="2254">2254</a>
<a href="#2255" id="2255">2255</a>
<a href="#2256" id="2256">2256</a>
<a href="#2257" id="2257">2257</a>
<a href="#2258" id="2258">2258</a>
<a href="#2259" id="2259">2259</a>
<a href="#2260" id="2260">2260</a>
<a href="#2261" id="2261">2261</a>
<a href="#2262" id="2262">2262</a>
<a href="#2263" id="2263">2263</a>
<a href="#2264" id="2264">2264</a>
<a href="#2265" id="2265">2265</a>
<a href="#2266" id="2266">2266</a>
<a href="#2267" id="2267">2267</a>
<a href="#2268" id="2268">2268</a>
<a href="#2269" id="2269">2269</a>
<a href="#2270" id="2270">2270</a>
<a href="#2271" id="2271">2271</a>
<a href="#2272" id="2272">2272</a>
<a href="#2273" id="2273">2273</a>
<a href="#2274" id="2274">2274</a>
<a href="#2275" id="2275">2275</a>
<a href="#2276" id="2276">2276</a>
<a href="#2277" id="2277">2277</a>
<a href="#2278" id="2278">2278</a>
<a href="#2279" id="2279">2279</a>
<a href="#2280" id="2280">2280</a>
<a href="#2281" id="2281">2281</a>
<a href="#2282" id="2282">2282</a>
<a href="#2283" id="2283">2283</a>
<a href="#2284" id="2284">2284</a>
<a href="#2285" id="2285">2285</a>
<a href="#2286" id="2286">2286</a>
<a href="#2287" id="2287">2287</a>
<a href="#2288" id="2288">2288</a>
<a href="#2289" id="2289">2289</a>
<a href="#2290" id="2290">2290</a>
<a href="#2291" id="2291">2291</a>
<a href="#2292" id="2292">2292</a>
<a href="#2293" id="2293">2293</a>
<a href="#2294" id="2294">2294</a>
<a href="#2295" id="2295">2295</a>
<a href="#2296" id="2296">2296</a>
<a href="#2297" id="2297">2297</a>
<a href="#2298" id="2298">2298</a>
<a href="#2299" id="2299">2299</a>
<a href="#2300" id="2300">2300</a>
<a href="#2301" id="2301">2301</a>
<a href="#2302" id="2302">2302</a>
<a href="#2303" id="2303">2303</a>
<a href="#2304" id="2304">2304</a>
<a href="#2305" id="2305">2305</a>
<a href="#2306" id="2306">2306</a>
<a href="#2307" id="2307">2307</a>
<a href="#2308" id="2308">2308</a>
<a href="#2309" id="2309">2309</a>
<a href="#2310" id="2310">2310</a>
<a href="#2311" id="2311">2311</a>
<a href="#2312" id="2312">2312</a>
<a href="#2313" id="2313">2313</a>
<a href="#2314" id="2314">2314</a>
<a href="#2315" id="2315">2315</a>
<a href="#2316" id="2316">2316</a>
<a href="#2317" id="2317">2317</a>
<a href="#2318" id="2318">2318</a>
<a href="#2319" id="2319">2319</a>
<a href="#2320" id="2320">2320</a>
<a href="#2321" id="2321">2321</a>
<a href="#2322" id="2322">2322</a>
<a href="#2323" id="2323">2323</a>
<a href="#2324" id="2324">2324</a>
<a href="#2325" id="2325">2325</a>
<a href="#2326" id="2326">2326</a>
<a href="#2327" id="2327">2327</a>
<a href="#2328" id="2328">2328</a>
<a href="#2329" id="2329">2329</a>
<a href="#2330" id="2330">2330</a>
<a href="#2331" id="2331">2331</a>
<a href="#2332" id="2332">2332</a>
<a href="#2333" id="2333">2333</a>
<a href="#2334" id="2334">2334</a>
<a href="#2335" id="2335">2335</a>
<a href="#2336" id="2336">2336</a>
<a href="#2337" id="2337">2337</a>
<a href="#2338" id="2338">2338</a>
<a href="#2339" id="2339">2339</a>
<a href="#2340" id="2340">2340</a>
<a href="#2341" id="2341">2341</a>
<a href="#2342" id="2342">2342</a>
<a href="#2343" id="2343">2343</a>
<a href="#2344" id="2344">2344</a>
<a href="#2345" id="2345">2345</a>
<a href="#2346" id="2346">2346</a>
<a href="#2347" id="2347">2347</a>
<a href="#2348" id="2348">2348</a>
<a href="#2349" id="2349">2349</a>
<a href="#2350" id="2350">2350</a>
<a href="#2351" id="2351">2351</a>
<a href="#2352" id="2352">2352</a>
<a href="#2353" id="2353">2353</a>
<a href="#2354" id="2354">2354</a>
<a href="#2355" id="2355">2355</a>
<a href="#2356" id="2356">2356</a>
<a href="#2357" id="2357">2357</a>
<a href="#2358" id="2358">2358</a>
<a href="#2359" id="2359">2359</a>
<a href="#2360" id="2360">2360</a>
<a href="#2361" id="2361">2361</a>
<a href="#2362" id="2362">2362</a>
<a href="#2363" id="2363">2363</a>
<a href="#2364" id="2364">2364</a>
<a href="#2365" id="2365">2365</a>
<a href="#2366" id="2366">2366</a>
<a href="#2367" id="2367">2367</a>
<a href="#2368" id="2368">2368</a>
<a href="#2369" id="2369">2369</a>
<a href="#2370" id="2370">2370</a>
<a href="#2371" id="2371">2371</a>
<a href="#2372" id="2372">2372</a>
<a href="#2373" id="2373">2373</a>
<a href="#2374" id="2374">2374</a>
<a href="#2375" id="2375">2375</a>
<a href="#2376" id="2376">2376</a>
<a href="#2377" id="2377">2377</a>
<a href="#2378" id="2378">2378</a>
<a href="#2379" id="2379">2379</a>
<a href="#2380" id="2380">2380</a>
<a href="#2381" id="2381">2381</a>
<a href="#2382" id="2382">2382</a>
<a href="#2383" id="2383">2383</a>
<a href="#2384" id="2384">2384</a>
<a href="#2385" id="2385">2385</a>
<a href="#2386" id="2386">2386</a>
<a href="#2387" id="2387">2387</a>
<a href="#2388" id="2388">2388</a>
<a href="#2389" id="2389">2389</a>
<a href="#2390" id="2390">2390</a>
<a href="#2391" id="2391">2391</a>
<a href="#2392" id="2392">2392</a>
<a href="#2393" id="2393">2393</a>
<a href="#2394" id="2394">2394</a>
<a href="#2395" id="2395">2395</a>
<a href="#2396" id="2396">2396</a>
<a href="#2397" id="2397">2397</a>
<a href="#2398" id="2398">2398</a>
<a href="#2399" id="2399">2399</a>
<a href="#2400" id="2400">2400</a>
<a href="#2401" id="2401">2401</a>
<a href="#2402" id="2402">2402</a>
<a href="#2403" id="2403">2403</a>
<a href="#2404" id="2404">2404</a>
<a href="#2405" id="2405">2405</a>
<a href="#2406" id="2406">2406</a>
<a href="#2407" id="2407">2407</a>
<a href="#2408" id="2408">2408</a>
<a href="#2409" id="2409">2409</a>
<a href="#2410" id="2410">2410</a>
<a href="#2411" id="2411">2411</a>
<a href="#2412" id="2412">2412</a>
<a href="#2413" id="2413">2413</a>
<a href="#2414" id="2414">2414</a>
<a href="#2415" id="2415">2415</a>
<a href="#2416" id="2416">2416</a>
<a href="#2417" id="2417">2417</a>
<a href="#2418" id="2418">2418</a>
<a href="#2419" id="2419">2419</a>
<a href="#2420" id="2420">2420</a>
<a href="#2421" id="2421">2421</a>
<a href="#2422" id="2422">2422</a>
<a href="#2423" id="2423">2423</a>
<a href="#2424" id="2424">2424</a>
<a href="#2425" id="2425">2425</a>
<a href="#2426" id="2426">2426</a>
<a href="#2427" id="2427">2427</a>
<a href="#2428" id="2428">2428</a>
<a href="#2429" id="2429">2429</a>
<a href="#2430" id="2430">2430</a>
<a href="#2431" id="2431">2431</a>
<a href="#2432" id="2432">2432</a>
<a href="#2433" id="2433">2433</a>
<a href="#2434" id="2434">2434</a>
<a href="#2435" id="2435">2435</a>
<a href="#2436" id="2436">2436</a>
<a href="#2437" id="2437">2437</a>
<a href="#2438" id="2438">2438</a>
<a href="#2439" id="2439">2439</a>
<a href="#2440" id="2440">2440</a>
<a href="#2441" id="2441">2441</a>
<a href="#2442" id="2442">2442</a>
<a href="#2443" id="2443">2443</a>
<a href="#2444" id="2444">2444</a>
<a href="#2445" id="2445">2445</a>
<a href="#2446" id="2446">2446</a>
<a href="#2447" id="2447">2447</a>
<a href="#2448" id="2448">2448</a>
<a href="#2449" id="2449">2449</a>
<a href="#2450" id="2450">2450</a>
<a href="#2451" id="2451">2451</a>
<a href="#2452" id="2452">2452</a>
<a href="#2453" id="2453">2453</a>
<a href="#2454" id="2454">2454</a>
<a href="#2455" id="2455">2455</a>
<a href="#2456" id="2456">2456</a>
<a href="#2457" id="2457">2457</a>
<a href="#2458" id="2458">2458</a>
<a href="#2459" id="2459">2459</a>
<a href="#2460" id="2460">2460</a>
<a href="#2461" id="2461">2461</a>
<a href="#2462" id="2462">2462</a>
<a href="#2463" id="2463">2463</a>
<a href="#2464" id="2464">2464</a>
<a href="#2465" id="2465">2465</a>
<a href="#2466" id="2466">2466</a>
<a href="#2467" id="2467">2467</a>
<a href="#2468" id="2468">2468</a>
<a href="#2469" id="2469">2469</a>
<a href="#2470" id="2470">2470</a>
<a href="#2471" id="2471">2471</a>
<a href="#2472" id="2472">2472</a>
<a href="#2473" id="2473">2473</a>
<a href="#2474" id="2474">2474</a>
<a href="#2475" id="2475">2475</a>
<a href="#2476" id="2476">2476</a>
<a href="#2477" id="2477">2477</a>
<a href="#2478" id="2478">2478</a>
<a href="#2479" id="2479">2479</a>
<a href="#2480" id="2480">2480</a>
<a href="#2481" id="2481">2481</a>
<a href="#2482" id="2482">2482</a>
<a href="#2483" id="2483">2483</a>
<a href="#2484" id="2484">2484</a>
<a href="#2485" id="2485">2485</a>
<a href="#2486" id="2486">2486</a>
<a href="#2487" id="2487">2487</a>
<a href="#2488" id="2488">2488</a>
<a href="#2489" id="2489">2489</a>
<a href="#2490" id="2490">2490</a>
<a href="#2491" id="2491">2491</a>
<a href="#2492" id="2492">2492</a>
<a href="#2493" id="2493">2493</a>
<a href="#2494" id="2494">2494</a>
<a href="#2495" id="2495">2495</a>
<a href="#2496" id="2496">2496</a>
<a href="#2497" id="2497">2497</a>
<a href="#2498" id="2498">2498</a>
<a href="#2499" id="2499">2499</a>
<a href="#2500" id="2500">2500</a>
<a href="#2501" id="2501">2501</a>
<a href="#2502" id="2502">2502</a>
<a href="#2503" id="2503">2503</a>
<a href="#2504" id="2504">2504</a>
<a href="#2505" id="2505">2505</a>
<a href="#2506" id="2506">2506</a>
<a href="#2507" id="2507">2507</a>
<a href="#2508" id="2508">2508</a>
<a href="#2509" id="2509">2509</a>
<a href="#2510" id="2510">2510</a>
<a href="#2511" id="2511">2511</a>
<a href="#2512" id="2512">2512</a>
<a href="#2513" id="2513">2513</a>
<a href="#2514" id="2514">2514</a>
<a href="#2515" id="2515">2515</a>
<a href="#2516" id="2516">2516</a>
<a href="#2517" id="2517">2517</a>
<a href="#2518" id="2518">2518</a>
<a href="#2519" id="2519">2519</a>
<a href="#2520" id="2520">2520</a>
<a href="#2521" id="2521">2521</a>
<a href="#2522" id="2522">2522</a>
<a href="#2523" id="2523">2523</a>
<a href="#2524" id="2524">2524</a>
<a href="#2525" id="2525">2525</a>
<a href="#2526" id="2526">2526</a>
<a href="#2527" id="2527">2527</a>
<a href="#2528" id="2528">2528</a>
<a href="#2529" id="2529">2529</a>
<a href="#2530" id="2530">2530</a>
<a href="#2531" id="2531">2531</a>
<a href="#2532" id="2532">2532</a>
<a href="#2533" id="2533">2533</a>
<a href="#2534" id="2534">2534</a>
<a href="#2535" id="2535">2535</a>
<a href="#2536" id="2536">2536</a>
<a href="#2537" id="2537">2537</a>
<a href="#2538" id="2538">2538</a>
<a href="#2539" id="2539">2539</a>
<a href="#2540" id="2540">2540</a>
<a href="#2541" id="2541">2541</a>
<a href="#2542" id="2542">2542</a>
<a href="#2543" id="2543">2543</a>
<a href="#2544" id="2544">2544</a>
<a href="#2545" id="2545">2545</a>
<a href="#2546" id="2546">2546</a>
<a href="#2547" id="2547">2547</a>
<a href="#2548" id="2548">2548</a>
<a href="#2549" id="2549">2549</a>
<a href="#2550" id="2550">2550</a>
<a href="#2551" id="2551">2551</a>
<a href="#2552" id="2552">2552</a>
<a href="#2553" id="2553">2553</a>
<a href="#2554" id="2554">2554</a>
<a href="#2555" id="2555">2555</a>
<a href="#2556" id="2556">2556</a>
<a href="#2557" id="2557">2557</a>
<a href="#2558" id="2558">2558</a>
<a href="#2559" id="2559">2559</a>
<a href="#2560" id="2560">2560</a>
<a href="#2561" id="2561">2561</a>
<a href="#2562" id="2562">2562</a>
<a href="#2563" id="2563">2563</a>
<a href="#2564" id="2564">2564</a>
<a href="#2565" id="2565">2565</a>
<a href="#2566" id="2566">2566</a>
<a href="#2567" id="2567">2567</a>
<a href="#2568" id="2568">2568</a>
<a href="#2569" id="2569">2569</a>
<a href="#2570" id="2570">2570</a>
<a href="#2571" id="2571">2571</a>
<a href="#2572" id="2572">2572</a>
<a href="#2573" id="2573">2573</a>
<a href="#2574" id="2574">2574</a>
<a href="#2575" id="2575">2575</a>
<a href="#2576" id="2576">2576</a>
<a href="#2577" id="2577">2577</a>
<a href="#2578" id="2578">2578</a>
<a href="#2579" id="2579">2579</a>
<a href="#2580" id="2580">2580</a>
<a href="#2581" id="2581">2581</a>
<a href="#2582" id="2582">2582</a>
<a href="#2583" id="2583">2583</a>
<a href="#2584" id="2584">2584</a>
<a href="#2585" id="2585">2585</a>
<a href="#2586" id="2586">2586</a>
<a href="#2587" id="2587">2587</a>
<a href="#2588" id="2588">2588</a>
<a href="#2589" id="2589">2589</a>
<a href="#2590" id="2590">2590</a>
<a href="#2591" id="2591">2591</a>
<a href="#2592" id="2592">2592</a>
<a href="#2593" id="2593">2593</a>
<a href="#2594" id="2594">2594</a>
<a href="#2595" id="2595">2595</a>
<a href="#2596" id="2596">2596</a>
<a href="#2597" id="2597">2597</a>
<a href="#2598" id="2598">2598</a>
<a href="#2599" id="2599">2599</a>
<a href="#2600" id="2600">2600</a>
<a href="#2601" id="2601">2601</a>
<a href="#2602" id="2602">2602</a>
<a href="#2603" id="2603">2603</a>
<a href="#2604" id="2604">2604</a>
<a href="#2605" id="2605">2605</a>
<a href="#2606" id="2606">2606</a>
<a href="#2607" id="2607">2607</a>
<a href="#2608" id="2608">2608</a>
<a href="#2609" id="2609">2609</a>
<a href="#2610" id="2610">2610</a>
<a href="#2611" id="2611">2611</a>
<a href="#2612" id="2612">2612</a>
<a href="#2613" id="2613">2613</a>
<a href="#2614" id="2614">2614</a>
<a href="#2615" id="2615">2615</a>
<a href="#2616" id="2616">2616</a>
<a href="#2617" id="2617">2617</a>
<a href="#2618" id="2618">2618</a>
<a href="#2619" id="2619">2619</a>
<a href="#2620" id="2620">2620</a>
<a href="#2621" id="2621">2621</a>
<a href="#2622" id="2622">2622</a>
<a href="#2623" id="2623">2623</a>
<a href="#2624" id="2624">2624</a>
<a href="#2625" id="2625">2625</a>
<a href="#2626" id="2626">2626</a>
<a href="#2627" id="2627">2627</a>
<a href="#2628" id="2628">2628</a>
<a href="#2629" id="2629">2629</a>
<a href="#2630" id="2630">2630</a>
<a href="#2631" id="2631">2631</a>
<a href="#2632" id="2632">2632</a>
<a href="#2633" id="2633">2633</a>
<a href="#2634" id="2634">2634</a>
<a href="#2635" id="2635">2635</a>
<a href="#2636" id="2636">2636</a>
<a href="#2637" id="2637">2637</a>
<a href="#2638" id="2638">2638</a>
<a href="#2639" id="2639">2639</a>
<a href="#2640" id="2640">2640</a>
<a href="#2641" id="2641">2641</a>
<a href="#2642" id="2642">2642</a>
<a href="#2643" id="2643">2643</a>
<a href="#2644" id="2644">2644</a>
<a href="#2645" id="2645">2645</a>
<a href="#2646" id="2646">2646</a>
<a href="#2647" id="2647">2647</a>
<a href="#2648" id="2648">2648</a>
<a href="#2649" id="2649">2649</a>
<a href="#2650" id="2650">2650</a>
<a href="#2651" id="2651">2651</a>
<a href="#2652" id="2652">2652</a>
<a href="#2653" id="2653">2653</a>
<a href="#2654" id="2654">2654</a>
<a href="#2655" id="2655">2655</a>
<a href="#2656" id="2656">2656</a>
<a href="#2657" id="2657">2657</a>
<a href="#2658" id="2658">2658</a>
<a href="#2659" id="2659">2659</a>
<a href="#2660" id="2660">2660</a>
<a href="#2661" id="2661">2661</a>
<a href="#2662" id="2662">2662</a>
<a href="#2663" id="2663">2663</a>
<a href="#2664" id="2664">2664</a>
<a href="#2665" id="2665">2665</a>
<a href="#2666" id="2666">2666</a>
<a href="#2667" id="2667">2667</a>
<a href="#2668" id="2668">2668</a>
<a href="#2669" id="2669">2669</a>
<a href="#2670" id="2670">2670</a>
<a href="#2671" id="2671">2671</a>
<a href="#2672" id="2672">2672</a>
<a href="#2673" id="2673">2673</a>
<a href="#2674" id="2674">2674</a>
<a href="#2675" id="2675">2675</a>
<a href="#2676" id="2676">2676</a>
<a href="#2677" id="2677">2677</a>
<a href="#2678" id="2678">2678</a>
<a href="#2679" id="2679">2679</a>
<a href="#2680" id="2680">2680</a>
<a href="#2681" id="2681">2681</a>
<a href="#2682" id="2682">2682</a>
<a href="#2683" id="2683">2683</a>
<a href="#2684" id="2684">2684</a>
<a href="#2685" id="2685">2685</a>
<a href="#2686" id="2686">2686</a>
<a href="#2687" id="2687">2687</a>
<a href="#2688" id="2688">2688</a>
<a href="#2689" id="2689">2689</a>
<a href="#2690" id="2690">2690</a>
<a href="#2691" id="2691">2691</a>
<a href="#2692" id="2692">2692</a>
<a href="#2693" id="2693">2693</a>
<a href="#2694" id="2694">2694</a>
<a href="#2695" id="2695">2695</a>
<a href="#2696" id="2696">2696</a>
<a href="#2697" id="2697">2697</a>
<a href="#2698" id="2698">2698</a>
<a href="#2699" id="2699">2699</a>
<a href="#2700" id="2700">2700</a>
<a href="#2701" id="2701">2701</a>
<a href="#2702" id="2702">2702</a>
<a href="#2703" id="2703">2703</a>
<a href="#2704" id="2704">2704</a>
<a href="#2705" id="2705">2705</a>
<a href="#2706" id="2706">2706</a>
<a href="#2707" id="2707">2707</a>
<a href="#2708" id="2708">2708</a>
<a href="#2709" id="2709">2709</a>
<a href="#2710" id="2710">2710</a>
<a href="#2711" id="2711">2711</a>
<a href="#2712" id="2712">2712</a>
<a href="#2713" id="2713">2713</a>
</pre></div><pre class="rust"><code><span class="kw">use </span>anchor_client::ClientError::AnchorError;
<span class="kw">use </span>std::ops::Deref;
<span class="kw">use </span>std::str::FromStr;
<span class="kw">use </span>std::sync::Arc;
<span class="kw">use </span>std::time::Duration;
<span class="kw">use </span>anchor_client::Cluster;
<span class="kw">use </span>anchor_lang::__private::bytemuck;
<span class="kw">use </span>anchor_lang::prelude::System;
<span class="kw">use </span>anchor_lang::{AccountDeserialize, AnchorDeserialize, Id};
<span class="kw">use </span>anchor_spl::associated_token::get_associated_token_address;
<span class="kw">use </span>anchor_spl::token::Token;
<span class="kw">use </span>fixed::types::I80F48;
<span class="kw">use </span>futures::{stream, StreamExt, TryFutureExt, TryStreamExt};
<span class="kw">use </span>itertools::Itertools;
<span class="kw">use </span>tracing::<span class="kw-2">*</span>;
<span class="kw">use </span>mango_v4::accounts_ix::{
HealthCheckKind, Serum3OrderType, Serum3SelfTradeBehavior, Serum3Side,
};
<span class="kw">use </span>mango_v4::accounts_zerocopy::KeyedAccountSharedData;
<span class="kw">use </span>mango_v4::health::HealthCache;
<span class="kw">use </span>mango_v4::state::{
Bank, Group, MangoAccountValue, OpenbookV2MarketIndex, OracleAccountInfos, PerpMarket,
PerpMarketIndex, PlaceOrderType, SelfTradeBehavior, Serum3MarketIndex, Side, TokenIndex,
};
<span class="kw">use </span><span class="kw">crate</span>::confirm_transaction::{wait_for_transaction_confirmation, RpcConfirmTransactionConfig};
<span class="kw">use </span><span class="kw">crate</span>::context::MangoGroupContext;
<span class="kw">use </span><span class="kw">crate</span>::gpa::{fetch_anchor_account, fetch_mango_accounts};
<span class="kw">use </span><span class="kw">crate</span>::priority_fees::{FixedPriorityFeeProvider, PriorityFeeProvider};
<span class="kw">use </span><span class="kw">crate</span>::util;
<span class="kw">use </span><span class="kw">crate</span>::util::PreparedInstructions;
<span class="kw">use crate</span>::{account_fetcher::<span class="kw-2">*</span>, swap};
<span class="kw">use crate</span>::{health_cache, Serum3MarketContext, TokenContext};
<span class="kw">use </span>solana_address_lookup_table_program::state::AddressLookupTable;
<span class="kw">use </span>solana_client::nonblocking::rpc_client::RpcClient <span class="kw">as </span>RpcClientAsync;
<span class="kw">use </span>solana_client::rpc_client::SerializableTransaction;
<span class="kw">use </span>solana_client::rpc_config::RpcSendTransactionConfig;
<span class="kw">use </span>solana_client::rpc_response::RpcSimulateTransactionResult;
<span class="kw">use </span>solana_sdk::address_lookup_table_account::AddressLookupTableAccount;
<span class="kw">use </span>solana_sdk::commitment_config::CommitmentLevel;
<span class="kw">use </span>solana_sdk::compute_budget::ComputeBudgetInstruction;
<span class="kw">use </span>solana_sdk::hash::Hash;
<span class="kw">use </span>solana_sdk::signer::keypair;
<span class="kw">use </span>solana_sdk::transaction::TransactionError;
<span class="kw">use </span>anyhow::Context;
<span class="kw">use </span>mango_v4::error::{IsAnchorErrorWithCode, MangoError};
<span class="kw">use </span>solana_sdk::account::ReadableAccount;
<span class="kw">use </span>solana_sdk::instruction::{AccountMeta, Instruction};
<span class="kw">use </span>solana_sdk::signature::{Keypair, Signature};
<span class="kw">use </span>solana_sdk::sysvar;
<span class="kw">use </span>solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, signer::Signer};
<span class="kw">pub const </span>MAX_ACCOUNTS_PER_TRANSACTION: usize = <span class="number">64</span>;
<span class="comment">// very close to anchor_client::Client, which unfortunately has no accessors or Clone
</span><span class="attr">#[derive(Clone, Builder)]
#[builder(name = <span class="string">&quot;ClientBuilder&quot;</span>, build_fn(name = <span class="string">&quot;build_config&quot;</span>))]
</span><span class="kw">pub struct </span>ClientConfig {
<span class="doccomment">/// RPC url
///
/// Defaults to Cluster::Mainnet, using the public crowded mainnet-beta rpc endpoint.
/// Should usually be overridden with a custom rpc endpoint.
</span><span class="attr">#[builder(default = <span class="string">&quot;Cluster::Mainnet&quot;</span>)]
</span><span class="kw">pub </span>cluster: Cluster,
<span class="doccomment">/// Transaction fee payer. Needs to be set to send transactions.
</span><span class="kw">pub </span>fee_payer: <span class="prelude-ty">Option</span>&lt;Arc&lt;Keypair&gt;&gt;,
<span class="doccomment">/// Commitment for interacting with the chain. Defaults to processed.
</span><span class="attr">#[builder(default = <span class="string">&quot;CommitmentConfig::processed()&quot;</span>)]
</span><span class="kw">pub </span>commitment: CommitmentConfig,
<span class="doccomment">/// Timeout, defaults to 60s
///
/// This timeout applies to rpc requests. Note that the timeout for transaction
/// confirmation is configured separately in rpc_confirm_transaction_config.
</span><span class="attr">#[builder(default = <span class="string">&quot;Duration::from_secs(60)&quot;</span>)]
</span><span class="kw">pub </span>timeout: Duration,
<span class="doccomment">/// Jupiter Timeout, defaults to 30s
///
/// This timeout applies to jupiter requests.
</span><span class="attr">#[builder(default = <span class="string">&quot;Duration::from_secs(30)&quot;</span>)]
</span><span class="kw">pub </span>jupiter_timeout: Duration,
<span class="attr">#[builder(default)]
</span><span class="kw">pub </span>transaction_builder_config: TransactionBuilderConfig,
<span class="doccomment">/// Defaults to a preflight check at processed commitment
</span><span class="attr">#[builder(default = <span class="string">&quot;ClientBuilder::default_rpc_send_transaction_config()&quot;</span>)]
</span><span class="kw">pub </span>rpc_send_transaction_config: RpcSendTransactionConfig,
<span class="doccomment">/// Defaults to waiting up to 60s for confirmation
</span><span class="attr">#[builder(default = <span class="string">&quot;ClientBuilder::default_rpc_confirm_transaction_config()&quot;</span>)]
</span><span class="kw">pub </span>rpc_confirm_transaction_config: RpcConfirmTransactionConfig,
<span class="attr">#[builder(default = <span class="string">&quot;\&quot;https://quote-api.jup.ag/v6\&quot;.into()&quot;</span>)]
</span><span class="kw">pub </span>jupiter_v6_url: String,
<span class="attr">#[builder(default = <span class="string">&quot;\&quot;\&quot;.into()&quot;</span>)]
</span><span class="kw">pub </span>jupiter_token: String,
<span class="attr">#[builder(default = <span class="string">&quot;\&quot;https://api.sanctum.so/v1\&quot;.into()&quot;</span>)]
</span><span class="kw">pub </span>sanctum_url: String,
<span class="doccomment">/// Sanctum Timeout, defaults to 30s
///
/// This timeout applies to jupiter requests.
</span><span class="attr">#[builder(default = <span class="string">&quot;Duration::from_secs(30)&quot;</span>)]
</span><span class="kw">pub </span>sanctum_timeout: Duration,
<span class="doccomment">/// Determines how fallback oracle accounts are provided to instructions. Defaults to Dynamic.
</span><span class="attr">#[builder(default = <span class="string">&quot;FallbackOracleConfig::Dynamic&quot;</span>)]
</span><span class="kw">pub </span>fallback_oracle_config: FallbackOracleConfig,
<span class="doccomment">/// If set, don&#39;t use `cluster` for sending transactions and send to all
/// addresses configured here instead.
</span><span class="attr">#[builder(default = <span class="string">&quot;None&quot;</span>)]
</span><span class="kw">pub </span>override_send_transaction_urls: <span class="prelude-ty">Option</span>&lt;Vec&lt;String&gt;&gt;,
}
<span class="kw">impl </span>ClientBuilder {
<span class="kw">pub fn </span>build(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Result</span>&lt;Client, ClientBuilderError&gt; {
<span class="kw">let </span>config = <span class="self">self</span>.build_config()<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(Client::new_from_config(config))
}
<span class="kw">pub fn </span>default_rpc_send_transaction_config() -&gt; RpcSendTransactionConfig {
RpcSendTransactionConfig {
preflight_commitment: <span class="prelude-val">Some</span>(CommitmentLevel::Processed),
..Default::default()
}
}
<span class="kw">pub fn </span>default_rpc_confirm_transaction_config() -&gt; RpcConfirmTransactionConfig {
RpcConfirmTransactionConfig {
timeout: <span class="prelude-val">Some</span>(Duration::from_secs(<span class="number">60</span>)),
..Default::default()
}
}
}
<span class="kw">pub struct </span>Client {
config: ClientConfig,
rpc_async: RpcClientAsync,
send_transaction_rpc_asyncs: Vec&lt;RpcClientAsync&gt;,
}
<span class="kw">impl </span>Client {
<span class="kw">pub fn </span>builder() -&gt; ClientBuilder {
ClientBuilder::default()
}
<span class="doccomment">/// Prefer using the builder()
</span><span class="kw">pub fn </span>new(
cluster: Cluster,
commitment: CommitmentConfig,
fee_payer: Arc&lt;Keypair&gt;,
timeout: <span class="prelude-ty">Option</span>&lt;Duration&gt;,
transaction_builder_config: TransactionBuilderConfig,
) -&gt; <span class="self">Self </span>{
<span class="self">Self</span>::builder()
.cluster(cluster)
.commitment(commitment)
.fee_payer(<span class="prelude-val">Some</span>(fee_payer))
.timeout(timeout.unwrap_or(Duration::from_secs(<span class="number">30</span>)))
.transaction_builder_config(transaction_builder_config)
.build()
.unwrap()
}
<span class="kw">pub fn </span>new_from_config(config: ClientConfig) -&gt; <span class="self">Self </span>{
<span class="self">Self </span>{
rpc_async: RpcClientAsync::new_with_timeout_and_commitment(
config.cluster.url().to_string(),
config.timeout,
config.commitment,
),
send_transaction_rpc_asyncs: config
.override_send_transaction_urls
.clone()
.unwrap_or_else(|| <span class="macro">vec!</span>[config.cluster.url().to_string()])
.into_iter()
.map(|url| {
RpcClientAsync::new_with_timeout_and_commitment(
url,
config.timeout,
config.commitment,
)
})
.collect_vec(),
config,
}
}
<span class="kw">pub fn </span>config(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ClientConfig {
<span class="kw-2">&amp;</span><span class="self">self</span>.config
}
<span class="kw">pub fn </span>rpc_async(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>RpcClientAsync {
<span class="kw-2">&amp;</span><span class="self">self</span>.rpc_async
}
<span class="doccomment">/// Sometimes clients don&#39;t want to borrow the Client instance and just pass on RpcClientAsync
</span><span class="kw">pub fn </span>new_rpc_async(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; RpcClientAsync {
<span class="kw">let </span>url = <span class="self">self</span>.config.cluster.url().to_string();
RpcClientAsync::new_with_timeout_and_commitment(
url,
<span class="self">self</span>.config.timeout,
<span class="self">self</span>.config.commitment,
)
}
<span class="comment">// TODO: this function here is awkward, since it (intentionally) doesn&#39;t use MangoClient::account_fetcher
</span><span class="kw">pub async fn </span>rpc_anchor_account&lt;T: AccountDeserialize&gt;(
<span class="kw-2">&amp;</span><span class="self">self</span>,
address: <span class="kw-2">&amp;</span>Pubkey,
) -&gt; anyhow::Result&lt;T&gt; {
fetch_anchor_account(<span class="self">self</span>.rpc_async(), address).<span class="kw">await
</span>}
<span class="kw">pub fn </span>fee_payer(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Arc&lt;Keypair&gt; {
<span class="self">self</span>.config
.fee_payer
.as_ref()
.expect(<span class="string">&quot;fee payer must be set&quot;</span>)
.clone()
}
<span class="doccomment">/// Sends a transaction via the configured cluster (or all override_send_transaction_urls).
///
/// Returns the tx signature if at least one send returned ok.
/// Note that a success does not mean that the transaction is confirmed.
</span><span class="kw">pub async fn </span>send_transaction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
tx: <span class="kw-2">&amp;</span><span class="kw">impl </span>SerializableTransaction,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>futures = <span class="self">self</span>.send_transaction_rpc_asyncs.iter().map(|rpc| {
rpc.send_transaction_with_config(tx, <span class="self">self</span>.config.rpc_send_transaction_config)
.map_err(prettify_solana_client_error)
});
<span class="kw">let </span><span class="kw-2">mut </span>results = futures::future::join_all(futures).<span class="kw">await</span>;
<span class="comment">// If all fail, return the first
</span><span class="kw">let </span>successful_sends = results.iter().filter(|r| r.is_ok()).count();
<span class="kw">if </span>successful_sends == <span class="number">0 </span>{
results.remove(<span class="number">0</span>)<span class="question-mark">?</span>;
}
<span class="comment">// Otherwise just log errors
</span><span class="kw">for </span>(result, rpc) <span class="kw">in </span>results.iter().zip(<span class="self">self</span>.send_transaction_rpc_asyncs.iter()) {
<span class="kw">if let </span><span class="prelude-val">Err</span>(err) = result {
<span class="macro">info!</span>(
rpc = rpc.url(),
successful_sends, <span class="string">&quot;one of the transaction sends failed: {err:?}&quot;</span>,
)
}
}
<span class="kw">return </span><span class="prelude-val">Ok</span>(<span class="kw-2">*</span>tx.get_signature());
}
}
<span class="comment">// todo: might want to integrate geyser, websockets, or simple http polling for keeping data fresh
</span><span class="kw">pub struct </span>MangoClient {
<span class="kw">pub </span>client: Client,
<span class="comment">// todo: possibly this object should have cache-functions, so there can be one getMultipleAccounts
// call to refresh banks etc -- if it&#39;s backed by websockets, these could just do nothing
</span><span class="kw">pub </span>account_fetcher: Arc&lt;<span class="kw">dyn </span>AccountFetcher&gt;,
<span class="kw">pub </span>authority: Arc&lt;Keypair&gt;,
<span class="kw">pub </span>mango_account_address: Pubkey,
<span class="kw">pub </span>context: MangoGroupContext,
<span class="kw">pub </span>http_client: reqwest::Client,
}
<span class="comment">// TODO: add retry framework for sending tx and rpc calls
// 1/ this works right now, but I think mid-term the MangoClient will want to interact with multiple mango accounts
// -- then we should probably specify accounts by owner+account_num / or pubkey
// 2/ pubkey, can be both owned, but also delegated accouns
</span><span class="kw">impl </span>MangoClient {
<span class="kw">pub fn </span>group_for_admin(admin: Pubkey, num: u32) -&gt; Pubkey {
Pubkey::find_program_address(
<span class="kw-2">&amp;</span>[<span class="string">&quot;Group&quot;</span>.as_ref(), admin.as_ref(), num.to_le_bytes().as_ref()],
<span class="kw-2">&amp;</span>mango_v4::ID,
)
.<span class="number">0
</span>}
<span class="kw">pub async fn </span>find_accounts(
client: <span class="kw-2">&amp;</span>Client,
group: Pubkey,
owner: <span class="kw-2">&amp;</span>Keypair,
) -&gt; anyhow::Result&lt;Vec&lt;(Pubkey, MangoAccountValue)&gt;&gt; {
fetch_mango_accounts(client.rpc_async(), mango_v4::ID, group, owner.pubkey()).<span class="kw">await
</span>}
<span class="kw">pub async fn </span>find_or_create_account(
client: <span class="kw-2">&amp;</span>Client,
group: Pubkey,
owner: Arc&lt;Keypair&gt;,
payer: Arc&lt;Keypair&gt;, <span class="comment">// pays the SOL for the new account
</span>mango_account_name: <span class="kw-2">&amp;</span>str,
) -&gt; anyhow::Result&lt;Pubkey&gt; {
<span class="kw">let </span>rpc = client.rpc_async();
<span class="kw">let </span>program = mango_v4::ID;
<span class="kw">let </span>owner_pk = owner.pubkey();
<span class="comment">// Mango Account
</span><span class="kw">let </span><span class="kw-2">mut </span>mango_account_tuples = fetch_mango_accounts(<span class="kw-2">&amp;</span>rpc, program, group, owner_pk).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>mango_account_opt = mango_account_tuples
.iter()
.find(|(<span class="kw">_</span>, account)| account.fixed.name() == mango_account_name);
<span class="kw">if </span>mango_account_opt.is_none() {
mango_account_tuples.sort_by(|a, b| {
a.<span class="number">1</span>.fixed
.account_num
.partial_cmp(<span class="kw-2">&amp;</span>b.<span class="number">1</span>.fixed.account_num)
.unwrap()
});
<span class="kw">let </span>account_num = <span class="kw">match </span>mango_account_tuples.last() {
<span class="prelude-val">Some</span>(tuple) =&gt; tuple.<span class="number">1</span>.fixed.account_num + <span class="number">1</span>,
<span class="prelude-val">None </span>=&gt; <span class="number">0u32</span>,
};
<span class="self">Self</span>::create_account(
client,
group,
owner.clone(),
payer,
account_num,
mango_account_name,
)
.<span class="kw">await
</span>.context(<span class="string">&quot;Failed to create account...&quot;</span>)<span class="question-mark">?</span>;
}
<span class="kw">let </span>mango_account_tuples = fetch_mango_accounts(<span class="kw-2">&amp;</span>rpc, program, group, owner_pk).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>index = mango_account_tuples
.iter()
.position(|tuple| tuple.<span class="number">1</span>.fixed.name() == mango_account_name)
.unwrap();
<span class="prelude-val">Ok</span>(mango_account_tuples[index].<span class="number">0</span>)
}
<span class="kw">pub async fn </span>create_account(
client: <span class="kw-2">&amp;</span>Client,
group: Pubkey,
owner: Arc&lt;Keypair&gt;,
payer: Arc&lt;Keypair&gt;, <span class="comment">// pays the SOL for the new account
</span>account_num: u32,
mango_account_name: <span class="kw-2">&amp;</span>str,
) -&gt; anyhow::Result&lt;(Pubkey, Signature)&gt; {
<span class="kw">let </span>account = Pubkey::find_program_address(
<span class="kw-2">&amp;</span>[
<span class="string">b&quot;MangoAccount&quot;</span>.as_ref(),
group.as_ref(),
owner.pubkey().as_ref(),
<span class="kw-2">&amp;</span>account_num.to_le_bytes(),
],
<span class="kw-2">&amp;</span>mango_v4::id(),
)
.<span class="number">0</span>;
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::AccountCreate {
group,
owner: owner.pubkey(),
account,
payer: payer.pubkey(),
system_program: System::id(),
},
<span class="prelude-val">None</span>,
),
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::AccountCreate {
account_num,
name: mango_account_name.to_owned(),
token_count: <span class="number">8</span>,
serum3_count: <span class="number">4</span>,
perp_count: <span class="number">4</span>,
perp_oo_count: <span class="number">8</span>,
}),
};
<span class="kw">let </span>txsig = TransactionBuilder {
instructions: <span class="macro">vec!</span>[ix],
address_lookup_tables: <span class="macro">vec!</span>[],
payer: payer.pubkey(),
signers: <span class="macro">vec!</span>[owner, payer],
config: client.config.transaction_builder_config.clone(),
}
.send_and_confirm(<span class="kw-2">&amp;</span>client)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>((account, txsig))
}
<span class="doccomment">/// Conveniently creates a RPC based client
</span><span class="kw">pub async fn </span>new_for_existing_account(
client: Client,
account: Pubkey,
authority: Arc&lt;Keypair&gt;,
) -&gt; anyhow::Result&lt;<span class="self">Self</span>&gt; {
<span class="kw">let </span>rpc = client.new_rpc_async();
<span class="kw">let </span>account_fetcher = Arc::new(CachedAccountFetcher::new(Arc::new(RpcAccountFetcher {
rpc,
})));
<span class="kw">let </span>mango_account =
account_fetcher_fetch_mango_account(<span class="kw-2">&amp;*</span>account_fetcher, <span class="kw-2">&amp;</span>account).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>group = mango_account.fixed.group;
<span class="kw">if </span>mango_account.fixed.owner != authority.pubkey() {
<span class="macro">anyhow::bail!</span>(
<span class="string">&quot;bad owner for account: expected {} got {}&quot;</span>,
mango_account.fixed.owner,
authority.pubkey()
);
}
<span class="kw">let </span>rpc = client.rpc_async();
<span class="kw">let </span>group_context = MangoGroupContext::new_from_rpc(<span class="kw-2">&amp;</span>rpc, group).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">Self</span>::new_detail(client, account, authority, group_context, account_fetcher)
}
<span class="doccomment">/// Allows control of AccountFetcher and externally created MangoGroupContext
</span><span class="kw">pub fn </span>new_detail(
client: Client,
account: Pubkey,
authority: Arc&lt;Keypair&gt;,
<span class="comment">// future: maybe pass Arc&lt;MangoGroupContext&gt;, so it can be extenally updated?
</span>group_context: MangoGroupContext,
account_fetcher: Arc&lt;<span class="kw">dyn </span>AccountFetcher&gt;,
) -&gt; anyhow::Result&lt;<span class="self">Self</span>&gt; {
<span class="prelude-val">Ok</span>(<span class="self">Self </span>{
client,
account_fetcher,
authority,
mango_account_address: account,
context: group_context,
http_client: reqwest::Client::new(),
})
}
<span class="kw">pub fn </span>authority(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Pubkey {
<span class="self">self</span>.authority.pubkey()
}
<span class="kw">pub fn </span>group(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Pubkey {
<span class="self">self</span>.context.group
}
<span class="kw">pub async fn </span>mango_account(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; anyhow::Result&lt;MangoAccountValue&gt; {
account_fetcher_fetch_mango_account(<span class="kw-2">&amp;*</span><span class="self">self</span>.account_fetcher, <span class="kw-2">&amp;</span><span class="self">self</span>.mango_account_address)
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>first_bank(<span class="kw-2">&amp;</span><span class="self">self</span>, token_index: TokenIndex) -&gt; anyhow::Result&lt;Bank&gt; {
<span class="kw">let </span>bank_address = <span class="self">self</span>.context.token(token_index).first_bank();
account_fetcher_fetch_anchor_account(<span class="kw-2">&amp;*</span><span class="self">self</span>.account_fetcher, <span class="kw-2">&amp;</span>bank_address).<span class="kw">await
</span>}
<span class="kw">pub async fn </span>derive_health_check_remaining_account_metas(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
affected_tokens: Vec&lt;TokenIndex&gt;,
writable_banks: Vec&lt;TokenIndex&gt;,
affected_perp_markets: Vec&lt;PerpMarketIndex&gt;,
) -&gt; anyhow::Result&lt;(Vec&lt;AccountMeta&gt;, u32)&gt; {
<span class="kw">let </span>fallback_contexts = <span class="self">self
</span>.context
.derive_fallback_oracle_keys(
<span class="kw-2">&amp;</span><span class="self">self</span>.client.config.fallback_oracle_config,
<span class="kw-2">&amp;*</span><span class="self">self</span>.account_fetcher,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.context.derive_health_check_remaining_account_metas(
<span class="kw-2">&amp;</span>account,
affected_tokens,
writable_banks,
affected_perp_markets,
fallback_contexts,
)
}
<span class="kw">pub async fn </span>derive_health_check_remaining_account_metas_two_accounts(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account_1: <span class="kw-2">&amp;</span>MangoAccountValue,
account_2: <span class="kw-2">&amp;</span>MangoAccountValue,
affected_tokens: <span class="kw-2">&amp;</span>[TokenIndex],
writable_banks: <span class="kw-2">&amp;</span>[TokenIndex],
) -&gt; anyhow::Result&lt;(Vec&lt;AccountMeta&gt;, u32)&gt; {
<span class="kw">let </span>fallback_contexts = <span class="self">self
</span>.context
.derive_fallback_oracle_keys(
<span class="kw-2">&amp;</span><span class="self">self</span>.client.config.fallback_oracle_config,
<span class="kw-2">&amp;*</span><span class="self">self</span>.account_fetcher,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.context
.derive_health_check_remaining_account_metas_two_accounts(
account_1,
account_2,
affected_tokens,
writable_banks,
fallback_contexts,
)
}
<span class="kw">pub async fn </span>health_cache(
<span class="kw-2">&amp;</span><span class="self">self</span>,
mango_account: <span class="kw-2">&amp;</span>MangoAccountValue,
) -&gt; anyhow::Result&lt;HealthCache&gt; {
health_cache::new(
<span class="kw-2">&amp;</span><span class="self">self</span>.context,
<span class="kw-2">&amp;</span><span class="self">self</span>.client.config.fallback_oracle_config,
<span class="kw-2">&amp;*</span><span class="self">self</span>.account_fetcher,
mango_account,
)
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>token_deposit(
<span class="kw-2">&amp;</span><span class="self">self</span>,
mint: Pubkey,
amount: u64,
reduce_only: bool,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>token = <span class="self">self</span>.context.token_by_mint(<span class="kw-2">&amp;</span>mint)<span class="question-mark">?</span>;
<span class="kw">let </span>token_index = token.token_index;
<span class="kw">let </span>mango_account = <span class="kw-2">&amp;</span><span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>(health_check_metas, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(
mango_account,
<span class="macro">vec!</span>[token_index],
<span class="macro">vec!</span>[],
<span class="macro">vec!</span>[],
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ixs = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::TokenDeposit {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
owner: <span class="self">self</span>.authority(),
bank: token.first_bank(),
vault: token.first_vault(),
oracle: token.oracle,
token_account: get_associated_token_address(
<span class="kw-2">&amp;</span><span class="self">self</span>.authority(),
<span class="kw-2">&amp;</span>token.mint,
),
token_authority: <span class="self">self</span>.authority(),
token_program: Token::id(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_check_metas.into_iter());
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::TokenDeposit {
amount,
reduce_only,
}),
},
<span class="self">self</span>.instruction_cu(health_cu),
);
<span class="self">self</span>.send_and_confirm_authority_tx(ixs.to_instructions())
.<span class="kw">await
</span>}
<span class="doccomment">/// Assert that health of account is &gt; N
</span><span class="kw">pub async fn </span>health_check_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
min_health_value: f64,
affected_tokens: Vec&lt;TokenIndex&gt;,
affected_perp_markets: Vec&lt;PerpMarketIndex&gt;,
check_kind: HealthCheckKind,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>(health_check_metas, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(
account,
affected_tokens,
<span class="macro">vec!</span>[],
affected_perp_markets,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ixs = PreparedInstructions::from_vec(
<span class="macro">vec!</span>[Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::HealthCheck {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
},
<span class="prelude-val">None</span>,
);
ams.extend(health_check_metas.into_iter());
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::HealthCheck {
min_health_value,
check_kind,
}),
}],
<span class="self">self</span>.instruction_cu(health_cu),
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="doccomment">/// Avoid executing same instruction multiple time
</span><span class="kw">pub async fn </span>sequence_check_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
mango_account_address: <span class="kw-2">&amp;</span>Pubkey,
mango_account: <span class="kw-2">&amp;</span>MangoAccountValue,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>ixs = PreparedInstructions::from_vec(
<span class="macro">vec!</span>[Instruction {
program_id: mango_v4::id(),
accounts: {
anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::SequenceCheck {
group: <span class="self">self</span>.group(),
account: <span class="kw-2">*</span>mango_account_address,
owner: mango_account.fixed.owner,
},
<span class="prelude-val">None</span>,
)
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::SequenceCheck {
expected_sequence_number: mango_account.fixed.sequence_number,
}),
}],
<span class="self">self</span>.context.compute_estimates.cu_for_sequence_check,
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="doccomment">/// Creates token withdraw instructions for the MangoClient&#39;s account/owner.
/// The `account` state is passed in separately so changes during the tx can be
/// accounted for when deriving health accounts.
</span><span class="kw">pub async fn </span>token_withdraw_instructions(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
mint: Pubkey,
amount: u64,
allow_borrow: bool,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>token = <span class="self">self</span>.context.token_by_mint(<span class="kw-2">&amp;</span>mint)<span class="question-mark">?</span>;
<span class="kw">let </span>token_index = token.token_index;
<span class="kw">let </span>(health_check_metas, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(account, <span class="macro">vec!</span>[token_index], <span class="macro">vec!</span>[], <span class="macro">vec!</span>[])
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ixs = PreparedInstructions::from_vec(
<span class="macro">vec!</span>[
spl_associated_token_account::instruction::create_associated_token_account_idempotent(
<span class="kw-2">&amp;</span><span class="self">self</span>.authority(),
<span class="kw-2">&amp;</span>account.fixed.owner,
<span class="kw-2">&amp;</span>mint,
<span class="kw-2">&amp;</span>Token::id(),
),
Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::TokenWithdraw {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
owner: <span class="self">self</span>.authority(),
bank: token.first_bank(),
vault: token.first_vault(),
oracle: token.oracle,
token_account: get_associated_token_address(
<span class="kw-2">&amp;</span>account.fixed.owner,
<span class="kw-2">&amp;</span>token.mint,
),
token_program: Token::id(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_check_metas.into_iter());
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::TokenWithdraw {
amount,
allow_borrow,
}),
},
],
<span class="self">self</span>.instruction_cu(health_cu) + <span class="self">self</span>.context.compute_estimates.cu_per_associated_token_account_creation,
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">pub async fn </span>token_withdraw(
<span class="kw-2">&amp;</span><span class="self">self</span>,
mint: Pubkey,
amount: u64,
allow_borrow: bool,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>account = <span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ixs = <span class="self">self
</span>.token_withdraw_instructions(<span class="kw-2">&amp;</span>account, mint, amount, allow_borrow)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.send_and_confirm_authority_tx(ixs.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>bank_oracle_price(<span class="kw-2">&amp;</span><span class="self">self</span>, token_index: TokenIndex) -&gt; anyhow::Result&lt;I80F48&gt; {
<span class="kw">let </span>bank = <span class="self">self</span>.first_bank(token_index).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>mint_info = <span class="self">self</span>.context.token(token_index);
<span class="kw">let </span>oracle = <span class="self">self
</span>.account_fetcher
.fetch_raw_account(<span class="kw-2">&amp;</span>mint_info.oracle)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>oracle_acc = <span class="kw-2">&amp;</span>KeyedAccountSharedData::new(mint_info.oracle, oracle.into());
<span class="kw">let </span>price = bank.oracle_price(<span class="kw-2">&amp;</span>OracleAccountInfos::from_reader(oracle_acc), <span class="prelude-val">None</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(price)
}
<span class="kw">pub async fn </span>perp_oracle_price(
<span class="kw-2">&amp;</span><span class="self">self</span>,
perp_market_index: PerpMarketIndex,
) -&gt; anyhow::Result&lt;I80F48&gt; {
<span class="kw">let </span>perp = <span class="self">self</span>.context.perp(perp_market_index);
<span class="kw">let </span>perp_market: PerpMarket =
account_fetcher_fetch_anchor_account(<span class="kw-2">&amp;*</span><span class="self">self</span>.account_fetcher, <span class="kw-2">&amp;</span>perp.address).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>oracle = <span class="self">self</span>.account_fetcher.fetch_raw_account(<span class="kw-2">&amp;</span>perp.oracle).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>oracle_acc = <span class="kw-2">&amp;</span>KeyedAccountSharedData::new(perp.oracle, oracle.into());
<span class="kw">let </span>price = perp_market.oracle_price(<span class="kw-2">&amp;</span>OracleAccountInfos::from_reader(oracle_acc), <span class="prelude-val">None</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(price)
}
<span class="comment">//
// Serum3
//
</span><span class="kw">pub fn </span>serum3_close_open_orders_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_index: Serum3MarketIndex,
) -&gt; PreparedInstructions {
<span class="kw">let </span>account_pubkey = <span class="self">self</span>.mango_account_address;
<span class="kw">let </span>s3 = <span class="self">self</span>.context.serum3(market_index);
<span class="kw">let </span>open_orders = <span class="self">self</span>.serum3_create_open_orders_address(market_index);
PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::Serum3CloseOpenOrders {
group: <span class="self">self</span>.group(),
account: account_pubkey,
serum_market: s3.address,
serum_program: s3.serum_program,
serum_market_external: s3.serum_market_external,
open_orders,
owner: <span class="self">self</span>.authority(),
sol_destination: <span class="self">self</span>.authority(),
},
<span class="prelude-val">None</span>,
),
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::Serum3CloseOpenOrders {},
),
},
<span class="self">self</span>.context.compute_estimates.cu_per_mango_instruction,
)
}
<span class="kw">pub async fn </span>serum3_close_open_orders(<span class="kw-2">&amp;</span><span class="self">self</span>, name: <span class="kw-2">&amp;</span>str) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>market_index = <span class="self">self</span>.context.serum3_market_index(name);
<span class="kw">let </span>ix = <span class="self">self</span>.serum3_close_open_orders_instruction(market_index);
<span class="self">self</span>.send_and_confirm_authority_tx(ix.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">pub fn </span>serum3_create_open_orders_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_index: Serum3MarketIndex,
) -&gt; Instruction {
<span class="kw">let </span>account_pubkey = <span class="self">self</span>.mango_account_address;
<span class="kw">let </span>s3 = <span class="self">self</span>.context.serum3(market_index);
<span class="kw">let </span>open_orders = <span class="self">self</span>.serum3_create_open_orders_address(market_index);
Instruction {
program_id: mango_v4::id(),
accounts: anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::Serum3CreateOpenOrders {
group: <span class="self">self</span>.group(),
account: account_pubkey,
serum_market: s3.address,
serum_program: s3.serum_program,
serum_market_external: s3.serum_market_external,
open_orders,
owner: <span class="self">self</span>.authority(),
payer: <span class="self">self</span>.authority(),
system_program: System::id(),
rent: sysvar::rent::id(),
},
<span class="prelude-val">None</span>,
),
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::Serum3CreateOpenOrders {},
),
}
}
<span class="kw">fn </span>serum3_create_open_orders_address(<span class="kw-2">&amp;</span><span class="self">self</span>, market_index: Serum3MarketIndex) -&gt; Pubkey {
<span class="kw">let </span>account_pubkey = <span class="self">self</span>.mango_account_address;
<span class="kw">let </span>s3 = <span class="self">self</span>.context.serum3(market_index);
<span class="kw">let </span>open_orders = Pubkey::find_program_address(
<span class="kw-2">&amp;</span>[
<span class="string">b&quot;Serum3OO&quot;</span>.as_ref(),
account_pubkey.as_ref(),
s3.address.as_ref(),
],
<span class="kw-2">&amp;</span>mango_v4::ID,
)
.<span class="number">0</span>;
open_orders
}
<span class="kw">pub async fn </span>serum3_create_open_orders(<span class="kw-2">&amp;</span><span class="self">self</span>, name: <span class="kw-2">&amp;</span>str) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>market_index = <span class="self">self</span>.context.serum3_market_index(name);
<span class="kw">let </span>ix = <span class="self">self</span>.serum3_create_open_orders_instruction(market_index);
<span class="self">self</span>.send_and_confirm_authority_tx(<span class="macro">vec!</span>[ix]).<span class="kw">await
</span>}
<span class="attr">#[allow(clippy::too_many_arguments)]
</span><span class="kw">pub async fn </span>serum3_place_order_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
market_index: Serum3MarketIndex,
side: Serum3Side,
limit_price: u64,
max_base_qty: u64,
max_native_quote_qty_including_fees: u64,
self_trade_behavior: Serum3SelfTradeBehavior,
order_type: Serum3OrderType,
client_order_id: u64,
limit: u16,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>s3 = <span class="self">self</span>.context.serum3(market_index);
<span class="kw">let </span>base = <span class="self">self</span>.context.serum3_base_token(market_index);
<span class="kw">let </span>quote = <span class="self">self</span>.context.serum3_quote_token(market_index);
<span class="kw">let </span>(payer_token, receiver_token) = <span class="kw">match </span>side {
Serum3Side::Bid =&gt; (<span class="kw-2">&amp;</span>quote, <span class="kw-2">&amp;</span>base),
Serum3Side::Ask =&gt; (<span class="kw-2">&amp;</span>base, <span class="kw-2">&amp;</span>quote),
};
<span class="kw">let </span>open_orders = account.serum3_orders(market_index).map(|x| x.open_orders)<span class="question-mark">?</span>;
<span class="kw">let </span>(health_check_metas, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(
<span class="kw-2">&amp;</span>account,
<span class="macro">vec!</span>[],
<span class="macro">vec!</span>[receiver_token.token_index],
<span class="macro">vec!</span>[],
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ixs = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::Serum3PlaceOrder {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
open_orders,
payer_bank: payer_token.first_bank(),
payer_vault: payer_token.first_vault(),
payer_oracle: payer_token.oracle,
serum_market: s3.address,
serum_program: s3.serum_program,
serum_market_external: s3.serum_market_external,
market_bids: s3.bids,
market_asks: s3.asks,
market_event_queue: s3.event_q,
market_request_queue: s3.req_q,
market_base_vault: s3.coin_vault,
market_quote_vault: s3.pc_vault,
market_vault_signer: s3.vault_signer,
owner: <span class="self">self</span>.authority(),
token_program: Token::id(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_check_metas.into_iter());
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::Serum3PlaceOrderV2 {
side,
limit_price,
max_base_qty,
max_native_quote_qty_including_fees,
self_trade_behavior,
order_type,
client_order_id,
limit,
},
),
},
<span class="self">self</span>.instruction_cu(health_cu)
+ <span class="self">self</span>.context.compute_estimates.cu_per_serum3_order_match * limit <span class="kw">as </span>u32,
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="attr">#[allow(clippy::too_many_arguments)]
</span><span class="kw">pub async fn </span>serum3_create_or_replace_account_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
<span class="kw-2">mut </span>account: <span class="kw-2">&amp;mut </span>MangoAccountValue,
market_index: Serum3MarketIndex,
side: Serum3Side,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>ixs = PreparedInstructions::new();
<span class="kw">let </span>base = <span class="self">self</span>.context.serum3_base_token(market_index);
<span class="kw">let </span>quote = <span class="self">self</span>.context.serum3_quote_token(market_index);
<span class="kw">let </span>(payer_token, receiver_token) = <span class="kw">match </span>side {
Serum3Side::Bid =&gt; (<span class="kw-2">&amp;</span>quote, <span class="kw-2">&amp;</span>base),
Serum3Side::Ask =&gt; (<span class="kw-2">&amp;</span>base, <span class="kw-2">&amp;</span>quote),
};
<span class="kw">let </span>open_orders_opt = account
.serum3_orders(market_index)
.map(|x| x.open_orders)
.ok();
<span class="kw">let </span><span class="kw-2">mut </span>missing_tokens = <span class="bool-val">false</span>;
<span class="kw">let </span>token_replace_ixs = <span class="self">self
</span>.find_existing_or_try_to_replace_token_positions(
<span class="kw-2">&amp;mut </span>account,
<span class="kw-2">&amp;</span>[payer_token.token_index, receiver_token.token_index],
)
.<span class="kw">await</span>;
<span class="kw">match </span>token_replace_ixs {
<span class="prelude-val">Ok</span>(res) =&gt; {
ixs.append(res);
}
<span class="prelude-val">Err</span>(<span class="kw">_</span>) =&gt; missing_tokens = <span class="bool-val">true</span>,
}
<span class="kw">if </span>open_orders_opt.is_none() {
<span class="kw">let </span>has_available_slot = account.all_serum3_orders().any(|p| !p.is_active());
<span class="kw">let </span>should_close_one_open_orders_account = !has_available_slot || missing_tokens;
<span class="kw">if </span>should_close_one_open_orders_account {
ixs.append(
<span class="self">self</span>.deactivate_first_active_unused_serum3_orders(<span class="kw-2">&amp;mut </span>account)
.<span class="kw">await</span><span class="question-mark">?</span>,
);
}
<span class="comment">// in case of missing token slots
// try again to create, as maybe deactivating the market slot resulted in some token being now unused
// but this time, in case of error, propagate to caller
</span><span class="kw">if </span>missing_tokens {
ixs.append(
<span class="self">self</span>.find_existing_or_try_to_replace_token_positions(
<span class="kw-2">&amp;mut </span>account,
<span class="kw-2">&amp;</span>[payer_token.token_index, receiver_token.token_index],
)
.<span class="kw">await</span><span class="question-mark">?</span>,
);
}
ixs.push(
<span class="self">self</span>.serum3_create_open_orders_instruction(market_index),
<span class="self">self</span>.context.compute_estimates.cu_per_mango_instruction,
);
<span class="kw">let </span>created_open_orders = <span class="self">self</span>.serum3_create_open_orders_address(market_index);
account.create_serum3_orders(market_index)<span class="question-mark">?</span>.open_orders = created_open_orders;
}
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">async fn </span>deactivate_first_active_unused_serum3_orders(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;mut </span>MangoAccountValue,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>serum3_closable_order_market_index = <span class="prelude-val">None</span>;
<span class="kw">for </span>p <span class="kw">in </span>account.all_serum3_orders() {
<span class="kw">let </span>open_orders_acc = <span class="self">self
</span>.account_fetcher
.fetch_raw_account(<span class="kw-2">&amp;</span>p.open_orders)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>open_orders_bytes = open_orders_acc.data();
<span class="kw">let </span>open_orders_data: <span class="kw-2">&amp;</span>serum_dex::state::OpenOrders = bytemuck::from_bytes(
<span class="kw-2">&amp;</span>open_orders_bytes[<span class="number">5</span>..<span class="number">5 </span>+ std::mem::size_of::&lt;serum_dex::state::OpenOrders&gt;()],
);
<span class="kw">let </span>is_closable = open_orders_data.free_slot_bits == u128::MAX
&amp;&amp; open_orders_data.native_coin_total == <span class="number">0
</span>&amp;&amp; open_orders_data.native_pc_total == <span class="number">0</span>;
<span class="kw">if </span>is_closable {
serum3_closable_order_market_index = <span class="prelude-val">Some</span>(p.market_index);
<span class="kw">break</span>;
}
}
<span class="kw">let </span>first_closable_slot =
serum3_closable_order_market_index.expect(<span class="string">&quot;couldn&#39;t find any serum3 slot available&quot;</span>);
<span class="kw">let </span>ixs = <span class="self">self</span>.serum3_close_open_orders_instruction(first_closable_slot);
<span class="kw">let </span>first_closable_market = account.serum3_orders(first_closable_slot)<span class="question-mark">?</span>;
<span class="kw">let </span>(tk1, tk2) = (
first_closable_market.base_token_index,
first_closable_market.quote_token_index,
);
account.token_position_mut(tk1)<span class="question-mark">?</span>.<span class="number">0</span>.decrement_in_use();
account.token_position_mut(tk2)<span class="question-mark">?</span>.<span class="number">0</span>.decrement_in_use();
account.deactivate_serum3_orders(first_closable_slot)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">async fn </span>find_existing_or_try_to_replace_token_positions(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;mut </span>MangoAccountValue,
token_indexes: <span class="kw-2">&amp;</span>[TokenIndex],
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>ixs = PreparedInstructions::new();
<span class="kw">for </span>token_index <span class="kw">in </span>token_indexes {
<span class="kw">let </span>result = <span class="self">self
</span>.find_existing_or_try_to_replace_token_position(account, <span class="kw-2">*</span>token_index)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">if let </span><span class="prelude-val">Some</span>(ix) = result {
ixs.append(ix);
}
}
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">async fn </span>find_existing_or_try_to_replace_token_position(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;mut </span>MangoAccountValue,
token_index: TokenIndex,
) -&gt; anyhow::Result&lt;<span class="prelude-ty">Option</span>&lt;PreparedInstructions&gt;&gt; {
<span class="kw">let </span>token_position_missing = account
.ensure_token_position(token_index)
.is_anchor_error_with_code(MangoError::NoFreeTokenPositionIndex.error_code());
<span class="kw">if </span>!token_position_missing {
<span class="kw">return </span><span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>);
}
<span class="kw">let </span>ixs = <span class="self">self</span>.deactivate_first_active_unused_token(account).<span class="kw">await</span><span class="question-mark">?</span>;
account.ensure_token_position(token_index)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(ixs))
}
<span class="kw">async fn </span>deactivate_first_active_unused_token(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;mut </span>MangoAccountValue,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>closable_tokens = account
.all_token_positions()
.enumerate()
.filter(|(<span class="kw">_</span>, p)| p.is_active() &amp;&amp; !p.is_in_use());
<span class="kw">let </span><span class="kw-2">mut </span>closable_token_position_raw_index_opt = <span class="prelude-val">None</span>;
<span class="kw">let </span><span class="kw-2">mut </span>closable_token_bank_opt = <span class="prelude-val">None</span>;
<span class="kw">for </span>(closable_token_position_raw_index, closable_token_position) <span class="kw">in </span>closable_tokens {
<span class="kw">let </span>bank = <span class="self">self</span>.first_bank(closable_token_position.token_index).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>native_balance = closable_token_position.native(<span class="kw-2">&amp;</span>bank);
<span class="kw">if </span>native_balance &lt; I80F48::ZERO {
<span class="kw">continue</span>;
}
<span class="kw">if </span>native_balance &gt; I80F48::ONE {
<span class="kw">continue</span>;
}
closable_token_position_raw_index_opt = <span class="prelude-val">Some</span>(closable_token_position_raw_index);
closable_token_bank_opt = <span class="prelude-val">Some</span>(bank);
<span class="kw">break</span>;
}
<span class="kw">if </span>closable_token_bank_opt.is_none() {
<span class="kw">return </span><span class="prelude-val">Err</span>(AnchorError(MangoError::NoFreeTokenPositionIndex.into()).into());
}
<span class="kw">let </span>withdraw_ixs = <span class="self">self
</span>.token_withdraw_instructions(
<span class="kw-2">&amp;</span>account,
closable_token_bank_opt.unwrap().mint,
u64::MAX,
<span class="bool-val">false</span>,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
account.deactivate_token_position(closable_token_position_raw_index_opt.unwrap());
<span class="kw">return </span><span class="prelude-val">Ok</span>(withdraw_ixs);
}
<span class="attr">#[allow(clippy::too_many_arguments)]
</span><span class="kw">pub async fn </span>serum3_place_order(
<span class="kw-2">&amp;</span><span class="self">self</span>,
name: <span class="kw-2">&amp;</span>str,
side: Serum3Side,
limit_price: u64,
max_base_qty: u64,
max_native_quote_qty_including_fees: u64,
self_trade_behavior: Serum3SelfTradeBehavior,
order_type: Serum3OrderType,
client_order_id: u64,
limit: u16,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>account = <span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>.clone();
<span class="kw">let </span>market_index = <span class="self">self</span>.context.serum3_market_index(name);
<span class="kw">let </span>create_or_replace_ixs = <span class="self">self
</span>.serum3_create_or_replace_account_instruction(<span class="kw-2">&amp;mut </span>account, market_index, side)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>place_order_ixs = <span class="self">self
</span>.serum3_place_order_instruction(
<span class="kw-2">&amp;</span>account,
market_index,
side,
limit_price,
max_base_qty,
max_native_quote_qty_including_fees,
self_trade_behavior,
order_type,
client_order_id,
limit,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span><span class="kw-2">mut </span>ixs = PreparedInstructions::new();
ixs.append(create_or_replace_ixs);
ixs.append(place_order_ixs);
<span class="self">self</span>.send_and_confirm_authority_tx(ixs.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>serum3_settle_funds(<span class="kw-2">&amp;</span><span class="self">self</span>, name: <span class="kw-2">&amp;</span>str) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>market_index = <span class="self">self</span>.context.serum3_market_index(name);
<span class="kw">let </span>s3 = <span class="self">self</span>.context.serum3(market_index);
<span class="kw">let </span>base = <span class="self">self</span>.context.serum3_base_token(market_index);
<span class="kw">let </span>quote = <span class="self">self</span>.context.serum3_quote_token(market_index);
<span class="kw">let </span>account = <span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>open_orders = account.serum3_orders(market_index).unwrap().open_orders;
<span class="kw">let </span>ix = <span class="self">self</span>.serum3_settle_funds_instruction(s3, base, quote, open_orders);
<span class="self">self</span>.send_and_confirm_authority_tx(ix.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">pub fn </span>serum3_settle_funds_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
s3: <span class="kw-2">&amp;</span>Serum3MarketContext,
base: <span class="kw-2">&amp;</span>TokenContext,
quote: <span class="kw-2">&amp;</span>TokenContext,
open_orders: Pubkey,
) -&gt; PreparedInstructions {
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::Serum3SettleFundsV2 {
v1: mango_v4::accounts::Serum3SettleFunds {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
open_orders,
quote_bank: quote.first_bank(),
quote_vault: quote.first_vault(),
base_bank: base.first_bank(),
base_vault: base.first_vault(),
serum_market: s3.address,
serum_program: s3.serum_program,
serum_market_external: s3.serum_market_external,
market_base_vault: s3.coin_vault,
market_quote_vault: s3.pc_vault,
market_vault_signer: s3.vault_signer,
owner: <span class="self">self</span>.authority(),
token_program: Token::id(),
},
v2: mango_v4::accounts::Serum3SettleFundsV2Extra {
quote_oracle: quote.oracle,
base_oracle: base.oracle,
},
},
<span class="prelude-val">None</span>,
),
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::Serum3SettleFundsV2 {
fees_to_dao: <span class="bool-val">true</span>,
}),
};
PreparedInstructions::from_single(
ix,
<span class="self">self</span>.context.compute_estimates.cu_per_mango_instruction,
)
}
<span class="kw">pub fn </span>serum3_cancel_all_orders_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
market_index: Serum3MarketIndex,
limit: u8,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>s3 = <span class="self">self</span>.context.serum3(market_index);
<span class="kw">let </span>open_orders = account.serum3_orders(market_index)<span class="question-mark">?</span>.open_orders;
<span class="kw">let </span>ixs = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::Serum3CancelAllOrders {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
open_orders,
market_bids: s3.bids,
market_asks: s3.asks,
market_event_queue: s3.event_q,
serum_market: s3.address,
serum_program: s3.serum_program,
serum_market_external: s3.serum_market_external,
owner: <span class="self">self</span>.authority(),
},
<span class="prelude-val">None</span>,
),
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::Serum3CancelAllOrders { limit },
),
},
<span class="self">self</span>.instruction_cu(<span class="number">0</span>)
+ <span class="self">self</span>.context.compute_estimates.cu_per_serum3_order_cancel * limit <span class="kw">as </span>u32,
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">pub async fn </span>serum3_cancel_all_orders(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_name: <span class="kw-2">&amp;</span>str,
) -&gt; <span class="prelude-ty">Result</span>&lt;Vec&lt;u128&gt;, anyhow::Error&gt; {
<span class="kw">let </span>market_index = <span class="self">self</span>.context.serum3_market_index(market_name);
<span class="kw">let </span>account = <span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>open_orders = account.serum3_orders(market_index).unwrap().open_orders;
<span class="kw">let </span>open_orders_acc = <span class="self">self</span>.account_fetcher.fetch_raw_account(<span class="kw-2">&amp;</span>open_orders).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>open_orders_bytes = open_orders_acc.data();
<span class="kw">let </span>open_orders_data: <span class="kw-2">&amp;</span>serum_dex::state::OpenOrders = bytemuck::from_bytes(
<span class="kw-2">&amp;</span>open_orders_bytes[<span class="number">5</span>..<span class="number">5 </span>+ std::mem::size_of::&lt;serum_dex::state::OpenOrders&gt;()],
);
<span class="kw">let </span><span class="kw-2">mut </span>orders = <span class="macro">vec!</span>[];
<span class="kw">for </span>order_id <span class="kw">in </span>open_orders_data.orders {
<span class="kw">if </span>order_id != <span class="number">0 </span>{
<span class="comment">// TODO: find side for order_id, and only cancel the relevant order
</span><span class="self">self</span>.serum3_cancel_order(market_name, Serum3Side::Bid, order_id)
.<span class="kw">await
</span>.ok();
<span class="self">self</span>.serum3_cancel_order(market_name, Serum3Side::Ask, order_id)
.<span class="kw">await
</span>.ok();
orders.push(order_id);
}
}
<span class="prelude-val">Ok</span>(orders)
}
<span class="kw">pub async fn </span>serum3_liq_force_cancel_orders_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
market_index: Serum3MarketIndex,
open_orders: <span class="kw-2">&amp;</span>Pubkey,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>s3 = <span class="self">self</span>.context.serum3(market_index);
<span class="kw">let </span>base = <span class="self">self</span>.context.serum3_base_token(market_index);
<span class="kw">let </span>quote = <span class="self">self</span>.context.serum3_quote_token(market_index);
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(liqee.<span class="number">1</span>, <span class="macro">vec!</span>[], <span class="macro">vec!</span>[], <span class="macro">vec!</span>[])
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>limit = <span class="number">5</span>;
<span class="kw">let </span>ix = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::Serum3LiqForceCancelOrders {
group: <span class="self">self</span>.group(),
account: <span class="kw-2">*</span>liqee.<span class="number">0</span>,
open_orders: <span class="kw-2">*</span>open_orders,
serum_market: s3.address,
serum_program: s3.serum_program,
serum_market_external: s3.serum_market_external,
market_bids: s3.bids,
market_asks: s3.asks,
market_event_queue: s3.event_q,
market_base_vault: s3.coin_vault,
market_quote_vault: s3.pc_vault,
market_vault_signer: s3.vault_signer,
quote_bank: quote.first_bank(),
quote_vault: quote.first_vault(),
base_bank: base.first_bank(),
base_vault: base.first_vault(),
token_program: Token::id(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams.into_iter());
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::Serum3LiqForceCancelOrders { limit },
),
},
<span class="self">self</span>.instruction_cu(health_cu)
+ <span class="self">self</span>.context.compute_estimates.cu_per_serum3_order_cancel * limit <span class="kw">as </span>u32,
);
<span class="prelude-val">Ok</span>(ix)
}
<span class="kw">pub async fn </span>openbook_v2_liq_force_cancel_orders_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
market_index: OpenbookV2MarketIndex,
open_orders: <span class="kw-2">&amp;</span>Pubkey,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>openbook_v2_market = <span class="self">self</span>.context.openbook_v2(market_index);
<span class="kw">let </span>base = <span class="self">self</span>.context.token(openbook_v2_market.base_token_index);
<span class="kw">let </span>quote = <span class="self">self</span>.context.token(openbook_v2_market.quote_token_index);
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(liqee.<span class="number">1</span>, <span class="macro">vec!</span>[], <span class="macro">vec!</span>[], <span class="macro">vec!</span>[])
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>limit = <span class="number">5</span>;
<span class="kw">let </span>ix = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::OpenbookV2LiqForceCancelOrders {
payer: <span class="self">self</span>.authority(),
group: <span class="self">self</span>.group(),
account: <span class="kw-2">*</span>liqee.<span class="number">0</span>,
open_orders: <span class="kw-2">*</span>open_orders,
openbook_v2_market: openbook_v2_market.address,
openbook_v2_program: openbook_v2_market.openbook_v2_program,
openbook_v2_market_external: openbook_v2_market.market_external,
bids: openbook_v2_market.bids,
asks: openbook_v2_market.asks,
event_heap: openbook_v2_market.event_heap,
market_base_vault: openbook_v2_market.market_base_vault,
market_quote_vault: openbook_v2_market.market_quote_vault,
market_vault_signer: openbook_v2_market.market_authority,
quote_bank: quote.first_bank(),
quote_vault: quote.first_vault(),
base_bank: base.first_bank(),
base_vault: base.first_vault(),
token_program: Token::id(),
system_program: System::id(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams.into_iter());
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::OpenbookV2LiqForceCancelOrders { limit },
),
},
<span class="self">self</span>.instruction_cu(health_cu)
+ <span class="self">self</span>.context.compute_estimates.cu_per_serum3_order_cancel * limit <span class="kw">as </span>u32,
);
<span class="prelude-val">Ok</span>(ix)
}
<span class="kw">pub async fn </span>serum3_liq_force_cancel_orders(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
market_index: Serum3MarketIndex,
open_orders: <span class="kw-2">&amp;</span>Pubkey,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>ixs = <span class="self">self
</span>.serum3_liq_force_cancel_orders_instruction(liqee, market_index, open_orders)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.send_and_confirm_permissionless_tx(ixs.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>serum3_cancel_order(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_name: <span class="kw-2">&amp;</span>str,
side: Serum3Side,
order_id: u128,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>market_index = <span class="self">self</span>.context.serum3_market_index(market_name);
<span class="kw">let </span>s3 = <span class="self">self</span>.context.serum3(market_index);
<span class="kw">let </span>account = <span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>open_orders = account.serum3_orders(market_index).unwrap().open_orders;
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::Serum3CancelOrder {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
serum_market: s3.address,
serum_program: s3.serum_program,
serum_market_external: s3.serum_market_external,
open_orders,
market_bids: s3.bids,
market_asks: s3.asks,
market_event_queue: s3.event_q,
owner: <span class="self">self</span>.authority(),
},
<span class="prelude-val">None</span>,
)
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::Serum3CancelOrder {
side,
order_id,
}),
};
<span class="self">self</span>.send_and_confirm_authority_tx(<span class="macro">vec!</span>[ix]).<span class="kw">await
</span>}
<span class="comment">//
// Perps
//
</span><span class="attr">#[allow(clippy::too_many_arguments)]
</span><span class="kw">pub async fn </span>perp_place_order_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
market_index: PerpMarketIndex,
side: Side,
price_lots: i64,
max_base_lots: i64,
max_quote_lots: i64,
client_order_id: u64,
order_type: PlaceOrderType,
reduce_only: bool,
expiry_timestamp: u64,
limit: u8,
self_trade_behavior: SelfTradeBehavior,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>ixs = PreparedInstructions::new();
<span class="kw">let </span>perp = <span class="self">self</span>.context.perp(market_index);
<span class="kw">let </span><span class="kw-2">mut </span>account = account.clone();
<span class="kw">let </span>close_perp_ixs_opt = <span class="self">self
</span>.replace_perp_market_if_needed(<span class="kw-2">&amp;</span>account, market_index)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">if let </span><span class="prelude-val">Some</span>((close_perp_ixs, modified_account)) = close_perp_ixs_opt {
account = modified_account;
ixs.append(close_perp_ixs);
}
<span class="kw">let </span>(health_remaining_metas, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(
<span class="kw-2">&amp;</span>account,
<span class="macro">vec!</span>[],
<span class="macro">vec!</span>[],
<span class="macro">vec!</span>[market_index],
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::PerpPlaceOrder {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
owner: <span class="self">self</span>.authority(),
perp_market: perp.address,
bids: perp.bids,
asks: perp.asks,
event_queue: perp.event_queue,
oracle: perp.oracle,
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_metas.into_iter());
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::PerpPlaceOrderV2 {
side,
price_lots,
max_base_lots,
max_quote_lots,
client_order_id,
order_type,
reduce_only,
expiry_timestamp,
limit,
self_trade_behavior,
}),
};
ixs.push(
ix,
<span class="self">self</span>.instruction_cu(health_cu)
+ <span class="self">self</span>.context.compute_estimates.cu_per_perp_order_match * limit <span class="kw">as </span>u32,
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">async fn </span>replace_perp_market_if_needed(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
perk_market_index: PerpMarketIndex,
) -&gt; anyhow::Result&lt;<span class="prelude-ty">Option</span>&lt;(PreparedInstructions, MangoAccountValue)&gt;&gt; {
<span class="kw">let </span>context = <span class="kw-2">&amp;</span><span class="self">self</span>.context;
<span class="kw">let </span>settle_token_index = context.perp(perk_market_index).settle_token_index;
<span class="kw">let </span><span class="kw-2">mut </span>account = account.clone();
<span class="kw">let </span>enforce_position_result =
account.ensure_perp_position(perk_market_index, settle_token_index);
<span class="kw">if </span>!enforce_position_result
.is_anchor_error_with_code(MangoError::NoFreePerpPositionIndex.error_code())
{
<span class="kw">return </span><span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>);
}
<span class="kw">let </span>perp_position_to_close_opt = account.find_first_active_unused_perp_position();
<span class="kw">match </span>perp_position_to_close_opt {
<span class="prelude-val">Some</span>(perp_position_to_close) =&gt; {
<span class="kw">let </span>close_ix = <span class="self">self
</span>.perp_deactivate_position_instruction(perp_position_to_close.market_index)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>previous_market = context.perp(perp_position_to_close.market_index);
account.deactivate_perp_position(
perp_position_to_close.market_index,
previous_market.settle_token_index,
)<span class="question-mark">?</span>;
account.ensure_perp_position(perk_market_index, settle_token_index)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>((close_ix, account)))
}
<span class="prelude-val">None </span>=&gt; <span class="macro">anyhow::bail!</span>(<span class="string">&quot;No perp market slot available&quot;</span>),
}
}
<span class="attr">#[allow(clippy::too_many_arguments)]
</span><span class="kw">pub async fn </span>perp_place_order(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_index: PerpMarketIndex,
side: Side,
price_lots: i64,
max_base_lots: i64,
max_quote_lots: i64,
client_order_id: u64,
order_type: PlaceOrderType,
reduce_only: bool,
expiry_timestamp: u64,
limit: u8,
self_trade_behavior: SelfTradeBehavior,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>account = <span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ixs = <span class="self">self
</span>.perp_place_order_instruction(
<span class="kw-2">&amp;</span>account,
market_index,
side,
price_lots,
max_base_lots,
max_quote_lots,
client_order_id,
order_type,
reduce_only,
expiry_timestamp,
limit,
self_trade_behavior,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.send_and_confirm_authority_tx(ixs.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">pub fn </span>perp_cancel_all_orders_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_index: PerpMarketIndex,
limit: u8,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>perp = <span class="self">self</span>.context.perp(market_index);
<span class="kw">let </span>ixs = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: {
anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::PerpCancelAllOrders {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
owner: <span class="self">self</span>.authority(),
perp_market: perp.address,
bids: perp.bids,
asks: perp.asks,
},
<span class="prelude-val">None</span>,
)
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::PerpCancelAllOrders { limit },
),
},
<span class="self">self</span>.instruction_cu(<span class="number">0</span>)
+ <span class="self">self</span>.context.compute_estimates.cu_per_perp_order_cancel * limit <span class="kw">as </span>u32,
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">pub async fn </span>perp_deactivate_position(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_index: PerpMarketIndex,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>ixs = <span class="self">self
</span>.perp_deactivate_position_instruction(market_index)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.send_and_confirm_authority_tx(ixs.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">async fn </span>perp_deactivate_position_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_index: PerpMarketIndex,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>perp = <span class="self">self</span>.context.perp(market_index);
<span class="kw">let </span>ixs = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::PerpDeactivatePosition {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
owner: <span class="self">self</span>.authority(),
perp_market: perp.address,
},
<span class="prelude-val">None</span>,
);
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::PerpDeactivatePosition {},
),
},
<span class="self">self</span>.context.compute_estimates.cu_per_mango_instruction,
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">pub async fn </span>perp_settle_pnl_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_index: PerpMarketIndex,
account_a: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
account_b: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>perp = <span class="self">self</span>.context.perp(market_index);
<span class="kw">let </span>settlement_token = <span class="self">self</span>.context.token(perp.settle_token_index);
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas_two_accounts(
account_a.<span class="number">1</span>,
account_b.<span class="number">1</span>,
<span class="kw-2">&amp;</span>[],
<span class="kw-2">&amp;</span>[],
)
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>ixs = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::PerpSettlePnl {
group: <span class="self">self</span>.group(),
settler: <span class="self">self</span>.mango_account_address,
settler_owner: <span class="self">self</span>.authority(),
perp_market: perp.address,
account_a: <span class="kw-2">*</span>account_a.<span class="number">0</span>,
account_b: <span class="kw-2">*</span>account_b.<span class="number">0</span>,
oracle: perp.oracle,
settle_bank: settlement_token.first_bank(),
settle_oracle: settlement_token.oracle,
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams.into_iter());
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::PerpSettlePnl {}),
},
<span class="self">self</span>.instruction_cu(health_cu),
);
<span class="prelude-val">Ok</span>(ixs)
}
<span class="kw">pub async fn </span>perp_settle_pnl(
<span class="kw-2">&amp;</span><span class="self">self</span>,
market_index: PerpMarketIndex,
account_a: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
account_b: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>ixs = <span class="self">self
</span>.perp_settle_pnl_instruction(market_index, account_a, account_b)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.send_and_confirm_permissionless_tx(ixs.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>perp_liq_force_cancel_orders(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
market_index: PerpMarketIndex,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>perp = <span class="self">self</span>.context.perp(market_index);
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(liqee.<span class="number">1</span>, <span class="macro">vec!</span>[], <span class="macro">vec!</span>[], <span class="macro">vec!</span>[])
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>limit = <span class="number">5</span>;
<span class="kw">let </span>ixs = PreparedInstructions::from_single(
Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::PerpLiqForceCancelOrders {
group: <span class="self">self</span>.group(),
account: <span class="kw-2">*</span>liqee.<span class="number">0</span>,
perp_market: perp.address,
bids: perp.bids,
asks: perp.asks,
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams.into_iter());
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::PerpLiqForceCancelOrders { limit },
),
},
<span class="self">self</span>.instruction_cu(health_cu)
+ <span class="self">self</span>.context.compute_estimates.cu_per_perp_order_cancel * limit <span class="kw">as </span>u32,
);
<span class="self">self</span>.send_and_confirm_permissionless_tx(ixs.to_instructions())
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>perp_liq_base_or_positive_pnl_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
market_index: PerpMarketIndex,
max_base_transfer: i64,
max_pnl_transfer: u64,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>perp = <span class="self">self</span>.context.perp(market_index);
<span class="kw">let </span>settle_token_info = <span class="self">self</span>.context.token(perp.settle_token_index);
<span class="kw">let </span>mango_account = <span class="kw-2">&amp;</span><span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas_two_accounts(
mango_account,
liqee.<span class="number">1</span>,
<span class="kw-2">&amp;</span>[],
<span class="kw-2">&amp;</span>[],
)
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::PerpLiqBaseOrPositivePnl {
group: <span class="self">self</span>.group(),
perp_market: perp.address,
oracle: perp.oracle,
liqor: <span class="self">self</span>.mango_account_address,
liqor_owner: <span class="self">self</span>.authority(),
liqee: <span class="kw-2">*</span>liqee.<span class="number">0</span>,
settle_bank: settle_token_info.first_bank(),
settle_vault: settle_token_info.first_vault(),
settle_oracle: settle_token_info.oracle,
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams.into_iter());
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::PerpLiqBaseOrPositivePnl {
max_base_transfer,
max_pnl_transfer,
},
),
};
<span class="prelude-val">Ok</span>(PreparedInstructions::from_single(
ix,
<span class="self">self</span>.instruction_cu(health_cu),
))
}
<span class="kw">pub async fn </span>perp_liq_negative_pnl_or_bankruptcy_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
market_index: PerpMarketIndex,
max_liab_transfer: u64,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>group = account_fetcher_fetch_anchor_account::&lt;Group&gt;(
<span class="kw-2">&amp;*</span><span class="self">self</span>.account_fetcher,
<span class="kw-2">&amp;</span><span class="self">self</span>.context.group,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>mango_account = <span class="kw-2">&amp;</span><span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>perp = <span class="self">self</span>.context.perp(market_index);
<span class="kw">let </span>settle_token_info = <span class="self">self</span>.context.token(perp.settle_token_index);
<span class="kw">let </span>insurance_token_info = <span class="self">self</span>.context.token_by_mint(<span class="kw-2">&amp;</span>group.insurance_mint)<span class="question-mark">?</span>;
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas_two_accounts(
mango_account,
liqee.<span class="number">1</span>,
<span class="kw-2">&amp;</span>[insurance_token_info.token_index],
<span class="kw-2">&amp;</span>[],
)
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::PerpLiqNegativePnlOrBankruptcyV2 {
group: <span class="self">self</span>.group(),
perp_market: perp.address,
oracle: perp.oracle,
liqor: <span class="self">self</span>.mango_account_address,
liqor_owner: <span class="self">self</span>.authority(),
liqee: <span class="kw-2">*</span>liqee.<span class="number">0</span>,
settle_bank: settle_token_info.first_bank(),
settle_vault: settle_token_info.first_vault(),
settle_oracle: settle_token_info.oracle,
insurance_vault: group.insurance_vault,
insurance_bank: insurance_token_info.first_bank(),
insurance_bank_vault: insurance_token_info.first_vault(),
insurance_oracle: insurance_token_info.oracle,
token_program: Token::id(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams.into_iter());
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::PerpLiqNegativePnlOrBankruptcyV2 { max_liab_transfer },
),
};
<span class="prelude-val">Ok</span>(PreparedInstructions::from_single(
ix,
<span class="self">self</span>.instruction_cu(health_cu),
))
}
<span class="kw">pub async fn </span>token_charge_collateral_fees_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>(<span class="kw-2">mut </span>health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(account.<span class="number">1</span>, <span class="macro">vec!</span>[], <span class="macro">vec!</span>[], <span class="macro">vec!</span>[])
.<span class="kw">await
</span>.unwrap();
<span class="comment">// The instruction requires mutable banks
</span><span class="kw">for </span>am <span class="kw">in </span><span class="kw-2">&amp;mut </span>health_remaining_ams[<span class="number">0</span>..account.<span class="number">1</span>.active_token_positions().count()] {
am.is_writable = <span class="bool-val">true</span>;
}
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::TokenChargeCollateralFees {
group: <span class="self">self</span>.group(),
account: <span class="kw-2">*</span>account.<span class="number">0</span>,
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams);
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::TokenChargeCollateralFees {},
),
};
<span class="kw">let </span><span class="kw-2">mut </span>chargeable_token_positions = <span class="number">0</span>;
<span class="kw">for </span>tp <span class="kw">in </span>account.<span class="number">1</span>.active_token_positions() {
<span class="kw">let </span>bank = <span class="self">self</span>.first_bank(tp.token_index).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>native = tp.native(<span class="kw-2">&amp;</span>bank);
<span class="kw">if </span>native.is_positive()
&amp;&amp; bank.maint_asset_weight.is_positive()
&amp;&amp; bank.collateral_fee_per_day &gt; <span class="number">0.0
</span>{
chargeable_token_positions += <span class="number">1</span>;
}
}
<span class="kw">let </span>cu_est = <span class="kw-2">&amp;</span><span class="self">self</span>.context.compute_estimates;
<span class="kw">let </span>cu = cu_est.cu_per_charge_collateral_fees
+ cu_est.cu_per_charge_collateral_fees_token * chargeable_token_positions
+ health_cu;
<span class="prelude-val">Ok</span>(PreparedInstructions::from_single(ix, cu))
}
<span class="comment">//
// Liquidation
//
</span><span class="kw">pub async fn </span>token_liq_with_token_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
asset_token_index: TokenIndex,
liab_token_index: TokenIndex,
max_liab_transfer: I80F48,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>mango_account = <span class="kw-2">&amp;</span><span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas_two_accounts(
mango_account,
liqee.<span class="number">1</span>,
<span class="kw-2">&amp;</span>[],
<span class="kw-2">&amp;</span>[asset_token_index, liab_token_index],
)
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::TokenLiqWithToken {
group: <span class="self">self</span>.group(),
liqee: <span class="kw-2">*</span>liqee.<span class="number">0</span>,
liqor: <span class="self">self</span>.mango_account_address,
liqor_owner: <span class="self">self</span>.authority(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams);
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::TokenLiqWithToken {
asset_token_index,
liab_token_index,
max_liab_transfer,
}),
};
<span class="prelude-val">Ok</span>(PreparedInstructions::from_single(
ix,
<span class="self">self</span>.instruction_cu(health_cu),
))
}
<span class="kw">pub async fn </span>token_liq_bankruptcy_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
liab_token_index: TokenIndex,
max_liab_transfer: I80F48,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>group = account_fetcher_fetch_anchor_account::&lt;Group&gt;(
<span class="kw-2">&amp;*</span><span class="self">self</span>.account_fetcher,
<span class="kw-2">&amp;</span><span class="self">self</span>.context.group,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>mango_account = <span class="kw-2">&amp;</span><span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>insurance_info = <span class="self">self</span>.context.token_by_mint(<span class="kw-2">&amp;</span>group.insurance_mint)<span class="question-mark">?</span>;
<span class="kw">let </span>liab_info = <span class="self">self</span>.context.token(liab_token_index);
<span class="kw">let </span>bank_remaining_ams = liab_info
.banks()
.iter()
.map(|bank_pubkey| util::to_writable_account_meta(<span class="kw-2">*</span>bank_pubkey))
.collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;();
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas_two_accounts(
mango_account,
liqee.<span class="number">1</span>,
<span class="kw-2">&amp;</span>[insurance_info.token_index],
<span class="kw-2">&amp;</span>[insurance_info.token_index, liab_token_index],
)
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::TokenLiqBankruptcy {
group: <span class="self">self</span>.group(),
liqee: <span class="kw-2">*</span>liqee.<span class="number">0</span>,
liqor: <span class="self">self</span>.mango_account_address,
liqor_owner: <span class="self">self</span>.authority(),
liab_mint_info: liab_info.mint_info_address,
quote_vault: insurance_info.first_vault(),
insurance_vault: group.insurance_vault,
token_program: Token::id(),
},
<span class="prelude-val">None</span>,
);
ams.extend(bank_remaining_ams);
ams.extend(health_remaining_ams);
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::TokenLiqBankruptcy {
max_liab_transfer,
}),
};
<span class="prelude-val">Ok</span>(PreparedInstructions::from_single(
ix,
<span class="self">self</span>.instruction_cu(health_cu),
))
}
<span class="kw">pub async fn </span>token_conditional_swap_trigger_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
liqee: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
token_conditional_swap_id: u64,
max_buy_token_to_liqee: u64,
max_sell_token_to_liqor: u64,
min_buy_token: u64,
min_taker_price: f32,
extra_affected_tokens: <span class="kw-2">&amp;</span>[TokenIndex],
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>mango_account = <span class="kw-2">&amp;</span><span class="self">self</span>.mango_account().<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>(tcs_index, tcs) = liqee
.<span class="number">1
</span>.token_conditional_swap_by_id(token_conditional_swap_id)<span class="question-mark">?</span>;
<span class="kw">let </span>affected_tokens = extra_affected_tokens
.iter()
.chain(<span class="kw-2">&amp;</span>[tcs.buy_token_index, tcs.sell_token_index])
.copied()
.collect_vec();
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas_two_accounts(
mango_account,
liqee.<span class="number">1</span>,
<span class="kw-2">&amp;</span>affected_tokens,
<span class="kw-2">&amp;</span>[tcs.buy_token_index, tcs.sell_token_index],
)
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::TokenConditionalSwapTrigger {
group: <span class="self">self</span>.group(),
liqee: <span class="kw-2">*</span>liqee.<span class="number">0</span>,
liqor: <span class="self">self</span>.mango_account_address,
liqor_authority: <span class="self">self</span>.authority(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams);
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::TokenConditionalSwapTriggerV2 {
token_conditional_swap_id,
token_conditional_swap_index: tcs_index.try_into().unwrap(),
max_buy_token_to_liqee,
max_sell_token_to_liqor,
min_buy_token,
min_taker_price,
},
),
};
<span class="prelude-val">Ok</span>(PreparedInstructions::from_single(
ix,
<span class="self">self</span>.instruction_cu(health_cu),
))
}
<span class="kw">pub async fn </span>token_conditional_swap_start_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: (<span class="kw-2">&amp;</span>Pubkey, <span class="kw-2">&amp;</span>MangoAccountValue),
token_conditional_swap_id: u64,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>(tcs_index, tcs) = account
.<span class="number">1
</span>.token_conditional_swap_by_id(token_conditional_swap_id)<span class="question-mark">?</span>;
<span class="kw">let </span>affected_tokens = <span class="macro">vec!</span>[tcs.buy_token_index, tcs.sell_token_index];
<span class="kw">let </span>(health_remaining_ams, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(account.<span class="number">1</span>, <span class="macro">vec!</span>[], affected_tokens, <span class="macro">vec!</span>[])
.<span class="kw">await
</span>.unwrap();
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::TokenConditionalSwapStart {
group: <span class="self">self</span>.group(),
liqee: <span class="kw-2">*</span>account.<span class="number">0</span>,
liqor: <span class="self">self</span>.mango_account_address,
liqor_authority: <span class="self">self</span>.authority(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_ams);
ams
},
data: anchor_lang::InstructionData::data(
<span class="kw-2">&amp;</span>mango_v4::instruction::TokenConditionalSwapStart {
token_conditional_swap_id,
token_conditional_swap_index: tcs_index.try_into().unwrap(),
},
),
};
<span class="prelude-val">Ok</span>(PreparedInstructions::from_single(
ix,
<span class="self">self</span>.instruction_cu(health_cu),
))
}
<span class="comment">// health region
</span><span class="kw">pub async fn </span>health_region_begin_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
affected_tokens: Vec&lt;TokenIndex&gt;,
writable_banks: Vec&lt;TokenIndex&gt;,
affected_perp_markets: Vec&lt;PerpMarketIndex&gt;,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>(health_remaining_metas, _health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(
account,
affected_tokens,
writable_banks,
affected_perp_markets,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::HealthRegionBegin {
group: <span class="self">self</span>.group(),
account: <span class="self">self</span>.mango_account_address,
instructions: solana_sdk::sysvar::instructions::id(),
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_metas.into_iter());
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::HealthRegionBegin {}),
};
<span class="comment">// There&#39;s only a single health computation in End
</span><span class="prelude-val">Ok</span>(PreparedInstructions::from_single(
ix,
<span class="self">self</span>.instruction_cu(<span class="number">0</span>),
))
}
<span class="kw">pub async fn </span>health_region_end_instruction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
account: <span class="kw-2">&amp;</span>MangoAccountValue,
affected_tokens: Vec&lt;TokenIndex&gt;,
writable_banks: Vec&lt;TokenIndex&gt;,
affected_perp_markets: Vec&lt;PerpMarketIndex&gt;,
) -&gt; anyhow::Result&lt;PreparedInstructions&gt; {
<span class="kw">let </span>(health_remaining_metas, health_cu) = <span class="self">self
</span>.derive_health_check_remaining_account_metas(
account,
affected_tokens,
writable_banks,
affected_perp_markets,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>ix = Instruction {
program_id: mango_v4::id(),
accounts: {
<span class="kw">let </span><span class="kw-2">mut </span>ams = anchor_lang::ToAccountMetas::to_account_metas(
<span class="kw-2">&amp;</span>mango_v4::accounts::HealthRegionEnd {
account: <span class="self">self</span>.mango_account_address,
},
<span class="prelude-val">None</span>,
);
ams.extend(health_remaining_metas.into_iter());
ams
},
data: anchor_lang::InstructionData::data(<span class="kw-2">&amp;</span>mango_v4::instruction::HealthRegionEnd {}),
};
<span class="prelude-val">Ok</span>(PreparedInstructions::from_single(
ix,
<span class="self">self</span>.instruction_cu(health_cu),
))
}
<span class="comment">// Swap (jupiter, sanctum)
</span><span class="kw">pub fn </span>swap(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; swap::Swap {
swap::Swap { mango_client: <span class="self">self </span>}
}
<span class="kw">pub fn </span>jupiter_v6(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; swap::jupiter_v6::JupiterV6 {
swap::jupiter_v6::JupiterV6 {
mango_client: <span class="self">self</span>,
timeout_duration: <span class="self">self</span>.client.config.jupiter_timeout,
}
}
<span class="kw">pub fn </span>sanctum(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; swap::sanctum::Sanctum {
swap::sanctum::Sanctum {
mango_client: <span class="self">self</span>,
timeout_duration: <span class="self">self</span>.client.config.sanctum_timeout,
}
}
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">async fn </span>deserialize_instructions_and_alts(
<span class="kw-2">&amp;</span><span class="self">self</span>,
message: <span class="kw-2">&amp;</span>solana_sdk::message::VersionedMessage,
) -&gt; anyhow::Result&lt;(Vec&lt;Instruction&gt;, Vec&lt;AddressLookupTableAccount&gt;)&gt; {
<span class="kw">let </span>lookups = message.address_table_lookups().unwrap_or_default();
<span class="kw">let </span>address_lookup_tables = <span class="self">self
</span>.fetch_address_lookup_tables(lookups.iter().map(|a| <span class="kw-2">&amp;</span>a.account_key))
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span><span class="kw-2">mut </span>account_keys = message.static_account_keys().to_vec();
<span class="kw">for </span>(lookups, table) <span class="kw">in </span>lookups.iter().zip(address_lookup_tables.iter()) {
account_keys.extend(
lookups
.writable_indexes
.iter()
.map(|<span class="kw-2">&amp;</span>index| table.addresses[index <span class="kw">as </span>usize]),
);
}
<span class="kw">for </span>(lookups, table) <span class="kw">in </span>lookups.iter().zip(address_lookup_tables.iter()) {
account_keys.extend(
lookups
.readonly_indexes
.iter()
.map(|<span class="kw-2">&amp;</span>index| table.addresses[index <span class="kw">as </span>usize]),
);
}
<span class="kw">let </span>compiled_ix = message
.instructions()
.iter()
.map(|ci| solana_sdk::instruction::Instruction {
program_id: <span class="kw-2">*</span>ci.program_id(<span class="kw-2">&amp;</span>account_keys),
accounts: ci
.accounts
.iter()
.map(|<span class="kw-2">&amp;</span>index| AccountMeta {
pubkey: account_keys[index <span class="kw">as </span>usize],
is_signer: message.is_signer(index.into()),
is_writable: message.is_maybe_writable(index.into()),
})
.collect(),
data: ci.data.clone(),
})
.collect();
<span class="prelude-val">Ok</span>((compiled_ix, address_lookup_tables))
}
<span class="kw">pub async fn </span>fetch_address_lookup_table(
<span class="kw-2">&amp;</span><span class="self">self</span>,
address: Pubkey,
) -&gt; anyhow::Result&lt;AddressLookupTableAccount&gt; {
<span class="kw">let </span>raw = <span class="self">self
</span>.account_fetcher
.fetch_raw_account_lookup_table(<span class="kw-2">&amp;</span>address)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>data = AddressLookupTable::deserialize(<span class="kw-2">&amp;</span>raw.data())<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(AddressLookupTableAccount {
key: address,
addresses: data.addresses.to_vec(),
})
}
<span class="kw">pub async fn </span>fetch_address_lookup_tables(
<span class="kw-2">&amp;</span><span class="self">self</span>,
alts: <span class="kw">impl </span>Iterator&lt;Item = <span class="kw-2">&amp;</span>Pubkey&gt;,
) -&gt; anyhow::Result&lt;Vec&lt;AddressLookupTableAccount&gt;&gt; {
stream::iter(alts)
.then(|a| <span class="self">self</span>.fetch_address_lookup_table(<span class="kw-2">*</span>a))
.try_collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;()
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>mango_address_lookup_tables(
<span class="kw-2">&amp;</span><span class="self">self</span>,
) -&gt; anyhow::Result&lt;Vec&lt;AddressLookupTableAccount&gt;&gt; {
stream::iter(<span class="self">self</span>.context.address_lookup_tables.iter())
.then(|<span class="kw-2">&amp;</span>k| <span class="self">self</span>.fetch_address_lookup_table(k))
.try_collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;()
.<span class="kw">await
</span>}
<span class="kw">fn </span>instruction_cu(<span class="kw-2">&amp;</span><span class="self">self</span>, health_cu: u32) -&gt; u32 {
<span class="self">self</span>.context.compute_estimates.cu_per_mango_instruction + health_cu
}
<span class="kw">pub async fn </span>send_and_confirm_authority_tx(
<span class="kw-2">&amp;</span><span class="self">self</span>,
instructions: Vec&lt;Instruction&gt;,
) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>tx_builder = TransactionBuilder {
instructions,
..<span class="self">self</span>.transaction_builder().<span class="kw">await</span><span class="question-mark">?
</span>};
tx_builder.signers.push(<span class="self">self</span>.authority.clone());
tx_builder.send_and_confirm(<span class="kw-2">&amp;</span><span class="self">self</span>.client).<span class="kw">await
</span>}
<span class="kw">pub async fn </span>send_and_confirm_permissionless_tx(
<span class="kw-2">&amp;</span><span class="self">self</span>,
instructions: Vec&lt;Instruction&gt;,
) -&gt; anyhow::Result&lt;Signature&gt; {
TransactionBuilder {
instructions,
..<span class="self">self</span>.transaction_builder().<span class="kw">await</span><span class="question-mark">?
</span>}
.send_and_confirm(<span class="kw-2">&amp;</span><span class="self">self</span>.client)
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>transaction_builder(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; anyhow::Result&lt;TransactionBuilder&gt; {
<span class="kw">let </span>fee_payer = <span class="self">self</span>.client.fee_payer();
<span class="prelude-val">Ok</span>(TransactionBuilder {
instructions: <span class="macro">vec!</span>[],
address_lookup_tables: <span class="self">self</span>.mango_address_lookup_tables().<span class="kw">await</span><span class="question-mark">?</span>,
payer: fee_payer.pubkey(),
signers: <span class="macro">vec!</span>[fee_payer],
config: <span class="self">self</span>.client.config.transaction_builder_config.clone(),
})
}
<span class="kw">pub async fn </span>simulate(
<span class="kw-2">&amp;</span><span class="self">self</span>,
instructions: Vec&lt;Instruction&gt;,
) -&gt; anyhow::Result&lt;SimulateTransactionResponse&gt; {
<span class="kw">let </span>fee_payer = <span class="self">self</span>.client.fee_payer();
TransactionBuilder {
instructions,
address_lookup_tables: <span class="macro">vec!</span>[],
payer: fee_payer.pubkey(),
signers: <span class="macro">vec!</span>[fee_payer],
config: <span class="self">self</span>.client.config.transaction_builder_config.clone(),
}
.simulate(<span class="kw-2">&amp;</span><span class="self">self</span>.client)
.<span class="kw">await
</span>}
<span class="kw">pub async fn </span>loop_check_for_context_changes_and_abort(
mango_client: Arc&lt;MangoClient&gt;,
interval: Duration,
) {
<span class="kw">let </span><span class="kw-2">mut </span>delay = <span class="kw">crate</span>::delay_interval(interval);
<span class="kw">let </span>rpc_async = mango_client.client.rpc_async();
<span class="kw">loop </span>{
delay.tick().<span class="kw">await</span>;
<span class="kw">let </span>new_context =
<span class="kw">match </span>MangoGroupContext::new_from_rpc(<span class="kw-2">&amp;</span>rpc_async, mango_client.group()).<span class="kw">await </span>{
<span class="prelude-val">Ok</span>(v) =&gt; v,
<span class="prelude-val">Err</span>(e) =&gt; {
<span class="macro">warn!</span>(<span class="string">&quot;could not fetch context to check for changes: {e:?}&quot;</span>);
<span class="kw">continue</span>;
}
};
<span class="kw">if </span>mango_client.context.changed_significantly(<span class="kw-2">&amp;</span>new_context) {
std::process::abort();
}
}
}
}
<span class="attr">#[derive(Debug, thiserror::Error)]
</span><span class="kw">pub enum </span>MangoClientError {
<span class="attr">#[error(<span class="string">&quot;Transaction simulation error. Error: {err:?}, Logs: {}&quot;</span>,
.logs.iter().join(<span class="string">&quot;; &quot;</span>)
)]
</span>SendTransactionPreflightFailure {
err: <span class="prelude-ty">Option</span>&lt;TransactionError&gt;,
logs: Vec&lt;String&gt;,
},
}
<span class="attr">#[derive(Copy, Clone, Debug, Default)]
</span><span class="kw">pub struct </span>TransactionSize {
<span class="kw">pub </span>accounts: usize,
<span class="kw">pub </span>length: usize,
}
<span class="kw">impl </span>TransactionSize {
<span class="kw">pub fn </span>is_within_limit(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">let </span>limit = <span class="self">Self</span>::limit();
<span class="self">self</span>.length &lt;= limit.length &amp;&amp; <span class="self">self</span>.accounts &lt;= limit.accounts
}
<span class="kw">pub fn </span>limit() -&gt; <span class="self">Self </span>{
<span class="self">Self </span>{
accounts: MAX_ACCOUNTS_PER_TRANSACTION,
length: solana_sdk::packet::PACKET_DATA_SIZE,
}
}
}
<span class="attr">#[derive(Clone, Debug, PartialEq, Eq)]
</span><span class="kw">pub enum </span>FallbackOracleConfig {
<span class="doccomment">/// No fallback oracles
</span>Never,
<span class="doccomment">/// Only provided fallback oracles are used
</span>Fixed(Vec&lt;Pubkey&gt;),
<span class="doccomment">/// The account_fetcher checks for stale oracles and uses fallbacks only for stale oracles
</span>Dynamic,
<span class="doccomment">/// Every possible fallback oracle (may cause serious issues with the 64 accounts-per-tx limit)
</span>All,
}
<span class="kw">impl </span>Default <span class="kw">for </span>FallbackOracleConfig {
<span class="kw">fn </span>default() -&gt; <span class="self">Self </span>{
FallbackOracleConfig::Dynamic
}
}
<span class="attr">#[derive(Clone, Default, Builder)]
</span><span class="kw">pub struct </span>TransactionBuilderConfig {
<span class="doccomment">/// adds a SetComputeUnitPrice instruction in front if none exists
</span><span class="kw">pub </span>priority_fee_provider: <span class="prelude-ty">Option</span>&lt;Arc&lt;<span class="kw">dyn </span>PriorityFeeProvider&gt;&gt;,
<span class="doccomment">/// adds a SetComputeUnitBudget instruction if none exists
</span><span class="kw">pub </span>compute_budget_per_instruction: <span class="prelude-ty">Option</span>&lt;u32&gt;,
}
<span class="kw">impl </span>TransactionBuilderConfig {
<span class="kw">pub fn </span>builder() -&gt; TransactionBuilderConfigBuilder {
TransactionBuilderConfigBuilder::default()
}
}
<span class="kw">impl </span>TransactionBuilderConfigBuilder {
<span class="kw">pub fn </span>prioritization_micro_lamports(<span class="kw-2">&amp;mut </span><span class="self">self</span>, cu: <span class="prelude-ty">Option</span>&lt;u64&gt;) -&gt; <span class="kw-2">&amp;mut </span><span class="self">Self </span>{
<span class="self">self</span>.priority_fee_provider(
cu.map(|cu| {
Arc::new(FixedPriorityFeeProvider::new(cu)) <span class="kw">as </span>Arc&lt;<span class="kw">dyn </span>PriorityFeeProvider&gt;
}),
)
}
}
<span class="kw">pub struct </span>TransactionBuilder {
<span class="kw">pub </span>instructions: Vec&lt;Instruction&gt;,
<span class="kw">pub </span>address_lookup_tables: Vec&lt;AddressLookupTableAccount&gt;,
<span class="kw">pub </span>signers: Vec&lt;Arc&lt;Keypair&gt;&gt;,
<span class="kw">pub </span>payer: Pubkey,
<span class="kw">pub </span>config: TransactionBuilderConfig,
}
<span class="kw">pub type </span>SimulateTransactionResponse =
solana_client::rpc_response::Response&lt;RpcSimulateTransactionResult&gt;;
<span class="kw">impl </span>TransactionBuilder {
<span class="kw">pub async fn </span>transaction(
<span class="kw-2">&amp;</span><span class="self">self</span>,
rpc: <span class="kw-2">&amp;</span>RpcClientAsync,
) -&gt; anyhow::Result&lt;solana_sdk::transaction::VersionedTransaction&gt; {
<span class="kw">let </span>(latest_blockhash, <span class="kw">_</span>) = rpc
.get_latest_blockhash_with_commitment(CommitmentConfig::finalized())
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="self">self</span>.transaction_with_blockhash(latest_blockhash)
}
<span class="kw">fn </span>instructions_with_cu_budget(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; Vec&lt;Instruction&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>ixs = <span class="self">self</span>.instructions.clone();
<span class="kw">let </span><span class="kw-2">mut </span>has_compute_unit_price = <span class="bool-val">false</span>;
<span class="kw">let </span><span class="kw-2">mut </span>has_compute_unit_limit = <span class="bool-val">false</span>;
<span class="kw">let </span><span class="kw-2">mut </span>cu_instructions = <span class="number">0</span>;
<span class="kw">for </span>ix <span class="kw">in </span>ixs.iter() {
<span class="kw">if </span>ix.program_id != solana_sdk::compute_budget::id() {
<span class="kw">continue</span>;
}
cu_instructions += <span class="number">1</span>;
<span class="kw">match </span>ComputeBudgetInstruction::try_from_slice(<span class="kw-2">&amp;</span>ix.data) {
<span class="prelude-val">Ok</span>(ComputeBudgetInstruction::SetComputeUnitLimit(<span class="kw">_</span>)) =&gt; {
has_compute_unit_limit = <span class="bool-val">true
</span>}
<span class="prelude-val">Ok</span>(ComputeBudgetInstruction::SetComputeUnitPrice(<span class="kw">_</span>)) =&gt; {
has_compute_unit_price = <span class="bool-val">true
</span>}
<span class="kw">_ </span>=&gt; {}
}
}
<span class="kw">let </span>cu_per_ix = <span class="self">self</span>.config.compute_budget_per_instruction.unwrap_or(<span class="number">0</span>);
<span class="kw">if </span>!has_compute_unit_limit &amp;&amp; cu_per_ix &gt; <span class="number">0 </span>{
<span class="kw">let </span>ix_count: u32 = (ixs.len() - cu_instructions).try_into().unwrap();
ixs.insert(
<span class="number">0</span>,
ComputeBudgetInstruction::set_compute_unit_limit(cu_per_ix * ix_count),
);
}
<span class="kw">let </span>cu_prio = <span class="self">self
</span>.config
.priority_fee_provider
.as_ref()
.map(|provider| provider.compute_unit_fee_microlamports())
.unwrap_or(<span class="number">0</span>);
<span class="kw">if </span>!has_compute_unit_price &amp;&amp; cu_prio &gt; <span class="number">0 </span>{
ixs.insert(<span class="number">0</span>, ComputeBudgetInstruction::set_compute_unit_price(cu_prio));
}
ixs
}
<span class="kw">pub fn </span>transaction_with_blockhash(
<span class="kw-2">&amp;</span><span class="self">self</span>,
blockhash: Hash,
) -&gt; anyhow::Result&lt;solana_sdk::transaction::VersionedTransaction&gt; {
<span class="kw">let </span>ixs = <span class="self">self</span>.instructions_with_cu_budget();
<span class="kw">let </span>v0_message = solana_sdk::message::v0::Message::try_compile(
<span class="kw-2">&amp;</span><span class="self">self</span>.payer,
<span class="kw-2">&amp;</span>ixs,
<span class="kw-2">&amp;</span><span class="self">self</span>.address_lookup_tables,
blockhash,
)<span class="question-mark">?</span>;
<span class="kw">let </span>versioned_message = solana_sdk::message::VersionedMessage::V0(v0_message);
<span class="kw">let </span>signers = <span class="self">self
</span>.signers
.iter()
.unique_by(|s| s.pubkey())
.map(|v| v.deref())
.collect::&lt;Vec&lt;<span class="kw">_</span>&gt;&gt;();
<span class="kw">let </span>tx =
solana_sdk::transaction::VersionedTransaction::try_new(versioned_message, <span class="kw-2">&amp;</span>signers)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(tx)
}
<span class="comment">// These two send() functions don&#39;t really belong into the transaction builder!
</span><span class="kw">pub async fn </span>send(<span class="kw-2">&amp;</span><span class="self">self</span>, client: <span class="kw-2">&amp;</span>Client) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>rpc = client.rpc_async();
<span class="kw">let </span>tx = <span class="self">self</span>.transaction(<span class="kw-2">&amp;</span>rpc).<span class="kw">await</span><span class="question-mark">?</span>;
client.send_transaction(<span class="kw-2">&amp;</span>tx).<span class="kw">await
</span>}
<span class="kw">pub async fn </span>simulate(<span class="kw-2">&amp;</span><span class="self">self</span>, client: <span class="kw-2">&amp;</span>Client) -&gt; anyhow::Result&lt;SimulateTransactionResponse&gt; {
<span class="kw">let </span>rpc = client.rpc_async();
<span class="kw">let </span>tx = <span class="self">self</span>.transaction(<span class="kw-2">&amp;</span>rpc).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(rpc.simulate_transaction(<span class="kw-2">&amp;</span>tx).<span class="kw">await</span><span class="question-mark">?</span>)
}
<span class="kw">pub async fn </span>send_and_confirm(<span class="kw-2">&amp;</span><span class="self">self</span>, client: <span class="kw-2">&amp;</span>Client) -&gt; anyhow::Result&lt;Signature&gt; {
<span class="kw">let </span>rpc = client.rpc_async();
<span class="kw">let </span>tx = <span class="self">self</span>.transaction(<span class="kw-2">&amp;</span>rpc).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let </span>recent_blockhash = tx.message.recent_blockhash();
<span class="kw">let </span>signature = client.send_transaction(<span class="kw-2">&amp;</span>tx).<span class="kw">await</span><span class="question-mark">?</span>;
wait_for_transaction_confirmation(
<span class="kw-2">&amp;</span>rpc,
<span class="kw-2">&amp;</span>signature,
recent_blockhash,
<span class="kw-2">&amp;</span>client.config.rpc_confirm_transaction_config,
)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(signature)
}
<span class="kw">pub fn </span>transaction_size(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; anyhow::Result&lt;TransactionSize&gt; {
<span class="kw">let </span>tx = <span class="self">self</span>.transaction_with_blockhash(solana_sdk::hash::Hash::default())<span class="question-mark">?</span>;
<span class="kw">let </span>bytes = bincode::serialize(<span class="kw-2">&amp;</span>tx)<span class="question-mark">?</span>;
<span class="kw">let </span>accounts = tx.message.static_account_keys().len()
+ tx.message
.address_table_lookups()
.map(|alts| {
alts.iter()
.map(|alt| alt.readonly_indexes.len() + alt.writable_indexes.len())
.sum()
})
.unwrap_or(<span class="number">0</span>);
<span class="prelude-val">Ok</span>(TransactionSize {
accounts,
length: bytes.len(),
})
}
<span class="kw">pub fn </span>append(<span class="kw-2">&amp;mut </span><span class="self">self</span>, prepared_instructions: PreparedInstructions) {
<span class="self">self</span>.instructions
.extend(prepared_instructions.to_instructions());
}
}
<span class="doccomment">/// Do some manual unpacking on some ClientErrors
///
/// Unfortunately solana&#39;s RpcResponseError will very unhelpfully print [N log messages]
/// instead of showing the actual log messages. This unpacks the error to provide more useful
/// output.
</span><span class="kw">pub fn </span>prettify_client_error(err: anchor_client::ClientError) -&gt; anyhow::Error {
<span class="kw">match </span>err {
anchor_client::ClientError::SolanaClientError(c) =&gt; prettify_solana_client_error(c),
<span class="kw">_ </span>=&gt; err.into(),
}
}
<span class="kw">pub fn </span>prettify_solana_client_error(
err: solana_client::client_error::ClientError,
) -&gt; anyhow::Error {
<span class="kw">use </span>solana_client::client_error::ClientErrorKind;
<span class="kw">use </span>solana_client::rpc_request::{RpcError, RpcResponseErrorData};
<span class="kw">match </span>err.kind() {
ClientErrorKind::RpcError(RpcError::RpcResponseError { data, .. }) =&gt; <span class="kw">match </span>data {
RpcResponseErrorData::SendTransactionPreflightFailure(s) =&gt; {
<span class="kw">return </span>MangoClientError::SendTransactionPreflightFailure {
err: s.err.clone(),
logs: s.logs.clone().unwrap_or_default(),
}
.into();
}
<span class="kw">_ </span>=&gt; {}
},
<span class="kw">_ </span>=&gt; {}
};
err.into()
}
<span class="attr">#[derive(Clone, Copy)]
</span><span class="kw">pub enum </span>JupiterSwapMode {
ExactIn,
ExactOut,
}
<span class="kw">pub fn </span>keypair_from_cli(keypair: <span class="kw-2">&amp;</span>str) -&gt; Keypair {
<span class="kw">let </span>maybe_keypair = keypair::read_keypair(<span class="kw-2">&amp;mut </span>keypair.as_bytes());
<span class="kw">match </span>maybe_keypair {
<span class="prelude-val">Ok</span>(keypair) =&gt; keypair,
<span class="prelude-val">Err</span>(<span class="kw">_</span>) =&gt; {
<span class="kw">let </span>path = std::path::PathBuf::from_str(<span class="kw-2">&amp;*</span>shellexpand::tilde(keypair)).unwrap();
keypair::read_keypair_file(path)
.unwrap_or_else(|<span class="kw">_</span>| <span class="macro">panic!</span>(<span class="string">&quot;Failed to read keypair from {}&quot;</span>, keypair))
}
}
}
<span class="kw">pub fn </span>pubkey_from_cli(pubkey: <span class="kw-2">&amp;</span>str) -&gt; Pubkey {
<span class="kw">match </span>Pubkey::from_str(pubkey) {
<span class="prelude-val">Ok</span>(p) =&gt; p,
<span class="prelude-val">Err</span>(<span class="kw">_</span>) =&gt; keypair_from_cli(pubkey).pubkey(),
}
}
</code></pre></div></section></main></body></html>