@bernierllc/email-domain-verification 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.eslintrc.cjs +29 -0
  2. package/README.md +397 -0
  3. package/__mocks__/@bernierllc/crypto-utils.ts +15 -0
  4. package/__mocks__/@bernierllc/logger.ts +42 -0
  5. package/__mocks__/@bernierllc/neverhub-adapter.ts +17 -0
  6. package/__tests__/EmailDomainVerificationService.test.ts +582 -0
  7. package/coverage/clover.xml +263 -0
  8. package/coverage/coverage-final.json +3 -0
  9. package/coverage/lcov-report/EmailDomainVerificationService.ts.html +3061 -0
  10. package/coverage/lcov-report/base.css +224 -0
  11. package/coverage/lcov-report/block-navigation.js +87 -0
  12. package/coverage/lcov-report/errors.ts.html +322 -0
  13. package/coverage/lcov-report/favicon.png +0 -0
  14. package/coverage/lcov-report/index.html +131 -0
  15. package/coverage/lcov-report/prettify.css +1 -0
  16. package/coverage/lcov-report/prettify.js +2 -0
  17. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  18. package/coverage/lcov-report/sorter.js +210 -0
  19. package/coverage/lcov.info +485 -0
  20. package/dist/EmailDomainVerificationService.d.ts +179 -0
  21. package/dist/EmailDomainVerificationService.js +822 -0
  22. package/dist/errors.d.ts +39 -0
  23. package/dist/errors.js +66 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.js +28 -0
  26. package/dist/types.d.ts +209 -0
  27. package/dist/types.js +9 -0
  28. package/jest.config.cjs +44 -0
  29. package/jest.setup.js +19 -0
  30. package/package.json +72 -0
  31. package/src/EmailDomainVerificationService.ts +992 -0
  32. package/src/dns2.d.ts +29 -0
  33. package/src/errors.ts +79 -0
  34. package/src/index.ts +11 -0
  35. package/src/types.ts +281 -0
  36. package/tsconfig.json +30 -0
