@basementuniverse/kanbn 1.1.0 → 2.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 (124) hide show
  1. package/README.md +2 -0
  2. package/coverage/base.css +224 -0
  3. package/coverage/block-navigation.js +87 -0
  4. package/coverage/coverage-summary.json +31 -0
  5. package/coverage/favicon.png +0 -0
  6. package/coverage/index.html +146 -0
  7. package/coverage/kanbn/index.html +116 -0
  8. package/coverage/kanbn/index.js.html +217 -0
  9. package/coverage/kanbn/src/board.js.html +646 -0
  10. package/coverage/kanbn/src/controller/add.js.html +1729 -0
  11. package/coverage/kanbn/src/controller/archive.js.html +277 -0
  12. package/coverage/kanbn/src/controller/board.js.html +217 -0
  13. package/coverage/kanbn/src/controller/burndown.js.html +607 -0
  14. package/coverage/kanbn/src/controller/comment.js.html +397 -0
  15. package/coverage/kanbn/src/controller/edit.js.html +2920 -0
  16. package/coverage/kanbn/src/controller/find.js.html +1597 -0
  17. package/coverage/kanbn/src/controller/gantt.js.html +1342 -0
  18. package/coverage/kanbn/src/controller/help.js.html +115 -0
  19. package/coverage/kanbn/src/controller/history.js.html +400 -0
  20. package/coverage/kanbn/src/controller/index.html +431 -0
  21. package/coverage/kanbn/src/controller/init.js.html +511 -0
  22. package/coverage/kanbn/src/controller/move.js.html +514 -0
  23. package/coverage/kanbn/src/controller/remove-all.js.html +226 -0
  24. package/coverage/kanbn/src/controller/remove.js.html +307 -0
  25. package/coverage/kanbn/src/controller/rename.js.html +397 -0
  26. package/coverage/kanbn/src/controller/restore.js.html +268 -0
  27. package/coverage/kanbn/src/controller/sort.js.html +1318 -0
  28. package/coverage/kanbn/src/controller/sprint.js.html +361 -0
  29. package/coverage/kanbn/src/controller/status.js.html +310 -0
  30. package/coverage/kanbn/src/controller/task.js.html +244 -0
  31. package/coverage/kanbn/src/controller/validate.js.html +367 -0
  32. package/coverage/kanbn/src/controller/version.js.html +100 -0
  33. package/coverage/kanbn/src/index.html +191 -0
  34. package/coverage/kanbn/src/main.js.html +9787 -0
  35. package/coverage/kanbn/src/parse-index.js.html +1063 -0
  36. package/coverage/kanbn/src/parse-markdown.js.html +202 -0
  37. package/coverage/kanbn/src/parse-task.js.html +2191 -0
  38. package/coverage/kanbn/src/utility.js.html +616 -0
  39. package/coverage/lcov.info +11837 -0
  40. package/coverage/prettify.css +1 -0
  41. package/coverage/prettify.js +2 -0
  42. package/coverage/sort-arrow-sprite.png +0 -0
  43. package/coverage/sorter.js +210 -0
  44. package/coverage/tmp/coverage-214292-1787777191526-0.json +1 -0
  45. package/coverage/tmp/coverage-214293-1787777184569-0.json +1 -0
  46. package/docs/advanced-configuration.md +2 -0
  47. package/docs/commands/add.txt +10 -0
  48. package/docs/commands/board.txt +3 -1
  49. package/docs/commands/burndown.txt +2 -4
  50. package/docs/commands/edit.txt +22 -0
  51. package/docs/commands/find.txt +45 -1
  52. package/docs/commands/help.txt +1 -0
  53. package/docs/commands/move.txt +1 -1
  54. package/docs/commands/sort.txt +13 -2
  55. package/docs/commands/validate.txt +12 -0
  56. package/docs/filtering-and-sorting.md +218 -0
  57. package/docs/index-structure.md +68 -19
  58. package/docs/index.md +26 -2
  59. package/docs/migration-2.0.md +92 -0
  60. package/docs/quick-start.md +37 -1
  61. package/docs/task-structure.md +12 -3
  62. package/docs/views.md +229 -0
  63. package/example/README.md +70 -0
  64. package/example/advanced/.kanbn/index.md +26 -0
  65. package/example/advanced/.kanbn/tasks/add-rate-limiting.md +18 -0
  66. package/example/advanced/.kanbn/tasks/add-sso-support.md +15 -0
  67. package/example/advanced/.kanbn/tasks/migrate-to-new-cdn.md +14 -0
  68. package/example/advanced/.kanbn/tasks/refresh-marketing-site.md +14 -0
  69. package/example/advanced/.kanbn/tasks/rotate-api-keys.md +15 -0
  70. package/example/advanced/.kanbn/tasks/split-billing-service.md +17 -0
  71. package/example/advanced/.kanbn/tasks/upgrade-node-runtime.md +19 -0
  72. package/example/advanced/kanbn.yml +59 -0
  73. package/example/views/.kanbn/index.md +140 -0
  74. package/example/views/.kanbn/tasks/add-audit-log-export.md +18 -0
  75. package/example/views/.kanbn/tasks/add-dark-mode-toggle.md +16 -0
  76. package/example/views/.kanbn/tasks/build-webhook-retry-queue.md +15 -0
  77. package/example/views/.kanbn/tasks/fix-avatar-upload-crash.md +13 -0
  78. package/example/views/.kanbn/tasks/fix-expired-session-redirect.md +15 -0
  79. package/example/views/.kanbn/tasks/investigate-offline-mode.md +12 -0
  80. package/example/views/.kanbn/tasks/rewrite-search-indexer.md +12 -0
  81. package/example/views/.kanbn/tasks/tidy-up-settings-copy.md +12 -0
  82. package/package.json +4 -3
  83. package/routes/edit.json +2 -1
  84. package/routes/validate.json +4 -2
  85. package/skills/kanbn-plan/references/index-structure.md +1 -0
  86. package/skills/kanbn-plan/references/task-structure.md +2 -0
  87. package/src/board.js +1 -0
  88. package/src/controller/board.js +6 -0
  89. package/src/controller/edit.js +65 -12
  90. package/src/controller/gantt.js +46 -1
  91. package/src/controller/status.js +12 -0
  92. package/src/controller/task.js +1 -1
  93. package/src/controller/validate.js +78 -15
  94. package/src/main.js +324 -152
  95. package/src/parse-index.js +3 -0
  96. package/src/parse-markdown.js +3 -1
  97. package/src/parse-task.js +28 -1
  98. package/src/utility.js +26 -1
  99. /package/example/{.kanbn → basic/.kanbn}/index.md +0 -0
  100. /package/example/{.kanbn → basic/.kanbn}/tasks/add-basic-activity-feed.md +0 -0
  101. /package/example/{.kanbn → basic/.kanbn}/tasks/add-passwordless-login-option.md +0 -0
  102. /package/example/{.kanbn → basic/.kanbn}/tasks/add-usage-alert-email-thresholds.md +0 -0
  103. /package/example/{.kanbn → basic/.kanbn}/tasks/build-email-template-system.md +0 -0
  104. /package/example/{.kanbn → basic/.kanbn}/tasks/build-invoice-download-endpoint.md +0 -0
  105. /package/example/{.kanbn → basic/.kanbn}/tasks/build-tenant-settings-page.md +0 -0
  106. /package/example/{.kanbn → basic/.kanbn}/tasks/create-organization-switcher.md +0 -0
  107. /package/example/{.kanbn → basic/.kanbn}/tasks/create-sandbox-environment-provisioner.md +0 -0
  108. /package/example/{.kanbn → basic/.kanbn}/tasks/create-self-serve-cancellation-flow.md +0 -0
  109. /package/example/{.kanbn → basic/.kanbn}/tasks/define-product-pricing-strategy.md +0 -0
  110. /package/example/{.kanbn → basic/.kanbn}/tasks/design-onboarding-checklist.md +0 -0
  111. /package/example/{.kanbn → basic/.kanbn}/tasks/design-team-invite-expiry-flow.md +0 -0
  112. /package/example/{.kanbn → basic/.kanbn}/tasks/implement-data-retention-policy-jobs.md +0 -0
  113. /package/example/{.kanbn → basic/.kanbn}/tasks/implement-feature-flags-foundation.md +0 -0
  114. /package/example/{.kanbn → basic/.kanbn}/tasks/implement-project-creation-wizard.md +0 -0
  115. /package/example/{.kanbn → basic/.kanbn}/tasks/implement-stripe-webhook-signature-check.md +0 -0
  116. /package/example/{.kanbn → basic/.kanbn}/tasks/implement-team-permissions-ui.md +0 -0
  117. /package/example/{.kanbn → basic/.kanbn}/tasks/implement-user-signup-and-login.md +0 -0
  118. /package/example/{.kanbn → basic/.kanbn}/tasks/integrate-crm-lead-sync.md +0 -0
  119. /package/example/{.kanbn → basic/.kanbn}/tasks/legal-review-terms-and-privacy.md +0 -0
  120. /package/example/{.kanbn → basic/.kanbn}/tasks/migrate-legacy-events-to-new-schema.md +0 -0
  121. /package/example/{.kanbn → basic/.kanbn}/tasks/optimize-dashboard-first-load.md +0 -0
  122. /package/example/{.kanbn → basic/.kanbn}/tasks/prototype-report-export-scheduler.md +0 -0
  123. /package/example/{.kanbn → basic/.kanbn}/tasks/publish-internal-qa-checklist.md +0 -0
  124. /package/example/{.kanbn → basic/.kanbn}/tasks/setup-ci-pipeline.md +0 -0
