takos-actions-engine 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/coverage/base.css +224 -0
  2. package/coverage/block-navigation.js +87 -0
  3. package/coverage/clover.xml +3477 -0
  4. package/coverage/coverage-final.json +20 -0
  5. package/coverage/favicon.png +0 -0
  6. package/coverage/index.html +176 -0
  7. package/coverage/prettify.css +1 -0
  8. package/coverage/prettify.js +2 -0
  9. package/coverage/sort-arrow-sprite.png +0 -0
  10. package/coverage/sorter.js +210 -0
  11. package/coverage/src/context/base.ts.html +1792 -0
  12. package/coverage/src/context/env.ts.html +1243 -0
  13. package/coverage/src/context/index.html +161 -0
  14. package/coverage/src/context/index.ts.html +229 -0
  15. package/coverage/src/context/secrets.ts.html +1276 -0
  16. package/coverage/src/index.html +131 -0
  17. package/coverage/src/index.ts.html +502 -0
  18. package/coverage/src/parser/expression.ts.html +2854 -0
  19. package/coverage/src/parser/index.html +161 -0
  20. package/coverage/src/parser/index.ts.html +163 -0
  21. package/coverage/src/parser/validator.ts.html +1588 -0
  22. package/coverage/src/parser/workflow.ts.html +616 -0
  23. package/coverage/src/scheduler/dependency.ts.html +1138 -0
  24. package/coverage/src/scheduler/index.html +221 -0
  25. package/coverage/src/scheduler/index.ts.html +214 -0
  26. package/coverage/src/scheduler/job-context.ts.html +265 -0
  27. package/coverage/src/scheduler/job-policy.ts.html +559 -0
  28. package/coverage/src/scheduler/job.ts.html +1816 -0
  29. package/coverage/src/scheduler/listener-registry.ts.html +199 -0
  30. package/coverage/src/scheduler/step.ts.html +2206 -0
  31. package/coverage/src/scheduler/steps-context.ts.html +217 -0
  32. package/coverage/src/types.ts.html +1897 -0
  33. package/coverage/src/utils/index.html +116 -0
  34. package/coverage/src/utils/needs.ts.html +127 -0
  35. package/dist/__tests__/context/env.test.d.ts +2 -0
  36. package/dist/__tests__/context/env.test.d.ts.map +1 -0
  37. package/dist/__tests__/context/env.test.js +28 -0
  38. package/dist/__tests__/context/env.test.js.map +1 -0
  39. package/dist/__tests__/index.test.d.ts +2 -0
  40. package/dist/__tests__/index.test.d.ts.map +1 -0
  41. package/dist/__tests__/index.test.js +50 -0
  42. package/dist/__tests__/index.test.js.map +1 -0
  43. package/dist/__tests__/parser/expression.test.d.ts +2 -0
  44. package/dist/__tests__/parser/expression.test.d.ts.map +1 -0
  45. package/dist/__tests__/parser/expression.test.js +116 -0
  46. package/dist/__tests__/parser/expression.test.js.map +1 -0
  47. package/dist/__tests__/parser/workflow.test.d.ts +2 -0
  48. package/dist/__tests__/parser/workflow.test.d.ts.map +1 -0
  49. package/dist/__tests__/parser/workflow.test.js +134 -0
  50. package/dist/__tests__/parser/workflow.test.js.map +1 -0
  51. package/dist/__tests__/scheduler/dependency.test.d.ts +2 -0
  52. package/dist/__tests__/scheduler/dependency.test.d.ts.map +1 -0
  53. package/dist/__tests__/scheduler/dependency.test.js +41 -0
  54. package/dist/__tests__/scheduler/dependency.test.js.map +1 -0
  55. package/dist/__tests__/scheduler/job-context.test.d.ts +2 -0
  56. package/dist/__tests__/scheduler/job-context.test.d.ts.map +1 -0
  57. package/dist/__tests__/scheduler/job-context.test.js +108 -0
  58. package/dist/__tests__/scheduler/job-context.test.js.map +1 -0
  59. package/dist/__tests__/scheduler/job-policy.test.d.ts +2 -0
  60. package/dist/__tests__/scheduler/job-policy.test.d.ts.map +1 -0
  61. package/dist/__tests__/scheduler/job-policy.test.js +159 -0
  62. package/dist/__tests__/scheduler/job-policy.test.js.map +1 -0
  63. package/dist/__tests__/scheduler/job.test.d.ts +2 -0
  64. package/dist/__tests__/scheduler/job.test.d.ts.map +1 -0
  65. package/dist/__tests__/scheduler/job.test.js +826 -0
  66. package/dist/__tests__/scheduler/job.test.js.map +1 -0
  67. package/dist/__tests__/scheduler/listener-registry.test.d.ts +2 -0
  68. package/dist/__tests__/scheduler/listener-registry.test.d.ts.map +1 -0
  69. package/dist/__tests__/scheduler/listener-registry.test.js +79 -0
  70. package/dist/__tests__/scheduler/listener-registry.test.js.map +1 -0
  71. package/dist/__tests__/scheduler/step.test.d.ts +2 -0
  72. package/dist/__tests__/scheduler/step.test.d.ts.map +1 -0
  73. package/dist/__tests__/scheduler/step.test.js +209 -0
  74. package/dist/__tests__/scheduler/step.test.js.map +1 -0
  75. package/dist/__tests__/scheduler/steps-context.test.d.ts +2 -0
  76. package/dist/__tests__/scheduler/steps-context.test.d.ts.map +1 -0
  77. package/dist/__tests__/scheduler/steps-context.test.js +43 -0
  78. package/dist/__tests__/scheduler/steps-context.test.js.map +1 -0
  79. package/dist/constants.d.ts +47 -0
  80. package/dist/constants.d.ts.map +1 -0
  81. package/dist/constants.js +53 -0
  82. package/dist/constants.js.map +1 -0
  83. package/dist/context.d.ts +37 -0
  84. package/dist/context.d.ts.map +1 -0
  85. package/dist/context.js +105 -0
  86. package/dist/context.js.map +1 -0
  87. package/dist/index.d.ts +9 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +10 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/parser/evaluator-builtins.d.ts +14 -0
  92. package/dist/parser/evaluator-builtins.d.ts.map +1 -0
  93. package/dist/parser/evaluator-builtins.js +258 -0
  94. package/dist/parser/evaluator-builtins.js.map +1 -0
  95. package/dist/parser/evaluator.d.ts +38 -0
  96. package/dist/parser/evaluator.d.ts.map +1 -0
  97. package/dist/parser/evaluator.js +257 -0
  98. package/dist/parser/evaluator.js.map +1 -0
  99. package/dist/parser/expression.d.ts +20 -0
  100. package/dist/parser/expression.d.ts.map +1 -0
  101. package/dist/parser/expression.js +128 -0
  102. package/dist/parser/expression.js.map +1 -0
  103. package/dist/parser/tokenizer.d.ts +26 -0
  104. package/dist/parser/tokenizer.d.ts.map +1 -0
  105. package/dist/parser/tokenizer.js +162 -0
  106. package/dist/parser/tokenizer.js.map +1 -0
  107. package/dist/parser/validator.d.ts +13 -0
  108. package/dist/parser/validator.d.ts.map +1 -0
  109. package/dist/parser/validator.js +383 -0
  110. package/dist/parser/validator.js.map +1 -0
  111. package/dist/parser/workflow.d.ts +30 -0
  112. package/dist/parser/workflow.d.ts.map +1 -0
  113. package/dist/parser/workflow.js +152 -0
  114. package/dist/parser/workflow.js.map +1 -0
  115. package/dist/scheduler/dependency.d.ts +37 -0
  116. package/dist/scheduler/dependency.d.ts.map +1 -0
  117. package/dist/scheduler/dependency.js +133 -0
  118. package/dist/scheduler/dependency.js.map +1 -0
  119. package/dist/scheduler/job-policy.d.ts +23 -0
  120. package/dist/scheduler/job-policy.d.ts.map +1 -0
  121. package/dist/scheduler/job-policy.js +117 -0
  122. package/dist/scheduler/job-policy.js.map +1 -0
  123. package/dist/scheduler/job.d.ts +151 -0
  124. package/dist/scheduler/job.d.ts.map +1 -0
  125. package/dist/scheduler/job.js +348 -0
  126. package/dist/scheduler/job.js.map +1 -0
  127. package/dist/scheduler/step-output-parser.d.ts +14 -0
  128. package/dist/scheduler/step-output-parser.d.ts.map +1 -0
  129. package/dist/scheduler/step-output-parser.js +70 -0
  130. package/dist/scheduler/step-output-parser.js.map +1 -0
  131. package/dist/scheduler/step.d.ts +74 -0
  132. package/dist/scheduler/step.d.ts.map +1 -0
  133. package/dist/scheduler/step.js +387 -0
  134. package/dist/scheduler/step.js.map +1 -0
  135. package/dist/types.d.ts +499 -0
  136. package/dist/types.d.ts.map +1 -0
  137. package/dist/types.js +5 -0
  138. package/dist/types.js.map +1 -0
  139. package/dist/workflow-models.d.ts +504 -0
  140. package/dist/workflow-models.d.ts.map +1 -0
  141. package/dist/workflow-models.js +5 -0
  142. package/dist/workflow-models.js.map +1 -0
  143. package/package.json +29 -0
  144. package/src/__tests__/context/env.test.ts +38 -0
  145. package/src/__tests__/index.test.ts +55 -0
  146. package/src/__tests__/parser/expression.test.ts +151 -0
  147. package/src/__tests__/parser/workflow.test.ts +151 -0
  148. package/src/__tests__/scheduler/dependency.test.ts +51 -0
  149. package/src/__tests__/scheduler/job-context.test.ts +119 -0
  150. package/src/__tests__/scheduler/job-policy.test.ts +195 -0
  151. package/src/__tests__/scheduler/job.test.ts +1014 -0
  152. package/src/__tests__/scheduler/listener-registry.test.ts +95 -0
  153. package/src/__tests__/scheduler/step.test.ts +258 -0
  154. package/src/__tests__/scheduler/steps-context.test.ts +49 -0
  155. package/src/constants.ts +61 -0
  156. package/src/context.ts +153 -0
  157. package/src/index.ts +64 -0
  158. package/src/parser/evaluator-builtins.ts +315 -0
  159. package/src/parser/evaluator.ts +333 -0
  160. package/src/parser/expression.ts +154 -0
  161. package/src/parser/tokenizer.ts +191 -0
  162. package/src/parser/validator.ts +444 -0
  163. package/src/parser/workflow.ts +176 -0
  164. package/src/scheduler/dependency.ts +180 -0
  165. package/src/scheduler/job-policy.ts +198 -0
  166. package/src/scheduler/job.ts +523 -0
  167. package/src/scheduler/step-output-parser.ts +94 -0
  168. package/src/scheduler/step.ts +543 -0
  169. package/src/workflow-models.ts +593 -0
  170. package/tsconfig.json +14 -0
  171. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,1816 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/scheduler/job.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/scheduler</a> job.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">90.08% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>318/353</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">89.87% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>71/79</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">89.28% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>25/28</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">90.08% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>318/353</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a>
