Files
zclaw_openfang/desktop/coverage/src/lib/agent-swarm.ts.html
iven d0c6319fc1
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
feat: 添加ESLint和Prettier配置并优化代码结构
style: 格式化代码文件并修复样式问题

docs: 新增部署文档和系统要求文档

test: 更新测试截图和覆盖率报告

refactor: 重构SchedulerPanel加载状态逻辑

ci: 添加lint和format脚本到package.json

build: 更新依赖项并添加开发工具

chore: 添加验证报告和上线审查计划
2026-03-26 08:02:23 +08:00

1732 lines
89 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>
<title>Code coverage report for src/lib/agent-swarm.ts</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../../prettify.css" />
<link rel="stylesheet" href="../../base.css" />
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(../../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1><a href="../../index.html">All files</a> / <a href="index.html">src/lib</a> agent-swarm.ts</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Statements</span>
<span class='fraction'>0/341</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/1</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/1</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Lines</span>
<span class='fraction'>0/341</span>
</div>
</div>
<p class="quiet">
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
</p>
<template id="filterTemplate">
<div class="quiet">
Filter:
<input type="search" id="fileSearch">
</div>
</template>
</div>
<div class='status-line low'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
<a name='L2'></a><a href='#L2'>2</a>
<a name='L3'></a><a href='#L3'>3</a>
<a name='L4'></a><a href='#L4'>4</a>
<a name='L5'></a><a href='#L5'>5</a>
<a name='L6'></a><a href='#L6'>6</a>
<a name='L7'></a><a href='#L7'>7</a>
<a name='L8'></a><a href='#L8'>8</a>
<a name='L9'></a><a href='#L9'>9</a>
<a name='L10'></a><a href='#L10'>10</a>
<a name='L11'></a><a href='#L11'>11</a>
<a name='L12'></a><a href='#L12'>12</a>
<a name='L13'></a><a href='#L13'>13</a>
<a name='L14'></a><a href='#L14'>14</a>
<a name='L15'></a><a href='#L15'>15</a>
<a name='L16'></a><a href='#L16'>16</a>
<a name='L17'></a><a href='#L17'>17</a>
<a name='L18'></a><a href='#L18'>18</a>
<a name='L19'></a><a href='#L19'>19</a>
<a name='L20'></a><a href='#L20'>20</a>
<a name='L21'></a><a href='#L21'>21</a>
<a name='L22'></a><a href='#L22'>22</a>
<a name='L23'></a><a href='#L23'>23</a>
<a name='L24'></a><a href='#L24'>24</a>
<a name='L25'></a><a href='#L25'>25</a>
<a name='L26'></a><a href='#L26'>26</a>
<a name='L27'></a><a href='#L27'>27</a>
<a name='L28'></a><a href='#L28'>28</a>
<a name='L29'></a><a href='#L29'>29</a>
<a name='L30'></a><a href='#L30'>30</a>
<a name='L31'></a><a href='#L31'>31</a>
<a name='L32'></a><a href='#L32'>32</a>
<a name='L33'></a><a href='#L33'>33</a>
<a name='L34'></a><a href='#L34'>34</a>
<a name='L35'></a><a href='#L35'>35</a>
<a name='L36'></a><a href='#L36'>36</a>
<a name='L37'></a><a href='#L37'>37</a>
<a name='L38'></a><a href='#L38'>38</a>
<a name='L39'></a><a href='#L39'>39</a>
<a name='L40'></a><a href='#L40'>40</a>
<a name='L41'></a><a href='#L41'>41</a>
<a name='L42'></a><a href='#L42'>42</a>
<a name='L43'></a><a href='#L43'>43</a>
<a name='L44'></a><a href='#L44'>44</a>
<a name='L45'></a><a href='#L45'>45</a>
<a name='L46'></a><a href='#L46'>46</a>
<a name='L47'></a><a href='#L47'>47</a>
<a name='L48'></a><a href='#L48'>48</a>
<a name='L49'></a><a href='#L49'>49</a>
<a name='L50'></a><a href='#L50'>50</a>
<a name='L51'></a><a href='#L51'>51</a>
<a name='L52'></a><a href='#L52'>52</a>
<a name='L53'></a><a href='#L53'>53</a>
<a name='L54'></a><a href='#L54'>54</a>
<a name='L55'></a><a href='#L55'>55</a>
<a name='L56'></a><a href='#L56'>56</a>
<a name='L57'></a><a href='#L57'>57</a>
<a name='L58'></a><a href='#L58'>58</a>
<a name='L59'></a><a href='#L59'>59</a>
<a name='L60'></a><a href='#L60'>60</a>
<a name='L61'></a><a href='#L61'>61</a>
<a name='L62'></a><a href='#L62'>62</a>
<a name='L63'></a><a href='#L63'>63</a>
<a name='L64'></a><a href='#L64'>64</a>
<a name='L65'></a><a href='#L65'>65</a>
<a name='L66'></a><a href='#L66'>66</a>
<a name='L67'></a><a href='#L67'>67</a>
<a name='L68'></a><a href='#L68'>68</a>
<a name='L69'></a><a href='#L69'>69</a>
<a name='L70'></a><a href='#L70'>70</a>
<a name='L71'></a><a href='#L71'>71</a>
<a name='L72'></a><a href='#L72'>72</a>
<a name='L73'></a><a href='#L73'>73</a>
<a name='L74'></a><a href='#L74'>74</a>
<a name='L75'></a><a href='#L75'>75</a>
<a name='L76'></a><a href='#L76'>76</a>
<a name='L77'></a><a href='#L77'>77</a>
<a name='L78'></a><a href='#L78'>78</a>
<a name='L79'></a><a href='#L79'>79</a>
<a name='L80'></a><a href='#L80'>80</a>
<a name='L81'></a><a href='#L81'>81</a>
<a name='L82'></a><a href='#L82'>82</a>
<a name='L83'></a><a href='#L83'>83</a>
<a name='L84'></a><a href='#L84'>84</a>
<a name='L85'></a><a href='#L85'>85</a>
<a name='L86'></a><a href='#L86'>86</a>
<a name='L87'></a><a href='#L87'>87</a>
<a name='L88'></a><a href='#L88'>88</a>
<a name='L89'></a><a href='#L89'>89</a>
<a name='L90'></a><a href='#L90'>90</a>
<a name='L91'></a><a href='#L91'>91</a>
<a name='L92'></a><a href='#L92'>92</a>
<a name='L93'></a><a href='#L93'>93</a>
<a name='L94'></a><a href='#L94'>94</a>
<a name='L95'></a><a href='#L95'>95</a>
<a name='L96'></a><a href='#L96'>96</a>
<a name='L97'></a><a href='#L97'>97</a>
<a name='L98'></a><a href='#L98'>98</a>
<a name='L99'></a><a href='#L99'>99</a>
<a name='L100'></a><a href='#L100'>100</a>
<a name='L101'></a><a href='#L101'>101</a>
<a name='L102'></a><a href='#L102'>102</a>
<a name='L103'></a><a href='#L103'>103</a>
<a name='L104'></a><a href='#L104'>104</a>
<a name='L105'></a><a href='#L105'>105</a>
<a name='L106'></a><a href='#L106'>106</a>
<a name='L107'></a><a href='#L107'>107</a>
<a name='L108'></a><a href='#L108'>108</a>
<a name='L109'></a><a href='#L109'>109</a>
<a name='L110'></a><a href='#L110'>110</a>
<a name='L111'></a><a href='#L111'>111</a>
<a name='L112'></a><a href='#L112'>112</a>
<a name='L113'></a><a href='#L113'>113</a>
<a name='L114'></a><a href='#L114'>114</a>
<a name='L115'></a><a href='#L115'>115</a>
<a name='L116'></a><a href='#L116'>116</a>
<a name='L117'></a><a href='#L117'>117</a>
<a name='L118'></a><a href='#L118'>118</a>
<a name='L119'></a><a href='#L119'>119</a>
<a name='L120'></a><a href='#L120'>120</a>
<a name='L121'></a><a href='#L121'>121</a>
<a name='L122'></a><a href='#L122'>122</a>
<a name='L123'></a><a href='#L123'>123</a>
<a name='L124'></a><a href='#L124'>124</a>
<a name='L125'></a><a href='#L125'>125</a>
<a name='L126'></a><a href='#L126'>126</a>
<a name='L127'></a><a href='#L127'>127</a>
<a name='L128'></a><a href='#L128'>128</a>
<a name='L129'></a><a href='#L129'>129</a>
<a name='L130'></a><a href='#L130'>130</a>
<a name='L131'></a><a href='#L131'>131</a>
<a name='L132'></a><a href='#L132'>132</a>
<a name='L133'></a><a href='#L133'>133</a>
<a name='L134'></a><a href='#L134'>134</a>
<a name='L135'></a><a href='#L135'>135</a>
<a name='L136'></a><a href='#L136'>136</a>
<a name='L137'></a><a href='#L137'>137</a>
<a name='L138'></a><a href='#L138'>138</a>
<a name='L139'></a><a href='#L139'>139</a>
<a name='L140'></a><a href='#L140'>140</a>
<a name='L141'></a><a href='#L141'>141</a>
<a name='L142'></a><a href='#L142'>142</a>
<a name='L143'></a><a href='#L143'>143</a>
<a name='L144'></a><a href='#L144'>144</a>
<a name='L145'></a><a href='#L145'>145</a>
<a name='L146'></a><a href='#L146'>146</a>
<a name='L147'></a><a href='#L147'>147</a>
<a name='L148'></a><a href='#L148'>148</a>
<a name='L149'></a><a href='#L149'>149</a>
<a name='L150'></a><a href='#L150'>150</a>
<a name='L151'></a><a href='#L151'>151</a>
<a name='L152'></a><a href='#L152'>152</a>
<a name='L153'></a><a href='#L153'>153</a>
<a name='L154'></a><a href='#L154'>154</a>
<a name='L155'></a><a href='#L155'>155</a>
<a name='L156'></a><a href='#L156'>156</a>
<a name='L157'></a><a href='#L157'>157</a>
<a name='L158'></a><a href='#L158'>158</a>
<a name='L159'></a><a href='#L159'>159</a>
<a name='L160'></a><a href='#L160'>160</a>
<a name='L161'></a><a href='#L161'>161</a>
<a name='L162'></a><a href='#L162'>162</a>
<a name='L163'></a><a href='#L163'>163</a>
<a name='L164'></a><a href='#L164'>164</a>
<a name='L165'></a><a href='#L165'>165</a>
<a name='L166'></a><a href='#L166'>166</a>
<a name='L167'></a><a href='#L167'>167</a>
<a name='L168'></a><a href='#L168'>168</a>
<a name='L169'></a><a href='#L169'>169</a>
<a name='L170'></a><a href='#L170'>170</a>
<a name='L171'></a><a href='#L171'>171</a>
<a name='L172'></a><a href='#L172'>172</a>
<a name='L173'></a><a href='#L173'>173</a>
<a name='L174'></a><a href='#L174'>174</a>
<a name='L175'></a><a href='#L175'>175</a>
<a name='L176'></a><a href='#L176'>176</a>
<a name='L177'></a><a href='#L177'>177</a>
<a name='L178'></a><a href='#L178'>178</a>
<a name='L179'></a><a href='#L179'>179</a>
<a name='L180'></a><a href='#L180'>180</a>
<a name='L181'></a><a href='#L181'>181</a>
<a name='L182'></a><a href='#L182'>182</a>
<a name='L183'></a><a href='#L183'>183</a>
<a name='L184'></a><a href='#L184'>184</a>
<a name='L185'></a><a href='#L185'>185</a>
<a name='L186'></a><a href='#L186'>186</a>
<a name='L187'></a><a href='#L187'>187</a>
<a name='L188'></a><a href='#L188'>188</a>
<a name='L189'></a><a href='#L189'>189</a>
<a name='L190'></a><a href='#L190'>190</a>
<a name='L191'></a><a href='#L191'>191</a>
<a name='L192'></a><a href='#L192'>192</a>
<a name='L193'></a><a href='#L193'>193</a>
<a name='L194'></a><a href='#L194'>194</a>
<a name='L195'></a><a href='#L195'>195</a>
<a name='L196'></a><a href='#L196'>196</a>
<a name='L197'></a><a href='#L197'>197</a>
<a name='L198'></a><a href='#L198'>198</a>
<a name='L199'></a><a href='#L199'>199</a>
<a name='L200'></a><a href='#L200'>200</a>
<a name='L201'></a><a href='#L201'>201</a>
<a name='L202'></a><a href='#L202'>202</a>
<a name='L203'></a><a href='#L203'>203</a>
<a name='L204'></a><a href='#L204'>204</a>
<a name='L205'></a><a href='#L205'>205</a>
<a name='L206'></a><a href='#L206'>206</a>
<a name='L207'></a><a href='#L207'>207</a>
<a name='L208'></a><a href='#L208'>208</a>
<a name='L209'></a><a href='#L209'>209</a>
<a name='L210'></a><a href='#L210'>210</a>
<a name='L211'></a><a href='#L211'>211</a>
<a name='L212'></a><a href='#L212'>212</a>
<a name='L213'></a><a href='#L213'>213</a>
<a name='L214'></a><a href='#L214'>214</a>
<a name='L215'></a><a href='#L215'>215</a>
<a name='L216'></a><a href='#L216'>216</a>
<a name='L217'></a><a href='#L217'>217</a>
<a name='L218'></a><a href='#L218'>218</a>
<a name='L219'></a><a href='#L219'>219</a>
<a name='L220'></a><a href='#L220'>220</a>
<a name='L221'></a><a href='#L221'>221</a>
<a name='L222'></a><a href='#L222'>222</a>
<a name='L223'></a><a href='#L223'>223</a>
<a name='L224'></a><a href='#L224'>224</a>
<a name='L225'></a><a href='#L225'>225</a>
<a name='L226'></a><a href='#L226'>226</a>
<a name='L227'></a><a href='#L227'>227</a>
<a name='L228'></a><a href='#L228'>228</a>
<a name='L229'></a><a href='#L229'>229</a>
<a name='L230'></a><a href='#L230'>230</a>
<a name='L231'></a><a href='#L231'>231</a>
<a name='L232'></a><a href='#L232'>232</a>
<a name='L233'></a><a href='#L233'>233</a>
<a name='L234'></a><a href='#L234'>234</a>
<a name='L235'></a><a href='#L235'>235</a>
<a name='L236'></a><a href='#L236'>236</a>
<a name='L237'></a><a href='#L237'>237</a>
<a name='L238'></a><a href='#L238'>238</a>
<a name='L239'></a><a href='#L239'>239</a>
<a name='L240'></a><a href='#L240'>240</a>
<a name='L241'></a><a href='#L241'>241</a>
<a name='L242'></a><a href='#L242'>242</a>
<a name='L243'></a><a href='#L243'>243</a>
<a name='L244'></a><a href='#L244'>244</a>
<a name='L245'></a><a href='#L245'>245</a>
<a name='L246'></a><a href='#L246'>246</a>
<a name='L247'></a><a href='#L247'>247</a>
<a name='L248'></a><a href='#L248'>248</a>
<a name='L249'></a><a href='#L249'>249</a>
<a name='L250'></a><a href='#L250'>250</a>
<a name='L251'></a><a href='#L251'>251</a>
<a name='L252'></a><a href='#L252'>252</a>
<a name='L253'></a><a href='#L253'>253</a>
<a name='L254'></a><a href='#L254'>254</a>
<a name='L255'></a><a href='#L255'>255</a>
<a name='L256'></a><a href='#L256'>256</a>
<a name='L257'></a><a href='#L257'>257</a>
<a name='L258'></a><a href='#L258'>258</a>
<a name='L259'></a><a href='#L259'>259</a>
<a name='L260'></a><a href='#L260'>260</a>
<a name='L261'></a><a href='#L261'>261</a>
<a name='L262'></a><a href='#L262'>262</a>
<a name='L263'></a><a href='#L263'>263</a>
<a name='L264'></a><a href='#L264'>264</a>
<a name='L265'></a><a href='#L265'>265</a>
<a name='L266'></a><a href='#L266'>266</a>
<a name='L267'></a><a href='#L267'>267</a>
<a name='L268'></a><a href='#L268'>268</a>
<a name='L269'></a><a href='#L269'>269</a>
<a name='L270'></a><a href='#L270'>270</a>
<a name='L271'></a><a href='#L271'>271</a>
<a name='L272'></a><a href='#L272'>272</a>
<a name='L273'></a><a href='#L273'>273</a>
<a name='L274'></a><a href='#L274'>274</a>
<a name='L275'></a><a href='#L275'>275</a>
<a name='L276'></a><a href='#L276'>276</a>
<a name='L277'></a><a href='#L277'>277</a>
<a name='L278'></a><a href='#L278'>278</a>
<a name='L279'></a><a href='#L279'>279</a>
<a name='L280'></a><a href='#L280'>280</a>
<a name='L281'></a><a href='#L281'>281</a>
<a name='L282'></a><a href='#L282'>282</a>
<a name='L283'></a><a href='#L283'>283</a>
<a name='L284'></a><a href='#L284'>284</a>
<a name='L285'></a><a href='#L285'>285</a>
<a name='L286'></a><a href='#L286'>286</a>
<a name='L287'></a><a href='#L287'>287</a>
<a name='L288'></a><a href='#L288'>288</a>
<a name='L289'></a><a href='#L289'>289</a>
<a name='L290'></a><a href='#L290'>290</a>
<a name='L291'></a><a href='#L291'>291</a>
<a name='L292'></a><a href='#L292'>292</a>
<a name='L293'></a><a href='#L293'>293</a>
<a name='L294'></a><a href='#L294'>294</a>
<a name='L295'></a><a href='#L295'>295</a>
<a name='L296'></a><a href='#L296'>296</a>
<a name='L297'></a><a href='#L297'>297</a>
<a name='L298'></a><a href='#L298'>298</a>
<a name='L299'></a><a href='#L299'>299</a>
<a name='L300'></a><a href='#L300'>300</a>
<a name='L301'></a><a href='#L301'>301</a>
<a name='L302'></a><a href='#L302'>302</a>
<a name='L303'></a><a href='#L303'>303</a>
<a name='L304'></a><a href='#L304'>304</a>
<a name='L305'></a><a href='#L305'>305</a>
<a name='L306'></a><a href='#L306'>306</a>
<a name='L307'></a><a href='#L307'>307</a>
<a name='L308'></a><a href='#L308'>308</a>
<a name='L309'></a><a href='#L309'>309</a>
<a name='L310'></a><a href='#L310'>310</a>
<a name='L311'></a><a href='#L311'>311</a>
<a name='L312'></a><a href='#L312'>312</a>
<a name='L313'></a><a href='#L313'>313</a>
<a name='L314'></a><a href='#L314'>314</a>
<a name='L315'></a><a href='#L315'>315</a>
<a name='L316'></a><a href='#L316'>316</a>
<a name='L317'></a><a href='#L317'>317</a>
<a name='L318'></a><a href='#L318'>318</a>
<a name='L319'></a><a href='#L319'>319</a>
<a name='L320'></a><a href='#L320'>320</a>
<a name='L321'></a><a href='#L321'>321</a>
<a name='L322'></a><a href='#L322'>322</a>
<a name='L323'></a><a href='#L323'>323</a>
<a name='L324'></a><a href='#L324'>324</a>
<a name='L325'></a><a href='#L325'>325</a>
<a name='L326'></a><a href='#L326'>326</a>
<a name='L327'></a><a href='#L327'>327</a>
<a name='L328'></a><a href='#L328'>328</a>
<a name='L329'></a><a href='#L329'>329</a>
<a name='L330'></a><a href='#L330'>330</a>
<a name='L331'></a><a href='#L331'>331</a>
<a name='L332'></a><a href='#L332'>332</a>
<a name='L333'></a><a href='#L333'>333</a>
<a name='L334'></a><a href='#L334'>334</a>
<a name='L335'></a><a href='#L335'>335</a>
<a name='L336'></a><a href='#L336'>336</a>
<a name='L337'></a><a href='#L337'>337</a>
<a name='L338'></a><a href='#L338'>338</a>
<a name='L339'></a><a href='#L339'>339</a>
<a name='L340'></a><a href='#L340'>340</a>
<a name='L341'></a><a href='#L341'>341</a>
<a name='L342'></a><a href='#L342'>342</a>
<a name='L343'></a><a href='#L343'>343</a>
<a name='L344'></a><a href='#L344'>344</a>
<a name='L345'></a><a href='#L345'>345</a>
<a name='L346'></a><a href='#L346'>346</a>
<a name='L347'></a><a href='#L347'>347</a>
<a name='L348'></a><a href='#L348'>348</a>
<a name='L349'></a><a href='#L349'>349</a>
<a name='L350'></a><a href='#L350'>350</a>
<a name='L351'></a><a href='#L351'>351</a>
<a name='L352'></a><a href='#L352'>352</a>
<a name='L353'></a><a href='#L353'>353</a>
<a name='L354'></a><a href='#L354'>354</a>
<a name='L355'></a><a href='#L355'>355</a>
<a name='L356'></a><a href='#L356'>356</a>
<a name='L357'></a><a href='#L357'>357</a>
<a name='L358'></a><a href='#L358'>358</a>
<a name='L359'></a><a href='#L359'>359</a>
<a name='L360'></a><a href='#L360'>360</a>
<a name='L361'></a><a href='#L361'>361</a>
<a name='L362'></a><a href='#L362'>362</a>
<a name='L363'></a><a href='#L363'>363</a>
<a name='L364'></a><a href='#L364'>364</a>
<a name='L365'></a><a href='#L365'>365</a>
<a name='L366'></a><a href='#L366'>366</a>
<a name='L367'></a><a href='#L367'>367</a>
<a name='L368'></a><a href='#L368'>368</a>
<a name='L369'></a><a href='#L369'>369</a>
<a name='L370'></a><a href='#L370'>370</a>
<a name='L371'></a><a href='#L371'>371</a>
<a name='L372'></a><a href='#L372'>372</a>
<a name='L373'></a><a href='#L373'>373</a>
<a name='L374'></a><a href='#L374'>374</a>
<a name='L375'></a><a href='#L375'>375</a>
<a name='L376'></a><a href='#L376'>376</a>
<a name='L377'></a><a href='#L377'>377</a>
<a name='L378'></a><a href='#L378'>378</a>
<a name='L379'></a><a href='#L379'>379</a>
<a name='L380'></a><a href='#L380'>380</a>
<a name='L381'></a><a href='#L381'>381</a>
<a name='L382'></a><a href='#L382'>382</a>
<a name='L383'></a><a href='#L383'>383</a>
<a name='L384'></a><a href='#L384'>384</a>
<a name='L385'></a><a href='#L385'>385</a>
<a name='L386'></a><a href='#L386'>386</a>
<a name='L387'></a><a href='#L387'>387</a>
<a name='L388'></a><a href='#L388'>388</a>
<a name='L389'></a><a href='#L389'>389</a>
<a name='L390'></a><a href='#L390'>390</a>
<a name='L391'></a><a href='#L391'>391</a>
<a name='L392'></a><a href='#L392'>392</a>
<a name='L393'></a><a href='#L393'>393</a>
<a name='L394'></a><a href='#L394'>394</a>
<a name='L395'></a><a href='#L395'>395</a>
<a name='L396'></a><a href='#L396'>396</a>
<a name='L397'></a><a href='#L397'>397</a>
<a name='L398'></a><a href='#L398'>398</a>
<a name='L399'></a><a href='#L399'>399</a>
<a name='L400'></a><a href='#L400'>400</a>
<a name='L401'></a><a href='#L401'>401</a>
<a name='L402'></a><a href='#L402'>402</a>
<a name='L403'></a><a href='#L403'>403</a>
<a name='L404'></a><a href='#L404'>404</a>
<a name='L405'></a><a href='#L405'>405</a>
<a name='L406'></a><a href='#L406'>406</a>
<a name='L407'></a><a href='#L407'>407</a>
<a name='L408'></a><a href='#L408'>408</a>
<a name='L409'></a><a href='#L409'>409</a>
<a name='L410'></a><a href='#L410'>410</a>
<a name='L411'></a><a href='#L411'>411</a>
<a name='L412'></a><a href='#L412'>412</a>
<a name='L413'></a><a href='#L413'>413</a>
<a name='L414'></a><a href='#L414'>414</a>
<a name='L415'></a><a href='#L415'>415</a>
<a name='L416'></a><a href='#L416'>416</a>
<a name='L417'></a><a href='#L417'>417</a>
<a name='L418'></a><a href='#L418'>418</a>
<a name='L419'></a><a href='#L419'>419</a>
<a name='L420'></a><a href='#L420'>420</a>
<a name='L421'></a><a href='#L421'>421</a>
<a name='L422'></a><a href='#L422'>422</a>
<a name='L423'></a><a href='#L423'>423</a>
<a name='L424'></a><a href='#L424'>424</a>
<a name='L425'></a><a href='#L425'>425</a>
<a name='L426'></a><a href='#L426'>426</a>
<a name='L427'></a><a href='#L427'>427</a>
<a name='L428'></a><a href='#L428'>428</a>
<a name='L429'></a><a href='#L429'>429</a>
<a name='L430'></a><a href='#L430'>430</a>
<a name='L431'></a><a href='#L431'>431</a>
<a name='L432'></a><a href='#L432'>432</a>
<a name='L433'></a><a href='#L433'>433</a>
<a name='L434'></a><a href='#L434'>434</a>
<a name='L435'></a><a href='#L435'>435</a>
<a name='L436'></a><a href='#L436'>436</a>
<a name='L437'></a><a href='#L437'>437</a>
<a name='L438'></a><a href='#L438'>438</a>
<a name='L439'></a><a href='#L439'>439</a>
<a name='L440'></a><a href='#L440'>440</a>
<a name='L441'></a><a href='#L441'>441</a>
<a name='L442'></a><a href='#L442'>442</a>
<a name='L443'></a><a href='#L443'>443</a>
<a name='L444'></a><a href='#L444'>444</a>
<a name='L445'></a><a href='#L445'>445</a>
<a name='L446'></a><a href='#L446'>446</a>
<a name='L447'></a><a href='#L447'>447</a>
<a name='L448'></a><a href='#L448'>448</a>
<a name='L449'></a><a href='#L449'>449</a>
<a name='L450'></a><a href='#L450'>450</a>
<a name='L451'></a><a href='#L451'>451</a>
<a name='L452'></a><a href='#L452'>452</a>
<a name='L453'></a><a href='#L453'>453</a>
<a name='L454'></a><a href='#L454'>454</a>
<a name='L455'></a><a href='#L455'>455</a>
<a name='L456'></a><a href='#L456'>456</a>
<a name='L457'></a><a href='#L457'>457</a>
<a name='L458'></a><a href='#L458'>458</a>
<a name='L459'></a><a href='#L459'>459</a>
<a name='L460'></a><a href='#L460'>460</a>
<a name='L461'></a><a href='#L461'>461</a>
<a name='L462'></a><a href='#L462'>462</a>
<a name='L463'></a><a href='#L463'>463</a>
<a name='L464'></a><a href='#L464'>464</a>
<a name='L465'></a><a href='#L465'>465</a>
<a name='L466'></a><a href='#L466'>466</a>
<a name='L467'></a><a href='#L467'>467</a>
<a name='L468'></a><a href='#L468'>468</a>
<a name='L469'></a><a href='#L469'>469</a>
<a name='L470'></a><a href='#L470'>470</a>
<a name='L471'></a><a href='#L471'>471</a>
<a name='L472'></a><a href='#L472'>472</a>
<a name='L473'></a><a href='#L473'>473</a>
<a name='L474'></a><a href='#L474'>474</a>
<a name='L475'></a><a href='#L475'>475</a>
<a name='L476'></a><a href='#L476'>476</a>
<a name='L477'></a><a href='#L477'>477</a>
<a name='L478'></a><a href='#L478'>478</a>
<a name='L479'></a><a href='#L479'>479</a>
<a name='L480'></a><a href='#L480'>480</a>
<a name='L481'></a><a href='#L481'>481</a>
<a name='L482'></a><a href='#L482'>482</a>
<a name='L483'></a><a href='#L483'>483</a>
<a name='L484'></a><a href='#L484'>484</a>
<a name='L485'></a><a href='#L485'>485</a>
<a name='L486'></a><a href='#L486'>486</a>
<a name='L487'></a><a href='#L487'>487</a>
<a name='L488'></a><a href='#L488'>488</a>
<a name='L489'></a><a href='#L489'>489</a>
<a name='L490'></a><a href='#L490'>490</a>
<a name='L491'></a><a href='#L491'>491</a>
<a name='L492'></a><a href='#L492'>492</a>
<a name='L493'></a><a href='#L493'>493</a>
<a name='L494'></a><a href='#L494'>494</a>
<a name='L495'></a><a href='#L495'>495</a>
<a name='L496'></a><a href='#L496'>496</a>
<a name='L497'></a><a href='#L497'>497</a>
<a name='L498'></a><a href='#L498'>498</a>
<a name='L499'></a><a href='#L499'>499</a>
<a name='L500'></a><a href='#L500'>500</a>
<a name='L501'></a><a href='#L501'>501</a>
<a name='L502'></a><a href='#L502'>502</a>
<a name='L503'></a><a href='#L503'>503</a>
<a name='L504'></a><a href='#L504'>504</a>
<a name='L505'></a><a href='#L505'>505</a>
<a name='L506'></a><a href='#L506'>506</a>
<a name='L507'></a><a href='#L507'>507</a>
<a name='L508'></a><a href='#L508'>508</a>
<a name='L509'></a><a href='#L509'>509</a>
<a name='L510'></a><a href='#L510'>510</a>
<a name='L511'></a><a href='#L511'>511</a>
<a name='L512'></a><a href='#L512'>512</a>
<a name='L513'></a><a href='#L513'>513</a>
<a name='L514'></a><a href='#L514'>514</a>
<a name='L515'></a><a href='#L515'>515</a>
<a name='L516'></a><a href='#L516'>516</a>
<a name='L517'></a><a href='#L517'>517</a>
<a name='L518'></a><a href='#L518'>518</a>
<a name='L519'></a><a href='#L519'>519</a>
<a name='L520'></a><a href='#L520'>520</a>
<a name='L521'></a><a href='#L521'>521</a>
<a name='L522'></a><a href='#L522'>522</a>
<a name='L523'></a><a href='#L523'>523</a>
<a name='L524'></a><a href='#L524'>524</a>
<a name='L525'></a><a href='#L525'>525</a>
<a name='L526'></a><a href='#L526'>526</a>
<a name='L527'></a><a href='#L527'>527</a>
<a name='L528'></a><a href='#L528'>528</a>
<a name='L529'></a><a href='#L529'>529</a>
<a name='L530'></a><a href='#L530'>530</a>
<a name='L531'></a><a href='#L531'>531</a>
<a name='L532'></a><a href='#L532'>532</a>
<a name='L533'></a><a href='#L533'>533</a>
<a name='L534'></a><a href='#L534'>534</a>
<a name='L535'></a><a href='#L535'>535</a>
<a name='L536'></a><a href='#L536'>536</a>
<a name='L537'></a><a href='#L537'>537</a>
<a name='L538'></a><a href='#L538'>538</a>
<a name='L539'></a><a href='#L539'>539</a>
<a name='L540'></a><a href='#L540'>540</a>
<a name='L541'></a><a href='#L541'>541</a>
<a name='L542'></a><a href='#L542'>542</a>
<a name='L543'></a><a href='#L543'>543</a>
<a name='L544'></a><a href='#L544'>544</a>
<a name='L545'></a><a href='#L545'>545</a>
<a name='L546'></a><a href='#L546'>546</a>
<a name='L547'></a><a href='#L547'>547</a>
<a name='L548'></a><a href='#L548'>548</a>
<a name='L549'></a><a href='#L549'>549</a>
<a name='L550'></a><a href='#L550'>550</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" >/**<span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" ></span></span></span>
* Agent Swarm - Multi-Agent collaboration framework for ZCLAW
*
* Enables multiple agents (clones) to collaborate on complex tasks through:
* - Sequential: Agents process in chain, each building on the previous
* - Parallel: Agents work simultaneously on different subtasks
* - Debate: Agents provide competing perspectives, coordinator synthesizes
*
* Integrates with existing Clone/Agent infrastructure via agentStore/gatewayStore.
*
* Reference: ZCLAW_AGENT_INTELLIGENCE_EVOLUTION.md §6.5.1
*/
&nbsp;
import { intelligenceClient } from './intelligence-client';
&nbsp;
// === Types ===
&nbsp;
export type CommunicationStyle = 'sequential' | 'parallel' | 'debate';
export type TaskDecomposition = 'auto' | 'manual';
export type SubtaskStatus = 'pending' | 'running' | 'done' | 'failed';
export type SwarmTaskStatus = 'planning' | 'executing' | 'aggregating' | 'done' | 'failed';
&nbsp;
export interface SwarmSpecialist {
agentId: string;
role: string;
capabilities: string[];
model?: string;
}
&nbsp;
export interface SwarmConfig {
coordinator: string;
specialists: SwarmSpecialist[];
taskDecomposition: TaskDecomposition;
communicationStyle: CommunicationStyle;
maxRoundsDebate: number;
timeoutPerSubtaskMs: number;
}
&nbsp;
export interface Subtask {
id: string;
assignedTo: string;
description: string;
status: SubtaskStatus;
result?: string;
error?: string;
startedAt?: string;
completedAt?: string;
round?: number;
}
&nbsp;
export interface SwarmTask {
id: string;
description: string;
subtasks: Subtask[];
status: SwarmTaskStatus;
communicationStyle: CommunicationStyle;
finalResult?: string;
createdAt: string;
completedAt?: string;
metadata?: Record&lt;string, unknown&gt;;
}
&nbsp;
export interface SwarmExecutionResult {
task: SwarmTask;
summary: string;
participantCount: number;
totalDurationMs: number;
}
&nbsp;
export type AgentExecutor = (
agentId: string,
prompt: string,
context?: string
) =&gt; Promise&lt;string&gt;;
&nbsp;
// === Default Config ===
&nbsp;
<span class="cstat-no" title="statement not covered" >export const DEFAULT_SWARM_CONFIG: SwarmConfig = {</span>
<span class="cstat-no" title="statement not covered" > coordinator: 'zclaw-main',</span>
<span class="cstat-no" title="statement not covered" > specialists: [],</span>
<span class="cstat-no" title="statement not covered" > taskDecomposition: 'auto',</span>
<span class="cstat-no" title="statement not covered" > communicationStyle: 'sequential',</span>
<span class="cstat-no" title="statement not covered" > maxRoundsDebate: 3,</span>
<span class="cstat-no" title="statement not covered" > timeoutPerSubtaskMs: 60_000,</span>
<span class="cstat-no" title="statement not covered" >};</span>
&nbsp;
// === Storage ===
&nbsp;
<span class="cstat-no" title="statement not covered" >const SWARM_HISTORY_KEY = 'zclaw-swarm-history';</span>
&nbsp;
// === Swarm Engine ===
&nbsp;
<span class="cstat-no" title="statement not covered" >export class AgentSwarm {</span>
<span class="cstat-no" title="statement not covered" > private config: SwarmConfig;</span>
<span class="cstat-no" title="statement not covered" > private history: SwarmTask[] = [];</span>
<span class="cstat-no" title="statement not covered" > private executor: AgentExecutor | null = null;</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > constructor(config?: Partial&lt;SwarmConfig&gt;) {</span>
<span class="cstat-no" title="statement not covered" > this.config = { ...DEFAULT_SWARM_CONFIG, ...config };</span>
<span class="cstat-no" title="statement not covered" > this.loadHistory();</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
/**
* Set the executor function used to dispatch prompts to individual agents.
* This decouples the swarm from the gateway transport layer.
*/
<span class="cstat-no" title="statement not covered" > setExecutor(executor: AgentExecutor): void {</span>
<span class="cstat-no" title="statement not covered" > this.executor = executor;</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
// === Task Creation ===
&nbsp;
/**
* Create a new swarm task. If taskDecomposition is 'auto', subtasks are
* generated based on specialist capabilities and the task description.
*/
<span class="cstat-no" title="statement not covered" > createTask(</span>
<span class="cstat-no" title="statement not covered" > description: string,</span>
<span class="cstat-no" title="statement not covered" > options?: {</span>
subtasks?: Array&lt;{ assignedTo: string; description: string }&gt;;
communicationStyle?: CommunicationStyle;
metadata?: Record&lt;string, unknown&gt;;
}
<span class="cstat-no" title="statement not covered" > ): SwarmTask {</span>
<span class="cstat-no" title="statement not covered" > const style = options?.communicationStyle || this.config.communicationStyle;</span>
<span class="cstat-no" title="statement not covered" > const taskId = `swarm_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > let subtasks: Subtask[];</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (options?.subtasks &amp;&amp; options.subtasks.length &gt; 0) {</span>
// Manual decomposition
<span class="cstat-no" title="statement not covered" > subtasks = options.subtasks.map((st, i) =&gt; ({</span>
<span class="cstat-no" title="statement not covered" > id: `${taskId}_sub_${i}`,</span>
<span class="cstat-no" title="statement not covered" > assignedTo: st.assignedTo,</span>
<span class="cstat-no" title="statement not covered" > description: st.description,</span>
<span class="cstat-no" title="statement not covered" > status: 'pending' as SubtaskStatus,</span>
<span class="cstat-no" title="statement not covered" > }));</span>
<span class="cstat-no" title="statement not covered" > } else {</span>
// Auto decomposition based on specialists
<span class="cstat-no" title="statement not covered" > subtasks = this.autoDecompose(taskId, description, style);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const task: SwarmTask = {</span>
<span class="cstat-no" title="statement not covered" > id: taskId,</span>
<span class="cstat-no" title="statement not covered" > description,</span>
<span class="cstat-no" title="statement not covered" > subtasks,</span>
<span class="cstat-no" title="statement not covered" > status: 'planning',</span>
<span class="cstat-no" title="statement not covered" > communicationStyle: style,</span>
<span class="cstat-no" title="statement not covered" > createdAt: new Date().toISOString(),</span>
<span class="cstat-no" title="statement not covered" > metadata: options?.metadata,</span>
<span class="cstat-no" title="statement not covered" > };</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > return task;</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
/**
* Execute a swarm task using the configured communication style.
*/
<span class="cstat-no" title="statement not covered" > async execute(task: SwarmTask): Promise&lt;SwarmExecutionResult&gt; {</span>
<span class="cstat-no" title="statement not covered" > if (!this.executor) {</span>
<span class="cstat-no" title="statement not covered" > throw new Error('[AgentSwarm] No executor set. Call setExecutor() first.');</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const startTime = Date.now();</span>
<span class="cstat-no" title="statement not covered" > task.status = 'executing';</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > try {</span>
<span class="cstat-no" title="statement not covered" > switch (task.communicationStyle) {</span>
<span class="cstat-no" title="statement not covered" > case 'sequential':</span>
<span class="cstat-no" title="statement not covered" > await this.executeSequential(task);</span>
<span class="cstat-no" title="statement not covered" > break;</span>
<span class="cstat-no" title="statement not covered" > case 'parallel':</span>
<span class="cstat-no" title="statement not covered" > await this.executeParallel(task);</span>
<span class="cstat-no" title="statement not covered" > break;</span>
<span class="cstat-no" title="statement not covered" > case 'debate':</span>
<span class="cstat-no" title="statement not covered" > await this.executeDebate(task);</span>
<span class="cstat-no" title="statement not covered" > break;</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
// Aggregation phase
<span class="cstat-no" title="statement not covered" > task.status = 'aggregating';</span>
<span class="cstat-no" title="statement not covered" > task.finalResult = await this.aggregate(task);</span>
<span class="cstat-no" title="statement not covered" > task.status = 'done';</span>
<span class="cstat-no" title="statement not covered" > task.completedAt = new Date().toISOString();</span>
<span class="cstat-no" title="statement not covered" > } catch (err) {</span>
<span class="cstat-no" title="statement not covered" > task.status = 'failed';</span>
<span class="cstat-no" title="statement not covered" > task.finalResult = `执行失败: ${err instanceof Error ? err.message : String(err)}`;</span>
<span class="cstat-no" title="statement not covered" > task.completedAt = new Date().toISOString();</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const totalDurationMs = Date.now() - startTime;</span>
&nbsp;
// Store in history
<span class="cstat-no" title="statement not covered" > this.history.push(task);</span>
<span class="cstat-no" title="statement not covered" > if (this.history.length &gt; 50) {</span>
<span class="cstat-no" title="statement not covered" > this.history = this.history.slice(-25);</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > this.saveHistory();</span>
&nbsp;
// Save task result as memory
<span class="cstat-no" title="statement not covered" > try {</span>
<span class="cstat-no" title="statement not covered" > await intelligenceClient.memory.store({</span>
<span class="cstat-no" title="statement not covered" > agent_id: this.config.coordinator,</span>
<span class="cstat-no" title="statement not covered" > memory_type: 'lesson',</span>
<span class="cstat-no" title="statement not covered" > content: `协作任务完成: "${task.description}" — ${task.subtasks.length}个子任务, 模式: ${task.communicationStyle}, 结果: ${(task.finalResult || '').slice(0, 200)}`,</span>
<span class="cstat-no" title="statement not covered" > importance: 6,</span>
<span class="cstat-no" title="statement not covered" > source: 'auto',</span>
<span class="cstat-no" title="statement not covered" > tags: ['swarm', task.communicationStyle],</span>
<span class="cstat-no" title="statement not covered" > });</span>
<span class="cstat-no" title="statement not covered" > } catch { /* non-critical */ }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const result: SwarmExecutionResult = {</span>
<span class="cstat-no" title="statement not covered" > task,</span>
<span class="cstat-no" title="statement not covered" > summary: task.finalResult || '',</span>
<span class="cstat-no" title="statement not covered" > participantCount: new Set(task.subtasks.map(s =&gt; s.assignedTo)).size,</span>
<span class="cstat-no" title="statement not covered" > totalDurationMs,</span>
<span class="cstat-no" title="statement not covered" > };</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > console.log(</span>
<span class="cstat-no" title="statement not covered" > `[AgentSwarm] Task "${task.description}" completed in ${totalDurationMs}ms, ` +</span>
<span class="cstat-no" title="statement not covered" > `${result.participantCount} participants, ${task.subtasks.length} subtasks`</span>
<span class="cstat-no" title="statement not covered" > );</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > return result;</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
// === Execution Strategies ===
&nbsp;
/**
* Sequential: Each agent runs in order, receiving the previous agent's output as context.
*/
<span class="cstat-no" title="statement not covered" > private async executeSequential(task: SwarmTask): Promise&lt;void&gt; {</span>
<span class="cstat-no" title="statement not covered" > let previousResult = '';</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > for (const subtask of task.subtasks) {</span>
<span class="cstat-no" title="statement not covered" > subtask.status = 'running';</span>
<span class="cstat-no" title="statement not covered" > subtask.startedAt = new Date().toISOString();</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > try {</span>
<span class="cstat-no" title="statement not covered" > const context = previousResult</span>
<span class="cstat-no" title="statement not covered" > ? `前一个Agent的输出:\n${previousResult}\n\n请基于以上内容继续完成你的部分。`</span>
<span class="cstat-no" title="statement not covered" > : '';</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const result = await this.executeSubtask(subtask, context);</span>
<span class="cstat-no" title="statement not covered" > subtask.result = result;</span>
<span class="cstat-no" title="statement not covered" > subtask.status = 'done';</span>
<span class="cstat-no" title="statement not covered" > previousResult = result;</span>
<span class="cstat-no" title="statement not covered" > } catch (err) {</span>
<span class="cstat-no" title="statement not covered" > subtask.status = 'failed';</span>
<span class="cstat-no" title="statement not covered" > subtask.error = err instanceof Error ? err.message : String(err);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > subtask.completedAt = new Date().toISOString();</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
/**
* Parallel: All agents run simultaneously, results collected independently.
*/
<span class="cstat-no" title="statement not covered" > private async executeParallel(task: SwarmTask): Promise&lt;void&gt; {</span>
<span class="cstat-no" title="statement not covered" > const promises = task.subtasks.map(async (subtask) =&gt; {</span>
<span class="cstat-no" title="statement not covered" > subtask.status = 'running';</span>
<span class="cstat-no" title="statement not covered" > subtask.startedAt = new Date().toISOString();</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > try {</span>
<span class="cstat-no" title="statement not covered" > const result = await this.executeSubtask(subtask);</span>
<span class="cstat-no" title="statement not covered" > subtask.result = result;</span>
<span class="cstat-no" title="statement not covered" > subtask.status = 'done';</span>
<span class="cstat-no" title="statement not covered" > } catch (err) {</span>
<span class="cstat-no" title="statement not covered" > subtask.status = 'failed';</span>
<span class="cstat-no" title="statement not covered" > subtask.error = err instanceof Error ? err.message : String(err);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > subtask.completedAt = new Date().toISOString();</span>
<span class="cstat-no" title="statement not covered" > });</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > await Promise.allSettled(promises);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
/**
* Debate: All agents respond to the same prompt in multiple rounds.
* Each round, agents can see previous round results.
*/
<span class="cstat-no" title="statement not covered" > private async executeDebate(task: SwarmTask): Promise&lt;void&gt; {</span>
<span class="cstat-no" title="statement not covered" > const maxRounds = this.config.maxRoundsDebate;</span>
<span class="cstat-no" title="statement not covered" > const agents = [...new Set(task.subtasks.map(s =&gt; s.assignedTo))];</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > for (let round = 1; round &lt;= maxRounds; round++) {</span>
<span class="cstat-no" title="statement not covered" > const roundContext = round &gt; 1</span>
<span class="cstat-no" title="statement not covered" > ? this.buildDebateContext(task, round - 1)</span>
<span class="cstat-no" title="statement not covered" > : '';</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const roundPromises = agents.map(async (agentId) =&gt; {</span>
<span class="cstat-no" title="statement not covered" > const subtaskId = `${task.id}_debate_r${round}_${agentId}`;</span>
<span class="cstat-no" title="statement not covered" > const subtask: Subtask = {</span>
<span class="cstat-no" title="statement not covered" > id: subtaskId,</span>
<span class="cstat-no" title="statement not covered" > assignedTo: agentId,</span>
<span class="cstat-no" title="statement not covered" > description: task.description,</span>
<span class="cstat-no" title="statement not covered" > status: 'running',</span>
<span class="cstat-no" title="statement not covered" > startedAt: new Date().toISOString(),</span>
<span class="cstat-no" title="statement not covered" > round,</span>
<span class="cstat-no" title="statement not covered" > };</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > try {</span>
<span class="cstat-no" title="statement not covered" > const prompt = round === 1</span>
<span class="cstat-no" title="statement not covered" > ? task.description</span>
<span class="cstat-no" title="statement not covered" > : `这是第${round}轮讨论。请参考其他Agent的观点给出你的更新后的分析。\n\n${roundContext}`;</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const result = await this.executeSubtask(subtask, '', prompt);</span>
<span class="cstat-no" title="statement not covered" > subtask.result = result;</span>
<span class="cstat-no" title="statement not covered" > subtask.status = 'done';</span>
<span class="cstat-no" title="statement not covered" > } catch (err) {</span>
<span class="cstat-no" title="statement not covered" > subtask.status = 'failed';</span>
<span class="cstat-no" title="statement not covered" > subtask.error = err instanceof Error ? err.message : String(err);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > subtask.completedAt = new Date().toISOString();</span>
<span class="cstat-no" title="statement not covered" > task.subtasks.push(subtask);</span>
<span class="cstat-no" title="statement not covered" > });</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > await Promise.allSettled(roundPromises);</span>
&nbsp;
// Check if consensus reached (all agents give similar answers)
<span class="cstat-no" title="statement not covered" > if (round &lt; maxRounds &amp;&amp; this.checkConsensus(task, round)) {</span>
<span class="cstat-no" title="statement not covered" > console.log(`[AgentSwarm] Debate consensus reached at round ${round}`);</span>
<span class="cstat-no" title="statement not covered" > break;</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
// === Helpers ===
&nbsp;
<span class="cstat-no" title="statement not covered" > private async executeSubtask(</span>
<span class="cstat-no" title="statement not covered" > subtask: Subtask,</span>
<span class="cstat-no" title="statement not covered" > context?: string,</span>
<span class="cstat-no" title="statement not covered" > promptOverride?: string</span>
<span class="cstat-no" title="statement not covered" > ): Promise&lt;string&gt; {</span>
<span class="cstat-no" title="statement not covered" > if (!this.executor) throw new Error('No executor');</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const prompt = promptOverride || subtask.description;</span>
<span class="cstat-no" title="statement not covered" > return this.executor(subtask.assignedTo, prompt, context);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
/**
* Auto-decompose a task into subtasks based on specialist roles.
*/
<span class="cstat-no" title="statement not covered" > private autoDecompose(</span>
<span class="cstat-no" title="statement not covered" > taskId: string,</span>
<span class="cstat-no" title="statement not covered" > description: string,</span>
<span class="cstat-no" title="statement not covered" > style: CommunicationStyle</span>
<span class="cstat-no" title="statement not covered" > ): Subtask[] {</span>
<span class="cstat-no" title="statement not covered" > const specialists = this.config.specialists;</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (specialists.length === 0) {</span>
// Single agent fallback
<span class="cstat-no" title="statement not covered" > return [{</span>
<span class="cstat-no" title="statement not covered" > id: `${taskId}_sub_0`,</span>
<span class="cstat-no" title="statement not covered" > assignedTo: this.config.coordinator,</span>
<span class="cstat-no" title="statement not covered" > description,</span>
<span class="cstat-no" title="statement not covered" > status: 'pending',</span>
<span class="cstat-no" title="statement not covered" > }];</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (style === 'debate') {</span>
// In debate mode, all specialists get the same task
<span class="cstat-no" title="statement not covered" > return specialists.map((spec, i) =&gt; ({</span>
<span class="cstat-no" title="statement not covered" > id: `${taskId}_sub_${i}`,</span>
<span class="cstat-no" title="statement not covered" > assignedTo: spec.agentId,</span>
<span class="cstat-no" title="statement not covered" > description: `作为${spec.role},请分析以下问题: ${description}`,</span>
<span class="cstat-no" title="statement not covered" > status: 'pending' as SubtaskStatus,</span>
<span class="cstat-no" title="statement not covered" > round: 1,</span>
<span class="cstat-no" title="statement not covered" > }));</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (style === 'parallel') {</span>
// In parallel, assign based on capabilities
<span class="cstat-no" title="statement not covered" > return specialists.map((spec, i) =&gt; ({</span>
<span class="cstat-no" title="statement not covered" > id: `${taskId}_sub_${i}`,</span>
<span class="cstat-no" title="statement not covered" > assignedTo: spec.agentId,</span>
<span class="cstat-no" title="statement not covered" > description: `从${spec.role}的角度完成: ${description}`,</span>
<span class="cstat-no" title="statement not covered" > status: 'pending' as SubtaskStatus,</span>
<span class="cstat-no" title="statement not covered" > }));</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
// Sequential: chain through specialists
<span class="cstat-no" title="statement not covered" > return specialists.map((spec, i) =&gt; ({</span>
<span class="cstat-no" title="statement not covered" > id: `${taskId}_sub_${i}`,</span>
<span class="cstat-no" title="statement not covered" > assignedTo: spec.agentId,</span>
<span class="cstat-no" title="statement not covered" > description: i === 0</span>
<span class="cstat-no" title="statement not covered" > ? `作为${spec.role},请首先分析: ${description}`</span>
<span class="cstat-no" title="statement not covered" > : `作为${spec.role},请基于前一位同事的分析继续深化: ${description}`,</span>
<span class="cstat-no" title="statement not covered" > status: 'pending' as SubtaskStatus,</span>
<span class="cstat-no" title="statement not covered" > }));</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > private buildDebateContext(task: SwarmTask, upToRound: number): string {</span>
<span class="cstat-no" title="statement not covered" > const roundSubtasks = task.subtasks.filter(</span>
<span class="cstat-no" title="statement not covered" > s =&gt; s.round &amp;&amp; s.round &lt;= upToRound &amp;&amp; s.status === 'done'</span>
<span class="cstat-no" title="statement not covered" > );</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (roundSubtasks.length === 0) return '';</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const lines = roundSubtasks.map(s =&gt; {</span>
<span class="cstat-no" title="statement not covered" > const specialist = this.config.specialists.find(sp =&gt; sp.agentId === s.assignedTo);</span>
<span class="cstat-no" title="statement not covered" > const role = specialist?.role || s.assignedTo;</span>
<span class="cstat-no" title="statement not covered" > return `**${role}** (第${s.round}轮):\n${s.result || '(无输出)'}`;</span>
<span class="cstat-no" title="statement not covered" > });</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > return `其他Agent的观点:\n\n${lines.join('\n\n---\n\n')}`;</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > private checkConsensus(task: SwarmTask, round: number): boolean {</span>
<span class="cstat-no" title="statement not covered" > const roundResults = task.subtasks</span>
<span class="cstat-no" title="statement not covered" > .filter(s =&gt; s.round === round &amp;&amp; s.status === 'done' &amp;&amp; s.result)</span>
<span class="cstat-no" title="statement not covered" > .map(s =&gt; s.result!);</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (roundResults.length &lt; 2) return false;</span>
&nbsp;
// Simple heuristic: if all results share &gt; 60% keywords, consider consensus
<span class="cstat-no" title="statement not covered" > const tokenSets = roundResults.map(r =&gt;</span>
<span class="cstat-no" title="statement not covered" > new Set(r.toLowerCase().split(/[\s,;.!?。,;!?]+/).filter(t =&gt; t.length &gt; 1))</span>
<span class="cstat-no" title="statement not covered" > );</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > for (let i = 1; i &lt; tokenSets.length; i++) {</span>
<span class="cstat-no" title="statement not covered" > const common = [...tokenSets[0]].filter(t =&gt; tokenSets[i].has(t));</span>
<span class="cstat-no" title="statement not covered" > const similarity = (2 * common.length) / (tokenSets[0].size + tokenSets[i].size);</span>
<span class="cstat-no" title="statement not covered" > if (similarity &lt; 0.6) return false;</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > return true;</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
/**
* Aggregate subtask results into a final summary.
* Phase 4: rule-based. Future: LLM-powered synthesis.
*/
<span class="cstat-no" title="statement not covered" > private async aggregate(task: SwarmTask): Promise&lt;string&gt; {</span>
<span class="cstat-no" title="statement not covered" > const completedSubtasks = task.subtasks.filter(s =&gt; s.status === 'done' &amp;&amp; s.result);</span>
<span class="cstat-no" title="statement not covered" > const failedSubtasks = task.subtasks.filter(s =&gt; s.status === 'failed');</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (completedSubtasks.length === 0) {</span>
<span class="cstat-no" title="statement not covered" > return failedSubtasks.length &gt; 0</span>
<span class="cstat-no" title="statement not covered" > ? `所有子任务失败: ${failedSubtasks.map(s =&gt; s.error).join('; ')}`</span>
<span class="cstat-no" title="statement not covered" > : '无结果';</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > const sections: string[] = [];</span>
<span class="cstat-no" title="statement not covered" > sections.push(`## 协作任务: ${task.description}`);</span>
<span class="cstat-no" title="statement not covered" > sections.push(`**模式**: ${task.communicationStyle} | **参与者**: ${new Set(completedSubtasks.map(s =&gt; s.assignedTo)).size}`);</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (task.communicationStyle === 'debate') {</span>
// Group by round
<span class="cstat-no" title="statement not covered" > const maxRound = Math.max(...completedSubtasks.map(s =&gt; s.round || 1));</span>
<span class="cstat-no" title="statement not covered" > for (let r = 1; r &lt;= maxRound; r++) {</span>
<span class="cstat-no" title="statement not covered" > const roundResults = completedSubtasks.filter(s =&gt; s.round === r);</span>
<span class="cstat-no" title="statement not covered" > if (roundResults.length &gt; 0) {</span>
<span class="cstat-no" title="statement not covered" > sections.push(`\n### 第${r}轮讨论`);</span>
<span class="cstat-no" title="statement not covered" > for (const s of roundResults) {</span>
<span class="cstat-no" title="statement not covered" > const spec = this.config.specialists.find(sp =&gt; sp.agentId === s.assignedTo);</span>
<span class="cstat-no" title="statement not covered" > sections.push(`**${spec?.role || s.assignedTo}**:\n${s.result}`);</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > } else {</span>
<span class="cstat-no" title="statement not covered" > for (const s of completedSubtasks) {</span>
<span class="cstat-no" title="statement not covered" > const spec = this.config.specialists.find(sp =&gt; sp.agentId === s.assignedTo);</span>
<span class="cstat-no" title="statement not covered" > sections.push(`\n### ${spec?.role || s.assignedTo}\n${s.result}`);</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > if (failedSubtasks.length &gt; 0) {</span>
<span class="cstat-no" title="statement not covered" > sections.push(`\n### 失败的子任务 (${failedSubtasks.length})`);</span>
<span class="cstat-no" title="statement not covered" > for (const s of failedSubtasks) {</span>
<span class="cstat-no" title="statement not covered" > sections.push(`- ${s.assignedTo}: ${s.error}`);</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > return sections.join('\n');</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
// === Query ===
&nbsp;
<span class="cstat-no" title="statement not covered" > getHistory(limit: number = 20): SwarmTask[] {</span>
<span class="cstat-no" title="statement not covered" > return this.history.slice(-limit);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > getTask(taskId: string): SwarmTask | undefined {</span>
<span class="cstat-no" title="statement not covered" > return this.history.find(t =&gt; t.id === taskId);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > getSpecialists(): SwarmSpecialist[] {</span>
<span class="cstat-no" title="statement not covered" > return [...this.config.specialists];</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > addSpecialist(specialist: SwarmSpecialist): void {</span>
<span class="cstat-no" title="statement not covered" > const existing = this.config.specialists.findIndex(s =&gt; s.agentId === specialist.agentId);</span>
<span class="cstat-no" title="statement not covered" > if (existing &gt;= 0) {</span>
<span class="cstat-no" title="statement not covered" > this.config.specialists[existing] = specialist;</span>
<span class="cstat-no" title="statement not covered" > } else {</span>
<span class="cstat-no" title="statement not covered" > this.config.specialists.push(specialist);</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > removeSpecialist(agentId: string): void {</span>
<span class="cstat-no" title="statement not covered" > this.config.specialists = this.config.specialists.filter(s =&gt; s.agentId !== agentId);</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
// === Config ===
&nbsp;
<span class="cstat-no" title="statement not covered" > getConfig(): SwarmConfig {</span>
<span class="cstat-no" title="statement not covered" > return { ...this.config, specialists: [...this.config.specialists] };</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > updateConfig(updates: Partial&lt;SwarmConfig&gt;): void {</span>
<span class="cstat-no" title="statement not covered" > this.config = { ...this.config, ...updates };</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
// === Persistence ===
&nbsp;
<span class="cstat-no" title="statement not covered" > private loadHistory(): void {</span>
<span class="cstat-no" title="statement not covered" > try {</span>
<span class="cstat-no" title="statement not covered" > const raw = localStorage.getItem(SWARM_HISTORY_KEY);</span>
<span class="cstat-no" title="statement not covered" > if (raw) this.history = JSON.parse(raw);</span>
<span class="cstat-no" title="statement not covered" > } catch {</span>
<span class="cstat-no" title="statement not covered" > this.history = [];</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > }</span>
&nbsp;
<span class="cstat-no" title="statement not covered" > private saveHistory(): void {</span>
<span class="cstat-no" title="statement not covered" > try {</span>
<span class="cstat-no" title="statement not covered" > localStorage.setItem(SWARM_HISTORY_KEY, JSON.stringify(this.history.slice(-25)));</span>
<span class="cstat-no" title="statement not covered" > } catch { /* silent */ }</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" >}</span>
&nbsp;
// === Singleton ===
&nbsp;
<span class="cstat-no" title="statement not covered" >let _instance: AgentSwarm | null = null;</span>
&nbsp;
<span class="cstat-no" title="statement not covered" >export function getAgentSwarm(config?: Partial&lt;SwarmConfig&gt;): AgentSwarm {</span>
<span class="cstat-no" title="statement not covered" > if (!_instance) {</span>
<span class="cstat-no" title="statement not covered" > _instance = new AgentSwarm(config);</span>
<span class="cstat-no" title="statement not covered" > }</span>
<span class="cstat-no" title="statement not covered" > return _instance;</span>
<span class="cstat-no" title="statement not covered" >}</span>
&nbsp;
<span class="cstat-no" title="statement not covered" >export function resetAgentSwarm(): void {</span>
<span class="cstat-no" title="statement not covered" > _instance = null;</span>
<span class="cstat-no" title="statement not covered" >}</span>
&nbsp;</pre></td></tr></table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2026-03-25T14:02:06.489Z
</div>
<script src="../../prettify.js"></script>
<script>
window.onload = function () {
prettyPrint();
};
</script>
<script src="../../sorter.js"></script>
<script src="../../block-navigation.js"></script>
</body>
</html>