a2acalling 0.6.73 → 0.6.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/.a2a-manifest.json +2 -2
  2. package/.c8rc.json +16 -0
  3. package/.node-version +1 -0
  4. package/.serena/project.yml +126 -0
  5. package/ARCHITECTURE.md +40 -16
  6. package/CONVENTIONS.md +39 -6
  7. package/biome.json +27 -0
  8. package/coverage/base.css +224 -0
  9. package/coverage/block-navigation.js +87 -0
  10. package/coverage/favicon.png +0 -0
  11. package/coverage/index.html +146 -0
  12. package/coverage/prettify.css +1 -0
  13. package/coverage/prettify.js +2 -0
  14. package/coverage/sort-arrow-sprite.png +0 -0
  15. package/coverage/sorter.js +210 -0
  16. package/coverage/src/index.html +131 -0
  17. package/coverage/src/index.js.html +313 -0
  18. package/coverage/src/lib/agent-card.js.html +418 -0
  19. package/coverage/src/lib/call-monitor.js.html +700 -0
  20. package/coverage/src/lib/callbook.js.html +1183 -0
  21. package/coverage/src/lib/claude-subagent.js.html +2173 -0
  22. package/coverage/src/lib/client.js.html +2134 -0
  23. package/coverage/src/lib/config.js.html +1525 -0
  24. package/coverage/src/lib/conversation-driver.js.html +1909 -0
  25. package/coverage/src/lib/conversations.js.html +2575 -0
  26. package/coverage/src/lib/crypto.js.html +424 -0
  27. package/coverage/src/lib/dashboard-events.js.html +724 -0
  28. package/coverage/src/lib/disclosure.js.html +2461 -0
  29. package/coverage/src/lib/external-ip.js.html +718 -0
  30. package/coverage/src/lib/index.html +506 -0
  31. package/coverage/src/lib/invite-host.js.html +754 -0
  32. package/coverage/src/lib/local-request.js.html +292 -0
  33. package/coverage/src/lib/logger.js.html +2116 -0
  34. package/coverage/src/lib/openclaw-integration.js.html +1102 -0
  35. package/coverage/src/lib/pid-file.js.html +394 -0
  36. package/coverage/src/lib/port-scanner.js.html +334 -0
  37. package/coverage/src/lib/prompt-template.js.html +1150 -0
  38. package/coverage/src/lib/runtime-adapter.js.html +2188 -0
  39. package/coverage/src/lib/summarizer.js.html +553 -0
  40. package/coverage/src/lib/summary-formatter.js.html +589 -0
  41. package/coverage/src/lib/summary-prompt.js.html +694 -0
  42. package/coverage/src/lib/tokens.js.html +2689 -0
  43. package/coverage/src/lib/turn-timeout.js.html +241 -0
  44. package/coverage/src/lib/update-checker.js.html +364 -0
  45. package/coverage/src/lib/update-manager.js.html +1024 -0
  46. package/coverage/src/routes/a2a.js.html +3724 -0
  47. package/coverage/src/routes/callbook.js.html +511 -0
  48. package/coverage/src/routes/dashboard.js.html +4819 -0
  49. package/coverage/src/routes/index.html +146 -0
  50. package/coverage/src/server.js.html +3622 -0
  51. package/coverage/tmp/coverage-1605378-1772576706365-0.json +1 -0
  52. package/coverage/tmp/coverage-1605384-1772576607459-0.json +1 -0
  53. package/coverage/tmp/coverage-1605410-1772576631155-0.json +1 -0
  54. package/coverage/tmp/coverage-1606942-1772576636869-0.json +1 -0
  55. package/coverage/tmp/coverage-1607004-1772576637454-0.json +1 -0
  56. package/coverage/tmp/coverage-1607044-1772576637876-0.json +1 -0
  57. package/coverage/tmp/coverage-1607096-1772576638356-0.json +1 -0
  58. package/coverage/tmp/coverage-1607145-1772576638777-0.json +1 -0
  59. package/coverage/tmp/coverage-1607201-1772576639277-0.json +1 -0
  60. package/coverage/tmp/coverage-1607247-1772576639755-0.json +1 -0
  61. package/coverage/tmp/coverage-1607317-1772576640083-0.json +1 -0
  62. package/coverage/tmp/coverage-1607381-1772576640465-0.json +1 -0
  63. package/coverage/tmp/coverage-1607446-1772576640868-0.json +1 -0
  64. package/coverage/tmp/coverage-1607501-1772576641662-0.json +1 -0
  65. package/coverage/tmp/coverage-1607534-1772576641565-0.json +1 -0
  66. package/coverage/tmp/coverage-1607627-1772576641871-0.json +1 -0
  67. package/coverage/tmp/coverage-1607665-1772576642172-0.json +1 -0
  68. package/coverage/tmp/coverage-1607714-1772576642577-0.json +1 -0
  69. package/coverage/tmp/coverage-1607788-1772576643466-0.json +1 -0
  70. package/coverage/tmp/coverage-1607924-1772576644678-0.json +1 -0
  71. package/coverage/tmp/coverage-1607978-1772576645154-0.json +1 -0
  72. package/coverage/tmp/coverage-1608035-1772576645564-0.json +1 -0
  73. package/coverage/tmp/coverage-1608106-1772576645967-0.json +1 -0
  74. package/coverage/tmp/coverage-1608179-1772576648656-0.json +1 -0
  75. package/coverage/tmp/coverage-1608196-1772576647367-0.json +1 -0
  76. package/coverage/tmp/coverage-1608217-1772576648557-0.json +1 -0
  77. package/coverage/tmp/coverage-1608256-1772576651378-0.json +1 -0
  78. package/coverage/tmp/coverage-1608265-1772576650058-0.json +1 -0
  79. package/coverage/tmp/coverage-1608289-1772576651358-0.json +1 -0
  80. package/coverage/tmp/coverage-1608591-1772576660465-0.json +1 -0
  81. package/coverage/tmp/coverage-1608648-1772576659272-0.json +1 -0
  82. package/coverage/tmp/coverage-1608665-1772576660374-0.json +1 -0
  83. package/coverage/tmp/coverage-1608677-1772576661268-0.json +1 -0
  84. package/coverage/tmp/coverage-1608684-1772576663968-0.json +1 -0
  85. package/coverage/tmp/coverage-1608692-1772576662575-0.json +1 -0
  86. package/coverage/tmp/coverage-1608701-1772576663873-0.json +1 -0
  87. package/coverage/tmp/coverage-1608718-1772576666674-0.json +1 -0
  88. package/coverage/tmp/coverage-1608725-1772576665463-0.json +1 -0
  89. package/coverage/tmp/coverage-1608738-1772576666577-0.json +1 -0
  90. package/coverage/tmp/coverage-1608753-1772576669664-0.json +1 -0
  91. package/coverage/tmp/coverage-1608763-1772576668275-0.json +1 -0
  92. package/coverage/tmp/coverage-1608771-1772576669563-0.json +1 -0
  93. package/coverage/tmp/coverage-1608828-1772576676574-0.json +1 -0
  94. package/coverage/tmp/coverage-1609244-1772576675272-0.json +1 -0
  95. package/coverage/tmp/coverage-1609342-1772576676478-0.json +1 -0
  96. package/coverage/tmp/coverage-1609450-1772576686954-0.json +1 -0
  97. package/coverage/tmp/coverage-1609841-1772576685466-0.json +1 -0
  98. package/coverage/tmp/coverage-1609925-1772576686855-0.json +1 -0
  99. package/coverage/tmp/coverage-1610399-1772576692469-0.json +1 -0
  100. package/coverage/tmp/coverage-1611283-1772576703062-0.json +1 -0
  101. package/coverage/tmp/coverage-1611294-1772576703755-0.json +1 -0
  102. package/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  103. package/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  104. package/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  105. package/docs/plans/2026-03-03-a2a-91-macos-packaging-plan.md +144 -0
  106. package/docs/signing-setup.md +49 -0
  107. package/eslint.config.js +16 -0
  108. package/knip.json +17 -0
  109. package/native/macos/certs/appldevcert.cer +0 -0
  110. package/native/macos/src-tauri/binaries/.gitkeep +0 -0
  111. package/native/macos/src-tauri/capabilities/default.json +11 -1
  112. package/native/macos/src-tauri/entitlements.plist +14 -0
  113. package/native/macos/src-tauri/src/discovery.rs +14 -3
  114. package/native/macos/src-tauri/src/health.rs +4 -0
  115. package/native/macos/src-tauri/src/lib.rs +52 -11
  116. package/native/macos/src-tauri/src/server.rs +262 -26
  117. package/native/macos/src-tauri/tauri.conf.json +13 -4
  118. package/package.json +16 -2
  119. package/pkg.config.json +14 -0
  120. package/scripts/build-standalone.sh +106 -0
  121. package/scripts/install-openclaw.js +3 -5
  122. package/scripts/smoke-test-standalone.sh +101 -0
  123. package/scripts/sync-version.sh +28 -0
  124. package/scripts/verify-app-bundle.sh +34 -0
  125. package/src/lib/agent-card.js +111 -0
  126. package/src/lib/client.js +290 -49
  127. package/src/lib/conversations.js +2 -0
  128. package/src/lib/local-request.js +69 -0
  129. package/src/lib/logger.js +2 -0
  130. package/src/lib/runtime-adapter.js +41 -1
  131. package/src/routes/a2a.js +393 -66
  132. package/src/routes/dashboard.js +1 -27
  133. package/src/server.js +19 -0
  134. package/.maestro/inbox/release-workflow-spam.md +0 -25
