@sentry/warden 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/CHANGELOG.md +246 -0
  2. package/README.md +2 -1
  3. package/coverage/lcov-report/base.css +224 -0
  4. package/coverage/lcov-report/block-navigation.js +87 -0
  5. package/coverage/lcov-report/favicon.png +0 -0
  6. package/coverage/lcov-report/index.html +446 -0
  7. package/coverage/lcov-report/prettify.css +1 -0
  8. package/coverage/lcov-report/prettify.js +2 -0
  9. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  10. package/coverage/lcov-report/sorter.js +210 -0
  11. package/coverage/lcov-report/src/action/checks/index.html +116 -0
  12. package/coverage/lcov-report/src/action/checks/manager.ts.html +499 -0
  13. package/coverage/lcov-report/src/action/error-reporting.ts.html +181 -0
  14. package/coverage/lcov-report/src/action/fix-evaluation/github.ts.html +508 -0
  15. package/coverage/lcov-report/src/action/fix-evaluation/index.html +161 -0
  16. package/coverage/lcov-report/src/action/fix-evaluation/index.ts.html +1243 -0
  17. package/coverage/lcov-report/src/action/fix-evaluation/judge.ts.html +817 -0
  18. package/coverage/lcov-report/src/action/fix-evaluation/types.ts.html +274 -0
  19. package/coverage/lcov-report/src/action/index.html +161 -0
  20. package/coverage/lcov-report/src/action/inputs.ts.html +529 -0
  21. package/coverage/lcov-report/src/action/pi-ncc-compat.ts.html +292 -0
  22. package/coverage/lcov-report/src/action/review/coordination.ts.html +208 -0
  23. package/coverage/lcov-report/src/action/review/index.html +131 -0
  24. package/coverage/lcov-report/src/action/review/poster.ts.html +1051 -0
  25. package/coverage/lcov-report/src/action/review-state.ts.html +280 -0
  26. package/coverage/lcov-report/src/action/triggers/executor.ts.html +856 -0
  27. package/coverage/lcov-report/src/action/triggers/index.html +116 -0
  28. package/coverage/lcov-report/src/action/workflow/base.ts.html +1135 -0
  29. package/coverage/lcov-report/src/action/workflow/index.html +146 -0
  30. package/coverage/lcov-report/src/action/workflow/pr-workflow.ts.html +2713 -0
  31. package/coverage/lcov-report/src/action/workflow/schedule.ts.html +1027 -0
  32. package/coverage/lcov-report/src/cli/args.ts.html +1657 -0
  33. package/coverage/lcov-report/src/cli/commands/add.ts.html +1567 -0
  34. package/coverage/lcov-report/src/cli/commands/build.ts.html +1618 -0
  35. package/coverage/lcov-report/src/cli/commands/index.html +191 -0
  36. package/coverage/lcov-report/src/cli/commands/init.ts.html +1357 -0
  37. package/coverage/lcov-report/src/cli/commands/runs.ts.html +2560 -0
  38. package/coverage/lcov-report/src/cli/commands/setup-app/browser.ts.html +214 -0
  39. package/coverage/lcov-report/src/cli/commands/setup-app/credentials.ts.html +220 -0
  40. package/coverage/lcov-report/src/cli/commands/setup-app/index.html +161 -0
  41. package/coverage/lcov-report/src/cli/commands/setup-app/manifest.ts.html +235 -0
  42. package/coverage/lcov-report/src/cli/commands/setup-app/server.ts.html +601 -0
  43. package/coverage/lcov-report/src/cli/commands/setup-app.ts.html +571 -0
  44. package/coverage/lcov-report/src/cli/commands/sync.ts.html +475 -0
  45. package/coverage/lcov-report/src/cli/context.ts.html +532 -0
  46. package/coverage/lcov-report/src/cli/diff-apply.ts.html +334 -0
  47. package/coverage/lcov-report/src/cli/files.ts.html +904 -0
  48. package/coverage/lcov-report/src/cli/fix.ts.html +1060 -0
  49. package/coverage/lcov-report/src/cli/git.ts.html +1201 -0
  50. package/coverage/lcov-report/src/cli/help.ts.html +1696 -0
  51. package/coverage/lcov-report/src/cli/index.html +281 -0
  52. package/coverage/lcov-report/src/cli/input.ts.html +397 -0
  53. package/coverage/lcov-report/src/cli/log-cleanup.ts.html +337 -0
  54. package/coverage/lcov-report/src/cli/main.ts.html +5107 -0
  55. package/coverage/lcov-report/src/cli/output/box.ts.html +790 -0
  56. package/coverage/lcov-report/src/cli/output/formatters.ts.html +1099 -0
  57. package/coverage/lcov-report/src/cli/output/icons.ts.html +142 -0
  58. package/coverage/lcov-report/src/cli/output/index.html +281 -0
  59. package/coverage/lcov-report/src/cli/output/index.ts.html +295 -0
  60. package/coverage/lcov-report/src/cli/output/ink-runner.tsx.html +1597 -0
  61. package/coverage/lcov-report/src/cli/output/jsonl-schema-gen.ts.html +355 -0
  62. package/coverage/lcov-report/src/cli/output/jsonl.ts.html +2137 -0
  63. package/coverage/lcov-report/src/cli/output/live-status.tsx.html +916 -0
  64. package/coverage/lcov-report/src/cli/output/reporter.ts.html +1630 -0
  65. package/coverage/lcov-report/src/cli/output/tasks.ts.html +3193 -0
  66. package/coverage/lcov-report/src/cli/output/tty.ts.html +310 -0
  67. package/coverage/lcov-report/src/cli/output/verbosity.ts.html +181 -0
  68. package/coverage/lcov-report/src/cli/signals.ts.html +199 -0
  69. package/coverage/lcov-report/src/cli/terminal.ts.html +1060 -0
  70. package/coverage/lcov-report/src/config/index.html +161 -0
  71. package/coverage/lcov-report/src/config/index.ts.html +94 -0
  72. package/coverage/lcov-report/src/config/loader.ts.html +1753 -0
  73. package/coverage/lcov-report/src/config/schema.ts.html +910 -0
  74. package/coverage/lcov-report/src/config/writer.ts.html +538 -0
  75. package/coverage/lcov-report/src/diff/apply.ts.html +241 -0
  76. package/coverage/lcov-report/src/diff/classify.ts.html +361 -0
  77. package/coverage/lcov-report/src/diff/coalesce.ts.html +1123 -0
  78. package/coverage/lcov-report/src/diff/context.ts.html +952 -0
  79. package/coverage/lcov-report/src/diff/index.html +191 -0
  80. package/coverage/lcov-report/src/diff/index.ts.html +100 -0
  81. package/coverage/lcov-report/src/diff/parser.ts.html +532 -0
  82. package/coverage/lcov-report/src/evals/harness.ts.html +700 -0
  83. package/coverage/lcov-report/src/evals/index.html +221 -0
  84. package/coverage/lcov-report/src/evals/index.ts.html +955 -0
  85. package/coverage/lcov-report/src/evals/names.ts.html +121 -0
  86. package/coverage/lcov-report/src/evals/runner.ts.html +664 -0
  87. package/coverage/lcov-report/src/evals/scaffold.ts.html +970 -0
  88. package/coverage/lcov-report/src/evals/types.ts.html +661 -0
  89. package/coverage/lcov-report/src/evals/usage.ts.html +178 -0
  90. package/coverage/lcov-report/src/evals/verify.ts.html +1054 -0
  91. package/coverage/lcov-report/src/event/context.ts.html +490 -0
  92. package/coverage/lcov-report/src/event/index.html +116 -0
  93. package/coverage/lcov-report/src/index.html +116 -0
  94. package/coverage/lcov-report/src/output/dedup.ts.html +2950 -0
  95. package/coverage/lcov-report/src/output/github-checks.ts.html +1579 -0
  96. package/coverage/lcov-report/src/output/index.html +161 -0
  97. package/coverage/lcov-report/src/output/renderer.ts.html +988 -0
  98. package/coverage/lcov-report/src/output/stale.ts.html +640 -0
  99. package/coverage/lcov-report/src/sdk/analyze.ts.html +3010 -0
  100. package/coverage/lcov-report/src/sdk/auth.ts.html +217 -0
  101. package/coverage/lcov-report/src/sdk/circuit-breaker.ts.html +304 -0
  102. package/coverage/lcov-report/src/sdk/errors.ts.html +658 -0
  103. package/coverage/lcov-report/src/sdk/extract.ts.html +1810 -0
  104. package/coverage/lcov-report/src/sdk/fix-quality.ts.html +841 -0
  105. package/coverage/lcov-report/src/sdk/haiku.ts.html +1456 -0
  106. package/coverage/lcov-report/src/sdk/index.html +416 -0
  107. package/coverage/lcov-report/src/sdk/json-output.ts.html +508 -0
  108. package/coverage/lcov-report/src/sdk/model-pricing.json.html +499 -0
  109. package/coverage/lcov-report/src/sdk/otel.ts.html +433 -0
  110. package/coverage/lcov-report/src/sdk/post-process.ts.html +412 -0
  111. package/coverage/lcov-report/src/sdk/prepare.ts.html +400 -0
  112. package/coverage/lcov-report/src/sdk/pricing.ts.html +778 -0
  113. package/coverage/lcov-report/src/sdk/prompt-sections.ts.html +595 -0
  114. package/coverage/lcov-report/src/sdk/prompt.ts.html +451 -0
  115. package/coverage/lcov-report/src/sdk/report-files.ts.html +166 -0
  116. package/coverage/lcov-report/src/sdk/retry.ts.html +202 -0
  117. package/coverage/lcov-report/src/sdk/runner.ts.html +400 -0
  118. package/coverage/lcov-report/src/sdk/runtimes/claude.ts.html +1693 -0
  119. package/coverage/lcov-report/src/sdk/runtimes/index.html +176 -0
  120. package/coverage/lcov-report/src/sdk/runtimes/index.ts.html +244 -0
  121. package/coverage/lcov-report/src/sdk/runtimes/model-selectors.ts.html +328 -0
  122. package/coverage/lcov-report/src/sdk/runtimes/pi.ts.html +2104 -0
  123. package/coverage/lcov-report/src/sdk/runtimes/types.ts.html +508 -0
  124. package/coverage/lcov-report/src/sdk/types.ts.html +730 -0
  125. package/coverage/lcov-report/src/sdk/usage.ts.html +502 -0
  126. package/coverage/lcov-report/src/sdk/verify.ts.html +1027 -0
  127. package/coverage/lcov-report/src/sentry.ts.html +994 -0
  128. package/coverage/lcov-report/src/skill-builder/agentic.ts.html +1063 -0
  129. package/coverage/lcov-report/src/skill-builder/authoring-provider.ts.html +334 -0
  130. package/coverage/lcov-report/src/skill-builder/definition.ts.html +748 -0
  131. package/coverage/lcov-report/src/skill-builder/index.html +236 -0
  132. package/coverage/lcov-report/src/skill-builder/outline-contract.ts.html +400 -0
  133. package/coverage/lcov-report/src/skill-builder/outline-state.ts.html +382 -0
  134. package/coverage/lcov-report/src/skill-builder/outline.ts.html +1402 -0
  135. package/coverage/lcov-report/src/skill-builder/skill-contract.ts.html +382 -0
  136. package/coverage/lcov-report/src/skill-builder/skill-prompts.ts.html +1180 -0
  137. package/coverage/lcov-report/src/skill-builder/skill.ts.html +2398 -0
  138. package/coverage/lcov-report/src/skills/index.html +131 -0
  139. package/coverage/lcov-report/src/skills/loader.ts.html +1693 -0
  140. package/coverage/lcov-report/src/skills/remote.ts.html +1909 -0
  141. package/coverage/lcov-report/src/triggers/index.html +116 -0
  142. package/coverage/lcov-report/src/triggers/matcher.ts.html +841 -0
  143. package/coverage/lcov-report/src/types/index.html +116 -0
  144. package/coverage/lcov-report/src/types/index.ts.html +1240 -0
  145. package/coverage/lcov-report/src/utils/async.ts.html +331 -0
  146. package/coverage/lcov-report/src/utils/exec.ts.html +496 -0
  147. package/coverage/lcov-report/src/utils/index.html +176 -0
  148. package/coverage/lcov-report/src/utils/index.ts.html +313 -0
  149. package/coverage/lcov-report/src/utils/path.ts.html +202 -0
  150. package/coverage/lcov-report/src/utils/version.ts.html +136 -0
  151. package/coverage/lcov.info +19134 -0
  152. package/dist/cli/commands/runs.d.ts +1 -1
  153. package/dist/cli/commands/runs.d.ts.map +1 -1
  154. package/dist/cli/commands/runs.js +1 -1
  155. package/dist/cli/commands/runs.js.map +1 -1
  156. package/dist/cli/files.d.ts.map +1 -1
  157. package/dist/cli/files.js +10 -11
  158. package/dist/cli/files.js.map +1 -1
  159. package/dist/sdk/verify.d.ts.map +1 -1
  160. package/dist/sdk/verify.js +3 -2
  161. package/dist/sdk/verify.js.map +1 -1
  162. package/dist/skill-builder/outline.d.ts.map +1 -1
  163. package/dist/skill-builder/outline.js.map +1 -1
  164. package/package.json +8 -3
  165. package/test-results.junit.xml +4329 -0
  166. package/dist/evals/index.d.ts +0 -22
  167. package/dist/evals/index.d.ts.map +0 -1
  168. package/dist/evals/index.js +0 -92
  169. package/dist/evals/index.js.map +0 -1
  170. package/dist/evals/judge.d.ts +0 -12
  171. package/dist/evals/judge.d.ts.map +0 -1
  172. package/dist/evals/judge.js +0 -171
  173. package/dist/evals/judge.js.map +0 -1
  174. package/dist/evals/runner.d.ts +0 -18
  175. package/dist/evals/runner.d.ts.map +0 -1
  176. package/dist/evals/runner.js +0 -149
  177. package/dist/evals/runner.js.map +0 -1
  178. package/dist/evals/setup.d.ts +0 -2
  179. package/dist/evals/setup.d.ts.map +0 -1
  180. package/dist/evals/setup.js +0 -22
  181. package/dist/evals/setup.js.map +0 -1
  182. package/dist/evals/types.d.ts +0 -160
  183. package/dist/evals/types.d.ts.map +0 -1
  184. package/dist/evals/types.js +0 -148
  185. package/dist/evals/types.js.map +0 -1
