@lexho111/plainblog 0.5.28 → 0.6.1

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 (64) hide show
  1. package/Article.js +73 -4
  2. package/Blog.js +342 -140
  3. package/Formatter.js +2 -11
  4. package/README.md +1 -1
  5. package/{blog → blog_test_empty.db} +0 -0
  6. package/blog_test_load.db +0 -0
  7. package/build-scripts.js +54 -0
  8. package/coverage/clover.xml +1051 -0
  9. package/coverage/coverage-final.json +20 -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/favicon.png +0 -0
  13. package/coverage/lcov-report/index.html +161 -0
  14. package/coverage/lcov-report/package/Article.js.html +406 -0
  15. package/coverage/lcov-report/package/Blog.js.html +2674 -0
  16. package/coverage/lcov-report/package/Formatter.js.html +379 -0
  17. package/coverage/lcov-report/package/build-scripts.js.html +247 -0
  18. package/coverage/lcov-report/package/build-styles.js.html +367 -0
  19. package/coverage/lcov-report/package/index.html +191 -0
  20. package/coverage/lcov-report/package/model/APIModel.js.html +190 -0
  21. package/coverage/lcov-report/package/model/ArrayList.js.html +382 -0
  22. package/coverage/lcov-report/package/model/ArrayListHashMap.js.html +379 -0
  23. package/coverage/lcov-report/package/model/BinarySearchTree.js.html +856 -0
  24. package/coverage/lcov-report/package/model/BinarySearchTreeHashMap.js.html +346 -0
  25. package/coverage/lcov-report/package/model/DataModel.js.html +322 -0
  26. package/coverage/lcov-report/package/model/DatabaseModel.js.html +232 -0
  27. package/coverage/lcov-report/package/model/FileAdapter.js.html +394 -0
  28. package/coverage/lcov-report/package/model/FileList.js.html +244 -0
  29. package/coverage/lcov-report/package/model/FileModel.js.html +358 -0
  30. package/coverage/lcov-report/package/model/SequelizeAdapter.js.html +538 -0
  31. package/coverage/lcov-report/package/model/SqliteAdapter.js.html +247 -0
  32. package/coverage/lcov-report/package/model/datastructures/ArrayList.js.html +439 -0
  33. package/coverage/lcov-report/package/model/datastructures/ArrayListHashMap.js.html +196 -0
  34. package/coverage/lcov-report/package/model/datastructures/BinarySearchTree.js.html +913 -0
  35. package/coverage/lcov-report/package/model/datastructures/BinarySearchTreeHashMap.js.html +352 -0
  36. package/coverage/lcov-report/package/model/datastructures/FileList.js.html +244 -0
  37. package/coverage/lcov-report/package/model/datastructures/index.html +176 -0
  38. package/coverage/lcov-report/package/model/index.html +206 -0
  39. package/coverage/lcov-report/package/utilities.js.html +511 -0
  40. package/coverage/lcov-report/prettify.css +1 -0
  41. package/coverage/lcov-report/prettify.js +2 -0
  42. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  43. package/coverage/lcov-report/sorter.js +210 -0
  44. package/coverage/lcov.info +2078 -0
  45. package/index.js +25 -1
  46. package/model/DataModel.js +80 -0
  47. package/model/DatabaseModel.js +21 -8
  48. package/model/FileAdapter.js +44 -4
  49. package/model/FileModel.js +48 -9
  50. package/model/SequelizeAdapter.js +11 -3
  51. package/model/datastructures/ArrayList.js +118 -0
  52. package/model/datastructures/ArrayListHashMap.js +37 -0
  53. package/model/datastructures/ArrayListHashMap.js.bk +90 -0
  54. package/model/datastructures/BinarySearchTree.js +277 -0
  55. package/model/datastructures/BinarySearchTreeHashMap.js +90 -0
  56. package/model/datastructures/BinarySearchTreeTest.js +16 -0
  57. package/model/datastructures/FileList.js +53 -0
  58. package/package.json +9 -3
  59. package/public/fetchData.js +0 -0
  60. package/public/scripts.min.js +2 -1
  61. package/public/styles.min.css +2 -1
  62. package/src/fetchData.js +150 -30
  63. package/src/styles.css +29 -0
  64. package/utilities.js +142 -0
