a2acalling 0.6.74 → 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 (118) 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 +11 -0
  6. package/CONVENTIONS.md +9 -0
  7. package/coverage/base.css +224 -0
  8. package/coverage/block-navigation.js +87 -0
  9. package/coverage/favicon.png +0 -0
  10. package/coverage/index.html +146 -0
  11. package/coverage/prettify.css +1 -0
  12. package/coverage/prettify.js +2 -0
  13. package/coverage/sort-arrow-sprite.png +0 -0
  14. package/coverage/sorter.js +210 -0
  15. package/coverage/src/index.html +131 -0
  16. package/coverage/src/index.js.html +313 -0
  17. package/coverage/src/lib/agent-card.js.html +418 -0
  18. package/coverage/src/lib/call-monitor.js.html +700 -0
  19. package/coverage/src/lib/callbook.js.html +1183 -0
  20. package/coverage/src/lib/claude-subagent.js.html +2173 -0
  21. package/coverage/src/lib/client.js.html +2134 -0
  22. package/coverage/src/lib/config.js.html +1525 -0
  23. package/coverage/src/lib/conversation-driver.js.html +1909 -0
  24. package/coverage/src/lib/conversations.js.html +2575 -0
  25. package/coverage/src/lib/crypto.js.html +424 -0
  26. package/coverage/src/lib/dashboard-events.js.html +724 -0
  27. package/coverage/src/lib/disclosure.js.html +2461 -0
  28. package/coverage/src/lib/external-ip.js.html +718 -0
  29. package/coverage/src/lib/index.html +506 -0
  30. package/coverage/src/lib/invite-host.js.html +754 -0
  31. package/coverage/src/lib/local-request.js.html +292 -0
  32. package/coverage/src/lib/logger.js.html +2116 -0
  33. package/coverage/src/lib/openclaw-integration.js.html +1102 -0
  34. package/coverage/src/lib/pid-file.js.html +394 -0
  35. package/coverage/src/lib/port-scanner.js.html +334 -0
  36. package/coverage/src/lib/prompt-template.js.html +1150 -0
  37. package/coverage/src/lib/runtime-adapter.js.html +2188 -0
  38. package/coverage/src/lib/summarizer.js.html +553 -0
  39. package/coverage/src/lib/summary-formatter.js.html +589 -0
  40. package/coverage/src/lib/summary-prompt.js.html +694 -0
  41. package/coverage/src/lib/tokens.js.html +2689 -0
  42. package/coverage/src/lib/turn-timeout.js.html +241 -0
  43. package/coverage/src/lib/update-checker.js.html +364 -0
  44. package/coverage/src/lib/update-manager.js.html +1024 -0
  45. package/coverage/src/routes/a2a.js.html +3724 -0
  46. package/coverage/src/routes/callbook.js.html +511 -0
  47. package/coverage/src/routes/dashboard.js.html +4819 -0
  48. package/coverage/src/routes/index.html +146 -0
  49. package/coverage/src/server.js.html +3622 -0
  50. package/coverage/tmp/coverage-1605378-1772576706365-0.json +1 -0
  51. package/coverage/tmp/coverage-1605384-1772576607459-0.json +1 -0
  52. package/coverage/tmp/coverage-1605410-1772576631155-0.json +1 -0
  53. package/coverage/tmp/coverage-1606942-1772576636869-0.json +1 -0
  54. package/coverage/tmp/coverage-1607004-1772576637454-0.json +1 -0
  55. package/coverage/tmp/coverage-1607044-1772576637876-0.json +1 -0
  56. package/coverage/tmp/coverage-1607096-1772576638356-0.json +1 -0
  57. package/coverage/tmp/coverage-1607145-1772576638777-0.json +1 -0
  58. package/coverage/tmp/coverage-1607201-1772576639277-0.json +1 -0
  59. package/coverage/tmp/coverage-1607247-1772576639755-0.json +1 -0
  60. package/coverage/tmp/coverage-1607317-1772576640083-0.json +1 -0
  61. package/coverage/tmp/coverage-1607381-1772576640465-0.json +1 -0
  62. package/coverage/tmp/coverage-1607446-1772576640868-0.json +1 -0
  63. package/coverage/tmp/coverage-1607501-1772576641662-0.json +1 -0
  64. package/coverage/tmp/coverage-1607534-1772576641565-0.json +1 -0
  65. package/coverage/tmp/coverage-1607627-1772576641871-0.json +1 -0
  66. package/coverage/tmp/coverage-1607665-1772576642172-0.json +1 -0
  67. package/coverage/tmp/coverage-1607714-1772576642577-0.json +1 -0
  68. package/coverage/tmp/coverage-1607788-1772576643466-0.json +1 -0
  69. package/coverage/tmp/coverage-1607924-1772576644678-0.json +1 -0
  70. package/coverage/tmp/coverage-1607978-1772576645154-0.json +1 -0
  71. package/coverage/tmp/coverage-1608035-1772576645564-0.json +1 -0
  72. package/coverage/tmp/coverage-1608106-1772576645967-0.json +1 -0
  73. package/coverage/tmp/coverage-1608179-1772576648656-0.json +1 -0
  74. package/coverage/tmp/coverage-1608196-1772576647367-0.json +1 -0
  75. package/coverage/tmp/coverage-1608217-1772576648557-0.json +1 -0
  76. package/coverage/tmp/coverage-1608256-1772576651378-0.json +1 -0
  77. package/coverage/tmp/coverage-1608265-1772576650058-0.json +1 -0
  78. package/coverage/tmp/coverage-1608289-1772576651358-0.json +1 -0
  79. package/coverage/tmp/coverage-1608591-1772576660465-0.json +1 -0
  80. package/coverage/tmp/coverage-1608648-1772576659272-0.json +1 -0
  81. package/coverage/tmp/coverage-1608665-1772576660374-0.json +1 -0
  82. package/coverage/tmp/coverage-1608677-1772576661268-0.json +1 -0
  83. package/coverage/tmp/coverage-1608684-1772576663968-0.json +1 -0
  84. package/coverage/tmp/coverage-1608692-1772576662575-0.json +1 -0
  85. package/coverage/tmp/coverage-1608701-1772576663873-0.json +1 -0
  86. package/coverage/tmp/coverage-1608718-1772576666674-0.json +1 -0
  87. package/coverage/tmp/coverage-1608725-1772576665463-0.json +1 -0
  88. package/coverage/tmp/coverage-1608738-1772576666577-0.json +1 -0
  89. package/coverage/tmp/coverage-1608753-1772576669664-0.json +1 -0
  90. package/coverage/tmp/coverage-1608763-1772576668275-0.json +1 -0
  91. package/coverage/tmp/coverage-1608771-1772576669563-0.json +1 -0
  92. package/coverage/tmp/coverage-1608828-1772576676574-0.json +1 -0
  93. package/coverage/tmp/coverage-1609244-1772576675272-0.json +1 -0
  94. package/coverage/tmp/coverage-1609342-1772576676478-0.json +1 -0
  95. package/coverage/tmp/coverage-1609450-1772576686954-0.json +1 -0
  96. package/coverage/tmp/coverage-1609841-1772576685466-0.json +1 -0
  97. package/coverage/tmp/coverage-1609925-1772576686855-0.json +1 -0
  98. package/coverage/tmp/coverage-1610399-1772576692469-0.json +1 -0
  99. package/coverage/tmp/coverage-1611283-1772576703062-0.json +1 -0
  100. package/coverage/tmp/coverage-1611294-1772576703755-0.json +1 -0
  101. package/docs/plans/2026-03-03-a2a-91-macos-packaging-plan.md +144 -0
  102. package/docs/signing-setup.md +49 -0
  103. package/native/macos/certs/appldevcert.cer +0 -0
  104. package/native/macos/src-tauri/binaries/.gitkeep +0 -0
  105. package/native/macos/src-tauri/capabilities/default.json +11 -1
  106. package/native/macos/src-tauri/entitlements.plist +14 -0
  107. package/native/macos/src-tauri/src/discovery.rs +14 -3
  108. package/native/macos/src-tauri/src/health.rs +4 -0
  109. package/native/macos/src-tauri/src/lib.rs +52 -11
  110. package/native/macos/src-tauri/src/server.rs +262 -26
  111. package/native/macos/src-tauri/tauri.conf.json +13 -4
  112. package/package.json +7 -2
  113. package/pkg.config.json +14 -0
  114. package/scripts/build-standalone.sh +106 -0
  115. package/scripts/smoke-test-standalone.sh +101 -0
  116. package/scripts/sync-version.sh +28 -0
  117. package/scripts/verify-app-bundle.sh +34 -0
  118. package/.maestro/inbox/release-workflow-spam.md +0 -25