@@ -0,0 +1,1063 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for kanbn/src/parse-index.js</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">kanbn/src</a> parse-index.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">98.77% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>322/326</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">94.33% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>50/53</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'>4/4</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">98.77% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>322/326</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></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
393
+ <span class="cline-any cline-yes">1x</span>
394
+ <span class="cline-any cline-yes">1x</span>
395
+ <span class="cline-any cline-yes">1x</span>
396
+ <span class="cline-any cline-yes">1x</span>
397
+ <span class="cline-any cline-yes">1x</span>
398
+ <span class="cline-any cline-yes">1x</span>
399
+ <span class="cline-any cline-yes">1x</span>
400
+ <span class="cline-any cline-yes">1x</span>
401
+ <span class="cline-any cline-yes">1x</span>
402
+ <span class="cline-any cline-yes">587x</span>
403
+ <span class="cline-any cline-yes">587x</span>
404
+ <span class="cline-any cline-yes">587x</span>
405
+ <span class="cline-any cline-yes">587x</span>
406
+ <span class="cline-any cline-yes">587x</span>
407
+ <span class="cline-any cline-yes">587x</span>
408
+ <span class="cline-any cline-yes">587x</span>
409
+ <span class="cline-any cline-yes">587x</span>
410
+ <span class="cline-any cline-yes">587x</span>
411
+ <span class="cline-any cline-yes">587x</span>
412
+ <span class="cline-any cline-yes">587x</span>
413
+ <span class="cline-any cline-yes">587x</span>
414
+ <span class="cline-any cline-yes">587x</span>
415
+ <span class="cline-any cline-yes">587x</span>
416
+ <span class="cline-any cline-yes">587x</span>
417
+ <span class="cline-any cline-yes">587x</span>
418
+ <span class="cline-any cline-yes">587x</span>
419
+ <span class="cline-any cline-yes">587x</span>
420
+ <span class="cline-any cline-yes">587x</span>
421
+ <span class="cline-any cline-yes">587x</span>
422
+ <span class="cline-any cline-yes">587x</span>
423
+ <span class="cline-any cline-yes">587x</span>
424
+ <span class="cline-any cline-yes">587x</span>
425
+ <span class="cline-any cline-yes">587x</span>
426
+ <span class="cline-any cline-yes">587x</span>
427
+ <span class="cline-any cline-yes">587x</span>
428
+ <span class="cline-any cline-yes">587x</span>
429
+ <span class="cline-any cline-yes">587x</span>
430
+ <span class="cline-any cline-yes">587x</span>
431
+ <span class="cline-any cline-yes">587x</span>
432
+ <span class="cline-any cline-yes">587x</span>
433
+ <span class="cline-any cline-yes">587x</span>
434
+ <span class="cline-any cline-yes">587x</span>
435
+ <span class="cline-any cline-yes">587x</span>
436
+ <span class="cline-any cline-yes">587x</span>
437
+ <span class="cline-any cline-yes">587x</span>
438
+ <span class="cline-any cline-yes">587x</span>
439
+ <span class="cline-any cline-yes">587x</span>
440
+ <span class="cline-any cline-yes">587x</span>
441
+ <span class="cline-any cline-yes">587x</span>
442
+ <span class="cline-any cline-yes">587x</span>
443
+ <span class="cline-any cline-yes">587x</span>
444
+ <span class="cline-any cline-yes">587x</span>
445
+ <span class="cline-any cline-yes">587x</span>
446
+ <span class="cline-any cline-yes">587x</span>
447
+ <span class="cline-any cline-yes">587x</span>
448
+ <span class="cline-any cline-yes">587x</span>
449
+ <span class="cline-any cline-yes">587x</span>
450
+ <span class="cline-any cline-yes">587x</span>
451
+ <span class="cline-any cline-yes">587x</span>
452
+ <span class="cline-any cline-yes">587x</span>
453
+ <span class="cline-any cline-yes">587x</span>
454
+ <span class="cline-any cline-yes">587x</span>
455
+ <span class="cline-any cline-yes">587x</span>
456
+ <span class="cline-any cline-yes">587x</span>
457
+ <span class="cline-any cline-yes">587x</span>
458
+ <span class="cline-any cline-yes">587x</span>
459
+ <span class="cline-any cline-yes">587x</span>
460
+ <span class="cline-any cline-yes">587x</span>
461
+ <span class="cline-any cline-yes">587x</span>
462
+ <span class="cline-any cline-yes">587x</span>
463
+ <span class="cline-any cline-yes">587x</span>
464
+ <span class="cline-any cline-yes">587x</span>
465
+ <span class="cline-any cline-yes">587x</span>
466
+ <span class="cline-any cline-yes">587x</span>
467
+ <span class="cline-any cline-yes">587x</span>
468
+ <span class="cline-any cline-yes">587x</span>
469
+ <span class="cline-any cline-yes">587x</span>
470
+ <span class="cline-any cline-yes">587x</span>
471
+ <span class="cline-any cline-yes">587x</span>
472
+ <span class="cline-any cline-yes">587x</span>
473
+ <span class="cline-any cline-yes">587x</span>
474
+ <span class="cline-any cline-yes">587x</span>
475
+ <span class="cline-any cline-yes">587x</span>
476
+ <span class="cline-any cline-yes">587x</span>
477
+ <span class="cline-any cline-yes">587x</span>
478
+ <span class="cline-any cline-yes">587x</span>
479
+ <span class="cline-any cline-yes">587x</span>
480
+ <span class="cline-any cline-yes">587x</span>
481
+ <span class="cline-any cline-yes">587x</span>
482
+ <span class="cline-any cline-yes">587x</span>
483
+ <span class="cline-any cline-yes">587x</span>
484
+ <span class="cline-any cline-yes">587x</span>
485
+ <span class="cline-any cline-yes">587x</span>
486
+ <span class="cline-any cline-yes">587x</span>
487
+ <span class="cline-any cline-yes">587x</span>
488
+ <span class="cline-any cline-yes">587x</span>
489
+ <span class="cline-any cline-yes">587x</span>
490
+ <span class="cline-any cline-yes">587x</span>
491
+ <span class="cline-any cline-yes">587x</span>
492
+ <span class="cline-any cline-yes">587x</span>
493
+ <span class="cline-any cline-yes">587x</span>
494
+ <span class="cline-any cline-yes">587x</span>
495
+ <span class="cline-any cline-yes">587x</span>
496
+ <span class="cline-any cline-yes">587x</span>
497
+ <span class="cline-any cline-yes">587x</span>
498
+ <span class="cline-any cline-yes">587x</span>
499
+ <span class="cline-any cline-yes">587x</span>
500
+ <span class="cline-any cline-yes">587x</span>
501
+ <span class="cline-any cline-yes">587x</span>
502
+ <span class="cline-any cline-yes">587x</span>
503
+ <span class="cline-any cline-yes">587x</span>
504
+ <span class="cline-any cline-yes">587x</span>
505
+ <span class="cline-any cline-yes">587x</span>
506
+ <span class="cline-any cline-yes">587x</span>
507
+ <span class="cline-any cline-yes">587x</span>
508
+ <span class="cline-any cline-yes">587x</span>
509
+ <span class="cline-any cline-yes">587x</span>
510
+ <span class="cline-any cline-yes">587x</span>
511
+ <span class="cline-any cline-yes">587x</span>
512
+ <span class="cline-any cline-yes">587x</span>
513
+ <span class="cline-any cline-yes">587x</span>
514
+ <span class="cline-any cline-yes">587x</span>
515
+ <span class="cline-any cline-yes">587x</span>
516
+ <span class="cline-any cline-yes">587x</span>
517
+ <span class="cline-any cline-yes">587x</span>
518
+ <span class="cline-any cline-yes">587x</span>
519
+ <span class="cline-any cline-yes">587x</span>
520
+ <span class="cline-any cline-yes">587x</span>
521
+ <span class="cline-any cline-yes">587x</span>
522
+ <span class="cline-any cline-yes">587x</span>
523
+ <span class="cline-any cline-yes">587x</span>
524
+ <span class="cline-any cline-yes">587x</span>
525
+ <span class="cline-any cline-yes">587x</span>
526
+ <span class="cline-any cline-yes">587x</span>
527
+ <span class="cline-any cline-yes">587x</span>
528
+ <span class="cline-any cline-yes">587x</span>
529
+ <span class="cline-any cline-yes">587x</span>
530
+ <span class="cline-any cline-yes">587x</span>
531
+ <span class="cline-any cline-yes">587x</span>
532
+ <span class="cline-any cline-yes">587x</span>
533
+ <span class="cline-any cline-yes">587x</span>
534
+ <span class="cline-any cline-yes">587x</span>
535
+ <span class="cline-any cline-yes">587x</span>
536
+ <span class="cline-any cline-yes">587x</span>
537
+ <span class="cline-any cline-yes">587x</span>
538
+ <span class="cline-any cline-yes">587x</span>
539
+ <span class="cline-any cline-yes">587x</span>
540
+ <span class="cline-any cline-yes">587x</span>
541
+ <span class="cline-any cline-yes">587x</span>
542
+ <span class="cline-any cline-yes">587x</span>
543
+ <span class="cline-any cline-yes">587x</span>
544
+ <span class="cline-any cline-yes">587x</span>
545
+ <span class="cline-any cline-yes">587x</span>
546
+ <span class="cline-any cline-yes">587x</span>
547
+ <span class="cline-any cline-yes">1x</span>
548
+ <span class="cline-any cline-yes">1x</span>
549
+ <span class="cline-any cline-yes">587x</span>
550
+ <span class="cline-any cline-yes">1x</span>
551
+ <span class="cline-any cline-yes">1x</span>
552
+ <span class="cline-any cline-yes">1x</span>
553
+ <span class="cline-any cline-yes">1x</span>
554
+ <span class="cline-any cline-yes">1x</span>
555
+ <span class="cline-any cline-yes">274x</span>
556
+ <span class="cline-any cline-yes">274x</span>
557
+ <span class="cline-any cline-yes">274x</span>
558
+ <span class="cline-any cline-yes">274x</span>
559
+ <span class="cline-any cline-yes">274x</span>
560
+ <span class="cline-any cline-yes">274x</span>
561
+ <span class="cline-any cline-yes">274x</span>
562
+ <span class="cline-any cline-yes">274x</span>
563
+ <span class="cline-any cline-yes">274x</span>
564
+ <span class="cline-any cline-yes">274x</span>
565
+ <span class="cline-any cline-yes">274x</span>
566
+ <span class="cline-any cline-no">&nbsp;</span>
567
+ <span class="cline-any cline-no">&nbsp;</span>
568
+ <span class="cline-any cline-yes">274x</span>
569
+ <span class="cline-any cline-yes">1x</span>
570
+ <span class="cline-any cline-yes">1x</span>
571
+ <span class="cline-any cline-yes">1x</span>
572
+ <span class="cline-any cline-yes">1x</span>
573
+ <span class="cline-any cline-yes">1x</span>
574
+ <span class="cline-any cline-yes">1x</span>
575
+ <span class="cline-any cline-yes">1x</span>
576
+ <span class="cline-any cline-yes">1x</span>
577
+ <span class="cline-any cline-yes">1x</span>
578
+ <span class="cline-any cline-yes">390x</span>
579
+ <span class="cline-any cline-yes">390x</span>
580
+ <span class="cline-any cline-yes">390x</span>
581
+ <span class="cline-any cline-yes">390x</span>
582
+ <span class="cline-any cline-yes">390x</span>
583
+ <span class="cline-any cline-yes">4x</span>
584
+ <span class="cline-any cline-yes">4x</span>
585
+ <span class="cline-any cline-yes">390x</span>
586
+ <span class="cline-any cline-yes">2x</span>
587
+ <span class="cline-any cline-yes">2x</span>
588
+ <span class="cline-any cline-yes">384x</span>
589
+ <span class="cline-any cline-yes">384x</span>
590
+ <span class="cline-any cline-yes">390x</span>
591
+ <span class="cline-any cline-yes">242x</span>
592
+ <span class="cline-any cline-yes">242x</span>
593
+ <span class="cline-any cline-yes">242x</span>
594
+ <span class="cline-any cline-yes">242x</span>
595
+ <span class="cline-any cline-yes">1x</span>
596
+ <span class="cline-any cline-yes">1x</span>
597
+ <span class="cline-any cline-yes">242x</span>
598
+ <span class="cline-any cline-yes">383x</span>
599
+ <span class="cline-any cline-yes">383x</span>
600
+ <span class="cline-any cline-yes">383x</span>
601
+ <span class="cline-any cline-yes">383x</span>
602
+ <span class="cline-any cline-yes">383x</span>
603
+ <span class="cline-any cline-yes">390x</span>
604
+ <span class="cline-any cline-yes">1x</span>
605
+ <span class="cline-any cline-yes">1x</span>
606
+ <span class="cline-any cline-yes">382x</span>
607
+ <span class="cline-any cline-yes">382x</span>
608
+ <span class="cline-any cline-yes">382x</span>
609
+ <span class="cline-any cline-yes">390x</span>
610
+ <span class="cline-any cline-yes">4x</span>
611
+ <span class="cline-any cline-yes">4x</span>
612
+ <span class="cline-any cline-yes">378x</span>
613
+ <span class="cline-any cline-yes">378x</span>
614
+ <span class="cline-any cline-yes">378x</span>
615
+ <span class="cline-any cline-yes">378x</span>
616
+ <span class="cline-any cline-yes">378x</span>
617
+ <span class="cline-any cline-yes">390x</span>
618
+ <span class="cline-any cline-yes">390x</span>
619
+ <span class="cline-any cline-yes">390x</span>
620
+ <span class="cline-any cline-yes">390x</span>
621
+ <span class="cline-any cline-yes">390x</span>
622
+ <span class="cline-any cline-yes">8x</span>
623
+ <span class="cline-any cline-yes">8x</span>
624
+ <span class="cline-any cline-yes">8x</span>
625
+ <span class="cline-any cline-yes">8x</span>
626
+ <span class="cline-any cline-yes">3x</span>
627
+ <span class="cline-any cline-yes">3x</span>
628
+ <span class="cline-any cline-yes">5x</span>
629
+ <span class="cline-any cline-yes">5x</span>
630
+ <span class="cline-any cline-yes">5x</span>
631
+ <span class="cline-any cline-yes">5x</span>
632
+ <span class="cline-any cline-yes">375x</span>
633
+ <span class="cline-any cline-yes">375x</span>
634
+ <span class="cline-any cline-yes">375x</span>
635
+ <span class="cline-any cline-yes">375x</span>
636
+ <span class="cline-any cline-yes">390x</span>
637
+ <span class="cline-any cline-yes">368x</span>
638
+ <span class="cline-any cline-yes">991x</span>
639
+ <span class="cline-any cline-yes">991x</span>
640
+ <span class="cline-any cline-yes">991x</span>
641
+ <span class="cline-any cline-yes">991x</span>
642
+ <span class="cline-any cline-yes">991x</span>
643
+ <span class="cline-any cline-yes">991x</span>
644
+ <span class="cline-any cline-yes">991x</span>
645
+ <span class="cline-any cline-yes">991x</span>
646
+ <span class="cline-any cline-yes">1x</span>
647
+ <span class="cline-any cline-yes">1x</span>
648
+ <span class="cline-any cline-yes">368x</span>
649
+ <span class="cline-any cline-yes">368x</span>
650
+ <span class="cline-any cline-yes">390x</span>
651
+ <span class="cline-any cline-yes">17x</span>
652
+ <span class="cline-any cline-yes">17x</span>
653
+ <span class="cline-any cline-yes">373x</span>
654
+ <span class="cline-any cline-yes">373x</span>
655
+ <span class="cline-any cline-yes">373x</span>
656
+ <span class="cline-any cline-yes">1x</span>
657
+ <span class="cline-any cline-yes">1x</span>
658
+ <span class="cline-any cline-yes">1x</span>
659
+ <span class="cline-any cline-yes">1x</span>
660
+ <span class="cline-any cline-yes">1x</span>
661
+ <span class="cline-any cline-yes">1x</span>
662
+ <span class="cline-any cline-yes">1x</span>
663
+ <span class="cline-any cline-yes">1x</span>
664
+ <span class="cline-any cline-yes">1x</span>
665
+ <span class="cline-any cline-yes">277x</span>
666
+ <span class="cline-any cline-yes">277x</span>
667
+ <span class="cline-any cline-yes">277x</span>
668
+ <span class="cline-any cline-yes">277x</span>
669
+ <span class="cline-any cline-yes">277x</span>
670
+ <span class="cline-any cline-yes">1x</span>
671
+ <span class="cline-any cline-yes">1x</span>
672
+ <span class="cline-any cline-yes">277x</span>
673
+ <span class="cline-any cline-yes">1x</span>
674
+ <span class="cline-any cline-yes">1x</span>
675
+ <span class="cline-any cline-yes">275x</span>
676
+ <span class="cline-any cline-yes">275x</span>
677
+ <span class="cline-any cline-yes">277x</span>
678
+ <span class="cline-any cline-yes">1x</span>
679
+ <span class="cline-any cline-yes">1x</span>
680
+ <span class="cline-any cline-yes">274x</span>
681
+ <span class="cline-any cline-yes">274x</span>
682
+ <span class="cline-any cline-yes">277x</span>
683
+ <span class="cline-any cline-yes">212x</span>
684
+ <span class="cline-any cline-yes">212x</span>
685
+ <span class="cline-any cline-yes">170x</span>
686
+ <span class="cline-any cline-yes">170x</span>
687
+ <span class="cline-any cline-yes">170x</span>
688
+ <span class="cline-any cline-yes">170x</span>
689
+ <span class="cline-any cline-yes">212x</span>
690
+ <span class="cline-any cline-yes">274x</span>
691
+ <span class="cline-any cline-yes">274x</span>
692
+ <span class="cline-any cline-yes">274x</span>
693
+ <span class="cline-any cline-yes">274x</span>
694
+ <span class="cline-any cline-yes">274x</span>
695
+ <span class="cline-any cline-yes">274x</span>
696
+ <span class="cline-any cline-yes">274x</span>
697
+ <span class="cline-any cline-yes">274x</span>
698
+ <span class="cline-any cline-yes">277x</span>
699
+ <span class="cline-any cline-no">&nbsp;</span>
700
+ <span class="cline-any cline-no">&nbsp;</span>
701
+ <span class="cline-any cline-yes">274x</span>
702
+ <span class="cline-any cline-yes">274x</span>
703
+ <span class="cline-any cline-yes">274x</span>
704
+ <span class="cline-any cline-yes">277x</span>
705
+ <span class="cline-any cline-yes">751x</span>
706
+ <span class="cline-any cline-yes">751x</span>
707
+ <span class="cline-any cline-yes">751x</span>
708
+ <span class="cline-any cline-yes">751x</span>
709
+ <span class="cline-any cline-yes">751x</span>
710
+ <span class="cline-any cline-yes">277x</span>
711
+ <span class="cline-any cline-yes">3x</span>
712
+ <span class="cline-any cline-yes">3x</span>
713
+ <span class="cline-any cline-yes">274x</span>
714
+ <span class="cline-any cline-yes">274x</span>
715
+ <span class="cline-any cline-yes">274x</span>
716
+ <span class="cline-any cline-yes">277x</span>
717
+ <span class="cline-any cline-yes">1x</span>
718
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const yaml = require('yamljs');
719
+ const fm = require('front-matter');
720
+ const marked = require('marked');
721
+ const validate = require('jsonschema').validate;
722
+ const parseMarkdown = require('./parse-markdown');
723
+ &nbsp;
724
+ /**
725
+ * Validate the options object
726
+ * @param {object} options
727
+ */
728
+ function validateOptions(options) {
729
+ const result = validate(options, {
730
+ type: 'object',
731
+ properties: {
732
+ 'hiddenColumns': {
733
+ type: 'array',
734
+ items: { type: 'string' }
735
+ },
736
+ 'startedColumns': {
737
+ type: 'array',
738
+ items: { type: 'string' }
739
+ },
740
+ 'completedColumns': {
741
+ type: 'array',
742
+ items: { type: 'string' }
743
+ },
744
+ 'startedField': { type: 'string' },
745
+ 'completedField': { type: 'string' },
746
+ 'verbose': { type: 'boolean' },
747
+ 'sprints': {
748
+ type: 'array',
749
+ items: {
750
+ type: 'object',
751
+ properties: {
752
+ 'start': { type: 'date' },
753
+ 'name': { type: 'string' },
754
+ 'description': { type: 'string' }
755
+ },
756
+ required: ['start', 'name']
757
+ }
758
+ },
759
+ 'defaultTaskWorkload': { type: 'number' },
760
+ 'taskWorkloadTags': {
761
+ type: 'object',
762
+ patternProperties: {
763
+ '^[\w ]+$': { type: 'number' }
764
+ }
765
+ },
766
+ 'columnSorting': {
767
+ type: 'object',
768
+ patternProperties: {
769
+ '^[\w ]+$': {
770
+ type: 'array',
771
+ items: {
772
+ type: 'object',
773
+ properties: {
774
+ 'field': { type: 'string' },
775
+ 'filter': { type: 'string' },
776
+ 'order': {
777
+ type: 'string',
778
+ enum: [
779
+ 'ascending',
780
+ 'descending'
781
+ ]
782
+ }
783
+ },
784
+ required: ['field']
785
+ }
786
+ }
787
+ }
788
+ },
789
+ 'taskTemplate': { type: 'string' },
790
+ 'dateFormat': { type: 'string' },
791
+ 'customFields': {
792
+ type: 'array',
793
+ items: {
794
+ type: 'object',
795
+ properties: {
796
+ 'name': { type: 'string' },
797
+ 'type': {
798
+ type: 'string',
799
+ enum: [
800
+ 'boolean',
801
+ 'string',
802
+ 'number',
803
+ 'date'
804
+ ]
805
+ },
806
+ 'updateDate': {
807
+ type: 'string',
808
+ enum: [
809
+ 'always',
810
+ 'once',
811
+ 'none'
812
+ ]
813
+ }
814
+ },
815
+ required: ['name', 'type']
816
+ }
817
+ },
818
+ 'views': {
819
+ type: 'array',
820
+ items: {
821
+ type: 'object',
822
+ properties: {
823
+ 'name': { type: 'string' },
824
+ 'filters': { type: 'object' },
825
+ 'columns': {
826
+ type: 'array',
827
+ items: {
828
+ type: 'object',
829
+ properties: {
830
+ 'name': { type: 'string' },
831
+ 'filters': { type: 'object' },
832
+ 'sorters': {
833
+ type: 'array',
834
+ items: {
835
+ type: 'object',
836
+ properties: {
837
+ 'field': { type: 'string' },
838
+ 'filter': { type: 'string' },
839
+ 'order': {
840
+ type: 'string',
841
+ enum: [
842
+ 'ascending',
843
+ 'descending'
844
+ ]
845
+ }
846
+ },
847
+ required: ['field']
848
+ }
849
+ }
850
+ },
851
+ required: ['name']
852
+ },
853
+ minItems: 1
854
+ },
855
+ 'lanes': {
856
+ type: 'array',
857
+ items: {
858
+ type: 'object',
859
+ properties: {
860
+ 'name': { type: 'string' },
861
+ 'filters': { type: 'object' }
862
+ },
863
+ required: ['name']
864
+ }
865
+ }
866
+ },
867
+ required: ['name']
868
+ }
869
+ }
870
+ }
871
+ });
872
+ if (result.errors.length) {
873
+ throw new Error(result.errors.map(error =&gt; `\n${error.property} ${error.message}`).join(''));
874
+ }
875
+ }
876
+ &nbsp;
877
+ /**
878
+ * Validate the columns object
879
+ * @param {object} columns
880
+ */
881
+ function validateColumns(columns) {
882
+ const result = validate(columns, {
883
+ type: 'object',
884
+ patternProperties: {
885
+ '^[\w ]+$': {
886
+ type: 'array',
887
+ items: { type: 'string' }
888
+ }
889
+ }
890
+ });
891
+ if (result.errors.length) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
892
+ <span class="cstat-no" title="statement not covered" > throw new Error(result.errors.map(error =&gt; `${error.property} ${error.message}`).join('\n'));</span>
893
+ <span class="cstat-no" title="statement not covered" > }</span>
894
+ }
895
+ &nbsp;
896
+ module.exports = {
897
+ &nbsp;
898
+ /**
899
+ * Convert markdown into an index object
900
+ * @param {string} data
901
+ * @return {object}
902
+ */
903
+ md2json(data) {
904
+ let name = '', description = '', options = {}, columns = {};
905
+ try {
906
+ &nbsp;
907
+ // Check data type
908
+ if (!data) {
909
+ throw new Error('data is null or empty');
910
+ }
911
+ if (typeof data !== 'string') {
912
+ throw new Error('data is not a string');
913
+ }
914
+ &nbsp;
915
+ // Get YAML front matter if any exists
916
+ if (fm.test(data)) {
917
+ ({ attributes: options, body: data } = fm(data));
918
+ &nbsp;
919
+ // Make sure the front matter contains an object
920
+ if (typeof options !== 'object') {
921
+ throw new Error('invalid front matter content');
922
+ }
923
+ }
924
+ &nbsp;
925
+ // Parse markdown to an object
926
+ let index = null;
927
+ try {
928
+ index = parseMarkdown(data);
929
+ } catch (error) {
930
+ throw new Error(`invalid markdown (${error.message})`);
931
+ }
932
+ &nbsp;
933
+ // Check resulting object
934
+ const indexHeadings = Object.keys(index);
935
+ if (indexHeadings.length === 0 || indexHeadings[0] === 'raw') {
936
+ throw new Error('data is missing a name heading');
937
+ }
938
+ &nbsp;
939
+ // Get name
940
+ name = indexHeadings[0];
941
+ &nbsp;
942
+ // Get description
943
+ description = name in index ? index[name].content.trim() <span class="branch-0 cbranch-no" title="branch not covered" >: '';</span>
944
+ &nbsp;
945
+ // Parse options
946
+ // Options will be serialized back to front-matter, this check remains here for backwards-compatibility
947
+ if ('Options' in index) {
948
+ &nbsp;
949
+ // Get embedded options and make sure it's an object
950
+ const embeddedOptions = yaml.parse(index['Options'].content.trim().replace(/```(yaml|yml)?/g, ''));
951
+ if (typeof embeddedOptions !== 'object') {
952
+ throw new Error('invalid options content');
953
+ }
954
+ &nbsp;
955
+ // Merge with front matter options
956
+ options = Object.assign(options, embeddedOptions);
957
+ }
958
+ validateOptions(options);
959
+ &nbsp;
960
+ // Parse columns
961
+ const columnNames = Object.keys(index).filter(column =&gt; ['raw', 'Options', name].indexOf(column) === -1);
962
+ if (columnNames.length) {
963
+ columns = Object.fromEntries(columnNames.map(columnName =&gt; {
964
+ try {
965
+ return [
966
+ columnName,
967
+ index[columnName].content
968
+ ? marked.lexer(index[columnName].content)[0].items.map(item =&gt; item.tokens[0].tokens[0].text)
969
+ : []
970
+ ];
971
+ } catch (error) {
972
+ throw new Error(`column "${columnName}" must contain a list`);
973
+ }
974
+ }));
975
+ }
976
+ } catch (error) {
977
+ throw new Error(`Unable to parse index: ${error.message}`);
978
+ }
979
+ &nbsp;
980
+ // Assemble index object
981
+ return { name, description, options, columns };
982
+ },
983
+ &nbsp;
984
+ /**
985
+ * Convert an index object into markdown
986
+ * @param {object} data
987
+ * @param {boolean} [ignoreOptions=false]
988
+ * @return {string}
989
+ */
990
+ json2md(data, ignoreOptions = false) {
991
+ const result = [];
992
+ try {
993
+ &nbsp;
994
+ // Check data type
995
+ if (!data) {
996
+ throw new Error('data is null or empty');
997
+ }
998
+ if (typeof data !== 'object') {
999
+ throw new Error('data is not an object');
1000
+ }
1001
+ &nbsp;
1002
+ // Check required fields
1003
+ if (!('name' in data)) {
1004
+ throw new Error('data object is missing name');
1005
+ }
1006
+ &nbsp;
1007
+ // Add options as front-matter content if present and not ignoring
1008
+ if ('options' in data &amp;&amp; data.options !== null &amp;&amp; !ignoreOptions) {
1009
+ validateOptions(data.options);
1010
+ if (Object.keys(data.options).length) {
1011
+ result.push(
1012
+ `---\n${yaml.stringify(data.options, 4, 2).trim()}\n---`
1013
+ );
1014
+ }
1015
+ }
1016
+ &nbsp;
1017
+ // Add name and description
1018
+ result.push(`# ${data.name}`);
1019
+ if ('description' in data) {
1020
+ result.push(data.description);
1021
+ }
1022
+ &nbsp;
1023
+ // Check columns
1024
+ if (!('columns' in data)) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1025
+ <span class="cstat-no" title="statement not covered" > throw new Error('data object is missing columns');</span>
1026
+ <span class="cstat-no" title="statement not covered" > }</span>
1027
+ validateColumns(data.columns);
1028
+ &nbsp;
1029
+ // Add columns
1030
+ for (let column in data.columns) {
1031
+ result.push(
1032
+ `## ${column}`,
1033
+ data.columns[column].map(task =&gt; `- [${task}](tasks/${task}.md)`).join('\n')
1034
+ );
1035
+ }
1036
+ } catch (error) {
1037
+ throw new Error(`Unable to build index: ${error.message}`);
1038
+ }
1039
+ &nbsp;
1040
+ // Filter empty lines and join into a string
1041
+ return `${result.filter(l =&gt; !!l).join('\n\n')}\n`;
1042
+ }
1043
+ };
1044
+ &nbsp;</pre></td></tr></table></pre>
1045
+
1046
+ <div class='push'></div><!-- for sticky footer -->
1047
+ </div><!-- /wrapper -->
1048
+ <div class='footer quiet pad2 space-top1 center small'>
1049
+ Code coverage generated by
1050
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1051
+ at 2026-08-26T20:46:31.702Z
1052
+ </div>
1053
+ <script src="../../prettify.js"></script>
1054
+ <script>
1055
+ window.onload = function () {
1056
+ prettyPrint();
1057
+ };
1058
+ </script>
1059
+ <script src="../../sorter.js"></script>
1060
+ <script src="../../block-navigation.js"></script>
1061
+ </body>
1062
+ </html>
1063
+