@@ -0,0 +1,1909 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/lib/conversation-driver.js</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/lib</a> conversation-driver.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">76.48% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>465/608</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">80% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>80/100</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>5/5</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">76.48% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>465/608</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ 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.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line medium'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a>
388
+ <a name='L323'></a><a href='#L323'>323</a>
389
+ <a name='L324'></a><a href='#L324'>324</a>
390
+ <a name='L325'></a><a href='#L325'>325</a>
391
+ <a name='L326'></a><a href='#L326'>326</a>
392
+ <a name='L327'></a><a href='#L327'>327</a>
393
+ <a name='L328'></a><a href='#L328'>328</a>
394
+ <a name='L329'></a><a href='#L329'>329</a>
395
+ <a name='L330'></a><a href='#L330'>330</a>
396
+ <a name='L331'></a><a href='#L331'>331</a>
397
+ <a name='L332'></a><a href='#L332'>332</a>
398
+ <a name='L333'></a><a href='#L333'>333</a>
399
+ <a name='L334'></a><a href='#L334'>334</a>
400
+ <a name='L335'></a><a href='#L335'>335</a>
401
+ <a name='L336'></a><a href='#L336'>336</a>
402
+ <a name='L337'></a><a href='#L337'>337</a>
403
+ <a name='L338'></a><a href='#L338'>338</a>
404
+ <a name='L339'></a><a href='#L339'>339</a>
405
+ <a name='L340'></a><a href='#L340'>340</a>
406
+ <a name='L341'></a><a href='#L341'>341</a>
407
+ <a name='L342'></a><a href='#L342'>342</a>
408
+ <a name='L343'></a><a href='#L343'>343</a>
409
+ <a name='L344'></a><a href='#L344'>344</a>
410
+ <a name='L345'></a><a href='#L345'>345</a>
411
+ <a name='L346'></a><a href='#L346'>346</a>
412
+ <a name='L347'></a><a href='#L347'>347</a>
413
+ <a name='L348'></a><a href='#L348'>348</a>
414
+ <a name='L349'></a><a href='#L349'>349</a>
415
+ <a name='L350'></a><a href='#L350'>350</a>
416
+ <a name='L351'></a><a href='#L351'>351</a>
417
+ <a name='L352'></a><a href='#L352'>352</a>
418
+ <a name='L353'></a><a href='#L353'>353</a>
419
+ <a name='L354'></a><a href='#L354'>354</a>
420
+ <a name='L355'></a><a href='#L355'>355</a>
421
+ <a name='L356'></a><a href='#L356'>356</a>
422
+ <a name='L357'></a><a href='#L357'>357</a>
423
+ <a name='L358'></a><a href='#L358'>358</a>
424
+ <a name='L359'></a><a href='#L359'>359</a>
425
+ <a name='L360'></a><a href='#L360'>360</a>
426
+ <a name='L361'></a><a href='#L361'>361</a>
427
+ <a name='L362'></a><a href='#L362'>362</a>
428
+ <a name='L363'></a><a href='#L363'>363</a>
429
+ <a name='L364'></a><a href='#L364'>364</a>
430
+ <a name='L365'></a><a href='#L365'>365</a>
431
+ <a name='L366'></a><a href='#L366'>366</a>
432
+ <a name='L367'></a><a href='#L367'>367</a>
433
+ <a name='L368'></a><a href='#L368'>368</a>
434
+ <a name='L369'></a><a href='#L369'>369</a>
435
+ <a name='L370'></a><a href='#L370'>370</a>
436
+ <a name='L371'></a><a href='#L371'>371</a>
437
+ <a name='L372'></a><a href='#L372'>372</a>
438
+ <a name='L373'></a><a href='#L373'>373</a>
439
+ <a name='L374'></a><a href='#L374'>374</a>
440
+ <a name='L375'></a><a href='#L375'>375</a>
441
+ <a name='L376'></a><a href='#L376'>376</a>
442
+ <a name='L377'></a><a href='#L377'>377</a>
443
+ <a name='L378'></a><a href='#L378'>378</a>
444
+ <a name='L379'></a><a href='#L379'>379</a>
445
+ <a name='L380'></a><a href='#L380'>380</a>
446
+ <a name='L381'></a><a href='#L381'>381</a>
447
+ <a name='L382'></a><a href='#L382'>382</a>
448
+ <a name='L383'></a><a href='#L383'>383</a>
449
+ <a name='L384'></a><a href='#L384'>384</a>
450
+ <a name='L385'></a><a href='#L385'>385</a>
451
+ <a name='L386'></a><a href='#L386'>386</a>
452
+ <a name='L387'></a><a href='#L387'>387</a>
453
+ <a name='L388'></a><a href='#L388'>388</a>
454
+ <a name='L389'></a><a href='#L389'>389</a>
455
+ <a name='L390'></a><a href='#L390'>390</a>
456
+ <a name='L391'></a><a href='#L391'>391</a>
457
+ <a name='L392'></a><a href='#L392'>392</a>
458
+ <a name='L393'></a><a href='#L393'>393</a>
459
+ <a name='L394'></a><a href='#L394'>394</a>
460
+ <a name='L395'></a><a href='#L395'>395</a>
461
+ <a name='L396'></a><a href='#L396'>396</a>
462
+ <a name='L397'></a><a href='#L397'>397</a>
463
+ <a name='L398'></a><a href='#L398'>398</a>
464
+ <a name='L399'></a><a href='#L399'>399</a>
465
+ <a name='L400'></a><a href='#L400'>400</a>
466
+ <a name='L401'></a><a href='#L401'>401</a>
467
+ <a name='L402'></a><a href='#L402'>402</a>
468
+ <a name='L403'></a><a href='#L403'>403</a>
469
+ <a name='L404'></a><a href='#L404'>404</a>
470
+ <a name='L405'></a><a href='#L405'>405</a>
471
+ <a name='L406'></a><a href='#L406'>406</a>
472
+ <a name='L407'></a><a href='#L407'>407</a>
473
+ <a name='L408'></a><a href='#L408'>408</a>
474
+ <a name='L409'></a><a href='#L409'>409</a>
475
+ <a name='L410'></a><a href='#L410'>410</a>
476
+ <a name='L411'></a><a href='#L411'>411</a>
477
+ <a name='L412'></a><a href='#L412'>412</a>
478
+ <a name='L413'></a><a href='#L413'>413</a>
479
+ <a name='L414'></a><a href='#L414'>414</a>
480
+ <a name='L415'></a><a href='#L415'>415</a>
481
+ <a name='L416'></a><a href='#L416'>416</a>
482
+ <a name='L417'></a><a href='#L417'>417</a>
483
+ <a name='L418'></a><a href='#L418'>418</a>
484
+ <a name='L419'></a><a href='#L419'>419</a>
485
+ <a name='L420'></a><a href='#L420'>420</a>
486
+ <a name='L421'></a><a href='#L421'>421</a>
487
+ <a name='L422'></a><a href='#L422'>422</a>
488
+ <a name='L423'></a><a href='#L423'>423</a>
489
+ <a name='L424'></a><a href='#L424'>424</a>
490
+ <a name='L425'></a><a href='#L425'>425</a>
491
+ <a name='L426'></a><a href='#L426'>426</a>
492
+ <a name='L427'></a><a href='#L427'>427</a>
493
+ <a name='L428'></a><a href='#L428'>428</a>
494
+ <a name='L429'></a><a href='#L429'>429</a>
495
+ <a name='L430'></a><a href='#L430'>430</a>
496
+ <a name='L431'></a><a href='#L431'>431</a>
497
+ <a name='L432'></a><a href='#L432'>432</a>
498
+ <a name='L433'></a><a href='#L433'>433</a>
499
+ <a name='L434'></a><a href='#L434'>434</a>
500
+ <a name='L435'></a><a href='#L435'>435</a>
501
+ <a name='L436'></a><a href='#L436'>436</a>
502
+ <a name='L437'></a><a href='#L437'>437</a>
503
+ <a name='L438'></a><a href='#L438'>438</a>
504
+ <a name='L439'></a><a href='#L439'>439</a>
505
+ <a name='L440'></a><a href='#L440'>440</a>
506
+ <a name='L441'></a><a href='#L441'>441</a>
507
+ <a name='L442'></a><a href='#L442'>442</a>
508
+ <a name='L443'></a><a href='#L443'>443</a>
509
+ <a name='L444'></a><a href='#L444'>444</a>
510
+ <a name='L445'></a><a href='#L445'>445</a>
511
+ <a name='L446'></a><a href='#L446'>446</a>
512
+ <a name='L447'></a><a href='#L447'>447</a>
513
+ <a name='L448'></a><a href='#L448'>448</a>
514
+ <a name='L449'></a><a href='#L449'>449</a>
515
+ <a name='L450'></a><a href='#L450'>450</a>
516
+ <a name='L451'></a><a href='#L451'>451</a>
517
+ <a name='L452'></a><a href='#L452'>452</a>
518
+ <a name='L453'></a><a href='#L453'>453</a>
519
+ <a name='L454'></a><a href='#L454'>454</a>
520
+ <a name='L455'></a><a href='#L455'>455</a>
521
+ <a name='L456'></a><a href='#L456'>456</a>
522
+ <a name='L457'></a><a href='#L457'>457</a>
523
+ <a name='L458'></a><a href='#L458'>458</a>
524
+ <a name='L459'></a><a href='#L459'>459</a>
525
+ <a name='L460'></a><a href='#L460'>460</a>
526
+ <a name='L461'></a><a href='#L461'>461</a>
527
+ <a name='L462'></a><a href='#L462'>462</a>
528
+ <a name='L463'></a><a href='#L463'>463</a>
529
+ <a name='L464'></a><a href='#L464'>464</a>
530
+ <a name='L465'></a><a href='#L465'>465</a>
531
+ <a name='L466'></a><a href='#L466'>466</a>
532
+ <a name='L467'></a><a href='#L467'>467</a>
533
+ <a name='L468'></a><a href='#L468'>468</a>
534
+ <a name='L469'></a><a href='#L469'>469</a>
535
+ <a name='L470'></a><a href='#L470'>470</a>
536
+ <a name='L471'></a><a href='#L471'>471</a>
537
+ <a name='L472'></a><a href='#L472'>472</a>
538
+ <a name='L473'></a><a href='#L473'>473</a>
539
+ <a name='L474'></a><a href='#L474'>474</a>
540
+ <a name='L475'></a><a href='#L475'>475</a>
541
+ <a name='L476'></a><a href='#L476'>476</a>
542
+ <a name='L477'></a><a href='#L477'>477</a>
543
+ <a name='L478'></a><a href='#L478'>478</a>
544
+ <a name='L479'></a><a href='#L479'>479</a>
545
+ <a name='L480'></a><a href='#L480'>480</a>
546
+ <a name='L481'></a><a href='#L481'>481</a>
547
+ <a name='L482'></a><a href='#L482'>482</a>
548
+ <a name='L483'></a><a href='#L483'>483</a>
549
+ <a name='L484'></a><a href='#L484'>484</a>
550
+ <a name='L485'></a><a href='#L485'>485</a>
551
+ <a name='L486'></a><a href='#L486'>486</a>
552
+ <a name='L487'></a><a href='#L487'>487</a>
553
+ <a name='L488'></a><a href='#L488'>488</a>
554
+ <a name='L489'></a><a href='#L489'>489</a>
555
+ <a name='L490'></a><a href='#L490'>490</a>
556
+ <a name='L491'></a><a href='#L491'>491</a>
557
+ <a name='L492'></a><a href='#L492'>492</a>
558
+ <a name='L493'></a><a href='#L493'>493</a>
559
+ <a name='L494'></a><a href='#L494'>494</a>
560
+ <a name='L495'></a><a href='#L495'>495</a>
561
+ <a name='L496'></a><a href='#L496'>496</a>
562
+ <a name='L497'></a><a href='#L497'>497</a>
563
+ <a name='L498'></a><a href='#L498'>498</a>
564
+ <a name='L499'></a><a href='#L499'>499</a>
565
+ <a name='L500'></a><a href='#L500'>500</a>
566
+ <a name='L501'></a><a href='#L501'>501</a>
567
+ <a name='L502'></a><a href='#L502'>502</a>
568
+ <a name='L503'></a><a href='#L503'>503</a>
569
+ <a name='L504'></a><a href='#L504'>504</a>
570
+ <a name='L505'></a><a href='#L505'>505</a>
571
+ <a name='L506'></a><a href='#L506'>506</a>
572
+ <a name='L507'></a><a href='#L507'>507</a>
573
+ <a name='L508'></a><a href='#L508'>508</a>
574
+ <a name='L509'></a><a href='#L509'>509</a>
575
+ <a name='L510'></a><a href='#L510'>510</a>
576
+ <a name='L511'></a><a href='#L511'>511</a>
577
+ <a name='L512'></a><a href='#L512'>512</a>
578
+ <a name='L513'></a><a href='#L513'>513</a>
579
+ <a name='L514'></a><a href='#L514'>514</a>
580
+ <a name='L515'></a><a href='#L515'>515</a>
581
+ <a name='L516'></a><a href='#L516'>516</a>
582
+ <a name='L517'></a><a href='#L517'>517</a>
583
+ <a name='L518'></a><a href='#L518'>518</a>
584
+ <a name='L519'></a><a href='#L519'>519</a>
585
+ <a name='L520'></a><a href='#L520'>520</a>
586
+ <a name='L521'></a><a href='#L521'>521</a>
587
+ <a name='L522'></a><a href='#L522'>522</a>
588
+ <a name='L523'></a><a href='#L523'>523</a>
589
+ <a name='L524'></a><a href='#L524'>524</a>
590
+ <a name='L525'></a><a href='#L525'>525</a>
591
+ <a name='L526'></a><a href='#L526'>526</a>
592
+ <a name='L527'></a><a href='#L527'>527</a>
593
+ <a name='L528'></a><a href='#L528'>528</a>
594
+ <a name='L529'></a><a href='#L529'>529</a>
595
+ <a name='L530'></a><a href='#L530'>530</a>
596
+ <a name='L531'></a><a href='#L531'>531</a>
597
+ <a name='L532'></a><a href='#L532'>532</a>
598
+ <a name='L533'></a><a href='#L533'>533</a>
599
+ <a name='L534'></a><a href='#L534'>534</a>
600
+ <a name='L535'></a><a href='#L535'>535</a>
601
+ <a name='L536'></a><a href='#L536'>536</a>
602
+ <a name='L537'></a><a href='#L537'>537</a>
603
+ <a name='L538'></a><a href='#L538'>538</a>
604
+ <a name='L539'></a><a href='#L539'>539</a>
605
+ <a name='L540'></a><a href='#L540'>540</a>
606
+ <a name='L541'></a><a href='#L541'>541</a>
607
+ <a name='L542'></a><a href='#L542'>542</a>
608
+ <a name='L543'></a><a href='#L543'>543</a>
609
+ <a name='L544'></a><a href='#L544'>544</a>
610
+ <a name='L545'></a><a href='#L545'>545</a>
611
+ <a name='L546'></a><a href='#L546'>546</a>
612
+ <a name='L547'></a><a href='#L547'>547</a>
613
+ <a name='L548'></a><a href='#L548'>548</a>
614
+ <a name='L549'></a><a href='#L549'>549</a>
615
+ <a name='L550'></a><a href='#L550'>550</a>
616
+ <a name='L551'></a><a href='#L551'>551</a>
617
+ <a name='L552'></a><a href='#L552'>552</a>
618
+ <a name='L553'></a><a href='#L553'>553</a>
619
+ <a name='L554'></a><a href='#L554'>554</a>
620
+ <a name='L555'></a><a href='#L555'>555</a>
621
+ <a name='L556'></a><a href='#L556'>556</a>
622
+ <a name='L557'></a><a href='#L557'>557</a>
623
+ <a name='L558'></a><a href='#L558'>558</a>
624
+ <a name='L559'></a><a href='#L559'>559</a>
625
+ <a name='L560'></a><a href='#L560'>560</a>
626
+ <a name='L561'></a><a href='#L561'>561</a>
627
+ <a name='L562'></a><a href='#L562'>562</a>
628
+ <a name='L563'></a><a href='#L563'>563</a>
629
+ <a name='L564'></a><a href='#L564'>564</a>
630
+ <a name='L565'></a><a href='#L565'>565</a>
631
+ <a name='L566'></a><a href='#L566'>566</a>
632
+ <a name='L567'></a><a href='#L567'>567</a>
633
+ <a name='L568'></a><a href='#L568'>568</a>
634
+ <a name='L569'></a><a href='#L569'>569</a>
635
+ <a name='L570'></a><a href='#L570'>570</a>
636
+ <a name='L571'></a><a href='#L571'>571</a>
637
+ <a name='L572'></a><a href='#L572'>572</a>
638
+ <a name='L573'></a><a href='#L573'>573</a>
639
+ <a name='L574'></a><a href='#L574'>574</a>
640
+ <a name='L575'></a><a href='#L575'>575</a>
641
+ <a name='L576'></a><a href='#L576'>576</a>
642
+ <a name='L577'></a><a href='#L577'>577</a>
643
+ <a name='L578'></a><a href='#L578'>578</a>
644
+ <a name='L579'></a><a href='#L579'>579</a>
645
+ <a name='L580'></a><a href='#L580'>580</a>
646
+ <a name='L581'></a><a href='#L581'>581</a>
647
+ <a name='L582'></a><a href='#L582'>582</a>
648
+ <a name='L583'></a><a href='#L583'>583</a>
649
+ <a name='L584'></a><a href='#L584'>584</a>
650
+ <a name='L585'></a><a href='#L585'>585</a>
651
+ <a name='L586'></a><a href='#L586'>586</a>
652
+ <a name='L587'></a><a href='#L587'>587</a>
653
+ <a name='L588'></a><a href='#L588'>588</a>
654
+ <a name='L589'></a><a href='#L589'>589</a>
655
+ <a name='L590'></a><a href='#L590'>590</a>
656
+ <a name='L591'></a><a href='#L591'>591</a>
657
+ <a name='L592'></a><a href='#L592'>592</a>
658
+ <a name='L593'></a><a href='#L593'>593</a>
659
+ <a name='L594'></a><a href='#L594'>594</a>
660
+ <a name='L595'></a><a href='#L595'>595</a>
661
+ <a name='L596'></a><a href='#L596'>596</a>
662
+ <a name='L597'></a><a href='#L597'>597</a>
663
+ <a name='L598'></a><a href='#L598'>598</a>
664
+ <a name='L599'></a><a href='#L599'>599</a>
665
+ <a name='L600'></a><a href='#L600'>600</a>
666
+ <a name='L601'></a><a href='#L601'>601</a>
667
+ <a name='L602'></a><a href='#L602'>602</a>
668
+ <a name='L603'></a><a href='#L603'>603</a>
669
+ <a name='L604'></a><a href='#L604'>604</a>
670
+ <a name='L605'></a><a href='#L605'>605</a>
671
+ <a name='L606'></a><a href='#L606'>606</a>
672
+ <a name='L607'></a><a href='#L607'>607</a>
673
+ <a name='L608'></a><a href='#L608'>608</a>
674
+ <a name='L609'></a><a href='#L609'>609</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
675
+ <span class="cline-any cline-yes">1x</span>
676
+ <span class="cline-any cline-yes">1x</span>
677
+ <span class="cline-any cline-yes">1x</span>
678
+ <span class="cline-any cline-yes">1x</span>
679
+ <span class="cline-any cline-yes">1x</span>
680
+ <span class="cline-any cline-yes">1x</span>
681
+ <span class="cline-any cline-yes">1x</span>
682
+ <span class="cline-any cline-yes">1x</span>
683
+ <span class="cline-any cline-yes">1x</span>
684
+ <span class="cline-any cline-yes">1x</span>
685
+ <span class="cline-any cline-yes">1x</span>
686
+ <span class="cline-any cline-yes">1x</span>
687
+ <span class="cline-any cline-yes">1x</span>
688
+ <span class="cline-any cline-yes">1x</span>
689
+ <span class="cline-any cline-yes">1x</span>
690
+ <span class="cline-any cline-yes">1x</span>
691
+ <span class="cline-any cline-yes">1x</span>
692
+ <span class="cline-any cline-yes">1x</span>
693
+ <span class="cline-any cline-yes">1x</span>
694
+ <span class="cline-any cline-yes">1x</span>
695
+ <span class="cline-any cline-yes">1x</span>
696
+ <span class="cline-any cline-yes">1x</span>
697
+ <span class="cline-any cline-yes">1x</span>
698
+ <span class="cline-any cline-yes">1x</span>
699
+ <span class="cline-any cline-yes">1x</span>
700
+ <span class="cline-any cline-yes">1x</span>
701
+ <span class="cline-any cline-yes">1x</span>
702
+ <span class="cline-any cline-yes">1x</span>
703
+ <span class="cline-any cline-yes">1x</span>
704
+ <span class="cline-any cline-yes">1x</span>
705
+ <span class="cline-any cline-yes">1x</span>
706
+ <span class="cline-any cline-yes">1x</span>
707
+ <span class="cline-any cline-yes">1x</span>
708
+ <span class="cline-any cline-yes">1x</span>
709
+ <span class="cline-any cline-yes">1x</span>
710
+ <span class="cline-any cline-yes">1x</span>
711
+ <span class="cline-any cline-yes">1x</span>
712
+ <span class="cline-any cline-yes">1x</span>
713
+ <span class="cline-any cline-yes">1x</span>
714
+ <span class="cline-any cline-yes">1x</span>
715
+ <span class="cline-any cline-yes">1x</span>
716
+ <span class="cline-any cline-yes">1x</span>
717
+ <span class="cline-any cline-yes">1x</span>
718
+ <span class="cline-any cline-yes">1x</span>
719
+ <span class="cline-any cline-yes">1x</span>
720
+ <span class="cline-any cline-yes">1x</span>
721
+ <span class="cline-any cline-yes">1x</span>
722
+ <span class="cline-any cline-yes">1x</span>
723
+ <span class="cline-any cline-yes">1x</span>
724
+ <span class="cline-any cline-yes">77x</span>
725
+ <span class="cline-any cline-yes">77x</span>
726
+ <span class="cline-any cline-yes">73x</span>
727
+ <span class="cline-any cline-yes">73x</span>
728
+ <span class="cline-any cline-yes">77x</span>
729
+ <span class="cline-any cline-yes">69x</span>
730
+ <span class="cline-any cline-yes">77x</span>
731
+ <span class="cline-any cline-yes">1x</span>
732
+ <span class="cline-any cline-yes">1x</span>
733
+ <span class="cline-any cline-yes">1x</span>
734
+ <span class="cline-any cline-yes">1x</span>
735
+ <span class="cline-any cline-yes">1x</span>
736
+ <span class="cline-any cline-yes">1x</span>
737
+ <span class="cline-any cline-yes">45x</span>
738
+ <span class="cline-any cline-yes">45x</span>
739
+ <span class="cline-any cline-yes">45x</span>
740
+ <span class="cline-any cline-yes">45x</span>
741
+ <span class="cline-any cline-yes">45x</span>
742
+ <span class="cline-any cline-yes">6x</span>
743
+ <span class="cline-any cline-yes">45x</span>
744
+ <span class="cline-any cline-yes">4x</span>
745
+ <span class="cline-any cline-yes">39x</span>
746
+ <span class="cline-any cline-yes">4x</span>
747
+ <span class="cline-any cline-yes">4x</span>
748
+ <span class="cline-any cline-yes">45x</span>
749
+ <span class="cline-any cline-yes">45x</span>
750
+ <span class="cline-any cline-yes">45x</span>
751
+ <span class="cline-any cline-yes">45x</span>
752
+ <span class="cline-any cline-yes">45x</span>
753
+ <span class="cline-any cline-yes">45x</span>
754
+ <span class="cline-any cline-yes">45x</span>
755
+ <span class="cline-any cline-yes">45x</span>
756
+ <span class="cline-any cline-yes">45x</span>
757
+ <span class="cline-any cline-yes">45x</span>
758
+ <span class="cline-any cline-yes">45x</span>
759
+ <span class="cline-any cline-yes">45x</span>
760
+ <span class="cline-any cline-yes">45x</span>
761
+ <span class="cline-any cline-yes">45x</span>
762
+ <span class="cline-any cline-yes">45x</span>
763
+ <span class="cline-any cline-yes">45x</span>
764
+ <span class="cline-any cline-yes">45x</span>
765
+ <span class="cline-any cline-yes">45x</span>
766
+ <span class="cline-any cline-yes">45x</span>
767
+ <span class="cline-any cline-yes">45x</span>
768
+ <span class="cline-any cline-yes">45x</span>
769
+ <span class="cline-any cline-yes">45x</span>
770
+ <span class="cline-any cline-yes">45x</span>
771
+ <span class="cline-any cline-yes">5x</span>
772
+ <span class="cline-any cline-yes">5x</span>
773
+ <span class="cline-any cline-yes">45x</span>
774
+ <span class="cline-any cline-yes">45x</span>
775
+ <span class="cline-any cline-yes">45x</span>
776
+ <span class="cline-any cline-yes">1x</span>
777
+ <span class="cline-any cline-yes">1x</span>
778
+ <span class="cline-any cline-yes">1x</span>
779
+ <span class="cline-any cline-yes">1x</span>
780
+ <span class="cline-any cline-yes">1x</span>
781
+ <span class="cline-any cline-yes">1x</span>
782
+ <span class="cline-any cline-yes">1x</span>
783
+ <span class="cline-any cline-yes">1x</span>
784
+ <span class="cline-any cline-yes">1x</span>
785
+ <span class="cline-any cline-yes">1x</span>
786
+ <span class="cline-any cline-yes">1x</span>
787
+ <span class="cline-any cline-yes">1x</span>
788
+ <span class="cline-any cline-yes">1x</span>
789
+ <span class="cline-any cline-yes">1x</span>
790
+ <span class="cline-any cline-yes">1x</span>
791
+ <span class="cline-any cline-yes">1x</span>
792
+ <span class="cline-any cline-yes">1x</span>
793
+ <span class="cline-any cline-yes">1x</span>
794
+ <span class="cline-any cline-yes">21x</span>
795
+ <span class="cline-any cline-yes">21x</span>
796
+ <span class="cline-any cline-yes">21x</span>
797
+ <span class="cline-any cline-yes">21x</span>
798
+ <span class="cline-any cline-yes">21x</span>
799
+ <span class="cline-any cline-yes">21x</span>
800
+ <span class="cline-any cline-yes">21x</span>
801
+ <span class="cline-any cline-yes">21x</span>
802
+ <span class="cline-any cline-yes">21x</span>
803
+ <span class="cline-any cline-yes">21x</span>
804
+ <span class="cline-any cline-yes">21x</span>
805
+ <span class="cline-any cline-yes">21x</span>
806
+ <span class="cline-any cline-yes">21x</span>
807
+ <span class="cline-any cline-yes">21x</span>
808
+ <span class="cline-any cline-yes">21x</span>
809
+ <span class="cline-any cline-yes">21x</span>
810
+ <span class="cline-any cline-yes">21x</span>
811
+ <span class="cline-any cline-yes">21x</span>
812
+ <span class="cline-any cline-yes">21x</span>
813
+ <span class="cline-any cline-yes">21x</span>
814
+ <span class="cline-any cline-yes">21x</span>
815
+ <span class="cline-any cline-yes">21x</span>
816
+ <span class="cline-any cline-yes">21x</span>
817
+ <span class="cline-any cline-yes">21x</span>
818
+ <span class="cline-any cline-yes">21x</span>
819
+ <span class="cline-any cline-yes">21x</span>
820
+ <span class="cline-any cline-yes">21x</span>
821
+ <span class="cline-any cline-yes">21x</span>
822
+ <span class="cline-any cline-yes">21x</span>
823
+ <span class="cline-any cline-yes">21x</span>
824
+ <span class="cline-any cline-yes">21x</span>
825
+ <span class="cline-any cline-yes">21x</span>
826
+ <span class="cline-any cline-yes">21x</span>
827
+ <span class="cline-any cline-yes">21x</span>
828
+ <span class="cline-any cline-yes">21x</span>
829
+ <span class="cline-any cline-yes">21x</span>
830
+ <span class="cline-any cline-yes">21x</span>
831
+ <span class="cline-any cline-yes">1x</span>
832
+ <span class="cline-any cline-yes">1x</span>
833
+ <span class="cline-any cline-yes">1x</span>
834
+ <span class="cline-any cline-yes">1x</span>
835
+ <span class="cline-any cline-yes">1x</span>
836
+ <span class="cline-any cline-yes">1x</span>
837
+ <span class="cline-any cline-yes">1x</span>
838
+ <span class="cline-any cline-yes">3x</span>
839
+ <span class="cline-any cline-yes">3x</span>
840
+ <span class="cline-any cline-yes">3x</span>
841
+ <span class="cline-any cline-yes">3x</span>
842
+ <span class="cline-any cline-yes">3x</span>
843
+ <span class="cline-any cline-yes">3x</span>
844
+ <span class="cline-any cline-no">&nbsp;</span>
845
+ <span class="cline-any cline-no">&nbsp;</span>
846
+ <span class="cline-any cline-no">&nbsp;</span>
847
+ <span class="cline-any cline-no">&nbsp;</span>
848
+ <span class="cline-any cline-no">&nbsp;</span>
849
+ <span class="cline-any cline-no">&nbsp;</span>
850
+ <span class="cline-any cline-no">&nbsp;</span>
851
+ <span class="cline-any cline-no">&nbsp;</span>
852
+ <span class="cline-any cline-no">&nbsp;</span>
853
+ <span class="cline-any cline-no">&nbsp;</span>
854
+ <span class="cline-any cline-no">&nbsp;</span>
855
+ <span class="cline-any cline-no">&nbsp;</span>
856
+ <span class="cline-any cline-no">&nbsp;</span>
857
+ <span class="cline-any cline-no">&nbsp;</span>
858
+ <span class="cline-any cline-no">&nbsp;</span>
859
+ <span class="cline-any cline-no">&nbsp;</span>
860
+ <span class="cline-any cline-no">&nbsp;</span>
861
+ <span class="cline-any cline-no">&nbsp;</span>
862
+ <span class="cline-any cline-no">&nbsp;</span>
863
+ <span class="cline-any cline-no">&nbsp;</span>
864
+ <span class="cline-any cline-no">&nbsp;</span>
865
+ <span class="cline-any cline-no">&nbsp;</span>
866
+ <span class="cline-any cline-no">&nbsp;</span>
867
+ <span class="cline-any cline-no">&nbsp;</span>
868
+ <span class="cline-any cline-no">&nbsp;</span>
869
+ <span class="cline-any cline-no">&nbsp;</span>
870
+ <span class="cline-any cline-no">&nbsp;</span>
871
+ <span class="cline-any cline-no">&nbsp;</span>
872
+ <span class="cline-any cline-no">&nbsp;</span>
873
+ <span class="cline-any cline-no">&nbsp;</span>
874
+ <span class="cline-any cline-no">&nbsp;</span>
875
+ <span class="cline-any cline-no">&nbsp;</span>
876
+ <span class="cline-any cline-no">&nbsp;</span>
877
+ <span class="cline-any cline-no">&nbsp;</span>
878
+ <span class="cline-any cline-no">&nbsp;</span>
879
+ <span class="cline-any cline-no">&nbsp;</span>
880
+ <span class="cline-any cline-no">&nbsp;</span>
881
+ <span class="cline-any cline-no">&nbsp;</span>
882
+ <span class="cline-any cline-no">&nbsp;</span>
883
+ <span class="cline-any cline-no">&nbsp;</span>
884
+ <span class="cline-any cline-no">&nbsp;</span>
885
+ <span class="cline-any cline-no">&nbsp;</span>
886
+ <span class="cline-any cline-no">&nbsp;</span>
887
+ <span class="cline-any cline-no">&nbsp;</span>
888
+ <span class="cline-any cline-no">&nbsp;</span>
889
+ <span class="cline-any cline-no">&nbsp;</span>
890
+ <span class="cline-any cline-no">&nbsp;</span>
891
+ <span class="cline-any cline-no">&nbsp;</span>
892
+ <span class="cline-any cline-no">&nbsp;</span>
893
+ <span class="cline-any cline-no">&nbsp;</span>
894
+ <span class="cline-any cline-no">&nbsp;</span>
895
+ <span class="cline-any cline-no">&nbsp;</span>
896
+ <span class="cline-any cline-no">&nbsp;</span>
897
+ <span class="cline-any cline-no">&nbsp;</span>
898
+ <span class="cline-any cline-no">&nbsp;</span>
899
+ <span class="cline-any cline-no">&nbsp;</span>
900
+ <span class="cline-any cline-no">&nbsp;</span>
901
+ <span class="cline-any cline-no">&nbsp;</span>
902
+ <span class="cline-any cline-no">&nbsp;</span>
903
+ <span class="cline-any cline-no">&nbsp;</span>
904
+ <span class="cline-any cline-no">&nbsp;</span>
905
+ <span class="cline-any cline-no">&nbsp;</span>
906
+ <span class="cline-any cline-no">&nbsp;</span>
907
+ <span class="cline-any cline-no">&nbsp;</span>
908
+ <span class="cline-any cline-no">&nbsp;</span>
909
+ <span class="cline-any cline-no">&nbsp;</span>
910
+ <span class="cline-any cline-no">&nbsp;</span>
911
+ <span class="cline-any cline-no">&nbsp;</span>
912
+ <span class="cline-any cline-no">&nbsp;</span>
913
+ <span class="cline-any cline-no">&nbsp;</span>
914
+ <span class="cline-any cline-no">&nbsp;</span>
915
+ <span class="cline-any cline-no">&nbsp;</span>
916
+ <span class="cline-any cline-no">&nbsp;</span>
917
+ <span class="cline-any cline-no">&nbsp;</span>
918
+ <span class="cline-any cline-no">&nbsp;</span>
919
+ <span class="cline-any cline-no">&nbsp;</span>
920
+ <span class="cline-any cline-no">&nbsp;</span>
921
+ <span class="cline-any cline-no">&nbsp;</span>
922
+ <span class="cline-any cline-no">&nbsp;</span>
923
+ <span class="cline-any cline-no">&nbsp;</span>
924
+ <span class="cline-any cline-no">&nbsp;</span>
925
+ <span class="cline-any cline-no">&nbsp;</span>
926
+ <span class="cline-any cline-no">&nbsp;</span>
927
+ <span class="cline-any cline-no">&nbsp;</span>
928
+ <span class="cline-any cline-no">&nbsp;</span>
929
+ <span class="cline-any cline-no">&nbsp;</span>
930
+ <span class="cline-any cline-no">&nbsp;</span>
931
+ <span class="cline-any cline-no">&nbsp;</span>
932
+ <span class="cline-any cline-no">&nbsp;</span>
933
+ <span class="cline-any cline-no">&nbsp;</span>
934
+ <span class="cline-any cline-yes">3x</span>
935
+ <span class="cline-any cline-yes">3x</span>
936
+ <span class="cline-any cline-yes">1x</span>
937
+ <span class="cline-any cline-yes">1x</span>
938
+ <span class="cline-any cline-yes">1x</span>
939
+ <span class="cline-any cline-yes">1x</span>
940
+ <span class="cline-any cline-yes">1x</span>
941
+ <span class="cline-any cline-yes">1x</span>
942
+ <span class="cline-any cline-yes">1x</span>
943
+ <span class="cline-any cline-yes">1x</span>
944
+ <span class="cline-any cline-yes">18x</span>
945
+ <span class="cline-any cline-yes">18x</span>
946
+ <span class="cline-any cline-yes">18x</span>
947
+ <span class="cline-any cline-yes">18x</span>
948
+ <span class="cline-any cline-yes">18x</span>
949
+ <span class="cline-any cline-yes">18x</span>
950
+ <span class="cline-any cline-yes">18x</span>
951
+ <span class="cline-any cline-yes">18x</span>
952
+ <span class="cline-any cline-yes">18x</span>
953
+ <span class="cline-any cline-yes">18x</span>
954
+ <span class="cline-any cline-yes">18x</span>
955
+ <span class="cline-any cline-yes">18x</span>
956
+ <span class="cline-any cline-yes">18x</span>
957
+ <span class="cline-any cline-yes">18x</span>
958
+ <span class="cline-any cline-yes">18x</span>
959
+ <span class="cline-any cline-yes">18x</span>
960
+ <span class="cline-any cline-yes">18x</span>
961
+ <span class="cline-any cline-yes">18x</span>
962
+ <span class="cline-any cline-yes">18x</span>
963
+ <span class="cline-any cline-yes">18x</span>
964
+ <span class="cline-any cline-yes">18x</span>
965
+ <span class="cline-any cline-yes">18x</span>
966
+ <span class="cline-any cline-yes">55x</span>
967
+ <span class="cline-any cline-yes">55x</span>
968
+ <span class="cline-any cline-yes">55x</span>
969
+ <span class="cline-any cline-yes">55x</span>
970
+ <span class="cline-any cline-yes">55x</span>
971
+ <span class="cline-any cline-yes">55x</span>
972
+ <span class="cline-any cline-yes">55x</span>
973
+ <span class="cline-any cline-no">&nbsp;</span>
974
+ <span class="cline-any cline-no">&nbsp;</span>
975
+ <span class="cline-any cline-no">&nbsp;</span>
976
+ <span class="cline-any cline-no">&nbsp;</span>
977
+ <span class="cline-any cline-no">&nbsp;</span>
978
+ <span class="cline-any cline-no">&nbsp;</span>
979
+ <span class="cline-any cline-no">&nbsp;</span>
980
+ <span class="cline-any cline-yes">55x</span>
981
+ <span class="cline-any cline-yes">55x</span>
982
+ <span class="cline-any cline-yes">55x</span>
983
+ <span class="cline-any cline-yes">3x</span>
984
+ <span class="cline-any cline-yes">3x</span>
985
+ <span class="cline-any cline-yes">2x</span>
986
+ <span class="cline-any cline-yes">3x</span>
987
+ <span class="cline-any cline-yes">1x</span>
988
+ <span class="cline-any cline-yes">1x</span>
989
+ <span class="cline-any cline-yes">3x</span>
990
+ <span class="cline-any cline-yes">3x</span>
991
+ <span class="cline-any cline-yes">3x</span>
992
+ <span class="cline-any cline-yes">3x</span>
993
+ <span class="cline-any cline-yes">3x</span>
994
+ <span class="cline-any cline-yes">3x</span>
995
+ <span class="cline-any cline-no">&nbsp;</span>
996
+ <span class="cline-any cline-no">&nbsp;</span>
997
+ <span class="cline-any cline-no">&nbsp;</span>
998
+ <span class="cline-any cline-no">&nbsp;</span>
999
+ <span class="cline-any cline-yes">3x</span>
1000
+ <span class="cline-any cline-yes">3x</span>
1001
+ <span class="cline-any cline-yes">3x</span>
1002
+ <span class="cline-any cline-yes">3x</span>
1003
+ <span class="cline-any cline-yes">55x</span>
1004
+ <span class="cline-any cline-yes">55x</span>
1005
+ <span class="cline-any cline-yes">55x</span>
1006
+ <span class="cline-any cline-yes">55x</span>
1007
+ <span class="cline-any cline-yes">55x</span>
1008
+ <span class="cline-any cline-yes">55x</span>
1009
+ <span class="cline-any cline-yes">4x</span>
1010
+ <span class="cline-any cline-yes">4x</span>
1011
+ <span class="cline-any cline-yes">4x</span>
1012
+ <span class="cline-any cline-yes">4x</span>
1013
+ <span class="cline-any cline-yes">4x</span>
1014
+ <span class="cline-any cline-yes">4x</span>
1015
+ <span class="cline-any cline-no">&nbsp;</span>
1016
+ <span class="cline-any cline-no">&nbsp;</span>
1017
+ <span class="cline-any cline-no">&nbsp;</span>
1018
+ <span class="cline-any cline-no">&nbsp;</span>
1019
+ <span class="cline-any cline-no">&nbsp;</span>
1020
+ <span class="cline-any cline-yes">4x</span>
1021
+ <span class="cline-any cline-yes">4x</span>
1022
+ <span class="cline-any cline-yes">4x</span>
1023
+ <span class="cline-any cline-yes">4x</span>
1024
+ <span class="cline-any cline-yes">4x</span>
1025
+ <span class="cline-any cline-yes">4x</span>
1026
+ <span class="cline-any cline-no">&nbsp;</span>
1027
+ <span class="cline-any cline-no">&nbsp;</span>
1028
+ <span class="cline-any cline-no">&nbsp;</span>
1029
+ <span class="cline-any cline-no">&nbsp;</span>
1030
+ <span class="cline-any cline-no">&nbsp;</span>
1031
+ <span class="cline-any cline-yes">4x</span>
1032
+ <span class="cline-any cline-yes">55x</span>
1033
+ <span class="cline-any cline-yes">55x</span>
1034
+ <span class="cline-any cline-yes">55x</span>
1035
+ <span class="cline-any cline-yes">55x</span>
1036
+ <span class="cline-any cline-yes">55x</span>
1037
+ <span class="cline-any cline-yes">55x</span>
1038
+ <span class="cline-any cline-yes">55x</span>
1039
+ <span class="cline-any cline-yes">55x</span>
1040
+ <span class="cline-any cline-yes">55x</span>
1041
+ <span class="cline-any cline-yes">55x</span>
1042
+ <span class="cline-any cline-yes">10x</span>
1043
+ <span class="cline-any cline-yes">10x</span>
1044
+ <span class="cline-any cline-yes">10x</span>
1045
+ <span class="cline-any cline-yes">10x</span>
1046
+ <span class="cline-any cline-yes">10x</span>
1047
+ <span class="cline-any cline-yes">10x</span>
1048
+ <span class="cline-any cline-yes">45x</span>
1049
+ <span class="cline-any cline-yes">45x</span>
1050
+ <span class="cline-any cline-yes">55x</span>
1051
+ <span class="cline-any cline-yes">4x</span>
1052
+ <span class="cline-any cline-yes">4x</span>
1053
+ <span class="cline-any cline-yes">4x</span>
1054
+ <span class="cline-any cline-yes">4x</span>
1055
+ <span class="cline-any cline-yes">4x</span>
1056
+ <span class="cline-any cline-yes">4x</span>
1057
+ <span class="cline-any cline-yes">41x</span>
1058
+ <span class="cline-any cline-yes">55x</span>
1059
+ <span class="cline-any cline-yes">2x</span>
1060
+ <span class="cline-any cline-yes">2x</span>
1061
+ <span class="cline-any cline-yes">2x</span>
1062
+ <span class="cline-any cline-yes">2x</span>
1063
+ <span class="cline-any cline-yes">2x</span>
1064
+ <span class="cline-any cline-yes">2x</span>
1065
+ <span class="cline-any cline-yes">39x</span>
1066
+ <span class="cline-any cline-yes">39x</span>
1067
+ <span class="cline-any cline-yes">55x</span>
1068
+ <span class="cline-any cline-yes">1x</span>
1069
+ <span class="cline-any cline-yes">1x</span>
1070
+ <span class="cline-any cline-yes">38x</span>
1071
+ <span class="cline-any cline-yes">38x</span>
1072
+ <span class="cline-any cline-yes">55x</span>
1073
+ <span class="cline-any cline-yes">55x</span>
1074
+ <span class="cline-any cline-yes">55x</span>
1075
+ <span class="cline-any cline-yes">55x</span>
1076
+ <span class="cline-any cline-yes">55x</span>
1077
+ <span class="cline-any cline-yes">55x</span>
1078
+ <span class="cline-any cline-yes">55x</span>
1079
+ <span class="cline-any cline-yes">55x</span>
1080
+ <span class="cline-any cline-yes">55x</span>
1081
+ <span class="cline-any cline-yes">55x</span>
1082
+ <span class="cline-any cline-yes">55x</span>
1083
+ <span class="cline-any cline-yes">55x</span>
1084
+ <span class="cline-any cline-yes">55x</span>
1085
+ <span class="cline-any cline-yes">55x</span>
1086
+ <span class="cline-any cline-yes">55x</span>
1087
+ <span class="cline-any cline-yes">55x</span>
1088
+ <span class="cline-any cline-yes">55x</span>
1089
+ <span class="cline-any cline-yes">55x</span>
1090
+ <span class="cline-any cline-yes">55x</span>
1091
+ <span class="cline-any cline-yes">55x</span>
1092
+ <span class="cline-any cline-yes">55x</span>
1093
+ <span class="cline-any cline-yes">55x</span>
1094
+ <span class="cline-any cline-yes">55x</span>
1095
+ <span class="cline-any cline-yes">55x</span>
1096
+ <span class="cline-any cline-yes">55x</span>
1097
+ <span class="cline-any cline-yes">55x</span>
1098
+ <span class="cline-any cline-yes">55x</span>
1099
+ <span class="cline-any cline-yes">55x</span>
1100
+ <span class="cline-any cline-yes">55x</span>
1101
+ <span class="cline-any cline-yes">55x</span>
1102
+ <span class="cline-any cline-yes">55x</span>
1103
+ <span class="cline-any cline-yes">55x</span>
1104
+ <span class="cline-any cline-yes">55x</span>
1105
+ <span class="cline-any cline-yes">55x</span>
1106
+ <span class="cline-any cline-yes">55x</span>
1107
+ <span class="cline-any cline-yes">55x</span>
1108
+ <span class="cline-any cline-yes">6x</span>
1109
+ <span class="cline-any cline-yes">6x</span>
1110
+ <span class="cline-any cline-yes">6x</span>
1111
+ <span class="cline-any cline-yes">6x</span>
1112
+ <span class="cline-any cline-yes">6x</span>
1113
+ <span class="cline-any cline-yes">6x</span>
1114
+ <span class="cline-any cline-yes">6x</span>
1115
+ <span class="cline-any cline-yes">6x</span>
1116
+ <span class="cline-any cline-yes">38x</span>
1117
+ <span class="cline-any cline-yes">38x</span>
1118
+ <span class="cline-any cline-yes">38x</span>
1119
+ <span class="cline-any cline-yes">38x</span>
1120
+ <span class="cline-any cline-yes">38x</span>
1121
+ <span class="cline-any cline-yes">38x</span>
1122
+ <span class="cline-any cline-yes">55x</span>
1123
+ <span class="cline-any cline-yes">55x</span>
1124
+ <span class="cline-any cline-yes">55x</span>
1125
+ <span class="cline-any cline-yes">55x</span>
1126
+ <span class="cline-any cline-yes">1x</span>
1127
+ <span class="cline-any cline-yes">1x</span>
1128
+ <span class="cline-any cline-yes">1x</span>
1129
+ <span class="cline-any cline-yes">1x</span>
1130
+ <span class="cline-any cline-yes">1x</span>
1131
+ <span class="cline-any cline-yes">1x</span>
1132
+ <span class="cline-any cline-yes">1x</span>
1133
+ <span class="cline-any cline-yes">37x</span>
1134
+ <span class="cline-any cline-yes">37x</span>
1135
+ <span class="cline-any cline-yes">37x</span>
1136
+ <span class="cline-any cline-yes">55x</span>
1137
+ <span class="cline-any cline-yes">55x</span>
1138
+ <span class="cline-any cline-yes">55x</span>
1139
+ <span class="cline-any cline-yes">3x</span>
1140
+ <span class="cline-any cline-yes">3x</span>
1141
+ <span class="cline-any cline-yes">3x</span>
1142
+ <span class="cline-any cline-yes">3x</span>
1143
+ <span class="cline-any cline-yes">3x</span>
1144
+ <span class="cline-any cline-yes">3x</span>
1145
+ <span class="cline-any cline-yes">3x</span>
1146
+ <span class="cline-any cline-yes">3x</span>
1147
+ <span class="cline-any cline-yes">2x</span>
1148
+ <span class="cline-any cline-yes">2x</span>
1149
+ <span class="cline-any cline-yes">3x</span>
1150
+ <span class="cline-any cline-yes">2x</span>
1151
+ <span class="cline-any cline-yes">2x</span>
1152
+ <span class="cline-any cline-yes">3x</span>
1153
+ <span class="cline-any cline-yes">2x</span>
1154
+ <span class="cline-any cline-yes">2x</span>
1155
+ <span class="cline-any cline-yes">3x</span>
1156
+ <span class="cline-any cline-yes">2x</span>
1157
+ <span class="cline-any cline-yes">2x</span>
1158
+ <span class="cline-any cline-yes">55x</span>
1159
+ <span class="cline-any cline-yes">34x</span>
1160
+ <span class="cline-any cline-yes">34x</span>
1161
+ <span class="cline-any cline-yes">34x</span>
1162
+ <span class="cline-any cline-yes">34x</span>
1163
+ <span class="cline-any cline-yes">34x</span>
1164
+ <span class="cline-any cline-no">&nbsp;</span>
1165
+ <span class="cline-any cline-no">&nbsp;</span>
1166
+ <span class="cline-any cline-no">&nbsp;</span>
1167
+ <span class="cline-any cline-no">&nbsp;</span>
1168
+ <span class="cline-any cline-no">&nbsp;</span>
1169
+ <span class="cline-any cline-no">&nbsp;</span>
1170
+ <span class="cline-any cline-no">&nbsp;</span>
1171
+ <span class="cline-any cline-no">&nbsp;</span>
1172
+ <span class="cline-any cline-no">&nbsp;</span>
1173
+ <span class="cline-any cline-no">&nbsp;</span>
1174
+ <span class="cline-any cline-no">&nbsp;</span>
1175
+ <span class="cline-any cline-no">&nbsp;</span>
1176
+ <span class="cline-any cline-no">&nbsp;</span>
1177
+ <span class="cline-any cline-no">&nbsp;</span>
1178
+ <span class="cline-any cline-no">&nbsp;</span>
1179
+ <span class="cline-any cline-no">&nbsp;</span>
1180
+ <span class="cline-any cline-yes">34x</span>
1181
+ <span class="cline-any cline-yes">34x</span>
1182
+ <span class="cline-any cline-yes">34x</span>
1183
+ <span class="cline-any cline-yes">34x</span>
1184
+ <span class="cline-any cline-yes">34x</span>
1185
+ <span class="cline-any cline-yes">34x</span>
1186
+ <span class="cline-any cline-yes">34x</span>
1187
+ <span class="cline-any cline-yes">34x</span>
1188
+ <span class="cline-any cline-yes">34x</span>
1189
+ <span class="cline-any cline-yes">37x</span>
1190
+ <span class="cline-any cline-yes">37x</span>
1191
+ <span class="cline-any cline-yes">37x</span>
1192
+ <span class="cline-any cline-yes">37x</span>
1193
+ <span class="cline-any cline-yes">55x</span>
1194
+ <span class="cline-any cline-yes">2x</span>
1195
+ <span class="cline-any cline-yes">2x</span>
1196
+ <span class="cline-any cline-yes">2x</span>
1197
+ <span class="cline-any cline-yes">2x</span>
1198
+ <span class="cline-any cline-yes">2x</span>
1199
+ <span class="cline-any cline-yes">2x</span>
1200
+ <span class="cline-any cline-yes">2x</span>
1201
+ <span class="cline-any cline-yes">2x</span>
1202
+ <span class="cline-any cline-yes">2x</span>
1203
+ <span class="cline-any cline-yes">37x</span>
1204
+ <span class="cline-any cline-yes">37x</span>
1205
+ <span class="cline-any cline-yes">55x</span>
1206
+ <span class="cline-any cline-yes">1x</span>
1207
+ <span class="cline-any cline-yes">1x</span>
1208
+ <span class="cline-any cline-yes">1x</span>
1209
+ <span class="cline-any cline-no">&nbsp;</span>
1210
+ <span class="cline-any cline-no">&nbsp;</span>
1211
+ <span class="cline-any cline-yes">1x</span>
1212
+ <span class="cline-any cline-yes">37x</span>
1213
+ <span class="cline-any cline-yes">37x</span>
1214
+ <span class="cline-any cline-yes">55x</span>
1215
+ <span class="cline-any cline-yes">1x</span>
1216
+ <span class="cline-any cline-yes">1x</span>
1217
+ <span class="cline-any cline-yes">1x</span>
1218
+ <span class="cline-any cline-yes">1x</span>
1219
+ <span class="cline-any cline-yes">1x</span>
1220
+ <span class="cline-any cline-yes">1x</span>
1221
+ <span class="cline-any cline-yes">1x</span>
1222
+ <span class="cline-any cline-yes">37x</span>
1223
+ <span class="cline-any cline-yes">37x</span>
1224
+ <span class="cline-any cline-yes">55x</span>
1225
+ <span class="cline-any cline-yes">14x</span>
1226
+ <span class="cline-any cline-yes">14x</span>
1227
+ <span class="cline-any cline-yes">14x</span>
1228
+ <span class="cline-any cline-yes">14x</span>
1229
+ <span class="cline-any cline-yes">14x</span>
1230
+ <span class="cline-any cline-yes">14x</span>
1231
+ <span class="cline-any cline-yes">14x</span>
1232
+ <span class="cline-any cline-yes">14x</span>
1233
+ <span class="cline-any cline-yes">14x</span>
1234
+ <span class="cline-any cline-no">&nbsp;</span>
1235
+ <span class="cline-any cline-no">&nbsp;</span>
1236
+ <span class="cline-any cline-yes">14x</span>
1237
+ <span class="cline-any cline-yes">55x</span>
1238
+ <span class="cline-any cline-yes">55x</span>
1239
+ <span class="cline-any cline-yes">55x</span>
1240
+ <span class="cline-any cline-yes">55x</span>
1241
+ <span class="cline-any cline-yes">55x</span>
1242
+ <span class="cline-any cline-yes">18x</span>
1243
+ <span class="cline-any cline-no">&nbsp;</span>
1244
+ <span class="cline-any cline-no">&nbsp;</span>
1245
+ <span class="cline-any cline-no">&nbsp;</span>
1246
+ <span class="cline-any cline-no">&nbsp;</span>
1247
+ <span class="cline-any cline-no">&nbsp;</span>
1248
+ <span class="cline-any cline-no">&nbsp;</span>
1249
+ <span class="cline-any cline-yes">18x</span>
1250
+ <span class="cline-any cline-yes">18x</span>
1251
+ <span class="cline-any cline-yes">18x</span>
1252
+ <span class="cline-any cline-yes">18x</span>
1253
+ <span class="cline-any cline-yes">18x</span>
1254
+ <span class="cline-any cline-yes">18x</span>
1255
+ <span class="cline-any cline-yes">3x</span>
1256
+ <span class="cline-any cline-yes">3x</span>
1257
+ <span class="cline-any cline-yes">3x</span>
1258
+ <span class="cline-any cline-yes">3x</span>
1259
+ <span class="cline-any cline-yes">3x</span>
1260
+ <span class="cline-any cline-yes">3x</span>
1261
+ <span class="cline-any cline-yes">3x</span>
1262
+ <span class="cline-any cline-yes">3x</span>
1263
+ <span class="cline-any cline-no">&nbsp;</span>
1264
+ <span class="cline-any cline-no">&nbsp;</span>
1265
+ <span class="cline-any cline-no">&nbsp;</span>
1266
+ <span class="cline-any cline-no">&nbsp;</span>
1267
+ <span class="cline-any cline-no">&nbsp;</span>
1268
+ <span class="cline-any cline-no">&nbsp;</span>
1269
+ <span class="cline-any cline-yes">3x</span>
1270
+ <span class="cline-any cline-yes">18x</span>
1271
+ <span class="cline-any cline-yes">18x</span>
1272
+ <span class="cline-any cline-yes">18x</span>
1273
+ <span class="cline-any cline-yes">18x</span>
1274
+ <span class="cline-any cline-yes">18x</span>
1275
+ <span class="cline-any cline-yes">18x</span>
1276
+ <span class="cline-any cline-yes">18x</span>
1277
+ <span class="cline-any cline-yes">18x</span>
1278
+ <span class="cline-any cline-yes">18x</span>
1279
+ <span class="cline-any cline-yes">1x</span>
1280
+ <span class="cline-any cline-yes">1x</span>
1281
+ <span class="cline-any cline-yes">1x</span>
1282
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/**
1283
+ * Conversation Driver — Outbound multi-turn orchestrator
1284
+ *
1285
+ * Drives a full multi-turn A2A conversation with a remote agent:
1286
+ * 1. Send message to remote via A2AClient.call()
1287
+ * 2. Store messages in DB
1288
+ * 3. Check close conditions
1289
+ * 4. Build prompt via buildAdaptiveConnectionPrompt()
1290
+ * 5. Call runtime.runTurn() to generate next message
1291
+ * 6. Extract collab state from response
1292
+ * 7. Persist collab state to DB
1293
+ * 8. Repeat until close conditions met
1294
+ * 9. Call A2AClient.end() and conclude locally
1295
+ */
1296
+ &nbsp;
1297
+ const crypto = require('crypto');
1298
+ const { A2AClient } = require('./client');
1299
+ const {
1300
+ buildAdaptiveConnectionPrompt,
1301
+ extractCollaborationState
1302
+ } = require('./prompt-template');
1303
+ const { getTopicsForTier, formatTopicsForPrompt, loadManifest } = require('./disclosure');
1304
+ const { createLogger } = require('./logger');
1305
+ const { buildUnifiedSummaryPrompt } = require('./summary-prompt');
1306
+ const { resolveTokenTimeoutMs, resolveTurnTimeoutMs } = require('./turn-timeout');
1307
+ &nbsp;
1308
+ const logger = createLogger({ component: 'a2a.conversation-driver' });
1309
+ &nbsp;
1310
+ /**
1311
+ * Detect remote termination intent from response text.
1312
+ * Returns true if the remote agent is clearly trying to end the conversation.
1313
+ */
1314
+ const TERMINATION_PATTERNS = [
1315
+ /\[TERMINAT/i,
1316
+ /\[DISCONNECT/i,
1317
+ /\[END.?CALL\]/i,
1318
+ /\[CLOSING\]/i,
1319
+ /\bEND.?CALL\b/i,
1320
+ /\bcall\s+closed\b/i,
1321
+ /\bwrapping\s+up\b/i,
1322
+ /\[No\s+further\b/i,
1323
+ /\bno\s+further\b/i,
1324
+ /\bREFUSING\s+(TO\s+)?(CONTINU|RESPOND|ENGAG)/i,
1325
+ /\bcall\s+complet(ed|e)\b/i,
1326
+ /\bconversation\s+(is\s+)?(over|ended|closed|complet)/i,
1327
+ /\bclosing\s+this\s+(call|conversation|connection)\b/i,
1328
+ /\bgoodbye\b.*\b(end|clos|terminat)/i,
1329
+ /\bdisconnect(ing|ed)\b/i
1330
+ ];
1331
+ &nbsp;
1332
+ function detectRemoteTermination(text) {
1333
+ if (!text || typeof text !== 'string') return false;
1334
+ // Very short responses (single dot, empty-ish) indicate dead conversation
1335
+ const trimmed = text.trim();
1336
+ if (trimmed.length &lt;= 1) return true;
1337
+ return TERMINATION_PATTERNS.some(pattern =&gt; pattern.test(text));
1338
+ }
1339
+ &nbsp;
1340
+ /**
1341
+ * Infer collaboration state progression when the runtime doesn't emit
1342
+ * &lt;collab_state&gt; tags (e.g. OpenClaw without adaptive mode). Advances phase based on
1343
+ * turn count and estimates overlap from remote text analysis.
1344
+ */
1345
+ function inferStateProgression(collabState, remoteText, turn) {
1346
+ const patch = {};
1347
+ &nbsp;
1348
+ // Phase progression based on turn count
1349
+ if (collabState.phase === 'handshake' &amp;&amp; turn &gt;= 2) {
1350
+ patch.phase = 'exploring';
1351
+ } else if (collabState.phase === 'exploring' &amp;&amp; turn &gt;= 5) {
1352
+ patch.phase = 'deepening';
1353
+ } else if (collabState.phase === 'deepening' &amp;&amp; turn &gt;= 8) {
1354
+ patch.phase = 'converging';
1355
+ }
1356
+ &nbsp;
1357
+ // Estimate overlap from remote text length and engagement signals
1358
+ const text = (remoteText <span class="branch-0 cbranch-no" title="branch not covered" >|| '')</span>.toLowerCase();
1359
+ const engagementSignals = [
1360
+ /\binteresting\b/, /\bgreat\b/, /\bexciting\b/, /\bagree\b/,
1361
+ /\bcollaborat/i, /\bpartner/i, /\btogether\b/, /\bshare\b/,
1362
+ /\bopportunit/i, /\bsynerg/i, /\bcomplement/i, /\balign/i,
1363
+ /\?/ // questions indicate engagement
1364
+ ];
1365
+ const matchCount = engagementSignals.filter(p =&gt; p.test(text)).length;
1366
+ const textLengthFactor = Math.min(text.length / 500, 1); // longer = more engaged
1367
+ const engagement = (matchCount / engagementSignals.length) * 0.5 + textLengthFactor * 0.3;
1368
+ &nbsp;
1369
+ // Blend current overlap with new engagement signal
1370
+ const newOverlap = collabState.overlapScore * 0.6 + engagement * 0.4;
1371
+ patch.overlapScore = Math.max(0.1, Math.min(0.95, newOverlap));
1372
+ &nbsp;
1373
+ // Confidence increases over turns
1374
+ patch.confidence = Math.min(0.9, 0.25 + turn * 0.08);
1375
+ &nbsp;
1376
+ // In converging phase, signal close — conversation has run its natural course
1377
+ const effectivePhase = patch.phase || collabState.phase;
1378
+ if (effectivePhase === 'converging') {
1379
+ patch.closeSignal = true;
1380
+ }
1381
+ &nbsp;
1382
+ return patch;
1383
+ }
1384
+ &nbsp;
1385
+ class ConversationDriver {
1386
+ /**
1387
+ * @param {object} options
1388
+ * @param {object} options.runtime - Runtime adapter with runTurn()
1389
+ * @param {object} options.agentContext - { name, owner }
1390
+ * @param {object} options.caller - Caller identity { name, owner, instance }
1391
+ * @param {string|object} options.endpoint - a2a:// URL or {host, token}
1392
+ * @param {object} [options.convStore] - ConversationStore instance
1393
+ * @param {object} [options.disclosure] - Disclosure manifest override
1394
+ * @param {number} [options.minTurns=8] - Minimum turns before close
1395
+ * @param {number} [options.maxTurns=30] - Maximum turns
1396
+ * @param {function} [options.onTurn] - Callback per turn: (turnInfo) =&gt; void
1397
+ * @param {string} [options.tier='public'] - Access tier
1398
+ * @param {function} [options.summarizer] - async (messages, ownerContext) =&gt; summary result
1399
+ * @param {object} [options.ownerContext] - Owner context for summarizer (goals, interests, etc.)
1400
+ */
1401
+ constructor(options) {
1402
+ this.runtime = options.runtime;
1403
+ this.agentContext = options.agentContext;
1404
+ this.caller = options.caller <span class="branch-0 cbranch-no" title="branch not covered" >|| {};</span>
1405
+ this.endpoint = options.endpoint;
1406
+ this.convStore = options.convStore || null;
1407
+ this.disclosure = options.disclosure || null;
1408
+ this.minTurns = options.minTurns || 8;
1409
+ this.maxTurns = options.maxTurns || 30;
1410
+ this.onTurn = options.onTurn || null;
1411
+ this.tier = options.tier || 'public';
1412
+ // Optional permission envelope for runtimes (primarily Claude mode).
1413
+ // If provided by caller, this keeps tool allowlists variable per token/profile.
1414
+ this.capabilities = Array.isArray(options.capabilities) <span class="branch-0 cbranch-no" title="branch not covered" >? options.capabilities </span>: [];
1415
+ this.allowedTopics = Array.isArray(options.allowedTopics) <span class="branch-0 cbranch-no" title="branch not covered" >? options.allowedTopics </span>: [];
1416
+ this.allowedGoals = Array.isArray(options.allowedGoals) <span class="branch-0 cbranch-no" title="branch not covered" >? options.allowedGoals </span>: [];
1417
+ this.allowedTools = Array.isArray(options.allowedTools) <span class="branch-0 cbranch-no" title="branch not covered" >? options.allowedTools </span>: [];
1418
+ this.summarizer = options.summarizer || null;
1419
+ this.ownerContext = options.ownerContext || {};
1420
+ this.claudeMode = options.runtime?.mode === 'claude';
1421
+ &nbsp;
1422
+ const tokenTimeoutMs = options.tokenTimeoutMs
1423
+ || options.claudeTimeoutMs
1424
+ || resolveTokenTimeoutMs(options.token);
1425
+ const configTimeoutMs = options.configTurnTimeoutMs;
1426
+ this.claudeTimeoutMs = resolveTurnTimeoutMs({ tokenTimeoutMs, configTimeoutMs });
1427
+ &nbsp;
1428
+ const clientTimeout = this.claudeMode
1429
+ ? Math.max(this.claudeTimeoutMs + 20000, 200000)
1430
+ : 65000;
1431
+ // A2A-52: pass Ed25519 keypair for request signing
1432
+ this.client = new A2AClient({
1433
+ caller: this.caller,
1434
+ timeout: clientTimeout,
1435
+ privateKey: options.privateKey || null,
1436
+ publicKey: options.publicKey || null
1437
+ });
1438
+ }
1439
+ &nbsp;
1440
+ /**
1441
+ * Build a summarizer function from the runtime adapter.
1442
+ * Mirrors server.js generateSummary — uses runtime.summarize when available,
1443
+ * falls back to defaultSummarizer otherwise.
1444
+ */
1445
+ _buildSummarizer() {
1446
+ const runtime = this.runtime;
1447
+ const agentContext = this.agentContext;
1448
+ const caller = this.caller;
1449
+ const tier = this.tier;
1450
+ &nbsp;
1451
+ return async (messages, ownerContext) =&gt; {
1452
+ <span class="cstat-no" title="statement not covered" > if (!messages || messages.length === 0) {</span>
1453
+ <span class="cstat-no" title="statement not covered" > return { summary: null };</span>
1454
+ <span class="cstat-no" title="statement not covered" > }</span>
1455
+ <span class="cstat-no" title="statement not covered" ></span>
1456
+ <span class="cstat-no" title="statement not covered" > // Build transcript in unified format</span>
1457
+ <span class="cstat-no" title="statement not covered" > const transcript = messages.map(m =&gt; ({</span>
1458
+ <span class="cstat-no" title="statement not covered" > direction: m.direction,</span>
1459
+ <span class="cstat-no" title="statement not covered" > content: m.content</span>
1460
+ <span class="cstat-no" title="statement not covered" > }));</span>
1461
+ <span class="cstat-no" title="statement not covered" ></span>
1462
+ <span class="cstat-no" title="statement not covered" > // Load disclosure manifest for the tier</span>
1463
+ <span class="cstat-no" title="statement not covered" > let disclosure = null;</span>
1464
+ <span class="cstat-no" title="statement not covered" > try {</span>
1465
+ <span class="cstat-no" title="statement not covered" > const tierTopics = getTopicsForTier(tier);</span>
1466
+ <span class="cstat-no" title="statement not covered" > if (tierTopics) {</span>
1467
+ <span class="cstat-no" title="statement not covered" > disclosure = {</span>
1468
+ <span class="cstat-no" title="statement not covered" > topics: tierTopics.topics || [],</span>
1469
+ <span class="cstat-no" title="statement not covered" > objectives: tierTopics.objectives || [],</span>
1470
+ <span class="cstat-no" title="statement not covered" > doNotDiscuss: tierTopics.do_not_discuss || [],</span>
1471
+ <span class="cstat-no" title="statement not covered" > neverDisclose: tierTopics.never_disclose || []</span>
1472
+ <span class="cstat-no" title="statement not covered" > };</span>
1473
+ <span class="cstat-no" title="statement not covered" > }</span>
1474
+ <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1475
+ <span class="cstat-no" title="statement not covered" > // Disclosure is optional — continue without it</span>
1476
+ <span class="cstat-no" title="statement not covered" > }</span>
1477
+ <span class="cstat-no" title="statement not covered" ></span>
1478
+ <span class="cstat-no" title="statement not covered" > // Look up collaboration state from convStore if available</span>
1479
+ <span class="cstat-no" title="statement not covered" > let collaborationState = null;</span>
1480
+ <span class="cstat-no" title="statement not covered" > if (this.convStore) {</span>
1481
+ <span class="cstat-no" title="statement not covered" > try {</span>
1482
+ <span class="cstat-no" title="statement not covered" > const dbState = this.convStore.loadCollabState(this.lastConversationId || '');</span>
1483
+ <span class="cstat-no" title="statement not covered" > if (dbState) {</span>
1484
+ <span class="cstat-no" title="statement not covered" > collaborationState = {</span>
1485
+ <span class="cstat-no" title="statement not covered" > phase: dbState.phase,</span>
1486
+ <span class="cstat-no" title="statement not covered" > overlapScore: dbState.overlapScore,</span>
1487
+ <span class="cstat-no" title="statement not covered" > turnCount: dbState.turnCount,</span>
1488
+ <span class="cstat-no" title="statement not covered" > activeThreads: dbState.activeThreads,</span>
1489
+ <span class="cstat-no" title="statement not covered" > candidateCollaborations: dbState.candidateCollaborations,</span>
1490
+ <span class="cstat-no" title="statement not covered" > closeSignal: dbState.closeSignal</span>
1491
+ <span class="cstat-no" title="statement not covered" > };</span>
1492
+ <span class="cstat-no" title="statement not covered" > }</span>
1493
+ <span class="cstat-no" title="statement not covered" > } catch (e) {</span>
1494
+ <span class="cstat-no" title="statement not covered" > // Best effort</span>
1495
+ <span class="cstat-no" title="statement not covered" > }</span>
1496
+ <span class="cstat-no" title="statement not covered" > }</span>
1497
+ <span class="cstat-no" title="statement not covered" ></span>
1498
+ <span class="cstat-no" title="statement not covered" > // Map ownerContext into unified format</span>
1499
+ <span class="cstat-no" title="statement not covered" > const unifiedOwnerContext = {</span>
1500
+ <span class="cstat-no" title="statement not covered" > agentName: agentContext.name,</span>
1501
+ <span class="cstat-no" title="statement not covered" > ownerName: agentContext.owner,</span>
1502
+ <span class="cstat-no" title="statement not covered" > goals: ownerContext?.goals || []</span>
1503
+ <span class="cstat-no" title="statement not covered" > };</span>
1504
+ <span class="cstat-no" title="statement not covered" ></span>
1505
+ <span class="cstat-no" title="statement not covered" > const prompt = buildUnifiedSummaryPrompt({</span>
1506
+ <span class="cstat-no" title="statement not covered" > transcript,</span>
1507
+ <span class="cstat-no" title="statement not covered" > callerInfo: {</span>
1508
+ <span class="cstat-no" title="statement not covered" > name: caller.name || null,</span>
1509
+ <span class="cstat-no" title="statement not covered" > owner: caller.owner || null,</span>
1510
+ <span class="cstat-no" title="statement not covered" > context: caller.context || null</span>
1511
+ <span class="cstat-no" title="statement not covered" > },</span>
1512
+ <span class="cstat-no" title="statement not covered" > conversationObjective: 'You initiated this call.',</span>
1513
+ <span class="cstat-no" title="statement not covered" > disclosure,</span>
1514
+ <span class="cstat-no" title="statement not covered" > collaborationState,</span>
1515
+ <span class="cstat-no" title="statement not covered" > ownerContext: unifiedOwnerContext</span>
1516
+ <span class="cstat-no" title="statement not covered" > });</span>
1517
+ <span class="cstat-no" title="statement not covered" ></span>
1518
+ <span class="cstat-no" title="statement not covered" > // Try runtime.summarize if available (OpenClaw path)</span>
1519
+ <span class="cstat-no" title="statement not covered" > if (typeof runtime.summarize === 'function') {</span>
1520
+ <span class="cstat-no" title="statement not covered" > try {</span>
1521
+ <span class="cstat-no" title="statement not covered" > const summarySessionId = this.lastConversationId</span>
1522
+ <span class="cstat-no" title="statement not covered" > ? `a2a-${this.lastConversationId}`</span>
1523
+ <span class="cstat-no" title="statement not covered" > : `summary-${Date.now()}`;</span>
1524
+ <span class="cstat-no" title="statement not covered" > return await runtime.summarize({</span>
1525
+ <span class="cstat-no" title="statement not covered" > sessionId: summarySessionId,</span>
1526
+ <span class="cstat-no" title="statement not covered" > prompt,</span>
1527
+ <span class="cstat-no" title="statement not covered" > messages,</span>
1528
+ <span class="cstat-no" title="statement not covered" > callerInfo: { name: agentContext.name, owner: agentContext.owner },</span>
1529
+ <span class="cstat-no" title="statement not covered" > timeoutMs: this.claudeMode ? this.claudeTimeoutMs : 35000</span>
1530
+ <span class="cstat-no" title="statement not covered" > });</span>
1531
+ <span class="cstat-no" title="statement not covered" > } catch (err) {</span>
1532
+ <span class="cstat-no" title="statement not covered" > logger.warn('Runtime summarizer failed, using default', {</span>
1533
+ <span class="cstat-no" title="statement not covered" > event: 'driver_runtime_summarize_failed',</span>
1534
+ <span class="cstat-no" title="statement not covered" > error: err</span>
1535
+ <span class="cstat-no" title="statement not covered" > });</span>
1536
+ <span class="cstat-no" title="statement not covered" > }</span>
1537
+ <span class="cstat-no" title="statement not covered" > }</span>
1538
+ <span class="cstat-no" title="statement not covered" ></span>
1539
+ <span class="cstat-no" title="statement not covered" > // Fallback: use defaultSummarizer</span>
1540
+ <span class="cstat-no" title="statement not covered" > const { defaultSummarizer } = require('./summarizer');</span>
1541
+ <span class="cstat-no" title="statement not covered" > return defaultSummarizer(messages, ownerContext);</span>
1542
+ };
1543
+ }
1544
+ &nbsp;
1545
+ /**
1546
+ * Run the full multi-turn conversation
1547
+ *
1548
+ * @param {string} openingMessage - First message to send
1549
+ * @returns {Promise&lt;{conversationId, turnCount, collabState, transcript}&gt;}
1550
+ */
1551
+ async run(openingMessage) {
1552
+ const transcript = [];
1553
+ let conversationId = null;
1554
+ let dbConversationStarted = false;
1555
+ &nbsp;
1556
+ const collabState = {
1557
+ phase: 'handshake',
1558
+ turnCount: 0,
1559
+ overlapScore: 0.15,
1560
+ activeThreads: [],
1561
+ candidateCollaborations: [],
1562
+ openQuestions: [],
1563
+ closeSignal: false,
1564
+ confidence: 0.25
1565
+ };
1566
+ &nbsp;
1567
+ // Placeholder until we get a real ID from the remote (or generate one)
1568
+ conversationId = `conv_${Date.now()}_local`;
1569
+ &nbsp;
1570
+ let nextMessage = openingMessage;
1571
+ const overlapHistory = [];
1572
+ &nbsp;
1573
+ for (let turn = 0; turn &lt; this.maxTurns; turn++) {
1574
+ // 1. Send message to remote
1575
+ let remoteResponse;
1576
+ try {
1577
+ remoteResponse = await this.client.call(this.endpoint, nextMessage, {
1578
+ conversationId
1579
+ });
1580
+ } <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
1581
+ <span class="cstat-no" title="statement not covered" > logger.error('Remote call failed', {</span>
1582
+ <span class="cstat-no" title="statement not covered" > event: 'driver_remote_call_failed',</span>
1583
+ <span class="cstat-no" title="statement not covered" > error: err,</span>
1584
+ <span class="cstat-no" title="statement not covered" > data: { turn, conversationId }</span>
1585
+ <span class="cstat-no" title="statement not covered" > });</span>
1586
+ <span class="cstat-no" title="statement not covered" > break;</span>
1587
+ <span class="cstat-no" title="statement not covered" > }</span>
1588
+ &nbsp;
1589
+ // Start DB conversation on first turn
1590
+ if (turn === 0 &amp;&amp; this.convStore &amp;&amp; !dbConversationStarted) {
1591
+ // Prefer remote's conversation ID, fall back to generated local one
1592
+ if (remoteResponse.conversation_id) {
1593
+ conversationId = remoteResponse.conversation_id;
1594
+ } else {
1595
+ conversationId = `conv_${Date.now()}_${crypto.randomBytes(4).toString('hex')}`;
1596
+ }
1597
+ &nbsp;
1598
+ const convResult = this.convStore.startConversation({
1599
+ id: conversationId,
1600
+ direction: 'outbound'
1601
+ });
1602
+ if (convResult.success === false) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1603
+ <span class="cstat-no" title="statement not covered" > logger.warn('Failed to start conversation in DB', {</span>
1604
+ <span class="cstat-no" title="statement not covered" > event: 'driver_start_conversation_failed',</span>
1605
+ <span class="cstat-no" title="statement not covered" > error: convResult.error</span>
1606
+ <span class="cstat-no" title="statement not covered" > });</span>
1607
+ } else {
1608
+ dbConversationStarted = true;
1609
+ }
1610
+ }
1611
+ &nbsp;
1612
+ const remoteText = remoteResponse.response <span class="branch-0 cbranch-no" title="branch not covered" >|| '';</span>
1613
+ const remoteContinue = remoteResponse.can_continue !== false;
1614
+ &nbsp;
1615
+ // 2. Store messages in DB (only if conversation was started in DB)
1616
+ if (this.convStore &amp;&amp; dbConversationStarted) {
1617
+ const outMsg = this.convStore.addMessage(conversationId, {
1618
+ direction: 'outbound',
1619
+ role: 'user',
1620
+ content: nextMessage
1621
+ });
1622
+ if (outMsg.success === false) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1623
+ <span class="cstat-no" title="statement not covered" > logger.warn('Failed to save outbound message', {</span>
1624
+ <span class="cstat-no" title="statement not covered" > event: 'driver_save_message_failed',</span>
1625
+ <span class="cstat-no" title="statement not covered" > error: outMsg.error</span>
1626
+ <span class="cstat-no" title="statement not covered" > });</span>
1627
+ <span class="cstat-no" title="statement not covered" > }</span>
1628
+ const inMsg = this.convStore.addMessage(conversationId, {
1629
+ direction: 'inbound',
1630
+ role: 'assistant',
1631
+ content: remoteText
1632
+ });
1633
+ if (inMsg.success === false) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1634
+ <span class="cstat-no" title="statement not covered" > logger.warn('Failed to save inbound message', {</span>
1635
+ <span class="cstat-no" title="statement not covered" > event: 'driver_save_message_failed',</span>
1636
+ <span class="cstat-no" title="statement not covered" > error: inMsg.error</span>
1637
+ <span class="cstat-no" title="statement not covered" > });</span>
1638
+ <span class="cstat-no" title="statement not covered" > }</span>
1639
+ }
1640
+ &nbsp;
1641
+ transcript.push(
1642
+ { role: 'outbound', content: nextMessage },
1643
+ { role: 'inbound', content: remoteText }
1644
+ );
1645
+ &nbsp;
1646
+ collabState.turnCount = turn + 1;
1647
+ &nbsp;
1648
+ // 3. Check close conditions
1649
+ if (!remoteContinue) {
1650
+ logger.info('Remote signaled conversation end', {
1651
+ event: 'driver_remote_close',
1652
+ data: { turn: turn + 1, conversationId }
1653
+ });
1654
+ break;
1655
+ }
1656
+ &nbsp;
1657
+ // 3b. Detect termination intent from remote text even if can_continue is true
1658
+ if (detectRemoteTermination(remoteText)) {
1659
+ logger.info('Remote text indicates termination intent', {
1660
+ event: 'driver_remote_text_close',
1661
+ data: { turn: turn + 1, conversationId, preview: remoteText.slice(0, 80) }
1662
+ });
1663
+ break;
1664
+ }
1665
+ &nbsp;
1666
+ if (collabState.closeSignal &amp;&amp; collabState.turnCount &gt;= this.minTurns) {
1667
+ logger.info('Local close signal met minimum turns', {
1668
+ event: 'driver_local_close',
1669
+ data: { turn: turn + 1, conversationId }
1670
+ });
1671
+ break;
1672
+ }
1673
+ &nbsp;
1674
+ // Don't generate a reply on the last possible turn
1675
+ if (turn + 1 &gt;= this.maxTurns) {
1676
+ break;
1677
+ }
1678
+ &nbsp;
1679
+ // 4. Build prompt for our turn
1680
+ const manifest = this.disclosure || loadManifest();
1681
+ const tierTopics = getTopicsForTier(this.tier);
1682
+ const formattedTopics = formatTopicsForPrompt(tierTopics);
1683
+ &nbsp;
1684
+ const prompt = buildAdaptiveConnectionPrompt({
1685
+ agentName: this.agentContext.name,
1686
+ ownerName: this.agentContext.owner,
1687
+ otherAgentName: this.caller.name <span class="branch-0 cbranch-no" title="branch not covered" >|| 'Remote Agent',</span>
1688
+ otherOwnerName: this.caller.owner || 'their owner',
1689
+ roleContext: 'You initiated this call.',
1690
+ accessTier: this.tier,
1691
+ tierTopics: formattedTopics,
1692
+ tierGoals: [],
1693
+ otherAgentGreeting: remoteText,
1694
+ personalityNotes: manifest.personality_notes || '',
1695
+ conversationState: collabState
1696
+ });
1697
+ &nbsp;
1698
+ // 5. Call runtime.runTurn() to generate next message
1699
+ const sessionId = `a2a-${conversationId}`;
1700
+ let rawResponse;
1701
+ const contextPayload = {
1702
+ conversationId,
1703
+ tier: this.tier,
1704
+ ownerName: this.agentContext.owner,
1705
+ agentName: this.agentContext.name,
1706
+ roleContext: 'You initiated this call.',
1707
+ capabilities: this.capabilities,
1708
+ allowedTopics: this.allowedTopics,
1709
+ allowed_topics: this.allowedTopics,
1710
+ allowedGoals: this.allowedGoals,
1711
+ allowed_goals: this.allowedGoals,
1712
+ allowedTools: this.allowedTools,
1713
+ allowed_tools: this.allowedTools
1714
+ };
1715
+ if (this.claudeMode) {
1716
+ contextPayload.turnCount = turn + 1;
1717
+ contextPayload.maxTurns = this.maxTurns;
1718
+ contextPayload.phase = collabState.phase;
1719
+ contextPayload.overlapScore = collabState.overlapScore;
1720
+ contextPayload.activeThreads = collabState.activeThreads;
1721
+ contextPayload.candidateCollaborations = collabState.candidateCollaborations;
1722
+ contextPayload.closeSignal = collabState.closeSignal;
1723
+ }
1724
+ try {
1725
+ rawResponse = await this.runtime.runTurn({
1726
+ sessionId,
1727
+ prompt,
1728
+ message: remoteText,
1729
+ caller: this.caller,
1730
+ timeoutMs: this.claudeMode ? this.claudeTimeoutMs : 65000,
1731
+ context: contextPayload
1732
+ });
1733
+ } catch (err) {
1734
+ logger.error('Runtime turn failed', {
1735
+ event: 'driver_runtime_failed',
1736
+ error: err,
1737
+ data: { turn: turn + 1, conversationId }
1738
+ });
1739
+ break;
1740
+ }
1741
+ &nbsp;
1742
+ // 6. Extract collab state from response
1743
+ // In claude mode, use the side channel (getLastTurnMeta) for state/flags
1744
+ const turnMeta = this.claudeMode ? this.runtime.getLastTurnMeta?.(sessionId) : null;
1745
+ &nbsp;
1746
+ if (turnMeta?.statePatch) {
1747
+ // Claude subagent returned structured state — apply it directly
1748
+ nextMessage = rawResponse;
1749
+ const sp = turnMeta.statePatch;
1750
+ if (sp.phase) collabState.phase = sp.phase;
1751
+ if (sp.overlapScore != null) {
1752
+ collabState.overlapScore = Math.max(0, Math.min(1, sp.overlapScore));
1753
+ }
1754
+ if (Array.isArray(sp.activeThreads)) {
1755
+ collabState.activeThreads = sp.activeThreads.slice(0, 4);
1756
+ }
1757
+ if (Array.isArray(sp.candidateCollaborations)) {
1758
+ collabState.candidateCollaborations = sp.candidateCollaborations.slice(0, 4);
1759
+ }
1760
+ if (sp.closeSignal != null) {
1761
+ collabState.closeSignal = Boolean(sp.closeSignal);
1762
+ }
1763
+ if (sp.confidence != null) {
1764
+ collabState.confidence = Math.max(0, Math.min(1, sp.confidence));
1765
+ }
1766
+ } else {
1767
+ // Non-claude path: extract from &lt;collab_state&gt; tags in response text
1768
+ const parsed = extractCollaborationState(rawResponse);
1769
+ nextMessage = parsed.cleanText <span class="branch-0 cbranch-no" title="branch not covered" >|| rawResponse;</span>
1770
+ &nbsp;
1771
+ if (parsed.hasState <span class="branch-0 cbranch-no" title="branch not covered" >&amp;&amp; parsed.statePatch)</span> <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1772
+ <span class="cstat-no" title="statement not covered" > if (parsed.statePatch.phase) collabState.phase = parsed.statePatch.phase;</span>
1773
+ <span class="cstat-no" title="statement not covered" > if (parsed.statePatch.overlapScore != null) {</span>
1774
+ <span class="cstat-no" title="statement not covered" > collabState.overlapScore = Math.max(0, Math.min(1, parsed.statePatch.overlapScore));</span>
1775
+ <span class="cstat-no" title="statement not covered" > }</span>
1776
+ <span class="cstat-no" title="statement not covered" > if (Array.isArray(parsed.statePatch.activeThreads)) {</span>
1777
+ <span class="cstat-no" title="statement not covered" > collabState.activeThreads = parsed.statePatch.activeThreads.slice(0, 4);</span>
1778
+ <span class="cstat-no" title="statement not covered" > }</span>
1779
+ <span class="cstat-no" title="statement not covered" > if (Array.isArray(parsed.statePatch.candidateCollaborations)) {</span>
1780
+ <span class="cstat-no" title="statement not covered" > collabState.candidateCollaborations = parsed.statePatch.candidateCollaborations.slice(0, 4);</span>
1781
+ <span class="cstat-no" title="statement not covered" > }</span>
1782
+ <span class="cstat-no" title="statement not covered" > if (parsed.statePatch.closeSignal != null) {</span>
1783
+ <span class="cstat-no" title="statement not covered" > collabState.closeSignal = Boolean(parsed.statePatch.closeSignal);</span>
1784
+ <span class="cstat-no" title="statement not covered" > }</span>
1785
+ <span class="cstat-no" title="statement not covered" > if (parsed.statePatch.confidence != null) {</span>
1786
+ <span class="cstat-no" title="statement not covered" > collabState.confidence = Math.max(0, Math.min(1, parsed.statePatch.confidence));</span>
1787
+ <span class="cstat-no" title="statement not covered" > }</span>
1788
+ } else {
1789
+ // No &lt;collab_state&gt; in response (generic/fallback runtime) — infer progression
1790
+ const inferred = inferStateProgression(collabState, remoteText, turn + 1);
1791
+ if (inferred.phase) collabState.phase = inferred.phase;
1792
+ if (inferred.overlapScore != null) collabState.overlapScore = inferred.overlapScore;
1793
+ if (inferred.confidence != null) collabState.confidence = inferred.confidence;
1794
+ if (inferred.closeSignal != null) collabState.closeSignal = inferred.closeSignal;
1795
+ }
1796
+ }
1797
+ &nbsp;
1798
+ // 6b. Overlap flatline detection — if overlap hasn't changed significantly
1799
+ // for 3+ consecutive turns while in converging phase, the conversation is dead
1800
+ overlapHistory.push(collabState.overlapScore);
1801
+ if (collabState.phase === 'converging' &amp;&amp; overlapHistory.length &gt;= 3) {
1802
+ const recent = overlapHistory.slice(-3);
1803
+ const maxDelta = Math.max(
1804
+ Math.abs(recent[1] - recent[0]),
1805
+ Math.abs(recent[2] - recent[1])
1806
+ );
1807
+ if (maxDelta &lt; 0.02) {
1808
+ collabState.closeSignal = true;
1809
+ }
1810
+ }
1811
+ &nbsp;
1812
+ // 7. Persist collab state to DB
1813
+ if (this.convStore) {
1814
+ try {
1815
+ this.convStore.saveCollabState(conversationId, collabState);
1816
+ } <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
1817
+ <span class="cstat-no" title="statement not covered" > // Best effort</span>
1818
+ <span class="cstat-no" title="statement not covered" > }</span>
1819
+ }
1820
+ &nbsp;
1821
+ // 7b. Store flags from claude subagent responses
1822
+ if (turnMeta?.flags?.length &gt; 0 &amp;&amp; this.convStore &amp;&amp; dbConversationStarted) {
1823
+ this.convStore.addMessage(conversationId, {
1824
+ direction: 'outbound',
1825
+ role: 'system',
1826
+ content: `[flags] ${turnMeta.flags.map(f =&gt; f.content <span class="branch-0 cbranch-no" title="branch not covered" >|| f.type)</span>.join('; ')}`,
1827
+ metadata: JSON.stringify({ flags: turnMeta.flags, turn: turn + 1 })
1828
+ });
1829
+ }
1830
+ &nbsp;
1831
+ // onTurn callback for progress output
1832
+ if (this.onTurn) {
1833
+ try {
1834
+ this.onTurn({
1835
+ turn: turn + 1,
1836
+ phase: collabState.phase,
1837
+ overlapScore: collabState.overlapScore,
1838
+ closeSignal: collabState.closeSignal,
1839
+ messagePreview: nextMessage.slice(0, 80)
1840
+ });
1841
+ } <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
1842
+ <span class="cstat-no" title="statement not covered" > // Don't let callback errors break the loop</span>
1843
+ <span class="cstat-no" title="statement not covered" > }</span>
1844
+ }
1845
+ }
1846
+ &nbsp;
1847
+ // 9. End conversation remotely
1848
+ try {
1849
+ await this.client.end(this.endpoint, conversationId);
1850
+ } <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
1851
+ <span class="cstat-no" title="statement not covered" > logger.warn('Failed to end remote conversation', {</span>
1852
+ <span class="cstat-no" title="statement not covered" > event: 'driver_end_failed',</span>
1853
+ <span class="cstat-no" title="statement not covered" > error: err,</span>
1854
+ <span class="cstat-no" title="statement not covered" > data: { conversationId }</span>
1855
+ <span class="cstat-no" title="statement not covered" > });</span>
1856
+ <span class="cstat-no" title="statement not covered" > }</span>
1857
+ &nbsp;
1858
+ // Conclude locally with summarizer
1859
+ // Store conversationId so _buildSummarizer can look up collab state
1860
+ this.lastConversationId = conversationId;
1861
+ let summary = null;
1862
+ if (this.convStore) {
1863
+ try {
1864
+ const summarizer = this.summarizer || this._buildSummarizer();
1865
+ const result = await this.convStore.concludeConversation(conversationId, {
1866
+ summarizer,
1867
+ ownerContext: this.ownerContext
1868
+ });
1869
+ summary = result.summary || null;
1870
+ } <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
1871
+ <span class="cstat-no" title="statement not covered" > logger.warn('Failed to conclude local conversation', {</span>
1872
+ <span class="cstat-no" title="statement not covered" > event: 'driver_conclude_failed',</span>
1873
+ <span class="cstat-no" title="statement not covered" > error: err,</span>
1874
+ <span class="cstat-no" title="statement not covered" > data: { conversationId }</span>
1875
+ <span class="cstat-no" title="statement not covered" > });</span>
1876
+ <span class="cstat-no" title="statement not covered" > }</span>
1877
+ }
1878
+ &nbsp;
1879
+ return {
1880
+ conversationId,
1881
+ turnCount: collabState.turnCount,
1882
+ collabState,
1883
+ transcript,
1884
+ summary
1885
+ };
1886
+ }
1887
+ }
1888
+ &nbsp;
1889
+ module.exports = { ConversationDriver, detectRemoteTermination, inferStateProgression };
1890
+ &nbsp;</pre></td></tr></table></pre>
1891
+
1892
+ <div class='push'></div><!-- for sticky footer -->
1893
+ </div><!-- /wrapper -->
1894
+ <div class='footer quiet pad2 space-top1 center small'>
1895
+ Code coverage generated by
1896
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1897
+ at 2026-03-03T22:25:10.857Z
1898
+ </div>
1899
+ <script src="../../prettify.js"></script>
1900
+ <script>
1901
+ window.onload = function () {
1902
+ prettyPrint();
1903
+ };
1904
+ </script>
1905
+ <script src="../../sorter.js"></script>
1906
+ <script src="../../block-navigation.js"></script>
1907
+ </body>
1908
+ </html>
1909
+