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.
- package/.a2a-manifest.json +2 -2
- package/.c8rc.json +16 -0
- package/.node-version +1 -0
- package/.serena/project.yml +126 -0
- package/ARCHITECTURE.md +11 -0
- package/CONVENTIONS.md +9 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +146 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/index.html +131 -0
- package/coverage/src/index.js.html +313 -0
- package/coverage/src/lib/agent-card.js.html +418 -0
- package/coverage/src/lib/call-monitor.js.html +700 -0
- package/coverage/src/lib/callbook.js.html +1183 -0
- package/coverage/src/lib/claude-subagent.js.html +2173 -0
- package/coverage/src/lib/client.js.html +2134 -0
- package/coverage/src/lib/config.js.html +1525 -0
- package/coverage/src/lib/conversation-driver.js.html +1909 -0
- package/coverage/src/lib/conversations.js.html +2575 -0
- package/coverage/src/lib/crypto.js.html +424 -0
- package/coverage/src/lib/dashboard-events.js.html +724 -0
- package/coverage/src/lib/disclosure.js.html +2461 -0
- package/coverage/src/lib/external-ip.js.html +718 -0
- package/coverage/src/lib/index.html +506 -0
- package/coverage/src/lib/invite-host.js.html +754 -0
- package/coverage/src/lib/local-request.js.html +292 -0
- package/coverage/src/lib/logger.js.html +2116 -0
- package/coverage/src/lib/openclaw-integration.js.html +1102 -0
- package/coverage/src/lib/pid-file.js.html +394 -0
- package/coverage/src/lib/port-scanner.js.html +334 -0
- package/coverage/src/lib/prompt-template.js.html +1150 -0
- package/coverage/src/lib/runtime-adapter.js.html +2188 -0
- package/coverage/src/lib/summarizer.js.html +553 -0
- package/coverage/src/lib/summary-formatter.js.html +589 -0
- package/coverage/src/lib/summary-prompt.js.html +694 -0
- package/coverage/src/lib/tokens.js.html +2689 -0
- package/coverage/src/lib/turn-timeout.js.html +241 -0
- package/coverage/src/lib/update-checker.js.html +364 -0
- package/coverage/src/lib/update-manager.js.html +1024 -0
- package/coverage/src/routes/a2a.js.html +3724 -0
- package/coverage/src/routes/callbook.js.html +511 -0
- package/coverage/src/routes/dashboard.js.html +4819 -0
- package/coverage/src/routes/index.html +146 -0
- package/coverage/src/server.js.html +3622 -0
- package/coverage/tmp/coverage-1605378-1772576706365-0.json +1 -0
- package/coverage/tmp/coverage-1605384-1772576607459-0.json +1 -0
- package/coverage/tmp/coverage-1605410-1772576631155-0.json +1 -0
- package/coverage/tmp/coverage-1606942-1772576636869-0.json +1 -0
- package/coverage/tmp/coverage-1607004-1772576637454-0.json +1 -0
- package/coverage/tmp/coverage-1607044-1772576637876-0.json +1 -0
- package/coverage/tmp/coverage-1607096-1772576638356-0.json +1 -0
- package/coverage/tmp/coverage-1607145-1772576638777-0.json +1 -0
- package/coverage/tmp/coverage-1607201-1772576639277-0.json +1 -0
- package/coverage/tmp/coverage-1607247-1772576639755-0.json +1 -0
- package/coverage/tmp/coverage-1607317-1772576640083-0.json +1 -0
- package/coverage/tmp/coverage-1607381-1772576640465-0.json +1 -0
- package/coverage/tmp/coverage-1607446-1772576640868-0.json +1 -0
- package/coverage/tmp/coverage-1607501-1772576641662-0.json +1 -0
- package/coverage/tmp/coverage-1607534-1772576641565-0.json +1 -0
- package/coverage/tmp/coverage-1607627-1772576641871-0.json +1 -0
- package/coverage/tmp/coverage-1607665-1772576642172-0.json +1 -0
- package/coverage/tmp/coverage-1607714-1772576642577-0.json +1 -0
- package/coverage/tmp/coverage-1607788-1772576643466-0.json +1 -0
- package/coverage/tmp/coverage-1607924-1772576644678-0.json +1 -0
- package/coverage/tmp/coverage-1607978-1772576645154-0.json +1 -0
- package/coverage/tmp/coverage-1608035-1772576645564-0.json +1 -0
- package/coverage/tmp/coverage-1608106-1772576645967-0.json +1 -0
- package/coverage/tmp/coverage-1608179-1772576648656-0.json +1 -0
- package/coverage/tmp/coverage-1608196-1772576647367-0.json +1 -0
- package/coverage/tmp/coverage-1608217-1772576648557-0.json +1 -0
- package/coverage/tmp/coverage-1608256-1772576651378-0.json +1 -0
- package/coverage/tmp/coverage-1608265-1772576650058-0.json +1 -0
- package/coverage/tmp/coverage-1608289-1772576651358-0.json +1 -0
- package/coverage/tmp/coverage-1608591-1772576660465-0.json +1 -0
- package/coverage/tmp/coverage-1608648-1772576659272-0.json +1 -0
- package/coverage/tmp/coverage-1608665-1772576660374-0.json +1 -0
- package/coverage/tmp/coverage-1608677-1772576661268-0.json +1 -0
- package/coverage/tmp/coverage-1608684-1772576663968-0.json +1 -0
- package/coverage/tmp/coverage-1608692-1772576662575-0.json +1 -0
- package/coverage/tmp/coverage-1608701-1772576663873-0.json +1 -0
- package/coverage/tmp/coverage-1608718-1772576666674-0.json +1 -0
- package/coverage/tmp/coverage-1608725-1772576665463-0.json +1 -0
- package/coverage/tmp/coverage-1608738-1772576666577-0.json +1 -0
- package/coverage/tmp/coverage-1608753-1772576669664-0.json +1 -0
- package/coverage/tmp/coverage-1608763-1772576668275-0.json +1 -0
- package/coverage/tmp/coverage-1608771-1772576669563-0.json +1 -0
- package/coverage/tmp/coverage-1608828-1772576676574-0.json +1 -0
- package/coverage/tmp/coverage-1609244-1772576675272-0.json +1 -0
- package/coverage/tmp/coverage-1609342-1772576676478-0.json +1 -0
- package/coverage/tmp/coverage-1609450-1772576686954-0.json +1 -0
- package/coverage/tmp/coverage-1609841-1772576685466-0.json +1 -0
- package/coverage/tmp/coverage-1609925-1772576686855-0.json +1 -0
- package/coverage/tmp/coverage-1610399-1772576692469-0.json +1 -0
- package/coverage/tmp/coverage-1611283-1772576703062-0.json +1 -0
- package/coverage/tmp/coverage-1611294-1772576703755-0.json +1 -0
- package/docs/plans/2026-03-03-a2a-91-macos-packaging-plan.md +144 -0
- package/docs/signing-setup.md +49 -0
- package/native/macos/certs/appldevcert.cer +0 -0
- package/native/macos/src-tauri/binaries/.gitkeep +0 -0
- package/native/macos/src-tauri/capabilities/default.json +11 -1
- package/native/macos/src-tauri/entitlements.plist +14 -0
- package/native/macos/src-tauri/src/discovery.rs +14 -3
- package/native/macos/src-tauri/src/health.rs +4 -0
- package/native/macos/src-tauri/src/lib.rs +52 -11
- package/native/macos/src-tauri/src/server.rs +262 -26
- package/native/macos/src-tauri/tauri.conf.json +13 -4
- package/package.json +7 -2
- package/pkg.config.json +14 -0
- package/scripts/build-standalone.sh +106 -0
- package/scripts/smoke-test-standalone.sh +101 -0
- package/scripts/sync-version.sh +28 -0
- package/scripts/verify-app-bundle.sh +34 -0
- package/.maestro/inbox/release-workflow-spam.md +0 -25
|
@@ -0,0 +1,2116 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/lib/logger.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> logger.js</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">87.44% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>592/677</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">71.2% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>136/191</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">92.3% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>36/39</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">87.44% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>592/677</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 high'></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>
|
|
675
|
+
<a name='L610'></a><a href='#L610'>610</a>
|
|
676
|
+
<a name='L611'></a><a href='#L611'>611</a>
|
|
677
|
+
<a name='L612'></a><a href='#L612'>612</a>
|
|
678
|
+
<a name='L613'></a><a href='#L613'>613</a>
|
|
679
|
+
<a name='L614'></a><a href='#L614'>614</a>
|
|
680
|
+
<a name='L615'></a><a href='#L615'>615</a>
|
|
681
|
+
<a name='L616'></a><a href='#L616'>616</a>
|
|
682
|
+
<a name='L617'></a><a href='#L617'>617</a>
|
|
683
|
+
<a name='L618'></a><a href='#L618'>618</a>
|
|
684
|
+
<a name='L619'></a><a href='#L619'>619</a>
|
|
685
|
+
<a name='L620'></a><a href='#L620'>620</a>
|
|
686
|
+
<a name='L621'></a><a href='#L621'>621</a>
|
|
687
|
+
<a name='L622'></a><a href='#L622'>622</a>
|
|
688
|
+
<a name='L623'></a><a href='#L623'>623</a>
|
|
689
|
+
<a name='L624'></a><a href='#L624'>624</a>
|
|
690
|
+
<a name='L625'></a><a href='#L625'>625</a>
|
|
691
|
+
<a name='L626'></a><a href='#L626'>626</a>
|
|
692
|
+
<a name='L627'></a><a href='#L627'>627</a>
|
|
693
|
+
<a name='L628'></a><a href='#L628'>628</a>
|
|
694
|
+
<a name='L629'></a><a href='#L629'>629</a>
|
|
695
|
+
<a name='L630'></a><a href='#L630'>630</a>
|
|
696
|
+
<a name='L631'></a><a href='#L631'>631</a>
|
|
697
|
+
<a name='L632'></a><a href='#L632'>632</a>
|
|
698
|
+
<a name='L633'></a><a href='#L633'>633</a>
|
|
699
|
+
<a name='L634'></a><a href='#L634'>634</a>
|
|
700
|
+
<a name='L635'></a><a href='#L635'>635</a>
|
|
701
|
+
<a name='L636'></a><a href='#L636'>636</a>
|
|
702
|
+
<a name='L637'></a><a href='#L637'>637</a>
|
|
703
|
+
<a name='L638'></a><a href='#L638'>638</a>
|
|
704
|
+
<a name='L639'></a><a href='#L639'>639</a>
|
|
705
|
+
<a name='L640'></a><a href='#L640'>640</a>
|
|
706
|
+
<a name='L641'></a><a href='#L641'>641</a>
|
|
707
|
+
<a name='L642'></a><a href='#L642'>642</a>
|
|
708
|
+
<a name='L643'></a><a href='#L643'>643</a>
|
|
709
|
+
<a name='L644'></a><a href='#L644'>644</a>
|
|
710
|
+
<a name='L645'></a><a href='#L645'>645</a>
|
|
711
|
+
<a name='L646'></a><a href='#L646'>646</a>
|
|
712
|
+
<a name='L647'></a><a href='#L647'>647</a>
|
|
713
|
+
<a name='L648'></a><a href='#L648'>648</a>
|
|
714
|
+
<a name='L649'></a><a href='#L649'>649</a>
|
|
715
|
+
<a name='L650'></a><a href='#L650'>650</a>
|
|
716
|
+
<a name='L651'></a><a href='#L651'>651</a>
|
|
717
|
+
<a name='L652'></a><a href='#L652'>652</a>
|
|
718
|
+
<a name='L653'></a><a href='#L653'>653</a>
|
|
719
|
+
<a name='L654'></a><a href='#L654'>654</a>
|
|
720
|
+
<a name='L655'></a><a href='#L655'>655</a>
|
|
721
|
+
<a name='L656'></a><a href='#L656'>656</a>
|
|
722
|
+
<a name='L657'></a><a href='#L657'>657</a>
|
|
723
|
+
<a name='L658'></a><a href='#L658'>658</a>
|
|
724
|
+
<a name='L659'></a><a href='#L659'>659</a>
|
|
725
|
+
<a name='L660'></a><a href='#L660'>660</a>
|
|
726
|
+
<a name='L661'></a><a href='#L661'>661</a>
|
|
727
|
+
<a name='L662'></a><a href='#L662'>662</a>
|
|
728
|
+
<a name='L663'></a><a href='#L663'>663</a>
|
|
729
|
+
<a name='L664'></a><a href='#L664'>664</a>
|
|
730
|
+
<a name='L665'></a><a href='#L665'>665</a>
|
|
731
|
+
<a name='L666'></a><a href='#L666'>666</a>
|
|
732
|
+
<a name='L667'></a><a href='#L667'>667</a>
|
|
733
|
+
<a name='L668'></a><a href='#L668'>668</a>
|
|
734
|
+
<a name='L669'></a><a href='#L669'>669</a>
|
|
735
|
+
<a name='L670'></a><a href='#L670'>670</a>
|
|
736
|
+
<a name='L671'></a><a href='#L671'>671</a>
|
|
737
|
+
<a name='L672'></a><a href='#L672'>672</a>
|
|
738
|
+
<a name='L673'></a><a href='#L673'>673</a>
|
|
739
|
+
<a name='L674'></a><a href='#L674'>674</a>
|
|
740
|
+
<a name='L675'></a><a href='#L675'>675</a>
|
|
741
|
+
<a name='L676'></a><a href='#L676'>676</a>
|
|
742
|
+
<a name='L677'></a><a href='#L677'>677</a>
|
|
743
|
+
<a name='L678'></a><a href='#L678'>678</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">76x</span>
|
|
744
|
+
<span class="cline-any cline-yes">76x</span>
|
|
745
|
+
<span class="cline-any cline-yes">76x</span>
|
|
746
|
+
<span class="cline-any cline-yes">76x</span>
|
|
747
|
+
<span class="cline-any cline-yes">76x</span>
|
|
748
|
+
<span class="cline-any cline-yes">76x</span>
|
|
749
|
+
<span class="cline-any cline-yes">76x</span>
|
|
750
|
+
<span class="cline-any cline-yes">76x</span>
|
|
751
|
+
<span class="cline-any cline-yes">76x</span>
|
|
752
|
+
<span class="cline-any cline-yes">76x</span>
|
|
753
|
+
<span class="cline-any cline-yes">76x</span>
|
|
754
|
+
<span class="cline-any cline-yes">76x</span>
|
|
755
|
+
<span class="cline-any cline-yes">746x</span>
|
|
756
|
+
<span class="cline-any cline-yes">746x</span>
|
|
757
|
+
<span class="cline-any cline-yes">746x</span>
|
|
758
|
+
<span class="cline-any cline-yes">746x</span>
|
|
759
|
+
<span class="cline-any cline-yes">746x</span>
|
|
760
|
+
<span class="cline-any cline-yes">76x</span>
|
|
761
|
+
<span class="cline-any cline-yes">76x</span>
|
|
762
|
+
<span class="cline-any cline-yes">76x</span>
|
|
763
|
+
<span class="cline-any cline-yes">76x</span>
|
|
764
|
+
<span class="cline-any cline-yes">76x</span>
|
|
765
|
+
<span class="cline-any cline-yes">76x</span>
|
|
766
|
+
<span class="cline-any cline-yes">76x</span>
|
|
767
|
+
<span class="cline-any cline-yes">76x</span>
|
|
768
|
+
<span class="cline-any cline-yes">76x</span>
|
|
769
|
+
<span class="cline-any cline-yes">76x</span>
|
|
770
|
+
<span class="cline-any cline-yes">788x</span>
|
|
771
|
+
<span class="cline-any cline-yes">788x</span>
|
|
772
|
+
<span class="cline-any cline-yes">788x</span>
|
|
773
|
+
<span class="cline-any cline-yes">788x</span>
|
|
774
|
+
<span class="cline-any cline-yes">788x</span>
|
|
775
|
+
<span class="cline-any cline-no"> </span>
|
|
776
|
+
<span class="cline-any cline-yes">788x</span>
|
|
777
|
+
<span class="cline-any cline-yes">788x</span>
|
|
778
|
+
<span class="cline-any cline-yes">76x</span>
|
|
779
|
+
<span class="cline-any cline-yes">3151x</span>
|
|
780
|
+
<span class="cline-any cline-yes">3151x</span>
|
|
781
|
+
<span class="cline-any cline-yes">3151x</span>
|
|
782
|
+
<span class="cline-any cline-yes">3151x</span>
|
|
783
|
+
<span class="cline-any cline-yes">76x</span>
|
|
784
|
+
<span class="cline-any cline-yes">721x</span>
|
|
785
|
+
<span class="cline-any cline-yes">721x</span>
|
|
786
|
+
<span class="cline-any cline-yes">721x</span>
|
|
787
|
+
<span class="cline-any cline-yes">721x</span>
|
|
788
|
+
<span class="cline-any cline-yes">721x</span>
|
|
789
|
+
<span class="cline-any cline-yes">76x</span>
|
|
790
|
+
<span class="cline-any cline-yes">1367x</span>
|
|
791
|
+
<span class="cline-any cline-yes">1367x</span>
|
|
792
|
+
<span class="cline-any cline-yes">1367x</span>
|
|
793
|
+
<span class="cline-any cline-yes">1367x</span>
|
|
794
|
+
<span class="cline-any cline-yes">1367x</span>
|
|
795
|
+
<span class="cline-any cline-yes">1367x</span>
|
|
796
|
+
<span class="cline-any cline-yes">76x</span>
|
|
797
|
+
<span class="cline-any cline-yes">543x</span>
|
|
798
|
+
<span class="cline-any cline-yes">543x</span>
|
|
799
|
+
<span class="cline-any cline-yes">14x</span>
|
|
800
|
+
<span class="cline-any cline-yes">14x</span>
|
|
801
|
+
<span class="cline-any cline-yes">14x</span>
|
|
802
|
+
<span class="cline-any cline-yes">14x</span>
|
|
803
|
+
<span class="cline-any cline-yes">14x</span>
|
|
804
|
+
<span class="cline-any cline-yes">14x</span>
|
|
805
|
+
<span class="cline-any cline-yes">14x</span>
|
|
806
|
+
<span class="cline-any cline-yes">14x</span>
|
|
807
|
+
<span class="cline-any cline-yes">14x</span>
|
|
808
|
+
<span class="cline-any cline-yes">14x</span>
|
|
809
|
+
<span class="cline-any cline-yes">14x</span>
|
|
810
|
+
<span class="cline-any cline-yes">14x</span>
|
|
811
|
+
<span class="cline-any cline-no"> </span>
|
|
812
|
+
<span class="cline-any cline-no"> </span>
|
|
813
|
+
<span class="cline-any cline-no"> </span>
|
|
814
|
+
<span class="cline-any cline-no"> </span>
|
|
815
|
+
<span class="cline-any cline-no"> </span>
|
|
816
|
+
<span class="cline-any cline-no"> </span>
|
|
817
|
+
<span class="cline-any cline-no"> </span>
|
|
818
|
+
<span class="cline-any cline-no"> </span>
|
|
819
|
+
<span class="cline-any cline-yes">543x</span>
|
|
820
|
+
<span class="cline-any cline-yes">76x</span>
|
|
821
|
+
<span class="cline-any cline-yes">543x</span>
|
|
822
|
+
<span class="cline-any cline-yes">543x</span>
|
|
823
|
+
<span class="cline-any cline-yes">543x</span>
|
|
824
|
+
<span class="cline-any cline-yes">543x</span>
|
|
825
|
+
<span class="cline-any cline-yes">543x</span>
|
|
826
|
+
<span class="cline-any cline-yes">14x</span>
|
|
827
|
+
<span class="cline-any cline-yes">14x</span>
|
|
828
|
+
<span class="cline-any cline-yes">543x</span>
|
|
829
|
+
<span class="cline-any cline-yes">543x</span>
|
|
830
|
+
<span class="cline-any cline-yes">543x</span>
|
|
831
|
+
<span class="cline-any cline-yes">543x</span>
|
|
832
|
+
<span class="cline-any cline-yes">543x</span>
|
|
833
|
+
<span class="cline-any cline-yes">543x</span>
|
|
834
|
+
<span class="cline-any cline-yes">543x</span>
|
|
835
|
+
<span class="cline-any cline-yes">543x</span>
|
|
836
|
+
<span class="cline-any cline-yes">543x</span>
|
|
837
|
+
<span class="cline-any cline-yes">543x</span>
|
|
838
|
+
<span class="cline-any cline-yes">543x</span>
|
|
839
|
+
<span class="cline-any cline-yes">543x</span>
|
|
840
|
+
<span class="cline-any cline-yes">543x</span>
|
|
841
|
+
<span class="cline-any cline-yes">543x</span>
|
|
842
|
+
<span class="cline-any cline-yes">543x</span>
|
|
843
|
+
<span class="cline-any cline-yes">543x</span>
|
|
844
|
+
<span class="cline-any cline-yes">543x</span>
|
|
845
|
+
<span class="cline-any cline-yes">543x</span>
|
|
846
|
+
<span class="cline-any cline-yes">76x</span>
|
|
847
|
+
<span class="cline-any cline-yes">76x</span>
|
|
848
|
+
<span class="cline-any cline-yes">76x</span>
|
|
849
|
+
<span class="cline-any cline-yes">289x</span>
|
|
850
|
+
<span class="cline-any cline-yes">289x</span>
|
|
851
|
+
<span class="cline-any cline-yes">289x</span>
|
|
852
|
+
<span class="cline-any cline-yes">289x</span>
|
|
853
|
+
<span class="cline-any cline-yes">289x</span>
|
|
854
|
+
<span class="cline-any cline-yes">289x</span>
|
|
855
|
+
<span class="cline-any cline-yes">76x</span>
|
|
856
|
+
<span class="cline-any cline-yes">76x</span>
|
|
857
|
+
<span class="cline-any cline-yes">289x</span>
|
|
858
|
+
<span class="cline-any cline-no"> </span>
|
|
859
|
+
<span class="cline-any cline-no"> </span>
|
|
860
|
+
<span class="cline-any cline-yes">289x</span>
|
|
861
|
+
<span class="cline-any cline-yes">76x</span>
|
|
862
|
+
<span class="cline-any cline-yes">76x</span>
|
|
863
|
+
<span class="cline-any cline-yes">1580x</span>
|
|
864
|
+
<span class="cline-any cline-yes">1580x</span>
|
|
865
|
+
<span class="cline-any cline-yes">120x</span>
|
|
866
|
+
<span class="cline-any cline-yes">120x</span>
|
|
867
|
+
<span class="cline-any cline-yes">120x</span>
|
|
868
|
+
<span class="cline-any cline-yes">120x</span>
|
|
869
|
+
<span class="cline-any cline-yes">120x</span>
|
|
870
|
+
<span class="cline-any cline-yes">120x</span>
|
|
871
|
+
<span class="cline-any cline-yes">1580x</span>
|
|
872
|
+
<span class="cline-any cline-no"> </span>
|
|
873
|
+
<span class="cline-any cline-no"> </span>
|
|
874
|
+
<span class="cline-any cline-yes">120x</span>
|
|
875
|
+
<span class="cline-any cline-yes">1580x</span>
|
|
876
|
+
<span class="cline-any cline-no"> </span>
|
|
877
|
+
<span class="cline-any cline-no"> </span>
|
|
878
|
+
<span class="cline-any cline-no"> </span>
|
|
879
|
+
<span class="cline-any cline-no"> </span>
|
|
880
|
+
<span class="cline-any cline-no"> </span>
|
|
881
|
+
<span class="cline-any cline-no"> </span>
|
|
882
|
+
<span class="cline-any cline-no"> </span>
|
|
883
|
+
<span class="cline-any cline-no"> </span>
|
|
884
|
+
<span class="cline-any cline-no"> </span>
|
|
885
|
+
<span class="cline-any cline-no"> </span>
|
|
886
|
+
<span class="cline-any cline-no"> </span>
|
|
887
|
+
<span class="cline-any cline-no"> </span>
|
|
888
|
+
<span class="cline-any cline-no"> </span>
|
|
889
|
+
<span class="cline-any cline-no"> </span>
|
|
890
|
+
<span class="cline-any cline-no"> </span>
|
|
891
|
+
<span class="cline-any cline-no"> </span>
|
|
892
|
+
<span class="cline-any cline-no"> </span>
|
|
893
|
+
<span class="cline-any cline-no"> </span>
|
|
894
|
+
<span class="cline-any cline-no"> </span>
|
|
895
|
+
<span class="cline-any cline-no"> </span>
|
|
896
|
+
<span class="cline-any cline-yes">120x</span>
|
|
897
|
+
<span class="cline-any cline-yes">120x</span>
|
|
898
|
+
<span class="cline-any cline-yes">1580x</span>
|
|
899
|
+
<span class="cline-any cline-no"> </span>
|
|
900
|
+
<span class="cline-any cline-no"> </span>
|
|
901
|
+
<span class="cline-any cline-no"> </span>
|
|
902
|
+
<span class="cline-any cline-yes">1580x</span>
|
|
903
|
+
<span class="cline-any cline-yes">76x</span>
|
|
904
|
+
<span class="cline-any cline-yes">76x</span>
|
|
905
|
+
<span class="cline-any cline-yes">120x</span>
|
|
906
|
+
<span class="cline-any cline-yes">120x</span>
|
|
907
|
+
<span class="cline-any cline-yes">120x</span>
|
|
908
|
+
<span class="cline-any cline-yes">120x</span>
|
|
909
|
+
<span class="cline-any cline-yes">120x</span>
|
|
910
|
+
<span class="cline-any cline-yes">120x</span>
|
|
911
|
+
<span class="cline-any cline-yes">120x</span>
|
|
912
|
+
<span class="cline-any cline-yes">120x</span>
|
|
913
|
+
<span class="cline-any cline-yes">120x</span>
|
|
914
|
+
<span class="cline-any cline-yes">120x</span>
|
|
915
|
+
<span class="cline-any cline-yes">120x</span>
|
|
916
|
+
<span class="cline-any cline-yes">120x</span>
|
|
917
|
+
<span class="cline-any cline-yes">120x</span>
|
|
918
|
+
<span class="cline-any cline-yes">120x</span>
|
|
919
|
+
<span class="cline-any cline-yes">120x</span>
|
|
920
|
+
<span class="cline-any cline-yes">120x</span>
|
|
921
|
+
<span class="cline-any cline-yes">120x</span>
|
|
922
|
+
<span class="cline-any cline-yes">120x</span>
|
|
923
|
+
<span class="cline-any cline-yes">120x</span>
|
|
924
|
+
<span class="cline-any cline-yes">120x</span>
|
|
925
|
+
<span class="cline-any cline-yes">120x</span>
|
|
926
|
+
<span class="cline-any cline-yes">120x</span>
|
|
927
|
+
<span class="cline-any cline-yes">120x</span>
|
|
928
|
+
<span class="cline-any cline-yes">120x</span>
|
|
929
|
+
<span class="cline-any cline-yes">120x</span>
|
|
930
|
+
<span class="cline-any cline-yes">120x</span>
|
|
931
|
+
<span class="cline-any cline-yes">120x</span>
|
|
932
|
+
<span class="cline-any cline-yes">120x</span>
|
|
933
|
+
<span class="cline-any cline-yes">120x</span>
|
|
934
|
+
<span class="cline-any cline-yes">120x</span>
|
|
935
|
+
<span class="cline-any cline-yes">120x</span>
|
|
936
|
+
<span class="cline-any cline-yes">120x</span>
|
|
937
|
+
<span class="cline-any cline-yes">120x</span>
|
|
938
|
+
<span class="cline-any cline-yes">120x</span>
|
|
939
|
+
<span class="cline-any cline-yes">76x</span>
|
|
940
|
+
<span class="cline-any cline-yes">76x</span>
|
|
941
|
+
<span class="cline-any cline-yes">120x</span>
|
|
942
|
+
<span class="cline-any cline-yes">120x</span>
|
|
943
|
+
<span class="cline-any cline-yes">120x</span>
|
|
944
|
+
<span class="cline-any cline-yes">120x</span>
|
|
945
|
+
<span class="cline-any cline-yes">120x</span>
|
|
946
|
+
<span class="cline-any cline-yes">120x</span>
|
|
947
|
+
<span class="cline-any cline-yes">120x</span>
|
|
948
|
+
<span class="cline-any cline-yes">120x</span>
|
|
949
|
+
<span class="cline-any cline-yes">120x</span>
|
|
950
|
+
<span class="cline-any cline-yes">76x</span>
|
|
951
|
+
<span class="cline-any cline-yes">76x</span>
|
|
952
|
+
<span class="cline-any cline-no"> </span>
|
|
953
|
+
<span class="cline-any cline-no"> </span>
|
|
954
|
+
<span class="cline-any cline-yes">76x</span>
|
|
955
|
+
<span class="cline-any cline-yes">76x</span>
|
|
956
|
+
<span class="cline-any cline-no"> </span>
|
|
957
|
+
<span class="cline-any cline-no"> </span>
|
|
958
|
+
<span class="cline-any cline-no"> </span>
|
|
959
|
+
<span class="cline-any cline-yes">76x</span>
|
|
960
|
+
<span class="cline-any cline-yes">76x</span>
|
|
961
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
962
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
963
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
964
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
965
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
966
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
967
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
968
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
969
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
970
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
971
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
972
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
973
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
974
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
975
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
976
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
977
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
978
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
979
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
980
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
981
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
982
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
983
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
984
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
985
|
+
<span class="cline-any cline-yes">2x</span>
|
|
986
|
+
<span class="cline-any cline-yes">2x</span>
|
|
987
|
+
<span class="cline-any cline-yes">2x</span>
|
|
988
|
+
<span class="cline-any cline-yes">2x</span>
|
|
989
|
+
<span class="cline-any cline-yes">1x</span>
|
|
990
|
+
<span class="cline-any cline-yes">1x</span>
|
|
991
|
+
<span class="cline-any cline-yes">2x</span>
|
|
992
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
993
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
994
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
995
|
+
<span class="cline-any cline-no"> </span>
|
|
996
|
+
<span class="cline-any cline-no"> </span>
|
|
997
|
+
<span class="cline-any cline-no"> </span>
|
|
998
|
+
<span class="cline-any cline-yes">1544x</span>
|
|
999
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1000
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1001
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1002
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1003
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1004
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1005
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1006
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1007
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1008
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1009
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1010
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1011
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1012
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1013
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1014
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1015
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1016
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1017
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1018
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1019
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1020
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1021
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1022
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1023
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1024
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1025
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1026
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1027
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1028
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1029
|
+
<span class="cline-any cline-no"> </span>
|
|
1030
|
+
<span class="cline-any cline-no"> </span>
|
|
1031
|
+
<span class="cline-any cline-no"> </span>
|
|
1032
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1033
|
+
<span class="cline-any cline-no"> </span>
|
|
1034
|
+
<span class="cline-any cline-no"> </span>
|
|
1035
|
+
<span class="cline-any cline-no"> </span>
|
|
1036
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1037
|
+
<span class="cline-any cline-no"> </span>
|
|
1038
|
+
<span class="cline-any cline-no"> </span>
|
|
1039
|
+
<span class="cline-any cline-no"> </span>
|
|
1040
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1041
|
+
<span class="cline-any cline-no"> </span>
|
|
1042
|
+
<span class="cline-any cline-no"> </span>
|
|
1043
|
+
<span class="cline-any cline-no"> </span>
|
|
1044
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1045
|
+
<span class="cline-any cline-no"> </span>
|
|
1046
|
+
<span class="cline-any cline-no"> </span>
|
|
1047
|
+
<span class="cline-any cline-no"> </span>
|
|
1048
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1049
|
+
<span class="cline-any cline-no"> </span>
|
|
1050
|
+
<span class="cline-any cline-no"> </span>
|
|
1051
|
+
<span class="cline-any cline-no"> </span>
|
|
1052
|
+
<span class="cline-any cline-no"> </span>
|
|
1053
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1054
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1055
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1056
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1057
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1058
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1059
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1060
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1061
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1062
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1063
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1064
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1065
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1066
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1067
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1068
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1069
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1070
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1071
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1072
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1073
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1074
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1075
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1076
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1077
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1078
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1079
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1080
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1081
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1082
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1083
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1084
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1085
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1086
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1087
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1088
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1089
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1090
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1091
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1092
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1093
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1094
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1095
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1096
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1097
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1098
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1099
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1100
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1101
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1102
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1103
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1104
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1105
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1106
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1107
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1108
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1109
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1110
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1111
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1112
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1113
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1114
|
+
<span class="cline-any cline-no"> </span>
|
|
1115
|
+
<span class="cline-any cline-no"> </span>
|
|
1116
|
+
<span class="cline-any cline-no"> </span>
|
|
1117
|
+
<span class="cline-any cline-no"> </span>
|
|
1118
|
+
<span class="cline-any cline-no"> </span>
|
|
1119
|
+
<span class="cline-any cline-no"> </span>
|
|
1120
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1121
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1122
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1123
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1124
|
+
<span class="cline-any cline-no"> </span>
|
|
1125
|
+
<span class="cline-any cline-no"> </span>
|
|
1126
|
+
<span class="cline-any cline-no"> </span>
|
|
1127
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1128
|
+
<span class="cline-any cline-no"> </span>
|
|
1129
|
+
<span class="cline-any cline-no"> </span>
|
|
1130
|
+
<span class="cline-any cline-no"> </span>
|
|
1131
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1132
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1133
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1134
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1135
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1136
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1137
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1138
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1139
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1140
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1141
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1142
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1143
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1144
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1145
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1146
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1147
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1148
|
+
<span class="cline-any cline-yes">6x</span>
|
|
1149
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1150
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1151
|
+
<span class="cline-any cline-yes">3x</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">2x</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">2x</span>
|
|
1159
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1160
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1161
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1162
|
+
<span class="cline-any cline-yes">47x</span>
|
|
1163
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1164
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1165
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1166
|
+
<span class="cline-any cline-no"> </span>
|
|
1167
|
+
<span class="cline-any cline-no"> </span>
|
|
1168
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1169
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1170
|
+
<span class="cline-any cline-yes">47x</span>
|
|
1171
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1172
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1173
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1174
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1175
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1176
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1177
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1178
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1179
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1180
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1181
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1182
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1183
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1184
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1185
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1186
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1187
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1188
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1189
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1190
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1191
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1192
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1193
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1194
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1195
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1196
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1197
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1198
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1199
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1200
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1201
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1202
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1203
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1204
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1205
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1206
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1207
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1208
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1209
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1210
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1211
|
+
<span class="cline-any cline-no"> </span>
|
|
1212
|
+
<span class="cline-any cline-no"> </span>
|
|
1213
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1214
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1215
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1216
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1217
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1218
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1219
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1220
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1221
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1222
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1223
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1224
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1225
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1226
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1227
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1228
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1229
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1230
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1231
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1232
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1233
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1234
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1235
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1236
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1237
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1238
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1239
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1240
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1241
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1242
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1243
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1244
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1245
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1246
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1247
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1248
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1249
|
+
<span class="cline-any cline-yes">986x</span>
|
|
1250
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1251
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1252
|
+
<span class="cline-any cline-yes">197x</span>
|
|
1253
|
+
<span class="cline-any cline-yes">197x</span>
|
|
1254
|
+
<span class="cline-any cline-yes">197x</span>
|
|
1255
|
+
<span class="cline-any cline-yes">197x</span>
|
|
1256
|
+
<span class="cline-any cline-yes">197x</span>
|
|
1257
|
+
<span class="cline-any cline-yes">197x</span>
|
|
1258
|
+
<span class="cline-any cline-yes">197x</span>
|
|
1259
|
+
<span class="cline-any cline-yes">197x</span>
|
|
1260
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1261
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1262
|
+
<span class="cline-any cline-no"> </span>
|
|
1263
|
+
<span class="cline-any cline-no"> </span>
|
|
1264
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1265
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1266
|
+
<span class="cline-any cline-yes">178x</span>
|
|
1267
|
+
<span class="cline-any cline-yes">178x</span>
|
|
1268
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1269
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1270
|
+
<span class="cline-any cline-yes">486x</span>
|
|
1271
|
+
<span class="cline-any cline-yes">486x</span>
|
|
1272
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1273
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1274
|
+
<span class="cline-any cline-yes">42x</span>
|
|
1275
|
+
<span class="cline-any cline-yes">42x</span>
|
|
1276
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1277
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1278
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1279
|
+
<span class="cline-any cline-yes">15x</span>
|
|
1280
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1281
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1282
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1283
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1284
|
+
<span class="cline-any cline-yes">178x</span>
|
|
1285
|
+
<span class="cline-any cline-yes">178x</span>
|
|
1286
|
+
<span class="cline-any cline-yes">543x</span>
|
|
1287
|
+
<span class="cline-any cline-yes">543x</span>
|
|
1288
|
+
<span class="cline-any cline-yes">543x</span>
|
|
1289
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1290
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1291
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1292
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1293
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1294
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1295
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1296
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1297
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1298
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1299
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1300
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1301
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1302
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1303
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1304
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1305
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1306
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1307
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1308
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1309
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1310
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1311
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1312
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1313
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1314
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1315
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1316
|
+
<span class="cline-any cline-yes">543x</span>
|
|
1317
|
+
<span class="cline-any cline-yes">721x</span>
|
|
1318
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1319
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1320
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1321
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1322
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1323
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1324
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1325
|
+
<span class="cline-any cline-yes">3x</span>
|
|
1326
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1327
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1328
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1329
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1330
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1331
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1332
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1333
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1334
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1335
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1336
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1337
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1338
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1339
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1340
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1341
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1342
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1343
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1344
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1345
|
+
<span class="cline-any cline-yes">501x</span>
|
|
1346
|
+
<span class="cline-any cline-yes">501x</span>
|
|
1347
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1348
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1349
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1350
|
+
<span class="cline-any cline-yes">46x</span>
|
|
1351
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1352
|
+
<span class="cline-any cline-yes">479x</span>
|
|
1353
|
+
<span class="cline-any cline-yes">479x</span>
|
|
1354
|
+
<span class="cline-any cline-yes">525x</span>
|
|
1355
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1356
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1357
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1358
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1359
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1360
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1361
|
+
<span class="cline-any cline-no"> </span>
|
|
1362
|
+
<span class="cline-any cline-no"> </span>
|
|
1363
|
+
<span class="cline-any cline-yes">19x</span>
|
|
1364
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1365
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1366
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1367
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1368
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1369
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1370
|
+
<span class="cline-any cline-yes">279x</span>
|
|
1371
|
+
<span class="cline-any cline-yes">279x</span>
|
|
1372
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1373
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1374
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1375
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1376
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1377
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1378
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1379
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1380
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1381
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1382
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1383
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1384
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1385
|
+
<span class="cline-any cline-yes">782x</span>
|
|
1386
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1387
|
+
<span class="cline-any cline-yes">229x</span>
|
|
1388
|
+
<span class="cline-any cline-yes">229x</span>
|
|
1389
|
+
<span class="cline-any cline-yes">229x</span>
|
|
1390
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1391
|
+
<span class="cline-any cline-yes">48x</span>
|
|
1392
|
+
<span class="cline-any cline-yes">48x</span>
|
|
1393
|
+
<span class="cline-any cline-yes">37x</span>
|
|
1394
|
+
<span class="cline-any cline-yes">37x</span>
|
|
1395
|
+
<span class="cline-any cline-yes">48x</span>
|
|
1396
|
+
<span class="cline-any cline-yes">48x</span>
|
|
1397
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1398
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1399
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1400
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1401
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1402
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1403
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1404
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1405
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1406
|
+
<span class="cline-any cline-no"> </span>
|
|
1407
|
+
<span class="cline-any cline-no"> </span>
|
|
1408
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1409
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1410
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1411
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1412
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1413
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1414
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1415
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1416
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1417
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1418
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1419
|
+
<span class="cline-any cline-yes">76x</span>
|
|
1420
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">/**
|
|
1421
|
+
* Structured logger with SQLite persistence and stdout output.
|
|
1422
|
+
*
|
|
1423
|
+
* - Writes structured entries to a local SQLite DB
|
|
1424
|
+
* - Prints concise lines to stdout/stderr for operator visibility
|
|
1425
|
+
* - Supports filtering and trace retrieval for dashboard APIs
|
|
1426
|
+
*/
|
|
1427
|
+
|
|
1428
|
+
const path = require('path');
|
|
1429
|
+
const fs = require('fs');
|
|
1430
|
+
const crypto = require('crypto');
|
|
1431
|
+
|
|
1432
|
+
function resolveDefaultConfigDir() {
|
|
1433
|
+
return process.env.A2A_CONFIG_DIR ||
|
|
1434
|
+
process.env.OPENCLAW_CONFIG_DIR ||
|
|
1435
|
+
path.join(process.env.HOME <span class="branch-0 cbranch-no" title="branch not covered" >|| '/tmp',</span> '.config', 'openclaw');
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
const LOG_DB_FILENAME = 'a2a-logs.db';
|
|
1439
|
+
const LOG_LEVEL_ORDER = {
|
|
1440
|
+
trace: 10,
|
|
1441
|
+
debug: 20,
|
|
1442
|
+
info: 30,
|
|
1443
|
+
warn: 40,
|
|
1444
|
+
error: 50
|
|
1445
|
+
};
|
|
1446
|
+
|
|
1447
|
+
function envBool(name, fallback = false) {
|
|
1448
|
+
const raw = process.env[name];
|
|
1449
|
+
if (raw === undefined <span class="branch-0 cbranch-no" title="branch not covered" >|| raw === null <span class="branch-0 cbranch-no" title="branch not covered" ></span>|| raw === '')</span> {
|
|
1450
|
+
return fallback;
|
|
1451
|
+
}
|
|
1452
|
+
<span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" > const normalized = String(raw).trim().toLowerCase();</span></span>
|
|
1453
|
+
return !(normalized === '0' || normalized === 'false' <span class="branch-0 cbranch-no" title="branch not covered" >|| normalized === 'no')</span>;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
function normalizeLevel(level) {
|
|
1457
|
+
const normalized = String(level <span class="branch-0 cbranch-no" title="branch not covered" >|| '')</span>.trim().toLowerCase();
|
|
1458
|
+
return LOG_LEVEL_ORDER[normalized] ? normalized <span class="branch-0 cbranch-no" title="branch not covered" >: 'info';</span>
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
function shouldLog(level, minimumLevel) {
|
|
1462
|
+
const current = LOG_LEVEL_ORDER[normalizeLevel(level)] <span class="branch-0 cbranch-no" title="branch not covered" >|| LOG_LEVEL_ORDER.info;</span>
|
|
1463
|
+
const threshold = LOG_LEVEL_ORDER[normalizeLevel(minimumLevel)] <span class="branch-0 cbranch-no" title="branch not covered" >|| LOG_LEVEL_ORDER.info;</span>
|
|
1464
|
+
return current >= threshold;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
function sanitizeText(value, maxLength = 1000) {
|
|
1468
|
+
return String(value <span class="branch-0 cbranch-no" title="branch not covered" >|| '')</span>
|
|
1469
|
+
.replace(/\s+/g, ' ')
|
|
1470
|
+
.trim()
|
|
1471
|
+
.slice(0, maxLength);
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
function serializeError(error, options = {}) {
|
|
1475
|
+
if (!error) return null;
|
|
1476
|
+
if (error instanceof Error) {
|
|
1477
|
+
const payload = {
|
|
1478
|
+
name: error.name <span class="branch-0 cbranch-no" title="branch not covered" >|| 'Error',</span>
|
|
1479
|
+
message: sanitizeText(error.message <span class="branch-0 cbranch-no" title="branch not covered" >|| 'Unknown error',</span> 2000)
|
|
1480
|
+
};
|
|
1481
|
+
if (error.code) payload.code = String(error.code);
|
|
1482
|
+
if (error.cause) <span class="branch-0 cbranch-no" title="branch not covered" >payload.cause = sanitizeText(String(error.cause), 400);</span>
|
|
1483
|
+
if (options.includeStacks && error.stack) {
|
|
1484
|
+
payload.stack = String(error.stack).slice(0, 8000);
|
|
1485
|
+
}
|
|
1486
|
+
return payload;
|
|
1487
|
+
}
|
|
1488
|
+
<span class="cstat-no" title="statement not covered" ><span class="branch-0 cbranch-no" title="branch not covered" > if (typeof error === 'object') {</span></span>
|
|
1489
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1490
|
+
<span class="cstat-no" title="statement not covered" > return JSON.parse(JSON.stringify(error));</span>
|
|
1491
|
+
<span class="cstat-no" title="statement not covered" > } catch (err) {</span>
|
|
1492
|
+
<span class="cstat-no" title="statement not covered" > return { message: sanitizeText(String(error), 2000) };</span>
|
|
1493
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1494
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1495
|
+
<span class="cstat-no" title="statement not covered" > return { message: sanitizeText(String(error), 2000) };</span>
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
function normalizeContext(context = {}, options = {}) {
|
|
1499
|
+
const entry = context && typeof context === 'object' ? { ...context } <span class="branch-0 cbranch-no" title="branch not covered" >: {};</span>
|
|
1500
|
+
const errorDetails = serializeError(entry.error, { includeStacks: options.includeStacks });
|
|
1501
|
+
const baseData = entry.data && typeof entry.data === 'object' ? { ...entry.data } : {};
|
|
1502
|
+
if (errorDetails) {
|
|
1503
|
+
baseData.error = errorDetails;
|
|
1504
|
+
}
|
|
1505
|
+
const hasData = Object.keys(baseData).length > 0;
|
|
1506
|
+
const statusCodeRaw = entry.status_code ?? entry.statusCode;
|
|
1507
|
+
const statusCode = Number.isFinite(Number(statusCodeRaw)) ? Number(statusCodeRaw) : null;
|
|
1508
|
+
const explicitErrorCode = entry.error_code || entry.errorCode || null;
|
|
1509
|
+
const inferredErrorCode = explicitErrorCode || (errorDetails && errorDetails.code <span class="branch-0 cbranch-no" title="branch not covered" >? errorDetails.code </span>: null);
|
|
1510
|
+
return {
|
|
1511
|
+
event: entry.event ? sanitizeText(entry.event, 120) : null,
|
|
1512
|
+
trace_id: entry.trace_id || entry.traceId || null,
|
|
1513
|
+
conversation_id: entry.conversation_id || entry.conversationId || null,
|
|
1514
|
+
token_id: entry.token_id || entry.tokenId || null,
|
|
1515
|
+
request_id: entry.request_id || entry.requestId || null,
|
|
1516
|
+
error_code: inferredErrorCode ? sanitizeText(inferredErrorCode, 120) : null,
|
|
1517
|
+
hint: entry.hint ? sanitizeText(entry.hint, 500) : null,
|
|
1518
|
+
status_code: statusCode,
|
|
1519
|
+
component: entry.component ? sanitizeText(entry.component, 120) : null,
|
|
1520
|
+
data: hasData ? baseData : null
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
class LogStore {
|
|
1525
|
+
constructor(configDir = resolveDefaultConfigDir()) {
|
|
1526
|
+
this.configDir = configDir;
|
|
1527
|
+
this.dbPath = path.join(configDir, LOG_DB_FILENAME);
|
|
1528
|
+
this.db = null;
|
|
1529
|
+
this._dbError = null;
|
|
1530
|
+
this._ensureDir();
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
_ensureDir() {
|
|
1534
|
+
if (!fs.existsSync(this.configDir)) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1535
|
+
<span class="cstat-no" title="statement not covered" > fs.mkdirSync(this.configDir, { recursive: true });</span>
|
|
1536
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
_initDb() {
|
|
1540
|
+
if (this.db) return this.db;
|
|
1541
|
+
if (this._dbError) <span class="branch-0 cbranch-no" title="branch not covered" >return null;</span>
|
|
1542
|
+
|
|
1543
|
+
try {
|
|
1544
|
+
const Database = require('better-sqlite3');
|
|
1545
|
+
this.db = new Database(this.dbPath);
|
|
1546
|
+
try {
|
|
1547
|
+
fs.chmodSync(this.dbPath, 0o600);
|
|
1548
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
|
|
1549
|
+
<span class="cstat-no" title="statement not covered" > // best effort</span>
|
|
1550
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1551
|
+
const ok = this._ensureSchema();
|
|
1552
|
+
if (!ok) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1553
|
+
<span class="cstat-no" title="statement not covered" > // Prototyping mode: do not attempt DB migrations; keep the old file and start fresh.</span>
|
|
1554
|
+
<span class="cstat-no" title="statement not covered" > const backupPath = `${this.dbPath}.legacy.${Date.now()}`;</span>
|
|
1555
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1556
|
+
<span class="cstat-no" title="statement not covered" > this.db.close();</span>
|
|
1557
|
+
<span class="cstat-no" title="statement not covered" > } catch (err) {</span>
|
|
1558
|
+
<span class="cstat-no" title="statement not covered" > // ignore</span>
|
|
1559
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1560
|
+
<span class="cstat-no" title="statement not covered" > fs.renameSync(this.dbPath, backupPath);</span>
|
|
1561
|
+
<span class="cstat-no" title="statement not covered" > this.db = new Database(this.dbPath);</span>
|
|
1562
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1563
|
+
<span class="cstat-no" title="statement not covered" > fs.chmodSync(this.dbPath, 0o600);</span>
|
|
1564
|
+
<span class="cstat-no" title="statement not covered" > } catch (err) {</span>
|
|
1565
|
+
<span class="cstat-no" title="statement not covered" > // best effort</span>
|
|
1566
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1567
|
+
<span class="cstat-no" title="statement not covered" > const ok2 = this._ensureSchema();</span>
|
|
1568
|
+
<span class="cstat-no" title="statement not covered" > if (!ok2) {</span>
|
|
1569
|
+
<span class="cstat-no" title="statement not covered" > this._dbError = 'failed_to_initialize_log_db_schema';</span>
|
|
1570
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1571
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1572
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1573
|
+
this._prepareStatements();
|
|
1574
|
+
return this.db;
|
|
1575
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
|
|
1576
|
+
<span class="cstat-no" title="statement not covered" > this._dbError = err.message || 'failed_to_initialize_log_db';</span>
|
|
1577
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
1578
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
_ensureSchema() {
|
|
1582
|
+
this.db.exec(`
|
|
1583
|
+
PRAGMA journal_mode = WAL;
|
|
1584
|
+
|
|
1585
|
+
CREATE TABLE IF NOT EXISTS logs (
|
|
1586
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1587
|
+
timestamp TEXT NOT NULL,
|
|
1588
|
+
level TEXT NOT NULL,
|
|
1589
|
+
component TEXT NOT NULL,
|
|
1590
|
+
event TEXT,
|
|
1591
|
+
message TEXT NOT NULL,
|
|
1592
|
+
trace_id TEXT,
|
|
1593
|
+
conversation_id TEXT,
|
|
1594
|
+
token_id TEXT,
|
|
1595
|
+
request_id TEXT,
|
|
1596
|
+
error_code TEXT,
|
|
1597
|
+
status_code INTEGER,
|
|
1598
|
+
hint TEXT,
|
|
1599
|
+
data TEXT
|
|
1600
|
+
);
|
|
1601
|
+
|
|
1602
|
+
CREATE INDEX IF NOT EXISTS idx_logs_timestamp ON logs(timestamp DESC);
|
|
1603
|
+
CREATE INDEX IF NOT EXISTS idx_logs_level ON logs(level);
|
|
1604
|
+
CREATE INDEX IF NOT EXISTS idx_logs_component ON logs(component);
|
|
1605
|
+
CREATE INDEX IF NOT EXISTS idx_logs_trace ON logs(trace_id);
|
|
1606
|
+
CREATE INDEX IF NOT EXISTS idx_logs_conversation ON logs(conversation_id);
|
|
1607
|
+
CREATE INDEX IF NOT EXISTS idx_logs_token ON logs(token_id);
|
|
1608
|
+
CREATE INDEX IF NOT EXISTS idx_logs_error_code ON logs(error_code);
|
|
1609
|
+
`);
|
|
1610
|
+
|
|
1611
|
+
const columns = this.db.prepare(`PRAGMA table_info(logs)`).all();
|
|
1612
|
+
const names = new Set(columns.map(c => c && c.name).filter(Boolean));
|
|
1613
|
+
const required = ['timestamp', 'level', 'component', 'message', 'error_code', 'status_code', 'hint', 'data'];
|
|
1614
|
+
return required.every((name) => names.has(name));
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
_prepareStatements() {
|
|
1618
|
+
this.insertStmt = this.db.prepare(`
|
|
1619
|
+
INSERT INTO logs (
|
|
1620
|
+
timestamp, level, component, event, message,
|
|
1621
|
+
trace_id, conversation_id, token_id, request_id, error_code, status_code, hint, data
|
|
1622
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1623
|
+
`);
|
|
1624
|
+
// A2A-64: Prepared statement for time-based retention pruning
|
|
1625
|
+
this.pruneStmt = this.db.prepare('DELETE FROM logs WHERE timestamp < ?');
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
<span class="fstat-no" title="function not covered" > isAvailable() {</span>
|
|
1629
|
+
<span class="cstat-no" title="statement not covered" > return this._initDb() !== null;</span>
|
|
1630
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1631
|
+
|
|
1632
|
+
<span class="fstat-no" title="function not covered" > getError() {</span>
|
|
1633
|
+
<span class="cstat-no" title="statement not covered" > this._initDb();</span>
|
|
1634
|
+
<span class="cstat-no" title="statement not covered" > return this._dbError;</span>
|
|
1635
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1636
|
+
|
|
1637
|
+
write(entry) {
|
|
1638
|
+
const db = this._initDb();
|
|
1639
|
+
if (!db) <span class="branch-0 cbranch-no" title="branch not covered" >return false;</span>
|
|
1640
|
+
const dataText = entry.data ? JSON.stringify(entry.data) : null;
|
|
1641
|
+
try {
|
|
1642
|
+
this.insertStmt.run(
|
|
1643
|
+
entry.timestamp,
|
|
1644
|
+
entry.level,
|
|
1645
|
+
entry.component,
|
|
1646
|
+
entry.event,
|
|
1647
|
+
entry.message,
|
|
1648
|
+
entry.trace_id,
|
|
1649
|
+
entry.conversation_id,
|
|
1650
|
+
entry.token_id,
|
|
1651
|
+
entry.request_id,
|
|
1652
|
+
entry.error_code,
|
|
1653
|
+
entry.status_code,
|
|
1654
|
+
entry.hint,
|
|
1655
|
+
dataText
|
|
1656
|
+
);
|
|
1657
|
+
|
|
1658
|
+
// A2A-64: Auto-prune on every 1000th write (dashboard-events.js pattern).
|
|
1659
|
+
// Best effort — prune failures must not affect write operations.
|
|
1660
|
+
this._writeCount = (this._writeCount || 0) + 1;
|
|
1661
|
+
if (this._writeCount % 1000 === 0 && !this._pruning) {
|
|
1662
|
+
try {
|
|
1663
|
+
const threshold = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
1664
|
+
this.pruneStmt.run(threshold);
|
|
1665
|
+
} catch (_) {
|
|
1666
|
+
// A2A-64: Best effort — silent catch like dashboard-events.js:149
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
return true;
|
|
1671
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
|
|
1672
|
+
<span class="cstat-no" title="statement not covered" > this._dbError = err.message || 'failed_to_write_log_entry';</span>
|
|
1673
|
+
<span class="cstat-no" title="statement not covered" > return false;</span>
|
|
1674
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
list(options = {}) {
|
|
1678
|
+
const db = this._initDb();
|
|
1679
|
+
if (!db) <span class="branch-0 cbranch-no" title="branch not covered" >return [];</span>
|
|
1680
|
+
|
|
1681
|
+
const limit = Math.min(1000, Math.max(1, Number.parseInt(options.limit <span class="branch-0 cbranch-no" title="branch not covered" >|| '200',</span> 10) <span class="branch-0 cbranch-no" title="branch not covered" >|| 200)</span>);
|
|
1682
|
+
const where = [];
|
|
1683
|
+
const params = [];
|
|
1684
|
+
|
|
1685
|
+
if (options.level) {
|
|
1686
|
+
where.push('level = ?');
|
|
1687
|
+
params.push(normalizeLevel(options.level));
|
|
1688
|
+
}
|
|
1689
|
+
if (options.component) {
|
|
1690
|
+
where.push('component = ?');
|
|
1691
|
+
params.push(String(options.component));
|
|
1692
|
+
}
|
|
1693
|
+
if (options.event) {
|
|
1694
|
+
where.push('event = ?');
|
|
1695
|
+
params.push(String(options.event));
|
|
1696
|
+
}
|
|
1697
|
+
if (options.errorCode) {
|
|
1698
|
+
where.push('error_code = ?');
|
|
1699
|
+
params.push(String(options.errorCode));
|
|
1700
|
+
}
|
|
1701
|
+
if (options.statusCode !== undefined && options.statusCode !== null && options.statusCode !== '') {
|
|
1702
|
+
where.push('status_code = ?');
|
|
1703
|
+
params.push(Number(options.statusCode));
|
|
1704
|
+
}
|
|
1705
|
+
if (options.traceId) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1706
|
+
<span class="cstat-no" title="statement not covered" > where.push('trace_id = ?');</span>
|
|
1707
|
+
<span class="cstat-no" title="statement not covered" > params.push(String(options.traceId));</span>
|
|
1708
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1709
|
+
if (options.conversationId) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1710
|
+
<span class="cstat-no" title="statement not covered" > where.push('conversation_id = ?');</span>
|
|
1711
|
+
<span class="cstat-no" title="statement not covered" > params.push(String(options.conversationId));</span>
|
|
1712
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1713
|
+
if (options.tokenId) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1714
|
+
<span class="cstat-no" title="statement not covered" > where.push('token_id = ?');</span>
|
|
1715
|
+
<span class="cstat-no" title="statement not covered" > params.push(String(options.tokenId));</span>
|
|
1716
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1717
|
+
if (options.from) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1718
|
+
<span class="cstat-no" title="statement not covered" > where.push('timestamp >= ?');</span>
|
|
1719
|
+
<span class="cstat-no" title="statement not covered" > params.push(String(options.from));</span>
|
|
1720
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1721
|
+
if (options.to) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1722
|
+
<span class="cstat-no" title="statement not covered" > where.push('timestamp <= ?');</span>
|
|
1723
|
+
<span class="cstat-no" title="statement not covered" > params.push(String(options.to));</span>
|
|
1724
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1725
|
+
if (options.search) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1726
|
+
<span class="cstat-no" title="statement not covered" > where.push('(message LIKE ? OR data LIKE ?)');</span>
|
|
1727
|
+
<span class="cstat-no" title="statement not covered" > const like = `%${String(options.search).replace(/%/g, '')}%`;</span>
|
|
1728
|
+
<span class="cstat-no" title="statement not covered" > params.push(like, like);</span>
|
|
1729
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1730
|
+
|
|
1731
|
+
const query = `
|
|
1732
|
+
SELECT id, timestamp, level, component, event, message,
|
|
1733
|
+
trace_id, conversation_id, token_id, request_id, error_code, status_code, hint, data
|
|
1734
|
+
FROM logs
|
|
1735
|
+
${where.length ? `WHERE ${where.join(' AND ')}` : ''}
|
|
1736
|
+
ORDER BY id DESC
|
|
1737
|
+
LIMIT ?
|
|
1738
|
+
`;
|
|
1739
|
+
params.push(limit);
|
|
1740
|
+
|
|
1741
|
+
return db.prepare(query).all(...params).map(row => ({
|
|
1742
|
+
id: row.id,
|
|
1743
|
+
timestamp: row.timestamp,
|
|
1744
|
+
level: row.level,
|
|
1745
|
+
component: row.component,
|
|
1746
|
+
event: row.event,
|
|
1747
|
+
message: row.message,
|
|
1748
|
+
trace_id: row.trace_id,
|
|
1749
|
+
conversation_id: row.conversation_id,
|
|
1750
|
+
token_id: row.token_id,
|
|
1751
|
+
request_id: row.request_id,
|
|
1752
|
+
error_code: row.error_code,
|
|
1753
|
+
status_code: row.status_code,
|
|
1754
|
+
hint: row.hint,
|
|
1755
|
+
data: row.data ? safeJsonParse(row.data) <span class="branch-0 cbranch-no" title="branch not covered" >: null</span>
|
|
1756
|
+
}));
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
getTrace(traceId, options = {}) {
|
|
1760
|
+
const db = this._initDb();
|
|
1761
|
+
if (!db || !traceId) <span class="branch-0 cbranch-no" title="branch not covered" >return [];</span>
|
|
1762
|
+
const limit = Math.min(1000, Math.max(1, Number.parseInt(options.limit <span class="branch-0 cbranch-no" title="branch not covered" >|| '500',</span> 10) <span class="branch-0 cbranch-no" title="branch not covered" >|| 500)</span>);
|
|
1763
|
+
return db.prepare(`
|
|
1764
|
+
SELECT id, timestamp, level, component, event, message,
|
|
1765
|
+
trace_id, conversation_id, token_id, request_id, error_code, status_code, hint, data
|
|
1766
|
+
FROM logs
|
|
1767
|
+
WHERE trace_id = ?
|
|
1768
|
+
ORDER BY id ASC
|
|
1769
|
+
LIMIT ?
|
|
1770
|
+
`).all(String(traceId), limit).map(row => ({
|
|
1771
|
+
id: row.id,
|
|
1772
|
+
timestamp: row.timestamp,
|
|
1773
|
+
level: row.level,
|
|
1774
|
+
component: row.component,
|
|
1775
|
+
event: row.event,
|
|
1776
|
+
message: row.message,
|
|
1777
|
+
trace_id: row.trace_id,
|
|
1778
|
+
conversation_id: row.conversation_id,
|
|
1779
|
+
token_id: row.token_id,
|
|
1780
|
+
request_id: row.request_id,
|
|
1781
|
+
error_code: row.error_code,
|
|
1782
|
+
status_code: row.status_code,
|
|
1783
|
+
hint: row.hint,
|
|
1784
|
+
data: row.data ? safeJsonParse(row.data) <span class="branch-0 cbranch-no" title="branch not covered" >: null</span>
|
|
1785
|
+
}));
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
stats(options = {}) {
|
|
1789
|
+
const db = this._initDb();
|
|
1790
|
+
if (!db) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1791
|
+
<span class="cstat-no" title="statement not covered" > return {</span>
|
|
1792
|
+
<span class="cstat-no" title="statement not covered" > total: 0,</span>
|
|
1793
|
+
<span class="cstat-no" title="statement not covered" > by_level: {},</span>
|
|
1794
|
+
<span class="cstat-no" title="statement not covered" > by_component: {}</span>
|
|
1795
|
+
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1796
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1797
|
+
|
|
1798
|
+
const where = [];
|
|
1799
|
+
const params = [];
|
|
1800
|
+
if (options.from) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1801
|
+
<span class="cstat-no" title="statement not covered" > where.push('timestamp >= ?');</span>
|
|
1802
|
+
<span class="cstat-no" title="statement not covered" > params.push(String(options.from));</span>
|
|
1803
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1804
|
+
if (options.to) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
|
|
1805
|
+
<span class="cstat-no" title="statement not covered" > where.push('timestamp <= ?');</span>
|
|
1806
|
+
<span class="cstat-no" title="statement not covered" > params.push(String(options.to));</span>
|
|
1807
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1808
|
+
const clause = where.length <span class="branch-0 cbranch-no" title="branch not covered" >? `WHERE ${where.join(' AND ')}` </span>: '';
|
|
1809
|
+
|
|
1810
|
+
const totalRow = db.prepare(`SELECT COUNT(*) AS count FROM logs ${clause}`).get(...params);
|
|
1811
|
+
const levelRows = db.prepare(`
|
|
1812
|
+
SELECT level, COUNT(*) AS count
|
|
1813
|
+
FROM logs ${clause}
|
|
1814
|
+
GROUP BY level
|
|
1815
|
+
`).all(...params);
|
|
1816
|
+
const componentRows = db.prepare(`
|
|
1817
|
+
SELECT component, COUNT(*) AS count
|
|
1818
|
+
FROM logs ${clause}
|
|
1819
|
+
GROUP BY component
|
|
1820
|
+
`).all(...params);
|
|
1821
|
+
|
|
1822
|
+
const byLevel = {};
|
|
1823
|
+
for (const row of levelRows) {
|
|
1824
|
+
byLevel[row.level] = row.count;
|
|
1825
|
+
}
|
|
1826
|
+
const byComponent = {};
|
|
1827
|
+
for (const row of componentRows) {
|
|
1828
|
+
byComponent[row.component] = row.count;
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
return {
|
|
1832
|
+
total: totalRow?.count <span class="branch-0 cbranch-no" title="branch not covered" >|| 0,</span>
|
|
1833
|
+
by_level: byLevel,
|
|
1834
|
+
by_component: byComponent
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
close() {
|
|
1839
|
+
if (this.db) {
|
|
1840
|
+
try {
|
|
1841
|
+
this.db.close();
|
|
1842
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
|
|
1843
|
+
<span class="cstat-no" title="statement not covered" > // best effort</span>
|
|
1844
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1845
|
+
this.db = null;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
/**
|
|
1850
|
+
* A2A-64: Delete log entries older than the retention period.
|
|
1851
|
+
*
|
|
1852
|
+
* @param {object} [options]
|
|
1853
|
+
* @param {number} [options.days=30] - Retention period in days
|
|
1854
|
+
* @returns {{ deleted: number }}
|
|
1855
|
+
*/
|
|
1856
|
+
pruneOld(options = {}) {
|
|
1857
|
+
const db = this._initDb();
|
|
1858
|
+
if (!db) <span class="branch-0 cbranch-no" title="branch not covered" >return { deleted: 0 };</span>
|
|
1859
|
+
|
|
1860
|
+
const days = Number.isFinite(options.days) ? options.days : 30;
|
|
1861
|
+
const threshold = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
1862
|
+
|
|
1863
|
+
// A2A-64: Set _pruning flag to prevent auto-prune recursion if the
|
|
1864
|
+
// cleanup logger writes back to this same store.
|
|
1865
|
+
this._pruning = true;
|
|
1866
|
+
let deleted = 0;
|
|
1867
|
+
try {
|
|
1868
|
+
const result = this.pruneStmt.run(threshold);
|
|
1869
|
+
deleted = result.changes;
|
|
1870
|
+
|
|
1871
|
+
// A2A-64: Only VACUUM after bulk deletions (>100 rows) to avoid unnecessary I/O
|
|
1872
|
+
if (deleted > 100) {
|
|
1873
|
+
db.exec('VACUUM');
|
|
1874
|
+
}
|
|
1875
|
+
} finally {
|
|
1876
|
+
this._pruning = false;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
// A2A-64: Log prune results AFTER prune completes to avoid recursion.
|
|
1880
|
+
// Use a Logger instance with stdout:false for the cleanup component.
|
|
1881
|
+
try {
|
|
1882
|
+
const cleanupLogger = new Logger(this, { component: 'a2a.cleanup', stdout: true, minLevel: 'info' });
|
|
1883
|
+
cleanupLogger.info(`Pruned ${deleted} log entries older than ${days} days`, {
|
|
1884
|
+
event: 'logs_pruned',
|
|
1885
|
+
data: { deleted, days, threshold }
|
|
1886
|
+
});
|
|
1887
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (_) {</span>
|
|
1888
|
+
<span class="cstat-no" title="statement not covered" > // A2A-64: Best effort — logging about prune results must not throw</span>
|
|
1889
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1890
|
+
|
|
1891
|
+
return { deleted };
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
/**
|
|
1895
|
+
* A2A-64: Return database-level stats for monitoring.
|
|
1896
|
+
* Complements the existing stats() method which provides level/component breakdowns.
|
|
1897
|
+
*
|
|
1898
|
+
* @returns {{ total: number, oldest_entry: string|null, newest_entry: string|null }}
|
|
1899
|
+
*/
|
|
1900
|
+
getDatabaseStats() {
|
|
1901
|
+
const db = this._initDb();
|
|
1902
|
+
if (!db) <span class="branch-0 cbranch-no" title="branch not covered" >return { total: 0, oldest_entry: null, newest_entry: null };</span>
|
|
1903
|
+
|
|
1904
|
+
const row = db.prepare(
|
|
1905
|
+
'SELECT COUNT(*) AS total, MIN(timestamp) AS oldest, MAX(timestamp) AS newest FROM logs'
|
|
1906
|
+
).get();
|
|
1907
|
+
|
|
1908
|
+
return {
|
|
1909
|
+
total: row?.total || 0,
|
|
1910
|
+
oldest_entry: row?.oldest || null,
|
|
1911
|
+
newest_entry: row?.newest || null
|
|
1912
|
+
};
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
class Logger {
|
|
1917
|
+
constructor(store, options = {}) {
|
|
1918
|
+
this.store = store;
|
|
1919
|
+
this.component = options.component <span class="branch-0 cbranch-no" title="branch not covered" >|| 'a2a';</span>
|
|
1920
|
+
this.bindings = options.bindings || {};
|
|
1921
|
+
this.stdout = options.stdout !== false;
|
|
1922
|
+
this.minLevel = normalizeLevel(options.minLevel || process.env.A2A_LOG_LEVEL || 'info');
|
|
1923
|
+
this.includeStacks = options.includeStacks !== undefined
|
|
1924
|
+
? Boolean(options.includeStacks)
|
|
1925
|
+
: envBool('A2A_LOG_STACKS', process.env.NODE_ENV !== 'production');
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
child(bindings = {}) {
|
|
1929
|
+
return new Logger(this.store, {
|
|
1930
|
+
component: bindings.component || this.component,
|
|
1931
|
+
bindings: { ...this.bindings, ...bindings },
|
|
1932
|
+
stdout: this.stdout,
|
|
1933
|
+
minLevel: this.minLevel,
|
|
1934
|
+
includeStacks: this.includeStacks
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
<span class="fstat-no" title="function not covered" > trace(message, context = {}) {</span>
|
|
1939
|
+
<span class="cstat-no" title="statement not covered" > return this.log('trace', message, context);</span>
|
|
1940
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1941
|
+
|
|
1942
|
+
debug(message, context = {}) {
|
|
1943
|
+
return this.log('debug', message, context);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
info(message, context = {}) {
|
|
1947
|
+
return this.log('info', message, context);
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
warn(message, context = {}) {
|
|
1951
|
+
return this.log('warn', message, context);
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
error(message, context = {}) {
|
|
1955
|
+
return this.log('error', message, context);
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
log(level, message, context = {}) {
|
|
1959
|
+
const normalizedLevel = normalizeLevel(level);
|
|
1960
|
+
if (!shouldLog(normalizedLevel, this.minLevel)) {
|
|
1961
|
+
return null;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
const now = new Date().toISOString();
|
|
1965
|
+
const mergedContext = {
|
|
1966
|
+
...(this.bindings <span class="branch-0 cbranch-no" title="branch not covered" >|| {})</span>,
|
|
1967
|
+
...(context <span class="branch-0 cbranch-no" title="branch not covered" >|| {})</span>
|
|
1968
|
+
};
|
|
1969
|
+
const normalized = normalizeContext(mergedContext, {
|
|
1970
|
+
includeStacks: this.includeStacks
|
|
1971
|
+
});
|
|
1972
|
+
|
|
1973
|
+
const entry = {
|
|
1974
|
+
timestamp: now,
|
|
1975
|
+
level: normalizedLevel,
|
|
1976
|
+
component: normalized.component || this.component <span class="branch-0 cbranch-no" title="branch not covered" >|| 'a2a',</span>
|
|
1977
|
+
event: normalized.event,
|
|
1978
|
+
message: sanitizeText(message, 2000) <span class="branch-0 cbranch-no" title="branch not covered" >|| '(empty)',</span>
|
|
1979
|
+
trace_id: normalized.trace_id ? String(normalized.trace_id) : null,
|
|
1980
|
+
conversation_id: normalized.conversation_id ? String(normalized.conversation_id) : null,
|
|
1981
|
+
token_id: normalized.token_id ? String(normalized.token_id) : null,
|
|
1982
|
+
request_id: normalized.request_id ? String(normalized.request_id) : null,
|
|
1983
|
+
error_code: normalized.error_code,
|
|
1984
|
+
status_code: normalized.status_code,
|
|
1985
|
+
hint: normalized.hint,
|
|
1986
|
+
data: normalized.data
|
|
1987
|
+
};
|
|
1988
|
+
|
|
1989
|
+
this.store.write(entry);
|
|
1990
|
+
if (this.stdout) {
|
|
1991
|
+
this._print(entry);
|
|
1992
|
+
}
|
|
1993
|
+
return entry;
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
list(options = {}) {
|
|
1997
|
+
return this.store.list(options);
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
getTrace(traceId, options = {}) {
|
|
2001
|
+
return this.store.getTrace(traceId, options);
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
stats(options = {}) {
|
|
2005
|
+
return this.store.stats(options);
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
_print(entry) {
|
|
2009
|
+
const parts = [
|
|
2010
|
+
`[a2a]`,
|
|
2011
|
+
entry.level.toUpperCase(),
|
|
2012
|
+
`${entry.component}${entry.event ? `:${entry.event}` <span class="branch-0 cbranch-no" title="branch not covered" >: ''}</span>`,
|
|
2013
|
+
entry.message
|
|
2014
|
+
];
|
|
2015
|
+
if (entry.trace_id) parts.push(`trace=${entry.trace_id}`);
|
|
2016
|
+
if (entry.conversation_id) parts.push(`conv=${entry.conversation_id}`);
|
|
2017
|
+
if (entry.token_id) parts.push(`tok=${entry.token_id}`);
|
|
2018
|
+
if (entry.request_id) parts.push(`req=${entry.request_id}`);
|
|
2019
|
+
if (entry.error_code) parts.push(`code=${entry.error_code}`);
|
|
2020
|
+
if (entry.status_code !== null && entry.status_code !== undefined) parts.push(`status=${entry.status_code}`);
|
|
2021
|
+
if (entry.data && Object.keys(entry.data).length > 0) {
|
|
2022
|
+
parts.push(`data=${JSON.stringify(entry.data)}`);
|
|
2023
|
+
}
|
|
2024
|
+
if (entry.hint) parts.push(`hint=${entry.hint}`);
|
|
2025
|
+
const line = parts.join(' ');
|
|
2026
|
+
if (entry.level === 'error' || entry.level === 'warn') {
|
|
2027
|
+
console.error(line);
|
|
2028
|
+
} else {
|
|
2029
|
+
console.log(line);
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
function safeJsonParse(value) {
|
|
2035
|
+
try {
|
|
2036
|
+
return JSON.parse(value);
|
|
2037
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (err) {</span>
|
|
2038
|
+
<span class="cstat-no" title="statement not covered" > return null;</span>
|
|
2039
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
const storeCache = new Map();
|
|
2043
|
+
|
|
2044
|
+
function getStore(configDir) {
|
|
2045
|
+
const resolved = path.resolve(configDir);
|
|
2046
|
+
if (!storeCache.has(resolved)) {
|
|
2047
|
+
storeCache.set(resolved, new LogStore(resolved));
|
|
2048
|
+
}
|
|
2049
|
+
return storeCache.get(resolved);
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
function createLogger(options = {}) {
|
|
2053
|
+
const configDir = options.configDir || resolveDefaultConfigDir();
|
|
2054
|
+
const store = getStore(configDir);
|
|
2055
|
+
return new Logger(store, {
|
|
2056
|
+
component: options.component <span class="branch-0 cbranch-no" title="branch not covered" >|| 'a2a',</span>
|
|
2057
|
+
bindings: options.bindings || {},
|
|
2058
|
+
stdout: options.stdout !== false,
|
|
2059
|
+
minLevel: options.minLevel,
|
|
2060
|
+
includeStacks: options.includeStacks
|
|
2061
|
+
});
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
function createTraceId(prefix = 'trace') {
|
|
2065
|
+
return `${prefix}_${crypto.randomBytes(8).toString('hex')}`;
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
function closeAllLoggerStores() {
|
|
2069
|
+
for (const store of storeCache.values()) {
|
|
2070
|
+
store.close();
|
|
2071
|
+
}
|
|
2072
|
+
storeCache.clear();
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
// A2A-65: Prune old entries from all cached logger stores.
|
|
2076
|
+
// Best effort — individual store failures are caught and logged.
|
|
2077
|
+
function pruneAllLoggerStores(options = {}) {
|
|
2078
|
+
const results = [];
|
|
2079
|
+
for (const store of storeCache.values()) {
|
|
2080
|
+
try {
|
|
2081
|
+
results.push(store.pruneOld(options));
|
|
2082
|
+
} <span class="branch-0 cbranch-no" title="branch not covered" >catch (_) {</span>
|
|
2083
|
+
<span class="cstat-no" title="statement not covered" > // A2A-65: Best effort — one store failure must not block others</span>
|
|
2084
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
2085
|
+
}
|
|
2086
|
+
return results;
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
module.exports = {
|
|
2090
|
+
LOG_DB_FILENAME,
|
|
2091
|
+
LogStore,
|
|
2092
|
+
createLogger,
|
|
2093
|
+
createTraceId,
|
|
2094
|
+
closeAllLoggerStores,
|
|
2095
|
+
pruneAllLoggerStores
|
|
2096
|
+
};
|
|
2097
|
+
</pre></td></tr></table></pre>
|
|
2098
|
+
|
|
2099
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
2100
|
+
</div><!-- /wrapper -->
|
|
2101
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
2102
|
+
Code coverage generated by
|
|
2103
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
2104
|
+
at 2026-03-03T22:25:10.857Z
|
|
2105
|
+
</div>
|
|
2106
|
+
<script src="../../prettify.js"></script>
|
|
2107
|
+
<script>
|
|
2108
|
+
window.onload = function () {
|
|
2109
|
+
prettyPrint();
|
|
2110
|
+
};
|
|
2111
|
+
</script>
|
|
2112
|
+
<script src="../../sorter.js"></script>
|
|
2113
|
+
<script src="../../block-navigation.js"></script>
|
|
2114
|
+
</body>
|
|
2115
|
+
</html>
|
|
2116
|
+
|