@@ -0,0 +1,988 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/output/renderer.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/output</a> renderer.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">96.12% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>124/129</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">95.12% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>78/82</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>23/23</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">96% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>120/125</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
368
+ <span class="cline-any cline-neutral">&nbsp;</span>
369
+ <span class="cline-any cline-neutral">&nbsp;</span>
370
+ <span class="cline-any cline-neutral">&nbsp;</span>
371
+ <span class="cline-any cline-neutral">&nbsp;</span>
372
+ <span class="cline-any cline-neutral">&nbsp;</span>
373
+ <span class="cline-any cline-neutral">&nbsp;</span>
374
+ <span class="cline-any cline-neutral">&nbsp;</span>
375
+ <span class="cline-any cline-yes">78x</span>
376
+ <span class="cline-any cline-neutral">&nbsp;</span>
377
+ <span class="cline-any cline-neutral">&nbsp;</span>
378
+ <span class="cline-any cline-yes">78x</span>
379
+ <span class="cline-any cline-yes">78x</span>
380
+ <span class="cline-any cline-yes">78x</span>
381
+ <span class="cline-any cline-yes">10x</span>
382
+ <span class="cline-any cline-neutral">&nbsp;</span>
383
+ <span class="cline-any cline-neutral">&nbsp;</span>
384
+ <span class="cline-any cline-neutral">&nbsp;</span>
385
+ <span class="cline-any cline-yes">78x</span>
386
+ <span class="cline-any cline-yes">78x</span>
387
+ <span class="cline-any cline-neutral">&nbsp;</span>
388
+ <span class="cline-any cline-neutral">&nbsp;</span>
389
+ <span class="cline-any cline-neutral">&nbsp;</span>
390
+ <span class="cline-any cline-yes">78x</span>
391
+ <span class="cline-any cline-yes">78x</span>
392
+ <span class="cline-any cline-yes">78x</span>
393
+ <span class="cline-any cline-neutral">&nbsp;</span>
394
+ <span class="cline-any cline-yes">78x</span>
395
+ <span class="cline-any cline-neutral">&nbsp;</span>
396
+ <span class="cline-any cline-neutral">&nbsp;</span>
397
+ <span class="cline-any cline-neutral">&nbsp;</span>
398
+ <span class="cline-any cline-neutral">&nbsp;</span>
399
+ <span class="cline-any cline-neutral">&nbsp;</span>
400
+ <span class="cline-any cline-neutral">&nbsp;</span>
401
+ <span class="cline-any cline-neutral">&nbsp;</span>
402
+ <span class="cline-any cline-neutral">&nbsp;</span>
403
+ <span class="cline-any cline-neutral">&nbsp;</span>
404
+ <span class="cline-any cline-neutral">&nbsp;</span>
405
+ <span class="cline-any cline-yes">78x</span>
406
+ <span class="cline-any cline-yes">78x</span>
407
+ <span class="cline-any cline-neutral">&nbsp;</span>
408
+ <span class="cline-any cline-neutral">&nbsp;</span>
409
+ <span class="cline-any cline-neutral">&nbsp;</span>
410
+ <span class="cline-any cline-yes">78x</span>
411
+ <span class="cline-any cline-neutral">&nbsp;</span>
412
+ <span class="cline-any cline-neutral">&nbsp;</span>
413
+ <span class="cline-any cline-yes">78x</span>
414
+ <span class="cline-any cline-yes">28x</span>
415
+ <span class="cline-any cline-yes">2x</span>
416
+ <span class="cline-any cline-neutral">&nbsp;</span>
417
+ <span class="cline-any cline-neutral">&nbsp;</span>
418
+ <span class="cline-any cline-neutral">&nbsp;</span>
419
+ <span class="cline-any cline-neutral">&nbsp;</span>
420
+ <span class="cline-any cline-neutral">&nbsp;</span>
421
+ <span class="cline-any cline-neutral">&nbsp;</span>
422
+ <span class="cline-any cline-yes">26x</span>
423
+ <span class="cline-any cline-yes">2x</span>
424
+ <span class="cline-any cline-neutral">&nbsp;</span>
425
+ <span class="cline-any cline-neutral">&nbsp;</span>
426
+ <span class="cline-any cline-neutral">&nbsp;</span>
427
+ <span class="cline-any cline-neutral">&nbsp;</span>
428
+ <span class="cline-any cline-neutral">&nbsp;</span>
429
+ <span class="cline-any cline-yes">24x</span>
430
+ <span class="cline-any cline-neutral">&nbsp;</span>
431
+ <span class="cline-any cline-neutral">&nbsp;</span>
432
+ <span class="cline-any cline-yes">50x</span>
433
+ <span class="cline-any cline-yes">59x</span>
434
+ <span class="cline-any cline-yes">59x</span>
435
+ <span class="cline-any cline-no">&nbsp;</span>
436
+ <span class="cline-any cline-neutral">&nbsp;</span>
437
+ <span class="cline-any cline-yes">59x</span>
438
+ <span class="cline-any cline-neutral">&nbsp;</span>
439
+ <span class="cline-any cline-yes">59x</span>
440
+ <span class="cline-any cline-yes">1x</span>
441
+ <span class="cline-any cline-neutral">&nbsp;</span>
442
+ <span class="cline-any cline-neutral">&nbsp;</span>
443
+ <span class="cline-any cline-yes">59x</span>
444
+ <span class="cline-any cline-yes">1x</span>
445
+ <span class="cline-any cline-neutral">&nbsp;</span>
446
+ <span class="cline-any cline-neutral">&nbsp;</span>
447
+ <span class="cline-any cline-neutral">&nbsp;</span>
448
+ <span class="cline-any cline-yes">59x</span>
449
+ <span class="cline-any cline-yes">3x</span>
450
+ <span class="cline-any cline-neutral">&nbsp;</span>
451
+ <span class="cline-any cline-neutral">&nbsp;</span>
452
+ <span class="cline-any cline-neutral">&nbsp;</span>
453
+ <span class="cline-any cline-yes">3x</span>
454
+ <span class="cline-any cline-yes">5x</span>
455
+ <span class="cline-any cline-yes">5x</span>
456
+ <span class="cline-any cline-neutral">&nbsp;</span>
457
+ <span class="cline-any cline-yes">3x</span>
458
+ <span class="cline-any cline-neutral">&nbsp;</span>
459
+ <span class="cline-any cline-neutral">&nbsp;</span>
460
+ <span class="cline-any cline-neutral">&nbsp;</span>
461
+ <span class="cline-any cline-yes">59x</span>
462
+ <span class="cline-any cline-neutral">&nbsp;</span>
463
+ <span class="cline-any cline-neutral">&nbsp;</span>
464
+ <span class="cline-any cline-yes">59x</span>
465
+ <span class="cline-any cline-yes">59x</span>
466
+ <span class="cline-any cline-yes">59x</span>
467
+ <span class="cline-any cline-neutral">&nbsp;</span>
468
+ <span class="cline-any cline-yes">59x</span>
469
+ <span class="cline-any cline-neutral">&nbsp;</span>
470
+ <span class="cline-any cline-yes">59x</span>
471
+ <span class="cline-any cline-neutral">&nbsp;</span>
472
+ <span class="cline-any cline-neutral">&nbsp;</span>
473
+ <span class="cline-any cline-neutral">&nbsp;</span>
474
+ <span class="cline-any cline-neutral">&nbsp;</span>
475
+ <span class="cline-any cline-neutral">&nbsp;</span>
476
+ <span class="cline-any cline-neutral">&nbsp;</span>
477
+ <span class="cline-any cline-neutral">&nbsp;</span>
478
+ <span class="cline-any cline-neutral">&nbsp;</span>
479
+ <span class="cline-any cline-neutral">&nbsp;</span>
480
+ <span class="cline-any cline-neutral">&nbsp;</span>
481
+ <span class="cline-any cline-yes">50x</span>
482
+ <span class="cline-any cline-neutral">&nbsp;</span>
483
+ <span class="cline-any cline-neutral">&nbsp;</span>
484
+ <span class="cline-any cline-neutral">&nbsp;</span>
485
+ <span class="cline-any cline-yes">78x</span>
486
+ <span class="cline-any cline-neutral">&nbsp;</span>
487
+ <span class="cline-any cline-neutral">&nbsp;</span>
488
+ <span class="cline-any cline-neutral">&nbsp;</span>
489
+ <span class="cline-any cline-neutral">&nbsp;</span>
490
+ <span class="cline-any cline-neutral">&nbsp;</span>
491
+ <span class="cline-any cline-neutral">&nbsp;</span>
492
+ <span class="cline-any cline-neutral">&nbsp;</span>
493
+ <span class="cline-any cline-neutral">&nbsp;</span>
494
+ <span class="cline-any cline-neutral">&nbsp;</span>
495
+ <span class="cline-any cline-neutral">&nbsp;</span>
496
+ <span class="cline-any cline-neutral">&nbsp;</span>
497
+ <span class="cline-any cline-neutral">&nbsp;</span>
498
+ <span class="cline-any cline-neutral">&nbsp;</span>
499
+ <span class="cline-any cline-neutral">&nbsp;</span>
500
+ <span class="cline-any cline-neutral">&nbsp;</span>
501
+ <span class="cline-any cline-neutral">&nbsp;</span>
502
+ <span class="cline-any cline-neutral">&nbsp;</span>
503
+ <span class="cline-any cline-neutral">&nbsp;</span>
504
+ <span class="cline-any cline-neutral">&nbsp;</span>
505
+ <span class="cline-any cline-neutral">&nbsp;</span>
506
+ <span class="cline-any cline-yes">78x</span>
507
+ <span class="cline-any cline-neutral">&nbsp;</span>
508
+ <span class="cline-any cline-yes">13x</span>
509
+ <span class="cline-any cline-neutral">&nbsp;</span>
510
+ <span class="cline-any cline-neutral">&nbsp;</span>
511
+ <span class="cline-any cline-yes">78x</span>
512
+ <span class="cline-any cline-yes">14x</span>
513
+ <span class="cline-any cline-neutral">&nbsp;</span>
514
+ <span class="cline-any cline-yes">78x</span>
515
+ <span class="cline-any cline-yes">13x</span>
516
+ <span class="cline-any cline-neutral">&nbsp;</span>
517
+ <span class="cline-any cline-neutral">&nbsp;</span>
518
+ <span class="cline-any cline-no">&nbsp;</span>
519
+ <span class="cline-any cline-neutral">&nbsp;</span>
520
+ <span class="cline-any cline-neutral">&nbsp;</span>
521
+ <span class="cline-any cline-neutral">&nbsp;</span>
522
+ <span class="cline-any cline-yes">1x</span>
523
+ <span class="cline-any cline-neutral">&nbsp;</span>
524
+ <span class="cline-any cline-yes">5x</span>
525
+ <span class="cline-any cline-yes">1x</span>
526
+ <span class="cline-any cline-neutral">&nbsp;</span>
527
+ <span class="cline-any cline-yes">1x</span>
528
+ <span class="cline-any cline-no">&nbsp;</span>
529
+ <span class="cline-any cline-neutral">&nbsp;</span>
530
+ <span class="cline-any cline-neutral">&nbsp;</span>
531
+ <span class="cline-any cline-yes">1x</span>
532
+ <span class="cline-any cline-neutral">&nbsp;</span>
533
+ <span class="cline-any cline-neutral">&nbsp;</span>
534
+ <span class="cline-any cline-neutral">&nbsp;</span>
535
+ <span class="cline-any cline-yes">2x</span>
536
+ <span class="cline-any cline-neutral">&nbsp;</span>
537
+ <span class="cline-any cline-neutral">&nbsp;</span>
538
+ <span class="cline-any cline-neutral">&nbsp;</span>
539
+ <span class="cline-any cline-yes">4x</span>
540
+ <span class="cline-any cline-neutral">&nbsp;</span>
541
+ <span class="cline-any cline-neutral">&nbsp;</span>
542
+ <span class="cline-any cline-neutral">&nbsp;</span>
543
+ <span class="cline-any cline-yes">67x</span>
544
+ <span class="cline-any cline-yes">67x</span>
545
+ <span class="cline-any cline-neutral">&nbsp;</span>
546
+ <span class="cline-any cline-neutral">&nbsp;</span>
547
+ <span class="cline-any cline-neutral">&nbsp;</span>
548
+ <span class="cline-any cline-neutral">&nbsp;</span>
549
+ <span class="cline-any cline-neutral">&nbsp;</span>
550
+ <span class="cline-any cline-neutral">&nbsp;</span>
551
+ <span class="cline-any cline-neutral">&nbsp;</span>
552
+ <span class="cline-any cline-neutral">&nbsp;</span>
553
+ <span class="cline-any cline-neutral">&nbsp;</span>
554
+ <span class="cline-any cline-yes">78x</span>
555
+ <span class="cline-any cline-neutral">&nbsp;</span>
556
+ <span class="cline-any cline-yes">78x</span>
557
+ <span class="cline-any cline-yes">78x</span>
558
+ <span class="cline-any cline-yes">78x</span>
559
+ <span class="cline-any cline-yes">78x</span>
560
+ <span class="cline-any cline-neutral">&nbsp;</span>
561
+ <span class="cline-any cline-yes">78x</span>
562
+ <span class="cline-any cline-yes">26x</span>
563
+ <span class="cline-any cline-neutral">&nbsp;</span>
564
+ <span class="cline-any cline-yes">52x</span>
565
+ <span class="cline-any cline-yes">52x</span>
566
+ <span class="cline-any cline-yes">52x</span>
567
+ <span class="cline-any cline-yes">52x</span>
568
+ <span class="cline-any cline-neutral">&nbsp;</span>
569
+ <span class="cline-any cline-neutral">&nbsp;</span>
570
+ <span class="cline-any cline-neutral">&nbsp;</span>
571
+ <span class="cline-any cline-yes">156x</span>
572
+ <span class="cline-any cline-yes">6x</span>
573
+ <span class="cline-any cline-yes">58x</span>
574
+ <span class="cline-any cline-neutral">&nbsp;</span>
575
+ <span class="cline-any cline-neutral">&nbsp;</span>
576
+ <span class="cline-any cline-yes">52x</span>
577
+ <span class="cline-any cline-neutral">&nbsp;</span>
578
+ <span class="cline-any cline-yes">52x</span>
579
+ <span class="cline-any cline-yes">52x</span>
580
+ <span class="cline-any cline-neutral">&nbsp;</span>
581
+ <span class="cline-any cline-yes">52x</span>
582
+ <span class="cline-any cline-yes">52x</span>
583
+ <span class="cline-any cline-yes">52x</span>
584
+ <span class="cline-any cline-yes">52x</span>
585
+ <span class="cline-any cline-yes">52x</span>
586
+ <span class="cline-any cline-yes">52x</span>
587
+ <span class="cline-any cline-yes">59x</span>
588
+ <span class="cline-any cline-neutral">&nbsp;</span>
589
+ <span class="cline-any cline-yes">52x</span>
590
+ <span class="cline-any cline-neutral">&nbsp;</span>
591
+ <span class="cline-any cline-neutral">&nbsp;</span>
592
+ <span class="cline-any cline-yes">62x</span>
593
+ <span class="cline-any cline-yes">52x</span>
594
+ <span class="cline-any cline-yes">3x</span>
595
+ <span class="cline-any cline-yes">3x</span>
596
+ <span class="cline-any cline-yes">3x</span>
597
+ <span class="cline-any cline-yes">3x</span>
598
+ <span class="cline-any cline-neutral">&nbsp;</span>
599
+ <span class="cline-any cline-neutral">&nbsp;</span>
600
+ <span class="cline-any cline-neutral">&nbsp;</span>
601
+ <span class="cline-any cline-no">&nbsp;</span>
602
+ <span class="cline-any cline-no">&nbsp;</span>
603
+ <span class="cline-any cline-neutral">&nbsp;</span>
604
+ <span class="cline-any cline-neutral">&nbsp;</span>
605
+ <span class="cline-any cline-neutral">&nbsp;</span>
606
+ <span class="cline-any cline-neutral">&nbsp;</span>
607
+ <span class="cline-any cline-neutral">&nbsp;</span>
608
+ <span class="cline-any cline-yes">78x</span>
609
+ <span class="cline-any cline-yes">4x</span>
610
+ <span class="cline-any cline-yes">4x</span>
611
+ <span class="cline-any cline-neutral">&nbsp;</span>
612
+ <span class="cline-any cline-neutral">&nbsp;</span>
613
+ <span class="cline-any cline-neutral">&nbsp;</span>
614
+ <span class="cline-any cline-yes">78x</span>
615
+ <span class="cline-any cline-yes">78x</span>
616
+ <span class="cline-any cline-yes">3x</span>
617
+ <span class="cline-any cline-neutral">&nbsp;</span>
618
+ <span class="cline-any cline-neutral">&nbsp;</span>
619
+ <span class="cline-any cline-yes">78x</span>
620
+ <span class="cline-any cline-neutral">&nbsp;</span>
621
+ <span class="cline-any cline-neutral">&nbsp;</span>
622
+ <span class="cline-any cline-neutral">&nbsp;</span>
623
+ <span class="cline-any cline-yes">59x</span>
624
+ <span class="cline-any cline-yes">2x</span>
625
+ <span class="cline-any cline-neutral">&nbsp;</span>
626
+ <span class="cline-any cline-yes">57x</span>
627
+ <span class="cline-any cline-neutral">&nbsp;</span>
628
+ <span class="cline-any cline-neutral">&nbsp;</span>
629
+ <span class="cline-any cline-neutral">&nbsp;</span>
630
+ <span class="cline-any cline-yes">62x</span>
631
+ <span class="cline-any cline-yes">62x</span>
632
+ <span class="cline-any cline-neutral">&nbsp;</span>
633
+ <span class="cline-any cline-neutral">&nbsp;</span>
634
+ <span class="cline-any cline-yes">62x</span>
635
+ <span class="cline-any cline-neutral">&nbsp;</span>
636
+ <span class="cline-any cline-neutral">&nbsp;</span>
637
+ <span class="cline-any cline-neutral">&nbsp;</span>
638
+ <span class="cline-any cline-neutral">&nbsp;</span>
639
+ <span class="cline-any cline-yes">8x</span>
640
+ <span class="cline-any cline-yes">8x</span>
641
+ <span class="cline-any cline-yes">9x</span>
642
+ <span class="cline-any cline-neutral">&nbsp;</span>
643
+ <span class="cline-any cline-neutral">&nbsp;</span>
644
+ <span class="cline-any cline-yes">9x</span>
645
+ <span class="cline-any cline-yes">9x</span>
646
+ <span class="cline-any cline-yes">9x</span>
647
+ <span class="cline-any cline-yes">9x</span>
648
+ <span class="cline-any cline-yes">9x</span>
649
+ <span class="cline-any cline-yes">1x</span>
650
+ <span class="cline-any cline-yes">1x</span>
651
+ <span class="cline-any cline-neutral">&nbsp;</span>
652
+ <span class="cline-any cline-neutral">&nbsp;</span>
653
+ <span class="cline-any cline-yes">8x</span>
654
+ <span class="cline-any cline-yes">8x</span>
655
+ <span class="cline-any cline-neutral">&nbsp;</span>
656
+ <span class="cline-any cline-neutral">&nbsp;</span>
657
+ <span class="cline-any cline-neutral">&nbsp;</span>
658
+ <span class="cline-any cline-yes">52x</span>
659
+ <span class="cline-any cline-yes">52x</span>
660
+ <span class="cline-any cline-yes">62x</span>
661
+ <span class="cline-any cline-yes">59x</span>
662
+ <span class="cline-any cline-yes">59x</span>
663
+ <span class="cline-any cline-yes">59x</span>
664
+ <span class="cline-any cline-neutral">&nbsp;</span>
665
+ <span class="cline-any cline-neutral">&nbsp;</span>
666
+ <span class="cline-any cline-yes">52x</span>
667
+ <span class="cline-any cline-neutral">&nbsp;</span>
668
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { SEVERITY_ORDER, filterFindings } from '../types/index.js';
669
+ import type { SkillReport, Finding, Severity, SeverityThreshold } from '../types/index.js';
670
+ import type { RenderResult, RenderOptions, GitHubReview, GitHubComment } from './types.js';
671
+ import { capitalize, formatStatsCompact, countBySeverity, pluralize } from '../cli/output/formatters.js';
672
+ import { generateContentHash, generateMarker } from './dedup.js';
673
+ import { escapeHtml } from '../utils/index.js';
674
+ &nbsp;
675
+ export function renderSkillReport(report: SkillReport, options: RenderOptions = {}): RenderResult {
676
+ const { includeSuggestions = true, maxFindings, groupByFile = true, reportOn, minConfidence, failOn, requestChanges, checkRunUrl, totalFindings, allFindings } = options;
677
+ &nbsp;
678
+ // Filter by reportOn threshold and confidence, then apply maxFindings limit
679
+ const filteredFindings = filterFindings(report.findings, reportOn, minConfidence);
680
+ const findings = maxFindings ? filteredFindings.slice(0, maxFindings) : filteredFindings;
681
+ const sortedFindings = [...findings].sort(
682
+ (a, b) =&gt; SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]
683
+ );
684
+ &nbsp;
685
+ // Calculate how many findings were filtered out
686
+ const total = totalFindings ?? report.findings.length;
687
+ const hiddenCount = total - sortedFindings.length;
688
+ &nbsp;
689
+ // Use allFindings for failOn evaluation if provided (e.g., when report.findings was modified for dedup)
690
+ // Apply confidence filtering to failOn evaluation too
691
+ const findingsForFailOn = filterFindings(allFindings ?? report.findings, undefined, minConfidence);
692
+ const review = renderReview(sortedFindings, report, includeSuggestions, failOn, findingsForFailOn, requestChanges);
693
+ const summaryComment = renderSummaryComment(report, sortedFindings, groupByFile, checkRunUrl, hiddenCount);
694
+ &nbsp;
695
+ return { review, summaryComment };
696
+ }
697
+ &nbsp;
698
+ function renderReview(
699
+ findings: Finding[],
700
+ report: SkillReport,
701
+ includeSuggestions: boolean,
702
+ failOn?: SeverityThreshold,
703
+ allFindings?: Finding[],
704
+ requestChanges?: boolean,
705
+ ): GitHubReview | undefined {
706
+ const findingsWithLocation = findings.filter((f) =&gt; f.location);
707
+ const findingsWithoutLocation = findings.filter((f) =&gt; !f.location);
708
+ &nbsp;
709
+ // Determine review event type based on failOn threshold against ALL findings.
710
+ // Use allFindings (or report.findings) so failOn operates independently of reportOn and deduplication.
711
+ const event = determineReviewEvent(allFindings ?? <span class="branch-1 cbranch-no" title="branch not covered" >report.findings, f</span>ailOn, requestChanges);
712
+ &nbsp;
713
+ // No inline comments to post. Create a review only for REQUEST_CHANGES or locationless findings.
714
+ if (findingsWithLocation.length === 0) {
715
+ if (findingsWithoutLocation.length &gt; 0) {
716
+ return {
717
+ event,
718
+ body: renderFindingsBody(findingsWithoutLocation, report.skill),
719
+ comments: [],
720
+ };
721
+ }
722
+ // Generic fallback for REQUEST_CHANGES when failOn triggers on findings below reportOn threshold
723
+ if (event === 'REQUEST_CHANGES') {
724
+ return {
725
+ event,
726
+ body: 'Findings exceed the configured threshold. See the GitHub Check for details.',
727
+ comments: [],
728
+ };
729
+ }
730
+ return undefined;
731
+ }
732
+ &nbsp;
733
+ const comments: GitHubComment[] = findingsWithLocation.map((finding) =&gt; {
734
+ const location = finding.location;
735
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (!location) {
736
+ <span class="cstat-no" title="statement not covered" > throw new Error('Unexpected: finding without location in filtered list');</span>
737
+ }
738
+ let body = `**${escapeHtml(finding.title)}**\n\n${escapeHtml(finding.description)}`;
739
+ &nbsp;
740
+ if (finding.verification) {
741
+ body += `\n\n${renderVerification(finding.verification)}`;
742
+ }
743
+ &nbsp;
744
+ if (includeSuggestions &amp;&amp; finding.suggestedFix) {
745
+ body += `\n\n${renderSuggestion(finding.suggestedFix.description, finding.suggestedFix.diff)}`;
746
+ }
747
+ &nbsp;
748
+ // Additional locations section
749
+ if (finding.additionalLocations?.length) {
750
+ body += '\n\n&lt;details&gt;&lt;summary&gt;Also found at ' +
751
+ `${finding.additionalLocations.length} additional ` +
752
+ pluralize(finding.additionalLocations.length, 'location') +
753
+ '&lt;/summary&gt;\n\n';
754
+ for (const loc of finding.additionalLocations) {
755
+ const range = loc.endLine ? `${loc.startLine}-${loc.endLine}` : `${loc.startLine}`;
756
+ body += `- \`${loc.path}:${range}\`\n`;
757
+ }
758
+ body += '\n&lt;/details&gt;';
759
+ }
760
+ &nbsp;
761
+ // Add attribution footer with skill name and finding ID
762
+ body += `\n\n${renderAttributionFooter(report.skill, finding.id)}`;
763
+ &nbsp;
764
+ // Add deduplication marker
765
+ const contentHash = generateContentHash(finding.title, finding.description);
766
+ const line = location.endLine ?? location.startLine;
767
+ body += `\n${generateMarker(location.path, line, contentHash)}`;
768
+ &nbsp;
769
+ const isMultiLine = location.endLine &amp;&amp; location.startLine !== location.endLine;
770
+ &nbsp;
771
+ return {
772
+ body,
773
+ path: location.path,
774
+ line: location.endLine ?? location.startLine,
775
+ side: 'RIGHT' as const,
776
+ start_line: isMultiLine ? location.startLine : undefined,
777
+ start_side: isMultiLine ? ('RIGHT' as const) : undefined,
778
+ };
779
+ });
780
+ &nbsp;
781
+ // Include locationless findings in the review body when mixed with inline comments
782
+ const body = findingsWithoutLocation.length &gt; 0
783
+ ? renderFindingsBody(findingsWithoutLocation, report.skill)
784
+ : '';
785
+ &nbsp;
786
+ return {
787
+ event,
788
+ body,
789
+ comments,
790
+ };
791
+ }
792
+ &nbsp;
793
+ /**
794
+ * Determine the PR review event type based on failOn threshold.
795
+ * Returns:
796
+ * - REQUEST_CHANGES if failOn is set and findings meet/exceed the threshold
797
+ * - COMMENT otherwise
798
+ *
799
+ * Clearing a previous REQUEST_CHANGES is handled by dismissing the review
800
+ * in the PR workflow, not by posting an APPROVE.
801
+ */
802
+ function determineReviewEvent(
803
+ findings: Finding[],
804
+ failOn?: SeverityThreshold,
805
+ requestChanges?: boolean,
806
+ ): GitHubReview['event'] {
807
+ if (!requestChanges) return 'COMMENT';
808
+ &nbsp;
809
+ const hasActiveThreshold = failOn &amp;&amp; failOn !== 'off';
810
+ &nbsp;
811
+ const hasBlockingFinding =
812
+ hasActiveThreshold &amp;&amp;
813
+ findings.some((f) =&gt; SEVERITY_ORDER[f.severity] &lt;= SEVERITY_ORDER[failOn]);
814
+ &nbsp;
815
+ if (hasBlockingFinding) {
816
+ return 'REQUEST_CHANGES';
817
+ }
818
+ &nbsp;
819
+ <span class="cstat-no" title="statement not covered" > return 'COMMENT';</span>
820
+ }
821
+ &nbsp;
822
+ function renderSuggestion(description: string, diff: string): string {
823
+ const suggestionLines = diff
824
+ .split('\n')
825
+ .filter((line) =&gt; line.startsWith('+') &amp;&amp; !line.startsWith('+++'))
826
+ .map((line) =&gt; line.slice(1));
827
+ &nbsp;
828
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (suggestionLines.length === 0) {
829
+ <span class="cstat-no" title="statement not covered" > return `**Suggested fix:** ${escapeHtml(description)}`;</span>
830
+ }
831
+ &nbsp;
832
+ return `**Suggested fix:** ${escapeHtml(description)}\n\n\`\`\`suggestion\n${suggestionLines.join('\n')}\n\`\`\``;
833
+ }
834
+ &nbsp;
835
+ function renderVerification(verification: string): string {
836
+ return `&lt;details&gt;&lt;summary&gt;Verification&lt;/summary&gt;\n\n${escapeHtml(verification)}\n\n&lt;/details&gt;`;
837
+ }
838
+ &nbsp;
839
+ function renderHiddenFindingsLink(hiddenCount: number, checkRunUrl: string): string {
840
+ return `[View ${hiddenCount} additional ${pluralize(hiddenCount, 'finding')} in Checks](${checkRunUrl})`;
841
+ }
842
+ &nbsp;
843
+ function renderAttributionFooter(skill: string, findingId?: string): string {
844
+ const idSuffix = findingId ? ` · ${escapeHtml(findingId)}` : '';
845
+ return `&lt;sub&gt;Identified by Warden ${escapeHtml(skill)}${idSuffix}&lt;/sub&gt;`;
846
+ }
847
+ &nbsp;
848
+ function renderSummaryComment(
849
+ report: SkillReport,
850
+ findings: Finding[],
851
+ groupByFile: boolean,
852
+ checkRunUrl?: string,
853
+ hiddenCount?: number
854
+ ): string {
855
+ const lines: string[] = [];
856
+ &nbsp;
857
+ lines.push(`## ${report.skill}`);
858
+ lines.push('');
859
+ lines.push(escapeHtml(report.summary));
860
+ lines.push('');
861
+ &nbsp;
862
+ if (findings.length === 0) {
863
+ lines.push('No findings to report.');
864
+ } else {
865
+ const counts = countBySeverity(findings);
866
+ lines.push('### Summary');
867
+ lines.push('');
868
+ lines.push(
869
+ `| Severity | Count |
870
+ |----------|-------|
871
+ ${Object.entries(counts)
872
+ .filter(([, count]) =&gt; count &gt; 0)
873
+ .sort(([a], [b]) =&gt; SEVERITY_ORDER[a as Severity] - SEVERITY_ORDER[b as Severity])
874
+ .map(([severity, count]) =&gt; `| ${capitalize(severity)} | ${count} |`)
875
+ .join('\n')}`
876
+ );
877
+ lines.push('');
878
+ &nbsp;
879
+ lines.push('### Findings');
880
+ lines.push('');
881
+ &nbsp;
882
+ if (groupByFile) {
883
+ const byFile = groupFindingsByFile(findings);
884
+ for (const [file, fileFindings] of Object.entries(byFile)) {
885
+ lines.push(`#### \`${file}\``);
886
+ lines.push('');
887
+ for (const finding of fileFindings) {
888
+ lines.push(renderFindingItem(finding));
889
+ }
890
+ lines.push('');
891
+ }
892
+ &nbsp;
893
+ const noLocation = findings.filter((f) =&gt; !f.location);
894
+ if (noLocation.length &gt; 0) {
895
+ lines.push('#### General');
896
+ lines.push('');
897
+ for (const finding of noLocation) {
898
+ lines.push(renderFindingItem(finding));
899
+ }
900
+ }
901
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
902
+ <span class="cstat-no" title="statement not covered" > for (const finding of findings) {</span>
903
+ <span class="cstat-no" title="statement not covered" > lines.push(renderFindingItem(finding));</span>
904
+ }
905
+ }
906
+ }
907
+ &nbsp;
908
+ // Add link to full report if there are hidden findings
909
+ if (hiddenCount &amp;&amp; hiddenCount &gt; 0 &amp;&amp; checkRunUrl) {
910
+ lines.push('');
911
+ lines.push(renderHiddenFindingsLink(hiddenCount, checkRunUrl));
912
+ }
913
+ &nbsp;
914
+ // Add stats footer
915
+ const statsLine = formatStatsCompact(report.durationMs, report.usage, report.auxiliaryUsage);
916
+ if (statsLine) {
917
+ lines.push('', '---', `&lt;sub&gt;${statsLine}&lt;/sub&gt;`);
918
+ }
919
+ &nbsp;
920
+ return lines.join('\n');
921
+ }
922
+ &nbsp;
923
+ function formatLineRange(loc: { startLine: number; endLine?: number }): string {
924
+ if (loc.endLine &amp;&amp; loc.endLine !== loc.startLine) {
925
+ return `L${loc.startLine}-${loc.endLine}`;
926
+ }
927
+ return `L${loc.startLine}`;
928
+ }
929
+ &nbsp;
930
+ function renderFindingItem(finding: Finding): string {
931
+ const location = finding.location ? ` (${formatLineRange(finding.location)})` : '';
932
+ const extra = finding.additionalLocations?.length
933
+ ? ` (+${finding.additionalLocations.length} more ${pluralize(finding.additionalLocations.length, 'location')})`
934
+ : '';
935
+ return `- \`${finding.id}\` **${escapeHtml(finding.title)}**${location}${extra} · ${finding.severity}: ${escapeHtml(finding.description)}`;
936
+ }
937
+ &nbsp;
938
+ /** Render findings as markdown for inclusion in a review body. */
939
+ export function renderFindingsBody(findings: Finding[], skill: string): string {
940
+ const lines: string[] = [];
941
+ for (const finding of findings) {
942
+ const location = finding.location
943
+ ? ` (\`${finding.location.path}:${finding.location.startLine}\`)`
944
+ : '';
945
+ lines.push(`**${escapeHtml(finding.title)}**${location}`);
946
+ lines.push('');
947
+ lines.push(escapeHtml(finding.description));
948
+ lines.push('');
949
+ if (finding.verification) {
950
+ lines.push(renderVerification(finding.verification));
951
+ lines.push('');
952
+ }
953
+ }
954
+ lines.push(renderAttributionFooter(skill));
955
+ return lines.join('\n');
956
+ }
957
+ &nbsp;
958
+ function groupFindingsByFile(findings: Finding[]): Record&lt;string, Finding[]&gt; {
959
+ const groups: Record&lt;string, Finding[]&gt; = {};
960
+ for (const finding of findings) {
961
+ if (finding.location) {
962
+ const path = finding.location.path;
963
+ groups[path] ??= [];
964
+ groups[path].push(finding);
965
+ }
966
+ }
967
+ return groups;
968
+ }
969
+ &nbsp;</pre></td></tr></table></pre>
970
+
971
+ <div class='push'></div><!-- for sticky footer -->
972
+ </div><!-- /wrapper -->
973
+ <div class='footer quiet pad2 space-top1 center small'>
974
+ Code coverage generated by
975
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
976
+ at 2026-05-17T04:35:52.381Z
977
+ </div>
978
+ <script src="../../prettify.js"></script>
979
+ <script>
980
+ window.onload = function () {
981
+ prettyPrint();
982
+ };
983
+ </script>
984
+ <script src="../../sorter.js"></script>
985
+ <script src="../../block-navigation.js"></script>
986
+ </body>
987
+ </html>
988
+