@@ -0,0 +1,2674 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for package/Blog.js</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../prettify.css" />
9
+ <link rel="stylesheet" href="../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../index.html">All files</a> / <a href="index.html">package</a> Blog.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">74.1% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>289/390</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">58.56% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>106/181</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">88% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>44/50</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">74.86% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>277/370</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line medium'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a>
388
+ <a name='L323'></a><a href='#L323'>323</a>
389
+ <a name='L324'></a><a href='#L324'>324</a>
390
+ <a name='L325'></a><a href='#L325'>325</a>
391
+ <a name='L326'></a><a href='#L326'>326</a>
392
+ <a name='L327'></a><a href='#L327'>327</a>
393
+ <a name='L328'></a><a href='#L328'>328</a>
394
+ <a name='L329'></a><a href='#L329'>329</a>
395
+ <a name='L330'></a><a href='#L330'>330</a>
396
+ <a name='L331'></a><a href='#L331'>331</a>
397
+ <a name='L332'></a><a href='#L332'>332</a>
398
+ <a name='L333'></a><a href='#L333'>333</a>
399
+ <a name='L334'></a><a href='#L334'>334</a>
400
+ <a name='L335'></a><a href='#L335'>335</a>
401
+ <a name='L336'></a><a href='#L336'>336</a>
402
+ <a name='L337'></a><a href='#L337'>337</a>
403
+ <a name='L338'></a><a href='#L338'>338</a>
404
+ <a name='L339'></a><a href='#L339'>339</a>
405
+ <a name='L340'></a><a href='#L340'>340</a>
406
+ <a name='L341'></a><a href='#L341'>341</a>
407
+ <a name='L342'></a><a href='#L342'>342</a>
408
+ <a name='L343'></a><a href='#L343'>343</a>
409
+ <a name='L344'></a><a href='#L344'>344</a>
410
+ <a name='L345'></a><a href='#L345'>345</a>
411
+ <a name='L346'></a><a href='#L346'>346</a>
412
+ <a name='L347'></a><a href='#L347'>347</a>
413
+ <a name='L348'></a><a href='#L348'>348</a>
414
+ <a name='L349'></a><a href='#L349'>349</a>
415
+ <a name='L350'></a><a href='#L350'>350</a>
416
+ <a name='L351'></a><a href='#L351'>351</a>
417
+ <a name='L352'></a><a href='#L352'>352</a>
418
+ <a name='L353'></a><a href='#L353'>353</a>
419
+ <a name='L354'></a><a href='#L354'>354</a>
420
+ <a name='L355'></a><a href='#L355'>355</a>
421
+ <a name='L356'></a><a href='#L356'>356</a>
422
+ <a name='L357'></a><a href='#L357'>357</a>
423
+ <a name='L358'></a><a href='#L358'>358</a>
424
+ <a name='L359'></a><a href='#L359'>359</a>
425
+ <a name='L360'></a><a href='#L360'>360</a>
426
+ <a name='L361'></a><a href='#L361'>361</a>
427
+ <a name='L362'></a><a href='#L362'>362</a>
428
+ <a name='L363'></a><a href='#L363'>363</a>
429
+ <a name='L364'></a><a href='#L364'>364</a>
430
+ <a name='L365'></a><a href='#L365'>365</a>
431
+ <a name='L366'></a><a href='#L366'>366</a>
432
+ <a name='L367'></a><a href='#L367'>367</a>
433
+ <a name='L368'></a><a href='#L368'>368</a>
434
+ <a name='L369'></a><a href='#L369'>369</a>
435
+ <a name='L370'></a><a href='#L370'>370</a>
436
+ <a name='L371'></a><a href='#L371'>371</a>
437
+ <a name='L372'></a><a href='#L372'>372</a>
438
+ <a name='L373'></a><a href='#L373'>373</a>
439
+ <a name='L374'></a><a href='#L374'>374</a>
440
+ <a name='L375'></a><a href='#L375'>375</a>
441
+ <a name='L376'></a><a href='#L376'>376</a>
442
+ <a name='L377'></a><a href='#L377'>377</a>
443
+ <a name='L378'></a><a href='#L378'>378</a>
444
+ <a name='L379'></a><a href='#L379'>379</a>
445
+ <a name='L380'></a><a href='#L380'>380</a>
446
+ <a name='L381'></a><a href='#L381'>381</a>
447
+ <a name='L382'></a><a href='#L382'>382</a>
448
+ <a name='L383'></a><a href='#L383'>383</a>
449
+ <a name='L384'></a><a href='#L384'>384</a>
450
+ <a name='L385'></a><a href='#L385'>385</a>
451
+ <a name='L386'></a><a href='#L386'>386</a>
452
+ <a name='L387'></a><a href='#L387'>387</a>
453
+ <a name='L388'></a><a href='#L388'>388</a>
454
+ <a name='L389'></a><a href='#L389'>389</a>
455
+ <a name='L390'></a><a href='#L390'>390</a>
456
+ <a name='L391'></a><a href='#L391'>391</a>
457
+ <a name='L392'></a><a href='#L392'>392</a>
458
+ <a name='L393'></a><a href='#L393'>393</a>
459
+ <a name='L394'></a><a href='#L394'>394</a>
460
+ <a name='L395'></a><a href='#L395'>395</a>
461
+ <a name='L396'></a><a href='#L396'>396</a>
462
+ <a name='L397'></a><a href='#L397'>397</a>
463
+ <a name='L398'></a><a href='#L398'>398</a>
464
+ <a name='L399'></a><a href='#L399'>399</a>
465
+ <a name='L400'></a><a href='#L400'>400</a>
466
+ <a name='L401'></a><a href='#L401'>401</a>
467
+ <a name='L402'></a><a href='#L402'>402</a>
468
+ <a name='L403'></a><a href='#L403'>403</a>
469
+ <a name='L404'></a><a href='#L404'>404</a>
470
+ <a name='L405'></a><a href='#L405'>405</a>
471
+ <a name='L406'></a><a href='#L406'>406</a>
472
+ <a name='L407'></a><a href='#L407'>407</a>
473
+ <a name='L408'></a><a href='#L408'>408</a>
474
+ <a name='L409'></a><a href='#L409'>409</a>
475
+ <a name='L410'></a><a href='#L410'>410</a>
476
+ <a name='L411'></a><a href='#L411'>411</a>
477
+ <a name='L412'></a><a href='#L412'>412</a>
478
+ <a name='L413'></a><a href='#L413'>413</a>
479
+ <a name='L414'></a><a href='#L414'>414</a>
480
+ <a name='L415'></a><a href='#L415'>415</a>
481
+ <a name='L416'></a><a href='#L416'>416</a>
482
+ <a name='L417'></a><a href='#L417'>417</a>
483
+ <a name='L418'></a><a href='#L418'>418</a>
484
+ <a name='L419'></a><a href='#L419'>419</a>
485
+ <a name='L420'></a><a href='#L420'>420</a>
486
+ <a name='L421'></a><a href='#L421'>421</a>
487
+ <a name='L422'></a><a href='#L422'>422</a>
488
+ <a name='L423'></a><a href='#L423'>423</a>
489
+ <a name='L424'></a><a href='#L424'>424</a>
490
+ <a name='L425'></a><a href='#L425'>425</a>
491
+ <a name='L426'></a><a href='#L426'>426</a>
492
+ <a name='L427'></a><a href='#L427'>427</a>
493
+ <a name='L428'></a><a href='#L428'>428</a>
494
+ <a name='L429'></a><a href='#L429'>429</a>
495
+ <a name='L430'></a><a href='#L430'>430</a>
496
+ <a name='L431'></a><a href='#L431'>431</a>
497
+ <a name='L432'></a><a href='#L432'>432</a>
498
+ <a name='L433'></a><a href='#L433'>433</a>
499
+ <a name='L434'></a><a href='#L434'>434</a>
500
+ <a name='L435'></a><a href='#L435'>435</a>
501
+ <a name='L436'></a><a href='#L436'>436</a>
502
+ <a name='L437'></a><a href='#L437'>437</a>
503
+ <a name='L438'></a><a href='#L438'>438</a>
504
+ <a name='L439'></a><a href='#L439'>439</a>
505
+ <a name='L440'></a><a href='#L440'>440</a>
506
+ <a name='L441'></a><a href='#L441'>441</a>
507
+ <a name='L442'></a><a href='#L442'>442</a>
508
+ <a name='L443'></a><a href='#L443'>443</a>
509
+ <a name='L444'></a><a href='#L444'>444</a>
510
+ <a name='L445'></a><a href='#L445'>445</a>
511
+ <a name='L446'></a><a href='#L446'>446</a>
512
+ <a name='L447'></a><a href='#L447'>447</a>
513
+ <a name='L448'></a><a href='#L448'>448</a>
514
+ <a name='L449'></a><a href='#L449'>449</a>
515
+ <a name='L450'></a><a href='#L450'>450</a>
516
+ <a name='L451'></a><a href='#L451'>451</a>
517
+ <a name='L452'></a><a href='#L452'>452</a>
518
+ <a name='L453'></a><a href='#L453'>453</a>
519
+ <a name='L454'></a><a href='#L454'>454</a>
520
+ <a name='L455'></a><a href='#L455'>455</a>
521
+ <a name='L456'></a><a href='#L456'>456</a>
522
+ <a name='L457'></a><a href='#L457'>457</a>
523
+ <a name='L458'></a><a href='#L458'>458</a>
524
+ <a name='L459'></a><a href='#L459'>459</a>
525
+ <a name='L460'></a><a href='#L460'>460</a>
526
+ <a name='L461'></a><a href='#L461'>461</a>
527
+ <a name='L462'></a><a href='#L462'>462</a>
528
+ <a name='L463'></a><a href='#L463'>463</a>
529
+ <a name='L464'></a><a href='#L464'>464</a>
530
+ <a name='L465'></a><a href='#L465'>465</a>
531
+ <a name='L466'></a><a href='#L466'>466</a>
532
+ <a name='L467'></a><a href='#L467'>467</a>
533
+ <a name='L468'></a><a href='#L468'>468</a>
534
+ <a name='L469'></a><a href='#L469'>469</a>
535
+ <a name='L470'></a><a href='#L470'>470</a>
536
+ <a name='L471'></a><a href='#L471'>471</a>
537
+ <a name='L472'></a><a href='#L472'>472</a>
538
+ <a name='L473'></a><a href='#L473'>473</a>
539
+ <a name='L474'></a><a href='#L474'>474</a>
540
+ <a name='L475'></a><a href='#L475'>475</a>
541
+ <a name='L476'></a><a href='#L476'>476</a>
542
+ <a name='L477'></a><a href='#L477'>477</a>
543
+ <a name='L478'></a><a href='#L478'>478</a>
544
+ <a name='L479'></a><a href='#L479'>479</a>
545
+ <a name='L480'></a><a href='#L480'>480</a>
546
+ <a name='L481'></a><a href='#L481'>481</a>
547
+ <a name='L482'></a><a href='#L482'>482</a>
548
+ <a name='L483'></a><a href='#L483'>483</a>
549
+ <a name='L484'></a><a href='#L484'>484</a>
550
+ <a name='L485'></a><a href='#L485'>485</a>
551
+ <a name='L486'></a><a href='#L486'>486</a>
552
+ <a name='L487'></a><a href='#L487'>487</a>
553
+ <a name='L488'></a><a href='#L488'>488</a>
554
+ <a name='L489'></a><a href='#L489'>489</a>
555
+ <a name='L490'></a><a href='#L490'>490</a>
556
+ <a name='L491'></a><a href='#L491'>491</a>
557
+ <a name='L492'></a><a href='#L492'>492</a>
558
+ <a name='L493'></a><a href='#L493'>493</a>
559
+ <a name='L494'></a><a href='#L494'>494</a>
560
+ <a name='L495'></a><a href='#L495'>495</a>
561
+ <a name='L496'></a><a href='#L496'>496</a>
562
+ <a name='L497'></a><a href='#L497'>497</a>
563
+ <a name='L498'></a><a href='#L498'>498</a>
564
+ <a name='L499'></a><a href='#L499'>499</a>
565
+ <a name='L500'></a><a href='#L500'>500</a>
566
+ <a name='L501'></a><a href='#L501'>501</a>
567
+ <a name='L502'></a><a href='#L502'>502</a>
568
+ <a name='L503'></a><a href='#L503'>503</a>
569
+ <a name='L504'></a><a href='#L504'>504</a>
570
+ <a name='L505'></a><a href='#L505'>505</a>
571
+ <a name='L506'></a><a href='#L506'>506</a>
572
+ <a name='L507'></a><a href='#L507'>507</a>
573
+ <a name='L508'></a><a href='#L508'>508</a>
574
+ <a name='L509'></a><a href='#L509'>509</a>
575
+ <a name='L510'></a><a href='#L510'>510</a>
576
+ <a name='L511'></a><a href='#L511'>511</a>
577
+ <a name='L512'></a><a href='#L512'>512</a>
578
+ <a name='L513'></a><a href='#L513'>513</a>
579
+ <a name='L514'></a><a href='#L514'>514</a>
580
+ <a name='L515'></a><a href='#L515'>515</a>
581
+ <a name='L516'></a><a href='#L516'>516</a>
582
+ <a name='L517'></a><a href='#L517'>517</a>
583
+ <a name='L518'></a><a href='#L518'>518</a>
584
+ <a name='L519'></a><a href='#L519'>519</a>
585
+ <a name='L520'></a><a href='#L520'>520</a>
586
+ <a name='L521'></a><a href='#L521'>521</a>
587
+ <a name='L522'></a><a href='#L522'>522</a>
588
+ <a name='L523'></a><a href='#L523'>523</a>
589
+ <a name='L524'></a><a href='#L524'>524</a>
590
+ <a name='L525'></a><a href='#L525'>525</a>
591
+ <a name='L526'></a><a href='#L526'>526</a>
592
+ <a name='L527'></a><a href='#L527'>527</a>
593
+ <a name='L528'></a><a href='#L528'>528</a>
594
+ <a name='L529'></a><a href='#L529'>529</a>
595
+ <a name='L530'></a><a href='#L530'>530</a>
596
+ <a name='L531'></a><a href='#L531'>531</a>
597
+ <a name='L532'></a><a href='#L532'>532</a>
598
+ <a name='L533'></a><a href='#L533'>533</a>
599
+ <a name='L534'></a><a href='#L534'>534</a>
600
+ <a name='L535'></a><a href='#L535'>535</a>
601
+ <a name='L536'></a><a href='#L536'>536</a>
602
+ <a name='L537'></a><a href='#L537'>537</a>
603
+ <a name='L538'></a><a href='#L538'>538</a>
604
+ <a name='L539'></a><a href='#L539'>539</a>
605
+ <a name='L540'></a><a href='#L540'>540</a>
606
+ <a name='L541'></a><a href='#L541'>541</a>
607
+ <a name='L542'></a><a href='#L542'>542</a>
608
+ <a name='L543'></a><a href='#L543'>543</a>
609
+ <a name='L544'></a><a href='#L544'>544</a>
610
+ <a name='L545'></a><a href='#L545'>545</a>
611
+ <a name='L546'></a><a href='#L546'>546</a>
612
+ <a name='L547'></a><a href='#L547'>547</a>
613
+ <a name='L548'></a><a href='#L548'>548</a>
614
+ <a name='L549'></a><a href='#L549'>549</a>
615
+ <a name='L550'></a><a href='#L550'>550</a>
616
+ <a name='L551'></a><a href='#L551'>551</a>
617
+ <a name='L552'></a><a href='#L552'>552</a>
618
+ <a name='L553'></a><a href='#L553'>553</a>
619
+ <a name='L554'></a><a href='#L554'>554</a>
620
+ <a name='L555'></a><a href='#L555'>555</a>
621
+ <a name='L556'></a><a href='#L556'>556</a>
622
+ <a name='L557'></a><a href='#L557'>557</a>
623
+ <a name='L558'></a><a href='#L558'>558</a>
624
+ <a name='L559'></a><a href='#L559'>559</a>
625
+ <a name='L560'></a><a href='#L560'>560</a>
626
+ <a name='L561'></a><a href='#L561'>561</a>
627
+ <a name='L562'></a><a href='#L562'>562</a>
628
+ <a name='L563'></a><a href='#L563'>563</a>
629
+ <a name='L564'></a><a href='#L564'>564</a>
630
+ <a name='L565'></a><a href='#L565'>565</a>
631
+ <a name='L566'></a><a href='#L566'>566</a>
632
+ <a name='L567'></a><a href='#L567'>567</a>
633
+ <a name='L568'></a><a href='#L568'>568</a>
634
+ <a name='L569'></a><a href='#L569'>569</a>
635
+ <a name='L570'></a><a href='#L570'>570</a>
636
+ <a name='L571'></a><a href='#L571'>571</a>
637
+ <a name='L572'></a><a href='#L572'>572</a>
638
+ <a name='L573'></a><a href='#L573'>573</a>
639
+ <a name='L574'></a><a href='#L574'>574</a>
640
+ <a name='L575'></a><a href='#L575'>575</a>
641
+ <a name='L576'></a><a href='#L576'>576</a>
642
+ <a name='L577'></a><a href='#L577'>577</a>
643
+ <a name='L578'></a><a href='#L578'>578</a>
644
+ <a name='L579'></a><a href='#L579'>579</a>
645
+ <a name='L580'></a><a href='#L580'>580</a>
646
+ <a name='L581'></a><a href='#L581'>581</a>
647
+ <a name='L582'></a><a href='#L582'>582</a>
648
+ <a name='L583'></a><a href='#L583'>583</a>
649
+ <a name='L584'></a><a href='#L584'>584</a>
650
+ <a name='L585'></a><a href='#L585'>585</a>
651
+ <a name='L586'></a><a href='#L586'>586</a>
652
+ <a name='L587'></a><a href='#L587'>587</a>
653
+ <a name='L588'></a><a href='#L588'>588</a>
654
+ <a name='L589'></a><a href='#L589'>589</a>
655
+ <a name='L590'></a><a href='#L590'>590</a>
656
+ <a name='L591'></a><a href='#L591'>591</a>
657
+ <a name='L592'></a><a href='#L592'>592</a>
658
+ <a name='L593'></a><a href='#L593'>593</a>
659
+ <a name='L594'></a><a href='#L594'>594</a>
660
+ <a name='L595'></a><a href='#L595'>595</a>
661
+ <a name='L596'></a><a href='#L596'>596</a>
662
+ <a name='L597'></a><a href='#L597'>597</a>
663
+ <a name='L598'></a><a href='#L598'>598</a>
664
+ <a name='L599'></a><a href='#L599'>599</a>
665
+ <a name='L600'></a><a href='#L600'>600</a>
666
+ <a name='L601'></a><a href='#L601'>601</a>
667
+ <a name='L602'></a><a href='#L602'>602</a>
668
+ <a name='L603'></a><a href='#L603'>603</a>
669
+ <a name='L604'></a><a href='#L604'>604</a>
670
+ <a name='L605'></a><a href='#L605'>605</a>
671
+ <a name='L606'></a><a href='#L606'>606</a>
672
+ <a name='L607'></a><a href='#L607'>607</a>
673
+ <a name='L608'></a><a href='#L608'>608</a>
674
+ <a name='L609'></a><a href='#L609'>609</a>
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></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
930
+ <span class="cline-any cline-neutral">&nbsp;</span>
931
+ <span class="cline-any cline-neutral">&nbsp;</span>
932
+ <span class="cline-any cline-neutral">&nbsp;</span>
933
+ <span class="cline-any cline-neutral">&nbsp;</span>
934
+ <span class="cline-any cline-neutral">&nbsp;</span>
935
+ <span class="cline-any cline-neutral">&nbsp;</span>
936
+ <span class="cline-any cline-neutral">&nbsp;</span>
937
+ <span class="cline-any cline-neutral">&nbsp;</span>
938
+ <span class="cline-any cline-neutral">&nbsp;</span>
939
+ <span class="cline-any cline-neutral">&nbsp;</span>
940
+ <span class="cline-any cline-neutral">&nbsp;</span>
941
+ <span class="cline-any cline-neutral">&nbsp;</span>
942
+ <span class="cline-any cline-neutral">&nbsp;</span>
943
+ <span class="cline-any cline-neutral">&nbsp;</span>
944
+ <span class="cline-any cline-neutral">&nbsp;</span>
945
+ <span class="cline-any cline-neutral">&nbsp;</span>
946
+ <span class="cline-any cline-neutral">&nbsp;</span>
947
+ <span class="cline-any cline-neutral">&nbsp;</span>
948
+ <span class="cline-any cline-neutral">&nbsp;</span>
949
+ <span class="cline-any cline-neutral">&nbsp;</span>
950
+ <span class="cline-any cline-neutral">&nbsp;</span>
951
+ <span class="cline-any cline-neutral">&nbsp;</span>
952
+ <span class="cline-any cline-neutral">&nbsp;</span>
953
+ <span class="cline-any cline-neutral">&nbsp;</span>
954
+ <span class="cline-any cline-yes">5x</span>
955
+ <span class="cline-any cline-neutral">&nbsp;</span>
956
+ <span class="cline-any cline-neutral">&nbsp;</span>
957
+ <span class="cline-any cline-neutral">&nbsp;</span>
958
+ <span class="cline-any cline-yes">31x</span>
959
+ <span class="cline-any cline-neutral">&nbsp;</span>
960
+ <span class="cline-any cline-neutral">&nbsp;</span>
961
+ <span class="cline-any cline-neutral">&nbsp;</span>
962
+ <span class="cline-any cline-yes">2x</span>
963
+ <span class="cline-any cline-neutral">&nbsp;</span>
964
+ <span class="cline-any cline-neutral">&nbsp;</span>
965
+ <span class="cline-any cline-neutral">&nbsp;</span>
966
+ <span class="cline-any cline-yes">31x</span>
967
+ <span class="cline-any cline-neutral">&nbsp;</span>
968
+ <span class="cline-any cline-neutral">&nbsp;</span>
969
+ <span class="cline-any cline-neutral">&nbsp;</span>
970
+ <span class="cline-any cline-neutral">&nbsp;</span>
971
+ <span class="cline-any cline-neutral">&nbsp;</span>
972
+ <span class="cline-any cline-neutral">&nbsp;</span>
973
+ <span class="cline-any cline-yes">31x</span>
974
+ <span class="cline-any cline-yes">31x</span>
975
+ <span class="cline-any cline-yes">31x</span>
976
+ <span class="cline-any cline-yes">31x</span>
977
+ <span class="cline-any cline-yes">31x</span>
978
+ <span class="cline-any cline-neutral">&nbsp;</span>
979
+ <span class="cline-any cline-yes">31x</span>
980
+ <span class="cline-any cline-neutral">&nbsp;</span>
981
+ <span class="cline-any cline-yes">31x</span>
982
+ <span class="cline-any cline-yes">31x</span>
983
+ <span class="cline-any cline-neutral">&nbsp;</span>
984
+ <span class="cline-any cline-yes">31x</span>
985
+ <span class="cline-any cline-yes">31x</span>
986
+ <span class="cline-any cline-neutral">&nbsp;</span>
987
+ <span class="cline-any cline-neutral">&nbsp;</span>
988
+ <span class="cline-any cline-neutral">&nbsp;</span>
989
+ <span class="cline-any cline-neutral">&nbsp;</span>
990
+ <span class="cline-any cline-yes">20x</span>
991
+ <span class="cline-any cline-neutral">&nbsp;</span>
992
+ <span class="cline-any cline-neutral">&nbsp;</span>
993
+ <span class="cline-any cline-neutral">&nbsp;</span>
994
+ <span class="cline-any cline-neutral">&nbsp;</span>
995
+ <span class="cline-any cline-neutral">&nbsp;</span>
996
+ <span class="cline-any cline-neutral">&nbsp;</span>
997
+ <span class="cline-any cline-yes">20x</span>
998
+ <span class="cline-any cline-neutral">&nbsp;</span>
999
+ <span class="cline-any cline-neutral">&nbsp;</span>
1000
+ <span class="cline-any cline-neutral">&nbsp;</span>
1001
+ <span class="cline-any cline-neutral">&nbsp;</span>
1002
+ <span class="cline-any cline-neutral">&nbsp;</span>
1003
+ <span class="cline-any cline-neutral">&nbsp;</span>
1004
+ <span class="cline-any cline-neutral">&nbsp;</span>
1005
+ <span class="cline-any cline-neutral">&nbsp;</span>
1006
+ <span class="cline-any cline-neutral">&nbsp;</span>
1007
+ <span class="cline-any cline-neutral">&nbsp;</span>
1008
+ <span class="cline-any cline-neutral">&nbsp;</span>
1009
+ <span class="cline-any cline-neutral">&nbsp;</span>
1010
+ <span class="cline-any cline-yes">20x</span>
1011
+ <span class="cline-any cline-neutral">&nbsp;</span>
1012
+ <span class="cline-any cline-neutral">&nbsp;</span>
1013
+ <span class="cline-any cline-neutral">&nbsp;</span>
1014
+ <span class="cline-any cline-yes">31x</span>
1015
+ <span class="cline-any cline-yes">31x</span>
1016
+ <span class="cline-any cline-yes">31x</span>
1017
+ <span class="cline-any cline-neutral">&nbsp;</span>
1018
+ <span class="cline-any cline-yes">31x</span>
1019
+ <span class="cline-any cline-yes">31x</span>
1020
+ <span class="cline-any cline-yes">31x</span>
1021
+ <span class="cline-any cline-yes">31x</span>
1022
+ <span class="cline-any cline-yes">31x</span>
1023
+ <span class="cline-any cline-yes">31x</span>
1024
+ <span class="cline-any cline-yes">31x</span>
1025
+ <span class="cline-any cline-yes">31x</span>
1026
+ <span class="cline-any cline-yes">31x</span>
1027
+ <span class="cline-any cline-yes">31x</span>
1028
+ <span class="cline-any cline-neutral">&nbsp;</span>
1029
+ <span class="cline-any cline-neutral">&nbsp;</span>
1030
+ <span class="cline-any cline-yes">6x</span>
1031
+ <span class="cline-any cline-neutral">&nbsp;</span>
1032
+ <span class="cline-any cline-neutral">&nbsp;</span>
1033
+ <span class="cline-any cline-neutral">&nbsp;</span>
1034
+ <span class="cline-any cline-no">&nbsp;</span>
1035
+ <span class="cline-any cline-neutral">&nbsp;</span>
1036
+ <span class="cline-any cline-neutral">&nbsp;</span>
1037
+ <span class="cline-any cline-neutral">&nbsp;</span>
1038
+ <span class="cline-any cline-neutral">&nbsp;</span>
1039
+ <span class="cline-any cline-neutral">&nbsp;</span>
1040
+ <span class="cline-any cline-neutral">&nbsp;</span>
1041
+ <span class="cline-any cline-neutral">&nbsp;</span>
1042
+ <span class="cline-any cline-yes">5x</span>
1043
+ <span class="cline-any cline-yes">5x</span>
1044
+ <span class="cline-any cline-neutral">&nbsp;</span>
1045
+ <span class="cline-any cline-neutral">&nbsp;</span>
1046
+ <span class="cline-any cline-neutral">&nbsp;</span>
1047
+ <span class="cline-any cline-yes">5x</span>
1048
+ <span class="cline-any cline-neutral">&nbsp;</span>
1049
+ <span class="cline-any cline-neutral">&nbsp;</span>
1050
+ <span class="cline-any cline-neutral">&nbsp;</span>
1051
+ <span class="cline-any cline-yes">22x</span>
1052
+ <span class="cline-any cline-neutral">&nbsp;</span>
1053
+ <span class="cline-any cline-neutral">&nbsp;</span>
1054
+ <span class="cline-any cline-neutral">&nbsp;</span>
1055
+ <span class="cline-any cline-yes">3x</span>
1056
+ <span class="cline-any cline-neutral">&nbsp;</span>
1057
+ <span class="cline-any cline-neutral">&nbsp;</span>
1058
+ <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-yes">4x</span>
1064
+ <span class="cline-any cline-yes">4x</span>
1065
+ <span class="cline-any cline-yes">4x</span>
1066
+ <span class="cline-any cline-yes">4x</span>
1067
+ <span class="cline-any cline-neutral">&nbsp;</span>
1068
+ <span class="cline-any cline-neutral">&nbsp;</span>
1069
+ <span class="cline-any cline-yes">4x</span>
1070
+ <span class="cline-any cline-neutral">&nbsp;</span>
1071
+ <span class="cline-any cline-neutral">&nbsp;</span>
1072
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">1x</span>
1078
+ <span class="cline-any cline-yes">1x</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-neutral">&nbsp;</span>
1085
+ <span class="cline-any cline-neutral">&nbsp;</span>
1086
+ <span class="cline-any cline-yes">3x</span>
1087
+ <span class="cline-any cline-yes">3x</span>
1088
+ <span class="cline-any cline-yes">3x</span>
1089
+ <span class="cline-any cline-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">164647x</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-yes">4x</span>
1097
+ <span class="cline-any cline-yes">1x</span>
1098
+ <span class="cline-any cline-yes">1x</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-yes">1x</span>
1103
+ <span class="cline-any cline-yes">1x</span>
1104
+ <span class="cline-any cline-yes">1x</span>
1105
+ <span class="cline-any cline-yes">1x</span>
1106
+ <span class="cline-any cline-yes">1x</span>
1107
+ <span class="cline-any cline-yes">1x</span>
1108
+ <span class="cline-any cline-neutral">&nbsp;</span>
1109
+ <span class="cline-any cline-yes">1x</span>
1110
+ <span class="cline-any cline-neutral">&nbsp;</span>
1111
+ <span class="cline-any cline-yes">1x</span>
1112
+ <span class="cline-any cline-yes">1x</span>
1113
+ <span class="cline-any cline-yes">1x</span>
1114
+ <span class="cline-any cline-yes">1x</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-yes">1x</span>
1119
+ <span class="cline-any cline-neutral">&nbsp;</span>
1120
+ <span class="cline-any cline-no">&nbsp;</span>
1121
+ <span class="cline-any cline-no">&nbsp;</span>
1122
+ <span class="cline-any cline-neutral">&nbsp;</span>
1123
+ <span class="cline-any cline-neutral">&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-neutral">&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-no">&nbsp;</span>
1132
+ <span class="cline-any cline-no">&nbsp;</span>
1133
+ <span class="cline-any cline-no">&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-no">&nbsp;</span>
1137
+ <span class="cline-any cline-no">&nbsp;</span>
1138
+ <span class="cline-any cline-no">&nbsp;</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-no">&nbsp;</span>
1142
+ <span class="cline-any cline-neutral">&nbsp;</span>
1143
+ <span class="cline-any cline-neutral">&nbsp;</span>
1144
+ <span class="cline-any cline-neutral">&nbsp;</span>
1145
+ <span class="cline-any cline-no">&nbsp;</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-neutral">&nbsp;</span>
1149
+ <span class="cline-any cline-neutral">&nbsp;</span>
1150
+ <span class="cline-any cline-yes">31x</span>
1151
+ <span class="cline-any cline-yes">25x</span>
1152
+ <span class="cline-any cline-neutral">&nbsp;</span>
1153
+ <span class="cline-any cline-neutral">&nbsp;</span>
1154
+ <span class="cline-any cline-neutral">&nbsp;</span>
1155
+ <span class="cline-any cline-yes">25x</span>
1156
+ <span class="cline-any cline-neutral">&nbsp;</span>
1157
+ <span class="cline-any cline-yes">9x</span>
1158
+ <span class="cline-any cline-neutral">&nbsp;</span>
1159
+ <span class="cline-any cline-yes">25x</span>
1160
+ <span class="cline-any cline-neutral">&nbsp;</span>
1161
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">22x</span>
1166
+ <span class="cline-any cline-yes">22x</span>
1167
+ <span class="cline-any cline-yes">22x</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-yes">22x</span>
1176
+ <span class="cline-any cline-neutral">&nbsp;</span>
1177
+ <span class="cline-any cline-yes">22x</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-yes">19x</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-yes">19x</span>
1185
+ <span class="cline-any cline-neutral">&nbsp;</span>
1186
+ <span class="cline-any cline-yes">3x</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">22x</span>
1191
+ <span class="cline-any cline-neutral">&nbsp;</span>
1192
+ <span class="cline-any cline-neutral">&nbsp;</span>
1193
+ <span class="cline-any cline-no">&nbsp;</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-yes">22x</span>
1198
+ <span class="cline-any cline-yes">22x</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-yes">22x</span>
1204
+ <span class="cline-any cline-yes">4x</span>
1205
+ <span class="cline-any cline-yes">4x</span>
1206
+ <span class="cline-any cline-yes">4x</span>
1207
+ <span class="cline-any cline-yes">4x</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-yes">4x</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-neutral">&nbsp;</span>
1215
+ <span class="cline-any cline-no">&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-neutral">&nbsp;</span>
1220
+ <span class="cline-any cline-neutral">&nbsp;</span>
1221
+ <span class="cline-any cline-yes">25x</span>
1222
+ <span class="cline-any cline-yes">25x</span>
1223
+ <span class="cline-any cline-yes">25x</span>
1224
+ <span class="cline-any cline-yes">25x</span>
1225
+ <span class="cline-any cline-neutral">&nbsp;</span>
1226
+ <span class="cline-any cline-yes">25x</span>
1227
+ <span class="cline-any cline-yes">2x</span>
1228
+ <span class="cline-any cline-yes">2x</span>
1229
+ <span class="cline-any cline-neutral">&nbsp;</span>
1230
+ <span class="cline-any cline-yes">23x</span>
1231
+ <span class="cline-any cline-yes">23x</span>
1232
+ <span class="cline-any cline-yes">19x</span>
1233
+ <span class="cline-any cline-yes">19x</span>
1234
+ <span class="cline-any cline-yes">19x</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-yes">23x</span>
1238
+ <span class="cline-any cline-yes">23x</span>
1239
+ <span class="cline-any cline-yes">23x</span>
1240
+ <span class="cline-any cline-yes">23x</span>
1241
+ <span class="cline-any cline-neutral">&nbsp;</span>
1242
+ <span class="cline-any cline-neutral">&nbsp;</span>
1243
+ <span class="cline-any cline-neutral">&nbsp;</span>
1244
+ <span class="cline-any cline-neutral">&nbsp;</span>
1245
+ <span class="cline-any cline-yes">23x</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-yes">23x</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-yes">23x</span>
1254
+ <span class="cline-any cline-yes">4x</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-neutral">&nbsp;</span>
1259
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">4x</span>
1263
+ <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</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-yes">23x</span>
1272
+ <span class="cline-any cline-no">&nbsp;</span>
1273
+ <span class="cline-any cline-yes">23x</span>
1274
+ <span class="cline-any cline-yes">23x</span>
1275
+ <span class="cline-any cline-yes">10x</span>
1276
+ <span class="cline-any cline-yes">13x</span>
1277
+ <span class="cline-any cline-yes">23x</span>
1278
+ <span class="cline-any cline-yes">23x</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-yes">25x</span>
1282
+ <span class="cline-any cline-neutral">&nbsp;</span>
1283
+ <span class="cline-any cline-neutral">&nbsp;</span>
1284
+ <span class="cline-any cline-neutral">&nbsp;</span>
1285
+ <span class="cline-any cline-neutral">&nbsp;</span>
1286
+ <span class="cline-any cline-yes">2x</span>
1287
+ <span class="cline-any cline-yes">2x</span>
1288
+ <span class="cline-any cline-yes">2x</span>
1289
+ <span class="cline-any cline-yes">2x</span>
1290
+ <span class="cline-any cline-yes">2x</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-yes">2x</span>
1295
+ <span class="cline-any cline-yes">2x</span>
1296
+ <span class="cline-any cline-yes">2x</span>
1297
+ <span class="cline-any cline-neutral">&nbsp;</span>
1298
+ <span class="cline-any cline-yes">2x</span>
1299
+ <span class="cline-any cline-yes">2x</span>
1300
+ <span class="cline-any cline-yes">2x</span>
1301
+ <span class="cline-any cline-neutral">&nbsp;</span>
1302
+ <span class="cline-any cline-yes">2x</span>
1303
+ <span class="cline-any cline-yes">2x</span>
1304
+ <span class="cline-any cline-yes">1x</span>
1305
+ <span class="cline-any cline-yes">2x</span>
1306
+ <span class="cline-any cline-yes">1x</span>
1307
+ <span class="cline-any cline-yes">2x</span>
1308
+ <span class="cline-any cline-neutral">&nbsp;</span>
1309
+ <span class="cline-any cline-yes">2x</span>
1310
+ <span class="cline-any cline-neutral">&nbsp;</span>
1311
+ <span class="cline-any cline-yes">2x</span>
1312
+ <span class="cline-any cline-yes">2x</span>
1313
+ <span class="cline-any cline-neutral">&nbsp;</span>
1314
+ <span class="cline-any cline-no">&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-yes">2x</span>
1319
+ <span class="cline-any cline-yes">2x</span>
1320
+ <span class="cline-any cline-neutral">&nbsp;</span>
1321
+ <span class="cline-any cline-neutral">&nbsp;</span>
1322
+ <span class="cline-any cline-neutral">&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-yes">8x</span>
1326
+ <span class="cline-any cline-neutral">&nbsp;</span>
1327
+ <span class="cline-any cline-yes">8x</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-yes">11x</span>
1331
+ <span class="cline-any cline-yes">8x</span>
1332
+ <span class="cline-any cline-yes">8x</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-yes">3x</span>
1337
+ <span class="cline-any cline-yes">1x</span>
1338
+ <span class="cline-any cline-no">&nbsp;</span>
1339
+ <span class="cline-any cline-no">&nbsp;</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-neutral">&nbsp;</span>
1344
+ <span class="cline-any cline-neutral">&nbsp;</span>
1345
+ <span class="cline-any cline-no">&nbsp;</span>
1346
+ <span class="cline-any cline-yes">1x</span>
1347
+ <span class="cline-any cline-yes">1x</span>
1348
+ <span class="cline-any cline-yes">1x</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-yes">2x</span>
1353
+ <span class="cline-any cline-no">&nbsp;</span>
1354
+ <span class="cline-any cline-no">&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-yes">2x</span>
1358
+ <span class="cline-any cline-no">&nbsp;</span>
1359
+ <span class="cline-any cline-no">&nbsp;</span>
1360
+ <span class="cline-any cline-no">&nbsp;</span>
1361
+ <span class="cline-any cline-no">&nbsp;</span>
1362
+ <span class="cline-any cline-neutral">&nbsp;</span>
1363
+ <span class="cline-any cline-no">&nbsp;</span>
1364
+ <span class="cline-any cline-neutral">&nbsp;</span>
1365
+ <span class="cline-any cline-yes">2x</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-yes">2x</span>
1370
+ <span class="cline-any cline-no">&nbsp;</span>
1371
+ <span class="cline-any cline-no">&nbsp;</span>
1372
+ <span class="cline-any cline-neutral">&nbsp;</span>
1373
+ <span class="cline-any cline-no">&nbsp;</span>
1374
+ <span class="cline-any cline-no">&nbsp;</span>
1375
+ <span class="cline-any cline-no">&nbsp;</span>
1376
+ <span class="cline-any cline-no">&nbsp;</span>
1377
+ <span class="cline-any cline-neutral">&nbsp;</span>
1378
+ <span class="cline-any cline-neutral">&nbsp;</span>
1379
+ <span class="cline-any cline-yes">2x</span>
1380
+ <span class="cline-any cline-yes">2x</span>
1381
+ <span class="cline-any cline-neutral">&nbsp;</span>
1382
+ <span class="cline-any cline-yes">2x</span>
1383
+ <span class="cline-any cline-neutral">&nbsp;</span>
1384
+ <span class="cline-any cline-neutral">&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-neutral">&nbsp;</span>
1388
+ <span class="cline-any cline-yes">2x</span>
1389
+ <span class="cline-any cline-yes">2x</span>
1390
+ <span class="cline-any cline-yes">2x</span>
1391
+ <span class="cline-any cline-yes">2x</span>
1392
+ <span class="cline-any cline-neutral">&nbsp;</span>
1393
+ <span class="cline-any cline-no">&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-no">&nbsp;</span>
1400
+ <span class="cline-any cline-no">&nbsp;</span>
1401
+ <span class="cline-any cline-no">&nbsp;</span>
1402
+ <span class="cline-any cline-neutral">&nbsp;</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-no">&nbsp;</span>
1406
+ <span class="cline-any cline-neutral">&nbsp;</span>
1407
+ <span class="cline-any cline-no">&nbsp;</span>
1408
+ <span class="cline-any cline-no">&nbsp;</span>
1409
+ <span class="cline-any cline-no">&nbsp;</span>
1410
+ <span class="cline-any cline-no">&nbsp;</span>
1411
+ <span class="cline-any cline-no">&nbsp;</span>
1412
+ <span class="cline-any cline-neutral">&nbsp;</span>
1413
+ <span class="cline-any cline-neutral">&nbsp;</span>
1414
+ <span class="cline-any cline-neutral">&nbsp;</span>
1415
+ <span class="cline-any cline-neutral">&nbsp;</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-no">&nbsp;</span>
1423
+ <span class="cline-any cline-no">&nbsp;</span>
1424
+ <span class="cline-any cline-no">&nbsp;</span>
1425
+ <span class="cline-any cline-no">&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-no">&nbsp;</span>
1432
+ <span class="cline-any cline-no">&nbsp;</span>
1433
+ <span class="cline-any cline-neutral">&nbsp;</span>
1434
+ <span class="cline-any cline-neutral">&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-no">&nbsp;</span>
1438
+ <span class="cline-any cline-no">&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-yes">8x</span>
1443
+ <span class="cline-any cline-neutral">&nbsp;</span>
1444
+ <span class="cline-any cline-yes">8x</span>
1445
+ <span class="cline-any cline-yes">8x</span>
1446
+ <span class="cline-any cline-yes">8x</span>
1447
+ <span class="cline-any cline-yes">8x</span>
1448
+ <span class="cline-any cline-neutral">&nbsp;</span>
1449
+ <span class="cline-any cline-yes">8x</span>
1450
+ <span class="cline-any cline-yes">8x</span>
1451
+ <span class="cline-any cline-yes">8x</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-neutral">&nbsp;</span>
1456
+ <span class="cline-any cline-neutral">&nbsp;</span>
1457
+ <span class="cline-any cline-yes">11x</span>
1458
+ <span class="cline-any cline-yes">11x</span>
1459
+ <span class="cline-any cline-neutral">&nbsp;</span>
1460
+ <span class="cline-any cline-yes">8x</span>
1461
+ <span class="cline-any cline-yes">8x</span>
1462
+ <span class="cline-any cline-yes">8x</span>
1463
+ <span class="cline-any cline-yes">8x</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-yes">3x</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-neutral">&nbsp;</span>
1471
+ <span class="cline-any cline-neutral">&nbsp;</span>
1472
+ <span class="cline-any cline-neutral">&nbsp;</span>
1473
+ <span class="cline-any cline-neutral">&nbsp;</span>
1474
+ <span class="cline-any cline-yes">25x</span>
1475
+ <span class="cline-any cline-yes">25x</span>
1476
+ <span class="cline-any cline-yes">25x</span>
1477
+ <span class="cline-any cline-neutral">&nbsp;</span>
1478
+ <span class="cline-any cline-neutral">&nbsp;</span>
1479
+ <span class="cline-any cline-neutral">&nbsp;</span>
1480
+ <span class="cline-any cline-yes">25x</span>
1481
+ <span class="cline-any cline-neutral">&nbsp;</span>
1482
+ <span class="cline-any cline-yes">25x</span>
1483
+ <span class="cline-any cline-yes">25x</span>
1484
+ <span class="cline-any cline-yes">24x</span>
1485
+ <span class="cline-any cline-yes">24x</span>
1486
+ <span class="cline-any cline-yes">311056x</span>
1487
+ <span class="cline-any cline-yes">155516x</span>
1488
+ <span class="cline-any cline-yes">155516x</span>
1489
+ <span class="cline-any cline-yes">155516x</span>
1490
+ <span class="cline-any cline-neutral">&nbsp;</span>
1491
+ <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</span>
1495
+ <span class="cline-any cline-yes">155516x</span>
1496
+ <span class="cline-any cline-yes">155516x</span>
1497
+ <span class="cline-any cline-yes">155516x</span>
1498
+ <span class="cline-any cline-neutral">&nbsp;</span>
1499
+ <span class="cline-any cline-yes">24x</span>
1500
+ <span class="cline-any cline-neutral">&nbsp;</span>
1501
+ <span class="cline-any cline-yes">1x</span>
1502
+ <span class="cline-any cline-yes">9118x</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-yes">9118x</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">2x</span>
1516
+ <span class="cline-any cline-yes">2x</span>
1517
+ <span class="cline-any cline-yes">2x</span>
1518
+ <span class="cline-any cline-neutral">&nbsp;</span>
1519
+ <span class="cline-any cline-neutral">&nbsp;</span>
1520
+ <span class="cline-any cline-neutral">&nbsp;</span>
1521
+ <span class="cline-any cline-neutral">&nbsp;</span>
1522
+ <span class="cline-any cline-neutral">&nbsp;</span>
1523
+ <span class="cline-any cline-neutral">&nbsp;</span>
1524
+ <span class="cline-any cline-yes">8x</span>
1525
+ <span class="cline-any cline-yes">8x</span>
1526
+ <span class="cline-any cline-neutral">&nbsp;</span>
1527
+ <span class="cline-any cline-yes">8x</span>
1528
+ <span class="cline-any cline-yes">6x</span>
1529
+ <span class="cline-any cline-yes">5x</span>
1530
+ <span class="cline-any cline-yes">5x</span>
1531
+ <span class="cline-any cline-neutral">&nbsp;</span>
1532
+ <span class="cline-any cline-neutral">&nbsp;</span>
1533
+ <span class="cline-any cline-yes">5x</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-yes">6x</span>
1537
+ <span class="cline-any cline-no">&nbsp;</span>
1538
+ <span class="cline-any cline-no">&nbsp;</span>
1539
+ <span class="cline-any cline-no">&nbsp;</span>
1540
+ <span class="cline-any cline-no">&nbsp;</span>
1541
+ <span class="cline-any cline-no">&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-yes">6x</span>
1545
+ <span class="cline-any cline-neutral">&nbsp;</span>
1546
+ <span class="cline-any cline-yes">1x</span>
1547
+ <span class="cline-any cline-yes">1x</span>
1548
+ <span class="cline-any cline-neutral">&nbsp;</span>
1549
+ <span class="cline-any cline-yes">1x</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-neutral">&nbsp;</span>
1553
+ <span class="cline-any cline-neutral">&nbsp;</span>
1554
+ <span class="cline-any cline-neutral">&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-yes">1x</span>
1559
+ <span class="cline-any cline-yes">1x</span>
1560
+ <span class="cline-any cline-yes">1x</span>
1561
+ <span class="cline-any cline-neutral">&nbsp;</span>
1562
+ <span class="cline-any cline-neutral">&nbsp;</span>
1563
+ <span class="cline-any cline-neutral">&nbsp;</span>
1564
+ <span class="cline-any cline-yes">1x</span>
1565
+ <span class="cline-any cline-neutral">&nbsp;</span>
1566
+ <span class="cline-any cline-neutral">&nbsp;</span>
1567
+ <span class="cline-any cline-neutral">&nbsp;</span>
1568
+ <span class="cline-any cline-yes">2x</span>
1569
+ <span class="cline-any cline-yes">2x</span>
1570
+ <span class="cline-any cline-yes">1x</span>
1571
+ <span class="cline-any cline-yes">1x</span>
1572
+ <span class="cline-any cline-yes">1x</span>
1573
+ <span class="cline-any cline-neutral">&nbsp;</span>
1574
+ <span class="cline-any cline-yes">1x</span>
1575
+ <span class="cline-any cline-yes">1x</span>
1576
+ <span class="cline-any cline-yes">1x</span>
1577
+ <span class="cline-any cline-yes">1x</span>
1578
+ <span class="cline-any cline-yes">1x</span>
1579
+ <span class="cline-any cline-neutral">&nbsp;</span>
1580
+ <span class="cline-any cline-yes">1x</span>
1581
+ <span class="cline-any cline-neutral">&nbsp;</span>
1582
+ <span class="cline-any cline-yes">1x</span>
1583
+ <span class="cline-any cline-neutral">&nbsp;</span>
1584
+ <span class="cline-any cline-yes">1x</span>
1585
+ <span class="cline-any cline-yes">1x</span>
1586
+ <span class="cline-any cline-no">&nbsp;</span>
1587
+ <span class="cline-any cline-no">&nbsp;</span>
1588
+ <span class="cline-any cline-no">&nbsp;</span>
1589
+ <span class="cline-any cline-no">&nbsp;</span>
1590
+ <span class="cline-any cline-no">&nbsp;</span>
1591
+ <span class="cline-any cline-neutral">&nbsp;</span>
1592
+ <span class="cline-any cline-no">&nbsp;</span>
1593
+ <span class="cline-any cline-no">&nbsp;</span>
1594
+ <span class="cline-any cline-no">&nbsp;</span>
1595
+ <span class="cline-any cline-no">&nbsp;</span>
1596
+ <span class="cline-any cline-no">&nbsp;</span>
1597
+ <span class="cline-any cline-neutral">&nbsp;</span>
1598
+ <span class="cline-any cline-no">&nbsp;</span>
1599
+ <span class="cline-any cline-no">&nbsp;</span>
1600
+ <span class="cline-any cline-neutral">&nbsp;</span>
1601
+ <span class="cline-any cline-no">&nbsp;</span>
1602
+ <span class="cline-any cline-no">&nbsp;</span>
1603
+ <span class="cline-any cline-no">&nbsp;</span>
1604
+ <span class="cline-any cline-no">&nbsp;</span>
1605
+ <span class="cline-any cline-no">&nbsp;</span>
1606
+ <span class="cline-any cline-neutral">&nbsp;</span>
1607
+ <span class="cline-any cline-no">&nbsp;</span>
1608
+ <span class="cline-any cline-no">&nbsp;</span>
1609
+ <span class="cline-any cline-no">&nbsp;</span>
1610
+ <span class="cline-any cline-no">&nbsp;</span>
1611
+ <span class="cline-any cline-no">&nbsp;</span>
1612
+ <span class="cline-any cline-neutral">&nbsp;</span>
1613
+ <span class="cline-any cline-no">&nbsp;</span>
1614
+ <span class="cline-any cline-no">&nbsp;</span>
1615
+ <span class="cline-any cline-no">&nbsp;</span>
1616
+ <span class="cline-any cline-no">&nbsp;</span>
1617
+ <span class="cline-any cline-neutral">&nbsp;</span>
1618
+ <span class="cline-any cline-no">&nbsp;</span>
1619
+ <span class="cline-any cline-no">&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-neutral">&nbsp;</span>
1624
+ <span class="cline-any cline-neutral">&nbsp;</span>
1625
+ <span class="cline-any cline-yes">2x</span>
1626
+ <span class="cline-any cline-yes">2x</span>
1627
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">1x</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-yes">1x</span>
1636
+ <span class="cline-any cline-yes">1x</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-neutral">&nbsp;</span>
1641
+ <span class="cline-any cline-yes">14x</span>
1642
+ <span class="cline-any cline-yes">14x</span>
1643
+ <span class="cline-any cline-neutral">&nbsp;</span>
1644
+ <span class="cline-any cline-yes">14x</span>
1645
+ <span class="cline-any cline-yes">14x</span>
1646
+ <span class="cline-any cline-neutral">&nbsp;</span>
1647
+ <span class="cline-any cline-neutral">&nbsp;</span>
1648
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">14x</span>
1653
+ <span class="cline-any cline-yes">14x</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">14x</span>
1659
+ <span class="cline-any cline-yes">14x</span>
1660
+ <span class="cline-any cline-yes">14x</span>
1661
+ <span class="cline-any cline-yes">14x</span>
1662
+ <span class="cline-any cline-yes">14x</span>
1663
+ <span class="cline-any cline-no">&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-yes">9x</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-neutral">&nbsp;</span>
1675
+ <span class="cline-any cline-neutral">&nbsp;</span>
1676
+ <span class="cline-any cline-yes">9x</span>
1677
+ <span class="cline-any cline-yes">9x</span>
1678
+ <span class="cline-any cline-neutral">&nbsp;</span>
1679
+ <span class="cline-any cline-yes">8x</span>
1680
+ <span class="cline-any cline-neutral">&nbsp;</span>
1681
+ <span class="cline-any cline-neutral">&nbsp;</span>
1682
+ <span class="cline-any cline-neutral">&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-yes">9x</span>
1687
+ <span class="cline-any cline-neutral">&nbsp;</span>
1688
+ <span class="cline-any cline-yes">2x</span>
1689
+ <span class="cline-any cline-neutral">&nbsp;</span>
1690
+ <span class="cline-any cline-yes">2x</span>
1691
+ <span class="cline-any cline-yes">2x</span>
1692
+ <span class="cline-any cline-yes">2x</span>
1693
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">2x</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-yes">2x</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-yes">2x</span>
1710
+ <span class="cline-any cline-yes">2x</span>
1711
+ <span class="cline-any cline-yes">2x</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-yes">2x</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-yes">2x</span>
1718
+ <span class="cline-any cline-neutral">&nbsp;</span>
1719
+ <span class="cline-any cline-yes">2x</span>
1720
+ <span class="cline-any cline-yes">2x</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-no">&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-neutral">&nbsp;</span>
1731
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">25x</span>
1737
+ <span class="cline-any cline-yes">25x</span>
1738
+ <span class="cline-any cline-neutral">&nbsp;</span>
1739
+ <span class="cline-any cline-yes">25x</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-yes">25x</span>
1743
+ <span class="cline-any cline-yes">25x</span>
1744
+ <span class="cline-any cline-neutral">&nbsp;</span>
1745
+ <span class="cline-any cline-yes">25x</span>
1746
+ <span class="cline-any cline-yes">25x</span>
1747
+ <span class="cline-any cline-yes">25x</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-yes">25x</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-neutral">&nbsp;</span>
1755
+ <span class="cline-any cline-neutral">&nbsp;</span>
1756
+ <span class="cline-any cline-yes">25x</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-yes">25x</span>
1763
+ <span class="cline-any cline-yes">25x</span>
1764
+ <span class="cline-any cline-yes">25x</span>
1765
+ <span class="cline-any cline-yes">25x</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-neutral">&nbsp;</span>
1769
+ <span class="cline-any cline-yes">25x</span>
1770
+ <span class="cline-any cline-yes">25x</span>
1771
+ <span class="cline-any cline-neutral">&nbsp;</span>
1772
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">25x</span>
1777
+ <span class="cline-any cline-no">&nbsp;</span>
1778
+ <span class="cline-any cline-no">&nbsp;</span>
1779
+ <span class="cline-any cline-neutral">&nbsp;</span>
1780
+ <span class="cline-any cline-no">&nbsp;</span>
1781
+ <span class="cline-any cline-neutral">&nbsp;</span>
1782
+ <span class="cline-any cline-no">&nbsp;</span>
1783
+ <span class="cline-any cline-no">&nbsp;</span>
1784
+ <span class="cline-any cline-no">&nbsp;</span>
1785
+ <span class="cline-any cline-neutral">&nbsp;</span>
1786
+ <span class="cline-any cline-neutral">&nbsp;</span>
1787
+ <span class="cline-any cline-neutral">&nbsp;</span>
1788
+ <span class="cline-any cline-neutral">&nbsp;</span>
1789
+ <span class="cline-any cline-neutral">&nbsp;</span>
1790
+ <span class="cline-any cline-neutral">&nbsp;</span>
1791
+ <span class="cline-any cline-neutral">&nbsp;</span>
1792
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import http from "http";
1793
+ import crypto from "node:crypto";
1794
+ import fs from "fs";
1795
+ import { URLSearchParams } from "url";
1796
+ import process from "node:process";
1797
+ import path from "path";
1798
+ import { fileURLToPath } from "url";
1799
+ import pkg from "./package.json" with { type: "json" };
1800
+ import createDebug from "debug";
1801
+ import Article from "./Article.js";
1802
+ import DatabaseModel from "./model/DatabaseModel.js";
1803
+ import { fetchData, postData } from "./model/APIModel.js";
1804
+ import { formatHTML, header, formatMarkdown, validate } from "./Formatter.js"; // import pkg from "./package.json" with { type: "json" };
1805
+ import { compileStyles, mergeStyles } from "./build-styles.js";
1806
+ import { compileScripts } from "./build-scripts.js";
1807
+ import FileAdapter from "./model/FileAdapter.js";
1808
+ import { table, log } from "./utilities.js";
1809
+ &nbsp;
1810
+ import DataModel from "./model/DataModel.js";
1811
+ import ArrayList from "./model/datastructures/ArrayList.js";
1812
+ import ArrayListHashMap from "./model/datastructures/ArrayListHashMap.js";
1813
+ import { BinarySearchTreeHashMap } from "./model/datastructures/BinarySearchTreeHashMap.js";
1814
+ import FileList from "./model/datastructures/FileList.js";
1815
+ &nbsp;
1816
+ // Initialize the debugger with a specific namespace
1817
+ const debug = createDebug("plainblog:Blog");
1818
+ &nbsp;
1819
+ export default class Blog {
1820
+ #makeDataModel() {
1821
+ return new BinarySearchTreeHashMap();
1822
+ }
1823
+ &nbsp;
1824
+ setDataModel(datamodel) {
1825
+ this.#articles = datamodel;
1826
+ }
1827
+ &nbsp;
1828
+ constructor() {
1829
+ this.database = {
1830
+ type: "file",
1831
+ username: "user",
1832
+ password: "password",
1833
+ host: "localhost",
1834
+ dbname: "articles.txt", // x
1835
+ };
1836
+ this.#title = "";
1837
+ this.#articles = new DataModel(this.#makeDataModel());
1838
+ this.#server = null;
1839
+ this.#password = "admin";
1840
+ this.#styles = "body { font-family: Arial; }";
1841
+ //this.scripts = "";
1842
+ this.compiledStyles = "";
1843
+ //this.compiledScripts = "";
1844
+ this.reloadStylesOnGET = false;
1845
+ this.sessions = new Set();
1846
+ &nbsp;
1847
+ this.#version = pkg.version;
1848
+ console.log(`version: ${this.#version}`);
1849
+ }
1850
+ &nbsp;
1851
+ /** @returns a json representation of the blog */
1852
+ json() {
1853
+ const serverInfo = this.#server
1854
+ ? {
1855
+ listening: this.#server.listening,
1856
+ address: this.#server.address(),
1857
+ }
1858
+ : null;
1859
+ &nbsp;
1860
+ const json = {
1861
+ version: this.#version,
1862
+ title: this.#title,
1863
+ articles: this.#articles.getAllArticles(),
1864
+ server: serverInfo,
1865
+ compiledStyles: this.compiledStyles,
1866
+ sessions: this.sessions,
1867
+ database: this.database,
1868
+ password: this.#password,
1869
+ styles: this.#styles,
1870
+ reloadStylesOnGET: this.reloadStylesOnGET,
1871
+ };
1872
+ &nbsp;
1873
+ return JSON.parse(JSON.stringify(json)); // make json read-only
1874
+ }
1875
+ &nbsp;
1876
+ // Private fields
1877
+ #version = null;
1878
+ #server = null;
1879
+ #password = null;
1880
+ #databaseModel;
1881
+ #isExternalAPI = false;
1882
+ #apiUrl = "";
1883
+ #title = "";
1884
+ #articles = [];
1885
+ #styles = "";
1886
+ #stylesHash = "";
1887
+ #scriptsHash = "";
1888
+ #stylesheetPath = "";
1889
+ compilestyle = false;
1890
+ #initPromise = null;
1891
+ &nbsp;
1892
+ setTitle(title) {
1893
+ this.#title = title;
1894
+ }
1895
+ &nbsp;
1896
+ <span class="fstat-no" title="function not covered" > se</span>tPassword(password) {
1897
+ <span class="cstat-no" title="statement not covered" > this.#password = password;</span>
1898
+ }
1899
+ &nbsp;
1900
+ /**
1901
+ * Appends CSS rules to the \&lt;style\&gt;-tag.
1902
+ * @param {string} style - A string containing CSS rules.
1903
+ */
1904
+ setStyle(style) {
1905
+ this.#styles += style;
1906
+ this.compilestyle = true;
1907
+ }
1908
+ &nbsp;
1909
+ set title(t) {
1910
+ this.#title = t;
1911
+ }
1912
+ &nbsp;
1913
+ get title() {
1914
+ return this.#title;
1915
+ }
1916
+ &nbsp;
1917
+ set password(x) {
1918
+ this.#password = x;
1919
+ }
1920
+ &nbsp;
1921
+ /**
1922
+ * allows you to inject a specific database implementation
1923
+ * @param {*} adapter a database adapter like PostgresAdapter or SqliteAdapter
1924
+ */
1925
+ setDatabaseAdapter(adapter) {
1926
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (!this.#databaseModel) {
1927
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (this.database.type === "file") {
1928
+ const adapter = new FileAdapter(this.database);
1929
+ this.#databaseModel = new DatabaseModel(adapter);
1930
+ }
1931
+ }
1932
+ this.#databaseModel.setDatabaseAdapter(adapter);
1933
+ }
1934
+ &nbsp;
1935
+ /**
1936
+ * Appends CSS rules to the \&lt;style\&gt;-tag.
1937
+ * @param {string} style - A string containing CSS rules.
1938
+ */
1939
+ set style(style) {
1940
+ this.#styles += style;
1941
+ this.compilestyle = true;
1942
+ }
1943
+ &nbsp;
1944
+ /**
1945
+ * Sets the path(s) to custom CSS or SCSS files to be compiled and used by the blog.
1946
+ * @param {string|string[]} files - A single file path or an array of file paths.
1947
+ */
1948
+ set stylesheetPath(files) {
1949
+ this.#stylesheetPath = files;
1950
+ console.log(`this.#stylesheetPath: ${this.#stylesheetPath}`);
1951
+ this.compilestyle = true;
1952
+ }
1953
+ &nbsp;
1954
+ addArticle(article) {
1955
+ this.#articles.insert(article);
1956
+ }
1957
+ &nbsp;
1958
+ #isAuthenticated(req) {
1959
+ if (!req.headers.cookie) return false;
1960
+ const params = new URLSearchParams(req.headers.cookie.replace(/; /g, "&amp;"));
1961
+ return this.sessions.has(params.get("session"));
1962
+ }
1963
+ &nbsp;
1964
+ async #handleLogin(req, res) {
1965
+ debug("handle login");
1966
+ const body = await new Promise((resolve, reject) =&gt; {
1967
+ let data = "";
1968
+ req.on("data", (chunk) =&gt; (data += chunk.toString()));
1969
+ req.on("end", () =&gt; resolve(data));
1970
+ req.on("error", reject);
1971
+ });
1972
+ const params = new URLSearchParams(body);
1973
+ &nbsp;
1974
+ if (params.get("password") === this.#password) {
1975
+ const id = crypto.randomUUID();
1976
+ this.sessions.add(id);
1977
+ res.writeHead(303, {
1978
+ "Set-Cookie": `session=${id}; HttpOnly; Path=/`,
1979
+ Location: "/",
1980
+ });
1981
+ res.end();
1982
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
1983
+ <span class="cstat-no" title="statement not covered" > res.writeHead(401, { "Content-Type": "text/html" });</span>
1984
+ <span class="cstat-no" title="statement not covered" > res.end(`${header("My Blog")}</span>
1985
+ &lt;body&gt;
1986
+ &lt;h1&gt;Unauthorized&lt;/h1&gt;&lt;div class="box"&gt;&lt;p&gt;Please enter the password.&lt;form method="POST"&gt;
1987
+ &lt;input type="password" name="password" placeholder="Password" /&gt;
1988
+ &lt;button style="margin: 2px;"&gt;Login&lt;/button&gt;&lt;/form&gt;&lt;/div&gt;
1989
+ &lt;/body&gt;&lt;/html&gt;`);
1990
+ }
1991
+ }
1992
+ &nbsp;
1993
+ #handleLogout(req, res) {
1994
+ <span class="cstat-no" title="statement not covered" > debug("handle logout");</span>
1995
+ <span class="cstat-no" title="statement not covered" > if (req.headers.cookie) {</span>
1996
+ const params = <span class="cstat-no" title="statement not covered" >new URLSearchParams(</span>
1997
+ req.headers.cookie.replace(/; /g, "&amp;"),
1998
+ );
1999
+ const sessionId = <span class="cstat-no" title="statement not covered" >params.get("session");</span>
2000
+ <span class="cstat-no" title="statement not covered" > if (this.sessions.has(sessionId)) {</span>
2001
+ <span class="cstat-no" title="statement not covered" > this.sessions.delete(sessionId);</span>
2002
+ }
2003
+ }
2004
+ <span class="cstat-no" title="statement not covered" > res.writeHead(303, {</span>
2005
+ "Set-Cookie": "session=; HttpOnly; Path=/; Max-Age=0",
2006
+ Location: "/",
2007
+ });
2008
+ <span class="cstat-no" title="statement not covered" > res.end();</span>
2009
+ }
2010
+ &nbsp;
2011
+ /** initializes database */
2012
+ async init() {
2013
+ if (this.#initPromise) return this.#initPromise;
2014
+ this.#initPromise = (async () =&gt; {
2015
+ //this.loadStyles();
2016
+ //this.loadScripts();
2017
+ // if there is a stylesheet path provided, process it
2018
+ if (this.#stylesheetPath != null &amp;&amp; this.compilestyle) {
2019
+ // read file from stylesheet path, compare checksums and write to public/styles.min.css
2020
+ await this.#processStylesheets(this.#stylesheetPath);
2021
+ }
2022
+ if (!this.#stylesheetPath) {
2023
+ // this.#styles
2024
+ // src/styles.css
2025
+ // compile and merge hardcoded styles in "this.#styles" with "src/styles.css" and write to file "styles.min.css"
2026
+ // which will be imported by webbrowser via '&lt;link rel="stylesheet" href="styles.min.css"...'
2027
+ &nbsp;
2028
+ const __filename = fileURLToPath(import.meta.url);
2029
+ const __dirname = path.dirname(__filename);
2030
+ const srcStylePath = path.join(__dirname, "src", "styles.css");
2031
+ const publicStylePath = path.join(
2032
+ process.cwd(),
2033
+ "public",
2034
+ "styles.min.css",
2035
+ );
2036
+ &nbsp;
2037
+ let publicHash = null;
2038
+ let srcStyles = "";
2039
+ &nbsp;
2040
+ await Promise.all([
2041
+ fs.promises
2042
+ .readFile(publicStylePath, "utf8")
2043
+ .then((publicCSS) =&gt; {
2044
+ const match = publicCSS.match(
2045
+ /\/\* source-hash: ([a-f0-9]{64}) \*\//,
2046
+ );
2047
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (match) publicHash = match[1];
2048
+ })
2049
+ .catch((err) =&gt; console.error(err)), // public/styles.min.css doesn't exist, will be created.
2050
+ fs.promises
2051
+ .readFile(srcStylePath, "utf8")
2052
+ .then((content) =&gt; {
2053
+ srcStyles = content;
2054
+ })
2055
+ .catch(<span class="fstat-no" title="function not covered" >(e</span>rr) =&gt; {
2056
+ <span class="cstat-no" title="statement not covered" > if (err.code !== "ENOENT") <span class="cstat-no" title="statement not covered" >console.error(err);</span></span>
2057
+ }), // ignore if src/styles.css doesn't exist
2058
+ ]);
2059
+ &nbsp;
2060
+ const combinedStyles = this.#styles + srcStyles;
2061
+ const srcHash = crypto
2062
+ .createHash("sha256")
2063
+ .update(combinedStyles)
2064
+ .digest("hex");
2065
+ &nbsp;
2066
+ if (srcHash !== publicHash &amp;&amp; this.compilestyle) {
2067
+ console.log("Styles have changed. Recompiling...");
2068
+ const finalStyles = await mergeStyles(this.#styles, srcStyles);
2069
+ try {
2070
+ await fs.promises.mkdir(path.dirname(publicStylePath), {
2071
+ recursive: true,
2072
+ });
2073
+ await fs.promises.writeFile(
2074
+ publicStylePath,
2075
+ finalStyles + `\n/* source-hash: ${srcHash} */`,
2076
+ );
2077
+ } catch (err) {
2078
+ <span class="cstat-no" title="statement not covered" > console.error("Failed to write styles to public folder:", err);</span>
2079
+ }
2080
+ }
2081
+ }
2082
+ &nbsp;
2083
+ // Process Scripts
2084
+ const __filename = fileURLToPath(import.meta.url);
2085
+ const __dirname = path.dirname(__filename);
2086
+ const srcScriptPath = path.join(__dirname, "src", "fetchData.js");
2087
+ await this.#processScripts(srcScriptPath);
2088
+ &nbsp;
2089
+ if (this.#isExternalAPI) {
2090
+ console.log("external API");
2091
+ await this.#loadFromAPI();
2092
+ } else {
2093
+ console.log(`database: ${this.database.type}`);
2094
+ if (!this.#databaseModel) {
2095
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (this.database.type === "file") {
2096
+ const adapter = new FileAdapter(this.database);
2097
+ this.#databaseModel = new DatabaseModel(adapter);
2098
+ }
2099
+ }
2100
+ console.log(`connected to database`);
2101
+ await this.#databaseModel.initialize();
2102
+ this.#articles.setDatabase(this.#databaseModel);
2103
+ const [dbTitle, dbArticles] = await Promise.all([
2104
+ this.#databaseModel.getBlogTitle(),
2105
+ this.#databaseModel.findAll(),
2106
+ ]);
2107
+ &nbsp;
2108
+ debug("dbArticles.size(): %d", dbArticles.length);
2109
+ //log(filename, "dbArticles.size(): " + dbArticles.length);
2110
+ //log(filename, "dbArticles.size(): " + dbArticles.length, "Blog.js");
2111
+ debug("all articles in Blog after loading from db");
2112
+ &nbsp;
2113
+ // Displays a beautiful table in the console
2114
+ //table(dbArticles)
2115
+ &nbsp;
2116
+ if (dbArticles.length == 0) {
2117
+ dbArticles.push(
2118
+ new Article(
2119
+ 1,
2120
+ "Sample Entry #1",
2121
+ "Prow scuttle parrel provost Sail ho shrouds spirits boom mizzenmast yardarm. Pinnace holystone mizzenmast quarter crow's nest nipperkin grog yardarm hempen halter furl. Swab barque interloper chantey doubloon starboard grog black jack gangway rutters.",
2122
+ new Date(),
2123
+ ),
2124
+ );
2125
+ dbArticles.push(
2126
+ new Article(
2127
+ 2,
2128
+ "Sample Entry #2",
2129
+ "Deadlights jack lad schooner scallywag dance the hempen jig carouser broadside cable strike colors. Bring a spring upon her cable holystone blow the man down spanker Shiver me timbers to go on account lookout wherry doubloon chase. Belay yo-ho-ho keelhaul squiffy black spot yardarm spyglass sheet transom heave to.",
2130
+ new Date(),
2131
+ ),
2132
+ );
2133
+ }
2134
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (this.reloadStylesOnGET)
2135
+ <span class="cstat-no" title="statement not covered" > console.log("reload scripts and styles on GET-Request");</span>
2136
+ let title = "";
2137
+ if (this.#title != null &amp;&amp; this.#title.length &gt; 0)
2138
+ title = this.#title; // use blog title if set
2139
+ else title = dbTitle; // use title from the database
2140
+ const responseData = { title: title, articles: dbArticles };
2141
+ this.#applyBlogData(responseData);
2142
+ }
2143
+ })();
2144
+ return this.#initPromise;
2145
+ }
2146
+ &nbsp;
2147
+ /** post a blog article */
2148
+ async postArticle(req, res) {
2149
+ const body = await new Promise((resolve, reject) =&gt; {
2150
+ let data = "";
2151
+ req.on("data", (chunk) =&gt; (data += chunk.toString()));
2152
+ req.on("end", () =&gt; resolve(data));
2153
+ req.on("error", reject);
2154
+ });
2155
+ &nbsp;
2156
+ //req.on("end", async () =&gt; {
2157
+ const params = new URLSearchParams(body);
2158
+ const title = params.get("title");
2159
+ const content = params.get("content");
2160
+ &nbsp;
2161
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (title &amp;&amp; content) {
2162
+ const newArticleData = { title, content };
2163
+ try {
2164
+ // Save the new article to the database via the ApiServer
2165
+ const promises = [];
2166
+ if (this.#databaseModel)
2167
+ promises.push(this.#databaseModel.save(newArticleData));
2168
+ if (this.#isExternalAPI)
2169
+ promises.push(postData(this.#apiUrl, newArticleData));
2170
+ await Promise.all(promises);
2171
+ // Add the article to the local list for immediate display
2172
+ this.#articles.insert(Article.createNew(title, content));
2173
+ // remove sample entries
2174
+ this.#articles.remove(1); // "Sample Entry #1"
2175
+ this.#articles.remove(2); // "Sample Entry #2"
2176
+ } catch (error) {
2177
+ <span class="cstat-no" title="statement not covered" > console.error("Failed to post new article to API:", error);</span>
2178
+ }
2179
+ }
2180
+ &nbsp;
2181
+ res.writeHead(303, { Location: "/" });
2182
+ res.end();
2183
+ //});
2184
+ }
2185
+ &nbsp;
2186
+ /** start a http server with default port 8080 */
2187
+ async startServer(port = <span class="branch-0 cbranch-no" title="branch not covered" >8080)</span> {
2188
+ await this.init();
2189
+ &nbsp;
2190
+ const server = http.createServer(async (req, res) =&gt; {
2191
+ //debug("query %s", req.url);
2192
+ // API routes
2193
+ if (req.url.startsWith("/api")) {
2194
+ await this.#jsonAPI(req, res);
2195
+ return;
2196
+ }
2197
+ &nbsp;
2198
+ // Web Page Routes
2199
+ if (req.url === "/login") {
2200
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (req.method === "GET") {
2201
+ <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": "text/html" });</span>
2202
+ <span class="cstat-no" title="statement not covered" > res.end(`${header("My Blog")}</span>
2203
+ &lt;body&gt;
2204
+ &lt;h1&gt;Login&lt;/h1&gt;&lt;div class="box"&gt;&lt;form method="POST"&gt;
2205
+ &lt;input type="password" name="password" placeholder="Password" /&gt;
2206
+ &lt;button style="margin: 2px;"&gt;Login&lt;/button&gt;&lt;/form&gt;&lt;/div&gt;
2207
+ &lt;/body&gt;&lt;/html&gt;`);
2208
+ <span class="cstat-no" title="statement not covered" > return;</span>
2209
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>if (req.method === "POST") {
2210
+ await this.#handleLogin(req, res);
2211
+ return;
2212
+ }
2213
+ }
2214
+ &nbsp;
2215
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (req.url === "/logout") {
2216
+ <span class="cstat-no" title="statement not covered" > this.#handleLogout(req, res);</span>
2217
+ <span class="cstat-no" title="statement not covered" > return;</span>
2218
+ }
2219
+ // POST new article
2220
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (req.method === "POST" &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >req.url === "/")</span> {
2221
+ <span class="cstat-no" title="statement not covered" > if (!this.#isAuthenticated(req)) {</span>
2222
+ <span class="cstat-no" title="statement not covered" > res.writeHead(403, { "Content-Type": "text/plain" });</span>
2223
+ <span class="cstat-no" title="statement not covered" > res.end("Forbidden");</span>
2224
+ <span class="cstat-no" title="statement not covered" > return;</span>
2225
+ }
2226
+ <span class="cstat-no" title="statement not covered" > await this.postArticle(req, res);</span>
2227
+ // GET artciles
2228
+ } else if (req.method === "GET" &amp;&amp; req.url === "/") {
2229
+ // load articles
2230
+ &nbsp;
2231
+ // reload styles and scripts on (every) request
2232
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (this.reloadStylesOnGET) {
2233
+ <span class="cstat-no" title="statement not covered" > if (this.#stylesheetPath != null &amp;&amp; this.compilestyle) {</span>
2234
+ <span class="cstat-no" title="statement not covered" > await this.#processStylesheets(this.#stylesheetPath);</span>
2235
+ }
2236
+ const __filename = <span class="cstat-no" title="statement not covered" >fileURLToPath(import.meta.url);</span>
2237
+ const __dirname = <span class="cstat-no" title="statement not covered" >path.dirname(__filename);</span>
2238
+ const srcScriptPath = <span class="cstat-no" title="statement not covered" >path.join(__dirname, "src", "fetchData.js");</span>
2239
+ <span class="cstat-no" title="statement not covered" > await this.#processScripts(srcScriptPath);</span>
2240
+ }
2241
+ &nbsp;
2242
+ let loggedin = false;
2243
+ if (!this.#isAuthenticated(req)) {
2244
+ // login
2245
+ loggedin = false;
2246
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
2247
+ // logout
2248
+ <span class="cstat-no" title="statement not covered" > loggedin = true;</span>
2249
+ }
2250
+ &nbsp;
2251
+ try {
2252
+ const html = await this.toHTML(loggedin); // render this blog to HTML
2253
+ res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8" });
2254
+ res.end(html);
2255
+ } catch (err) {
2256
+ <span class="cstat-no" title="statement not covered" > console.error(err);</span>
2257
+ <span class="cstat-no" title="statement not covered" > res.writeHead(500, { "Content-Type": "text/plain" });</span>
2258
+ <span class="cstat-no" title="statement not covered" > res.end("Internal Server Error");</span>
2259
+ }
2260
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
2261
+ // Try to serve static files from public folder
2262
+ <span class="cstat-no" title="statement not covered" > try {</span>
2263
+ const publicDir = <span class="cstat-no" title="statement not covered" >path.join(process.cwd(), "public");</span>
2264
+ const parsedUrl = <span class="cstat-no" title="statement not covered" >new URL(</span>
2265
+ req.url,
2266
+ `http://${req.headers.host || "localhost"}`,
2267
+ );
2268
+ const filePath = <span class="cstat-no" title="statement not covered" >path.join(publicDir, parsedUrl.pathname);</span>
2269
+ &nbsp;
2270
+ <span class="cstat-no" title="statement not covered" > if (filePath.startsWith(publicDir)) {</span>
2271
+ const stats = <span class="cstat-no" title="statement not covered" >await fs.promises.stat(filePath);</span>
2272
+ <span class="cstat-no" title="statement not covered" > if (stats.isFile()) {</span>
2273
+ const ext = <span class="cstat-no" title="statement not covered" >path.extname(filePath).toLowerCase();</span>
2274
+ const mimeTypes = <span class="cstat-no" title="statement not covered" >{</span>
2275
+ ".html": "text/html",
2276
+ ".js": "text/javascript",
2277
+ ".css": "text/css",
2278
+ ".json": "application/json",
2279
+ ".png": "image/png",
2280
+ ".jpg": "image/jpeg",
2281
+ ".gif": "image/gif",
2282
+ ".svg": "image/svg+xml",
2283
+ ".ico": "image/x-icon",
2284
+ };
2285
+ const contentType = <span class="cstat-no" title="statement not covered" >mimeTypes[ext] || "application/octet-stream";</span>
2286
+ <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": contentType });</span>
2287
+ <span class="cstat-no" title="statement not covered" > fs.createReadStream(filePath).pipe(res);</span>
2288
+ <span class="cstat-no" title="statement not covered" > return;</span>
2289
+ }
2290
+ }
2291
+ } catch (err) {
2292
+ // ENOENT (file not found) is expected, leading to a 404.
2293
+ // Only log other, unexpected errors.
2294
+ <span class="cstat-no" title="statement not covered" > if (err.code !== "ENOENT") {</span>
2295
+ <span class="cstat-no" title="statement not covered" > console.error(err);</span>
2296
+ }
2297
+ }
2298
+ &nbsp;
2299
+ // Error 404
2300
+ <span class="cstat-no" title="statement not covered" > res.writeHead(404, { "Content-Type": "application/json" });</span>
2301
+ <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ message: "Not Found" }));</span>
2302
+ }
2303
+ });
2304
+ &nbsp;
2305
+ this.#server = server;
2306
+ &nbsp;
2307
+ return new Promise((resolve, reject) =&gt; {
2308
+ const errorHandler = <span class="fstat-no" title="function not covered" >(e</span>rr) =&gt; <span class="cstat-no" title="statement not covered" >reject(err);</span>
2309
+ this.#server.once("error", errorHandler);
2310
+ this.#server.listen(port, "0.0.0.0", () =&gt; {
2311
+ // &lt;-- for docker 0.0.0.0, localhost 127.0.0.1
2312
+ this.#server.removeListener("error", errorHandler);
2313
+ console.log(`server running at http://localhost:${port}/`);
2314
+ resolve(); // Resolve the promise when the server is listening
2315
+ });
2316
+ });
2317
+ } // http server
2318
+ &nbsp;
2319
+ async closeServer() {
2320
+ return new Promise((resolve, reject) =&gt; {
2321
+ if (this.#server) {
2322
+ // if server is running
2323
+ this.#server.close((err) =&gt; {
2324
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (err &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >err.code !== "ERR_SERVER_NOT_RUNNING")</span> <span class="cstat-no" title="statement not covered" >return reject(err);</span>
2325
+ console.log("Server closed.");
2326
+ resolve();
2327
+ });
2328
+ } else {
2329
+ // server is not running
2330
+ resolve(); // Nothing to close
2331
+ }
2332
+ });
2333
+ }
2334
+ &nbsp;
2335
+ /** Populates the blog's title and articles from a data object. */
2336
+ #applyBlogData(data) {
2337
+ debug("applyBlogData");
2338
+ if (this.#articles.storage.clear) {
2339
+ this.#articles.storage.clear();
2340
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
2341
+ //this.#articles.setDataModel(this.#makeDataModel()); // Fallback if clear() isn't implemented
2342
+ }
2343
+ this.#title = data.title;
2344
+ // Assuming data contains a title and an array of articles with title and content
2345
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (this.#articles &amp;&amp; data.articles &amp;&amp; Array.isArray(data.articles)) {
2346
+ if (this.#articles.getStorageName().includes("BinarySearchTree")) {
2347
+ debug("using special insert method for BST");
2348
+ const insertBalanced = (start, end) =&gt; {
2349
+ if (start &gt; end) return;
2350
+ const mid = Math.floor((start + end) / 2);
2351
+ const articleData = data.articles[mid];
2352
+ const article = new Article(
2353
+ articleData.id,
2354
+ articleData.title,
2355
+ articleData.content,
2356
+ articleData.createdAt,
2357
+ );
2358
+ this.addArticle(article);
2359
+ insertBalanced(start, mid - 1);
2360
+ insertBalanced(mid + 1, end);
2361
+ };
2362
+ insertBalanced(0, data.articles.length - 1);
2363
+ } else {
2364
+ for (const articleData of data.articles) {
2365
+ const article = new Article(
2366
+ articleData.id,
2367
+ articleData.title,
2368
+ articleData.content,
2369
+ articleData.createdAt,
2370
+ );
2371
+ this.addArticle(article);
2372
+ }
2373
+ }
2374
+ }
2375
+ }
2376
+ &nbsp;
2377
+ async #loadFromAPI() {
2378
+ const data = await fetchData(this.#apiUrl);
2379
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (data) {
2380
+ this.#applyBlogData(data);
2381
+ }
2382
+ }
2383
+ &nbsp;
2384
+ // controller
2385
+ /** everything that happens in /api */
2386
+ async #jsonAPI(req, res) {
2387
+ const url = new URL(req.url, `http://${req.headers.host || <span class="branch-1 cbranch-no" title="branch not covered" >"localhost"}</span>`);
2388
+ const pathname = url.pathname;
2389
+ &nbsp;
2390
+ if (req.method === "GET") {
2391
+ if (pathname === "/api" || pathname === "/api/") {
2392
+ res.writeHead(200, { "Content-Type": "application/json" });
2393
+ const data = {
2394
+ title: this.title,
2395
+ };
2396
+ res.end(JSON.stringify(data));
2397
+ }
2398
+ // Search
2399
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (url.searchParams.has("q")) {
2400
+ const query = <span class="cstat-no" title="statement not covered" >url.searchParams.get("q");</span>
2401
+ <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": "application/json" });</span>
2402
+ const results = <span class="cstat-no" title="statement not covered" >this.#articles.search(query);</span>
2403
+ <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ articles: results }));</span>
2404
+ <span class="cstat-no" title="statement not covered" > return;</span>
2405
+ }
2406
+ // GET all blog data
2407
+ if (pathname === "/api/articles") {
2408
+ // Use 'offset' param as startId (filter) to get items starting at ID
2409
+ const pLimit = parseInt(url.searchParams.get("limit"));
2410
+ const limit = !isNaN(pLimit) ? <span class="branch-0 cbranch-no" title="branch not covered" >pLimit </span>: null;
2411
+ &nbsp;
2412
+ const start = url.searchParams.get("startdate");
2413
+ const end = url.searchParams.get("enddate");
2414
+ //const parsedStart = parseDateParam(qStartdate);
2415
+ //const parsedEnd = parseDateParam(qEnddate, true);
2416
+ &nbsp;
2417
+ //const effectiveStart = parsedStart !== null ? parsedStart : startID;
2418
+ //const effectiveEnd = parsedEnd !== null ? parsedEnd : endID;
2419
+ &nbsp;
2420
+ // controller
2421
+ res.writeHead(200, { "Content-Type": "application/json" });
2422
+ const dbArticles = await this.#articles.findAll(start, end, limit);
2423
+ const responseData = {
2424
+ title: this.title, // Keep the title from the original constant
2425
+ articles: dbArticles,
2426
+ };
2427
+ res.end(JSON.stringify(responseData));
2428
+ }
2429
+ &nbsp;
2430
+ // POST a new article
2431
+ } else if (req.method === "POST" &amp;&amp; pathname === "/api/articles") {
2432
+ if (!this.#isAuthenticated(req)) {
2433
+ res.writeHead(403, { "Content-Type": "application/json" });
2434
+ res.end(JSON.stringify({ error: "Forbidden" }));
2435
+ return;
2436
+ }
2437
+ const body = await new Promise((resolve, reject) =&gt; {
2438
+ let data = "";
2439
+ req.on("data", (chunk) =&gt; (data += chunk.toString()));
2440
+ req.on("end", () =&gt; resolve(data));
2441
+ req.on("error", reject);
2442
+ });
2443
+ const newArticle = JSON.parse(body);
2444
+ // local
2445
+ await this.#databaseModel.save(newArticle); // --&gt; to api server
2446
+ // extern
2447
+ res.writeHead(201, { "Content-Type": "application/json" });
2448
+ res.end(JSON.stringify(newArticle));
2449
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="else path not taken" >E</span>if (req.method === "DELETE" &amp;&amp; pathname === "/api/articles") {</span>
2450
+ <span class="cstat-no" title="statement not covered" > if (!this.#isAuthenticated(req)) {</span>
2451
+ <span class="cstat-no" title="statement not covered" > res.writeHead(403, { "Content-Type": "application/json" });</span>
2452
+ <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ error: "Forbidden" }));</span>
2453
+ <span class="cstat-no" title="statement not covered" > return;</span>
2454
+ }
2455
+ const id = <span class="cstat-no" title="statement not covered" >url.searchParams.get("id");</span>
2456
+ <span class="cstat-no" title="statement not covered" > if (id) {</span>
2457
+ <span class="cstat-no" title="statement not covered" > this.#articles.remove(parseInt(id));</span>
2458
+ <span class="cstat-no" title="statement not covered" > if (this.#databaseModel) {</span>
2459
+ <span class="cstat-no" title="statement not covered" > await this.#databaseModel.remove(parseInt(id));</span>
2460
+ }
2461
+ <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": "application/json" });</span>
2462
+ <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ status: "deleted", id }));</span>
2463
+ }
2464
+ } else <span class="cstat-no" title="statement not covered" >if (req.method === "PUT" &amp;&amp; pathname === "/api/articles") {</span>
2465
+ <span class="cstat-no" title="statement not covered" > if (!this.#isAuthenticated(req)) {</span>
2466
+ <span class="cstat-no" title="statement not covered" > res.writeHead(403, { "Content-Type": "application/json" });</span>
2467
+ <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ error: "Forbidden" }));</span>
2468
+ <span class="cstat-no" title="statement not covered" > return;</span>
2469
+ }
2470
+ const id = <span class="cstat-no" title="statement not covered" >url.searchParams.get("id");</span>
2471
+ const body = <span class="cstat-no" title="statement not covered" >await new Promise(<span class="fstat-no" title="function not covered" >(r</span>esolve) =&gt; {</span>
2472
+ let data = <span class="cstat-no" title="statement not covered" >"";</span>
2473
+ <span class="cstat-no" title="statement not covered" > req.on("data", <span class="fstat-no" title="function not covered" >(c</span>hunk) =&gt; (<span class="cstat-no" title="statement not covered" >data += chunk)</span>);</span>
2474
+ <span class="cstat-no" title="statement not covered" > req.on("end", <span class="fstat-no" title="function not covered" >()</span> =&gt; <span class="cstat-no" title="statement not covered" >resolve(data))</span>;</span>
2475
+ });
2476
+ const { title, content } = <span class="cstat-no" title="statement not covered" >JSON.parse(body);</span>
2477
+ <span class="cstat-no" title="statement not covered" > this.#articles.update(parseInt(id), title, content);</span>
2478
+ <span class="cstat-no" title="statement not covered" > if (this.#databaseModel) {</span>
2479
+ <span class="cstat-no" title="statement not covered" > await this.#databaseModel.update(parseInt(id), { title, content });</span>
2480
+ }
2481
+ <span class="cstat-no" title="statement not covered" > res.writeHead(200, { "Content-Type": "application/json" });</span>
2482
+ <span class="cstat-no" title="statement not covered" > res.end(JSON.stringify({ status: "updated", id }));</span>
2483
+ }
2484
+ }
2485
+ &nbsp;
2486
+ /** set external API */
2487
+ setAPI(APIUrl) {
2488
+ this.#apiUrl = APIUrl;
2489
+ this.#isExternalAPI = true;
2490
+ }
2491
+ &nbsp;
2492
+ /** print markdown to the console */
2493
+ print() {
2494
+ const data = {
2495
+ title: this.title,
2496
+ articles: this.#articles.getAllArticles(),
2497
+ };
2498
+ const markdown = formatMarkdown(data);
2499
+ console.log(markdown);
2500
+ }
2501
+ &nbsp;
2502
+ /** render this blog content to valid html */
2503
+ async toHTML(loggedin) {
2504
+ const articles = this.#articles.getAllArticles();
2505
+ const articles_after = articles.slice(0, 50);
2506
+ // prettier-ignore
2507
+ debug("slice articles from %d to %d", articles.length, articles_after.length);
2508
+ const data = {
2509
+ title: this.title,
2510
+ articles: articles_after,
2511
+ loggedin,
2512
+ login: "",
2513
+ };
2514
+ &nbsp;
2515
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (loggedin) <span class="cstat-no" title="statement not covered" >data.login = `&lt;a href="/logout"&gt;logout&lt;/a&gt;`;</span>
2516
+ else data.login = `&lt;a href="/login"&gt;login&lt;/a&gt;`;
2517
+ &nbsp;
2518
+ //debug("typeof data: %o", typeof data);
2519
+ //debug("typeof data.articles: %o", typeof data.articles);
2520
+ //debug("typeof data.articles: %O", data.articles);
2521
+ const article = data.articles[0];
2522
+ debug("first article: ");
2523
+ debug("%d %s %s", article.id, article.title, article.getContentVeryShort());
2524
+ const html = formatHTML(data);
2525
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (validate(html)) return html;
2526
+ <span class="cstat-no" title="statement not covered" > throw new Error("Error. Invalid HTML!");</span>
2527
+ }
2528
+ &nbsp;
2529
+ /**
2530
+ * read files, compare checksums, compile and write to public/styles.min.css
2531
+ * @param {string[]} files - Array of css/scss file paths to process.
2532
+ */
2533
+ async #processStylesheets(files) {
2534
+ console.log("process stylesheets");
2535
+ &nbsp;
2536
+ // Normalize input to array (handles string or array)
2537
+ // "file1.css" --&gt; ["file1.css"]
2538
+ // ["file1.css", "file2.css",...]
2539
+ const fileList = Array.isArray(files) ? files : [files];
2540
+ const styleFiles = fileList.filter(
2541
+ (f) =&gt;
2542
+ typeof f === "string" &amp;&amp;
2543
+ (f.endsWith(".scss") || f.endsWith(".css")) &amp;&amp;
2544
+ !f.endsWith(".min.css"),
2545
+ );
2546
+ //const scriptFiles = files.filter((f) =&gt; f.endsWith(".js") &amp;&amp; !f.endsWith(".min.js"));
2547
+ &nbsp;
2548
+ // --- Process Styles ---
2549
+ if (styleFiles.length &gt; 0) {
2550
+ // read file
2551
+ const fileData = await Promise.all(
2552
+ styleFiles.sort().map(async (f) =&gt; {
2553
+ const content = await fs.promises.readFile(f, "utf-8");
2554
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (content == "") <span class="cstat-no" title="statement not covered" >throw new Error("Invalid Filepath or empty file!");</span>
2555
+ return { path: f, content };
2556
+ }),
2557
+ );
2558
+ &nbsp;
2559
+ // compute hash
2560
+ const currentHash = crypto
2561
+ .createHash("sha256")
2562
+ .update(
2563
+ fileData
2564
+ .map((f) =&gt;
2565
+ crypto.createHash("sha256").update(f.content).digest("hex"),
2566
+ )
2567
+ .join(""),
2568
+ )
2569
+ .digest("hex");
2570
+ &nbsp;
2571
+ // check if hash matches
2572
+ if (currentHash !== this.#stylesHash &amp;&amp; this.compilestyle) {
2573
+ console.log("Style assets have changed. Recompiling...");
2574
+ this.#stylesHash = currentHash;
2575
+ &nbsp;
2576
+ // Compile styles using the standalone script from build-styles.js
2577
+ this.compiledStyles = await compileStyles(fileData);
2578
+ &nbsp;
2579
+ // generate a file
2580
+ const publicDir = path.join(process.cwd(), "public");
2581
+ &nbsp;
2582
+ await fs.promises.mkdir(publicDir, { recursive: true });
2583
+ await fs.promises.writeFile(
2584
+ path.join(publicDir, "styles.min.css"),
2585
+ this.compiledStyles + `\n/* source-hash: ${currentHash} */`,
2586
+ );
2587
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
2588
+ <span class="cstat-no" title="statement not covered" > console.log("styles are up-to-date");</span>
2589
+ }
2590
+ }
2591
+ }
2592
+ &nbsp;
2593
+ /**
2594
+ * read files, compare checksums, compile and write to public/scripts.min.js
2595
+ * @param {string|string[]} files - File path(s) to process.
2596
+ */
2597
+ async #processScripts(files) {
2598
+ // Normalize input to array
2599
+ const fileList = Array.isArray(files) ? <span class="branch-0 cbranch-no" title="branch not covered" >files </span>: [files];
2600
+ const scriptFiles = fileList.filter(
2601
+ (f) =&gt;
2602
+ typeof f === "string" &amp;&amp; f.endsWith(".js") &amp;&amp; !f.endsWith(".min.js"),
2603
+ );
2604
+ &nbsp;
2605
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (scriptFiles.length &gt; 0) {
2606
+ const fileData = await Promise.all(
2607
+ scriptFiles.map(async (f) =&gt; {
2608
+ const content = await fs.promises.readFile(f, "utf-8");
2609
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (content == "") <span class="cstat-no" title="statement not covered" >throw new Error("Invalid Filepath or empty file!");</span>
2610
+ return { path: f, content };
2611
+ }),
2612
+ );
2613
+ &nbsp;
2614
+ const currentHash = crypto
2615
+ .createHash("sha256")
2616
+ .update(
2617
+ fileData
2618
+ .map((f) =&gt;
2619
+ crypto.createHash("sha256").update(f.content).digest("hex"),
2620
+ )
2621
+ .join(""),
2622
+ )
2623
+ .digest("hex");
2624
+ &nbsp;
2625
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (!this.#scriptsHash) {
2626
+ try {
2627
+ const publicDir = path.join(process.cwd(), "public");
2628
+ const existing = await fs.promises.readFile(
2629
+ path.join(publicDir, "scripts.min.js"),
2630
+ "utf-8",
2631
+ );
2632
+ const match = existing.match(/\/\* source-hash: ([a-f0-9]{64}) \*\//);
2633
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (match) this.#scriptsHash = match[1];
2634
+ } catch (err) {
2635
+ // ignore
2636
+ }
2637
+ }
2638
+ &nbsp;
2639
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (currentHash !== this.#scriptsHash) {
2640
+ <span class="cstat-no" title="statement not covered" > console.log("Script assets have changed. Recompiling...");</span>
2641
+ <span class="cstat-no" title="statement not covered" > this.#scriptsHash = currentHash;</span>
2642
+ &nbsp;
2643
+ const compiledScripts = <span class="cstat-no" title="statement not covered" >await compileScripts(fileData);</span>
2644
+ &nbsp;
2645
+ const publicDir = <span class="cstat-no" title="statement not covered" >path.join(process.cwd(), "public");</span>
2646
+ <span class="cstat-no" title="statement not covered" > await fs.promises.mkdir(publicDir, { recursive: true });</span>
2647
+ <span class="cstat-no" title="statement not covered" > await fs.promises.writeFile(</span>
2648
+ path.join(publicDir, "scripts.min.js"),
2649
+ compiledScripts + `\n/* source-hash: ${currentHash} */`,
2650
+ );
2651
+ }
2652
+ }
2653
+ }
2654
+ }
2655
+ &nbsp;</pre></td></tr></table></pre>
2656
+
2657
+ <div class='push'></div><!-- for sticky footer -->
2658
+ </div><!-- /wrapper -->
2659
+ <div class='footer quiet pad2 space-top1 center small'>
2660
+ Code coverage generated by
2661
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2662
+ at 2026-01-18T09:21:18.383Z
2663
+ </div>
2664
+ <script src="../prettify.js"></script>
2665
+ <script>
2666
+ window.onload = function () {
2667
+ prettyPrint();
2668
+ };
2669
+ </script>
2670
+ <script src="../sorter.js"></script>
2671
+ <script src="../block-navigation.js"></script>
2672
+ </body>
2673
+ </html>
2674
+