@@ -0,0 +1,1024 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/lib/update-manager.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> update-manager.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">55.91% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>175/313</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">54.71% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>29/53</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">64.7% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>11/17</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">55.91% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>175/313</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></td><td class="line-coverage quiet"><span class="cline-any cline-yes">4x</span>
380
+ <span class="cline-any cline-yes">4x</span>
381
+ <span class="cline-any cline-yes">4x</span>
382
+ <span class="cline-any cline-yes">4x</span>
383
+ <span class="cline-any cline-yes">4x</span>
384
+ <span class="cline-any cline-yes">4x</span>
385
+ <span class="cline-any cline-yes">4x</span>
386
+ <span class="cline-any cline-yes">4x</span>
387
+ <span class="cline-any cline-yes">4x</span>
388
+ <span class="cline-any cline-yes">4x</span>
389
+ <span class="cline-any cline-yes">3x</span>
390
+ <span class="cline-any cline-yes">4x</span>
391
+ <span class="cline-any cline-yes">4x</span>
392
+ <span class="cline-any cline-yes">4x</span>
393
+ <span class="cline-any cline-yes">4x</span>
394
+ <span class="cline-any cline-yes">4x</span>
395
+ <span class="cline-any cline-yes">3x</span>
396
+ <span class="cline-any cline-yes">4x</span>
397
+ <span class="cline-any cline-yes">4x</span>
398
+ <span class="cline-any cline-yes">2x</span>
399
+ <span class="cline-any cline-yes">2x</span>
400
+ <span class="cline-any cline-yes">2x</span>
401
+ <span class="cline-any cline-yes">2x</span>
402
+ <span class="cline-any cline-yes">2x</span>
403
+ <span class="cline-any cline-yes">2x</span>
404
+ <span class="cline-any cline-yes">4x</span>
405
+ <span class="cline-any cline-no">&nbsp;</span>
406
+ <span class="cline-any cline-no">&nbsp;</span>
407
+ <span class="cline-any cline-no">&nbsp;</span>
408
+ <span class="cline-any cline-no">&nbsp;</span>
409
+ <span class="cline-any cline-no">&nbsp;</span>
410
+ <span class="cline-any cline-no">&nbsp;</span>
411
+ <span class="cline-any cline-no">&nbsp;</span>
412
+ <span class="cline-any cline-no">&nbsp;</span>
413
+ <span class="cline-any cline-no">&nbsp;</span>
414
+ <span class="cline-any cline-no">&nbsp;</span>
415
+ <span class="cline-any cline-no">&nbsp;</span>
416
+ <span class="cline-any cline-no">&nbsp;</span>
417
+ <span class="cline-any cline-no">&nbsp;</span>
418
+ <span class="cline-any cline-yes">4x</span>
419
+ <span class="cline-any cline-yes">4x</span>
420
+ <span class="cline-any cline-yes">4x</span>
421
+ <span class="cline-any cline-yes">2x</span>
422
+ <span class="cline-any cline-yes">2x</span>
423
+ <span class="cline-any cline-yes">2x</span>
424
+ <span class="cline-any cline-yes">2x</span>
425
+ <span class="cline-any cline-yes">2x</span>
426
+ <span class="cline-any cline-yes">2x</span>
427
+ <span class="cline-any cline-yes">2x</span>
428
+ <span class="cline-any cline-yes">2x</span>
429
+ <span class="cline-any cline-yes">2x</span>
430
+ <span class="cline-any cline-yes">2x</span>
431
+ <span class="cline-any cline-yes">2x</span>
432
+ <span class="cline-any cline-yes">2x</span>
433
+ <span class="cline-any cline-yes">2x</span>
434
+ <span class="cline-any cline-yes">2x</span>
435
+ <span class="cline-any cline-yes">2x</span>
436
+ <span class="cline-any cline-yes">2x</span>
437
+ <span class="cline-any cline-yes">2x</span>
438
+ <span class="cline-any cline-yes">2x</span>
439
+ <span class="cline-any cline-yes">2x</span>
440
+ <span class="cline-any cline-yes">2x</span>
441
+ <span class="cline-any cline-yes">2x</span>
442
+ <span class="cline-any cline-yes">2x</span>
443
+ <span class="cline-any cline-yes">2x</span>
444
+ <span class="cline-any cline-yes">2x</span>
445
+ <span class="cline-any cline-yes">2x</span>
446
+ <span class="cline-any cline-yes">2x</span>
447
+ <span class="cline-any cline-yes">2x</span>
448
+ <span class="cline-any cline-yes">2x</span>
449
+ <span class="cline-any cline-yes">2x</span>
450
+ <span class="cline-any cline-yes">2x</span>
451
+ <span class="cline-any cline-yes">2x</span>
452
+ <span class="cline-any cline-yes">2x</span>
453
+ <span class="cline-any cline-yes">2x</span>
454
+ <span class="cline-any cline-yes">2x</span>
455
+ <span class="cline-any cline-yes">2x</span>
456
+ <span class="cline-any cline-no">&nbsp;</span>
457
+ <span class="cline-any cline-no">&nbsp;</span>
458
+ <span class="cline-any cline-no">&nbsp;</span>
459
+ <span class="cline-any cline-no">&nbsp;</span>
460
+ <span class="cline-any cline-yes">2x</span>
461
+ <span class="cline-any cline-yes">4x</span>
462
+ <span class="cline-any cline-yes">4x</span>
463
+ <span class="cline-any cline-yes">2x</span>
464
+ <span class="cline-any cline-yes">1x</span>
465
+ <span class="cline-any cline-yes">2x</span>
466
+ <span class="cline-any cline-yes">1x</span>
467
+ <span class="cline-any cline-yes">1x</span>
468
+ <span class="cline-any cline-yes">1x</span>
469
+ <span class="cline-any cline-yes">1x</span>
470
+ <span class="cline-any cline-yes">1x</span>
471
+ <span class="cline-any cline-yes">2x</span>
472
+ <span class="cline-any cline-yes">4x</span>
473
+ <span class="cline-any cline-yes">4x</span>
474
+ <span class="cline-any cline-no">&nbsp;</span>
475
+ <span class="cline-any cline-no">&nbsp;</span>
476
+ <span class="cline-any cline-no">&nbsp;</span>
477
+ <span class="cline-any cline-no">&nbsp;</span>
478
+ <span class="cline-any cline-no">&nbsp;</span>
479
+ <span class="cline-any cline-no">&nbsp;</span>
480
+ <span class="cline-any cline-no">&nbsp;</span>
481
+ <span class="cline-any cline-no">&nbsp;</span>
482
+ <span class="cline-any cline-no">&nbsp;</span>
483
+ <span class="cline-any cline-no">&nbsp;</span>
484
+ <span class="cline-any cline-yes">4x</span>
485
+ <span class="cline-any cline-yes">4x</span>
486
+ <span class="cline-any cline-yes">3x</span>
487
+ <span class="cline-any cline-yes">3x</span>
488
+ <span class="cline-any cline-yes">3x</span>
489
+ <span class="cline-any cline-yes">4x</span>
490
+ <span class="cline-any cline-yes">4x</span>
491
+ <span class="cline-any cline-yes">5x</span>
492
+ <span class="cline-any cline-yes">5x</span>
493
+ <span class="cline-any cline-yes">5x</span>
494
+ <span class="cline-any cline-yes">5x</span>
495
+ <span class="cline-any cline-yes">5x</span>
496
+ <span class="cline-any cline-yes">5x</span>
497
+ <span class="cline-any cline-yes">5x</span>
498
+ <span class="cline-any cline-yes">4x</span>
499
+ <span class="cline-any cline-yes">4x</span>
500
+ <span class="cline-any cline-no">&nbsp;</span>
501
+ <span class="cline-any cline-no">&nbsp;</span>
502
+ <span class="cline-any cline-no">&nbsp;</span>
503
+ <span class="cline-any cline-no">&nbsp;</span>
504
+ <span class="cline-any cline-no">&nbsp;</span>
505
+ <span class="cline-any cline-no">&nbsp;</span>
506
+ <span class="cline-any cline-no">&nbsp;</span>
507
+ <span class="cline-any cline-no">&nbsp;</span>
508
+ <span class="cline-any cline-no">&nbsp;</span>
509
+ <span class="cline-any cline-no">&nbsp;</span>
510
+ <span class="cline-any cline-no">&nbsp;</span>
511
+ <span class="cline-any cline-no">&nbsp;</span>
512
+ <span class="cline-any cline-yes">4x</span>
513
+ <span class="cline-any cline-yes">4x</span>
514
+ <span class="cline-any cline-yes">1x</span>
515
+ <span class="cline-any cline-yes">1x</span>
516
+ <span class="cline-any cline-no">&nbsp;</span>
517
+ <span class="cline-any cline-no">&nbsp;</span>
518
+ <span class="cline-any cline-no">&nbsp;</span>
519
+ <span class="cline-any cline-yes">1x</span>
520
+ <span class="cline-any cline-yes">1x</span>
521
+ <span class="cline-any cline-no">&nbsp;</span>
522
+ <span class="cline-any cline-no">&nbsp;</span>
523
+ <span class="cline-any cline-no">&nbsp;</span>
524
+ <span class="cline-any cline-no">&nbsp;</span>
525
+ <span class="cline-any cline-no">&nbsp;</span>
526
+ <span class="cline-any cline-no">&nbsp;</span>
527
+ <span class="cline-any cline-yes">1x</span>
528
+ <span class="cline-any cline-yes">1x</span>
529
+ <span class="cline-any cline-yes">1x</span>
530
+ <span class="cline-any cline-yes">1x</span>
531
+ <span class="cline-any cline-yes">1x</span>
532
+ <span class="cline-any cline-yes">1x</span>
533
+ <span class="cline-any cline-yes">1x</span>
534
+ <span class="cline-any cline-yes">1x</span>
535
+ <span class="cline-any cline-yes">1x</span>
536
+ <span class="cline-any cline-yes">1x</span>
537
+ <span class="cline-any cline-yes">4x</span>
538
+ <span class="cline-any cline-yes">4x</span>
539
+ <span class="cline-any cline-yes">2x</span>
540
+ <span class="cline-any cline-yes">1x</span>
541
+ <span class="cline-any cline-yes">1x</span>
542
+ <span class="cline-any cline-yes">1x</span>
543
+ <span class="cline-any cline-yes">2x</span>
544
+ <span class="cline-any cline-yes">4x</span>
545
+ <span class="cline-any cline-yes">4x</span>
546
+ <span class="cline-any cline-yes">2x</span>
547
+ <span class="cline-any cline-yes">2x</span>
548
+ <span class="cline-any cline-yes">4x</span>
549
+ <span class="cline-any cline-yes">4x</span>
550
+ <span class="cline-any cline-no">&nbsp;</span>
551
+ <span class="cline-any cline-no">&nbsp;</span>
552
+ <span class="cline-any cline-no">&nbsp;</span>
553
+ <span class="cline-any cline-yes">4x</span>
554
+ <span class="cline-any cline-yes">4x</span>
555
+ <span class="cline-any cline-yes">2x</span>
556
+ <span class="cline-any cline-no">&nbsp;</span>
557
+ <span class="cline-any cline-no">&nbsp;</span>
558
+ <span class="cline-any cline-yes">2x</span>
559
+ <span class="cline-any cline-no">&nbsp;</span>
560
+ <span class="cline-any cline-no">&nbsp;</span>
561
+ <span class="cline-any cline-yes">2x</span>
562
+ <span class="cline-any cline-yes">2x</span>
563
+ <span class="cline-any cline-yes">2x</span>
564
+ <span class="cline-any cline-yes">2x</span>
565
+ <span class="cline-any cline-yes">2x</span>
566
+ <span class="cline-any cline-yes">2x</span>
567
+ <span class="cline-any cline-yes">2x</span>
568
+ <span class="cline-any cline-yes">2x</span>
569
+ <span class="cline-any cline-yes">2x</span>
570
+ <span class="cline-any cline-yes">2x</span>
571
+ <span class="cline-any cline-yes">2x</span>
572
+ <span class="cline-any cline-yes">2x</span>
573
+ <span class="cline-any cline-yes">1x</span>
574
+ <span class="cline-any cline-no">&nbsp;</span>
575
+ <span class="cline-any cline-no">&nbsp;</span>
576
+ <span class="cline-any cline-no">&nbsp;</span>
577
+ <span class="cline-any cline-no">&nbsp;</span>
578
+ <span class="cline-any cline-no">&nbsp;</span>
579
+ <span class="cline-any cline-no">&nbsp;</span>
580
+ <span class="cline-any cline-no">&nbsp;</span>
581
+ <span class="cline-any cline-yes">1x</span>
582
+ <span class="cline-any cline-yes">2x</span>
583
+ <span class="cline-any cline-yes">2x</span>
584
+ <span class="cline-any cline-no">&nbsp;</span>
585
+ <span class="cline-any cline-no">&nbsp;</span>
586
+ <span class="cline-any cline-no">&nbsp;</span>
587
+ <span class="cline-any cline-no">&nbsp;</span>
588
+ <span class="cline-any cline-no">&nbsp;</span>
589
+ <span class="cline-any cline-no">&nbsp;</span>
590
+ <span class="cline-any cline-no">&nbsp;</span>
591
+ <span class="cline-any cline-yes">1x</span>
592
+ <span class="cline-any cline-yes">1x</span>
593
+ <span class="cline-any cline-no">&nbsp;</span>
594
+ <span class="cline-any cline-no">&nbsp;</span>
595
+ <span class="cline-any cline-no">&nbsp;</span>
596
+ <span class="cline-any cline-no">&nbsp;</span>
597
+ <span class="cline-any cline-no">&nbsp;</span>
598
+ <span class="cline-any cline-no">&nbsp;</span>
599
+ <span class="cline-any cline-no">&nbsp;</span>
600
+ <span class="cline-any cline-no">&nbsp;</span>
601
+ <span class="cline-any cline-yes">1x</span>
602
+ <span class="cline-any cline-yes">1x</span>
603
+ <span class="cline-any cline-yes">1x</span>
604
+ <span class="cline-any cline-yes">2x</span>
605
+ <span class="cline-any cline-yes">2x</span>
606
+ <span class="cline-any cline-yes">2x</span>
607
+ <span class="cline-any cline-yes">1x</span>
608
+ <span class="cline-any cline-yes">1x</span>
609
+ <span class="cline-any cline-yes">1x</span>
610
+ <span class="cline-any cline-yes">1x</span>
611
+ <span class="cline-any cline-yes">1x</span>
612
+ <span class="cline-any cline-yes">1x</span>
613
+ <span class="cline-any cline-yes">1x</span>
614
+ <span class="cline-any cline-yes">1x</span>
615
+ <span class="cline-any cline-yes">1x</span>
616
+ <span class="cline-any cline-no">&nbsp;</span>
617
+ <span class="cline-any cline-no">&nbsp;</span>
618
+ <span class="cline-any cline-no">&nbsp;</span>
619
+ <span class="cline-any cline-no">&nbsp;</span>
620
+ <span class="cline-any cline-no">&nbsp;</span>
621
+ <span class="cline-any cline-no">&nbsp;</span>
622
+ <span class="cline-any cline-no">&nbsp;</span>
623
+ <span class="cline-any cline-no">&nbsp;</span>
624
+ <span class="cline-any cline-no">&nbsp;</span>
625
+ <span class="cline-any cline-no">&nbsp;</span>
626
+ <span class="cline-any cline-no">&nbsp;</span>
627
+ <span class="cline-any cline-no">&nbsp;</span>
628
+ <span class="cline-any cline-no">&nbsp;</span>
629
+ <span class="cline-any cline-no">&nbsp;</span>
630
+ <span class="cline-any cline-no">&nbsp;</span>
631
+ <span class="cline-any cline-no">&nbsp;</span>
632
+ <span class="cline-any cline-no">&nbsp;</span>
633
+ <span class="cline-any cline-no">&nbsp;</span>
634
+ <span class="cline-any cline-no">&nbsp;</span>
635
+ <span class="cline-any cline-no">&nbsp;</span>
636
+ <span class="cline-any cline-no">&nbsp;</span>
637
+ <span class="cline-any cline-no">&nbsp;</span>
638
+ <span class="cline-any cline-no">&nbsp;</span>
639
+ <span class="cline-any cline-no">&nbsp;</span>
640
+ <span class="cline-any cline-no">&nbsp;</span>
641
+ <span class="cline-any cline-no">&nbsp;</span>
642
+ <span class="cline-any cline-no">&nbsp;</span>
643
+ <span class="cline-any cline-no">&nbsp;</span>
644
+ <span class="cline-any cline-no">&nbsp;</span>
645
+ <span class="cline-any cline-no">&nbsp;</span>
646
+ <span class="cline-any cline-no">&nbsp;</span>
647
+ <span class="cline-any cline-no">&nbsp;</span>
648
+ <span class="cline-any cline-no">&nbsp;</span>
649
+ <span class="cline-any cline-no">&nbsp;</span>
650
+ <span class="cline-any cline-no">&nbsp;</span>
651
+ <span class="cline-any cline-no">&nbsp;</span>
652
+ <span class="cline-any cline-no">&nbsp;</span>
653
+ <span class="cline-any cline-no">&nbsp;</span>
654
+ <span class="cline-any cline-no">&nbsp;</span>
655
+ <span class="cline-any cline-no">&nbsp;</span>
656
+ <span class="cline-any cline-no">&nbsp;</span>
657
+ <span class="cline-any cline-no">&nbsp;</span>
658
+ <span class="cline-any cline-no">&nbsp;</span>
659
+ <span class="cline-any cline-no">&nbsp;</span>
660
+ <span class="cline-any cline-no">&nbsp;</span>
661
+ <span class="cline-any cline-no">&nbsp;</span>
662
+ <span class="cline-any cline-yes">1x</span>
663
+ <span class="cline-any cline-yes">1x</span>
664
+ <span class="cline-any cline-yes">1x</span>
665
+ <span class="cline-any cline-yes">1x</span>
666
+ <span class="cline-any cline-yes">2x</span>
667
+ <span class="cline-any cline-yes">4x</span>
668
+ <span class="cline-any cline-yes">4x</span>
669
+ <span class="cline-any cline-no">&nbsp;</span>
670
+ <span class="cline-any cline-no">&nbsp;</span>
671
+ <span class="cline-any cline-no">&nbsp;</span>
672
+ <span class="cline-any cline-no">&nbsp;</span>
673
+ <span class="cline-any cline-no">&nbsp;</span>
674
+ <span class="cline-any cline-no">&nbsp;</span>
675
+ <span class="cline-any cline-no">&nbsp;</span>
676
+ <span class="cline-any cline-no">&nbsp;</span>
677
+ <span class="cline-any cline-no">&nbsp;</span>
678
+ <span class="cline-any cline-no">&nbsp;</span>
679
+ <span class="cline-any cline-no">&nbsp;</span>
680
+ <span class="cline-any cline-no">&nbsp;</span>
681
+ <span class="cline-any cline-no">&nbsp;</span>
682
+ <span class="cline-any cline-no">&nbsp;</span>
683
+ <span class="cline-any cline-no">&nbsp;</span>
684
+ <span class="cline-any cline-yes">4x</span>
685
+ <span class="cline-any cline-yes">4x</span>
686
+ <span class="cline-any cline-yes">4x</span>
687
+ <span class="cline-any cline-yes">4x</span>
688
+ <span class="cline-any cline-yes">4x</span>
689
+ <span class="cline-any cline-yes">4x</span>
690
+ <span class="cline-any cline-yes">4x</span>
691
+ <span class="cline-any cline-yes">4x</span>
692
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const { execFile } = require('child_process');
693
+ const { EventEmitter } = require('events');
694
+ const { createLogger } = require('./logger');
695
+ const { checkForUpdate, isSameMajor } = require('./update-checker');
696
+ &nbsp;
697
+ const DEFAULT_INTERVAL_MS = 60 * 60 * 1000;
698
+ const DEFAULT_NPM_TIMEOUT_MS = 2 * 60 * 1000;
699
+ &nbsp;
700
+ function isUpdateSafe(callMonitor) {
701
+ if (!callMonitor || typeof callMonitor.getActiveCount !== 'function') return true;
702
+ return Number(callMonitor.getActiveCount()) === 0;
703
+ }
704
+ &nbsp;
705
+ function shouldApplyUpdate(currentVersion, latestVersion, options = {}) {
706
+ if (!latestVersion) <span class="branch-0 cbranch-no" title="branch not covered" >return false;</span>
707
+ if (options.allowMajor) return true;
708
+ return isSameMajor(currentVersion, latestVersion);
709
+ }
710
+ &nbsp;
711
+ function autoUpdateDisabledByEnv() {
712
+ if (String(process.env.CI || '').toLowerCase() === 'true') <span class="branch-0 cbranch-no" title="branch not covered" >return true;</span>
713
+ if (String(process.env.A2A_AUTO_UPDATE || '').trim() === '0') <span class="branch-0 cbranch-no" title="branch not covered" >return true;</span>
714
+ if (String(process.env.NO_AUTO_UPDATE || '').trim() === '1') <span class="branch-0 cbranch-no" title="branch not covered" >return true;</span>
715
+ return false;
716
+ }
717
+ &nbsp;
718
+ <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >function execFilePromise(cmd, args, options = {}) {</span></span>
719
+ <span class="cstat-no" title="statement not covered" > return new Promise((resolve, reject) =&gt; {</span>
720
+ <span class="cstat-no" title="statement not covered" > execFile(cmd, args, options, (err, stdout, stderr) =&gt; {</span>
721
+ <span class="cstat-no" title="statement not covered" > if (err) {</span>
722
+ <span class="cstat-no" title="statement not covered" > err.stdout = stdout;</span>
723
+ <span class="cstat-no" title="statement not covered" > err.stderr = stderr;</span>
724
+ <span class="cstat-no" title="statement not covered" > reject(err);</span>
725
+ <span class="cstat-no" title="statement not covered" > return;</span>
726
+ <span class="cstat-no" title="statement not covered" > }</span>
727
+ <span class="cstat-no" title="statement not covered" > resolve({ stdout, stderr });</span>
728
+ <span class="cstat-no" title="statement not covered" > });</span>
729
+ <span class="cstat-no" title="statement not covered" > });</span>
730
+ <span class="cstat-no" title="statement not covered" >}</span>
731
+ &nbsp;
732
+ class UpdateManager extends EventEmitter {
733
+ constructor(options = {}) {
734
+ super();
735
+ this.currentVersion = options.currentVersion;
736
+ this.config = options.config || null;
737
+ this.logger = options.logger || createLogger({ component: 'a2a.updater' });
738
+ this.intervalMs = Number.isFinite(options.intervalMs) <span class="branch-0 cbranch-no" title="branch not covered" >&amp;&amp; options.intervalMs &gt; 0</span>
739
+ <span class="branch-0 cbranch-no" title="branch not covered" > ? options.intervalMs</span>
740
+ : DEFAULT_INTERVAL_MS;
741
+ this.allowMajor = Boolean(options.allowMajor);
742
+ this.enabled = options.enabled !== false;
743
+ this.getCallMonitor = typeof options.getCallMonitor === 'function'
744
+ ? options.getCallMonitor
745
+ <span class="branch-0 cbranch-no" title="branch not covered" > : (<span class="fstat-no" title="function not covered" >() =&gt; null)</span>;</span>
746
+ this.installTimeoutMs = Number.isFinite(options.installTimeoutMs) <span class="branch-0 cbranch-no" title="branch not covered" >&amp;&amp; options.installTimeoutMs &gt; 0</span>
747
+ <span class="branch-0 cbranch-no" title="branch not covered" > ? options.installTimeoutMs</span>
748
+ : DEFAULT_NPM_TIMEOUT_MS;
749
+ this.restartFn = typeof options.restartFn === 'function' ? options.restartFn <span class="branch-0 cbranch-no" title="branch not covered" >: null;</span>
750
+ this._execFile = options.execFile || execFilePromise;
751
+ this._status = {
752
+ state: 'up_to_date',
753
+ enabled: this.enabled,
754
+ current_version: this.currentVersion,
755
+ latest_version: this.currentVersion,
756
+ target_version: null,
757
+ active_calls: 0,
758
+ last_checked_at: null,
759
+ last_success_at: null,
760
+ last_error: null,
761
+ defer_reason: null
762
+ };
763
+ this._timer = null;
764
+ this._running = false;
765
+ this._pendingManualUpdate = false;
766
+ &nbsp;
767
+ this._loadConfig();
768
+ if (autoUpdateDisabledByEnv()) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
769
+ <span class="cstat-no" title="statement not covered" > this.enabled = false;</span>
770
+ <span class="cstat-no" title="statement not covered" > this._status.enabled = false;</span>
771
+ <span class="cstat-no" title="statement not covered" > this.logger.info('Auto-update disabled by environment', { event: 'updater_env_disabled' });</span>
772
+ <span class="cstat-no" title="statement not covered" > }</span>
773
+ }
774
+ &nbsp;
775
+ _loadConfig() {
776
+ if (!this.config || typeof this.config.getAutoUpdate !== 'function') return;
777
+ const cfg = this.config.getAutoUpdate();
778
+ if (cfg &amp;&amp; typeof cfg === 'object') {
779
+ if (typeof cfg.enabled === 'boolean') this.enabled = cfg.enabled;
780
+ if (Number.isFinite(cfg.intervalMs) &amp;&amp; cfg.intervalMs &gt; 0) this.intervalMs = cfg.intervalMs;
781
+ if (typeof cfg.allowMajor === 'boolean') this.allowMajor = cfg.allowMajor;
782
+ }
783
+ this._status.enabled = this.enabled;
784
+ }
785
+ &nbsp;
786
+ <span class="fstat-no" title="function not covered" > _persistConfigPatch(patch) {</span>
787
+ <span class="cstat-no" title="statement not covered" > if (!this.config || typeof this.config.setAutoUpdate !== 'function') return;</span>
788
+ <span class="cstat-no" title="statement not covered" > try {</span>
789
+ <span class="cstat-no" title="statement not covered" > this.config.setAutoUpdate(patch);</span>
790
+ <span class="cstat-no" title="statement not covered" > } catch (err) {</span>
791
+ <span class="cstat-no" title="statement not covered" > this.logger.warn('Failed to persist auto-update config patch', {</span>
792
+ <span class="cstat-no" title="statement not covered" > event: 'updater_config_patch_failed',</span>
793
+ <span class="cstat-no" title="statement not covered" > error: err</span>
794
+ <span class="cstat-no" title="statement not covered" > });</span>
795
+ <span class="cstat-no" title="statement not covered" > }</span>
796
+ <span class="cstat-no" title="statement not covered" > }</span>
797
+ &nbsp;
798
+ _setStatus(patch) {
799
+ this._status = { ...this._status, ...patch };
800
+ this.emit('status', this.getStatus());
801
+ }
802
+ &nbsp;
803
+ getStatus() {
804
+ return {
805
+ ...this._status,
806
+ enabled: this.enabled,
807
+ interval_ms: this.intervalMs,
808
+ allow_major: this.allowMajor
809
+ };
810
+ }
811
+ &nbsp;
812
+ <span class="fstat-no" title="function not covered" > async setEnabled(enabled) {</span>
813
+ <span class="cstat-no" title="statement not covered" > this.enabled = Boolean(enabled);</span>
814
+ <span class="cstat-no" title="statement not covered" > this._setStatus({ enabled: this.enabled });</span>
815
+ <span class="cstat-no" title="statement not covered" > this._persistConfigPatch({ enabled: this.enabled });</span>
816
+ <span class="cstat-no" title="statement not covered" > if (this.enabled &amp;&amp; !this._timer) {</span>
817
+ <span class="cstat-no" title="statement not covered" > this.start();</span>
818
+ <span class="cstat-no" title="statement not covered" > await this.triggerCheck({ reason: 'manual_enable' });</span>
819
+ <span class="cstat-no" title="statement not covered" > }</span>
820
+ <span class="cstat-no" title="statement not covered" > if (!this.enabled &amp;&amp; this._timer) {</span>
821
+ <span class="cstat-no" title="statement not covered" > this.stop();</span>
822
+ <span class="cstat-no" title="statement not covered" > }</span>
823
+ <span class="cstat-no" title="statement not covered" > return this.getStatus();</span>
824
+ <span class="cstat-no" title="statement not covered" > }</span>
825
+ &nbsp;
826
+ start() {
827
+ if (this._timer) <span class="branch-0 cbranch-no" title="branch not covered" >return;</span>
828
+ if (!this.enabled) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
829
+ <span class="cstat-no" title="statement not covered" > this.logger.info('Auto-updater disabled', { event: 'updater_disabled' });</span>
830
+ <span class="cstat-no" title="statement not covered" > return;</span>
831
+ <span class="cstat-no" title="statement not covered" > }</span>
832
+ &nbsp;
833
+ this._timer = setInterval(() =&gt; {
834
+ <span class="cstat-no" title="statement not covered" > this.triggerCheck({ reason: 'interval' }).catch((err) =&gt; {</span>
835
+ <span class="cstat-no" title="statement not covered" > this.logger.warn('Auto-update interval check failed', {</span>
836
+ <span class="cstat-no" title="statement not covered" > event: 'updater_interval_failed',</span>
837
+ <span class="cstat-no" title="statement not covered" > error: err</span>
838
+ <span class="cstat-no" title="statement not covered" > });</span>
839
+ <span class="cstat-no" title="statement not covered" > });</span>
840
+ }, this.intervalMs);
841
+ &nbsp;
842
+ this.logger.info('Auto-updater started', {
843
+ event: 'updater_started',
844
+ data: {
845
+ interval_ms: this.intervalMs,
846
+ allow_major: this.allowMajor
847
+ }
848
+ });
849
+ }
850
+ &nbsp;
851
+ stop() {
852
+ if (!this._timer) return;
853
+ clearInterval(this._timer);
854
+ this._timer = null;
855
+ this.logger.info('Auto-updater stopped', { event: 'updater_stopped' });
856
+ }
857
+ &nbsp;
858
+ async triggerCheck(options = {}) {
859
+ return this._runCycle({ ...options, manualUpdate: false, forceCheck: Boolean(options.forceCheck) });
860
+ }
861
+ &nbsp;
862
+ <span class="fstat-no" title="function not covered" > async triggerUpdate(options = {}) {</span>
863
+ <span class="cstat-no" title="statement not covered" > this._pendingManualUpdate = true;</span>
864
+ <span class="cstat-no" title="statement not covered" > return this._runCycle({ ...options, manualUpdate: true });</span>
865
+ <span class="cstat-no" title="statement not covered" > }</span>
866
+ &nbsp;
867
+ async _runCycle(options = {}) {
868
+ if (this._running) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
869
+ <span class="cstat-no" title="statement not covered" > return this.getStatus();</span>
870
+ <span class="cstat-no" title="statement not covered" > }</span>
871
+ if (!this.enabled <span class="branch-0 cbranch-no" title="branch not covered" >&amp;&amp; !options.manualUpdate <span class="branch-0 cbranch-no" title="branch not covered" ></span>&amp;&amp; !options.forceCheck)</span> <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
872
+ <span class="cstat-no" title="statement not covered" > return this.getStatus();</span>
873
+ <span class="cstat-no" title="statement not covered" > }</span>
874
+ &nbsp;
875
+ this._running = true;
876
+ const nowIso = new Date().toISOString();
877
+ this._setStatus({
878
+ state: 'checking',
879
+ last_checked_at: nowIso,
880
+ last_error: null,
881
+ defer_reason: null
882
+ });
883
+ &nbsp;
884
+ try {
885
+ const result = await checkForUpdate(this.currentVersion);
886
+ if (result.error) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
887
+ <span class="cstat-no" title="statement not covered" > this._setStatus({</span>
888
+ <span class="cstat-no" title="statement not covered" > state: 'failed',</span>
889
+ <span class="cstat-no" title="statement not covered" > latest_version: this.currentVersion,</span>
890
+ <span class="cstat-no" title="statement not covered" > last_error: result.error</span>
891
+ <span class="cstat-no" title="statement not covered" > });</span>
892
+ <span class="cstat-no" title="statement not covered" > return this.getStatus();</span>
893
+ <span class="cstat-no" title="statement not covered" > }</span>
894
+ &nbsp;
895
+ const latest = result.latest <span class="branch-0 cbranch-no" title="branch not covered" >|| this.currentVersion;</span>
896
+ if (!result.available) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
897
+ <span class="cstat-no" title="statement not covered" > this._setStatus({</span>
898
+ <span class="cstat-no" title="statement not covered" > state: 'up_to_date',</span>
899
+ <span class="cstat-no" title="statement not covered" > latest_version: latest,</span>
900
+ <span class="cstat-no" title="statement not covered" > target_version: null</span>
901
+ <span class="cstat-no" title="statement not covered" > });</span>
902
+ <span class="cstat-no" title="statement not covered" > return this.getStatus();</span>
903
+ <span class="cstat-no" title="statement not covered" > }</span>
904
+ &nbsp;
905
+ if (!shouldApplyUpdate(this.currentVersion, latest, { allowMajor: this.allowMajor })) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
906
+ <span class="cstat-no" title="statement not covered" > this._setStatus({</span>
907
+ <span class="cstat-no" title="statement not covered" > state: 'up_to_date',</span>
908
+ <span class="cstat-no" title="statement not covered" > latest_version: latest,</span>
909
+ <span class="cstat-no" title="statement not covered" > target_version: null,</span>
910
+ <span class="cstat-no" title="statement not covered" > defer_reason: 'cross_major_blocked'</span>
911
+ <span class="cstat-no" title="statement not covered" > });</span>
912
+ <span class="cstat-no" title="statement not covered" > return this.getStatus();</span>
913
+ <span class="cstat-no" title="statement not covered" > }</span>
914
+ &nbsp;
915
+ const monitor = this.getCallMonitor();
916
+ const activeCalls = monitor &amp;&amp; typeof monitor.getActiveCount === 'function'
917
+ ? Number(monitor.getActiveCount()) <span class="branch-0 cbranch-no" title="branch not covered" >|| 0</span>
918
+ <span class="branch-0 cbranch-no" title="branch not covered" > : 0;</span>
919
+ if (!isUpdateSafe(monitor) &amp;&amp; !options.force) {
920
+ this._setStatus({
921
+ state: 'waiting_for_safe_restart',
922
+ latest_version: latest,
923
+ target_version: latest,
924
+ active_calls: activeCalls,
925
+ defer_reason: 'active_calls'
926
+ });
927
+ return this.getStatus();
928
+ }
929
+ <span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" ></span></span>
930
+ <span class="cstat-no" title="statement not covered" > this._setStatus({</span>
931
+ <span class="cstat-no" title="statement not covered" > state: 'downloading',</span>
932
+ <span class="cstat-no" title="statement not covered" > latest_version: latest,</span>
933
+ <span class="cstat-no" title="statement not covered" > target_version: latest,</span>
934
+ <span class="cstat-no" title="statement not covered" > active_calls: activeCalls</span>
935
+ <span class="cstat-no" title="statement not covered" > });</span>
936
+ <span class="cstat-no" title="statement not covered" ></span>
937
+ <span class="cstat-no" title="statement not covered" > await this._installVersion(latest);</span>
938
+ <span class="cstat-no" title="statement not covered" > this.currentVersion = latest;</span>
939
+ <span class="cstat-no" title="statement not covered" > this._persistConfigPatch({ lastGoodVersion: latest });</span>
940
+ <span class="cstat-no" title="statement not covered" ></span>
941
+ <span class="cstat-no" title="statement not covered" > this._setStatus({</span>
942
+ <span class="cstat-no" title="statement not covered" > state: 'restarting',</span>
943
+ <span class="cstat-no" title="statement not covered" > current_version: latest,</span>
944
+ <span class="cstat-no" title="statement not covered" > latest_version: latest,</span>
945
+ <span class="cstat-no" title="statement not covered" > target_version: latest,</span>
946
+ <span class="cstat-no" title="statement not covered" > last_success_at: new Date().toISOString(),</span>
947
+ <span class="cstat-no" title="statement not covered" > last_error: null,</span>
948
+ <span class="cstat-no" title="statement not covered" > defer_reason: null,</span>
949
+ <span class="cstat-no" title="statement not covered" > active_calls: 0</span>
950
+ <span class="cstat-no" title="statement not covered" > });</span>
951
+ <span class="cstat-no" title="statement not covered" ></span>
952
+ <span class="cstat-no" title="statement not covered" > if (this.restartFn) {</span>
953
+ <span class="cstat-no" title="statement not covered" > await this.restartFn(latest);</span>
954
+ <span class="cstat-no" title="statement not covered" > } else {</span>
955
+ <span class="cstat-no" title="statement not covered" > this._setStatus({</span>
956
+ <span class="cstat-no" title="statement not covered" > state: 'up_to_date',</span>
957
+ <span class="cstat-no" title="statement not covered" > current_version: latest,</span>
958
+ <span class="cstat-no" title="statement not covered" > latest_version: latest,</span>
959
+ <span class="cstat-no" title="statement not covered" > target_version: null</span>
960
+ <span class="cstat-no" title="statement not covered" > });</span>
961
+ <span class="cstat-no" title="statement not covered" > }</span>
962
+ <span class="cstat-no" title="statement not covered" ></span>
963
+ <span class="cstat-no" title="statement not covered" > return this.getStatus();</span>
964
+ <span class="cstat-no" title="statement not covered" > } catch (err) {</span>
965
+ <span class="cstat-no" title="statement not covered" > const message = err &amp;&amp; err.message ? err.message : 'update_failed';</span>
966
+ <span class="cstat-no" title="statement not covered" > this._setStatus({</span>
967
+ <span class="cstat-no" title="statement not covered" > state: 'failed',</span>
968
+ <span class="cstat-no" title="statement not covered" > last_error: message</span>
969
+ <span class="cstat-no" title="statement not covered" > });</span>
970
+ <span class="cstat-no" title="statement not covered" > this.logger.error('Auto-update failed', {</span>
971
+ <span class="cstat-no" title="statement not covered" > event: 'updater_failed',</span>
972
+ <span class="cstat-no" title="statement not covered" > error: err</span>
973
+ <span class="cstat-no" title="statement not covered" > });</span>
974
+ <span class="cstat-no" title="statement not covered" > return this.getStatus();</span>
975
+ } finally {
976
+ this._running = false;
977
+ this._pendingManualUpdate = false;
978
+ }
979
+ }
980
+ &nbsp;
981
+ <span class="fstat-no" title="function not covered" > async _installVersion(version) {</span>
982
+ <span class="cstat-no" title="statement not covered" > const args = ['install', '-g', `a2acalling@${version}`];</span>
983
+ <span class="cstat-no" title="statement not covered" > this._setStatus({ state: 'applying' });</span>
984
+ <span class="cstat-no" title="statement not covered" > this.logger.info('Installing auto-update target', {</span>
985
+ <span class="cstat-no" title="statement not covered" > event: 'updater_install_start',</span>
986
+ <span class="cstat-no" title="statement not covered" > data: { version }</span>
987
+ <span class="cstat-no" title="statement not covered" > });</span>
988
+ <span class="cstat-no" title="statement not covered" > await this._execFile('npm', args, {</span>
989
+ <span class="cstat-no" title="statement not covered" > timeout: this.installTimeoutMs,</span>
990
+ <span class="cstat-no" title="statement not covered" > env: process.env</span>
991
+ <span class="cstat-no" title="statement not covered" > });</span>
992
+ <span class="cstat-no" title="statement not covered" > this.logger.info('Auto-update install complete', {</span>
993
+ <span class="cstat-no" title="statement not covered" > event: 'updater_install_done',</span>
994
+ <span class="cstat-no" title="statement not covered" > data: { version }</span>
995
+ <span class="cstat-no" title="statement not covered" > });</span>
996
+ <span class="cstat-no" title="statement not covered" > }</span>
997
+ }
998
+ &nbsp;
999
+ module.exports = {
1000
+ DEFAULT_INTERVAL_MS,
1001
+ isUpdateSafe,
1002
+ shouldApplyUpdate,
1003
+ UpdateManager
1004
+ };
1005
+ &nbsp;</pre></td></tr></table></pre>
1006
+
1007
+ <div class='push'></div><!-- for sticky footer -->
1008
+ </div><!-- /wrapper -->
1009
+ <div class='footer quiet pad2 space-top1 center small'>
1010
+ Code coverage generated by
1011
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1012
+ at 2026-03-03T22:25:10.857Z
1013
+ </div>
1014
+ <script src="../../prettify.js"></script>
1015
+ <script>
1016
+ window.onload = function () {
1017
+ prettyPrint();
1018
+ };
1019
+ </script>
1020
+ <script src="../../sorter.js"></script>
1021
+ <script src="../../block-navigation.js"></script>
1022
+ </body>
1023
+ </html>
1024
+