388
+ <a name='L323'></a><a href='#L323'>323</a>
389
+ <a name='L324'></a><a href='#L324'>324</a>
390
+ <a name='L325'></a><a href='#L325'>325</a>
391
+ <a name='L326'></a><a href='#L326'>326</a>
392
+ <a name='L327'></a><a href='#L327'>327</a>
393
+ <a name='L328'></a><a href='#L328'>328</a>
394
+ <a name='L329'></a><a href='#L329'>329</a>
395
+ <a name='L330'></a><a href='#L330'>330</a>
396
+ <a name='L331'></a><a href='#L331'>331</a>
397
+ <a name='L332'></a><a href='#L332'>332</a>
398
+ <a name='L333'></a><a href='#L333'>333</a>
399
+ <a name='L334'></a><a href='#L334'>334</a>
400
+ <a name='L335'></a><a href='#L335'>335</a>
401
+ <a name='L336'></a><a href='#L336'>336</a>
402
+ <a name='L337'></a><a href='#L337'>337</a>
403
+ <a name='L338'></a><a href='#L338'>338</a>
404
+ <a name='L339'></a><a href='#L339'>339</a>
405
+ <a name='L340'></a><a href='#L340'>340</a>
406
+ <a name='L341'></a><a href='#L341'>341</a>
407
+ <a name='L342'></a><a href='#L342'>342</a>
408
+ <a name='L343'></a><a href='#L343'>343</a>
409
+ <a name='L344'></a><a href='#L344'>344</a>
410
+ <a name='L345'></a><a href='#L345'>345</a>
411
+ <a name='L346'></a><a href='#L346'>346</a>
412
+ <a name='L347'></a><a href='#L347'>347</a>
413
+ <a name='L348'></a><a href='#L348'>348</a>
414
+ <a name='L349'></a><a href='#L349'>349</a>
415
+ <a name='L350'></a><a href='#L350'>350</a>
416
+ <a name='L351'></a><a href='#L351'>351</a>
417
+ <a name='L352'></a><a href='#L352'>352</a>
418
+ <a name='L353'></a><a href='#L353'>353</a>
419
+ <a name='L354'></a><a href='#L354'>354</a>
420
+ <a name='L355'></a><a href='#L355'>355</a>
421
+ <a name='L356'></a><a href='#L356'>356</a>
422
+ <a name='L357'></a><a href='#L357'>357</a>
423
+ <a name='L358'></a><a href='#L358'>358</a>
424
+ <a name='L359'></a><a href='#L359'>359</a>
425
+ <a name='L360'></a><a href='#L360'>360</a>
426
+ <a name='L361'></a><a href='#L361'>361</a>
427
+ <a name='L362'></a><a href='#L362'>362</a>
428
+ <a name='L363'></a><a href='#L363'>363</a>
429
+ <a name='L364'></a><a href='#L364'>364</a>
430
+ <a name='L365'></a><a href='#L365'>365</a>
431
+ <a name='L366'></a><a href='#L366'>366</a>
432
+ <a name='L367'></a><a href='#L367'>367</a>
433
+ <a name='L368'></a><a href='#L368'>368</a>
434
+ <a name='L369'></a><a href='#L369'>369</a>
435
+ <a name='L370'></a><a href='#L370'>370</a>
436
+ <a name='L371'></a><a href='#L371'>371</a>
437
+ <a name='L372'></a><a href='#L372'>372</a>
438
+ <a name='L373'></a><a href='#L373'>373</a>
439
+ <a name='L374'></a><a href='#L374'>374</a>
440
+ <a name='L375'></a><a href='#L375'>375</a>
441
+ <a name='L376'></a><a href='#L376'>376</a>
442
+ <a name='L377'></a><a href='#L377'>377</a>
443
+ <a name='L378'></a><a href='#L378'>378</a>
444
+ <a name='L379'></a><a href='#L379'>379</a>
445
+ <a name='L380'></a><a href='#L380'>380</a>
446
+ <a name='L381'></a><a href='#L381'>381</a>
447
+ <a name='L382'></a><a href='#L382'>382</a>
448
+ <a name='L383'></a><a href='#L383'>383</a>
449
+ <a name='L384'></a><a href='#L384'>384</a>
450
+ <a name='L385'></a><a href='#L385'>385</a>
451
+ <a name='L386'></a><a href='#L386'>386</a>
452
+ <a name='L387'></a><a href='#L387'>387</a>
453
+ <a name='L388'></a><a href='#L388'>388</a>
454
+ <a name='L389'></a><a href='#L389'>389</a>
455
+ <a name='L390'></a><a href='#L390'>390</a>
456
+ <a name='L391'></a><a href='#L391'>391</a>
457
+ <a name='L392'></a><a href='#L392'>392</a>
458
+ <a name='L393'></a><a href='#L393'>393</a>
459
+ <a name='L394'></a><a href='#L394'>394</a>
460
+ <a name='L395'></a><a href='#L395'>395</a>
461
+ <a name='L396'></a><a href='#L396'>396</a>
462
+ <a name='L397'></a><a href='#L397'>397</a>
463
+ <a name='L398'></a><a href='#L398'>398</a>
464
+ <a name='L399'></a><a href='#L399'>399</a>
465
+ <a name='L400'></a><a href='#L400'>400</a>
466
+ <a name='L401'></a><a href='#L401'>401</a>
467
+ <a name='L402'></a><a href='#L402'>402</a>
468
+ <a name='L403'></a><a href='#L403'>403</a>
469
+ <a name='L404'></a><a href='#L404'>404</a>
470
+ <a name='L405'></a><a href='#L405'>405</a>
471
+ <a name='L406'></a><a href='#L406'>406</a>
472
+ <a name='L407'></a><a href='#L407'>407</a>
473
+ <a name='L408'></a><a href='#L408'>408</a>
474
+ <a name='L409'></a><a href='#L409'>409</a>
475
+ <a name='L410'></a><a href='#L410'>410</a>
476
+ <a name='L411'></a><a href='#L411'>411</a>
477
+ <a name='L412'></a><a href='#L412'>412</a>
478
+ <a name='L413'></a><a href='#L413'>413</a>
479
+ <a name='L414'></a><a href='#L414'>414</a>
480
+ <a name='L415'></a><a href='#L415'>415</a>
481
+ <a name='L416'></a><a href='#L416'>416</a>
482
+ <a name='L417'></a><a href='#L417'>417</a>
483
+ <a name='L418'></a><a href='#L418'>418</a>
484
+ <a name='L419'></a><a href='#L419'>419</a>
485
+ <a name='L420'></a><a href='#L420'>420</a>
486
+ <a name='L421'></a><a href='#L421'>421</a>
487
+ <a name='L422'></a><a href='#L422'>422</a>
488
+ <a name='L423'></a><a href='#L423'>423</a>
489
+ <a name='L424'></a><a href='#L424'>424</a>
490
+ <a name='L425'></a><a href='#L425'>425</a>
491
+ <a name='L426'></a><a href='#L426'>426</a>
492
+ <a name='L427'></a><a href='#L427'>427</a>
493
+ <a name='L428'></a><a href='#L428'>428</a>
494
+ <a name='L429'></a><a href='#L429'>429</a>
495
+ <a name='L430'></a><a href='#L430'>430</a>
496
+ <a name='L431'></a><a href='#L431'>431</a>
497
+ <a name='L432'></a><a href='#L432'>432</a>
498
+ <a name='L433'></a><a href='#L433'>433</a>
499
+ <a name='L434'></a><a href='#L434'>434</a>
500
+ <a name='L435'></a><a href='#L435'>435</a>
501
+ <a name='L436'></a><a href='#L436'>436</a>
502
+ <a name='L437'></a><a href='#L437'>437</a>
503
+ <a name='L438'></a><a href='#L438'>438</a>
504
+ <a name='L439'></a><a href='#L439'>439</a>
505
+ <a name='L440'></a><a href='#L440'>440</a>
506
+ <a name='L441'></a><a href='#L441'>441</a>
507
+ <a name='L442'></a><a href='#L442'>442</a>
508
+ <a name='L443'></a><a href='#L443'>443</a>
509
+ <a name='L444'></a><a href='#L444'>444</a>
510
+ <a name='L445'></a><a href='#L445'>445</a>
511
+ <a name='L446'></a><a href='#L446'>446</a>
512
+ <a name='L447'></a><a href='#L447'>447</a>
513
+ <a name='L448'></a><a href='#L448'>448</a>
514
+ <a name='L449'></a><a href='#L449'>449</a>
515
+ <a name='L450'></a><a href='#L450'>450</a>
516
+ <a name='L451'></a><a href='#L451'>451</a>
517
+ <a name='L452'></a><a href='#L452'>452</a>
518
+ <a name='L453'></a><a href='#L453'>453</a>
519
+ <a name='L454'></a><a href='#L454'>454</a>
520
+ <a name='L455'></a><a href='#L455'>455</a>
521
+ <a name='L456'></a><a href='#L456'>456</a>
522
+ <a name='L457'></a><a href='#L457'>457</a>
523
+ <a name='L458'></a><a href='#L458'>458</a>
524
+ <a name='L459'></a><a href='#L459'>459</a>
525
+ <a name='L460'></a><a href='#L460'>460</a>
526
+ <a name='L461'></a><a href='#L461'>461</a>
527
+ <a name='L462'></a><a href='#L462'>462</a>
528
+ <a name='L463'></a><a href='#L463'>463</a>
529
+ <a name='L464'></a><a href='#L464'>464</a>
530
+ <a name='L465'></a><a href='#L465'>465</a>
531
+ <a name='L466'></a><a href='#L466'>466</a>
532
+ <a name='L467'></a><a href='#L467'>467</a>
533
+ <a name='L468'></a><a href='#L468'>468</a>
534
+ <a name='L469'></a><a href='#L469'>469</a>
535
+ <a name='L470'></a><a href='#L470'>470</a>
536
+ <a name='L471'></a><a href='#L471'>471</a>
537
+ <a name='L472'></a><a href='#L472'>472</a>
538
+ <a name='L473'></a><a href='#L473'>473</a>
539
+ <a name='L474'></a><a href='#L474'>474</a>
540
+ <a name='L475'></a><a href='#L475'>475</a>
541
+ <a name='L476'></a><a href='#L476'>476</a>
542
+ <a name='L477'></a><a href='#L477'>477</a>
543
+ <a name='L478'></a><a href='#L478'>478</a>
544
+ <a name='L479'></a><a href='#L479'>479</a>
545
+ <a name='L480'></a><a href='#L480'>480</a>
546
+ <a name='L481'></a><a href='#L481'>481</a>
547
+ <a name='L482'></a><a href='#L482'>482</a>
548
+ <a name='L483'></a><a href='#L483'>483</a>
549
+ <a name='L484'></a><a href='#L484'>484</a>
550
+ <a name='L485'></a><a href='#L485'>485</a>
551
+ <a name='L486'></a><a href='#L486'>486</a>
552
+ <a name='L487'></a><a href='#L487'>487</a>
553
+ <a name='L488'></a><a href='#L488'>488</a>
554
+ <a name='L489'></a><a href='#L489'>489</a>
555
+ <a name='L490'></a><a href='#L490'>490</a>
556
+ <a name='L491'></a><a href='#L491'>491</a>
557
+ <a name='L492'></a><a href='#L492'>492</a>
558
+ <a name='L493'></a><a href='#L493'>493</a>
559
+ <a name='L494'></a><a href='#L494'>494</a>
560
+ <a name='L495'></a><a href='#L495'>495</a>
561
+ <a name='L496'></a><a href='#L496'>496</a>
562
+ <a name='L497'></a><a href='#L497'>497</a>
563
+ <a name='L498'></a><a href='#L498'>498</a>
564
+ <a name='L499'></a><a href='#L499'>499</a>
565
+ <a name='L500'></a><a href='#L500'>500</a>
566
+ <a name='L501'></a><a href='#L501'>501</a>
567
+ <a name='L502'></a><a href='#L502'>502</a>
568
+ <a name='L503'></a><a href='#L503'>503</a>
569
+ <a name='L504'></a><a href='#L504'>504</a>
570
+ <a name='L505'></a><a href='#L505'>505</a>
571
+ <a name='L506'></a><a href='#L506'>506</a>
572
+ <a name='L507'></a><a href='#L507'>507</a>
573
+ <a name='L508'></a><a href='#L508'>508</a>
574
+ <a name='L509'></a><a href='#L509'>509</a>
575
+ <a name='L510'></a><a href='#L510'>510</a>
576
+ <a name='L511'></a><a href='#L511'>511</a>
577
+ <a name='L512'></a><a href='#L512'>512</a>
578
+ <a name='L513'></a><a href='#L513'>513</a>
579
+ <a name='L514'></a><a href='#L514'>514</a>
580
+ <a name='L515'></a><a href='#L515'>515</a>
581
+ <a name='L516'></a><a href='#L516'>516</a>
582
+ <a name='L517'></a><a href='#L517'>517</a>
583
+ <a name='L518'></a><a href='#L518'>518</a>
584
+ <a name='L519'></a><a href='#L519'>519</a>
585
+ <a name='L520'></a><a href='#L520'>520</a>
586
+ <a name='L521'></a><a href='#L521'>521</a>
587
+ <a name='L522'></a><a href='#L522'>522</a>
588
+ <a name='L523'></a><a href='#L523'>523</a>
589
+ <a name='L524'></a><a href='#L524'>524</a>
590
+ <a name='L525'></a><a href='#L525'>525</a>
591
+ <a name='L526'></a><a href='#L526'>526</a>
592
+ <a name='L527'></a><a href='#L527'>527</a>
593
+ <a name='L528'></a><a href='#L528'>528</a>
594
+ <a name='L529'></a><a href='#L529'>529</a>
595
+ <a name='L530'></a><a href='#L530'>530</a>
596
+ <a name='L531'></a><a href='#L531'>531</a>
597
+ <a name='L532'></a><a href='#L532'>532</a>
598
+ <a name='L533'></a><a href='#L533'>533</a>
599
+ <a name='L534'></a><a href='#L534'>534</a>
600
+ <a name='L535'></a><a href='#L535'>535</a>
601
+ <a name='L536'></a><a href='#L536'>536</a>
602
+ <a name='L537'></a><a href='#L537'>537</a>
603
+ <a name='L538'></a><a href='#L538'>538</a>
604
+ <a name='L539'></a><a href='#L539'>539</a>
605
+ <a name='L540'></a><a href='#L540'>540</a>
606
+ <a name='L541'></a><a href='#L541'>541</a>
607
+ <a name='L542'></a><a href='#L542'>542</a>
608
+ <a name='L543'></a><a href='#L543'>543</a>
609
+ <a name='L544'></a><a href='#L544'>544</a>
610
+ <a name='L545'></a><a href='#L545'>545</a>
611
+ <a name='L546'></a><a href='#L546'>546</a>
612
+ <a name='L547'></a><a href='#L547'>547</a>
613
+ <a name='L548'></a><a href='#L548'>548</a>
614
+ <a name='L549'></a><a href='#L549'>549</a>
615
+ <a name='L550'></a><a href='#L550'>550</a>
616
+ <a name='L551'></a><a href='#L551'>551</a>
617
+ <a name='L552'></a><a href='#L552'>552</a>
618
+ <a name='L553'></a><a href='#L553'>553</a>
619
+ <a name='L554'></a><a href='#L554'>554</a>
620
+ <a name='L555'></a><a href='#L555'>555</a>
621
+ <a name='L556'></a><a href='#L556'>556</a>
622
+ <a name='L557'></a><a href='#L557'>557</a>
623
+ <a name='L558'></a><a href='#L558'>558</a>
624
+ <a name='L559'></a><a href='#L559'>559</a>
625
+ <a name='L560'></a><a href='#L560'>560</a>
626
+ <a name='L561'></a><a href='#L561'>561</a>
627
+ <a name='L562'></a><a href='#L562'>562</a>
628
+ <a name='L563'></a><a href='#L563'>563</a>
629
+ <a name='L564'></a><a href='#L564'>564</a>
630
+ <a name='L565'></a><a href='#L565'>565</a>
631
+ <a name='L566'></a><a href='#L566'>566</a>
632
+ <a name='L567'></a><a href='#L567'>567</a>
633
+ <a name='L568'></a><a href='#L568'>568</a>
634
+ <a name='L569'></a><a href='#L569'>569</a>
635
+ <a name='L570'></a><a href='#L570'>570</a>
636
+ <a name='L571'></a><a href='#L571'>571</a>
637
+ <a name='L572'></a><a href='#L572'>572</a>
638
+ <a name='L573'></a><a href='#L573'>573</a>
639
+ <a name='L574'></a><a href='#L574'>574</a>
640
+ <a name='L575'></a><a href='#L575'>575</a>
641
+ <a name='L576'></a><a href='#L576'>576</a>
642
+ <a name='L577'></a><a href='#L577'>577</a>
643
+ <a name='L578'></a><a href='#L578'>578</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
644
+ <span class="cline-any cline-neutral">&nbsp;</span>
645
+ <span class="cline-any cline-neutral">&nbsp;</span>
646
+ <span class="cline-any cline-neutral">&nbsp;</span>
647
+ <span class="cline-any cline-neutral">&nbsp;</span>
648
+ <span class="cline-any cline-neutral">&nbsp;</span>
649
+ <span class="cline-any cline-neutral">&nbsp;</span>
650
+ <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</span>
654
+ <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</span>
659
+ <span class="cline-any cline-neutral">&nbsp;</span>
660
+ <span class="cline-any cline-neutral">&nbsp;</span>
661
+ <span class="cline-any cline-neutral">&nbsp;</span>
662
+ <span class="cline-any cline-neutral">&nbsp;</span>
663
+ <span class="cline-any cline-neutral">&nbsp;</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-neutral">&nbsp;</span>
667
+ <span class="cline-any cline-neutral">&nbsp;</span>
668
+ <span class="cline-any cline-neutral">&nbsp;</span>
669
+ <span class="cline-any cline-neutral">&nbsp;</span>
670
+ <span class="cline-any cline-neutral">&nbsp;</span>
671
+ <span class="cline-any cline-neutral">&nbsp;</span>
672
+ <span class="cline-any cline-neutral">&nbsp;</span>
673
+ <span class="cline-any cline-neutral">&nbsp;</span>
674
+ <span class="cline-any cline-neutral">&nbsp;</span>
675
+ <span class="cline-any cline-neutral">&nbsp;</span>
676
+ <span class="cline-any cline-neutral">&nbsp;</span>
677
+ <span class="cline-any cline-neutral">&nbsp;</span>
678
+ <span class="cline-any cline-neutral">&nbsp;</span>
679
+ <span class="cline-any cline-neutral">&nbsp;</span>
680
+ <span class="cline-any cline-neutral">&nbsp;</span>
681
+ <span class="cline-any cline-neutral">&nbsp;</span>
682
+ <span class="cline-any cline-neutral">&nbsp;</span>
683
+ <span class="cline-any cline-neutral">&nbsp;</span>
684
+ <span class="cline-any cline-neutral">&nbsp;</span>
685
+ <span class="cline-any cline-neutral">&nbsp;</span>
686
+ <span class="cline-any cline-neutral">&nbsp;</span>
687
+ <span class="cline-any cline-neutral">&nbsp;</span>
688
+ <span class="cline-any cline-neutral">&nbsp;</span>
689
+ <span class="cline-any cline-neutral">&nbsp;</span>
690
+ <span class="cline-any cline-neutral">&nbsp;</span>
691
+ <span class="cline-any cline-neutral">&nbsp;</span>
692
+ <span class="cline-any cline-neutral">&nbsp;</span>
693
+ <span class="cline-any cline-neutral">&nbsp;</span>
694
+ <span class="cline-any cline-neutral">&nbsp;</span>
695
+ <span class="cline-any cline-neutral">&nbsp;</span>
696
+ <span class="cline-any cline-neutral">&nbsp;</span>
697
+ <span class="cline-any cline-neutral">&nbsp;</span>
698
+ <span class="cline-any cline-neutral">&nbsp;</span>
699
+ <span class="cline-any cline-neutral">&nbsp;</span>
700
+ <span class="cline-any cline-neutral">&nbsp;</span>
701
+ <span class="cline-any cline-neutral">&nbsp;</span>
702
+ <span class="cline-any cline-neutral">&nbsp;</span>
703
+ <span class="cline-any cline-neutral">&nbsp;</span>
704
+ <span class="cline-any cline-neutral">&nbsp;</span>
705
+ <span class="cline-any cline-neutral">&nbsp;</span>
706
+ <span class="cline-any cline-neutral">&nbsp;</span>
707
+ <span class="cline-any cline-neutral">&nbsp;</span>
708
+ <span class="cline-any cline-neutral">&nbsp;</span>
709
+ <span class="cline-any cline-neutral">&nbsp;</span>
710
+ <span class="cline-any cline-neutral">&nbsp;</span>
711
+ <span class="cline-any cline-neutral">&nbsp;</span>
712
+ <span class="cline-any cline-neutral">&nbsp;</span>
713
+ <span class="cline-any cline-neutral">&nbsp;</span>
714
+ <span class="cline-any cline-neutral">&nbsp;</span>
715
+ <span class="cline-any cline-neutral">&nbsp;</span>
716
+ <span class="cline-any cline-yes">1x</span>
717
+ <span class="cline-any cline-yes">20x</span>
718
+ <span class="cline-any cline-yes">20x</span>
719
+ <span class="cline-any cline-yes">20x</span>
720
+ <span class="cline-any cline-yes">20x</span>
721
+ <span class="cline-any cline-yes">20x</span>
722
+ <span class="cline-any cline-yes">20x</span>
723
+ <span class="cline-any cline-yes">20x</span>
724
+ <span class="cline-any cline-yes">20x</span>
725
+ <span class="cline-any cline-neutral">&nbsp;</span>
726
+ <span class="cline-any cline-yes">20x</span>
727
+ <span class="cline-any cline-yes">20x</span>
728
+ <span class="cline-any cline-yes">20x</span>
729
+ <span class="cline-any cline-yes">20x</span>
730
+ <span class="cline-any cline-yes">20x</span>
731
+ <span class="cline-any cline-yes">20x</span>
732
+ <span class="cline-any cline-yes">20x</span>
733
+ <span class="cline-any cline-yes">20x</span>
734
+ <span class="cline-any cline-yes">20x</span>
735
+ <span class="cline-any cline-yes">20x</span>
736
+ <span class="cline-any cline-yes">20x</span>
737
+ <span class="cline-any cline-yes">20x</span>
738
+ <span class="cline-any cline-yes">20x</span>
739
+ <span class="cline-any cline-yes">20x</span>
740
+ <span class="cline-any cline-yes">20x</span>
741
+ <span class="cline-any cline-neutral">&nbsp;</span>
742
+ <span class="cline-any cline-neutral">&nbsp;</span>
743
+ <span class="cline-any cline-neutral">&nbsp;</span>
744
+ <span class="cline-any cline-neutral">&nbsp;</span>
745
+ <span class="cline-any cline-yes">20x</span>
746
+ <span class="cline-any cline-yes">10x</span>
747
+ <span class="cline-any cline-yes">10x</span>
748
+ <span class="cline-any cline-neutral">&nbsp;</span>
749
+ <span class="cline-any cline-neutral">&nbsp;</span>
750
+ <span class="cline-any cline-neutral">&nbsp;</span>
751
+ <span class="cline-any cline-neutral">&nbsp;</span>
752
+ <span class="cline-any cline-yes">20x</span>
753
+ <span class="cline-any cline-yes">140x</span>
754
+ <span class="cline-any cline-yes">140x</span>
755
+ <span class="cline-any cline-neutral">&nbsp;</span>
756
+ <span class="cline-any cline-neutral">&nbsp;</span>
757
+ <span class="cline-any cline-neutral">&nbsp;</span>
758
+ <span class="cline-any cline-neutral">&nbsp;</span>
759
+ <span class="cline-any cline-yes">20x</span>
760
+ <span class="cline-any cline-yes">2x</span>
761
+ <span class="cline-any cline-yes">2x</span>
762
+ <span class="cline-any cline-neutral">&nbsp;</span>
763
+ <span class="cline-any cline-neutral">&nbsp;</span>
764
+ <span class="cline-any cline-neutral">&nbsp;</span>
765
+ <span class="cline-any cline-neutral">&nbsp;</span>
766
+ <span class="cline-any cline-neutral">&nbsp;</span>
767
+ <span class="cline-any cline-yes">20x</span>
768
+ <span class="cline-any cline-yes">19x</span>
769
+ <span class="cline-any cline-yes">19x</span>
770
+ <span class="cline-any cline-yes">19x</span>
771
+ <span class="cline-any cline-neutral">&nbsp;</span>
772
+ <span class="cline-any cline-neutral">&nbsp;</span>
773
+ <span class="cline-any cline-neutral">&nbsp;</span>
774
+ <span class="cline-any cline-neutral">&nbsp;</span>
775
+ <span class="cline-any cline-yes">20x</span>
776
+ <span class="cline-any cline-neutral">&nbsp;</span>
777
+ <span class="cline-any cline-yes">19x</span>
778
+ <span class="cline-any cline-yes">19x</span>
779
+ <span class="cline-any cline-no">&nbsp;</span>
780
+ <span class="cline-any cline-no">&nbsp;</span>
781
+ <span class="cline-any cline-no">&nbsp;</span>
782
+ <span class="cline-any cline-no">&nbsp;</span>
783
+ <span class="cline-any cline-no">&nbsp;</span>
784
+ <span class="cline-any cline-neutral">&nbsp;</span>
785
+ <span class="cline-any cline-yes">19x</span>
786
+ <span class="cline-any cline-yes">19x</span>
787
+ <span class="cline-any cline-neutral">&nbsp;</span>
788
+ <span class="cline-any cline-yes">19x</span>
789
+ <span class="cline-any cline-yes">19x</span>
790
+ <span class="cline-any cline-neutral">&nbsp;</span>
791
+ <span class="cline-any cline-neutral">&nbsp;</span>
792
+ <span class="cline-any cline-neutral">&nbsp;</span>
793
+ <span class="cline-any cline-neutral">&nbsp;</span>
794
+ <span class="cline-any cline-yes">20x</span>
795
+ <span class="cline-any cline-yes">19x</span>
796
+ <span class="cline-any cline-no">&nbsp;</span>
797
+ <span class="cline-any cline-no">&nbsp;</span>
798
+ <span class="cline-any cline-neutral">&nbsp;</span>
799
+ <span class="cline-any cline-yes">19x</span>
800
+ <span class="cline-any cline-yes">19x</span>
801
+ <span class="cline-any cline-neutral">&nbsp;</span>
802
+ <span class="cline-any cline-yes">19x</span>
803
+ <span class="cline-any cline-yes">19x</span>
804
+ <span class="cline-any cline-yes">19x</span>
805
+ <span class="cline-any cline-neutral">&nbsp;</span>
806
+ <span class="cline-any cline-yes">19x</span>
807
+ <span class="cline-any cline-yes">23x</span>
808
+ <span class="cline-any cline-neutral">&nbsp;</span>
809
+ <span class="cline-any cline-yes">23x</span>
810
+ <span class="cline-any cline-yes">23x</span>
811
+ <span class="cline-any cline-neutral">&nbsp;</span>
812
+ <span class="cline-any cline-neutral">&nbsp;</span>
813
+ <span class="cline-any cline-yes">23x</span>
814
+ <span class="cline-any cline-neutral">&nbsp;</span>
815
+ <span class="cline-any cline-yes">23x</span>
816
+ <span class="cline-any cline-neutral">&nbsp;</span>
817
+ <span class="cline-any cline-neutral">&nbsp;</span>
818
+ <span class="cline-any cline-yes">23x</span>
819
+ <span class="cline-any cline-yes">21x</span>
820
+ <span class="cline-any cline-yes">21x</span>
821
+ <span class="cline-any cline-yes">21x</span>
822
+ <span class="cline-any cline-yes">21x</span>
823
+ <span class="cline-any cline-yes">13x</span>
824
+ <span class="cline-any cline-yes">13x</span>
825
+ <span class="cline-any cline-neutral">&nbsp;</span>
826
+ <span class="cline-any cline-yes">8x</span>
827
+ <span class="cline-any cline-yes">19x</span>
828
+ <span class="cline-any cline-yes">3x</span>
829
+ <span class="cline-any cline-yes">3x</span>
830
+ <span class="cline-any cline-yes">8x</span>
831
+ <span class="cline-any cline-yes">8x</span>
832
+ <span class="cline-any cline-yes">23x</span>
833
+ <span class="cline-any cline-neutral">&nbsp;</span>
834
+ <span class="cline-any cline-yes">23x</span>
835
+ <span class="cline-any cline-yes">23x</span>
836
+ <span class="cline-any cline-yes">23x</span>
837
+ <span class="cline-any cline-yes">23x</span>
838
+ <span class="cline-any cline-yes">23x</span>
839
+ <span class="cline-any cline-yes">23x</span>
840
+ <span class="cline-any cline-yes">19x</span>
841
+ <span class="cline-any cline-yes">19x</span>
842
+ <span class="cline-any cline-yes">19x</span>
843
+ <span class="cline-any cline-yes">19x</span>
844
+ <span class="cline-any cline-neutral">&nbsp;</span>
845
+ <span class="cline-any cline-neutral">&nbsp;</span>
846
+ <span class="cline-any cline-neutral">&nbsp;</span>
847
+ <span class="cline-any cline-neutral">&nbsp;</span>
848
+ <span class="cline-any cline-yes">20x</span>
849
+ <span class="cline-any cline-yes">23x</span>
850
+ <span class="cline-any cline-yes">23x</span>
851
+ <span class="cline-any cline-yes">23x</span>
852
+ <span class="cline-any cline-yes">23x</span>
853
+ <span class="cline-any cline-yes">23x</span>
854
+ <span class="cline-any cline-neutral">&nbsp;</span>
855
+ <span class="cline-any cline-neutral">&nbsp;</span>
856
+ <span class="cline-any cline-yes">23x</span>
857
+ <span class="cline-any cline-yes">24x</span>
858
+ <span class="cline-any cline-yes">24x</span>
859
+ <span class="cline-any cline-neutral">&nbsp;</span>
860
+ <span class="cline-any cline-yes">23x</span>
861
+ <span class="cline-any cline-yes">23x</span>
862
+ <span class="cline-any cline-no">&nbsp;</span>
863
+ <span class="cline-any cline-no">&nbsp;</span>
864
+ <span class="cline-any cline-no">&nbsp;</span>
865
+ <span class="cline-any cline-neutral">&nbsp;</span>
866
+ <span class="cline-any cline-yes">23x</span>
867
+ <span class="cline-any cline-neutral">&nbsp;</span>
868
+ <span class="cline-any cline-yes">23x</span>
869
+ <span class="cline-any cline-neutral">&nbsp;</span>
870
+ <span class="cline-any cline-yes">23x</span>
871
+ <span class="cline-any cline-yes">7x</span>
872
+ <span class="cline-any cline-yes">7x</span>
873
+ <span class="cline-any cline-yes">7x</span>
874
+ <span class="cline-any cline-yes">23x</span>
875
+ <span class="cline-any cline-yes">23x</span>
876
+ <span class="cline-any cline-neutral">&nbsp;</span>
877
+ <span class="cline-any cline-neutral">&nbsp;</span>
878
+ <span class="cline-any cline-neutral">&nbsp;</span>
879
+ <span class="cline-any cline-neutral">&nbsp;</span>
880
+ <span class="cline-any cline-yes">20x</span>
881
+ <span class="cline-any cline-yes">7x</span>
882
+ <span class="cline-any cline-yes">7x</span>
883
+ <span class="cline-any cline-yes">7x</span>
884
+ <span class="cline-any cline-yes">7x</span>
885
+ <span class="cline-any cline-yes">1x</span>
886
+ <span class="cline-any cline-yes">1x</span>
887
+ <span class="cline-any cline-yes">7x</span>
888
+ <span class="cline-any cline-neutral">&nbsp;</span>
889
+ <span class="cline-any cline-neutral">&nbsp;</span>
890
+ <span class="cline-any cline-neutral">&nbsp;</span>
891
+ <span class="cline-any cline-neutral">&nbsp;</span>
892
+ <span class="cline-any cline-yes">20x</span>
893
+ <span class="cline-any cline-yes">4x</span>
894
+ <span class="cline-any cline-yes">4x</span>
895
+ <span class="cline-any cline-no">&nbsp;</span>
896
+ <span class="cline-any cline-no">&nbsp;</span>
897
+ <span class="cline-any cline-neutral">&nbsp;</span>
898
+ <span class="cline-any cline-yes">4x</span>
899
+ <span class="cline-any cline-yes">4x</span>
900
+ <span class="cline-any cline-yes">4x</span>
901
+ <span class="cline-any cline-yes">4x</span>
902
+ <span class="cline-any cline-yes">4x</span>
903
+ <span class="cline-any cline-yes">4x</span>
904
+ <span class="cline-any cline-yes">4x</span>
905
+ <span class="cline-any cline-yes">4x</span>
906
+ <span class="cline-any cline-yes">4x</span>
907
+ <span class="cline-any cline-yes">4x</span>
908
+ <span class="cline-any cline-neutral">&nbsp;</span>
909
+ <span class="cline-any cline-neutral">&nbsp;</span>
910
+ <span class="cline-any cline-neutral">&nbsp;</span>
911
+ <span class="cline-any cline-neutral">&nbsp;</span>
912
+ <span class="cline-any cline-yes">20x</span>
913
+ <span class="cline-any cline-yes">28x</span>
914
+ <span class="cline-any cline-yes">28x</span>
915
+ <span class="cline-any cline-yes">28x</span>
916
+ <span class="cline-any cline-yes">28x</span>
917
+ <span class="cline-any cline-yes">28x</span>
918
+ <span class="cline-any cline-neutral">&nbsp;</span>
919
+ <span class="cline-any cline-yes">28x</span>
920
+ <span class="cline-any cline-yes">1x</span>
921
+ <span class="cline-any cline-yes">1x</span>
922
+ <span class="cline-any cline-neutral">&nbsp;</span>
923
+ <span class="cline-any cline-yes">28x</span>
924
+ <span class="cline-any cline-yes">2x</span>
925
+ <span class="cline-any cline-no">&nbsp;</span>
926
+ <span class="cline-any cline-no">&nbsp;</span>
927
+ <span class="cline-any cline-neutral">&nbsp;</span>
928
+ <span class="cline-any cline-yes">2x</span>
929
+ <span class="cline-any cline-yes">2x</span>
930
+ <span class="cline-any cline-yes">2x</span>
931
+ <span class="cline-any cline-yes">2x</span>
932
+ <span class="cline-any cline-yes">2x</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-yes">25x</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-yes">28x</span>
939
+ <span class="cline-any cline-yes">3x</span>
940
+ <span class="cline-any cline-yes">3x</span>
941
+ <span class="cline-any cline-yes">3x</span>
942
+ <span class="cline-any cline-yes">3x</span>
943
+ <span class="cline-any cline-yes">3x</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-yes">22x</span>
947
+ <span class="cline-any cline-yes">22x</span>
948
+ <span class="cline-any cline-yes">28x</span>
949
+ <span class="cline-any cline-yes">1x</span>
950
+ <span class="cline-any cline-yes">1x</span>
951
+ <span class="cline-any cline-neutral">&nbsp;</span>
952
+ <span class="cline-any cline-yes">21x</span>
953
+ <span class="cline-any cline-neutral">&nbsp;</span>
954
+ <span class="cline-any cline-yes">21x</span>
955
+ <span class="cline-any cline-yes">21x</span>
956
+ <span class="cline-any cline-neutral">&nbsp;</span>
957
+ <span class="cline-any cline-yes">21x</span>
958
+ <span class="cline-any cline-yes">21x</span>
959
+ <span class="cline-any cline-yes">28x</span>
960
+ <span class="cline-any cline-yes">1x</span>
961
+ <span class="cline-any cline-yes">1x</span>
962
+ <span class="cline-any cline-neutral">&nbsp;</span>
963
+ <span class="cline-any cline-yes">21x</span>
964
+ <span class="cline-any cline-yes">28x</span>
965
+ <span class="cline-any cline-neutral">&nbsp;</span>
966
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">20x</span>
970
+ <span class="cline-any cline-yes">21x</span>
971
+ <span class="cline-any cline-yes">21x</span>
972
+ <span class="cline-any cline-yes">21x</span>
973
+ <span class="cline-any cline-yes">21x</span>
974
+ <span class="cline-any cline-yes">21x</span>
975
+ <span class="cline-any cline-neutral">&nbsp;</span>
976
+ <span class="cline-any cline-yes">21x</span>
977
+ <span class="cline-any cline-yes">26x</span>
978
+ <span class="cline-any cline-yes">1x</span>
979
+ <span class="cline-any cline-yes">1x</span>
980
+ <span class="cline-any cline-yes">1x</span>
981
+ <span class="cline-any cline-neutral">&nbsp;</span>
982
+ <span class="cline-any cline-yes">25x</span>
983
+ <span class="cline-any cline-yes">25x</span>
984
+ <span class="cline-any cline-yes">25x</span>
985
+ <span class="cline-any cline-yes">25x</span>
986
+ <span class="cline-any cline-yes">25x</span>
987
+ <span class="cline-any cline-yes">24x</span>
988
+ <span class="cline-any cline-neutral">&nbsp;</span>
989
+ <span class="cline-any cline-yes">24x</span>
990
+ <span class="cline-any cline-yes">24x</span>
991
+ <span class="cline-any cline-yes">24x</span>
992
+ <span class="cline-any cline-yes">26x</span>
993
+ <span class="cline-any cline-yes">26x</span>
994
+ <span class="cline-any cline-yes">26x</span>
995
+ <span class="cline-any cline-yes">16x</span>
996
+ <span class="cline-any cline-yes">16x</span>
997
+ <span class="cline-any cline-neutral">&nbsp;</span>
998
+ <span class="cline-any cline-yes">8x</span>
999
+ <span class="cline-any cline-yes">8x</span>
1000
+ <span class="cline-any cline-yes">8x</span>
1001
+ <span class="cline-any cline-yes">24x</span>
1002
+ <span class="cline-any cline-yes">7x</span>
1003
+ <span class="cline-any cline-yes">7x</span>
1004
+ <span class="cline-any cline-yes">8x</span>
1005
+ <span class="cline-any cline-yes">8x</span>
1006
+ <span class="cline-any cline-neutral">&nbsp;</span>
1007
+ <span class="cline-any cline-yes">20x</span>
1008
+ <span class="cline-any cline-yes">21x</span>
1009
+ <span class="cline-any cline-neutral">&nbsp;</span>
1010
+ <span class="cline-any cline-neutral">&nbsp;</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-yes">20x</span>
1014
+ <span class="cline-any cline-yes">21x</span>
1015
+ <span class="cline-any cline-yes">21x</span>
1016
+ <span class="cline-any cline-yes">21x</span>
1017
+ <span class="cline-any cline-yes">21x</span>
1018
+ <span class="cline-any cline-yes">21x</span>
1019
+ <span class="cline-any cline-yes">21x</span>
1020
+ <span class="cline-any cline-yes">21x</span>
1021
+ <span class="cline-any cline-yes">21x</span>
1022
+ <span class="cline-any cline-yes">21x</span>
1023
+ <span class="cline-any cline-yes">21x</span>
1024
+ <span class="cline-any cline-neutral">&nbsp;</span>
1025
+ <span class="cline-any cline-neutral">&nbsp;</span>
1026
+ <span class="cline-any cline-neutral">&nbsp;</span>
1027
+ <span class="cline-any cline-neutral">&nbsp;</span>
1028
+ <span class="cline-any cline-yes">20x</span>
1029
+ <span class="cline-any cline-yes">31x</span>
1030
+ <span class="cline-any cline-yes">31x</span>
1031
+ <span class="cline-any cline-yes">31x</span>
1032
+ <span class="cline-any cline-yes">31x</span>
1033
+ <span class="cline-any cline-neutral">&nbsp;</span>
1034
+ <span class="cline-any cline-neutral">&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-yes">20x</span>
1038
+ <span class="cline-any cline-yes">4x</span>
1039
+ <span class="cline-any cline-yes">4x</span>
1040
+ <span class="cline-any cline-yes">4x</span>
1041
+ <span class="cline-any cline-yes">4x</span>
1042
+ <span class="cline-any cline-yes">4x</span>
1043
+ <span class="cline-any cline-yes">4x</span>
1044
+ <span class="cline-any cline-yes">4x</span>
1045
+ <span class="cline-any cline-yes">4x</span>
1046
+ <span class="cline-any cline-yes">4x</span>
1047
+ <span class="cline-any cline-yes">4x</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-neutral">&nbsp;</span>
1052
+ <span class="cline-any cline-yes">20x</span>
1053
+ <span class="cline-any cline-yes">31x</span>
1054
+ <span class="cline-any cline-yes">31x</span>
1055
+ <span class="cline-any cline-yes">31x</span>
1056
+ <span class="cline-any cline-yes">31x</span>
1057
+ <span class="cline-any cline-yes">31x</span>
1058
+ <span class="cline-any cline-yes">31x</span>
1059
+ <span class="cline-any cline-yes">31x</span>
1060
+ <span class="cline-any cline-yes">31x</span>
1061
+ <span class="cline-any cline-yes">31x</span>
1062
+ <span class="cline-any cline-yes">31x</span>
1063
+ <span class="cline-any cline-yes">31x</span>
1064
+ <span class="cline-any cline-yes">31x</span>
1065
+ <span class="cline-any cline-neutral">&nbsp;</span>
1066
+ <span class="cline-any cline-neutral">&nbsp;</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">20x</span>
1070
+ <span class="cline-any cline-yes">21x</span>
1071
+ <span class="cline-any cline-yes">21x</span>
1072
+ <span class="cline-any cline-yes">21x</span>
1073
+ <span class="cline-any cline-yes">21x</span>
1074
+ <span class="cline-any cline-yes">21x</span>
1075
+ <span class="cline-any cline-yes">21x</span>
1076
+ <span class="cline-any cline-neutral">&nbsp;</span>
1077
+ <span class="cline-any cline-neutral">&nbsp;</span>
1078
+ <span class="cline-any cline-neutral">&nbsp;</span>
1079
+ <span class="cline-any cline-neutral">&nbsp;</span>
1080
+ <span class="cline-any cline-yes">20x</span>
1081
+ <span class="cline-any cline-yes">31x</span>
1082
+ <span class="cline-any cline-yes">31x</span>
1083
+ <span class="cline-any cline-yes">31x</span>
1084
+ <span class="cline-any cline-yes">31x</span>
1085
+ <span class="cline-any cline-yes">31x</span>
1086
+ <span class="cline-any cline-yes">4x</span>
1087
+ <span class="cline-any cline-yes">4x</span>
1088
+ <span class="cline-any cline-yes">4x</span>
1089
+ <span class="cline-any cline-yes">4x</span>
1090
+ <span class="cline-any cline-yes">4x</span>
1091
+ <span class="cline-any cline-yes">4x</span>
1092
+ <span class="cline-any cline-yes">4x</span>
1093
+ <span class="cline-any cline-neutral">&nbsp;</span>
1094
+ <span class="cline-any cline-yes">31x</span>
1095
+ <span class="cline-any cline-yes">31x</span>
1096
+ <span class="cline-any cline-yes">31x</span>
1097
+ <span class="cline-any cline-yes">31x</span>
1098
+ <span class="cline-any cline-yes">31x</span>
1099
+ <span class="cline-any cline-yes">31x</span>
1100
+ <span class="cline-any cline-neutral">&nbsp;</span>
1101
+ <span class="cline-any cline-neutral">&nbsp;</span>
1102
+ <span class="cline-any cline-neutral">&nbsp;</span>
1103
+ <span class="cline-any cline-neutral">&nbsp;</span>
1104
+ <span class="cline-any cline-yes">20x</span>
1105
+ <span class="cline-any cline-yes">25x</span>
1106
+ <span class="cline-any cline-yes">25x</span>
1107
+ <span class="cline-any cline-yes">25x</span>
1108
+ <span class="cline-any cline-yes">25x</span>
1109
+ <span class="cline-any cline-yes">25x</span>
1110
+ <span class="cline-any cline-yes">25x</span>
1111
+ <span class="cline-any cline-yes">25x</span>
1112
+ <span class="cline-any cline-yes">25x</span>
1113
+ <span class="cline-any cline-yes">25x</span>
1114
+ <span class="cline-any cline-yes">25x</span>
1115
+ <span class="cline-any cline-yes">25x</span>
1116
+ <span class="cline-any cline-yes">25x</span>
1117
+ <span class="cline-any cline-neutral">&nbsp;</span>
1118
+ <span class="cline-any cline-neutral">&nbsp;</span>
1119
+ <span class="cline-any cline-neutral">&nbsp;</span>
1120
+ <span class="cline-any cline-neutral">&nbsp;</span>
1121
+ <span class="cline-any cline-yes">20x</span>
1122
+ <span class="cline-any cline-yes">25x</span>
1123
+ <span class="cline-any cline-yes">25x</span>
1124
+ <span class="cline-any cline-yes">25x</span>
1125
+ <span class="cline-any cline-yes">25x</span>
1126
+ <span class="cline-any cline-neutral">&nbsp;</span>
1127
+ <span class="cline-any cline-yes">25x</span>
1128
+ <span class="cline-any cline-yes">25x</span>
1129
+ <span class="cline-any cline-yes">25x</span>
1130
+ <span class="cline-any cline-yes">25x</span>
1131
+ <span class="cline-any cline-yes">25x</span>
1132
+ <span class="cline-any cline-neutral">&nbsp;</span>
1133
+ <span class="cline-any cline-neutral">&nbsp;</span>
1134
+ <span class="cline-any cline-neutral">&nbsp;</span>
1135
+ <span class="cline-any cline-neutral">&nbsp;</span>
1136
+ <span class="cline-any cline-yes">20x</span>
1137
+ <span class="cline-any cline-yes">30x</span>
1138
+ <span class="cline-any cline-yes">30x</span>
1139
+ <span class="cline-any cline-neutral">&nbsp;</span>
1140
+ <span class="cline-any cline-neutral">&nbsp;</span>
1141
+ <span class="cline-any cline-neutral">&nbsp;</span>
1142
+ <span class="cline-any cline-neutral">&nbsp;</span>
1143
+ <span class="cline-any cline-yes">20x</span>
1144
+ <span class="cline-any cline-yes">168x</span>
1145
+ <span class="cline-any cline-yes">168x</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">20x</span>
1151
+ <span class="cline-any cline-yes">49x</span>
1152
+ <span class="cline-any cline-yes">49x</span>
1153
+ <span class="cline-any cline-yes">49x</span>
1154
+ <span class="cline-any cline-yes">49x</span>
1155
+ <span class="cline-any cline-yes">70x</span>
1156
+ <span class="cline-any cline-yes">70x</span>
1157
+ <span class="cline-any cline-yes">49x</span>
1158
+ <span class="cline-any cline-yes">49x</span>
1159
+ <span class="cline-any cline-yes">49x</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-yes">20x</span>
1165
+ <span class="cline-any cline-yes">5x</span>
1166
+ <span class="cline-any cline-yes">5x</span>
1167
+ <span class="cline-any cline-yes">7x</span>
1168
+ <span class="cline-any cline-yes">3x</span>
1169
+ <span class="cline-any cline-yes">3x</span>
1170
+ <span class="cline-any cline-yes">3x</span>
1171
+ <span class="cline-any cline-yes">7x</span>
1172
+ <span class="cline-any cline-neutral">&nbsp;</span>
1173
+ <span class="cline-any cline-yes">5x</span>
1174
+ <span class="cline-any cline-yes">3x</span>
1175
+ <span class="cline-any cline-yes">3x</span>
1176
+ <span class="cline-any cline-neutral">&nbsp;</span>
1177
+ <span class="cline-any cline-yes">5x</span>
1178
+ <span class="cline-any cline-no">&nbsp;</span>
1179
+ <span class="cline-any cline-no">&nbsp;</span>
1180
+ <span class="cline-any cline-neutral">&nbsp;</span>
1181
+ <span class="cline-any cline-yes">2x</span>
1182
+ <span class="cline-any cline-yes">5x</span>
1183
+ <span class="cline-any cline-yes">20x</span>
1184
+ <span class="cline-any cline-neutral">&nbsp;</span>
1185
+ <span class="cline-any cline-neutral">&nbsp;</span>
1186
+ <span class="cline-any cline-neutral">&nbsp;</span>
1187
+ <span class="cline-any cline-neutral">&nbsp;</span>
1188
+ <span class="cline-any cline-yes">1x</span>
1189
+ <span class="cline-any cline-no">&nbsp;</span>
1190
+ <span class="cline-any cline-no">&nbsp;</span>
1191
+ <span class="cline-any cline-no">&nbsp;</span>
1192
+ <span class="cline-any cline-neutral">&nbsp;</span>
1193
+ <span class="cline-any cline-neutral">&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-yes">1x</span>
1197
+ <span class="cline-any cline-no">&nbsp;</span>
1198
+ <span class="cline-any cline-no">&nbsp;</span>
1199
+ <span class="cline-any cline-no">&nbsp;</span>
1200
+ <span class="cline-any cline-neutral">&nbsp;</span>
1201
+ <span class="cline-any cline-neutral">&nbsp;</span>
1202
+ <span class="cline-any cline-neutral">&nbsp;</span>
1203
+ <span class="cline-any cline-neutral">&nbsp;</span>
1204
+ <span class="cline-any cline-yes">1x</span>
1205
+ <span class="cline-any cline-no">&nbsp;</span>
1206
+ <span class="cline-any cline-no">&nbsp;</span>
1207
+ <span class="cline-any cline-no">&nbsp;</span>
1208
+ <span class="cline-any cline-no">&nbsp;</span>
1209
+ <span class="cline-any cline-no">&nbsp;</span>
1210
+ <span class="cline-any cline-no">&nbsp;</span>
1211
+ <span class="cline-any cline-neutral">&nbsp;</span>
1212
+ <span class="cline-any cline-no">&nbsp;</span>
1213
+ <span class="cline-any cline-no">&nbsp;</span>
1214
+ <span class="cline-any cline-no">&nbsp;</span>
1215
+ <span class="cline-any cline-no">&nbsp;</span>
1216
+ <span class="cline-any cline-no">&nbsp;</span>
1217
+ <span class="cline-any cline-neutral">&nbsp;</span>
1218
+ <span class="cline-any cline-no">&nbsp;</span>
1219
+ <span class="cline-any cline-no">&nbsp;</span>
1220
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/**
1221
+ * Job scheduler and execution management
1222
+ */
1223
+ import type {
1224
+ Workflow,
1225
+ Job,
1226
+ JobResult,
1227
+ ExecutionPlan,
1228
+ ExecutionContext,
1229
+ Conclusion,
1230
+ RunStatus,
1231
+ } from '../types.js';
1232
+ import { evaluateCondition } from '../parser/expression.js';
1233
+ import {
1234
+ buildDependencyGraph,
1235
+ groupIntoPhases,
1236
+ detectCycle,
1237
+ DependencyError,
1238
+ type DependencyGraph,
1239
+ } from './dependency.js';
1240
+ import { StepRunner, type StepRunnerOptions } from './step.js';
1241
+ import {
1242
+ createListenerRegistry,
1243
+ type ListenerRegistry,
1244
+ } from './listener-registry.js';
1245
+ import { buildStepsContext } from './steps-context.js';
1246
+ import {
1247
+ buildPlanDependencyPolicy,
1248
+ classifyStepControl,
1249
+ createCompletedJobResult,
1250
+ createInProgressJobResult,
1251
+ finalizeJobResult,
1252
+ getDependencySkipReason,
1253
+ getJobNeeds,
1254
+ type JobExecutionState,
1255
+ } from './job-policy.js';
1256
+ import {
1257
+ buildJobExecutionContext,
1258
+ buildNeedsContext,
1259
+ } from './job-context.js';
1260
+ &nbsp;
1261
+ /**
1262
+ * Job scheduler options
1263
+ */
1264
+ export interface JobSchedulerOptions {
1265
+ /** Maximum parallel jobs (0 = unlimited) */
1266
+ maxParallel?: number;
1267
+ /** Fail fast - cancel remaining jobs on first failure */
1268
+ failFast?: boolean;
1269
+ /** Step runner options */
1270
+ stepRunner?: StepRunnerOptions;
1271
+ }
1272
+ &nbsp;
1273
+ /**
1274
+ * Job scheduler event types
1275
+ */
1276
+ export type JobSchedulerEvent =
1277
+ | { type: 'job:start'; jobId: string; job: Job }
1278
+ | { type: 'job:complete'; jobId: string; result: JobResult }
1279
+ | { type: 'job:skip'; jobId: string; reason: string; result: JobResult }
1280
+ | { type: 'phase:start'; phase: number; jobs: string[] }
1281
+ | { type: 'phase:complete'; phase: number }
1282
+ | { type: 'workflow:start'; phases: string[][] }
1283
+ | { type: 'workflow:complete'; results: Record&lt;string, JobResult&gt; };
1284
+ &nbsp;
1285
+ /**
1286
+ * Job scheduler event listener
1287
+ */
1288
+ export type JobSchedulerListener = (event: JobSchedulerEvent) =&gt; void;
1289
+ &nbsp;
1290
+ /**
1291
+ * Job scheduler for workflow execution
1292
+ */
1293
+ export class JobScheduler {
1294
+ private workflow: Workflow;
1295
+ private options: JobSchedulerOptions;
1296
+ private graph: DependencyGraph;
1297
+ private results: Map&lt;string, JobResult&gt;;
1298
+ private listenerRegistry: ListenerRegistry&lt;JobSchedulerEvent, JobSchedulerListener&gt;;
1299
+ private cancelled: boolean;
1300
+ private running: boolean;
1301
+ private stepRunner: StepRunner;
1302
+ &nbsp;
1303
+ constructor(workflow: Workflow, options: JobSchedulerOptions = {}) {
1304
+ this.workflow = workflow;
1305
+ this.options = {
1306
+ maxParallel: options.maxParallel ?? 0,
1307
+ failFast: options.failFast ?? true,
1308
+ stepRunner: options.stepRunner ?? {},
1309
+ };
1310
+ this.graph = buildDependencyGraph(workflow);
1311
+ this.results = new Map();
1312
+ this.listenerRegistry =
1313
+ createListenerRegistry&lt;JobSchedulerEvent, JobSchedulerListener&gt;();
1314
+ this.cancelled = false;
1315
+ this.running = false;
1316
+ this.stepRunner = new StepRunner(this.options.stepRunner);
1317
+ }
1318
+ &nbsp;
1319
+ /**
1320
+ * Add event listener
1321
+ */
1322
+ on(listener: JobSchedulerListener): () =&gt; void {
1323
+ return this.listenerRegistry.on(listener);
1324
+ }
1325
+ &nbsp;
1326
+ /**
1327
+ * Emit event to all listeners
1328
+ */
1329
+ private emit(event: JobSchedulerEvent): void {
1330
+ this.listenerRegistry.emit(event);
1331
+ }
1332
+ &nbsp;
1333
+ /**
1334
+ * Cancel workflow execution
1335
+ */
1336
+ cancel(): void {
1337
+ this.cancelled = true;
1338
+ }
1339
+ &nbsp;
1340
+ /**
1341
+ * Reset scheduler runtime state for a new run.
1342
+ * Keeps listeners and configuration intact.
1343
+ */
1344
+ reset(): void {
1345
+ this.results.clear();
1346
+ this.cancelled = false;
1347
+ }
1348
+ &nbsp;
1349
+ /**
1350
+ * Create execution plan
1351
+ */
1352
+ createPlan(): ExecutionPlan {
1353
+ // Check for cycles
1354
+ const cycle = detectCycle(this.graph);
1355
+ if (cycle.length &gt; 0) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1356
+ <span class="cstat-no" title="statement not covered" > throw new DependencyError(</span>
1357
+ <span class="cstat-no" title="statement not covered" > `Circular dependency detected: ${cycle.join(' -&gt; ')}`,</span>
1358
+ <span class="cstat-no" title="statement not covered" > cycle</span>
1359
+ <span class="cstat-no" title="statement not covered" > );</span>
1360
+ <span class="cstat-no" title="statement not covered" > }</span>
1361
+ &nbsp;
1362
+ const phases = groupIntoPhases(this.graph);
1363
+ const { dependencies, skippable } = buildPlanDependencyPolicy(this.workflow);
1364
+ &nbsp;
1365
+ return { phases, dependencies, skippable };
1366
+ }
1367
+ &nbsp;
1368
+ /**
1369
+ * Run all jobs in workflow
1370
+ */
1371
+ async run(context: ExecutionContext): Promise&lt;Record&lt;string, JobResult&gt;&gt; {
1372
+ if (this.running) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1373
+ <span class="cstat-no" title="statement not covered" > throw new Error('JobScheduler is already running');</span>
1374
+ <span class="cstat-no" title="statement not covered" > }</span>
1375
+ &nbsp;
1376
+ this.running = true;
1377
+ this.reset();
1378
+ &nbsp;
1379
+ try {
1380
+ const plan = this.createPlan();
1381
+ this.emit({ type: 'workflow:start', phases: plan.phases });
1382
+ &nbsp;
1383
+ for (let phaseIndex = 0; phaseIndex &lt; plan.phases.length; phaseIndex++) {
1384
+ if (this.cancelled) <span class="branch-0 cbranch-no" title="branch not covered" >break;</span>
1385
+ &nbsp;
1386
+ const phase = plan.phases[phaseIndex];
1387
+ this.emit({ type: 'phase:start', phase: phaseIndex, jobs: phase });
1388
+ &nbsp;
1389
+ // Run jobs in phase (potentially in parallel)
1390
+ await this.runPhase(phase, context);
1391
+ &nbsp;
1392
+ this.emit({ type: 'phase:complete', phase: phaseIndex });
1393
+ &nbsp;
1394
+ // Check for failures in fail-fast mode
1395
+ if (this.options.failFast) {
1396
+ const phaseFailed = phase.some(
1397
+ (jobId) =&gt; this.results.get(jobId)?.conclusion === 'failure'
1398
+ );
1399
+ if (!phaseFailed) {
1400
+ continue;
1401
+ }
1402
+ &nbsp;
1403
+ this.cancelled = true;
1404
+ for (let i = phaseIndex + 1; i &lt; plan.phases.length; i++) {
1405
+ this.markJobsCancelled(plan.phases[i]);
1406
+ }
1407
+ break;
1408
+ }
1409
+ }
1410
+ &nbsp;
1411
+ const results = this.getResults();
1412
+ this.emit({
1413
+ type: 'workflow:complete',
1414
+ results: this.cloneJobResultsRecord(results),
1415
+ });
1416
+ return results;
1417
+ } finally {
1418
+ this.running = false;
1419
+ }
1420
+ }
1421
+ &nbsp;
1422
+ /**
1423
+ * Run jobs in a single phase
1424
+ */
1425
+ private async runPhase(
1426
+ jobIds: string[],
1427
+ context: ExecutionContext
1428
+ ): Promise&lt;void&gt; {
1429
+ const maxParallel = this.options.maxParallel || jobIds.length;
1430
+ const chunks: string[][] = [];
1431
+ &nbsp;
1432
+ // Split into chunks based on max parallel
1433
+ for (let i = 0; i &lt; jobIds.length; i += maxParallel) {
1434
+ chunks.push(jobIds.slice(i, i + maxParallel));
1435
+ }
1436
+ &nbsp;
1437
+ for (let index = 0; index &lt; chunks.length; index++) {
1438
+ if (this.cancelled) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1439
+ <span class="cstat-no" title="statement not covered" > this.markPendingChunksCancelled(chunks, index);</span>
1440
+ <span class="cstat-no" title="statement not covered" > break;</span>
1441
+ <span class="cstat-no" title="statement not covered" > }</span>
1442
+ &nbsp;
1443
+ const chunk = chunks[index];
1444
+ &nbsp;
1445
+ await Promise.all(chunk.map((jobId) =&gt; this.runJob(jobId, context)));
1446
+ &nbsp;
1447
+ if (this.cancelled) {
1448
+ this.markPendingChunksCancelled(chunks, index + 1);
1449
+ break;
1450
+ }
1451
+ }
1452
+ }
1453
+ &nbsp;
1454
+ /**
1455
+ * Mark pending chunks as cancelled from the specified index.
1456
+ */
1457
+ private markPendingChunksCancelled(
1458
+ chunks: string[][],
1459
+ startIndex: number
1460
+ ): void {
1461
+ for (let pending = startIndex; pending &lt; chunks.length; pending++) {
1462
+ this.markJobsCancelled(chunks[pending]);
1463
+ }
1464
+ }
1465
+ &nbsp;
1466
+ /**
1467
+ * Mark jobs as cancelled if they don't already have a result.
1468
+ */
1469
+ private markJobsCancelled(jobIds: string[]): void {
1470
+ for (const jobId of jobIds) {
1471
+ if (this.results.has(jobId)) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1472
+ <span class="cstat-no" title="statement not covered" > continue;</span>
1473
+ <span class="cstat-no" title="statement not covered" > }</span>
1474
+ &nbsp;
1475
+ this.completeTerminalJob(
1476
+ jobId,
1477
+ createCompletedJobResult(
1478
+ jobId,
1479
+ this.workflow.jobs[jobId].name,
1480
+ 'cancelled'
1481
+ )
1482
+ );
1483
+ }
1484
+ }
1485
+ &nbsp;
1486
+ /**
1487
+ * Run a single job
1488
+ */
1489
+ private async runJob(
1490
+ jobId: string,
1491
+ context: ExecutionContext
1492
+ ): Promise&lt;JobResult&gt; {
1493
+ const job = this.workflow.jobs[jobId];
1494
+ const existingResult = this.results.get(jobId);
1495
+ &nbsp;
1496
+ if (existingResult?.conclusion === 'cancelled') {
1497
+ return this.cloneJobResult(existingResult);
1498
+ }
1499
+ &nbsp;
1500
+ if (this.cancelled) {
1501
+ if (existingResult) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1502
+ <span class="cstat-no" title="statement not covered" > return this.cloneJobResult(existingResult);</span>
1503
+ <span class="cstat-no" title="statement not covered" > }</span>
1504
+ &nbsp;
1505
+ return this.completeTerminalJob(
1506
+ jobId,
1507
+ createCompletedJobResult(jobId, job.name, 'cancelled')
1508
+ );
1509
+ }
1510
+ &nbsp;
1511
+ // Build job-specific context with needs
1512
+ const jobContext = this.buildJobContext(jobId, context);
1513
+ &nbsp;
1514
+ // Check if job should be skipped
1515
+ if (job.if !== undefined) {
1516
+ const shouldRun = evaluateCondition(job.if, jobContext);
1517
+ if (!shouldRun) {
1518
+ return this.skipJob(jobId, job.name, 'Condition not met');
1519
+ }
1520
+ }
1521
+ &nbsp;
1522
+ // Dependencies are success-only: any non-success dependency conclusion skips this job.
1523
+ const needs = getJobNeeds(job);
1524
+ const dependencySkipReason = getDependencySkipReason(needs, this.results);
1525
+ if (dependencySkipReason) {
1526
+ return this.skipJob(jobId, job.name, dependencySkipReason);
1527
+ }
1528
+ &nbsp;
1529
+ this.emit({ type: 'job:start', jobId, job });
1530
+ &nbsp;
1531
+ const result = createInProgressJobResult(jobId, job.name);
1532
+ let executionState: JobExecutionState;
1533
+ &nbsp;
1534
+ try {
1535
+ executionState = await this.executeJobSteps(job, jobContext, result);
1536
+ } catch {
1537
+ executionState = { failed: true, cancelled: false };
1538
+ }
1539
+ &nbsp;
1540
+ return this.finalizeAndStoreJobResult(jobId, result, executionState);
1541
+ }
1542
+ &nbsp;
1543
+ /**
1544
+ * Execute all steps for a job and return the final execution state.
1545
+ */
1546
+ private async executeJobSteps(
1547
+ job: Job,
1548
+ jobContext: ExecutionContext,
1549
+ result: JobResult
1550
+ ): Promise&lt;JobExecutionState&gt; {
1551
+ const executionState: JobExecutionState = { failed: false, cancelled: false };
1552
+ &nbsp;
1553
+ for (let i = 0; i &lt; job.steps.length; i++) {
1554
+ if (this.cancelled) {
1555
+ executionState.cancelled = true;
1556
+ break;
1557
+ }
1558
+ &nbsp;
1559
+ const step = job.steps[i];
1560
+ const stepContext = this.buildStepContext(jobContext, result);
1561
+ const stepResult = await this.stepRunner.runStep(step, stepContext, {
1562
+ index: i,
1563
+ });
1564
+ result.steps.push(stepResult);
1565
+ &nbsp;
1566
+ const stepControl = classifyStepControl(
1567
+ step,
1568
+ stepResult,
1569
+ this.options.<span class="branch-0 cbranch-no" title="branch not covered" >failFast ?? true</span>
1570
+ );
1571
+ if (!stepControl.shouldStopJob) {
1572
+ continue;
1573
+ }
1574
+ &nbsp;
1575
+ if (stepControl.shouldMarkJobFailed) {
1576
+ executionState.failed = true;
1577
+ }
1578
+ if (stepControl.shouldCancelWorkflow) {
1579
+ this.cancelled = true;
1580
+ }
1581
+ break;
1582
+ }
1583
+ &nbsp;
1584
+ return executionState;
1585
+ }
1586
+ &nbsp;
1587
+ /**
1588
+ * Finalize and record a completed job result.
1589
+ */
1590
+ private finalizeAndStoreJobResult(
1591
+ jobId: string,
1592
+ result: JobResult,
1593
+ executionState: JobExecutionState
1594
+ ): JobResult {
1595
+ const finalizedResult = this.finalizeJobExecutionResult(
1596
+ result,
1597
+ executionState
1598
+ );
1599
+ return this.completeTerminalJob(jobId, finalizedResult);
1600
+ }
1601
+ &nbsp;
1602
+ /**
1603
+ * Store job result and return it.
1604
+ */
1605
+ private storeJobResult(jobId: string, result: JobResult): JobResult {
1606
+ const storedResult = this.cloneJobResult(result);
1607
+ this.results.set(jobId, storedResult);
1608
+ return storedResult;
1609
+ }
1610
+ &nbsp;
1611
+ /**
1612
+ * Create, store, and emit skip result for a job.
1613
+ */
1614
+ private skipJob(
1615
+ jobId: string,
1616
+ jobName: JobResult['name'],
1617
+ reason: string
1618
+ ): JobResult {
1619
+ return this.completeTerminalJob(
1620
+ jobId,
1621
+ createCompletedJobResult(jobId, jobName, 'skipped'),
1622
+ { skipReason: reason }
1623
+ );
1624
+ }
1625
+ &nbsp;
1626
+ /**
1627
+ * Store terminal job result and emit terminal job events.
1628
+ */
1629
+ private completeTerminalJob(
1630
+ jobId: string,
1631
+ result: JobResult,
1632
+ options: { skipReason?: string } = {}
1633
+ ): JobResult {
1634
+ const storedResult = this.storeJobResult(jobId, result);
1635
+ this.emitTerminalObservationEvents(
1636
+ jobId,
1637
+ storedResult,
1638
+ options.skipReason
1639
+ );
1640
+ return this.cloneJobResult(storedResult);
1641
+ }
1642
+ &nbsp;
1643
+ /**
1644
+ * Finalize in-progress job result.
1645
+ */
1646
+ private finalizeJobExecutionResult(
1647
+ result: JobResult,
1648
+ executionState: JobExecutionState
1649
+ ): JobResult {
1650
+ finalizeJobResult(result, executionState);
1651
+ return result;
1652
+ }
1653
+ &nbsp;
1654
+ /**
1655
+ * Emit terminal observation events for a job.
1656
+ */
1657
+ private emitTerminalObservationEvents(
1658
+ jobId: string,
1659
+ storedResult: JobResult,
1660
+ skipReason?: string
1661
+ ): void {
1662
+ if (skipReason !== undefined) {
1663
+ this.emit({
1664
+ type: 'job:skip',
1665
+ jobId,
1666
+ reason: skipReason,
1667
+ result: this.cloneJobResult(storedResult),
1668
+ });
1669
+ }
1670
+ &nbsp;
1671
+ this.emit({
1672
+ type: 'job:complete',
1673
+ jobId,
1674
+ result: this.cloneJobResult(storedResult),
1675
+ });
1676
+ }
1677
+ &nbsp;
1678
+ /**
1679
+ * Build execution context with needs data
1680
+ */
1681
+ private buildJobContext(
1682
+ jobId: string,
1683
+ context: ExecutionContext
1684
+ ): ExecutionContext {
1685
+ const job = this.workflow.jobs[jobId];
1686
+ const needs = getJobNeeds(job);
1687
+ const needsContext = buildNeedsContext(needs, this.results);
1688
+ return buildJobExecutionContext(context, needsContext, [
1689
+ context.env,
1690
+ this.workflow.env,
1691
+ job.env,
1692
+ ]);
1693
+ }
1694
+ &nbsp;
1695
+ /**
1696
+ * Build step context with previous step outputs
1697
+ */
1698
+ private buildStepContext(
1699
+ jobContext: ExecutionContext,
1700
+ jobResult: JobResult
1701
+ ): ExecutionContext {
1702
+ const stepsContext = buildStepsContext(jobResult.steps);
1703
+ &nbsp;
1704
+ return {
1705
+ ...jobContext,
1706
+ steps: stepsContext,
1707
+ };
1708
+ }
1709
+ &nbsp;
1710
+ /**
1711
+ * Get current results
1712
+ */
1713
+ getResults(): Record&lt;string, JobResult&gt; {
1714
+ return this.cloneJobResultsRecord(Object.fromEntries(this.results));
1715
+ }
1716
+ &nbsp;
1717
+ /**
1718
+ * Clone a job result to prevent external mutation from corrupting scheduler state.
1719
+ */
1720
+ private cloneJobResult(result: JobResult): JobResult {
1721
+ return structuredClone(result);
1722
+ }
1723
+ &nbsp;
1724
+ /**
1725
+ * Clone a job result record.
1726
+ */
1727
+ private cloneJobResultsRecord(
1728
+ results: Record&lt;string, JobResult&gt;
1729
+ ): Record&lt;string, JobResult&gt; {
1730
+ return Object.fromEntries(
1731
+ Object.entries(results).map(([jobId, result]) =&gt; [
1732
+ jobId,
1733
+ this.cloneJobResult(result),
1734
+ ])
1735
+ );
1736
+ }
1737
+ &nbsp;
1738
+ /**
1739
+ * Get overall conclusion
1740
+ */
1741
+ getConclusion(): Conclusion {
1742
+ let hasFailure = false;
1743
+ for (const result of this.results.values()) {
1744
+ if (result.conclusion === 'failure') {
1745
+ hasFailure = true;
1746
+ break;
1747
+ }
1748
+ }
1749
+ &nbsp;
1750
+ if (hasFailure) {
1751
+ return 'failure';
1752
+ }
1753
+ &nbsp;
1754
+ if (this.cancelled) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1755
+ <span class="cstat-no" title="statement not covered" > return 'cancelled';</span>
1756
+ <span class="cstat-no" title="statement not covered" > }</span>
1757
+ &nbsp;
1758
+ return 'success';
1759
+ }
1760
+ }
1761
+ &nbsp;
1762
+ /**
1763
+ * Create execution plan for workflow
1764
+ */
1765
+ export <span class="fstat-no" title="function not covered" >function createExecutionPlan(workflow: Workflow): ExecutionPlan {</span>
1766
+ <span class="cstat-no" title="statement not covered" > const scheduler = new JobScheduler(workflow);</span>
1767
+ <span class="cstat-no" title="statement not covered" > return scheduler.createPlan();</span>
1768
+ <span class="cstat-no" title="statement not covered" >}</span>
1769
+ &nbsp;
1770
+ /**
1771
+ * Get parallel job groups
1772
+ */
1773
+ export <span class="fstat-no" title="function not covered" >function getParallelGroups(workflow: Workflow): string[][] {</span>
1774
+ <span class="cstat-no" title="statement not covered" > const graph = buildDependencyGraph(workflow);</span>
1775
+ <span class="cstat-no" title="statement not covered" > return groupIntoPhases(graph);</span>
1776
+ <span class="cstat-no" title="statement not covered" >}</span>
1777
+ &nbsp;
1778
+ /**
1779
+ * Check if jobs can run in parallel
1780
+ */
1781
+ export <span class="fstat-no" title="function not covered" >function canRunInParallel(</span>
1782
+ <span class="cstat-no" title="statement not covered" > workflow: Workflow,</span>
1783
+ <span class="cstat-no" title="statement not covered" > jobA: string,</span>
1784
+ <span class="cstat-no" title="statement not covered" > jobB: string</span>
1785
+ <span class="cstat-no" title="statement not covered" >): boolean {</span>
1786
+ <span class="cstat-no" title="statement not covered" > const graph = buildDependencyGraph(workflow);</span>
1787
+ <span class="cstat-no" title="statement not covered" > const phases = groupIntoPhases(graph);</span>
1788
+ &nbsp;
1789
+ <span class="cstat-no" title="statement not covered" > for (const phase of phases) {</span>
1790
+ <span class="cstat-no" title="statement not covered" > if (phase.includes(jobA) &amp;&amp; phase.includes(jobB)) {</span>
1791
+ <span class="cstat-no" title="statement not covered" > return true;</span>
1792
+ <span class="cstat-no" title="statement not covered" > }</span>
1793
+ <span class="cstat-no" title="statement not covered" > }</span>
1794
+ &nbsp;
1795
+ <span class="cstat-no" title="statement not covered" > return false;</span>
1796
+ <span class="cstat-no" title="statement not covered" >}</span>
1797
+ &nbsp;</pre></td></tr></table></pre>
1798
+
1799
+ <div class='push'></div><!-- for sticky footer -->
1800
+ </div><!-- /wrapper -->
1801
+ <div class='footer quiet pad2 space-top1 center small'>
1802
+ Code coverage generated by
1803
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1804
+ at 2026-02-27T18:23:31.775Z
1805
+ </div>
1806
+ <script src="../../prettify.js"></script>
1807
+ <script>
1808
+ window.onload = function () {
1809
+ prettyPrint();
1810
+ };
1811
+ </script>
1812
+ <script src="../../sorter.js"></script>
1813
+ <script src="../../block-navigation.js"></script>
1814
+ </body>
1815
+ </html>
1816
+