@@ -0,0 +1,3061 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for EmailDomainVerificationService.ts</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> EmailDomainVerificationService.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">72.68% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>173/238</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">51.4% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>55/107</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">79.16% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>38/48</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">73.27% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>170/232</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>
744
+ <a name='L679'></a><a href='#L679'>679</a>
745
+ <a name='L680'></a><a href='#L680'>680</a>
746
+ <a name='L681'></a><a href='#L681'>681</a>
747
+ <a name='L682'></a><a href='#L682'>682</a>
748
+ <a name='L683'></a><a href='#L683'>683</a>
749
+ <a name='L684'></a><a href='#L684'>684</a>
750
+ <a name='L685'></a><a href='#L685'>685</a>
751
+ <a name='L686'></a><a href='#L686'>686</a>
752
+ <a name='L687'></a><a href='#L687'>687</a>
753
+ <a name='L688'></a><a href='#L688'>688</a>
754
+ <a name='L689'></a><a href='#L689'>689</a>
755
+ <a name='L690'></a><a href='#L690'>690</a>
756
+ <a name='L691'></a><a href='#L691'>691</a>
757
+ <a name='L692'></a><a href='#L692'>692</a>
758
+ <a name='L693'></a><a href='#L693'>693</a>
759
+ <a name='L694'></a><a href='#L694'>694</a>
760
+ <a name='L695'></a><a href='#L695'>695</a>
761
+ <a name='L696'></a><a href='#L696'>696</a>
762
+ <a name='L697'></a><a href='#L697'>697</a>
763
+ <a name='L698'></a><a href='#L698'>698</a>
764
+ <a name='L699'></a><a href='#L699'>699</a>
765
+ <a name='L700'></a><a href='#L700'>700</a>
766
+ <a name='L701'></a><a href='#L701'>701</a>
767
+ <a name='L702'></a><a href='#L702'>702</a>
768
+ <a name='L703'></a><a href='#L703'>703</a>
769
+ <a name='L704'></a><a href='#L704'>704</a>
770
+ <a name='L705'></a><a href='#L705'>705</a>
771
+ <a name='L706'></a><a href='#L706'>706</a>
772
+ <a name='L707'></a><a href='#L707'>707</a>
773
+ <a name='L708'></a><a href='#L708'>708</a>
774
+ <a name='L709'></a><a href='#L709'>709</a>
775
+ <a name='L710'></a><a href='#L710'>710</a>
776
+ <a name='L711'></a><a href='#L711'>711</a>
777
+ <a name='L712'></a><a href='#L712'>712</a>
778
+ <a name='L713'></a><a href='#L713'>713</a>
779
+ <a name='L714'></a><a href='#L714'>714</a>
780
+ <a name='L715'></a><a href='#L715'>715</a>
781
+ <a name='L716'></a><a href='#L716'>716</a>
782
+ <a name='L717'></a><a href='#L717'>717</a>
783
+ <a name='L718'></a><a href='#L718'>718</a>
784
+ <a name='L719'></a><a href='#L719'>719</a>
785
+ <a name='L720'></a><a href='#L720'>720</a>
786
+ <a name='L721'></a><a href='#L721'>721</a>
787
+ <a name='L722'></a><a href='#L722'>722</a>
788
+ <a name='L723'></a><a href='#L723'>723</a>
789
+ <a name='L724'></a><a href='#L724'>724</a>
790
+ <a name='L725'></a><a href='#L725'>725</a>
791
+ <a name='L726'></a><a href='#L726'>726</a>
792
+ <a name='L727'></a><a href='#L727'>727</a>
793
+ <a name='L728'></a><a href='#L728'>728</a>
794
+ <a name='L729'></a><a href='#L729'>729</a>
795
+ <a name='L730'></a><a href='#L730'>730</a>
796
+ <a name='L731'></a><a href='#L731'>731</a>
797
+ <a name='L732'></a><a href='#L732'>732</a>
798
+ <a name='L733'></a><a href='#L733'>733</a>
799
+ <a name='L734'></a><a href='#L734'>734</a>
800
+ <a name='L735'></a><a href='#L735'>735</a>
801
+ <a name='L736'></a><a href='#L736'>736</a>
802
+ <a name='L737'></a><a href='#L737'>737</a>
803
+ <a name='L738'></a><a href='#L738'>738</a>
804
+ <a name='L739'></a><a href='#L739'>739</a>
805
+ <a name='L740'></a><a href='#L740'>740</a>
806
+ <a name='L741'></a><a href='#L741'>741</a>
807
+ <a name='L742'></a><a href='#L742'>742</a>
808
+ <a name='L743'></a><a href='#L743'>743</a>
809
+ <a name='L744'></a><a href='#L744'>744</a>
810
+ <a name='L745'></a><a href='#L745'>745</a>
811
+ <a name='L746'></a><a href='#L746'>746</a>
812
+ <a name='L747'></a><a href='#L747'>747</a>
813
+ <a name='L748'></a><a href='#L748'>748</a>
814
+ <a name='L749'></a><a href='#L749'>749</a>
815
+ <a name='L750'></a><a href='#L750'>750</a>
816
+ <a name='L751'></a><a href='#L751'>751</a>
817
+ <a name='L752'></a><a href='#L752'>752</a>
818
+ <a name='L753'></a><a href='#L753'>753</a>
819
+ <a name='L754'></a><a href='#L754'>754</a>
820
+ <a name='L755'></a><a href='#L755'>755</a>
821
+ <a name='L756'></a><a href='#L756'>756</a>
822
+ <a name='L757'></a><a href='#L757'>757</a>
823
+ <a name='L758'></a><a href='#L758'>758</a>
824
+ <a name='L759'></a><a href='#L759'>759</a>
825
+ <a name='L760'></a><a href='#L760'>760</a>
826
+ <a name='L761'></a><a href='#L761'>761</a>
827
+ <a name='L762'></a><a href='#L762'>762</a>
828
+ <a name='L763'></a><a href='#L763'>763</a>
829
+ <a name='L764'></a><a href='#L764'>764</a>
830
+ <a name='L765'></a><a href='#L765'>765</a>
831
+ <a name='L766'></a><a href='#L766'>766</a>
832
+ <a name='L767'></a><a href='#L767'>767</a>
833
+ <a name='L768'></a><a href='#L768'>768</a>
834
+ <a name='L769'></a><a href='#L769'>769</a>
835
+ <a name='L770'></a><a href='#L770'>770</a>
836
+ <a name='L771'></a><a href='#L771'>771</a>
837
+ <a name='L772'></a><a href='#L772'>772</a>
838
+ <a name='L773'></a><a href='#L773'>773</a>
839
+ <a name='L774'></a><a href='#L774'>774</a>
840
+ <a name='L775'></a><a href='#L775'>775</a>
841
+ <a name='L776'></a><a href='#L776'>776</a>
842
+ <a name='L777'></a><a href='#L777'>777</a>
843
+ <a name='L778'></a><a href='#L778'>778</a>
844
+ <a name='L779'></a><a href='#L779'>779</a>
845
+ <a name='L780'></a><a href='#L780'>780</a>
846
+ <a name='L781'></a><a href='#L781'>781</a>
847
+ <a name='L782'></a><a href='#L782'>782</a>
848
+ <a name='L783'></a><a href='#L783'>783</a>
849
+ <a name='L784'></a><a href='#L784'>784</a>
850
+ <a name='L785'></a><a href='#L785'>785</a>
851
+ <a name='L786'></a><a href='#L786'>786</a>
852
+ <a name='L787'></a><a href='#L787'>787</a>
853
+ <a name='L788'></a><a href='#L788'>788</a>
854
+ <a name='L789'></a><a href='#L789'>789</a>
855
+ <a name='L790'></a><a href='#L790'>790</a>
856
+ <a name='L791'></a><a href='#L791'>791</a>
857
+ <a name='L792'></a><a href='#L792'>792</a>
858
+ <a name='L793'></a><a href='#L793'>793</a>
859
+ <a name='L794'></a><a href='#L794'>794</a>
860
+ <a name='L795'></a><a href='#L795'>795</a>
861
+ <a name='L796'></a><a href='#L796'>796</a>
862
+ <a name='L797'></a><a href='#L797'>797</a>
863
+ <a name='L798'></a><a href='#L798'>798</a>
864
+ <a name='L799'></a><a href='#L799'>799</a>
865
+ <a name='L800'></a><a href='#L800'>800</a>
866
+ <a name='L801'></a><a href='#L801'>801</a>
867
+ <a name='L802'></a><a href='#L802'>802</a>
868
+ <a name='L803'></a><a href='#L803'>803</a>
869
+ <a name='L804'></a><a href='#L804'>804</a>
870
+ <a name='L805'></a><a href='#L805'>805</a>
871
+ <a name='L806'></a><a href='#L806'>806</a>
872
+ <a name='L807'></a><a href='#L807'>807</a>
873
+ <a name='L808'></a><a href='#L808'>808</a>
874
+ <a name='L809'></a><a href='#L809'>809</a>
875
+ <a name='L810'></a><a href='#L810'>810</a>
876
+ <a name='L811'></a><a href='#L811'>811</a>
877
+ <a name='L812'></a><a href='#L812'>812</a>
878
+ <a name='L813'></a><a href='#L813'>813</a>
879
+ <a name='L814'></a><a href='#L814'>814</a>
880
+ <a name='L815'></a><a href='#L815'>815</a>
881
+ <a name='L816'></a><a href='#L816'>816</a>
882
+ <a name='L817'></a><a href='#L817'>817</a>
883
+ <a name='L818'></a><a href='#L818'>818</a>
884
+ <a name='L819'></a><a href='#L819'>819</a>
885
+ <a name='L820'></a><a href='#L820'>820</a>
886
+ <a name='L821'></a><a href='#L821'>821</a>
887
+ <a name='L822'></a><a href='#L822'>822</a>
888
+ <a name='L823'></a><a href='#L823'>823</a>
889
+ <a name='L824'></a><a href='#L824'>824</a>
890
+ <a name='L825'></a><a href='#L825'>825</a>
891
+ <a name='L826'></a><a href='#L826'>826</a>
892
+ <a name='L827'></a><a href='#L827'>827</a>
893
+ <a name='L828'></a><a href='#L828'>828</a>
894
+ <a name='L829'></a><a href='#L829'>829</a>
895
+ <a name='L830'></a><a href='#L830'>830</a>
896
+ <a name='L831'></a><a href='#L831'>831</a>
897
+ <a name='L832'></a><a href='#L832'>832</a>
898
+ <a name='L833'></a><a href='#L833'>833</a>
899
+ <a name='L834'></a><a href='#L834'>834</a>
900
+ <a name='L835'></a><a href='#L835'>835</a>
901
+ <a name='L836'></a><a href='#L836'>836</a>
902
+ <a name='L837'></a><a href='#L837'>837</a>
903
+ <a name='L838'></a><a href='#L838'>838</a>
904
+ <a name='L839'></a><a href='#L839'>839</a>
905
+ <a name='L840'></a><a href='#L840'>840</a>
906
+ <a name='L841'></a><a href='#L841'>841</a>
907
+ <a name='L842'></a><a href='#L842'>842</a>
908
+ <a name='L843'></a><a href='#L843'>843</a>
909
+ <a name='L844'></a><a href='#L844'>844</a>
910
+ <a name='L845'></a><a href='#L845'>845</a>
911
+ <a name='L846'></a><a href='#L846'>846</a>
912
+ <a name='L847'></a><a href='#L847'>847</a>
913
+ <a name='L848'></a><a href='#L848'>848</a>
914
+ <a name='L849'></a><a href='#L849'>849</a>
915
+ <a name='L850'></a><a href='#L850'>850</a>
916
+ <a name='L851'></a><a href='#L851'>851</a>
917
+ <a name='L852'></a><a href='#L852'>852</a>
918
+ <a name='L853'></a><a href='#L853'>853</a>
919
+ <a name='L854'></a><a href='#L854'>854</a>
920
+ <a name='L855'></a><a href='#L855'>855</a>
921
+ <a name='L856'></a><a href='#L856'>856</a>
922
+ <a name='L857'></a><a href='#L857'>857</a>
923
+ <a name='L858'></a><a href='#L858'>858</a>
924
+ <a name='L859'></a><a href='#L859'>859</a>
925
+ <a name='L860'></a><a href='#L860'>860</a>
926
+ <a name='L861'></a><a href='#L861'>861</a>
927
+ <a name='L862'></a><a href='#L862'>862</a>
928
+ <a name='L863'></a><a href='#L863'>863</a>
929
+ <a name='L864'></a><a href='#L864'>864</a>
930
+ <a name='L865'></a><a href='#L865'>865</a>
931
+ <a name='L866'></a><a href='#L866'>866</a>
932
+ <a name='L867'></a><a href='#L867'>867</a>
933
+ <a name='L868'></a><a href='#L868'>868</a>
934
+ <a name='L869'></a><a href='#L869'>869</a>
935
+ <a name='L870'></a><a href='#L870'>870</a>
936
+ <a name='L871'></a><a href='#L871'>871</a>
937
+ <a name='L872'></a><a href='#L872'>872</a>
938
+ <a name='L873'></a><a href='#L873'>873</a>
939
+ <a name='L874'></a><a href='#L874'>874</a>
940
+ <a name='L875'></a><a href='#L875'>875</a>
941
+ <a name='L876'></a><a href='#L876'>876</a>
942
+ <a name='L877'></a><a href='#L877'>877</a>
943
+ <a name='L878'></a><a href='#L878'>878</a>
944
+ <a name='L879'></a><a href='#L879'>879</a>
945
+ <a name='L880'></a><a href='#L880'>880</a>
946
+ <a name='L881'></a><a href='#L881'>881</a>
947
+ <a name='L882'></a><a href='#L882'>882</a>
948
+ <a name='L883'></a><a href='#L883'>883</a>
949
+ <a name='L884'></a><a href='#L884'>884</a>
950
+ <a name='L885'></a><a href='#L885'>885</a>
951
+ <a name='L886'></a><a href='#L886'>886</a>
952
+ <a name='L887'></a><a href='#L887'>887</a>
953
+ <a name='L888'></a><a href='#L888'>888</a>
954
+ <a name='L889'></a><a href='#L889'>889</a>
955
+ <a name='L890'></a><a href='#L890'>890</a>
956
+ <a name='L891'></a><a href='#L891'>891</a>
957
+ <a name='L892'></a><a href='#L892'>892</a>
958
+ <a name='L893'></a><a href='#L893'>893</a>
959
+ <a name='L894'></a><a href='#L894'>894</a>
960
+ <a name='L895'></a><a href='#L895'>895</a>
961
+ <a name='L896'></a><a href='#L896'>896</a>
962
+ <a name='L897'></a><a href='#L897'>897</a>
963
+ <a name='L898'></a><a href='#L898'>898</a>
964
+ <a name='L899'></a><a href='#L899'>899</a>
965
+ <a name='L900'></a><a href='#L900'>900</a>
966
+ <a name='L901'></a><a href='#L901'>901</a>
967
+ <a name='L902'></a><a href='#L902'>902</a>
968
+ <a name='L903'></a><a href='#L903'>903</a>
969
+ <a name='L904'></a><a href='#L904'>904</a>
970
+ <a name='L905'></a><a href='#L905'>905</a>
971
+ <a name='L906'></a><a href='#L906'>906</a>
972
+ <a name='L907'></a><a href='#L907'>907</a>
973
+ <a name='L908'></a><a href='#L908'>908</a>
974
+ <a name='L909'></a><a href='#L909'>909</a>
975
+ <a name='L910'></a><a href='#L910'>910</a>
976
+ <a name='L911'></a><a href='#L911'>911</a>
977
+ <a name='L912'></a><a href='#L912'>912</a>
978
+ <a name='L913'></a><a href='#L913'>913</a>
979
+ <a name='L914'></a><a href='#L914'>914</a>
980
+ <a name='L915'></a><a href='#L915'>915</a>
981
+ <a name='L916'></a><a href='#L916'>916</a>
982
+ <a name='L917'></a><a href='#L917'>917</a>
983
+ <a name='L918'></a><a href='#L918'>918</a>
984
+ <a name='L919'></a><a href='#L919'>919</a>
985
+ <a name='L920'></a><a href='#L920'>920</a>
986
+ <a name='L921'></a><a href='#L921'>921</a>
987
+ <a name='L922'></a><a href='#L922'>922</a>
988
+ <a name='L923'></a><a href='#L923'>923</a>
989
+ <a name='L924'></a><a href='#L924'>924</a>
990
+ <a name='L925'></a><a href='#L925'>925</a>
991
+ <a name='L926'></a><a href='#L926'>926</a>
992
+ <a name='L927'></a><a href='#L927'>927</a>
993
+ <a name='L928'></a><a href='#L928'>928</a>
994
+ <a name='L929'></a><a href='#L929'>929</a>
995
+ <a name='L930'></a><a href='#L930'>930</a>
996
+ <a name='L931'></a><a href='#L931'>931</a>
997
+ <a name='L932'></a><a href='#L932'>932</a>
998
+ <a name='L933'></a><a href='#L933'>933</a>
999
+ <a name='L934'></a><a href='#L934'>934</a>
1000
+ <a name='L935'></a><a href='#L935'>935</a>
1001
+ <a name='L936'></a><a href='#L936'>936</a>
1002
+ <a name='L937'></a><a href='#L937'>937</a>
1003
+ <a name='L938'></a><a href='#L938'>938</a>
1004
+ <a name='L939'></a><a href='#L939'>939</a>
1005
+ <a name='L940'></a><a href='#L940'>940</a>
1006
+ <a name='L941'></a><a href='#L941'>941</a>
1007
+ <a name='L942'></a><a href='#L942'>942</a>
1008
+ <a name='L943'></a><a href='#L943'>943</a>
1009
+ <a name='L944'></a><a href='#L944'>944</a>
1010
+ <a name='L945'></a><a href='#L945'>945</a>
1011
+ <a name='L946'></a><a href='#L946'>946</a>
1012
+ <a name='L947'></a><a href='#L947'>947</a>
1013
+ <a name='L948'></a><a href='#L948'>948</a>
1014
+ <a name='L949'></a><a href='#L949'>949</a>
1015
+ <a name='L950'></a><a href='#L950'>950</a>
1016
+ <a name='L951'></a><a href='#L951'>951</a>
1017
+ <a name='L952'></a><a href='#L952'>952</a>
1018
+ <a name='L953'></a><a href='#L953'>953</a>
1019
+ <a name='L954'></a><a href='#L954'>954</a>
1020
+ <a name='L955'></a><a href='#L955'>955</a>
1021
+ <a name='L956'></a><a href='#L956'>956</a>
1022
+ <a name='L957'></a><a href='#L957'>957</a>
1023
+ <a name='L958'></a><a href='#L958'>958</a>
1024
+ <a name='L959'></a><a href='#L959'>959</a>
1025
+ <a name='L960'></a><a href='#L960'>960</a>
1026
+ <a name='L961'></a><a href='#L961'>961</a>
1027
+ <a name='L962'></a><a href='#L962'>962</a>
1028
+ <a name='L963'></a><a href='#L963'>963</a>
1029
+ <a name='L964'></a><a href='#L964'>964</a>
1030
+ <a name='L965'></a><a href='#L965'>965</a>
1031
+ <a name='L966'></a><a href='#L966'>966</a>
1032
+ <a name='L967'></a><a href='#L967'>967</a>
1033
+ <a name='L968'></a><a href='#L968'>968</a>
1034
+ <a name='L969'></a><a href='#L969'>969</a>
1035
+ <a name='L970'></a><a href='#L970'>970</a>
1036
+ <a name='L971'></a><a href='#L971'>971</a>
1037
+ <a name='L972'></a><a href='#L972'>972</a>
1038
+ <a name='L973'></a><a href='#L973'>973</a>
1039
+ <a name='L974'></a><a href='#L974'>974</a>
1040
+ <a name='L975'></a><a href='#L975'>975</a>
1041
+ <a name='L976'></a><a href='#L976'>976</a>
1042
+ <a name='L977'></a><a href='#L977'>977</a>
1043
+ <a name='L978'></a><a href='#L978'>978</a>
1044
+ <a name='L979'></a><a href='#L979'>979</a>
1045
+ <a name='L980'></a><a href='#L980'>980</a>
1046
+ <a name='L981'></a><a href='#L981'>981</a>
1047
+ <a name='L982'></a><a href='#L982'>982</a>
1048
+ <a name='L983'></a><a href='#L983'>983</a>
1049
+ <a name='L984'></a><a href='#L984'>984</a>
1050
+ <a name='L985'></a><a href='#L985'>985</a>
1051
+ <a name='L986'></a><a href='#L986'>986</a>
1052
+ <a name='L987'></a><a href='#L987'>987</a>
1053
+ <a name='L988'></a><a href='#L988'>988</a>
1054
+ <a name='L989'></a><a href='#L989'>989</a>
1055
+ <a name='L990'></a><a href='#L990'>990</a>
1056
+ <a name='L991'></a><a href='#L991'>991</a>
1057
+ <a name='L992'></a><a href='#L992'>992</a>
1058
+ <a name='L993'></a><a href='#L993'>993</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
1059
+ <span class="cline-any cline-neutral">&nbsp;</span>
1060
+ <span class="cline-any cline-neutral">&nbsp;</span>
1061
+ <span class="cline-any cline-neutral">&nbsp;</span>
1062
+ <span class="cline-any cline-neutral">&nbsp;</span>
1063
+ <span class="cline-any cline-neutral">&nbsp;</span>
1064
+ <span class="cline-any cline-neutral">&nbsp;</span>
1065
+ <span class="cline-any cline-neutral">&nbsp;</span>
1066
+ <span class="cline-any cline-yes">1x</span>
1067
+ <span class="cline-any cline-yes">1x</span>
1068
+ <span class="cline-any cline-yes">1x</span>
1069
+ <span class="cline-any cline-yes">1x</span>
1070
+ <span class="cline-any cline-yes">1x</span>
1071
+ <span class="cline-any cline-yes">1x</span>
1072
+ <span class="cline-any cline-yes">1x</span>
1073
+ <span class="cline-any cline-neutral">&nbsp;</span>
1074
+ <span class="cline-any cline-neutral">&nbsp;</span>
1075
+ <span class="cline-any cline-neutral">&nbsp;</span>
1076
+ <span class="cline-any cline-neutral">&nbsp;</span>
1077
+ <span class="cline-any cline-neutral">&nbsp;</span>
1078
+ <span class="cline-any cline-neutral">&nbsp;</span>
1079
+ <span class="cline-any cline-neutral">&nbsp;</span>
1080
+ <span class="cline-any cline-neutral">&nbsp;</span>
1081
+ <span class="cline-any cline-neutral">&nbsp;</span>
1082
+ <span class="cline-any cline-neutral">&nbsp;</span>
1083
+ <span class="cline-any cline-neutral">&nbsp;</span>
1084
+ <span class="cline-any cline-yes">1x</span>
1085
+ <span class="cline-any cline-neutral">&nbsp;</span>
1086
+ <span class="cline-any cline-neutral">&nbsp;</span>
1087
+ <span class="cline-any cline-neutral">&nbsp;</span>
1088
+ <span class="cline-any cline-neutral">&nbsp;</span>
1089
+ <span class="cline-any cline-neutral">&nbsp;</span>
1090
+ <span class="cline-any cline-neutral">&nbsp;</span>
1091
+ <span class="cline-any cline-neutral">&nbsp;</span>
1092
+ <span class="cline-any cline-yes">1x</span>
1093
+ <span class="cline-any cline-neutral">&nbsp;</span>
1094
+ <span class="cline-any cline-neutral">&nbsp;</span>
1095
+ <span class="cline-any cline-neutral">&nbsp;</span>
1096
+ <span class="cline-any cline-neutral">&nbsp;</span>
1097
+ <span class="cline-any cline-neutral">&nbsp;</span>
1098
+ <span class="cline-any cline-neutral">&nbsp;</span>
1099
+ <span class="cline-any cline-neutral">&nbsp;</span>
1100
+ <span class="cline-any cline-neutral">&nbsp;</span>
1101
+ <span class="cline-any cline-neutral">&nbsp;</span>
1102
+ <span class="cline-any cline-neutral">&nbsp;</span>
1103
+ <span class="cline-any cline-neutral">&nbsp;</span>
1104
+ <span class="cline-any cline-yes">29x</span>
1105
+ <span class="cline-any cline-neutral">&nbsp;</span>
1106
+ <span class="cline-any cline-neutral">&nbsp;</span>
1107
+ <span class="cline-any cline-neutral">&nbsp;</span>
1108
+ <span class="cline-any cline-yes">29x</span>
1109
+ <span class="cline-any cline-yes">29x</span>
1110
+ <span class="cline-any cline-neutral">&nbsp;</span>
1111
+ <span class="cline-any cline-neutral">&nbsp;</span>
1112
+ <span class="cline-any cline-neutral">&nbsp;</span>
1113
+ <span class="cline-any cline-yes">29x</span>
1114
+ <span class="cline-any cline-yes">29x</span>
1115
+ <span class="cline-any cline-neutral">&nbsp;</span>
1116
+ <span class="cline-any cline-neutral">&nbsp;</span>
1117
+ <span class="cline-any cline-neutral">&nbsp;</span>
1118
+ <span class="cline-any cline-neutral">&nbsp;</span>
1119
+ <span class="cline-any cline-neutral">&nbsp;</span>
1120
+ <span class="cline-any cline-neutral">&nbsp;</span>
1121
+ <span class="cline-any cline-no">&nbsp;</span>
1122
+ <span class="cline-any cline-no">&nbsp;</span>
1123
+ <span class="cline-any cline-no">&nbsp;</span>
1124
+ <span class="cline-any cline-neutral">&nbsp;</span>
1125
+ <span class="cline-any cline-neutral">&nbsp;</span>
1126
+ <span class="cline-any cline-no">&nbsp;</span>
1127
+ <span class="cline-any cline-neutral">&nbsp;</span>
1128
+ <span class="cline-any cline-neutral">&nbsp;</span>
1129
+ <span class="cline-any cline-neutral">&nbsp;</span>
1130
+ <span class="cline-any cline-neutral">&nbsp;</span>
1131
+ <span class="cline-any cline-neutral">&nbsp;</span>
1132
+ <span class="cline-any cline-neutral">&nbsp;</span>
1133
+ <span class="cline-any cline-neutral">&nbsp;</span>
1134
+ <span class="cline-any cline-neutral">&nbsp;</span>
1135
+ <span class="cline-any cline-neutral">&nbsp;</span>
1136
+ <span class="cline-any cline-neutral">&nbsp;</span>
1137
+ <span class="cline-any cline-neutral">&nbsp;</span>
1138
+ <span class="cline-any cline-yes">23x</span>
1139
+ <span class="cline-any cline-neutral">&nbsp;</span>
1140
+ <span class="cline-any cline-neutral">&nbsp;</span>
1141
+ <span class="cline-any cline-neutral">&nbsp;</span>
1142
+ <span class="cline-any cline-neutral">&nbsp;</span>
1143
+ <span class="cline-any cline-yes">23x</span>
1144
+ <span class="cline-any cline-neutral">&nbsp;</span>
1145
+ <span class="cline-any cline-yes">23x</span>
1146
+ <span class="cline-any cline-neutral">&nbsp;</span>
1147
+ <span class="cline-any cline-neutral">&nbsp;</span>
1148
+ <span class="cline-any cline-yes">22x</span>
1149
+ <span class="cline-any cline-neutral">&nbsp;</span>
1150
+ <span class="cline-any cline-neutral">&nbsp;</span>
1151
+ <span class="cline-any cline-neutral">&nbsp;</span>
1152
+ <span class="cline-any cline-yes">22x</span>
1153
+ <span class="cline-any cline-yes">1x</span>
1154
+ <span class="cline-any cline-yes">1x</span>
1155
+ <span class="cline-any cline-neutral">&nbsp;</span>
1156
+ <span class="cline-any cline-neutral">&nbsp;</span>
1157
+ <span class="cline-any cline-neutral">&nbsp;</span>
1158
+ <span class="cline-any cline-yes">22x</span>
1159
+ <span class="cline-any cline-neutral">&nbsp;</span>
1160
+ <span class="cline-any cline-neutral">&nbsp;</span>
1161
+ <span class="cline-any cline-yes">22x</span>
1162
+ <span class="cline-any cline-neutral">&nbsp;</span>
1163
+ <span class="cline-any cline-neutral">&nbsp;</span>
1164
+ <span class="cline-any cline-neutral">&nbsp;</span>
1165
+ <span class="cline-any cline-neutral">&nbsp;</span>
1166
+ <span class="cline-any cline-neutral">&nbsp;</span>
1167
+ <span class="cline-any cline-neutral">&nbsp;</span>
1168
+ <span class="cline-any cline-yes">22x</span>
1169
+ <span class="cline-any cline-neutral">&nbsp;</span>
1170
+ <span class="cline-any cline-neutral">&nbsp;</span>
1171
+ <span class="cline-any cline-neutral">&nbsp;</span>
1172
+ <span class="cline-any cline-neutral">&nbsp;</span>
1173
+ <span class="cline-any cline-neutral">&nbsp;</span>
1174
+ <span class="cline-any cline-yes">22x</span>
1175
+ <span class="cline-any cline-neutral">&nbsp;</span>
1176
+ <span class="cline-any cline-neutral">&nbsp;</span>
1177
+ <span class="cline-any cline-neutral">&nbsp;</span>
1178
+ <span class="cline-any cline-neutral">&nbsp;</span>
1179
+ <span class="cline-any cline-neutral">&nbsp;</span>
1180
+ <span class="cline-any cline-neutral">&nbsp;</span>
1181
+ <span class="cline-any cline-neutral">&nbsp;</span>
1182
+ <span class="cline-any cline-neutral">&nbsp;</span>
1183
+ <span class="cline-any cline-neutral">&nbsp;</span>
1184
+ <span class="cline-any cline-neutral">&nbsp;</span>
1185
+ <span class="cline-any cline-neutral">&nbsp;</span>
1186
+ <span class="cline-any cline-neutral">&nbsp;</span>
1187
+ <span class="cline-any cline-neutral">&nbsp;</span>
1188
+ <span class="cline-any cline-neutral">&nbsp;</span>
1189
+ <span class="cline-any cline-neutral">&nbsp;</span>
1190
+ <span class="cline-any cline-yes">1x</span>
1191
+ <span class="cline-any cline-yes">1x</span>
1192
+ <span class="cline-any cline-neutral">&nbsp;</span>
1193
+ <span class="cline-any cline-yes">1x</span>
1194
+ <span class="cline-any cline-neutral">&nbsp;</span>
1195
+ <span class="cline-any cline-neutral">&nbsp;</span>
1196
+ <span class="cline-any cline-neutral">&nbsp;</span>
1197
+ <span class="cline-any cline-neutral">&nbsp;</span>
1198
+ <span class="cline-any cline-neutral">&nbsp;</span>
1199
+ <span class="cline-any cline-neutral">&nbsp;</span>
1200
+ <span class="cline-any cline-neutral">&nbsp;</span>
1201
+ <span class="cline-any cline-neutral">&nbsp;</span>
1202
+ <span class="cline-any cline-neutral">&nbsp;</span>
1203
+ <span class="cline-any cline-neutral">&nbsp;</span>
1204
+ <span class="cline-any cline-neutral">&nbsp;</span>
1205
+ <span class="cline-any cline-neutral">&nbsp;</span>
1206
+ <span class="cline-any cline-neutral">&nbsp;</span>
1207
+ <span class="cline-any cline-neutral">&nbsp;</span>
1208
+ <span class="cline-any cline-neutral">&nbsp;</span>
1209
+ <span class="cline-any cline-neutral">&nbsp;</span>
1210
+ <span class="cline-any cline-neutral">&nbsp;</span>
1211
+ <span class="cline-any cline-neutral">&nbsp;</span>
1212
+ <span class="cline-any cline-neutral">&nbsp;</span>
1213
+ <span class="cline-any cline-neutral">&nbsp;</span>
1214
+ <span class="cline-any cline-yes">3x</span>
1215
+ <span class="cline-any cline-neutral">&nbsp;</span>
1216
+ <span class="cline-any cline-neutral">&nbsp;</span>
1217
+ <span class="cline-any cline-neutral">&nbsp;</span>
1218
+ <span class="cline-any cline-neutral">&nbsp;</span>
1219
+ <span class="cline-any cline-yes">3x</span>
1220
+ <span class="cline-any cline-neutral">&nbsp;</span>
1221
+ <span class="cline-any cline-yes">3x</span>
1222
+ <span class="cline-any cline-yes">4x</span>
1223
+ <span class="cline-any cline-yes">4x</span>
1224
+ <span class="cline-any cline-yes">4x</span>
1225
+ <span class="cline-any cline-neutral">&nbsp;</span>
1226
+ <span class="cline-any cline-yes">4x</span>
1227
+ <span class="cline-any cline-yes">2x</span>
1228
+ <span class="cline-any cline-neutral">&nbsp;</span>
1229
+ <span class="cline-any cline-neutral">&nbsp;</span>
1230
+ <span class="cline-any cline-neutral">&nbsp;</span>
1231
+ <span class="cline-any cline-neutral">&nbsp;</span>
1232
+ <span class="cline-any cline-neutral">&nbsp;</span>
1233
+ <span class="cline-any cline-yes">2x</span>
1234
+ <span class="cline-any cline-neutral">&nbsp;</span>
1235
+ <span class="cline-any cline-neutral">&nbsp;</span>
1236
+ <span class="cline-any cline-neutral">&nbsp;</span>
1237
+ <span class="cline-any cline-neutral">&nbsp;</span>
1238
+ <span class="cline-any cline-neutral">&nbsp;</span>
1239
+ <span class="cline-any cline-neutral">&nbsp;</span>
1240
+ <span class="cline-any cline-neutral">&nbsp;</span>
1241
+ <span class="cline-any cline-no">&nbsp;</span>
1242
+ <span class="cline-any cline-no">&nbsp;</span>
1243
+ <span class="cline-any cline-neutral">&nbsp;</span>
1244
+ <span class="cline-any cline-no">&nbsp;</span>
1245
+ <span class="cline-any cline-neutral">&nbsp;</span>
1246
+ <span class="cline-any cline-neutral">&nbsp;</span>
1247
+ <span class="cline-any cline-neutral">&nbsp;</span>
1248
+ <span class="cline-any cline-neutral">&nbsp;</span>
1249
+ <span class="cline-any cline-neutral">&nbsp;</span>
1250
+ <span class="cline-any cline-neutral">&nbsp;</span>
1251
+ <span class="cline-any cline-neutral">&nbsp;</span>
1252
+ <span class="cline-any cline-neutral">&nbsp;</span>
1253
+ <span class="cline-any cline-neutral">&nbsp;</span>
1254
+ <span class="cline-any cline-neutral">&nbsp;</span>
1255
+ <span class="cline-any cline-neutral">&nbsp;</span>
1256
+ <span class="cline-any cline-neutral">&nbsp;</span>
1257
+ <span class="cline-any cline-neutral">&nbsp;</span>
1258
+ <span class="cline-any cline-yes">4x</span>
1259
+ <span class="cline-any cline-yes">3x</span>
1260
+ <span class="cline-any cline-neutral">&nbsp;</span>
1261
+ <span class="cline-any cline-neutral">&nbsp;</span>
1262
+ <span class="cline-any cline-neutral">&nbsp;</span>
1263
+ <span class="cline-any cline-yes">4x</span>
1264
+ <span class="cline-any cline-neutral">&nbsp;</span>
1265
+ <span class="cline-any cline-neutral">&nbsp;</span>
1266
+ <span class="cline-any cline-yes">3x</span>
1267
+ <span class="cline-any cline-neutral">&nbsp;</span>
1268
+ <span class="cline-any cline-neutral">&nbsp;</span>
1269
+ <span class="cline-any cline-neutral">&nbsp;</span>
1270
+ <span class="cline-any cline-neutral">&nbsp;</span>
1271
+ <span class="cline-any cline-neutral">&nbsp;</span>
1272
+ <span class="cline-any cline-neutral">&nbsp;</span>
1273
+ <span class="cline-any cline-neutral">&nbsp;</span>
1274
+ <span class="cline-any cline-neutral">&nbsp;</span>
1275
+ <span class="cline-any cline-neutral">&nbsp;</span>
1276
+ <span class="cline-any cline-neutral">&nbsp;</span>
1277
+ <span class="cline-any cline-neutral">&nbsp;</span>
1278
+ <span class="cline-any cline-neutral">&nbsp;</span>
1279
+ <span class="cline-any cline-neutral">&nbsp;</span>
1280
+ <span class="cline-any cline-neutral">&nbsp;</span>
1281
+ <span class="cline-any cline-neutral">&nbsp;</span>
1282
+ <span class="cline-any cline-yes">8x</span>
1283
+ <span class="cline-any cline-neutral">&nbsp;</span>
1284
+ <span class="cline-any cline-yes">8x</span>
1285
+ <span class="cline-any cline-yes">8x</span>
1286
+ <span class="cline-any cline-neutral">&nbsp;</span>
1287
+ <span class="cline-any cline-yes">8x</span>
1288
+ <span class="cline-any cline-yes">8x</span>
1289
+ <span class="cline-any cline-neutral">&nbsp;</span>
1290
+ <span class="cline-any cline-yes">8x</span>
1291
+ <span class="cline-any cline-neutral">&nbsp;</span>
1292
+ <span class="cline-any cline-neutral">&nbsp;</span>
1293
+ <span class="cline-any cline-neutral">&nbsp;</span>
1294
+ <span class="cline-any cline-neutral">&nbsp;</span>
1295
+ <span class="cline-any cline-neutral">&nbsp;</span>
1296
+ <span class="cline-any cline-neutral">&nbsp;</span>
1297
+ <span class="cline-any cline-yes">8x</span>
1298
+ <span class="cline-any cline-neutral">&nbsp;</span>
1299
+ <span class="cline-any cline-neutral">&nbsp;</span>
1300
+ <span class="cline-any cline-neutral">&nbsp;</span>
1301
+ <span class="cline-any cline-neutral">&nbsp;</span>
1302
+ <span class="cline-any cline-neutral">&nbsp;</span>
1303
+ <span class="cline-any cline-neutral">&nbsp;</span>
1304
+ <span class="cline-any cline-neutral">&nbsp;</span>
1305
+ <span class="cline-any cline-yes">8x</span>
1306
+ <span class="cline-any cline-yes">7x</span>
1307
+ <span class="cline-any cline-neutral">&nbsp;</span>
1308
+ <span class="cline-any cline-neutral">&nbsp;</span>
1309
+ <span class="cline-any cline-yes">8x</span>
1310
+ <span class="cline-any cline-yes">8x</span>
1311
+ <span class="cline-any cline-neutral">&nbsp;</span>
1312
+ <span class="cline-any cline-neutral">&nbsp;</span>
1313
+ <span class="cline-any cline-neutral">&nbsp;</span>
1314
+ <span class="cline-any cline-neutral">&nbsp;</span>
1315
+ <span class="cline-any cline-neutral">&nbsp;</span>
1316
+ <span class="cline-any cline-neutral">&nbsp;</span>
1317
+ <span class="cline-any cline-neutral">&nbsp;</span>
1318
+ <span class="cline-any cline-neutral">&nbsp;</span>
1319
+ <span class="cline-any cline-no">&nbsp;</span>
1320
+ <span class="cline-any cline-no">&nbsp;</span>
1321
+ <span class="cline-any cline-neutral">&nbsp;</span>
1322
+ <span class="cline-any cline-no">&nbsp;</span>
1323
+ <span class="cline-any cline-neutral">&nbsp;</span>
1324
+ <span class="cline-any cline-neutral">&nbsp;</span>
1325
+ <span class="cline-any cline-neutral">&nbsp;</span>
1326
+ <span class="cline-any cline-neutral">&nbsp;</span>
1327
+ <span class="cline-any cline-neutral">&nbsp;</span>
1328
+ <span class="cline-any cline-neutral">&nbsp;</span>
1329
+ <span class="cline-any cline-neutral">&nbsp;</span>
1330
+ <span class="cline-any cline-neutral">&nbsp;</span>
1331
+ <span class="cline-any cline-neutral">&nbsp;</span>
1332
+ <span class="cline-any cline-neutral">&nbsp;</span>
1333
+ <span class="cline-any cline-neutral">&nbsp;</span>
1334
+ <span class="cline-any cline-neutral">&nbsp;</span>
1335
+ <span class="cline-any cline-neutral">&nbsp;</span>
1336
+ <span class="cline-any cline-neutral">&nbsp;</span>
1337
+ <span class="cline-any cline-neutral">&nbsp;</span>
1338
+ <span class="cline-any cline-neutral">&nbsp;</span>
1339
+ <span class="cline-any cline-yes">1x</span>
1340
+ <span class="cline-any cline-neutral">&nbsp;</span>
1341
+ <span class="cline-any cline-neutral">&nbsp;</span>
1342
+ <span class="cline-any cline-neutral">&nbsp;</span>
1343
+ <span class="cline-any cline-yes">1x</span>
1344
+ <span class="cline-any cline-neutral">&nbsp;</span>
1345
+ <span class="cline-any cline-neutral">&nbsp;</span>
1346
+ <span class="cline-any cline-neutral">&nbsp;</span>
1347
+ <span class="cline-any cline-neutral">&nbsp;</span>
1348
+ <span class="cline-any cline-neutral">&nbsp;</span>
1349
+ <span class="cline-any cline-neutral">&nbsp;</span>
1350
+ <span class="cline-any cline-neutral">&nbsp;</span>
1351
+ <span class="cline-any cline-neutral">&nbsp;</span>
1352
+ <span class="cline-any cline-neutral">&nbsp;</span>
1353
+ <span class="cline-any cline-neutral">&nbsp;</span>
1354
+ <span class="cline-any cline-neutral">&nbsp;</span>
1355
+ <span class="cline-any cline-neutral">&nbsp;</span>
1356
+ <span class="cline-any cline-neutral">&nbsp;</span>
1357
+ <span class="cline-any cline-neutral">&nbsp;</span>
1358
+ <span class="cline-any cline-neutral">&nbsp;</span>
1359
+ <span class="cline-any cline-neutral">&nbsp;</span>
1360
+ <span class="cline-any cline-yes">3x</span>
1361
+ <span class="cline-any cline-yes">3x</span>
1362
+ <span class="cline-any cline-neutral">&nbsp;</span>
1363
+ <span class="cline-any cline-neutral">&nbsp;</span>
1364
+ <span class="cline-any cline-neutral">&nbsp;</span>
1365
+ <span class="cline-any cline-neutral">&nbsp;</span>
1366
+ <span class="cline-any cline-neutral">&nbsp;</span>
1367
+ <span class="cline-any cline-neutral">&nbsp;</span>
1368
+ <span class="cline-any cline-neutral">&nbsp;</span>
1369
+ <span class="cline-any cline-neutral">&nbsp;</span>
1370
+ <span class="cline-any cline-neutral">&nbsp;</span>
1371
+ <span class="cline-any cline-neutral">&nbsp;</span>
1372
+ <span class="cline-any cline-neutral">&nbsp;</span>
1373
+ <span class="cline-any cline-neutral">&nbsp;</span>
1374
+ <span class="cline-any cline-neutral">&nbsp;</span>
1375
+ <span class="cline-any cline-neutral">&nbsp;</span>
1376
+ <span class="cline-any cline-neutral">&nbsp;</span>
1377
+ <span class="cline-any cline-yes">7x</span>
1378
+ <span class="cline-any cline-neutral">&nbsp;</span>
1379
+ <span class="cline-any cline-neutral">&nbsp;</span>
1380
+ <span class="cline-any cline-yes">7x</span>
1381
+ <span class="cline-any cline-no">&nbsp;</span>
1382
+ <span class="cline-any cline-no">&nbsp;</span>
1383
+ <span class="cline-any cline-neutral">&nbsp;</span>
1384
+ <span class="cline-any cline-no">&nbsp;</span>
1385
+ <span class="cline-any cline-no">&nbsp;</span>
1386
+ <span class="cline-any cline-neutral">&nbsp;</span>
1387
+ <span class="cline-any cline-no">&nbsp;</span>
1388
+ <span class="cline-any cline-neutral">&nbsp;</span>
1389
+ <span class="cline-any cline-neutral">&nbsp;</span>
1390
+ <span class="cline-any cline-neutral">&nbsp;</span>
1391
+ <span class="cline-any cline-neutral">&nbsp;</span>
1392
+ <span class="cline-any cline-neutral">&nbsp;</span>
1393
+ <span class="cline-any cline-neutral">&nbsp;</span>
1394
+ <span class="cline-any cline-no">&nbsp;</span>
1395
+ <span class="cline-any cline-no">&nbsp;</span>
1396
+ <span class="cline-any cline-neutral">&nbsp;</span>
1397
+ <span class="cline-any cline-neutral">&nbsp;</span>
1398
+ <span class="cline-any cline-neutral">&nbsp;</span>
1399
+ <span class="cline-any cline-yes">7x</span>
1400
+ <span class="cline-any cline-yes">7x</span>
1401
+ <span class="cline-any cline-neutral">&nbsp;</span>
1402
+ <span class="cline-any cline-yes">7x</span>
1403
+ <span class="cline-any cline-neutral">&nbsp;</span>
1404
+ <span class="cline-any cline-neutral">&nbsp;</span>
1405
+ <span class="cline-any cline-neutral">&nbsp;</span>
1406
+ <span class="cline-any cline-neutral">&nbsp;</span>
1407
+ <span class="cline-any cline-neutral">&nbsp;</span>
1408
+ <span class="cline-any cline-neutral">&nbsp;</span>
1409
+ <span class="cline-any cline-neutral">&nbsp;</span>
1410
+ <span class="cline-any cline-neutral">&nbsp;</span>
1411
+ <span class="cline-any cline-yes">8x</span>
1412
+ <span class="cline-any cline-yes">8x</span>
1413
+ <span class="cline-any cline-yes">1x</span>
1414
+ <span class="cline-any cline-yes">1x</span>
1415
+ <span class="cline-any cline-yes">1x</span>
1416
+ <span class="cline-any cline-neutral">&nbsp;</span>
1417
+ <span class="cline-any cline-neutral">&nbsp;</span>
1418
+ <span class="cline-any cline-neutral">&nbsp;</span>
1419
+ <span class="cline-any cline-neutral">&nbsp;</span>
1420
+ <span class="cline-any cline-neutral">&nbsp;</span>
1421
+ <span class="cline-any cline-neutral">&nbsp;</span>
1422
+ <span class="cline-any cline-neutral">&nbsp;</span>
1423
+ <span class="cline-any cline-neutral">&nbsp;</span>
1424
+ <span class="cline-any cline-neutral">&nbsp;</span>
1425
+ <span class="cline-any cline-neutral">&nbsp;</span>
1426
+ <span class="cline-any cline-neutral">&nbsp;</span>
1427
+ <span class="cline-any cline-neutral">&nbsp;</span>
1428
+ <span class="cline-any cline-neutral">&nbsp;</span>
1429
+ <span class="cline-any cline-neutral">&nbsp;</span>
1430
+ <span class="cline-any cline-neutral">&nbsp;</span>
1431
+ <span class="cline-any cline-neutral">&nbsp;</span>
1432
+ <span class="cline-any cline-neutral">&nbsp;</span>
1433
+ <span class="cline-any cline-neutral">&nbsp;</span>
1434
+ <span class="cline-any cline-no">&nbsp;</span>
1435
+ <span class="cline-any cline-neutral">&nbsp;</span>
1436
+ <span class="cline-any cline-neutral">&nbsp;</span>
1437
+ <span class="cline-any cline-neutral">&nbsp;</span>
1438
+ <span class="cline-any cline-neutral">&nbsp;</span>
1439
+ <span class="cline-any cline-neutral">&nbsp;</span>
1440
+ <span class="cline-any cline-neutral">&nbsp;</span>
1441
+ <span class="cline-any cline-neutral">&nbsp;</span>
1442
+ <span class="cline-any cline-neutral">&nbsp;</span>
1443
+ <span class="cline-any cline-neutral">&nbsp;</span>
1444
+ <span class="cline-any cline-neutral">&nbsp;</span>
1445
+ <span class="cline-any cline-neutral">&nbsp;</span>
1446
+ <span class="cline-any cline-neutral">&nbsp;</span>
1447
+ <span class="cline-any cline-yes">22x</span>
1448
+ <span class="cline-any cline-neutral">&nbsp;</span>
1449
+ <span class="cline-any cline-neutral">&nbsp;</span>
1450
+ <span class="cline-any cline-yes">22x</span>
1451
+ <span class="cline-any cline-yes">17x</span>
1452
+ <span class="cline-any cline-neutral">&nbsp;</span>
1453
+ <span class="cline-any cline-neutral">&nbsp;</span>
1454
+ <span class="cline-any cline-neutral">&nbsp;</span>
1455
+ <span class="cline-any cline-yes">22x</span>
1456
+ <span class="cline-any cline-yes">1x</span>
1457
+ <span class="cline-any cline-neutral">&nbsp;</span>
1458
+ <span class="cline-any cline-neutral">&nbsp;</span>
1459
+ <span class="cline-any cline-neutral">&nbsp;</span>
1460
+ <span class="cline-any cline-yes">22x</span>
1461
+ <span class="cline-any cline-yes">22x</span>
1462
+ <span class="cline-any cline-neutral">&nbsp;</span>
1463
+ <span class="cline-any cline-yes">22x</span>
1464
+ <span class="cline-any cline-neutral">&nbsp;</span>
1465
+ <span class="cline-any cline-neutral">&nbsp;</span>
1466
+ <span class="cline-any cline-neutral">&nbsp;</span>
1467
+ <span class="cline-any cline-neutral">&nbsp;</span>
1468
+ <span class="cline-any cline-neutral">&nbsp;</span>
1469
+ <span class="cline-any cline-neutral">&nbsp;</span>
1470
+ <span class="cline-any cline-yes">17x</span>
1471
+ <span class="cline-any cline-yes">17x</span>
1472
+ <span class="cline-any cline-yes">17x</span>
1473
+ <span class="cline-any cline-yes">17x</span>
1474
+ <span class="cline-any cline-neutral">&nbsp;</span>
1475
+ <span class="cline-any cline-yes">17x</span>
1476
+ <span class="cline-any cline-neutral">&nbsp;</span>
1477
+ <span class="cline-any cline-neutral">&nbsp;</span>
1478
+ <span class="cline-any cline-yes">17x</span>
1479
+ <span class="cline-any cline-yes">17x</span>
1480
+ <span class="cline-any cline-no">&nbsp;</span>
1481
+ <span class="cline-any cline-no">&nbsp;</span>
1482
+ <span class="cline-any cline-no">&nbsp;</span>
1483
+ <span class="cline-any cline-no">&nbsp;</span>
1484
+ <span class="cline-any cline-neutral">&nbsp;</span>
1485
+ <span class="cline-any cline-neutral">&nbsp;</span>
1486
+ <span class="cline-any cline-yes">17x</span>
1487
+ <span class="cline-any cline-yes">18x</span>
1488
+ <span class="cline-any cline-neutral">&nbsp;</span>
1489
+ <span class="cline-any cline-neutral">&nbsp;</span>
1490
+ <span class="cline-any cline-yes">17x</span>
1491
+ <span class="cline-any cline-yes">1x</span>
1492
+ <span class="cline-any cline-neutral">&nbsp;</span>
1493
+ <span class="cline-any cline-neutral">&nbsp;</span>
1494
+ <span class="cline-any cline-yes">17x</span>
1495
+ <span class="cline-any cline-yes">1x</span>
1496
+ <span class="cline-any cline-neutral">&nbsp;</span>
1497
+ <span class="cline-any cline-neutral">&nbsp;</span>
1498
+ <span class="cline-any cline-yes">17x</span>
1499
+ <span class="cline-any cline-neutral">&nbsp;</span>
1500
+ <span class="cline-any cline-yes">17x</span>
1501
+ <span class="cline-any cline-neutral">&nbsp;</span>
1502
+ <span class="cline-any cline-neutral">&nbsp;</span>
1503
+ <span class="cline-any cline-neutral">&nbsp;</span>
1504
+ <span class="cline-any cline-neutral">&nbsp;</span>
1505
+ <span class="cline-any cline-neutral">&nbsp;</span>
1506
+ <span class="cline-any cline-neutral">&nbsp;</span>
1507
+ <span class="cline-any cline-neutral">&nbsp;</span>
1508
+ <span class="cline-any cline-neutral">&nbsp;</span>
1509
+ <span class="cline-any cline-neutral">&nbsp;</span>
1510
+ <span class="cline-any cline-neutral">&nbsp;</span>
1511
+ <span class="cline-any cline-neutral">&nbsp;</span>
1512
+ <span class="cline-any cline-neutral">&nbsp;</span>
1513
+ <span class="cline-any cline-neutral">&nbsp;</span>
1514
+ <span class="cline-any cline-neutral">&nbsp;</span>
1515
+ <span class="cline-any cline-yes">1x</span>
1516
+ <span class="cline-any cline-yes">1x</span>
1517
+ <span class="cline-any cline-yes">1x</span>
1518
+ <span class="cline-any cline-yes">1x</span>
1519
+ <span class="cline-any cline-yes">1x</span>
1520
+ <span class="cline-any cline-neutral">&nbsp;</span>
1521
+ <span class="cline-any cline-yes">1x</span>
1522
+ <span class="cline-any cline-neutral">&nbsp;</span>
1523
+ <span class="cline-any cline-yes">1x</span>
1524
+ <span class="cline-any cline-yes">1x</span>
1525
+ <span class="cline-any cline-neutral">&nbsp;</span>
1526
+ <span class="cline-any cline-neutral">&nbsp;</span>
1527
+ <span class="cline-any cline-yes">1x</span>
1528
+ <span class="cline-any cline-no">&nbsp;</span>
1529
+ <span class="cline-any cline-neutral">&nbsp;</span>
1530
+ <span class="cline-any cline-neutral">&nbsp;</span>
1531
+ <span class="cline-any cline-yes">1x</span>
1532
+ <span class="cline-any cline-neutral">&nbsp;</span>
1533
+ <span class="cline-any cline-neutral">&nbsp;</span>
1534
+ <span class="cline-any cline-neutral">&nbsp;</span>
1535
+ <span class="cline-any cline-neutral">&nbsp;</span>
1536
+ <span class="cline-any cline-neutral">&nbsp;</span>
1537
+ <span class="cline-any cline-neutral">&nbsp;</span>
1538
+ <span class="cline-any cline-neutral">&nbsp;</span>
1539
+ <span class="cline-any cline-neutral">&nbsp;</span>
1540
+ <span class="cline-any cline-neutral">&nbsp;</span>
1541
+ <span class="cline-any cline-neutral">&nbsp;</span>
1542
+ <span class="cline-any cline-neutral">&nbsp;</span>
1543
+ <span class="cline-any cline-neutral">&nbsp;</span>
1544
+ <span class="cline-any cline-neutral">&nbsp;</span>
1545
+ <span class="cline-any cline-neutral">&nbsp;</span>
1546
+ <span class="cline-any cline-yes">22x</span>
1547
+ <span class="cline-any cline-neutral">&nbsp;</span>
1548
+ <span class="cline-any cline-yes">20x</span>
1549
+ <span class="cline-any cline-neutral">&nbsp;</span>
1550
+ <span class="cline-any cline-yes">1x</span>
1551
+ <span class="cline-any cline-neutral">&nbsp;</span>
1552
+ <span class="cline-any cline-yes">1x</span>
1553
+ <span class="cline-any cline-neutral">&nbsp;</span>
1554
+ <span class="cline-any cline-no">&nbsp;</span>
1555
+ <span class="cline-any cline-neutral">&nbsp;</span>
1556
+ <span class="cline-any cline-neutral">&nbsp;</span>
1557
+ <span class="cline-any cline-neutral">&nbsp;</span>
1558
+ <span class="cline-any cline-neutral">&nbsp;</span>
1559
+ <span class="cline-any cline-neutral">&nbsp;</span>
1560
+ <span class="cline-any cline-neutral">&nbsp;</span>
1561
+ <span class="cline-any cline-neutral">&nbsp;</span>
1562
+ <span class="cline-any cline-yes">20x</span>
1563
+ <span class="cline-any cline-neutral">&nbsp;</span>
1564
+ <span class="cline-any cline-neutral">&nbsp;</span>
1565
+ <span class="cline-any cline-neutral">&nbsp;</span>
1566
+ <span class="cline-any cline-yes">20x</span>
1567
+ <span class="cline-any cline-neutral">&nbsp;</span>
1568
+ <span class="cline-any cline-neutral">&nbsp;</span>
1569
+ <span class="cline-any cline-neutral">&nbsp;</span>
1570
+ <span class="cline-any cline-neutral">&nbsp;</span>
1571
+ <span class="cline-any cline-neutral">&nbsp;</span>
1572
+ <span class="cline-any cline-neutral">&nbsp;</span>
1573
+ <span class="cline-any cline-neutral">&nbsp;</span>
1574
+ <span class="cline-any cline-neutral">&nbsp;</span>
1575
+ <span class="cline-any cline-neutral">&nbsp;</span>
1576
+ <span class="cline-any cline-yes">20x</span>
1577
+ <span class="cline-any cline-neutral">&nbsp;</span>
1578
+ <span class="cline-any cline-neutral">&nbsp;</span>
1579
+ <span class="cline-any cline-neutral">&nbsp;</span>
1580
+ <span class="cline-any cline-neutral">&nbsp;</span>
1581
+ <span class="cline-any cline-neutral">&nbsp;</span>
1582
+ <span class="cline-any cline-neutral">&nbsp;</span>
1583
+ <span class="cline-any cline-yes">1x</span>
1584
+ <span class="cline-any cline-neutral">&nbsp;</span>
1585
+ <span class="cline-any cline-neutral">&nbsp;</span>
1586
+ <span class="cline-any cline-yes">1x</span>
1587
+ <span class="cline-any cline-neutral">&nbsp;</span>
1588
+ <span class="cline-any cline-neutral">&nbsp;</span>
1589
+ <span class="cline-any cline-neutral">&nbsp;</span>
1590
+ <span class="cline-any cline-neutral">&nbsp;</span>
1591
+ <span class="cline-any cline-neutral">&nbsp;</span>
1592
+ <span class="cline-any cline-neutral">&nbsp;</span>
1593
+ <span class="cline-any cline-neutral">&nbsp;</span>
1594
+ <span class="cline-any cline-neutral">&nbsp;</span>
1595
+ <span class="cline-any cline-neutral">&nbsp;</span>
1596
+ <span class="cline-any cline-yes">1x</span>
1597
+ <span class="cline-any cline-neutral">&nbsp;</span>
1598
+ <span class="cline-any cline-neutral">&nbsp;</span>
1599
+ <span class="cline-any cline-neutral">&nbsp;</span>
1600
+ <span class="cline-any cline-neutral">&nbsp;</span>
1601
+ <span class="cline-any cline-neutral">&nbsp;</span>
1602
+ <span class="cline-any cline-neutral">&nbsp;</span>
1603
+ <span class="cline-any cline-yes">1x</span>
1604
+ <span class="cline-any cline-neutral">&nbsp;</span>
1605
+ <span class="cline-any cline-neutral">&nbsp;</span>
1606
+ <span class="cline-any cline-yes">1x</span>
1607
+ <span class="cline-any cline-neutral">&nbsp;</span>
1608
+ <span class="cline-any cline-neutral">&nbsp;</span>
1609
+ <span class="cline-any cline-neutral">&nbsp;</span>
1610
+ <span class="cline-any cline-neutral">&nbsp;</span>
1611
+ <span class="cline-any cline-neutral">&nbsp;</span>
1612
+ <span class="cline-any cline-neutral">&nbsp;</span>
1613
+ <span class="cline-any cline-neutral">&nbsp;</span>
1614
+ <span class="cline-any cline-neutral">&nbsp;</span>
1615
+ <span class="cline-any cline-neutral">&nbsp;</span>
1616
+ <span class="cline-any cline-yes">1x</span>
1617
+ <span class="cline-any cline-neutral">&nbsp;</span>
1618
+ <span class="cline-any cline-neutral">&nbsp;</span>
1619
+ <span class="cline-any cline-neutral">&nbsp;</span>
1620
+ <span class="cline-any cline-neutral">&nbsp;</span>
1621
+ <span class="cline-any cline-neutral">&nbsp;</span>
1622
+ <span class="cline-any cline-neutral">&nbsp;</span>
1623
+ <span class="cline-any cline-yes">1x</span>
1624
+ <span class="cline-any cline-yes">1x</span>
1625
+ <span class="cline-any cline-neutral">&nbsp;</span>
1626
+ <span class="cline-any cline-neutral">&nbsp;</span>
1627
+ <span class="cline-any cline-yes">1x</span>
1628
+ <span class="cline-any cline-neutral">&nbsp;</span>
1629
+ <span class="cline-any cline-neutral">&nbsp;</span>
1630
+ <span class="cline-any cline-neutral">&nbsp;</span>
1631
+ <span class="cline-any cline-neutral">&nbsp;</span>
1632
+ <span class="cline-any cline-neutral">&nbsp;</span>
1633
+ <span class="cline-any cline-neutral">&nbsp;</span>
1634
+ <span class="cline-any cline-neutral">&nbsp;</span>
1635
+ <span class="cline-any cline-neutral">&nbsp;</span>
1636
+ <span class="cline-any cline-neutral">&nbsp;</span>
1637
+ <span class="cline-any cline-neutral">&nbsp;</span>
1638
+ <span class="cline-any cline-neutral">&nbsp;</span>
1639
+ <span class="cline-any cline-neutral">&nbsp;</span>
1640
+ <span class="cline-any cline-yes">1x</span>
1641
+ <span class="cline-any cline-neutral">&nbsp;</span>
1642
+ <span class="cline-any cline-neutral">&nbsp;</span>
1643
+ <span class="cline-any cline-neutral">&nbsp;</span>
1644
+ <span class="cline-any cline-neutral">&nbsp;</span>
1645
+ <span class="cline-any cline-neutral">&nbsp;</span>
1646
+ <span class="cline-any cline-yes">1x</span>
1647
+ <span class="cline-any cline-neutral">&nbsp;</span>
1648
+ <span class="cline-any cline-yes">1x</span>
1649
+ <span class="cline-any cline-neutral">&nbsp;</span>
1650
+ <span class="cline-any cline-neutral">&nbsp;</span>
1651
+ <span class="cline-any cline-neutral">&nbsp;</span>
1652
+ <span class="cline-any cline-neutral">&nbsp;</span>
1653
+ <span class="cline-any cline-neutral">&nbsp;</span>
1654
+ <span class="cline-any cline-neutral">&nbsp;</span>
1655
+ <span class="cline-any cline-neutral">&nbsp;</span>
1656
+ <span class="cline-any cline-neutral">&nbsp;</span>
1657
+ <span class="cline-any cline-neutral">&nbsp;</span>
1658
+ <span class="cline-any cline-yes">1x</span>
1659
+ <span class="cline-any cline-neutral">&nbsp;</span>
1660
+ <span class="cline-any cline-neutral">&nbsp;</span>
1661
+ <span class="cline-any cline-neutral">&nbsp;</span>
1662
+ <span class="cline-any cline-neutral">&nbsp;</span>
1663
+ <span class="cline-any cline-neutral">&nbsp;</span>
1664
+ <span class="cline-any cline-neutral">&nbsp;</span>
1665
+ <span class="cline-any cline-neutral">&nbsp;</span>
1666
+ <span class="cline-any cline-neutral">&nbsp;</span>
1667
+ <span class="cline-any cline-neutral">&nbsp;</span>
1668
+ <span class="cline-any cline-neutral">&nbsp;</span>
1669
+ <span class="cline-any cline-neutral">&nbsp;</span>
1670
+ <span class="cline-any cline-neutral">&nbsp;</span>
1671
+ <span class="cline-any cline-neutral">&nbsp;</span>
1672
+ <span class="cline-any cline-neutral">&nbsp;</span>
1673
+ <span class="cline-any cline-neutral">&nbsp;</span>
1674
+ <span class="cline-any cline-yes">22x</span>
1675
+ <span class="cline-any cline-neutral">&nbsp;</span>
1676
+ <span class="cline-any cline-yes">20x</span>
1677
+ <span class="cline-any cline-neutral">&nbsp;</span>
1678
+ <span class="cline-any cline-yes">1x</span>
1679
+ <span class="cline-any cline-neutral">&nbsp;</span>
1680
+ <span class="cline-any cline-yes">1x</span>
1681
+ <span class="cline-any cline-neutral">&nbsp;</span>
1682
+ <span class="cline-any cline-no">&nbsp;</span>
1683
+ <span class="cline-any cline-neutral">&nbsp;</span>
1684
+ <span class="cline-any cline-neutral">&nbsp;</span>
1685
+ <span class="cline-any cline-neutral">&nbsp;</span>
1686
+ <span class="cline-any cline-neutral">&nbsp;</span>
1687
+ <span class="cline-any cline-neutral">&nbsp;</span>
1688
+ <span class="cline-any cline-neutral">&nbsp;</span>
1689
+ <span class="cline-any cline-neutral">&nbsp;</span>
1690
+ <span class="cline-any cline-neutral">&nbsp;</span>
1691
+ <span class="cline-any cline-neutral">&nbsp;</span>
1692
+ <span class="cline-any cline-yes">20x</span>
1693
+ <span class="cline-any cline-yes">20x</span>
1694
+ <span class="cline-any cline-neutral">&nbsp;</span>
1695
+ <span class="cline-any cline-neutral">&nbsp;</span>
1696
+ <span class="cline-any cline-neutral">&nbsp;</span>
1697
+ <span class="cline-any cline-neutral">&nbsp;</span>
1698
+ <span class="cline-any cline-neutral">&nbsp;</span>
1699
+ <span class="cline-any cline-neutral">&nbsp;</span>
1700
+ <span class="cline-any cline-neutral">&nbsp;</span>
1701
+ <span class="cline-any cline-neutral">&nbsp;</span>
1702
+ <span class="cline-any cline-neutral">&nbsp;</span>
1703
+ <span class="cline-any cline-neutral">&nbsp;</span>
1704
+ <span class="cline-any cline-neutral">&nbsp;</span>
1705
+ <span class="cline-any cline-neutral">&nbsp;</span>
1706
+ <span class="cline-any cline-neutral">&nbsp;</span>
1707
+ <span class="cline-any cline-neutral">&nbsp;</span>
1708
+ <span class="cline-any cline-neutral">&nbsp;</span>
1709
+ <span class="cline-any cline-neutral">&nbsp;</span>
1710
+ <span class="cline-any cline-neutral">&nbsp;</span>
1711
+ <span class="cline-any cline-yes">20x</span>
1712
+ <span class="cline-any cline-neutral">&nbsp;</span>
1713
+ <span class="cline-any cline-neutral">&nbsp;</span>
1714
+ <span class="cline-any cline-neutral">&nbsp;</span>
1715
+ <span class="cline-any cline-neutral">&nbsp;</span>
1716
+ <span class="cline-any cline-neutral">&nbsp;</span>
1717
+ <span class="cline-any cline-neutral">&nbsp;</span>
1718
+ <span class="cline-any cline-no">&nbsp;</span>
1719
+ <span class="cline-any cline-no">&nbsp;</span>
1720
+ <span class="cline-any cline-no">&nbsp;</span>
1721
+ <span class="cline-any cline-neutral">&nbsp;</span>
1722
+ <span class="cline-any cline-neutral">&nbsp;</span>
1723
+ <span class="cline-any cline-neutral">&nbsp;</span>
1724
+ <span class="cline-any cline-neutral">&nbsp;</span>
1725
+ <span class="cline-any cline-neutral">&nbsp;</span>
1726
+ <span class="cline-any cline-neutral">&nbsp;</span>
1727
+ <span class="cline-any cline-neutral">&nbsp;</span>
1728
+ <span class="cline-any cline-neutral">&nbsp;</span>
1729
+ <span class="cline-any cline-neutral">&nbsp;</span>
1730
+ <span class="cline-any cline-yes">1x</span>
1731
+ <span class="cline-any cline-yes">1x</span>
1732
+ <span class="cline-any cline-neutral">&nbsp;</span>
1733
+ <span class="cline-any cline-neutral">&nbsp;</span>
1734
+ <span class="cline-any cline-neutral">&nbsp;</span>
1735
+ <span class="cline-any cline-neutral">&nbsp;</span>
1736
+ <span class="cline-any cline-neutral">&nbsp;</span>
1737
+ <span class="cline-any cline-neutral">&nbsp;</span>
1738
+ <span class="cline-any cline-neutral">&nbsp;</span>
1739
+ <span class="cline-any cline-neutral">&nbsp;</span>
1740
+ <span class="cline-any cline-neutral">&nbsp;</span>
1741
+ <span class="cline-any cline-neutral">&nbsp;</span>
1742
+ <span class="cline-any cline-neutral">&nbsp;</span>
1743
+ <span class="cline-any cline-neutral">&nbsp;</span>
1744
+ <span class="cline-any cline-neutral">&nbsp;</span>
1745
+ <span class="cline-any cline-neutral">&nbsp;</span>
1746
+ <span class="cline-any cline-neutral">&nbsp;</span>
1747
+ <span class="cline-any cline-yes">1x</span>
1748
+ <span class="cline-any cline-neutral">&nbsp;</span>
1749
+ <span class="cline-any cline-neutral">&nbsp;</span>
1750
+ <span class="cline-any cline-neutral">&nbsp;</span>
1751
+ <span class="cline-any cline-neutral">&nbsp;</span>
1752
+ <span class="cline-any cline-neutral">&nbsp;</span>
1753
+ <span class="cline-any cline-neutral">&nbsp;</span>
1754
+ <span class="cline-any cline-no">&nbsp;</span>
1755
+ <span class="cline-any cline-no">&nbsp;</span>
1756
+ <span class="cline-any cline-no">&nbsp;</span>
1757
+ <span class="cline-any cline-neutral">&nbsp;</span>
1758
+ <span class="cline-any cline-neutral">&nbsp;</span>
1759
+ <span class="cline-any cline-neutral">&nbsp;</span>
1760
+ <span class="cline-any cline-neutral">&nbsp;</span>
1761
+ <span class="cline-any cline-neutral">&nbsp;</span>
1762
+ <span class="cline-any cline-neutral">&nbsp;</span>
1763
+ <span class="cline-any cline-neutral">&nbsp;</span>
1764
+ <span class="cline-any cline-neutral">&nbsp;</span>
1765
+ <span class="cline-any cline-neutral">&nbsp;</span>
1766
+ <span class="cline-any cline-neutral">&nbsp;</span>
1767
+ <span class="cline-any cline-neutral">&nbsp;</span>
1768
+ <span class="cline-any cline-yes">1x</span>
1769
+ <span class="cline-any cline-neutral">&nbsp;</span>
1770
+ <span class="cline-any cline-neutral">&nbsp;</span>
1771
+ <span class="cline-any cline-neutral">&nbsp;</span>
1772
+ <span class="cline-any cline-yes">1x</span>
1773
+ <span class="cline-any cline-neutral">&nbsp;</span>
1774
+ <span class="cline-any cline-neutral">&nbsp;</span>
1775
+ <span class="cline-any cline-neutral">&nbsp;</span>
1776
+ <span class="cline-any cline-neutral">&nbsp;</span>
1777
+ <span class="cline-any cline-neutral">&nbsp;</span>
1778
+ <span class="cline-any cline-neutral">&nbsp;</span>
1779
+ <span class="cline-any cline-neutral">&nbsp;</span>
1780
+ <span class="cline-any cline-neutral">&nbsp;</span>
1781
+ <span class="cline-any cline-neutral">&nbsp;</span>
1782
+ <span class="cline-any cline-neutral">&nbsp;</span>
1783
+ <span class="cline-any cline-neutral">&nbsp;</span>
1784
+ <span class="cline-any cline-neutral">&nbsp;</span>
1785
+ <span class="cline-any cline-neutral">&nbsp;</span>
1786
+ <span class="cline-any cline-no">&nbsp;</span>
1787
+ <span class="cline-any cline-neutral">&nbsp;</span>
1788
+ <span class="cline-any cline-no">&nbsp;</span>
1789
+ <span class="cline-any cline-neutral">&nbsp;</span>
1790
+ <span class="cline-any cline-no">&nbsp;</span>
1791
+ <span class="cline-any cline-neutral">&nbsp;</span>
1792
+ <span class="cline-any cline-no">&nbsp;</span>
1793
+ <span class="cline-any cline-neutral">&nbsp;</span>
1794
+ <span class="cline-any cline-no">&nbsp;</span>
1795
+ <span class="cline-any cline-neutral">&nbsp;</span>
1796
+ <span class="cline-any cline-neutral">&nbsp;</span>
1797
+ <span class="cline-any cline-neutral">&nbsp;</span>
1798
+ <span class="cline-any cline-neutral">&nbsp;</span>
1799
+ <span class="cline-any cline-neutral">&nbsp;</span>
1800
+ <span class="cline-any cline-neutral">&nbsp;</span>
1801
+ <span class="cline-any cline-neutral">&nbsp;</span>
1802
+ <span class="cline-any cline-neutral">&nbsp;</span>
1803
+ <span class="cline-any cline-neutral">&nbsp;</span>
1804
+ <span class="cline-any cline-neutral">&nbsp;</span>
1805
+ <span class="cline-any cline-no">&nbsp;</span>
1806
+ <span class="cline-any cline-neutral">&nbsp;</span>
1807
+ <span class="cline-any cline-no">&nbsp;</span>
1808
+ <span class="cline-any cline-neutral">&nbsp;</span>
1809
+ <span class="cline-any cline-neutral">&nbsp;</span>
1810
+ <span class="cline-any cline-neutral">&nbsp;</span>
1811
+ <span class="cline-any cline-neutral">&nbsp;</span>
1812
+ <span class="cline-any cline-neutral">&nbsp;</span>
1813
+ <span class="cline-any cline-neutral">&nbsp;</span>
1814
+ <span class="cline-any cline-neutral">&nbsp;</span>
1815
+ <span class="cline-any cline-neutral">&nbsp;</span>
1816
+ <span class="cline-any cline-no">&nbsp;</span>
1817
+ <span class="cline-any cline-no">&nbsp;</span>
1818
+ <span class="cline-any cline-no">&nbsp;</span>
1819
+ <span class="cline-any cline-neutral">&nbsp;</span>
1820
+ <span class="cline-any cline-neutral">&nbsp;</span>
1821
+ <span class="cline-any cline-neutral">&nbsp;</span>
1822
+ <span class="cline-any cline-no">&nbsp;</span>
1823
+ <span class="cline-any cline-neutral">&nbsp;</span>
1824
+ <span class="cline-any cline-neutral">&nbsp;</span>
1825
+ <span class="cline-any cline-neutral">&nbsp;</span>
1826
+ <span class="cline-any cline-neutral">&nbsp;</span>
1827
+ <span class="cline-any cline-neutral">&nbsp;</span>
1828
+ <span class="cline-any cline-neutral">&nbsp;</span>
1829
+ <span class="cline-any cline-neutral">&nbsp;</span>
1830
+ <span class="cline-any cline-neutral">&nbsp;</span>
1831
+ <span class="cline-any cline-neutral">&nbsp;</span>
1832
+ <span class="cline-any cline-no">&nbsp;</span>
1833
+ <span class="cline-any cline-neutral">&nbsp;</span>
1834
+ <span class="cline-any cline-neutral">&nbsp;</span>
1835
+ <span class="cline-any cline-neutral">&nbsp;</span>
1836
+ <span class="cline-any cline-neutral">&nbsp;</span>
1837
+ <span class="cline-any cline-neutral">&nbsp;</span>
1838
+ <span class="cline-any cline-no">&nbsp;</span>
1839
+ <span class="cline-any cline-no">&nbsp;</span>
1840
+ <span class="cline-any cline-no">&nbsp;</span>
1841
+ <span class="cline-any cline-neutral">&nbsp;</span>
1842
+ <span class="cline-any cline-neutral">&nbsp;</span>
1843
+ <span class="cline-any cline-neutral">&nbsp;</span>
1844
+ <span class="cline-any cline-neutral">&nbsp;</span>
1845
+ <span class="cline-any cline-neutral">&nbsp;</span>
1846
+ <span class="cline-any cline-neutral">&nbsp;</span>
1847
+ <span class="cline-any cline-neutral">&nbsp;</span>
1848
+ <span class="cline-any cline-neutral">&nbsp;</span>
1849
+ <span class="cline-any cline-neutral">&nbsp;</span>
1850
+ <span class="cline-any cline-neutral">&nbsp;</span>
1851
+ <span class="cline-any cline-no">&nbsp;</span>
1852
+ <span class="cline-any cline-no">&nbsp;</span>
1853
+ <span class="cline-any cline-neutral">&nbsp;</span>
1854
+ <span class="cline-any cline-neutral">&nbsp;</span>
1855
+ <span class="cline-any cline-neutral">&nbsp;</span>
1856
+ <span class="cline-any cline-neutral">&nbsp;</span>
1857
+ <span class="cline-any cline-neutral">&nbsp;</span>
1858
+ <span class="cline-any cline-neutral">&nbsp;</span>
1859
+ <span class="cline-any cline-neutral">&nbsp;</span>
1860
+ <span class="cline-any cline-neutral">&nbsp;</span>
1861
+ <span class="cline-any cline-neutral">&nbsp;</span>
1862
+ <span class="cline-any cline-no">&nbsp;</span>
1863
+ <span class="cline-any cline-neutral">&nbsp;</span>
1864
+ <span class="cline-any cline-neutral">&nbsp;</span>
1865
+ <span class="cline-any cline-neutral">&nbsp;</span>
1866
+ <span class="cline-any cline-neutral">&nbsp;</span>
1867
+ <span class="cline-any cline-neutral">&nbsp;</span>
1868
+ <span class="cline-any cline-no">&nbsp;</span>
1869
+ <span class="cline-any cline-no">&nbsp;</span>
1870
+ <span class="cline-any cline-no">&nbsp;</span>
1871
+ <span class="cline-any cline-neutral">&nbsp;</span>
1872
+ <span class="cline-any cline-neutral">&nbsp;</span>
1873
+ <span class="cline-any cline-neutral">&nbsp;</span>
1874
+ <span class="cline-any cline-neutral">&nbsp;</span>
1875
+ <span class="cline-any cline-neutral">&nbsp;</span>
1876
+ <span class="cline-any cline-neutral">&nbsp;</span>
1877
+ <span class="cline-any cline-neutral">&nbsp;</span>
1878
+ <span class="cline-any cline-neutral">&nbsp;</span>
1879
+ <span class="cline-any cline-neutral">&nbsp;</span>
1880
+ <span class="cline-any cline-neutral">&nbsp;</span>
1881
+ <span class="cline-any cline-neutral">&nbsp;</span>
1882
+ <span class="cline-any cline-no">&nbsp;</span>
1883
+ <span class="cline-any cline-neutral">&nbsp;</span>
1884
+ <span class="cline-any cline-no">&nbsp;</span>
1885
+ <span class="cline-any cline-neutral">&nbsp;</span>
1886
+ <span class="cline-any cline-neutral">&nbsp;</span>
1887
+ <span class="cline-any cline-neutral">&nbsp;</span>
1888
+ <span class="cline-any cline-neutral">&nbsp;</span>
1889
+ <span class="cline-any cline-neutral">&nbsp;</span>
1890
+ <span class="cline-any cline-neutral">&nbsp;</span>
1891
+ <span class="cline-any cline-neutral">&nbsp;</span>
1892
+ <span class="cline-any cline-neutral">&nbsp;</span>
1893
+ <span class="cline-any cline-neutral">&nbsp;</span>
1894
+ <span class="cline-any cline-neutral">&nbsp;</span>
1895
+ <span class="cline-any cline-neutral">&nbsp;</span>
1896
+ <span class="cline-any cline-neutral">&nbsp;</span>
1897
+ <span class="cline-any cline-yes">4x</span>
1898
+ <span class="cline-any cline-yes">4x</span>
1899
+ <span class="cline-any cline-neutral">&nbsp;</span>
1900
+ <span class="cline-any cline-yes">4x</span>
1901
+ <span class="cline-any cline-yes">4x</span>
1902
+ <span class="cline-any cline-yes">4x</span>
1903
+ <span class="cline-any cline-yes">4x</span>
1904
+ <span class="cline-any cline-yes">4x</span>
1905
+ <span class="cline-any cline-yes">8x</span>
1906
+ <span class="cline-any cline-yes">4x</span>
1907
+ <span class="cline-any cline-neutral">&nbsp;</span>
1908
+ <span class="cline-any cline-neutral">&nbsp;</span>
1909
+ <span class="cline-any cline-yes">4x</span>
1910
+ <span class="cline-any cline-neutral">&nbsp;</span>
1911
+ <span class="cline-any cline-no">&nbsp;</span>
1912
+ <span class="cline-any cline-neutral">&nbsp;</span>
1913
+ <span class="cline-any cline-neutral">&nbsp;</span>
1914
+ <span class="cline-any cline-neutral">&nbsp;</span>
1915
+ <span class="cline-any cline-neutral">&nbsp;</span>
1916
+ <span class="cline-any cline-neutral">&nbsp;</span>
1917
+ <span class="cline-any cline-neutral">&nbsp;</span>
1918
+ <span class="cline-any cline-yes">4x</span>
1919
+ <span class="cline-any cline-yes">4x</span>
1920
+ <span class="cline-any cline-neutral">&nbsp;</span>
1921
+ <span class="cline-any cline-neutral">&nbsp;</span>
1922
+ <span class="cline-any cline-yes">4x</span>
1923
+ <span class="cline-any cline-yes">4x</span>
1924
+ <span class="cline-any cline-yes">4x</span>
1925
+ <span class="cline-any cline-yes">4x</span>
1926
+ <span class="cline-any cline-neutral">&nbsp;</span>
1927
+ <span class="cline-any cline-yes">4x</span>
1928
+ <span class="cline-any cline-neutral">&nbsp;</span>
1929
+ <span class="cline-any cline-neutral">&nbsp;</span>
1930
+ <span class="cline-any cline-neutral">&nbsp;</span>
1931
+ <span class="cline-any cline-neutral">&nbsp;</span>
1932
+ <span class="cline-any cline-neutral">&nbsp;</span>
1933
+ <span class="cline-any cline-neutral">&nbsp;</span>
1934
+ <span class="cline-any cline-neutral">&nbsp;</span>
1935
+ <span class="cline-any cline-neutral">&nbsp;</span>
1936
+ <span class="cline-any cline-yes">4x</span>
1937
+ <span class="cline-any cline-neutral">&nbsp;</span>
1938
+ <span class="cline-any cline-neutral">&nbsp;</span>
1939
+ <span class="cline-any cline-neutral">&nbsp;</span>
1940
+ <span class="cline-any cline-neutral">&nbsp;</span>
1941
+ <span class="cline-any cline-neutral">&nbsp;</span>
1942
+ <span class="cline-any cline-neutral">&nbsp;</span>
1943
+ <span class="cline-any cline-neutral">&nbsp;</span>
1944
+ <span class="cline-any cline-yes">4x</span>
1945
+ <span class="cline-any cline-yes">4x</span>
1946
+ <span class="cline-any cline-yes">4x</span>
1947
+ <span class="cline-any cline-yes">4x</span>
1948
+ <span class="cline-any cline-yes">8x</span>
1949
+ <span class="cline-any cline-yes">4x</span>
1950
+ <span class="cline-any cline-neutral">&nbsp;</span>
1951
+ <span class="cline-any cline-no">&nbsp;</span>
1952
+ <span class="cline-any cline-no">&nbsp;</span>
1953
+ <span class="cline-any cline-neutral">&nbsp;</span>
1954
+ <span class="cline-any cline-neutral">&nbsp;</span>
1955
+ <span class="cline-any cline-no">&nbsp;</span>
1956
+ <span class="cline-any cline-neutral">&nbsp;</span>
1957
+ <span class="cline-any cline-neutral">&nbsp;</span>
1958
+ <span class="cline-any cline-neutral">&nbsp;</span>
1959
+ <span class="cline-any cline-neutral">&nbsp;</span>
1960
+ <span class="cline-any cline-neutral">&nbsp;</span>
1961
+ <span class="cline-any cline-neutral">&nbsp;</span>
1962
+ <span class="cline-any cline-neutral">&nbsp;</span>
1963
+ <span class="cline-any cline-neutral">&nbsp;</span>
1964
+ <span class="cline-any cline-neutral">&nbsp;</span>
1965
+ <span class="cline-any cline-neutral">&nbsp;</span>
1966
+ <span class="cline-any cline-neutral">&nbsp;</span>
1967
+ <span class="cline-any cline-yes">23x</span>
1968
+ <span class="cline-any cline-neutral">&nbsp;</span>
1969
+ <span class="cline-any cline-yes">23x</span>
1970
+ <span class="cline-any cline-yes">1x</span>
1971
+ <span class="cline-any cline-neutral">&nbsp;</span>
1972
+ <span class="cline-any cline-neutral">&nbsp;</span>
1973
+ <span class="cline-any cline-neutral">&nbsp;</span>
1974
+ <span class="cline-any cline-neutral">&nbsp;</span>
1975
+ <span class="cline-any cline-neutral">&nbsp;</span>
1976
+ <span class="cline-any cline-neutral">&nbsp;</span>
1977
+ <span class="cline-any cline-neutral">&nbsp;</span>
1978
+ <span class="cline-any cline-neutral">&nbsp;</span>
1979
+ <span class="cline-any cline-neutral">&nbsp;</span>
1980
+ <span class="cline-any cline-neutral">&nbsp;</span>
1981
+ <span class="cline-any cline-yes">30x</span>
1982
+ <span class="cline-any cline-neutral">&nbsp;</span>
1983
+ <span class="cline-any cline-yes">30x</span>
1984
+ <span class="cline-any cline-yes">30x</span>
1985
+ <span class="cline-any cline-neutral">&nbsp;</span>
1986
+ <span class="cline-any cline-neutral">&nbsp;</span>
1987
+ <span class="cline-any cline-neutral">&nbsp;</span>
1988
+ <span class="cline-any cline-neutral">&nbsp;</span>
1989
+ <span class="cline-any cline-neutral">&nbsp;</span>
1990
+ <span class="cline-any cline-neutral">&nbsp;</span>
1991
+ <span class="cline-any cline-yes">30x</span>
1992
+ <span class="cline-any cline-neutral">&nbsp;</span>
1993
+ <span class="cline-any cline-neutral">&nbsp;</span>
1994
+ <span class="cline-any cline-neutral">&nbsp;</span>
1995
+ <span class="cline-any cline-neutral">&nbsp;</span>
1996
+ <span class="cline-any cline-neutral">&nbsp;</span>
1997
+ <span class="cline-any cline-neutral">&nbsp;</span>
1998
+ <span class="cline-any cline-no">&nbsp;</span>
1999
+ <span class="cline-any cline-neutral">&nbsp;</span>
2000
+ <span class="cline-any cline-no">&nbsp;</span>
2001
+ <span class="cline-any cline-neutral">&nbsp;</span>
2002
+ <span class="cline-any cline-neutral">&nbsp;</span>
2003
+ <span class="cline-any cline-neutral">&nbsp;</span>
2004
+ <span class="cline-any cline-neutral">&nbsp;</span>
2005
+ <span class="cline-any cline-neutral">&nbsp;</span>
2006
+ <span class="cline-any cline-neutral">&nbsp;</span>
2007
+ <span class="cline-any cline-neutral">&nbsp;</span>
2008
+ <span class="cline-any cline-neutral">&nbsp;</span>
2009
+ <span class="cline-any cline-neutral">&nbsp;</span>
2010
+ <span class="cline-any cline-neutral">&nbsp;</span>
2011
+ <span class="cline-any cline-neutral">&nbsp;</span>
2012
+ <span class="cline-any cline-no">&nbsp;</span>
2013
+ <span class="cline-any cline-neutral">&nbsp;</span>
2014
+ <span class="cline-any cline-neutral">&nbsp;</span>
2015
+ <span class="cline-any cline-neutral">&nbsp;</span>
2016
+ <span class="cline-any cline-neutral">&nbsp;</span>
2017
+ <span class="cline-any cline-neutral">&nbsp;</span>
2018
+ <span class="cline-any cline-neutral">&nbsp;</span>
2019
+ <span class="cline-any cline-yes">33x</span>
2020
+ <span class="cline-any cline-neutral">&nbsp;</span>
2021
+ <span class="cline-any cline-yes">2x</span>
2022
+ <span class="cline-any cline-yes">2x</span>
2023
+ <span class="cline-any cline-neutral">&nbsp;</span>
2024
+ <span class="cline-any cline-neutral">&nbsp;</span>
2025
+ <span class="cline-any cline-neutral">&nbsp;</span>
2026
+ <span class="cline-any cline-neutral">&nbsp;</span>
2027
+ <span class="cline-any cline-neutral">&nbsp;</span>
2028
+ <span class="cline-any cline-neutral">&nbsp;</span>
2029
+ <span class="cline-any cline-no">&nbsp;</span>
2030
+ <span class="cline-any cline-neutral">&nbsp;</span>
2031
+ <span class="cline-any cline-neutral">&nbsp;</span>
2032
+ <span class="cline-any cline-neutral">&nbsp;</span>
2033
+ <span class="cline-any cline-neutral">&nbsp;</span>
2034
+ <span class="cline-any cline-neutral">&nbsp;</span>
2035
+ <span class="cline-any cline-neutral">&nbsp;</span>
2036
+ <span class="cline-any cline-neutral">&nbsp;</span>
2037
+ <span class="cline-any cline-neutral">&nbsp;</span>
2038
+ <span class="cline-any cline-neutral">&nbsp;</span>
2039
+ <span class="cline-any cline-neutral">&nbsp;</span>
2040
+ <span class="cline-any cline-neutral">&nbsp;</span>
2041
+ <span class="cline-any cline-yes">28x</span>
2042
+ <span class="cline-any cline-yes">6x</span>
2043
+ <span class="cline-any cline-yes">6x</span>
2044
+ <span class="cline-any cline-neutral">&nbsp;</span>
2045
+ <span class="cline-any cline-neutral">&nbsp;</span>
2046
+ <span class="cline-any cline-yes">28x</span>
2047
+ <span class="cline-any cline-yes">28x</span>
2048
+ <span class="cline-any cline-neutral">&nbsp;</span>
2049
+ <span class="cline-any cline-neutral">&nbsp;</span>
2050
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/*
2051
+ Copyright (c) 2025 Bernier LLC
2052
+ &nbsp;
2053
+ This file is licensed to the client under a limited-use license.
2054
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
2055
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
2056
+ */
2057
+ &nbsp;
2058
+ import { Logger, LogLevel, ConsoleTransport } from '@bernierllc/logger';
2059
+ import { generateUUIDKey } from '@bernierllc/crypto-utils';
2060
+ import { NeverHubAdapter } from '@bernierllc/neverhub-adapter';
2061
+ import { Resolver } from 'dns2';
2062
+ import axios, { AxiosInstance } from 'axios';
2063
+ import { CronJob } from 'cron';
2064
+ import { generateKeyPairSync } from 'crypto';
2065
+ import {
2066
+ DomainConfig,
2067
+ DomainVerificationResult,
2068
+ DNSPropagationResult,
2069
+ DomainHealthStatus,
2070
+ VerificationHistoryEntry,
2071
+ DNSRecord,
2072
+ DKIMConfig,
2073
+ VerificationStatus,
2074
+ EmailProvider
2075
+ } from './types';
2076
+ import { InvalidDomainError } from './errors';
2077
+ &nbsp;
2078
+ /**
2079
+ * Email Domain Verification Service
2080
+ *
2081
+ * Manages domain verification for email service providers including
2082
+ * DNS record generation, propagation monitoring, and health checks.
2083
+ */
2084
+ export class EmailDomainVerificationService {
2085
+ private logger: Logger;
2086
+ private neverhub?: NeverHubAdapter;
2087
+ private httpClient: AxiosInstance;
2088
+ private healthCheckJobs: Map&lt;string, CronJob&gt;;
2089
+ private verificationHistory: Map&lt;string, VerificationHistoryEntry[]&gt;;
2090
+ &nbsp;
2091
+ constructor(config?: {
2092
+ logger?: Logger;
2093
+ neverhub?: NeverHubAdapter;
2094
+ healthCheckInterval?: string; // Cron expression
2095
+ }) {
2096
+ this.logger = config?.logger || <span class="branch-1 cbranch-no" title="branch not covered" >new Logger({</span>
2097
+ level: LogLevel.INFO,
2098
+ transports: [new ConsoleTransport({ level: LogLevel.INFO })]
2099
+ });
2100
+ this.neverhub = config?.neverhub;
2101
+ this.httpClient = axios.create({
2102
+ timeout: 30000,
2103
+ headers: { 'User-Agent': '@bernierllc/email-domain-verification/1.0.0' }
2104
+ });
2105
+ this.healthCheckJobs = new Map();
2106
+ this.verificationHistory = new Map();
2107
+ }
2108
+ &nbsp;
2109
+ /**
2110
+ * Initialize service with NeverHub registration
2111
+ */
2112
+ <span class="fstat-no" title="function not covered" > async </span>initialize(): Promise&lt;void&gt; {
2113
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (await NeverHubAdapter.detect()) {</span>
2114
+ <span class="cstat-no" title="statement not covered" > this.neverhub = new NeverHubAdapter();</span>
2115
+ <span class="cstat-no" title="statement not covered" > await this.registerWithNeverHub();</span>
2116
+ }
2117
+ &nbsp;
2118
+ <span class="cstat-no" title="statement not covered" > this.logger.info('Email Domain Verification Service initialized', {</span>
2119
+ neverhubEnabled: !!this.neverhub
2120
+ });
2121
+ }
2122
+ &nbsp;
2123
+ /**
2124
+ * Setup domain verification for a provider
2125
+ *
2126
+ * @param config - Domain configuration
2127
+ * @returns Verification result with DNS records to configure
2128
+ */
2129
+ async setupDomain(config: DomainConfig): Promise&lt;DomainVerificationResult&gt; {
2130
+ this.logger.info('Setting up domain verification', {
2131
+ domain: config.domain,
2132
+ provider: config.provider
2133
+ });
2134
+ &nbsp;
2135
+ try {
2136
+ // Validate domain
2137
+ this.validateDomain(config.domain);
2138
+ &nbsp;
2139
+ // Generate DNS records based on provider and configuration
2140
+ const dnsRecords = await this.generateDNSRecords(config);
2141
+ &nbsp;
2142
+ // Generate DKIM keypair if enabled
2143
+ let dkimConfig: DKIMConfig | undefined;
2144
+ if (config.dkim.enabled) {
2145
+ dkimConfig = await this.generateDKIMConfig(config);
2146
+ dnsRecords.push(dkimConfig.dnsRecord);
2147
+ }
2148
+ &nbsp;
2149
+ // Register domain with provider
2150
+ const providerData = await this.registerWithProvider(config, dkimConfig);
2151
+ &nbsp;
2152
+ // Record verification initiation
2153
+ this.addHistoryEntry(config.domain, {
2154
+ eventType: 'initiated',
2155
+ details: `Domain verification initiated for ${config.provider}`,
2156
+ newStatus: 'pending'
2157
+ });
2158
+ &nbsp;
2159
+ // Publish event
2160
+ await this.publishEvent('domain.verification.initiated', {
2161
+ domain: config.domain,
2162
+ provider: config.provider,
2163
+ recordCount: dnsRecords.length
2164
+ });
2165
+ &nbsp;
2166
+ return {
2167
+ success: true,
2168
+ domain: config.domain,
2169
+ status: 'pending',
2170
+ dnsRecords,
2171
+ dkimConfig,
2172
+ providerData,
2173
+ estimatedPropagationTime: 3600, // 1 hour typical
2174
+ nextSteps: [
2175
+ 'Add the DNS records to your domain registrar',
2176
+ 'Wait for DNS propagation (typically 1-24 hours)',
2177
+ 'Use checkPropagation() to monitor DNS propagation status',
2178
+ 'Use verifyDomain() to complete verification with provider'
2179
+ ]
2180
+ };
2181
+ } catch (error) {
2182
+ const errorMessage = error instanceof Error ? error.message : <span class="branch-1 cbranch-no" title="branch not covered" >String(error);</span>
2183
+ this.logger.error(`Domain setup failed for ${config.domain}: ${errorMessage}`);
2184
+ &nbsp;
2185
+ return {
2186
+ success: false,
2187
+ domain: config.domain,
2188
+ status: 'failed',
2189
+ dnsRecords: [],
2190
+ errors: [error instanceof Error ? error.message : <span class="branch-1 cbranch-no" title="branch not covered" >'Unknown error']</span>
2191
+ };
2192
+ }
2193
+ }
2194
+ &nbsp;
2195
+ /**
2196
+ * Check DNS propagation status for domain records
2197
+ *
2198
+ * @param domain - Domain name
2199
+ * @param records - DNS records to check
2200
+ * @returns Propagation results for each record
2201
+ */
2202
+ async checkPropagation(
2203
+ domain: string,
2204
+ records: DNSRecord[]
2205
+ ): Promise&lt;DNSPropagationResult[]&gt; {
2206
+ this.logger.info('Checking DNS propagation', {
2207
+ domain,
2208
+ recordCount: records.length
2209
+ });
2210
+ &nbsp;
2211
+ const results: DNSPropagationResult[] = [];
2212
+ &nbsp;
2213
+ for (const record of records) {
2214
+ try {
2215
+ const result = await this.checkRecordPropagation(domain, record);
2216
+ results.push(result);
2217
+ &nbsp;
2218
+ if (result.propagated &amp;&amp; result.valuesMatch) {
2219
+ this.logger.info('DNS record propagated successfully', {
2220
+ domain,
2221
+ type: record.type,
2222
+ host: record.host
2223
+ });
2224
+ } else {
2225
+ this.logger.warn('DNS record not yet propagated', {
2226
+ domain,
2227
+ type: record.type,
2228
+ host: record.host,
2229
+ propagationPercentage: result.propagationPercentage
2230
+ });
2231
+ }
2232
+ } catch (error) {
2233
+ const errorMessage = <span class="cstat-no" title="statement not covered" >error instanceof Error ? error.message : String(error);</span>
2234
+ <span class="cstat-no" title="statement not covered" > this.logger.error(`Propagation check failed for ${domain} ${record.type}: ${errorMessage}`);</span>
2235
+ &nbsp;
2236
+ <span class="cstat-no" title="statement not covered" > results.push({</span>
2237
+ domain,
2238
+ record,
2239
+ propagated: false,
2240
+ nameservers: [],
2241
+ propagationPercentage: 0,
2242
+ expectedValue: record.value,
2243
+ valuesMatch: false,
2244
+ errors: [error instanceof Error ? error.message : 'Unknown error']
2245
+ });
2246
+ }
2247
+ }
2248
+ &nbsp;
2249
+ // Publish propagation status event
2250
+ const overallPropagation = results.reduce((acc, r) =&gt; acc + r.propagationPercentage, 0) / results.length;
2251
+ await this.publishEvent('domain.propagation.checked', {
2252
+ domain,
2253
+ propagationPercentage: overallPropagation,
2254
+ recordCount: records.length,
2255
+ propagatedCount: results.filter(r =&gt; r.propagated).length
2256
+ });
2257
+ &nbsp;
2258
+ return results;
2259
+ }
2260
+ &nbsp;
2261
+ /**
2262
+ * Verify domain with email provider
2263
+ *
2264
+ * @param domain - Domain name
2265
+ * @param provider - Email provider
2266
+ * @param providerCredentials - Provider API credentials
2267
+ * @returns Verification result
2268
+ */
2269
+ async verifyDomain(
2270
+ domain: string,
2271
+ provider: EmailProvider,
2272
+ providerCredentials: Record&lt;string, unknown&gt;
2273
+ ): Promise&lt;DomainVerificationResult&gt; {
2274
+ this.logger.info('Verifying domain with provider', { domain, provider });
2275
+ &nbsp;
2276
+ try {
2277
+ const providerData = await this.verifyWithProvider(domain, provider, providerCredentials);
2278
+ &nbsp;
2279
+ const status: VerificationStatus = providerData.verified ? 'verified' : 'failed';
2280
+ const detailsMessage = typeof providerData.message === 'string' ? providerData.message : <span class="branch-1 cbranch-no" title="branch not covered" >'Verification completed';</span>
2281
+ &nbsp;
2282
+ this.addHistoryEntry(domain, {
2283
+ eventType: status === 'verified' ? 'verified' : 'failed',
2284
+ details: detailsMessage,
2285
+ newStatus: status,
2286
+ previousStatus: 'propagating'
2287
+ });
2288
+ &nbsp;
2289
+ await this.publishEvent('domain.verification.completed', {
2290
+ domain,
2291
+ provider,
2292
+ status,
2293
+ success: status === 'verified'
2294
+ });
2295
+ &nbsp;
2296
+ // Start health monitoring if verified
2297
+ if (status === 'verified') {
2298
+ this.startHealthMonitoring(domain, provider, providerCredentials);
2299
+ }
2300
+ &nbsp;
2301
+ const errorMessage = typeof providerData.message === 'string' ? providerData.message : <span class="branch-1 cbranch-no" title="branch not covered" >'Verification failed';</span>
2302
+ return {
2303
+ success: status === 'verified',
2304
+ domain,
2305
+ status,
2306
+ dnsRecords: [],
2307
+ providerData,
2308
+ errors: status === 'failed' ? [errorMessage] : undefined
2309
+ };
2310
+ } catch (error) {
2311
+ const errMsg = <span class="cstat-no" title="statement not covered" >error instanceof Error ? error.message : String(error);</span>
2312
+ <span class="cstat-no" title="statement not covered" > this.logger.error(`Domain verification failed for ${domain} with ${provider}: ${errMsg}`);</span>
2313
+ &nbsp;
2314
+ <span class="cstat-no" title="statement not covered" > return {</span>
2315
+ success: false,
2316
+ domain,
2317
+ status: 'failed',
2318
+ dnsRecords: [],
2319
+ errors: [error instanceof Error ? error.message : 'Unknown error']
2320
+ };
2321
+ }
2322
+ }
2323
+ &nbsp;
2324
+ /**
2325
+ * Get domain health status
2326
+ *
2327
+ * @param domain - Domain name
2328
+ * @returns Health status
2329
+ */
2330
+ async getDomainHealth(domain: string): Promise&lt;DomainHealthStatus&gt; {
2331
+ this.logger.info('Checking domain health', { domain });
2332
+ &nbsp;
2333
+ // Implementation would check DNS records, provider status, etc.
2334
+ // Returning basic structure for type safety
2335
+ return {
2336
+ domain,
2337
+ healthy: true,
2338
+ verificationStatus: 'verified',
2339
+ lastChecked: new Date(),
2340
+ records: []
2341
+ };
2342
+ }
2343
+ &nbsp;
2344
+ /**
2345
+ * Get verification history for domain
2346
+ *
2347
+ * @param domain - Domain name
2348
+ * @param limit - Maximum number of entries to return
2349
+ * @returns History entries
2350
+ */
2351
+ getVerificationHistory(domain: string, limit = 50): VerificationHistoryEntry[] {
2352
+ const history = this.verificationHistory.get(domain) || [];
2353
+ return history.slice(-limit);
2354
+ }
2355
+ &nbsp;
2356
+ /**
2357
+ * Start automated health monitoring for domain
2358
+ *
2359
+ * @param domain - Domain name
2360
+ * @param provider - Email provider
2361
+ * @param credentials - Provider credentials
2362
+ */
2363
+ private startHealthMonitoring(
2364
+ domain: string,
2365
+ provider: EmailProvider,
2366
+ credentials: Record&lt;string, unknown&gt;
2367
+ ): void {
2368
+ // Stop existing job if any
2369
+ this.stopHealthMonitoring(domain);
2370
+ &nbsp;
2371
+ // Create new cron job (runs every 6 hours)
2372
+ const job = new CronJob('0 */6 * * *', <span class="fstat-no" title="function not covered" >async </span>() =&gt; {
2373
+ <span class="cstat-no" title="statement not covered" > try {</span>
2374
+ const health = <span class="cstat-no" title="statement not covered" >await this.performHealthCheck(domain, provider, credentials);</span>
2375
+ &nbsp;
2376
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!health.healthy) {</span>
2377
+ <span class="cstat-no" title="statement not covered" > this.logger.warn('Domain health check failed', { domain, warnings: health.warnings });</span>
2378
+ &nbsp;
2379
+ <span class="cstat-no" title="statement not covered" > await this.publishEvent('domain.health.unhealthy', {</span>
2380
+ domain,
2381
+ provider,
2382
+ warnings: health.warnings
2383
+ });
2384
+ }
2385
+ } catch (error) {
2386
+ const errMsg = <span class="cstat-no" title="statement not covered" >error instanceof Error ? error.message : String(error);</span>
2387
+ <span class="cstat-no" title="statement not covered" > this.logger.error(`Health check failed for ${domain}: ${errMsg}`);</span>
2388
+ }
2389
+ });
2390
+ &nbsp;
2391
+ job.start();
2392
+ this.healthCheckJobs.set(domain, job);
2393
+ &nbsp;
2394
+ this.logger.info('Health monitoring started', { domain });
2395
+ }
2396
+ &nbsp;
2397
+ /**
2398
+ * Stop health monitoring for domain
2399
+ *
2400
+ * @param domain - Domain name
2401
+ */
2402
+ stopHealthMonitoring(domain: string): void {
2403
+ const job = this.healthCheckJobs.get(domain);
2404
+ if (job) {
2405
+ job.stop();
2406
+ this.healthCheckJobs.delete(domain);
2407
+ this.logger.info('Health monitoring stopped', { domain });
2408
+ }
2409
+ }
2410
+ &nbsp;
2411
+ /**
2412
+ * Perform health check for domain
2413
+ *
2414
+ * @param domain - Domain name
2415
+ * @param provider - Email provider
2416
+ * @param credentials - Provider credentials
2417
+ * @returns Health status
2418
+ */
2419
+ private <span class="fstat-no" title="function not covered" >async </span>performHealthCheck(
2420
+ domain: string,
2421
+ _provider: EmailProvider,
2422
+ _credentials: Record&lt;string, unknown&gt;
2423
+ ): Promise&lt;DomainHealthStatus&gt; {
2424
+ // Implementation would check DNS records, provider API status, etc.
2425
+ // Returning basic structure for type safety
2426
+ <span class="cstat-no" title="statement not covered" > return {</span>
2427
+ domain,
2428
+ healthy: true,
2429
+ verificationStatus: 'verified',
2430
+ lastChecked: new Date(),
2431
+ records: []
2432
+ };
2433
+ }
2434
+ &nbsp;
2435
+ /**
2436
+ * Generate DNS records for domain configuration
2437
+ */
2438
+ private async generateDNSRecords(config: DomainConfig): Promise&lt;DNSRecord[]&gt; {
2439
+ const records: DNSRecord[] = [];
2440
+ &nbsp;
2441
+ // Generate SPF record
2442
+ if (config.spf.enabled) {
2443
+ records.push(this.generateSPFRecord(config));
2444
+ }
2445
+ &nbsp;
2446
+ // Generate DMARC record
2447
+ if (config.dmarc.enabled) {
2448
+ records.push(this.generateDMARCRecord(config));
2449
+ }
2450
+ &nbsp;
2451
+ // Generate provider-specific records
2452
+ const providerRecords = await this.generateProviderRecords(config);
2453
+ records.push(...providerRecords);
2454
+ &nbsp;
2455
+ return records;
2456
+ }
2457
+ &nbsp;
2458
+ /**
2459
+ * Generate SPF DNS record
2460
+ */
2461
+ private generateSPFRecord(config: DomainConfig): DNSRecord {
2462
+ const includes = config.spf.includes || [];
2463
+ const ipv4s = config.spf.ipv4Addresses || [];
2464
+ const ipv6s = config.spf.ipv6Addresses || [];
2465
+ const strict = config.spf.strict !== false;
2466
+ &nbsp;
2467
+ let spfValue = 'v=spf1';
2468
+ &nbsp;
2469
+ // Add provider-specific includes
2470
+ if (config.provider === 'sendgrid') {
2471
+ includes.push('include:sendgrid.net');
2472
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="else path not taken" >E</span>if (config.provider === 'mailgun') {</span>
2473
+ <span class="cstat-no" title="statement not covered" > includes.push('include:mailgun.org');</span>
2474
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="if path not taken" >I</span>if (config.provider === 'ses') {</span>
2475
+ <span class="cstat-no" title="statement not covered" > includes.push('include:amazonses.com');</span>
2476
+ }
2477
+ &nbsp;
2478
+ includes.forEach(inc =&gt; {
2479
+ spfValue += ` ${inc}`;
2480
+ });
2481
+ &nbsp;
2482
+ ipv4s.forEach(ip =&gt; {
2483
+ spfValue += ` ip4:${ip}`;
2484
+ });
2485
+ &nbsp;
2486
+ ipv6s.forEach(ip =&gt; {
2487
+ spfValue += ` ip6:${ip}`;
2488
+ });
2489
+ &nbsp;
2490
+ spfValue += strict ? ' -all' : ' ~all';
2491
+ &nbsp;
2492
+ return {
2493
+ type: 'SPF',
2494
+ host: config.domain,
2495
+ value: spfValue,
2496
+ ttl: 3600,
2497
+ provider: config.provider,
2498
+ required: true,
2499
+ instructions: `Add this TXT record to your domain:\n\nHost: ${config.domain}\nValue: ${spfValue}\nTTL: 3600`
2500
+ };
2501
+ }
2502
+ &nbsp;
2503
+ /**
2504
+ * Generate DMARC DNS record
2505
+ */
2506
+ private generateDMARCRecord(config: DomainConfig): DNSRecord {
2507
+ const policy = config.dmarc.policy || <span class="branch-1 cbranch-no" title="branch not covered" >'none';</span>
2508
+ const percentage = config.dmarc.percentage || <span class="branch-1 cbranch-no" title="branch not covered" >100;</span>
2509
+ const reportEmail = config.dmarc.reportEmail;
2510
+ const aggregateEmail = config.dmarc.aggregateEmail;
2511
+ const subdomain = config.dmarc.subdomain || 'none';
2512
+ &nbsp;
2513
+ let dmarcValue = `v=DMARC1; p=${policy}; pct=${percentage}; sp=${subdomain};`;
2514
+ &nbsp;
2515
+ if (reportEmail) {
2516
+ dmarcValue += ` rua=mailto:${reportEmail};`;
2517
+ }
2518
+ &nbsp;
2519
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (aggregateEmail) {
2520
+ <span class="cstat-no" title="statement not covered" > dmarcValue += ` ruf=mailto:${aggregateEmail};`;</span>
2521
+ }
2522
+ &nbsp;
2523
+ return {
2524
+ type: 'DMARC',
2525
+ host: `_dmarc.${config.domain}`,
2526
+ value: dmarcValue,
2527
+ ttl: 3600,
2528
+ provider: config.provider,
2529
+ required: true,
2530
+ instructions: `Add this TXT record to your domain:\n\nHost: _dmarc.${config.domain}\nValue: ${dmarcValue}\nTTL: 3600`
2531
+ };
2532
+ }
2533
+ &nbsp;
2534
+ /**
2535
+ * Generate provider-specific DNS records
2536
+ */
2537
+ private async generateProviderRecords(config: DomainConfig): Promise&lt;DNSRecord[]&gt; {
2538
+ switch (config.provider) {
2539
+ case 'sendgrid':
2540
+ return this.generateSendGridRecords(config);
2541
+ case 'mailgun':
2542
+ return this.generateMailgunRecords(config);
2543
+ case 'ses':
2544
+ return this.generateSESRecords(config);
2545
+ <span class="branch-3 cbranch-no" title="branch not covered" > default:</span>
2546
+ <span class="cstat-no" title="statement not covered" > return [];</span>
2547
+ }
2548
+ }
2549
+ &nbsp;
2550
+ /**
2551
+ * Generate SendGrid-specific DNS records
2552
+ */
2553
+ private generateSendGridRecords(config: DomainConfig): DNSRecord[] {
2554
+ const records: DNSRecord[] = [];
2555
+ &nbsp;
2556
+ // SendGrid domain authentication requires CNAME records
2557
+ // These would normally come from SendGrid API
2558
+ records.push({
2559
+ type: 'CNAME',
2560
+ host: `em123.${config.domain}`,
2561
+ value: 'u123.wl.sendgrid.net',
2562
+ ttl: 3600,
2563
+ provider: 'sendgrid',
2564
+ required: true,
2565
+ instructions: 'Add this CNAME record (actual values will come from SendGrid API)'
2566
+ });
2567
+ &nbsp;
2568
+ return records;
2569
+ }
2570
+ &nbsp;
2571
+ /**
2572
+ * Generate Mailgun-specific DNS records
2573
+ */
2574
+ private generateMailgunRecords(config: DomainConfig): DNSRecord[] {
2575
+ const records: DNSRecord[] = [];
2576
+ &nbsp;
2577
+ // Mailgun requires specific TXT records
2578
+ records.push({
2579
+ type: 'TXT',
2580
+ host: config.domain,
2581
+ value: 'v=spf1 include:mailgun.org ~all',
2582
+ ttl: 3600,
2583
+ provider: 'mailgun',
2584
+ required: true,
2585
+ instructions: 'Add this TXT record for Mailgun SPF'
2586
+ });
2587
+ &nbsp;
2588
+ return records;
2589
+ }
2590
+ &nbsp;
2591
+ /**
2592
+ * Generate AWS SES-specific DNS records
2593
+ */
2594
+ private generateSESRecords(config: DomainConfig): DNSRecord[] {
2595
+ const records: DNSRecord[] = [];
2596
+ &nbsp;
2597
+ // SES requires TXT record for verification
2598
+ records.push({
2599
+ type: 'TXT',
2600
+ host: `_amazonses.${config.domain}`,
2601
+ value: 'verification-token-from-ses',
2602
+ ttl: 3600,
2603
+ provider: 'ses',
2604
+ required: true,
2605
+ instructions: 'Add this TXT record (actual token will come from AWS SES)'
2606
+ });
2607
+ &nbsp;
2608
+ return records;
2609
+ }
2610
+ &nbsp;
2611
+ /**
2612
+ * Generate DKIM configuration with keypair
2613
+ */
2614
+ private async generateDKIMConfig(config: DomainConfig): Promise&lt;DKIMConfig&gt; {
2615
+ const selector = config.dkim.selector || <span class="branch-1 cbranch-no" title="branch not covered" >'default';</span>
2616
+ const keySize = config.dkim.keySize || <span class="branch-1 cbranch-no" title="branch not covered" >2048;</span>
2617
+ &nbsp;
2618
+ // Generate DKIM keypair using Node.js crypto
2619
+ const { publicKey, privateKey } = generateKeyPairSync('rsa', {
2620
+ modulusLength: keySize,
2621
+ publicKeyEncoding: {
2622
+ type: 'spki',
2623
+ format: 'pem'
2624
+ },
2625
+ privateKeyEncoding: {
2626
+ type: 'pkcs8',
2627
+ format: 'pem'
2628
+ }
2629
+ });
2630
+ &nbsp;
2631
+ // Format public key for DNS (remove headers/newlines, base64)
2632
+ const publicKeyForDNS = publicKey
2633
+ .replace(/-----BEGIN PUBLIC KEY-----/, '')
2634
+ .replace(/-----END PUBLIC KEY-----/, '')
2635
+ .replace(/\n/g, '')
2636
+ .replace(/\r/g, '');
2637
+ &nbsp;
2638
+ const dkimValue = `v=DKIM1; k=rsa; p=${publicKeyForDNS}`;
2639
+ &nbsp;
2640
+ const dnsRecord: DNSRecord = {
2641
+ type: 'DKIM',
2642
+ host: `${selector}._domainkey.${config.domain}`,
2643
+ value: dkimValue,
2644
+ ttl: 3600,
2645
+ provider: config.provider,
2646
+ required: true,
2647
+ instructions: `Add this TXT record to your domain:\n\nHost: ${selector}._domainkey.${config.domain}\nValue: ${dkimValue}\nTTL: 3600`
2648
+ };
2649
+ &nbsp;
2650
+ return {
2651
+ selector,
2652
+ privateKey,
2653
+ publicKey,
2654
+ keySize,
2655
+ dnsRecord
2656
+ };
2657
+ }
2658
+ &nbsp;
2659
+ /**
2660
+ * Register domain with email provider
2661
+ */
2662
+ private async registerWithProvider(
2663
+ config: DomainConfig,
2664
+ _dkimConfig?: DKIMConfig
2665
+ ): Promise&lt;Record&lt;string, unknown&gt;&gt; {
2666
+ switch (config.provider) {
2667
+ case 'sendgrid':
2668
+ return this.registerWithSendGrid(config);
2669
+ case 'mailgun':
2670
+ return this.registerWithMailgun(config);
2671
+ case 'ses':
2672
+ return this.registerWithSES(config);
2673
+ <span class="branch-3 cbranch-no" title="branch not covered" > default:</span>
2674
+ <span class="cstat-no" title="statement not covered" > return { registered: false, message: 'Provider not supported' };</span>
2675
+ }
2676
+ }
2677
+ &nbsp;
2678
+ /**
2679
+ * Register domain with SendGrid
2680
+ */
2681
+ private async registerWithSendGrid(
2682
+ config: DomainConfig
2683
+ ): Promise&lt;Record&lt;string, unknown&gt;&gt; {
2684
+ try {
2685
+ const response = await this.httpClient.post(
2686
+ 'https://api.sendgrid.com/v3/whitelabel/domains',
2687
+ {
2688
+ domain: config.domain,
2689
+ subdomain: 'em',
2690
+ username: 'sendgrid',
2691
+ ips: [],
2692
+ custom_spf: false,
2693
+ default: true,
2694
+ automatic_security: true
2695
+ },
2696
+ {
2697
+ headers: {
2698
+ Authorization: `Bearer ${config.providerCredentials.apiKey as string}`
2699
+ }
2700
+ }
2701
+ );
2702
+ &nbsp;
2703
+ return {
2704
+ registered: true,
2705
+ domainId: response.data.id,
2706
+ dnsRecords: response.data.dns,
2707
+ message: 'Domain registered with SendGrid'
2708
+ };
2709
+ } catch (error) {
2710
+ const errMsg = <span class="cstat-no" title="statement not covered" >error instanceof Error ? error.message : String(error);</span>
2711
+ <span class="cstat-no" title="statement not covered" > this.logger.error(`SendGrid registration failed for ${config.domain}: ${errMsg}`);</span>
2712
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
2713
+ }
2714
+ }
2715
+ &nbsp;
2716
+ /**
2717
+ * Register domain with Mailgun
2718
+ */
2719
+ private async registerWithMailgun(
2720
+ config: DomainConfig
2721
+ ): Promise&lt;Record&lt;string, unknown&gt;&gt; {
2722
+ try {
2723
+ const response = await this.httpClient.post(
2724
+ 'https://api.mailgun.net/v3/domains',
2725
+ new URLSearchParams({
2726
+ name: config.domain,
2727
+ smtp_password: (config.providerCredentials.smtpPassword as string) || '',
2728
+ spam_action: 'disabled',
2729
+ wildcard: 'false'
2730
+ }),
2731
+ {
2732
+ auth: {
2733
+ username: 'api',
2734
+ password: config.providerCredentials.apiKey as string
2735
+ }
2736
+ }
2737
+ );
2738
+ &nbsp;
2739
+ return {
2740
+ registered: true,
2741
+ domain: response.data.domain,
2742
+ dnsRecords: response.data.receiving_dns_records.concat(response.data.sending_dns_records),
2743
+ message: 'Domain registered with Mailgun'
2744
+ };
2745
+ } catch (error) {
2746
+ const errMsg = <span class="cstat-no" title="statement not covered" >error instanceof Error ? error.message : String(error);</span>
2747
+ <span class="cstat-no" title="statement not covered" > this.logger.error(`Mailgun registration failed for ${config.domain}: ${errMsg}`);</span>
2748
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
2749
+ }
2750
+ }
2751
+ &nbsp;
2752
+ /**
2753
+ * Register domain with AWS SES
2754
+ */
2755
+ private async registerWithSES(
2756
+ config: DomainConfig
2757
+ ): Promise&lt;Record&lt;string, unknown&gt;&gt; {
2758
+ // AWS SES registration would use AWS SDK
2759
+ // This is a placeholder implementation
2760
+ this.logger.info('AWS SES registration not yet implemented', {
2761
+ domain: config.domain
2762
+ });
2763
+ &nbsp;
2764
+ return {
2765
+ registered: false,
2766
+ message: 'AWS SES registration requires AWS SDK integration'
2767
+ };
2768
+ }
2769
+ &nbsp;
2770
+ /**
2771
+ * Verify domain with email provider
2772
+ */
2773
+ private <span class="fstat-no" title="function not covered" >async </span>verifyWithProvider(
2774
+ domain: string,
2775
+ provider: EmailProvider,
2776
+ credentials: Record&lt;string, unknown&gt;
2777
+ ): Promise&lt;Record&lt;string, unknown&gt;&gt; {
2778
+ <span class="cstat-no" title="statement not covered" > switch (provider) {</span>
2779
+ case 'sendgrid':
2780
+ <span class="cstat-no" title="statement not covered" > return this.verifyWithSendGrid(domain, credentials);</span>
2781
+ case 'mailgun':
2782
+ <span class="cstat-no" title="statement not covered" > return this.verifyWithMailgun(domain, credentials);</span>
2783
+ case 'ses':
2784
+ <span class="cstat-no" title="statement not covered" > return this.verifyWithSES(domain, credentials);</span>
2785
+ default:
2786
+ <span class="cstat-no" title="statement not covered" > return { verified: false, message: 'Provider not supported' };</span>
2787
+ }
2788
+ }
2789
+ &nbsp;
2790
+ /**
2791
+ * Verify domain with SendGrid
2792
+ */
2793
+ private <span class="fstat-no" title="function not covered" >async </span>verifyWithSendGrid(
2794
+ domain: string,
2795
+ credentials: Record&lt;string, unknown&gt;
2796
+ ): Promise&lt;Record&lt;string, unknown&gt;&gt; {
2797
+ <span class="cstat-no" title="statement not covered" > try {</span>
2798
+ // Get domain ID from SendGrid
2799
+ const domainsResponse = <span class="cstat-no" title="statement not covered" >await this.httpClient.get(</span>
2800
+ 'https://api.sendgrid.com/v3/whitelabel/domains',
2801
+ {
2802
+ headers: {
2803
+ Authorization: `Bearer ${credentials.apiKey as string}`
2804
+ }
2805
+ }
2806
+ );
2807
+ &nbsp;
2808
+ const domainData = <span class="cstat-no" title="statement not covered" >domainsResponse.data.find(<span class="fstat-no" title="function not covered" >(d</span>: { domain: string }) =&gt; <span class="cstat-no" title="statement not covered" >d.domain === domain)</span>;</span>
2809
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!domainData) {</span>
2810
+ <span class="cstat-no" title="statement not covered" > return { verified: false, message: 'Domain not found in SendGrid' };</span>
2811
+ }
2812
+ &nbsp;
2813
+ // Trigger verification
2814
+ const verifyResponse = <span class="cstat-no" title="statement not covered" >await this.httpClient.post(</span>
2815
+ `https://api.sendgrid.com/v3/whitelabel/domains/${domainData.id}/validate`,
2816
+ {},
2817
+ {
2818
+ headers: {
2819
+ Authorization: `Bearer ${credentials.apiKey as string}`
2820
+ }
2821
+ }
2822
+ );
2823
+ &nbsp;
2824
+ <span class="cstat-no" title="statement not covered" > return {</span>
2825
+ verified: verifyResponse.data.valid,
2826
+ validationResults: verifyResponse.data.validation_results,
2827
+ message: verifyResponse.data.valid ? 'Domain verified' : 'Verification failed'
2828
+ };
2829
+ } catch (error) {
2830
+ const errMsg = <span class="cstat-no" title="statement not covered" >error instanceof Error ? error.message : String(error);</span>
2831
+ <span class="cstat-no" title="statement not covered" > this.logger.error(`SendGrid verification failed for ${domain}: ${errMsg}`);</span>
2832
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
2833
+ }
2834
+ }
2835
+ &nbsp;
2836
+ /**
2837
+ * Verify domain with Mailgun
2838
+ */
2839
+ private <span class="fstat-no" title="function not covered" >async </span>verifyWithMailgun(
2840
+ domain: string,
2841
+ credentials: Record&lt;string, unknown&gt;
2842
+ ): Promise&lt;Record&lt;string, unknown&gt;&gt; {
2843
+ <span class="cstat-no" title="statement not covered" > try {</span>
2844
+ const response = <span class="cstat-no" title="statement not covered" >await this.httpClient.get(</span>
2845
+ `https://api.mailgun.net/v3/domains/${domain}`,
2846
+ {
2847
+ auth: {
2848
+ username: 'api',
2849
+ password: credentials.apiKey as string
2850
+ }
2851
+ }
2852
+ );
2853
+ &nbsp;
2854
+ <span class="cstat-no" title="statement not covered" > return {</span>
2855
+ verified: response.data.domain.state === 'active',
2856
+ state: response.data.domain.state,
2857
+ message: response.data.domain.state === 'active' ? 'Domain verified' : 'Verification pending'
2858
+ };
2859
+ } catch (error) {
2860
+ const errMsg = <span class="cstat-no" title="statement not covered" >error instanceof Error ? error.message : String(error);</span>
2861
+ <span class="cstat-no" title="statement not covered" > this.logger.error(`Mailgun verification failed for ${domain}: ${errMsg}`);</span>
2862
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
2863
+ }
2864
+ }
2865
+ &nbsp;
2866
+ /**
2867
+ * Verify domain with AWS SES
2868
+ */
2869
+ private <span class="fstat-no" title="function not covered" >async </span>verifyWithSES(
2870
+ domain: string,
2871
+ _credentials: Record&lt;string, unknown&gt;
2872
+ ): Promise&lt;Record&lt;string, unknown&gt;&gt; {
2873
+ // AWS SES verification would use AWS SDK
2874
+ <span class="cstat-no" title="statement not covered" > this.logger.info('AWS SES verification not yet implemented', { domain });</span>
2875
+ &nbsp;
2876
+ <span class="cstat-no" title="statement not covered" > return {</span>
2877
+ verified: false,
2878
+ message: 'AWS SES verification requires AWS SDK integration'
2879
+ };
2880
+ }
2881
+ &nbsp;
2882
+ /**
2883
+ * Check propagation for single DNS record
2884
+ */
2885
+ private async checkRecordPropagation(
2886
+ domain: string,
2887
+ record: DNSRecord
2888
+ ): Promise&lt;DNSPropagationResult&gt; {
2889
+ const nameservers = await this.getNameservers(domain);
2890
+ const results: { ns: string; value?: string; error?: string }[] = [];
2891
+ &nbsp;
2892
+ for (const ns of nameservers) {
2893
+ try {
2894
+ const resolver = new Resolver({ nameServers: [ns] });
2895
+ const response = await resolver.resolve(record.host, 'TXT');
2896
+ const value = response.answers
2897
+ .filter((a: { type: string }) =&gt; a.type === 'TXT')
2898
+ .map((a: { data: string }) =&gt; a.data)
2899
+ .join('');
2900
+ &nbsp;
2901
+ results.push({ ns, value });
2902
+ } catch (error) {
2903
+ <span class="cstat-no" title="statement not covered" > results.push({</span>
2904
+ ns,
2905
+ error: error instanceof Error ? error.message : 'Unknown error'
2906
+ });
2907
+ }
2908
+ }
2909
+ &nbsp;
2910
+ const propagatedCount = results.filter(
2911
+ r =&gt; r.value &amp;&amp; r.value.includes(record.value.substring(0, 20))
2912
+ ).length;
2913
+ &nbsp;
2914
+ const propagationPercentage = (propagatedCount / nameservers.length) * 100;
2915
+ const propagated = propagationPercentage &gt;= 80; // 80% threshold
2916
+ const actualValue = results.find(r =&gt; r.value)?.value;
2917
+ const valuesMatch = actualValue?.includes(record.value.substring(0, 20)) || false;
2918
+ &nbsp;
2919
+ return {
2920
+ domain,
2921
+ record,
2922
+ propagated,
2923
+ nameservers,
2924
+ propagationPercentage,
2925
+ actualValue,
2926
+ expectedValue: record.value,
2927
+ valuesMatch,
2928
+ errors: results.filter(r =&gt; r.error).map(<span class="fstat-no" title="function not covered" >r </span>=&gt; <span class="cstat-no" title="statement not covered" >r.error!)</span>
2929
+ };
2930
+ }
2931
+ &nbsp;
2932
+ /**
2933
+ * Get nameservers for domain
2934
+ */
2935
+ private async getNameservers(domain: string): Promise&lt;string[]&gt; {
2936
+ try {
2937
+ const resolver = new Resolver();
2938
+ const response = await resolver.resolve(domain, 'NS');
2939
+ return response.answers
2940
+ .filter((a) =&gt; a.ns !== undefined)
2941
+ .map((a) =&gt; a.ns as string);
2942
+ } catch (error) {
2943
+ const errMsg = <span class="cstat-no" title="statement not covered" >error instanceof Error ? error.message : String(error);</span>
2944
+ <span class="cstat-no" title="statement not covered" > this.logger.warn(`Failed to get nameservers for ${domain}, using defaults: ${errMsg}`);</span>
2945
+ &nbsp;
2946
+ // Return common public DNS servers as fallback
2947
+ <span class="cstat-no" title="statement not covered" > return [</span>
2948
+ '8.8.8.8', // Google
2949
+ '1.1.1.1', // Cloudflare
2950
+ '208.67.222.222' // OpenDNS
2951
+ ];
2952
+ }
2953
+ }
2954
+ &nbsp;
2955
+ /**
2956
+ * Validate domain name format
2957
+ */
2958
+ private validateDomain(domain: string): void {
2959
+ const domainRegex = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$/i;
2960
+ &nbsp;
2961
+ if (!domainRegex.test(domain)) {
2962
+ throw new InvalidDomainError(`Invalid domain name: ${domain}`);
2963
+ }
2964
+ }
2965
+ &nbsp;
2966
+ /**
2967
+ * Add entry to verification history
2968
+ */
2969
+ private async addHistoryEntry(
2970
+ domain: string,
2971
+ entry: Omit&lt;VerificationHistoryEntry, 'id' | 'domain' | 'timestamp'&gt;
2972
+ ): Promise&lt;void&gt; {
2973
+ const history = this.verificationHistory.get(domain) || [];
2974
+ &nbsp;
2975
+ const result = await generateUUIDKey();
2976
+ history.push({
2977
+ id: result.key,
2978
+ domain,
2979
+ timestamp: new Date(),
2980
+ ...entry
2981
+ });
2982
+ &nbsp;
2983
+ this.verificationHistory.set(domain, history);
2984
+ }
2985
+ &nbsp;
2986
+ /**
2987
+ * Register with NeverHub
2988
+ */
2989
+ private <span class="fstat-no" title="function not covered" >async </span>registerWithNeverHub(): Promise&lt;void&gt; {
2990
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!this.neverhub) <span class="cstat-no" title="statement not covered" >return;</span></span>
2991
+ &nbsp;
2992
+ <span class="cstat-no" title="statement not covered" > await this.neverhub.register({</span>
2993
+ type: 'email-domain-verification',
2994
+ name: '@bernierllc/email-domain-verification',
2995
+ version: '1.0.0',
2996
+ capabilities: [
2997
+ { type: 'email', name: 'domain-verification', version: '1.0.0' },
2998
+ { type: 'dns', name: 'record-management', version: '1.0.0' },
2999
+ { type: 'monitoring', name: 'health-checks', version: '1.0.0' }
3000
+ ],
3001
+ dependencies: ['logging', 'crypto']
3002
+ });
3003
+ &nbsp;
3004
+ <span class="cstat-no" title="statement not covered" > this.logger.info('Registered with NeverHub');</span>
3005
+ }
3006
+ &nbsp;
3007
+ /**
3008
+ * Publish event to NeverHub
3009
+ */
3010
+ private async publishEvent(eventType: string, data: Record&lt;string, unknown&gt;): Promise&lt;void&gt; {
3011
+ if (!this.neverhub) return;
3012
+ &nbsp;
3013
+ try {
3014
+ await this.neverhub.publishEvent({
3015
+ type: eventType,
3016
+ data,
3017
+ source: '@bernierllc/email-domain-verification',
3018
+ timestamp: new Date().toISOString()
3019
+ });
3020
+ } catch (error) {
3021
+ <span class="cstat-no" title="statement not covered" > this.logger.warn('Failed to publish event to NeverHub', {</span>
3022
+ eventType,
3023
+ error: error instanceof Error ? error.message : String(error)
3024
+ });
3025
+ }
3026
+ }
3027
+ &nbsp;
3028
+ /**
3029
+ * Cleanup resources
3030
+ */
3031
+ async shutdown(): Promise&lt;void&gt; {
3032
+ // Stop all health monitoring jobs
3033
+ for (const [domain, job] of this.healthCheckJobs.entries()) {
3034
+ job.stop();
3035
+ this.logger.info('Stopped health monitoring', { domain });
3036
+ }
3037
+ &nbsp;
3038
+ this.healthCheckJobs.clear();
3039
+ this.logger.info('Email Domain Verification Service shut down');
3040
+ }
3041
+ }
3042
+ &nbsp;</pre></td></tr></table></pre>
3043
+
3044
+ <div class='push'></div><!-- for sticky footer -->
3045
+ </div><!-- /wrapper -->
3046
+ <div class='footer quiet pad2 space-top1 center small'>
3047
+ Code coverage generated by
3048
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
3049
+ at 2025-11-25T22:13:36.808Z
3050
+ </div>
3051
+ <script src="prettify.js"></script>
3052
+ <script>
3053
+ window.onload = function () {
3054
+ prettyPrint();
3055
+ };
3056
+ </script>
3057
+ <script src="sorter.js"></script>
3058
+ <script src="block-navigation.js"></script>
3059
+ </body>
3060
+ </html>
3061
+