@featurevisor/sdk 0.36.0 → 0.38.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.
- package/CHANGELOG.md +22 -0
- package/README.md +14 -14
- package/coverage/clover.xml +378 -315
- package/coverage/coverage-final.json +7 -7
- package/coverage/lcov-report/bucket.ts.html +4 -4
- package/coverage/lcov-report/conditions.ts.html +38 -38
- package/coverage/lcov-report/datafileReader.ts.html +4 -4
- package/coverage/lcov-report/emitter.ts.html +1 -1
- package/coverage/lcov-report/feature.ts.html +80 -20
- package/coverage/lcov-report/index.html +28 -28
- package/coverage/lcov-report/instance.ts.html +754 -220
- package/coverage/lcov-report/logger.ts.html +3 -3
- package/coverage/lcov-report/segments.ts.html +12 -12
- package/coverage/lcov.info +661 -559
- package/dist/index.js +1 -1
- package/dist/index.js.gz +0 -0
- package/dist/index.js.map +1 -1
- package/lib/conditions.d.ts +3 -3
- package/lib/conditions.js +35 -35
- package/lib/conditions.js.map +1 -1
- package/lib/feature.d.ts +4 -3
- package/lib/feature.js +13 -5
- package/lib/feature.js.map +1 -1
- package/lib/instance.d.ts +36 -27
- package/lib/instance.js +289 -148
- package/lib/instance.js.map +1 -1
- package/lib/segments.d.ts +3 -3
- package/lib/segments.js +8 -8
- package/lib/segments.js.map +1 -1
- package/package.json +3 -3
- package/src/conditions.ts +37 -37
- package/src/feature.ts +26 -6
- package/src/instance.spec.ts +64 -61
- package/src/instance.ts +325 -147
- package/src/segments.ts +9 -9
|
@@ -23,30 +23,30 @@
|
|
|
23
23
|
<div class='clearfix'>
|
|
24
24
|
|
|
25
25
|
<div class='fl pad1y space-right2'>
|
|
26
|
-
<span class="strong">50% </span>
|
|
26
|
+
<span class="strong">50.9% </span>
|
|
27
27
|
<span class="quiet">Statements</span>
|
|
28
|
-
<span class='fraction'>
|
|
28
|
+
<span class='fraction'>197/387</span>
|
|
29
29
|
</div>
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<div class='fl pad1y space-right2'>
|
|
33
|
-
<span class="strong">
|
|
33
|
+
<span class="strong">37.43% </span>
|
|
34
34
|
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>
|
|
35
|
+
<span class='fraction'>76/203</span>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
<div class='fl pad1y space-right2'>
|
|
40
|
-
<span class="strong">
|
|
40
|
+
<span class="strong">49.01% </span>
|
|
41
41
|
<span class="quiet">Functions</span>
|
|
42
|
-
<span class='fraction'>
|
|
42
|
+
<span class='fraction'>25/51</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
<div class='fl pad1y space-right2'>
|
|
47
|
-
<span class="strong">
|
|
47
|
+
<span class="strong">51.44% </span>
|
|
48
48
|
<span class="quiet">Lines</span>
|
|
49
|
-
<span class='fraction'>
|
|
49
|
+
<span class='fraction'>196/381</span>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
|
|
@@ -1113,7 +1113,186 @@
|
|
|
1113
1113
|
<a name='L1048'></a><a href='#L1048'>1048</a>
|
|
1114
1114
|
<a name='L1049'></a><a href='#L1049'>1049</a>
|
|
1115
1115
|
<a name='L1050'></a><a href='#L1050'>1050</a>
|
|
1116
|
-
<a name='L1051'></a><a href='#L1051'>1051</a
|
|
1116
|
+
<a name='L1051'></a><a href='#L1051'>1051</a>
|
|
1117
|
+
<a name='L1052'></a><a href='#L1052'>1052</a>
|
|
1118
|
+
<a name='L1053'></a><a href='#L1053'>1053</a>
|
|
1119
|
+
<a name='L1054'></a><a href='#L1054'>1054</a>
|
|
1120
|
+
<a name='L1055'></a><a href='#L1055'>1055</a>
|
|
1121
|
+
<a name='L1056'></a><a href='#L1056'>1056</a>
|
|
1122
|
+
<a name='L1057'></a><a href='#L1057'>1057</a>
|
|
1123
|
+
<a name='L1058'></a><a href='#L1058'>1058</a>
|
|
1124
|
+
<a name='L1059'></a><a href='#L1059'>1059</a>
|
|
1125
|
+
<a name='L1060'></a><a href='#L1060'>1060</a>
|
|
1126
|
+
<a name='L1061'></a><a href='#L1061'>1061</a>
|
|
1127
|
+
<a name='L1062'></a><a href='#L1062'>1062</a>
|
|
1128
|
+
<a name='L1063'></a><a href='#L1063'>1063</a>
|
|
1129
|
+
<a name='L1064'></a><a href='#L1064'>1064</a>
|
|
1130
|
+
<a name='L1065'></a><a href='#L1065'>1065</a>
|
|
1131
|
+
<a name='L1066'></a><a href='#L1066'>1066</a>
|
|
1132
|
+
<a name='L1067'></a><a href='#L1067'>1067</a>
|
|
1133
|
+
<a name='L1068'></a><a href='#L1068'>1068</a>
|
|
1134
|
+
<a name='L1069'></a><a href='#L1069'>1069</a>
|
|
1135
|
+
<a name='L1070'></a><a href='#L1070'>1070</a>
|
|
1136
|
+
<a name='L1071'></a><a href='#L1071'>1071</a>
|
|
1137
|
+
<a name='L1072'></a><a href='#L1072'>1072</a>
|
|
1138
|
+
<a name='L1073'></a><a href='#L1073'>1073</a>
|
|
1139
|
+
<a name='L1074'></a><a href='#L1074'>1074</a>
|
|
1140
|
+
<a name='L1075'></a><a href='#L1075'>1075</a>
|
|
1141
|
+
<a name='L1076'></a><a href='#L1076'>1076</a>
|
|
1142
|
+
<a name='L1077'></a><a href='#L1077'>1077</a>
|
|
1143
|
+
<a name='L1078'></a><a href='#L1078'>1078</a>
|
|
1144
|
+
<a name='L1079'></a><a href='#L1079'>1079</a>
|
|
1145
|
+
<a name='L1080'></a><a href='#L1080'>1080</a>
|
|
1146
|
+
<a name='L1081'></a><a href='#L1081'>1081</a>
|
|
1147
|
+
<a name='L1082'></a><a href='#L1082'>1082</a>
|
|
1148
|
+
<a name='L1083'></a><a href='#L1083'>1083</a>
|
|
1149
|
+
<a name='L1084'></a><a href='#L1084'>1084</a>
|
|
1150
|
+
<a name='L1085'></a><a href='#L1085'>1085</a>
|
|
1151
|
+
<a name='L1086'></a><a href='#L1086'>1086</a>
|
|
1152
|
+
<a name='L1087'></a><a href='#L1087'>1087</a>
|
|
1153
|
+
<a name='L1088'></a><a href='#L1088'>1088</a>
|
|
1154
|
+
<a name='L1089'></a><a href='#L1089'>1089</a>
|
|
1155
|
+
<a name='L1090'></a><a href='#L1090'>1090</a>
|
|
1156
|
+
<a name='L1091'></a><a href='#L1091'>1091</a>
|
|
1157
|
+
<a name='L1092'></a><a href='#L1092'>1092</a>
|
|
1158
|
+
<a name='L1093'></a><a href='#L1093'>1093</a>
|
|
1159
|
+
<a name='L1094'></a><a href='#L1094'>1094</a>
|
|
1160
|
+
<a name='L1095'></a><a href='#L1095'>1095</a>
|
|
1161
|
+
<a name='L1096'></a><a href='#L1096'>1096</a>
|
|
1162
|
+
<a name='L1097'></a><a href='#L1097'>1097</a>
|
|
1163
|
+
<a name='L1098'></a><a href='#L1098'>1098</a>
|
|
1164
|
+
<a name='L1099'></a><a href='#L1099'>1099</a>
|
|
1165
|
+
<a name='L1100'></a><a href='#L1100'>1100</a>
|
|
1166
|
+
<a name='L1101'></a><a href='#L1101'>1101</a>
|
|
1167
|
+
<a name='L1102'></a><a href='#L1102'>1102</a>
|
|
1168
|
+
<a name='L1103'></a><a href='#L1103'>1103</a>
|
|
1169
|
+
<a name='L1104'></a><a href='#L1104'>1104</a>
|
|
1170
|
+
<a name='L1105'></a><a href='#L1105'>1105</a>
|
|
1171
|
+
<a name='L1106'></a><a href='#L1106'>1106</a>
|
|
1172
|
+
<a name='L1107'></a><a href='#L1107'>1107</a>
|
|
1173
|
+
<a name='L1108'></a><a href='#L1108'>1108</a>
|
|
1174
|
+
<a name='L1109'></a><a href='#L1109'>1109</a>
|
|
1175
|
+
<a name='L1110'></a><a href='#L1110'>1110</a>
|
|
1176
|
+
<a name='L1111'></a><a href='#L1111'>1111</a>
|
|
1177
|
+
<a name='L1112'></a><a href='#L1112'>1112</a>
|
|
1178
|
+
<a name='L1113'></a><a href='#L1113'>1113</a>
|
|
1179
|
+
<a name='L1114'></a><a href='#L1114'>1114</a>
|
|
1180
|
+
<a name='L1115'></a><a href='#L1115'>1115</a>
|
|
1181
|
+
<a name='L1116'></a><a href='#L1116'>1116</a>
|
|
1182
|
+
<a name='L1117'></a><a href='#L1117'>1117</a>
|
|
1183
|
+
<a name='L1118'></a><a href='#L1118'>1118</a>
|
|
1184
|
+
<a name='L1119'></a><a href='#L1119'>1119</a>
|
|
1185
|
+
<a name='L1120'></a><a href='#L1120'>1120</a>
|
|
1186
|
+
<a name='L1121'></a><a href='#L1121'>1121</a>
|
|
1187
|
+
<a name='L1122'></a><a href='#L1122'>1122</a>
|
|
1188
|
+
<a name='L1123'></a><a href='#L1123'>1123</a>
|
|
1189
|
+
<a name='L1124'></a><a href='#L1124'>1124</a>
|
|
1190
|
+
<a name='L1125'></a><a href='#L1125'>1125</a>
|
|
1191
|
+
<a name='L1126'></a><a href='#L1126'>1126</a>
|
|
1192
|
+
<a name='L1127'></a><a href='#L1127'>1127</a>
|
|
1193
|
+
<a name='L1128'></a><a href='#L1128'>1128</a>
|
|
1194
|
+
<a name='L1129'></a><a href='#L1129'>1129</a>
|
|
1195
|
+
<a name='L1130'></a><a href='#L1130'>1130</a>
|
|
1196
|
+
<a name='L1131'></a><a href='#L1131'>1131</a>
|
|
1197
|
+
<a name='L1132'></a><a href='#L1132'>1132</a>
|
|
1198
|
+
<a name='L1133'></a><a href='#L1133'>1133</a>
|
|
1199
|
+
<a name='L1134'></a><a href='#L1134'>1134</a>
|
|
1200
|
+
<a name='L1135'></a><a href='#L1135'>1135</a>
|
|
1201
|
+
<a name='L1136'></a><a href='#L1136'>1136</a>
|
|
1202
|
+
<a name='L1137'></a><a href='#L1137'>1137</a>
|
|
1203
|
+
<a name='L1138'></a><a href='#L1138'>1138</a>
|
|
1204
|
+
<a name='L1139'></a><a href='#L1139'>1139</a>
|
|
1205
|
+
<a name='L1140'></a><a href='#L1140'>1140</a>
|
|
1206
|
+
<a name='L1141'></a><a href='#L1141'>1141</a>
|
|
1207
|
+
<a name='L1142'></a><a href='#L1142'>1142</a>
|
|
1208
|
+
<a name='L1143'></a><a href='#L1143'>1143</a>
|
|
1209
|
+
<a name='L1144'></a><a href='#L1144'>1144</a>
|
|
1210
|
+
<a name='L1145'></a><a href='#L1145'>1145</a>
|
|
1211
|
+
<a name='L1146'></a><a href='#L1146'>1146</a>
|
|
1212
|
+
<a name='L1147'></a><a href='#L1147'>1147</a>
|
|
1213
|
+
<a name='L1148'></a><a href='#L1148'>1148</a>
|
|
1214
|
+
<a name='L1149'></a><a href='#L1149'>1149</a>
|
|
1215
|
+
<a name='L1150'></a><a href='#L1150'>1150</a>
|
|
1216
|
+
<a name='L1151'></a><a href='#L1151'>1151</a>
|
|
1217
|
+
<a name='L1152'></a><a href='#L1152'>1152</a>
|
|
1218
|
+
<a name='L1153'></a><a href='#L1153'>1153</a>
|
|
1219
|
+
<a name='L1154'></a><a href='#L1154'>1154</a>
|
|
1220
|
+
<a name='L1155'></a><a href='#L1155'>1155</a>
|
|
1221
|
+
<a name='L1156'></a><a href='#L1156'>1156</a>
|
|
1222
|
+
<a name='L1157'></a><a href='#L1157'>1157</a>
|
|
1223
|
+
<a name='L1158'></a><a href='#L1158'>1158</a>
|
|
1224
|
+
<a name='L1159'></a><a href='#L1159'>1159</a>
|
|
1225
|
+
<a name='L1160'></a><a href='#L1160'>1160</a>
|
|
1226
|
+
<a name='L1161'></a><a href='#L1161'>1161</a>
|
|
1227
|
+
<a name='L1162'></a><a href='#L1162'>1162</a>
|
|
1228
|
+
<a name='L1163'></a><a href='#L1163'>1163</a>
|
|
1229
|
+
<a name='L1164'></a><a href='#L1164'>1164</a>
|
|
1230
|
+
<a name='L1165'></a><a href='#L1165'>1165</a>
|
|
1231
|
+
<a name='L1166'></a><a href='#L1166'>1166</a>
|
|
1232
|
+
<a name='L1167'></a><a href='#L1167'>1167</a>
|
|
1233
|
+
<a name='L1168'></a><a href='#L1168'>1168</a>
|
|
1234
|
+
<a name='L1169'></a><a href='#L1169'>1169</a>
|
|
1235
|
+
<a name='L1170'></a><a href='#L1170'>1170</a>
|
|
1236
|
+
<a name='L1171'></a><a href='#L1171'>1171</a>
|
|
1237
|
+
<a name='L1172'></a><a href='#L1172'>1172</a>
|
|
1238
|
+
<a name='L1173'></a><a href='#L1173'>1173</a>
|
|
1239
|
+
<a name='L1174'></a><a href='#L1174'>1174</a>
|
|
1240
|
+
<a name='L1175'></a><a href='#L1175'>1175</a>
|
|
1241
|
+
<a name='L1176'></a><a href='#L1176'>1176</a>
|
|
1242
|
+
<a name='L1177'></a><a href='#L1177'>1177</a>
|
|
1243
|
+
<a name='L1178'></a><a href='#L1178'>1178</a>
|
|
1244
|
+
<a name='L1179'></a><a href='#L1179'>1179</a>
|
|
1245
|
+
<a name='L1180'></a><a href='#L1180'>1180</a>
|
|
1246
|
+
<a name='L1181'></a><a href='#L1181'>1181</a>
|
|
1247
|
+
<a name='L1182'></a><a href='#L1182'>1182</a>
|
|
1248
|
+
<a name='L1183'></a><a href='#L1183'>1183</a>
|
|
1249
|
+
<a name='L1184'></a><a href='#L1184'>1184</a>
|
|
1250
|
+
<a name='L1185'></a><a href='#L1185'>1185</a>
|
|
1251
|
+
<a name='L1186'></a><a href='#L1186'>1186</a>
|
|
1252
|
+
<a name='L1187'></a><a href='#L1187'>1187</a>
|
|
1253
|
+
<a name='L1188'></a><a href='#L1188'>1188</a>
|
|
1254
|
+
<a name='L1189'></a><a href='#L1189'>1189</a>
|
|
1255
|
+
<a name='L1190'></a><a href='#L1190'>1190</a>
|
|
1256
|
+
<a name='L1191'></a><a href='#L1191'>1191</a>
|
|
1257
|
+
<a name='L1192'></a><a href='#L1192'>1192</a>
|
|
1258
|
+
<a name='L1193'></a><a href='#L1193'>1193</a>
|
|
1259
|
+
<a name='L1194'></a><a href='#L1194'>1194</a>
|
|
1260
|
+
<a name='L1195'></a><a href='#L1195'>1195</a>
|
|
1261
|
+
<a name='L1196'></a><a href='#L1196'>1196</a>
|
|
1262
|
+
<a name='L1197'></a><a href='#L1197'>1197</a>
|
|
1263
|
+
<a name='L1198'></a><a href='#L1198'>1198</a>
|
|
1264
|
+
<a name='L1199'></a><a href='#L1199'>1199</a>
|
|
1265
|
+
<a name='L1200'></a><a href='#L1200'>1200</a>
|
|
1266
|
+
<a name='L1201'></a><a href='#L1201'>1201</a>
|
|
1267
|
+
<a name='L1202'></a><a href='#L1202'>1202</a>
|
|
1268
|
+
<a name='L1203'></a><a href='#L1203'>1203</a>
|
|
1269
|
+
<a name='L1204'></a><a href='#L1204'>1204</a>
|
|
1270
|
+
<a name='L1205'></a><a href='#L1205'>1205</a>
|
|
1271
|
+
<a name='L1206'></a><a href='#L1206'>1206</a>
|
|
1272
|
+
<a name='L1207'></a><a href='#L1207'>1207</a>
|
|
1273
|
+
<a name='L1208'></a><a href='#L1208'>1208</a>
|
|
1274
|
+
<a name='L1209'></a><a href='#L1209'>1209</a>
|
|
1275
|
+
<a name='L1210'></a><a href='#L1210'>1210</a>
|
|
1276
|
+
<a name='L1211'></a><a href='#L1211'>1211</a>
|
|
1277
|
+
<a name='L1212'></a><a href='#L1212'>1212</a>
|
|
1278
|
+
<a name='L1213'></a><a href='#L1213'>1213</a>
|
|
1279
|
+
<a name='L1214'></a><a href='#L1214'>1214</a>
|
|
1280
|
+
<a name='L1215'></a><a href='#L1215'>1215</a>
|
|
1281
|
+
<a name='L1216'></a><a href='#L1216'>1216</a>
|
|
1282
|
+
<a name='L1217'></a><a href='#L1217'>1217</a>
|
|
1283
|
+
<a name='L1218'></a><a href='#L1218'>1218</a>
|
|
1284
|
+
<a name='L1219'></a><a href='#L1219'>1219</a>
|
|
1285
|
+
<a name='L1220'></a><a href='#L1220'>1220</a>
|
|
1286
|
+
<a name='L1221'></a><a href='#L1221'>1221</a>
|
|
1287
|
+
<a name='L1222'></a><a href='#L1222'>1222</a>
|
|
1288
|
+
<a name='L1223'></a><a href='#L1223'>1223</a>
|
|
1289
|
+
<a name='L1224'></a><a href='#L1224'>1224</a>
|
|
1290
|
+
<a name='L1225'></a><a href='#L1225'>1225</a>
|
|
1291
|
+
<a name='L1226'></a><a href='#L1226'>1226</a>
|
|
1292
|
+
<a name='L1227'></a><a href='#L1227'>1227</a>
|
|
1293
|
+
<a name='L1228'></a><a href='#L1228'>1228</a>
|
|
1294
|
+
<a name='L1229'></a><a href='#L1229'>1229</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
1295
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1117
1296
|
<span class="cline-any cline-neutral"> </span>
|
|
1118
1297
|
<span class="cline-any cline-neutral"> </span>
|
|
1119
1298
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1179,6 +1358,8 @@
|
|
|
1179
1358
|
<span class="cline-any cline-neutral"> </span>
|
|
1180
1359
|
<span class="cline-any cline-neutral"> </span>
|
|
1181
1360
|
<span class="cline-any cline-neutral"> </span>
|
|
1361
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1362
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1182
1363
|
<span class="cline-any cline-yes">1x</span>
|
|
1183
1364
|
<span class="cline-any cline-neutral"> </span>
|
|
1184
1365
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1199,6 +1380,13 @@
|
|
|
1199
1380
|
<span class="cline-any cline-yes">1x</span>
|
|
1200
1381
|
<span class="cline-any cline-yes">1x</span>
|
|
1201
1382
|
<span class="cline-any cline-yes">1x</span>
|
|
1383
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1384
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1385
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1386
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1387
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1388
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1389
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1202
1390
|
<span class="cline-any cline-neutral"> </span>
|
|
1203
1391
|
<span class="cline-any cline-neutral"> </span>
|
|
1204
1392
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1388,7 +1576,7 @@
|
|
|
1388
1576
|
<span class="cline-any cline-neutral"> </span>
|
|
1389
1577
|
<span class="cline-any cline-neutral"> </span>
|
|
1390
1578
|
<span class="cline-any cline-neutral"> </span>
|
|
1391
|
-
<span class="cline-any cline-yes">
|
|
1579
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1392
1580
|
<span class="cline-any cline-neutral"> </span>
|
|
1393
1581
|
<span class="cline-any cline-neutral"> </span>
|
|
1394
1582
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1397,66 +1585,66 @@
|
|
|
1397
1585
|
<span class="cline-any cline-neutral"> </span>
|
|
1398
1586
|
<span class="cline-any cline-neutral"> </span>
|
|
1399
1587
|
<span class="cline-any cline-neutral"> </span>
|
|
1400
|
-
<span class="cline-any cline-yes">
|
|
1588
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1401
1589
|
<span class="cline-any cline-neutral"> </span>
|
|
1402
1590
|
<span class="cline-any cline-neutral"> </span>
|
|
1403
1591
|
<span class="cline-any cline-neutral"> </span>
|
|
1404
1592
|
<span class="cline-any cline-neutral"> </span>
|
|
1405
|
-
<span class="cline-any cline-yes">
|
|
1406
|
-
<span class="cline-any cline-yes">
|
|
1407
|
-
<span class="cline-any cline-yes">
|
|
1408
|
-
<span class="cline-any cline-yes">
|
|
1409
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1410
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1411
|
-
<span class="cline-any cline-yes">2x</span>
|
|
1593
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1594
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1595
|
+
<span class="cline-any cline-yes">13x</span>
|
|
1596
|
+
<span class="cline-any cline-yes">7x</span>
|
|
1412
1597
|
<span class="cline-any cline-yes">2x</span>
|
|
1413
1598
|
<span class="cline-any cline-yes">2x</span>
|
|
1599
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1600
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1601
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1414
1602
|
<span class="cline-any cline-neutral"> </span>
|
|
1415
1603
|
<span class="cline-any cline-no"> </span>
|
|
1416
1604
|
<span class="cline-any cline-neutral"> </span>
|
|
1417
1605
|
<span class="cline-any cline-no"> </span>
|
|
1418
1606
|
<span class="cline-any cline-neutral"> </span>
|
|
1419
1607
|
<span class="cline-any cline-neutral"> </span>
|
|
1420
|
-
<span class="cline-any cline-yes">
|
|
1608
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1421
1609
|
<span class="cline-any cline-neutral"> </span>
|
|
1422
|
-
<span class="cline-any cline-yes">
|
|
1423
|
-
<span class="cline-any cline-yes">
|
|
1610
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1611
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1424
1612
|
<span class="cline-any cline-neutral"> </span>
|
|
1425
|
-
<span class="cline-any cline-yes">
|
|
1426
|
-
<span class="cline-any cline-yes">
|
|
1613
|
+
<span class="cline-any cline-yes">27x</span>
|
|
1614
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1427
1615
|
<span class="cline-any cline-neutral"> </span>
|
|
1428
1616
|
<span class="cline-any cline-neutral"> </span>
|
|
1429
|
-
<span class="cline-any cline-yes">
|
|
1430
|
-
<span class="cline-any cline-yes">
|
|
1617
|
+
<span class="cline-any cline-yes">25x</span>
|
|
1618
|
+
<span class="cline-any cline-yes">17x</span>
|
|
1431
1619
|
<span class="cline-any cline-neutral"> </span>
|
|
1432
1620
|
<span class="cline-any cline-neutral"> </span>
|
|
1433
|
-
<span class="cline-any cline-yes">
|
|
1434
|
-
<span class="cline-any cline-yes">
|
|
1621
|
+
<span class="cline-any cline-yes">8x</span>
|
|
1622
|
+
<span class="cline-any cline-yes">5x</span>
|
|
1435
1623
|
<span class="cline-any cline-neutral"> </span>
|
|
1436
1624
|
<span class="cline-any cline-neutral"> </span>
|
|
1437
1625
|
<span class="cline-any cline-neutral"> </span>
|
|
1438
1626
|
<span class="cline-any cline-neutral"> </span>
|
|
1439
|
-
<span class="cline-any cline-yes">
|
|
1627
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1440
1628
|
<span class="cline-any cline-neutral"> </span>
|
|
1441
|
-
<span class="cline-any cline-yes">
|
|
1629
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1442
1630
|
<span class="cline-any cline-neutral"> </span>
|
|
1443
|
-
<span class="cline-any cline-yes">
|
|
1444
|
-
<span class="cline-any cline-yes">
|
|
1631
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1632
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1445
1633
|
<span class="cline-any cline-neutral"> </span>
|
|
1446
1634
|
<span class="cline-any cline-neutral"> </span>
|
|
1447
|
-
<span class="cline-any cline-yes">
|
|
1635
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1448
1636
|
<span class="cline-any cline-neutral"> </span>
|
|
1449
1637
|
<span class="cline-any cline-neutral"> </span>
|
|
1450
1638
|
<span class="cline-any cline-neutral"> </span>
|
|
1451
|
-
<span class="cline-any cline-yes">
|
|
1639
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1452
1640
|
<span class="cline-any cline-neutral"> </span>
|
|
1453
|
-
<span class="cline-any cline-yes">
|
|
1641
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1454
1642
|
<span class="cline-any cline-neutral"> </span>
|
|
1455
|
-
<span class="cline-any cline-yes">
|
|
1643
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1456
1644
|
<span class="cline-any cline-no"> </span>
|
|
1457
1645
|
<span class="cline-any cline-neutral"> </span>
|
|
1458
1646
|
<span class="cline-any cline-neutral"> </span>
|
|
1459
|
-
<span class="cline-any cline-yes">
|
|
1647
|
+
<span class="cline-any cline-yes">20x</span>
|
|
1460
1648
|
<span class="cline-any cline-neutral"> </span>
|
|
1461
1649
|
<span class="cline-any cline-neutral"> </span>
|
|
1462
1650
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1537,28 +1725,29 @@
|
|
|
1537
1725
|
<span class="cline-any cline-neutral"> </span>
|
|
1538
1726
|
<span class="cline-any cline-neutral"> </span>
|
|
1539
1727
|
<span class="cline-any cline-neutral"> </span>
|
|
1540
|
-
<span class="cline-any cline-yes">
|
|
1541
|
-
<span class="cline-any cline-yes">
|
|
1728
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1729
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1730
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1731
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1732
|
+
<span class="cline-any cline-yes">14x</span>
|
|
1733
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1542
1734
|
<span class="cline-any cline-neutral"> </span>
|
|
1543
1735
|
<span class="cline-any cline-neutral"> </span>
|
|
1544
|
-
<span class="cline-any cline-yes">12x</span>
|
|
1545
|
-
<span class="cline-any cline-yes">2x</span>
|
|
1546
1736
|
<span class="cline-any cline-neutral"> </span>
|
|
1547
|
-
<span class="cline-any cline-yes">2x</span>
|
|
1548
1737
|
<span class="cline-any cline-yes">2x</span>
|
|
1549
1738
|
<span class="cline-any cline-neutral"> </span>
|
|
1550
1739
|
<span class="cline-any cline-neutral"> </span>
|
|
1551
1740
|
<span class="cline-any cline-neutral"> </span>
|
|
1552
1741
|
<span class="cline-any cline-neutral"> </span>
|
|
1553
1742
|
<span class="cline-any cline-neutral"> </span>
|
|
1554
|
-
<span class="cline-any cline-yes">2x</span>
|
|
1555
1743
|
<span class="cline-any cline-neutral"> </span>
|
|
1556
1744
|
<span class="cline-any cline-yes">2x</span>
|
|
1557
1745
|
<span class="cline-any cline-neutral"> </span>
|
|
1746
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1558
1747
|
<span class="cline-any cline-neutral"> </span>
|
|
1559
1748
|
<span class="cline-any cline-neutral"> </span>
|
|
1560
1749
|
<span class="cline-any cline-neutral"> </span>
|
|
1561
|
-
<span class="cline-any cline-yes">
|
|
1750
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1562
1751
|
<span class="cline-any cline-neutral"> </span>
|
|
1563
1752
|
<span class="cline-any cline-neutral"> </span>
|
|
1564
1753
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1567,7 +1756,6 @@
|
|
|
1567
1756
|
<span class="cline-any cline-neutral"> </span>
|
|
1568
1757
|
<span class="cline-any cline-yes">1x</span>
|
|
1569
1758
|
<span class="cline-any cline-neutral"> </span>
|
|
1570
|
-
<span class="cline-any cline-yes">1x</span>
|
|
1571
1759
|
<span class="cline-any cline-neutral"> </span>
|
|
1572
1760
|
<span class="cline-any cline-neutral"> </span>
|
|
1573
1761
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1578,10 +1766,10 @@
|
|
|
1578
1766
|
<span class="cline-any cline-yes">1x</span>
|
|
1579
1767
|
<span class="cline-any cline-neutral"> </span>
|
|
1580
1768
|
<span class="cline-any cline-neutral"> </span>
|
|
1581
|
-
<span class="cline-any cline-yes">
|
|
1769
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1582
1770
|
<span class="cline-any cline-neutral"> </span>
|
|
1583
1771
|
<span class="cline-any cline-neutral"> </span>
|
|
1584
|
-
<span class="cline-any cline-yes">
|
|
1772
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1585
1773
|
<span class="cline-any cline-no"> </span>
|
|
1586
1774
|
<span class="cline-any cline-neutral"> </span>
|
|
1587
1775
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1592,46 +1780,63 @@
|
|
|
1592
1780
|
<span class="cline-any cline-no"> </span>
|
|
1593
1781
|
<span class="cline-any cline-neutral"> </span>
|
|
1594
1782
|
<span class="cline-any cline-neutral"> </span>
|
|
1595
|
-
<span class="cline-any cline-yes">
|
|
1783
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1596
1784
|
<span class="cline-any cline-neutral"> </span>
|
|
1597
1785
|
<span class="cline-any cline-neutral"> </span>
|
|
1786
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1787
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1788
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1789
|
+
<span class="cline-any cline-no"> </span>
|
|
1790
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1598
1791
|
<span class="cline-any cline-neutral"> </span>
|
|
1599
1792
|
<span class="cline-any cline-neutral"> </span>
|
|
1600
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1601
1793
|
<span class="cline-any cline-neutral"> </span>
|
|
1602
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1603
|
-
<span class="cline-any cline-no"> </span>
|
|
1604
1794
|
<span class="cline-any cline-neutral"> </span>
|
|
1605
1795
|
<span class="cline-any cline-no"> </span>
|
|
1796
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1606
1797
|
<span class="cline-any cline-no"> </span>
|
|
1607
1798
|
<span class="cline-any cline-neutral"> </span>
|
|
1608
1799
|
<span class="cline-any cline-neutral"> </span>
|
|
1609
1800
|
<span class="cline-any cline-neutral"> </span>
|
|
1801
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1802
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1803
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1610
1804
|
<span class="cline-any cline-neutral"> </span>
|
|
1805
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1611
1806
|
<span class="cline-any cline-neutral"> </span>
|
|
1807
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1808
|
+
<span class="cline-any cline-no"> </span>
|
|
1612
1809
|
<span class="cline-any cline-no"> </span>
|
|
1613
1810
|
<span class="cline-any cline-neutral"> </span>
|
|
1811
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1812
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1813
|
+
<span class="cline-any cline-no"> </span>
|
|
1614
1814
|
<span class="cline-any cline-no"> </span>
|
|
1615
1815
|
<span class="cline-any cline-neutral"> </span>
|
|
1616
1816
|
<span class="cline-any cline-neutral"> </span>
|
|
1617
1817
|
<span class="cline-any cline-neutral"> </span>
|
|
1618
1818
|
<span class="cline-any cline-neutral"> </span>
|
|
1619
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1620
1819
|
<span class="cline-any cline-neutral"> </span>
|
|
1621
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1622
1820
|
<span class="cline-any cline-neutral"> </span>
|
|
1623
1821
|
<span class="cline-any cline-neutral"> </span>
|
|
1822
|
+
<span class="cline-any cline-no"> </span>
|
|
1823
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1824
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1825
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1826
|
+
<span class="cline-any cline-no"> </span>
|
|
1624
1827
|
<span class="cline-any cline-neutral"> </span>
|
|
1625
1828
|
<span class="cline-any cline-neutral"> </span>
|
|
1626
1829
|
<span class="cline-any cline-neutral"> </span>
|
|
1627
1830
|
<span class="cline-any cline-neutral"> </span>
|
|
1628
1831
|
<span class="cline-any cline-neutral"> </span>
|
|
1629
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1630
1832
|
<span class="cline-any cline-neutral"> </span>
|
|
1631
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1632
1833
|
<span class="cline-any cline-no"> </span>
|
|
1633
1834
|
<span class="cline-any cline-neutral"> </span>
|
|
1634
1835
|
<span class="cline-any cline-no"> </span>
|
|
1836
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1837
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1838
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1839
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1635
1840
|
<span class="cline-any cline-no"> </span>
|
|
1636
1841
|
<span class="cline-any cline-neutral"> </span>
|
|
1637
1842
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1640,27 +1845,31 @@
|
|
|
1640
1845
|
<span class="cline-any cline-neutral"> </span>
|
|
1641
1846
|
<span class="cline-any cline-neutral"> </span>
|
|
1642
1847
|
<span class="cline-any cline-neutral"> </span>
|
|
1848
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1643
1849
|
<span class="cline-any cline-no"> </span>
|
|
1644
1850
|
<span class="cline-any cline-neutral"> </span>
|
|
1645
1851
|
<span class="cline-any cline-no"> </span>
|
|
1646
1852
|
<span class="cline-any cline-neutral"> </span>
|
|
1647
1853
|
<span class="cline-any cline-neutral"> </span>
|
|
1648
1854
|
<span class="cline-any cline-neutral"> </span>
|
|
1855
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1649
1856
|
<span class="cline-any cline-neutral"> </span>
|
|
1650
|
-
<span class="cline-any cline-yes">
|
|
1651
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1857
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1652
1858
|
<span class="cline-any cline-neutral"> </span>
|
|
1653
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1654
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1655
1859
|
<span class="cline-any cline-neutral"> </span>
|
|
1656
1860
|
<span class="cline-any cline-neutral"> </span>
|
|
1657
1861
|
<span class="cline-any cline-neutral"> </span>
|
|
1658
1862
|
<span class="cline-any cline-neutral"> </span>
|
|
1659
1863
|
<span class="cline-any cline-neutral"> </span>
|
|
1660
1864
|
<span class="cline-any cline-neutral"> </span>
|
|
1661
|
-
<span class="cline-any cline-yes">9x</span>
|
|
1662
1865
|
<span class="cline-any cline-neutral"> </span>
|
|
1663
|
-
<span class="cline-any cline-yes">
|
|
1866
|
+
<span class="cline-any cline-yes">11x</span>
|
|
1867
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1868
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1869
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1870
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1871
|
+
<span class="cline-any cline-no"> </span>
|
|
1872
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1664
1873
|
<span class="cline-any cline-neutral"> </span>
|
|
1665
1874
|
<span class="cline-any cline-neutral"> </span>
|
|
1666
1875
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1669,12 +1878,20 @@
|
|
|
1669
1878
|
<span class="cline-any cline-no"> </span>
|
|
1670
1879
|
<span class="cline-any cline-neutral"> </span>
|
|
1671
1880
|
<span class="cline-any cline-no"> </span>
|
|
1881
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1882
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1883
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1884
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1885
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1672
1886
|
<span class="cline-any cline-no"> </span>
|
|
1673
1887
|
<span class="cline-any cline-neutral"> </span>
|
|
1674
1888
|
<span class="cline-any cline-neutral"> </span>
|
|
1675
1889
|
<span class="cline-any cline-neutral"> </span>
|
|
1676
1890
|
<span class="cline-any cline-neutral"> </span>
|
|
1891
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1892
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1677
1893
|
<span class="cline-any cline-neutral"> </span>
|
|
1894
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1678
1895
|
<span class="cline-any cline-neutral"> </span>
|
|
1679
1896
|
<span class="cline-any cline-no"> </span>
|
|
1680
1897
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1682,55 +1899,130 @@
|
|
|
1682
1899
|
<span class="cline-any cline-neutral"> </span>
|
|
1683
1900
|
<span class="cline-any cline-neutral"> </span>
|
|
1684
1901
|
<span class="cline-any cline-neutral"> </span>
|
|
1685
|
-
<span class="cline-any cline-no"> </span>
|
|
1686
1902
|
<span class="cline-any cline-neutral"> </span>
|
|
1687
1903
|
<span class="cline-any cline-neutral"> </span>
|
|
1688
1904
|
<span class="cline-any cline-neutral"> </span>
|
|
1689
1905
|
<span class="cline-any cline-neutral"> </span>
|
|
1690
1906
|
<span class="cline-any cline-neutral"> </span>
|
|
1907
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1908
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1909
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1910
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1911
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1912
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1913
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1691
1914
|
<span class="cline-any cline-no"> </span>
|
|
1692
1915
|
<span class="cline-any cline-neutral"> </span>
|
|
1916
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1917
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1918
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1693
1919
|
<span class="cline-any cline-no"> </span>
|
|
1694
1920
|
<span class="cline-any cline-neutral"> </span>
|
|
1695
1921
|
<span class="cline-any cline-no"> </span>
|
|
1696
1922
|
<span class="cline-any cline-neutral"> </span>
|
|
1697
1923
|
<span class="cline-any cline-neutral"> </span>
|
|
1698
1924
|
<span class="cline-any cline-neutral"> </span>
|
|
1925
|
+
<span class="cline-any cline-yes">12x</span>
|
|
1926
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1927
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1928
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1929
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1930
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1931
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1932
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1933
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1699
1934
|
<span class="cline-any cline-neutral"> </span>
|
|
1935
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1936
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1937
|
+
<span class="cline-any cline-yes">2x</span>
|
|
1938
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1939
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1940
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1941
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1942
|
+
<span class="cline-any cline-yes">10x</span>
|
|
1700
1943
|
<span class="cline-any cline-neutral"> </span>
|
|
1944
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1945
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1946
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1947
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1948
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1949
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1950
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1951
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1952
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1953
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1954
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1955
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1956
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1957
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1958
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1959
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1960
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1961
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1962
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1963
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1964
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1965
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1701
1966
|
<span class="cline-any cline-no"> </span>
|
|
1702
1967
|
<span class="cline-any cline-neutral"> </span>
|
|
1703
1968
|
<span class="cline-any cline-neutral"> </span>
|
|
1704
1969
|
<span class="cline-any cline-neutral"> </span>
|
|
1705
1970
|
<span class="cline-any cline-neutral"> </span>
|
|
1971
|
+
<span class="cline-any cline-no"> </span>
|
|
1706
1972
|
<span class="cline-any cline-neutral"> </span>
|
|
1973
|
+
<span class="cline-any cline-no"> </span>
|
|
1707
1974
|
<span class="cline-any cline-neutral"> </span>
|
|
1708
1975
|
<span class="cline-any cline-neutral"> </span>
|
|
1709
|
-
<span class="cline-any cline-yes">11x</span>
|
|
1710
|
-
<span class="cline-any cline-yes">11x</span>
|
|
1711
1976
|
<span class="cline-any cline-neutral"> </span>
|
|
1712
|
-
<span class="cline-any cline-yes">
|
|
1713
|
-
<span class="cline-any cline-
|
|
1977
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1978
|
+
<span class="cline-any cline-no"> </span>
|
|
1714
1979
|
<span class="cline-any cline-neutral"> </span>
|
|
1715
1980
|
<span class="cline-any cline-neutral"> </span>
|
|
1716
|
-
<span class="cline-any cline-yes">8x</span>
|
|
1717
|
-
<span class="cline-any cline-yes">8x</span>
|
|
1718
1981
|
<span class="cline-any cline-neutral"> </span>
|
|
1719
1982
|
<span class="cline-any cline-neutral"> </span>
|
|
1720
1983
|
<span class="cline-any cline-no"> </span>
|
|
1721
1984
|
<span class="cline-any cline-neutral"> </span>
|
|
1722
1985
|
<span class="cline-any cline-no"> </span>
|
|
1723
1986
|
<span class="cline-any cline-neutral"> </span>
|
|
1987
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1988
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1989
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1990
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1991
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1992
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1993
|
+
<span class="cline-any cline-yes">9x</span>
|
|
1724
1994
|
<span class="cline-any cline-no"> </span>
|
|
1725
1995
|
<span class="cline-any cline-neutral"> </span>
|
|
1996
|
+
<span class="cline-any cline-no"> </span>
|
|
1997
|
+
<span class="cline-any cline-no"> </span>
|
|
1726
1998
|
<span class="cline-any cline-neutral"> </span>
|
|
1727
1999
|
<span class="cline-any cline-neutral"> </span>
|
|
1728
2000
|
<span class="cline-any cline-neutral"> </span>
|
|
1729
2001
|
<span class="cline-any cline-neutral"> </span>
|
|
1730
2002
|
<span class="cline-any cline-neutral"> </span>
|
|
2003
|
+
<span class="cline-any cline-no"> </span>
|
|
1731
2004
|
<span class="cline-any cline-neutral"> </span>
|
|
1732
2005
|
<span class="cline-any cline-no"> </span>
|
|
1733
2006
|
<span class="cline-any cline-neutral"> </span>
|
|
2007
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2008
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2009
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2010
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2011
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2012
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2013
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2014
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2015
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2016
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2017
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2018
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2019
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2020
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2021
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2022
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2023
|
+
<span class="cline-any cline-no"> </span>
|
|
2024
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2025
|
+
<span class="cline-any cline-no"> </span>
|
|
1734
2026
|
<span class="cline-any cline-no"> </span>
|
|
1735
2027
|
<span class="cline-any cline-neutral"> </span>
|
|
1736
2028
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1738,6 +2030,7 @@
|
|
|
1738
2030
|
<span class="cline-any cline-neutral"> </span>
|
|
1739
2031
|
<span class="cline-any cline-neutral"> </span>
|
|
1740
2032
|
<span class="cline-any cline-neutral"> </span>
|
|
2033
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1741
2034
|
<span class="cline-any cline-no"> </span>
|
|
1742
2035
|
<span class="cline-any cline-neutral"> </span>
|
|
1743
2036
|
<span class="cline-any cline-no"> </span>
|
|
@@ -1745,12 +2038,36 @@
|
|
|
1745
2038
|
<span class="cline-any cline-neutral"> </span>
|
|
1746
2039
|
<span class="cline-any cline-neutral"> </span>
|
|
1747
2040
|
<span class="cline-any cline-neutral"> </span>
|
|
2041
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2042
|
+
<span class="cline-any cline-yes">11x</span>
|
|
2043
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2044
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2045
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2046
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2047
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2048
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2049
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2050
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2051
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2052
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2053
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2054
|
+
<span class="cline-any cline-yes">9x</span>
|
|
2055
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2056
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2057
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2058
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2059
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2060
|
+
<span class="cline-any cline-no"> </span>
|
|
2061
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2062
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2063
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1748
2064
|
<span class="cline-any cline-neutral"> </span>
|
|
1749
2065
|
<span class="cline-any cline-neutral"> </span>
|
|
1750
2066
|
<span class="cline-any cline-no"> </span>
|
|
1751
2067
|
<span class="cline-any cline-neutral"> </span>
|
|
1752
2068
|
<span class="cline-any cline-no"> </span>
|
|
1753
2069
|
<span class="cline-any cline-neutral"> </span>
|
|
2070
|
+
<span class="cline-any cline-no"> </span>
|
|
1754
2071
|
<span class="cline-any cline-neutral"> </span>
|
|
1755
2072
|
<span class="cline-any cline-neutral"> </span>
|
|
1756
2073
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1758,6 +2075,27 @@
|
|
|
1758
2075
|
<span class="cline-any cline-neutral"> </span>
|
|
1759
2076
|
<span class="cline-any cline-no"> </span>
|
|
1760
2077
|
<span class="cline-any cline-neutral"> </span>
|
|
2078
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2079
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2080
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2081
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2082
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2083
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2084
|
+
<span class="cline-any cline-yes">11x</span>
|
|
2085
|
+
<span class="cline-any cline-yes">11x</span>
|
|
2086
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2087
|
+
<span class="cline-any cline-yes">11x</span>
|
|
2088
|
+
<span class="cline-any cline-yes">3x</span>
|
|
2089
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2090
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2091
|
+
<span class="cline-any cline-yes">8x</span>
|
|
2092
|
+
<span class="cline-any cline-yes">8x</span>
|
|
2093
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2094
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2095
|
+
<span class="cline-any cline-no"> </span>
|
|
2096
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2097
|
+
<span class="cline-any cline-no"> </span>
|
|
2098
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1761
2099
|
<span class="cline-any cline-no"> </span>
|
|
1762
2100
|
<span class="cline-any cline-neutral"> </span>
|
|
1763
2101
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1765,6 +2103,7 @@
|
|
|
1765
2103
|
<span class="cline-any cline-neutral"> </span>
|
|
1766
2104
|
<span class="cline-any cline-neutral"> </span>
|
|
1767
2105
|
<span class="cline-any cline-neutral"> </span>
|
|
2106
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1768
2107
|
<span class="cline-any cline-yes">1x</span>
|
|
1769
2108
|
<span class="cline-any cline-yes">1x</span>
|
|
1770
2109
|
<span class="cline-any cline-yes">1x</span>
|
|
@@ -1777,8 +2116,6 @@
|
|
|
1777
2116
|
<span class="cline-any cline-neutral"> </span>
|
|
1778
2117
|
<span class="cline-any cline-yes">1x</span>
|
|
1779
2118
|
<span class="cline-any cline-neutral"> </span>
|
|
1780
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1781
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1782
2119
|
<span class="cline-any cline-yes">1x</span>
|
|
1783
2120
|
<span class="cline-any cline-neutral"> </span>
|
|
1784
2121
|
<span class="cline-any cline-yes">1x</span>
|
|
@@ -1845,6 +2182,22 @@
|
|
|
1845
2182
|
<span class="cline-any cline-no"> </span>
|
|
1846
2183
|
<span class="cline-any cline-no"> </span>
|
|
1847
2184
|
<span class="cline-any cline-neutral"> </span>
|
|
2185
|
+
<span class="cline-any cline-no"> </span>
|
|
2186
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2187
|
+
<span class="cline-any cline-no"> </span>
|
|
2188
|
+
<span class="cline-any cline-no"> </span>
|
|
2189
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2190
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2191
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2192
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2193
|
+
<span class="cline-any cline-no"> </span>
|
|
2194
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2195
|
+
<span class="cline-any cline-no"> </span>
|
|
2196
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2197
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2198
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2199
|
+
<span class="cline-any cline-no"> </span>
|
|
2200
|
+
<span class="cline-any cline-no"> </span>
|
|
1848
2201
|
<span class="cline-any cline-neutral"> </span>
|
|
1849
2202
|
<span class="cline-any cline-no"> </span>
|
|
1850
2203
|
<span class="cline-any cline-no"> </span>
|
|
@@ -1864,15 +2217,18 @@
|
|
|
1864
2217
|
<span class="cline-any cline-neutral"> </span>
|
|
1865
2218
|
<span class="cline-any cline-neutral"> </span>
|
|
1866
2219
|
<span class="cline-any cline-neutral"> </span>
|
|
1867
|
-
<span class="cline-any cline-no"> </span>
|
|
1868
2220
|
<span class="cline-any cline-neutral"> </span>
|
|
2221
|
+
<span class="cline-any cline-no"> </span>
|
|
1869
2222
|
<span class="cline-any cline-neutral"> </span>
|
|
1870
2223
|
<span class="cline-any cline-neutral"> </span>
|
|
1871
2224
|
<span class="cline-any cline-neutral"> </span>
|
|
1872
2225
|
<span class="cline-any cline-neutral"> </span>
|
|
1873
2226
|
<span class="cline-any cline-neutral"> </span>
|
|
2227
|
+
<span class="cline-any cline-no"> </span>
|
|
1874
2228
|
<span class="cline-any cline-neutral"> </span>
|
|
1875
2229
|
<span class="cline-any cline-no"> </span>
|
|
2230
|
+
<span class="cline-any cline-no"> </span>
|
|
2231
|
+
<span class="cline-any cline-no"> </span>
|
|
1876
2232
|
<span class="cline-any cline-neutral"> </span>
|
|
1877
2233
|
<span class="cline-any cline-neutral"> </span>
|
|
1878
2234
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1884,6 +2240,8 @@
|
|
|
1884
2240
|
<span class="cline-any cline-no"> </span>
|
|
1885
2241
|
<span class="cline-any cline-neutral"> </span>
|
|
1886
2242
|
<span class="cline-any cline-neutral"> </span>
|
|
2243
|
+
<span class="cline-any cline-neutral"> </span>
|
|
2244
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1887
2245
|
<span class="cline-any cline-no"> </span>
|
|
1888
2246
|
<span class="cline-any cline-neutral"> </span>
|
|
1889
2247
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1919,8 +2277,6 @@
|
|
|
1919
2277
|
<span class="cline-any cline-no"> </span>
|
|
1920
2278
|
<span class="cline-any cline-neutral"> </span>
|
|
1921
2279
|
<span class="cline-any cline-neutral"> </span>
|
|
1922
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1923
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1924
2280
|
<span class="cline-any cline-no"> </span>
|
|
1925
2281
|
<span class="cline-any cline-neutral"> </span>
|
|
1926
2282
|
<span class="cline-any cline-no"> </span>
|
|
@@ -2164,7 +2520,7 @@
|
|
|
2164
2520
|
<span class="cline-any cline-yes">10x</span>
|
|
2165
2521
|
<span class="cline-any cline-neutral"> </span>
|
|
2166
2522
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import {
|
|
2167
|
-
|
|
2523
|
+
Context,
|
|
2168
2524
|
AttributeValue,
|
|
2169
2525
|
BucketKey,
|
|
2170
2526
|
BucketValue,
|
|
@@ -2172,10 +2528,11 @@
|
|
|
2172
2528
|
Feature,
|
|
2173
2529
|
FeatureKey,
|
|
2174
2530
|
InitialFeatures,
|
|
2531
|
+
OverrideFeature,
|
|
2175
2532
|
StickyFeatures,
|
|
2533
|
+
Traffic,
|
|
2176
2534
|
VariableType,
|
|
2177
2535
|
VariableValue,
|
|
2178
|
-
VariationType,
|
|
2179
2536
|
VariationValue,
|
|
2180
2537
|
Variation,
|
|
2181
2538
|
RuleKey,
|
|
@@ -2187,7 +2544,7 @@ import { createLogger, Logger } from "./logger";
|
|
|
2187
2544
|
import { DatafileReader } from "./datafileReader";
|
|
2188
2545
|
import { Emitter } from "./emitter";
|
|
2189
2546
|
import { getBucketedNumber } from "./bucket";
|
|
2190
|
-
import { findForceFromFeature, getMatchedTrafficAndAllocation } from "./feature";
|
|
2547
|
+
import { findForceFromFeature, getMatchedTraffic, getMatchedTrafficAndAllocation } from "./feature";
|
|
2191
2548
|
import { allConditionsAreMatched } from "./conditions";
|
|
2192
2549
|
import { allGroupSegmentsAreMatched } from "./segments";
|
|
2193
2550
|
|
|
@@ -2196,13 +2553,13 @@ export type ReadyCallback = () => void;
|
|
|
2196
2553
|
export type ActivationCallback = (
|
|
2197
2554
|
featureName: string,
|
|
2198
2555
|
variation: VariationValue,
|
|
2199
|
-
|
|
2200
|
-
|
|
2556
|
+
context: Context,
|
|
2557
|
+
captureContext: Context,
|
|
2201
2558
|
) => void;
|
|
2202
2559
|
|
|
2203
|
-
export type ConfigureBucketKey = (feature,
|
|
2560
|
+
export type ConfigureBucketKey = (feature, context, bucketKey: BucketKey) => BucketKey;
|
|
2204
2561
|
|
|
2205
|
-
export type ConfigureBucketValue = (feature,
|
|
2562
|
+
export type ConfigureBucketValue = (feature, context, bucketValue: BucketValue) => BucketValue;
|
|
2206
2563
|
|
|
2207
2564
|
export interface Statuses {
|
|
2208
2565
|
ready: boolean;
|
|
@@ -2211,6 +2568,8 @@ export interface Statuses {
|
|
|
2211
2568
|
|
|
2212
2569
|
const DEFAULT_BUCKET_KEY_SEPARATOR = ".";
|
|
2213
2570
|
|
|
2571
|
+
export type InterceptContext = (context: Context) => Context;
|
|
2572
|
+
|
|
2214
2573
|
export interface InstanceOptions {
|
|
2215
2574
|
bucketKeySeparator?: string;
|
|
2216
2575
|
configureBucketKey?: ConfigureBucketKey;
|
|
@@ -2219,7 +2578,7 @@ export interface InstanceOptions {
|
|
|
2219
2578
|
datafileUrl?: string;
|
|
2220
2579
|
handleDatafileFetch?: (datafileUrl: string) => Promise<DatafileContent>;
|
|
2221
2580
|
initialFeatures?: InitialFeatures;
|
|
2222
|
-
|
|
2581
|
+
interceptContext?: InterceptContext;
|
|
2223
2582
|
logger?: Logger;
|
|
2224
2583
|
onActivation?: ActivationCallback;
|
|
2225
2584
|
onReady?: ReadyCallback;
|
|
@@ -2241,6 +2600,9 @@ export type DatafileFetchHandler = (datafileUrl: string) => Promise<Datafi
|
|
|
2241
2600
|
|
|
2242
2601
|
export enum EvaluationReason {
|
|
2243
2602
|
NOT_FOUND = "not_found",
|
|
2603
|
+
NO_VARIATIONS = "no_variations",
|
|
2604
|
+
DISABLED = "disabled",
|
|
2605
|
+
OUT_OF_RANGE = "out_of_range",
|
|
2244
2606
|
FORCED = "forced",
|
|
2245
2607
|
INITIAL = "initial",
|
|
2246
2608
|
STICKY = "sticky",
|
|
@@ -2260,6 +2622,10 @@ export interface Evaluation {
|
|
|
2260
2622
|
bucketValue?: BucketValue;
|
|
2261
2623
|
ruleKey?: RuleKey;
|
|
2262
2624
|
error?: Error;
|
|
2625
|
+
enabled?: boolean;
|
|
2626
|
+
traffic?: Traffic;
|
|
2627
|
+
sticky?: OverrideFeature;
|
|
2628
|
+
initial?: OverrideFeature;
|
|
2263
2629
|
|
|
2264
2630
|
// variation
|
|
2265
2631
|
variation?: Variation;
|
|
@@ -2282,7 +2648,7 @@ function fetchDatafileContent(
|
|
|
2282
2648
|
<span class="cstat-no" title="statement not covered" > return fetch(datafileUrl).then(<span class="fstat-no" title="function not covered" >(r</span>es) => <span class="cstat-no" title="statement not covered" >res.json())</span>;</span>
|
|
2283
2649
|
}
|
|
2284
2650
|
|
|
2285
|
-
type FieldType =
|
|
2651
|
+
type FieldType = string | VariableType;
|
|
2286
2652
|
type ValueType = VariableValue;
|
|
2287
2653
|
|
|
2288
2654
|
export function <span class="fstat-no" title="function not covered" >getValueByType(</span>value: ValueType, fieldType: FieldType): ValueType {
|
|
@@ -2321,7 +2687,7 @@ export class FeaturevisorInstance {
|
|
|
2321
2687
|
private datafileUrl?: string;
|
|
2322
2688
|
private handleDatafileFetch?: DatafileFetchHandler;
|
|
2323
2689
|
private initialFeatures?: InitialFeatures;
|
|
2324
|
-
private
|
|
2690
|
+
private interceptContext?: InterceptContext;
|
|
2325
2691
|
private logger: Logger;
|
|
2326
2692
|
private refreshInterval?: number; // seconds
|
|
2327
2693
|
private stickyFeatures?: StickyFeatures;
|
|
@@ -2347,7 +2713,7 @@ export class FeaturevisorInstance {
|
|
|
2347
2713
|
this.datafileUrl = options.datafileUrl;
|
|
2348
2714
|
this.handleDatafileFetch = options.handleDatafileFetch;
|
|
2349
2715
|
this.initialFeatures = options.initialFeatures;
|
|
2350
|
-
this.
|
|
2716
|
+
this.interceptContext = options.interceptContext;
|
|
2351
2717
|
this.logger = options.logger || createLogger();
|
|
2352
2718
|
this.refreshInterval = options.refreshInterval;
|
|
2353
2719
|
this.stickyFeatures = options.stickyFeatures;
|
|
@@ -2446,7 +2812,7 @@ export class FeaturevisorInstance {
|
|
|
2446
2812
|
/**
|
|
2447
2813
|
* Bucketing
|
|
2448
2814
|
*/
|
|
2449
|
-
private getBucketKey(feature: Feature,
|
|
2815
|
+
private getBucketKey(feature: Feature, context: Context): BucketKey {
|
|
2450
2816
|
const featureKey = feature.key;
|
|
2451
2817
|
|
|
2452
2818
|
let type;
|
|
@@ -2470,7 +2836,7 @@ export class FeaturevisorInstance {
|
|
|
2470
2836
|
const bucketKey: AttributeValue[] = [];
|
|
2471
2837
|
|
|
2472
2838
|
attributeKeys.forEach((attributeKey) => {
|
|
2473
|
-
const attributeValue =
|
|
2839
|
+
const attributeValue = context[attributeKey];
|
|
2474
2840
|
|
|
2475
2841
|
if (typeof attributeValue === "undefined") {
|
|
2476
2842
|
return;
|
|
@@ -2491,19 +2857,19 @@ export class FeaturevisorInstance {
|
|
|
2491
2857
|
const result = bucketKey.join(this.bucketKeySeparator);
|
|
2492
2858
|
|
|
2493
2859
|
if (this.configureBucketKey) {
|
|
2494
|
-
return this.configureBucketKey(feature,
|
|
2860
|
+
return this.configureBucketKey(feature, context, result);
|
|
2495
2861
|
}
|
|
2496
2862
|
|
|
2497
2863
|
return result;
|
|
2498
2864
|
}
|
|
2499
2865
|
|
|
2500
|
-
private getBucketValue(feature: Feature,
|
|
2501
|
-
const bucketKey = this.getBucketKey(feature,
|
|
2866
|
+
private getBucketValue(feature: Feature, context: Context): BucketValue {
|
|
2867
|
+
const bucketKey = this.getBucketKey(feature, context);
|
|
2502
2868
|
|
|
2503
2869
|
const value = getBucketedNumber(bucketKey);
|
|
2504
2870
|
|
|
2505
2871
|
<span class="missing-if-branch" title="if path not taken" >I</span>if (this.configureBucketValue) {
|
|
2506
|
-
<span class="cstat-no" title="statement not covered" > return this.configureBucketValue(feature,
|
|
2872
|
+
<span class="cstat-no" title="statement not covered" > return this.configureBucketValue(feature, context, value);</span>
|
|
2507
2873
|
}
|
|
2508
2874
|
|
|
2509
2875
|
return value;
|
|
@@ -2580,15 +2946,208 @@ export class FeaturevisorInstance {
|
|
|
2580
2946
|
|
|
2581
2947
|
clearInterval(this.intervalId);
|
|
2582
2948
|
}
|
|
2949
|
+
|
|
2950
|
+
/**
|
|
2951
|
+
* Flag
|
|
2952
|
+
*/
|
|
2953
|
+
evaluateFlag(featureKey: FeatureKey | Feature, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: Evaluation {
|
|
2954
|
+
let evaluation: Evaluation;
|
|
2955
|
+
|
|
2956
|
+
try {
|
|
2957
|
+
const key = typeof featureKey === "string" ? featureKey : <span class="branch-1 cbranch-no" title="branch not covered" >featureKey.key;</span>
|
|
2958
|
+
|
|
2959
|
+
// sticky
|
|
2960
|
+
if (
|
|
2961
|
+
this.stickyFeatures &&
|
|
2962
|
+
this.stickyFeatures[key] &&
|
|
2963
|
+
typeof this.stickyFeatures[key].enabled !== "undefined"
|
|
2964
|
+
) {
|
|
2965
|
+
evaluation = {
|
|
2966
|
+
featureKey: key,
|
|
2967
|
+
reason: EvaluationReason.STICKY,
|
|
2968
|
+
enabled: this.stickyFeatures[key].enabled,
|
|
2969
|
+
sticky: this.stickyFeatures[key],
|
|
2970
|
+
};
|
|
2971
|
+
|
|
2972
|
+
this.logger.debug("using sticky enabled", evaluation);
|
|
2973
|
+
|
|
2974
|
+
return evaluation;
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
// initial
|
|
2978
|
+
if (
|
|
2979
|
+
this.statuses &&
|
|
2980
|
+
!this.statuses.ready &&
|
|
2981
|
+
this.initialFeatures &&
|
|
2982
|
+
this.initialFeatures[key] &&
|
|
2983
|
+
typeof this.initialFeatures[key].enabled !== "undefined"
|
|
2984
|
+
) {
|
|
2985
|
+
evaluation = {
|
|
2986
|
+
featureKey: key,
|
|
2987
|
+
reason: EvaluationReason.INITIAL,
|
|
2988
|
+
enabled: this.initialFeatures[key].enabled,
|
|
2989
|
+
initial: this.initialFeatures[key],
|
|
2990
|
+
};
|
|
2991
|
+
|
|
2992
|
+
this.logger.debug("using initial enabled", evaluation);
|
|
2993
|
+
|
|
2994
|
+
return evaluation;
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2997
|
+
const feature = this.getFeature(featureKey);
|
|
2998
|
+
|
|
2999
|
+
// not found
|
|
3000
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!feature) {
|
|
3001
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3002
|
+
featureKey: key,
|
|
3003
|
+
reason: EvaluationReason.NOT_FOUND,
|
|
3004
|
+
};
|
|
3005
|
+
|
|
3006
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn("feature not found", evaluation);</span>
|
|
3007
|
+
|
|
3008
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3009
|
+
}
|
|
3010
|
+
|
|
3011
|
+
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
|
|
3012
|
+
|
|
3013
|
+
// forced
|
|
3014
|
+
const force = findForceFromFeature(feature, context, this.datafileReader);
|
|
3015
|
+
|
|
3016
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (force && <span class="branch-1 cbranch-no" title="branch not covered" >typeof force.enabled !== "undefined")</span> {
|
|
3017
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3018
|
+
featureKey: feature.key,
|
|
3019
|
+
reason: EvaluationReason.FORCED,
|
|
3020
|
+
enabled: force.enabled,
|
|
3021
|
+
};
|
|
3022
|
+
|
|
3023
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug("forced enabled found", evaluation);</span>
|
|
3024
|
+
|
|
3025
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
// bucketing
|
|
3029
|
+
const bucketValue = this.getBucketValue(feature, finalContext);
|
|
3030
|
+
|
|
3031
|
+
const matchedTraffic = getMatchedTraffic(feature.traffic, finalContext, this.datafileReader);
|
|
3032
|
+
|
|
3033
|
+
if (matchedTraffic) {
|
|
3034
|
+
// check if mutually exclusive
|
|
3035
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (feature.ranges && <span class="branch-1 cbranch-no" title="branch not covered" >feature.ranges.length > 0)</span> {
|
|
3036
|
+
const matchedRange = <span class="cstat-no" title="statement not covered" >feature.ranges.find(<span class="fstat-no" title="function not covered" >(r</span>ange) => {</span>
|
|
3037
|
+
<span class="cstat-no" title="statement not covered" > return bucketValue >= range[0] && bucketValue < range[1];</span>
|
|
3038
|
+
});
|
|
3039
|
+
|
|
3040
|
+
// matched
|
|
3041
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (matchedRange) {</span>
|
|
3042
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3043
|
+
featureKey: feature.key,
|
|
3044
|
+
reason: EvaluationReason.ALLOCATED,
|
|
3045
|
+
enabled:
|
|
3046
|
+
typeof matchedTraffic.enabled === "undefined" ? true : matchedTraffic.enabled,
|
|
3047
|
+
bucketValue,
|
|
3048
|
+
};
|
|
3049
|
+
|
|
3050
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3053
|
+
// no match
|
|
3054
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3055
|
+
featureKey: feature.key,
|
|
3056
|
+
reason: EvaluationReason.OUT_OF_RANGE,
|
|
3057
|
+
enabled: false,
|
|
3058
|
+
bucketValue,
|
|
3059
|
+
};
|
|
3060
|
+
|
|
3061
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug("not matched", evaluation);</span>
|
|
3062
|
+
|
|
3063
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3064
|
+
}
|
|
3065
|
+
|
|
3066
|
+
// override from rule
|
|
3067
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (typeof matchedTraffic.enabled !== "undefined") {
|
|
3068
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3069
|
+
featureKey: feature.key,
|
|
3070
|
+
reason: EvaluationReason.OVERRIDE,
|
|
3071
|
+
enabled: matchedTraffic.enabled,
|
|
3072
|
+
bucketValue,
|
|
3073
|
+
ruleKey: matchedTraffic.key,
|
|
3074
|
+
traffic: matchedTraffic,
|
|
3075
|
+
};
|
|
3076
|
+
|
|
3077
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug("override from rule", evaluation);</span>
|
|
3078
|
+
|
|
3079
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3080
|
+
}
|
|
3081
|
+
|
|
3082
|
+
// treated as enabled because of matched traffic
|
|
3083
|
+
if (bucketValue < matchedTraffic.percentage) {
|
|
3084
|
+
// @TODO: verify if range check should be inclusive or not
|
|
3085
|
+
evaluation = {
|
|
3086
|
+
featureKey: feature.key,
|
|
3087
|
+
reason: EvaluationReason.RULE,
|
|
3088
|
+
enabled: true,
|
|
3089
|
+
bucketValue,
|
|
3090
|
+
ruleKey: matchedTraffic.key,
|
|
3091
|
+
traffic: matchedTraffic,
|
|
3092
|
+
};
|
|
3093
|
+
|
|
3094
|
+
return evaluation;
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
|
|
3098
|
+
// nothing matched
|
|
3099
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3100
|
+
featureKey: feature.key,
|
|
3101
|
+
reason: EvaluationReason.ERROR,
|
|
3102
|
+
enabled: false,
|
|
3103
|
+
bucketValue,
|
|
3104
|
+
};
|
|
3105
|
+
|
|
3106
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3107
|
+
} catch (e) {
|
|
3108
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3109
|
+
featureKey: typeof featureKey === "string" ? featureKey : featureKey.key,
|
|
3110
|
+
reason: EvaluationReason.ERROR,
|
|
3111
|
+
error: e,
|
|
3112
|
+
};
|
|
3113
|
+
|
|
3114
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
|
|
3118
|
+
isEnabled(featureKey: FeatureKey | Feature, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: boolean {
|
|
3119
|
+
try {
|
|
3120
|
+
const evaluation = this.evaluateFlag(featureKey, context);
|
|
3121
|
+
|
|
3122
|
+
return evaluation.enabled === true;
|
|
3123
|
+
} catch (e) {
|
|
3124
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error("isEnabled", { featureKey, error: e });</span>
|
|
3125
|
+
|
|
3126
|
+
<span class="cstat-no" title="statement not covered" > return false;</span>
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
2583
3129
|
|
|
2584
3130
|
/**
|
|
2585
3131
|
* Variation
|
|
2586
3132
|
*/
|
|
2587
|
-
evaluateVariation(featureKey: FeatureKey | Feature,
|
|
3133
|
+
evaluateVariation(featureKey: FeatureKey | Feature, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: Evaluation {
|
|
2588
3134
|
let evaluation: Evaluation;
|
|
2589
3135
|
|
|
2590
3136
|
try {
|
|
2591
3137
|
const key = typeof featureKey === "string" ? featureKey : <span class="branch-1 cbranch-no" title="branch not covered" >featureKey.key;</span>
|
|
3138
|
+
|
|
3139
|
+
const flag = this.evaluateFlag(featureKey, context);
|
|
3140
|
+
|
|
3141
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (flag.enabled === false) {
|
|
3142
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3143
|
+
featureKey: key,
|
|
3144
|
+
reason: EvaluationReason.DISABLED,
|
|
3145
|
+
};
|
|
3146
|
+
|
|
3147
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug("feature is disabled", evaluation);</span>
|
|
3148
|
+
|
|
3149
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3150
|
+
}
|
|
2592
3151
|
|
|
2593
3152
|
// sticky
|
|
2594
3153
|
if (this.stickyFeatures && this.stickyFeatures[key]) {
|
|
@@ -2637,17 +3196,27 @@ export class FeaturevisorInstance {
|
|
|
2637
3196
|
reason: EvaluationReason.NOT_FOUND,
|
|
2638
3197
|
};
|
|
2639
3198
|
|
|
2640
|
-
<span class="cstat-no" title="statement not covered" > this.logger.warn("feature not found
|
|
3199
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn("feature not found", evaluation);</span>
|
|
2641
3200
|
|
|
2642
3201
|
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
2643
3202
|
}
|
|
2644
3203
|
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
3204
|
+
// no variations
|
|
3205
|
+
<span class="missing-if-branch" title="if path not taken" >I</span>if (!feature.variations || feature.variations.length === 0) {
|
|
3206
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3207
|
+
featureKey: key,
|
|
3208
|
+
reason: EvaluationReason.NO_VARIATIONS,
|
|
3209
|
+
};
|
|
3210
|
+
|
|
3211
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn("no variations", evaluation);</span>
|
|
3212
|
+
|
|
3213
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3216
|
+
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
|
|
2648
3217
|
|
|
2649
3218
|
// forced
|
|
2650
|
-
const force = findForceFromFeature(feature,
|
|
3219
|
+
const force = findForceFromFeature(feature, context, this.datafileReader);
|
|
2651
3220
|
|
|
2652
3221
|
<span class="missing-if-branch" title="if path not taken" >I</span>if (force && <span class="branch-1 cbranch-no" title="branch not covered" >force.variation)</span> {
|
|
2653
3222
|
const variation = <span class="cstat-no" title="statement not covered" >feature.variations.find(<span class="fstat-no" title="function not covered" >(v</span>) => <span class="cstat-no" title="statement not covered" >v.value === force.variation)</span>;</span>
|
|
@@ -2666,11 +3235,11 @@ export class FeaturevisorInstance {
|
|
|
2666
3235
|
}
|
|
2667
3236
|
|
|
2668
3237
|
// bucketing
|
|
2669
|
-
const bucketValue = this.getBucketValue(feature,
|
|
3238
|
+
const bucketValue = this.getBucketValue(feature, finalContext);
|
|
2670
3239
|
|
|
2671
3240
|
const { matchedTraffic, matchedAllocation } = getMatchedTrafficAndAllocation(
|
|
2672
3241
|
feature.traffic,
|
|
2673
|
-
|
|
3242
|
+
finalContext,
|
|
2674
3243
|
bucketValue,
|
|
2675
3244
|
this.datafileReader,
|
|
2676
3245
|
this.logger,
|
|
@@ -2715,30 +3284,14 @@ export class FeaturevisorInstance {
|
|
|
2715
3284
|
}
|
|
2716
3285
|
}
|
|
2717
3286
|
|
|
2718
|
-
//
|
|
2719
|
-
const variation = <span class="cstat-no" title="statement not covered" >feature.variations.find(<span class="fstat-no" title="function not covered" >(v</span>) => <span class="cstat-no" title="statement not covered" >v.value === feature.defaultVariation)</span>;</span>
|
|
2720
|
-
|
|
2721
|
-
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (variation) {</span>
|
|
2722
|
-
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
2723
|
-
featureKey: feature.key,
|
|
2724
|
-
reason: EvaluationReason.DEFAULTED,
|
|
2725
|
-
bucketValue,
|
|
2726
|
-
variation,
|
|
2727
|
-
};
|
|
2728
|
-
|
|
2729
|
-
<span class="cstat-no" title="statement not covered" > this.logger.debug("using default variation", evaluation);</span>
|
|
2730
|
-
|
|
2731
|
-
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
2732
|
-
}
|
|
2733
|
-
|
|
2734
|
-
// nothing matched (this should never happen)
|
|
3287
|
+
// nothing matched
|
|
2735
3288
|
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
2736
3289
|
featureKey: feature.key,
|
|
2737
3290
|
reason: EvaluationReason.ERROR,
|
|
2738
3291
|
bucketValue,
|
|
2739
3292
|
};
|
|
2740
3293
|
|
|
2741
|
-
<span class="cstat-no" title="statement not covered" > this.logger.
|
|
3294
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug("no matched variation", evaluation);</span>
|
|
2742
3295
|
|
|
2743
3296
|
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
2744
3297
|
} catch (e) {
|
|
@@ -2754,10 +3307,10 @@ export class FeaturevisorInstance {
|
|
|
2754
3307
|
|
|
2755
3308
|
getVariation(
|
|
2756
3309
|
featureKey: FeatureKey | Feature,
|
|
2757
|
-
|
|
3310
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2758
3311
|
): VariationValue | undefined {
|
|
2759
3312
|
try {
|
|
2760
|
-
const evaluation = this.evaluateVariation(featureKey,
|
|
3313
|
+
const evaluation = this.evaluateVariation(featureKey, context);
|
|
2761
3314
|
|
|
2762
3315
|
if (typeof evaluation.variationValue !== "undefined") {
|
|
2763
3316
|
return evaluation.variationValue;
|
|
@@ -2774,49 +3327,13 @@ export class FeaturevisorInstance {
|
|
|
2774
3327
|
<span class="cstat-no" title="statement not covered" > return undefined;</span>
|
|
2775
3328
|
}
|
|
2776
3329
|
}
|
|
2777
|
-
|
|
2778
|
-
<span class="fstat-no" title="function not covered" > getVariationBoolean(</span>
|
|
2779
|
-
featureKey: FeatureKey | Feature,
|
|
2780
|
-
attributes: Attributes = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2781
|
-
): boolean | undefined {
|
|
2782
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, attributes);</span>
|
|
2783
|
-
|
|
2784
|
-
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "boolean") as boolean | undefined;</span>
|
|
2785
|
-
}
|
|
2786
|
-
|
|
2787
|
-
<span class="fstat-no" title="function not covered" > getVariationString(</span>
|
|
2788
|
-
featureKey: FeatureKey | Feature,
|
|
2789
|
-
attributes: Attributes = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2790
|
-
): string | undefined {
|
|
2791
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, attributes);</span>
|
|
2792
|
-
|
|
2793
|
-
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "string") as string | undefined;</span>
|
|
2794
|
-
}
|
|
2795
|
-
|
|
2796
|
-
<span class="fstat-no" title="function not covered" > getVariationInteger(</span>
|
|
2797
|
-
featureKey: FeatureKey | Feature,
|
|
2798
|
-
attributes: Attributes = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2799
|
-
): number | undefined {
|
|
2800
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, attributes);</span>
|
|
2801
|
-
|
|
2802
|
-
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "integer") as number | undefined;</span>
|
|
2803
|
-
}
|
|
2804
|
-
|
|
2805
|
-
<span class="fstat-no" title="function not covered" > getVariationDouble(</span>
|
|
2806
|
-
featureKey: FeatureKey | Feature,
|
|
2807
|
-
attributes: Attributes = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2808
|
-
): number | undefined {
|
|
2809
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, attributes);</span>
|
|
2810
|
-
|
|
2811
|
-
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "double") as number | undefined;</span>
|
|
2812
|
-
}
|
|
2813
3330
|
|
|
2814
3331
|
/**
|
|
2815
3332
|
* Activate
|
|
2816
3333
|
*/
|
|
2817
|
-
activate(featureKey: FeatureKey,
|
|
3334
|
+
activate(featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: VariationValue | undefined {
|
|
2818
3335
|
try {
|
|
2819
|
-
const evaluation = this.evaluateVariation(featureKey,
|
|
3336
|
+
const evaluation = this.evaluateVariation(featureKey, context);
|
|
2820
3337
|
const variationValue = evaluation.variation
|
|
2821
3338
|
? evaluation.variation.value
|
|
2822
3339
|
: <span class="branch-1 cbranch-no" title="branch not covered" >evaluation.variationValue;</span>
|
|
@@ -2825,19 +3342,17 @@ export class FeaturevisorInstance {
|
|
|
2825
3342
|
<span class="cstat-no" title="statement not covered" > return undefined;</span>
|
|
2826
3343
|
}
|
|
2827
3344
|
|
|
2828
|
-
const
|
|
2829
|
-
? <span class="branch-0 cbranch-no" title="branch not covered" >this.interceptAttributes(attributes)</span>
|
|
2830
|
-
: attributes;
|
|
3345
|
+
const finalContext = this.interceptContext ? <span class="branch-0 cbranch-no" title="branch not covered" >this.interceptContext(context) </span>: context;
|
|
2831
3346
|
|
|
2832
|
-
const
|
|
3347
|
+
const captureContext: Context = {};
|
|
2833
3348
|
|
|
2834
3349
|
const attributesForCapturing = this.datafileReader
|
|
2835
3350
|
.getAllAttributes()
|
|
2836
3351
|
.filter(<span class="fstat-no" title="function not covered" >(a</span>) => <span class="cstat-no" title="statement not covered" >a.capture === true)</span>;
|
|
2837
3352
|
|
|
2838
3353
|
attributesForCapturing.forEach(<span class="fstat-no" title="function not covered" >(a</span>) => {
|
|
2839
|
-
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof
|
|
2840
|
-
<span class="cstat-no" title="statement not covered" >
|
|
3354
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof finalContext[a.key] !== "undefined") {</span>
|
|
3355
|
+
<span class="cstat-no" title="statement not covered" > captureContext[a.key] = context[a.key];</span>
|
|
2841
3356
|
}
|
|
2842
3357
|
});
|
|
2843
3358
|
|
|
@@ -2845,8 +3360,8 @@ export class FeaturevisorInstance {
|
|
|
2845
3360
|
"activation",
|
|
2846
3361
|
featureKey,
|
|
2847
3362
|
variationValue,
|
|
2848
|
-
|
|
2849
|
-
|
|
3363
|
+
finalContext,
|
|
3364
|
+
captureContext,
|
|
2850
3365
|
evaluation,
|
|
2851
3366
|
);
|
|
2852
3367
|
|
|
@@ -2858,26 +3373,26 @@ export class FeaturevisorInstance {
|
|
|
2858
3373
|
}
|
|
2859
3374
|
}
|
|
2860
3375
|
|
|
2861
|
-
<span class="fstat-no" title="function not covered" > activateBoolean(</span>featureKey: FeatureKey,
|
|
2862
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey,
|
|
3376
|
+
<span class="fstat-no" title="function not covered" > activateBoolean(</span>featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: boolean | undefined {
|
|
3377
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey, context);</span>
|
|
2863
3378
|
|
|
2864
3379
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "boolean") as boolean | undefined;</span>
|
|
2865
3380
|
}
|
|
2866
3381
|
|
|
2867
|
-
<span class="fstat-no" title="function not covered" > activateString(</span>featureKey: FeatureKey,
|
|
2868
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey,
|
|
3382
|
+
<span class="fstat-no" title="function not covered" > activateString(</span>featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: string | undefined {
|
|
3383
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey, context);</span>
|
|
2869
3384
|
|
|
2870
3385
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "string") as string | undefined;</span>
|
|
2871
3386
|
}
|
|
2872
3387
|
|
|
2873
|
-
<span class="fstat-no" title="function not covered" > activateInteger(</span>featureKey: FeatureKey,
|
|
2874
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey,
|
|
3388
|
+
<span class="fstat-no" title="function not covered" > activateInteger(</span>featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: number | undefined {
|
|
3389
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey, context);</span>
|
|
2875
3390
|
|
|
2876
3391
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "integer") as number | undefined;</span>
|
|
2877
3392
|
}
|
|
2878
3393
|
|
|
2879
|
-
<span class="fstat-no" title="function not covered" > activateDouble(</span>featureKey: FeatureKey,
|
|
2880
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey,
|
|
3394
|
+
<span class="fstat-no" title="function not covered" > activateDouble(</span>featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: number | undefined {
|
|
3395
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey, context);</span>
|
|
2881
3396
|
|
|
2882
3397
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "double") as number | undefined;</span>
|
|
2883
3398
|
}
|
|
@@ -2888,28 +3403,45 @@ export class FeaturevisorInstance {
|
|
|
2888
3403
|
<span class="fstat-no" title="function not covered" > evaluateVariable(</span>
|
|
2889
3404
|
featureKey: FeatureKey | Feature,
|
|
2890
3405
|
variableKey: VariableKey,
|
|
2891
|
-
|
|
3406
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2892
3407
|
): Evaluation {
|
|
2893
3408
|
let evaluation: Evaluation;
|
|
2894
3409
|
|
|
2895
3410
|
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
2896
3411
|
const key = <span class="cstat-no" title="statement not covered" >typeof featureKey === "string" ? featureKey : featureKey.key;</span>
|
|
3412
|
+
|
|
3413
|
+
const flag = <span class="cstat-no" title="statement not covered" >this.evaluateFlag(featureKey, context);</span>
|
|
3414
|
+
|
|
3415
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (flag.enabled === false) {</span>
|
|
3416
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3417
|
+
featureKey: key,
|
|
3418
|
+
reason: EvaluationReason.DISABLED,
|
|
3419
|
+
};
|
|
3420
|
+
|
|
3421
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug("feature is disabled", evaluation);</span>
|
|
3422
|
+
|
|
3423
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3424
|
+
}
|
|
2897
3425
|
|
|
2898
3426
|
// sticky
|
|
2899
|
-
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (this.stickyFeatures && this.stickyFeatures[key]
|
|
2900
|
-
const
|
|
3427
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (this.stickyFeatures && this.stickyFeatures[key]) {</span>
|
|
3428
|
+
const variables = <span class="cstat-no" title="statement not covered" >this.stickyFeatures[key].variables;</span>
|
|
2901
3429
|
|
|
2902
|
-
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (
|
|
2903
|
-
<span class="cstat-no" title="statement not covered" >
|
|
2904
|
-
featureKey: key,
|
|
2905
|
-
reason: EvaluationReason.STICKY,
|
|
2906
|
-
variableKey,
|
|
2907
|
-
variableValue: result,
|
|
2908
|
-
};
|
|
3430
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (variables) {</span>
|
|
3431
|
+
const result = <span class="cstat-no" title="statement not covered" >variables[variableKey];</span>
|
|
2909
3432
|
|
|
2910
|
-
<span class="cstat-no" title="statement not covered" >
|
|
3433
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof result !== "undefined") {</span>
|
|
3434
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3435
|
+
featureKey: key,
|
|
3436
|
+
reason: EvaluationReason.STICKY,
|
|
3437
|
+
variableKey,
|
|
3438
|
+
variableValue: result,
|
|
3439
|
+
};
|
|
2911
3440
|
|
|
2912
|
-
<span class="cstat-no" title="statement not covered" >
|
|
3441
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug("using sticky variable", evaluation);</span>
|
|
3442
|
+
|
|
3443
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3444
|
+
}
|
|
2913
3445
|
}
|
|
2914
3446
|
}
|
|
2915
3447
|
|
|
@@ -2918,20 +3450,24 @@ export class FeaturevisorInstance {
|
|
|
2918
3450
|
this.statuses &&
|
|
2919
3451
|
!this.statuses.ready &&
|
|
2920
3452
|
this.initialFeatures &&
|
|
2921
|
-
this.initialFeatures[key]
|
|
2922
|
-
this.initialFeatures[key].variables &&
|
|
2923
|
-
typeof this.initialFeatures[key].variables[variableKey] !== "undefined"
|
|
3453
|
+
this.initialFeatures[key]
|
|
2924
3454
|
) {
|
|
2925
|
-
<span class="cstat-no" title="statement not covered" >
|
|
2926
|
-
featureKey: key,
|
|
2927
|
-
reason: EvaluationReason.INITIAL,
|
|
2928
|
-
variableKey,
|
|
2929
|
-
variableValue: this.initialFeatures[key].variables[variableKey],
|
|
2930
|
-
};
|
|
3455
|
+
const variables = <span class="cstat-no" title="statement not covered" >this.initialFeatures[key].variables;</span>
|
|
2931
3456
|
|
|
2932
|
-
<span class="cstat-no" title="statement not covered" >
|
|
3457
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (variables) {</span>
|
|
3458
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof variables[variableKey] !== "undefined") {</span>
|
|
3459
|
+
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
3460
|
+
featureKey: key,
|
|
3461
|
+
reason: EvaluationReason.INITIAL,
|
|
3462
|
+
variableKey,
|
|
3463
|
+
variableValue: variables[variableKey],
|
|
3464
|
+
};
|
|
2933
3465
|
|
|
2934
|
-
<span class="cstat-no" title="statement not covered" >
|
|
3466
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug("using initial variable", evaluation);</span>
|
|
3467
|
+
|
|
3468
|
+
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
2935
3471
|
}
|
|
2936
3472
|
|
|
2937
3473
|
const feature = <span class="cstat-no" title="statement not covered" >this.getFeature(featureKey);</span>
|
|
@@ -2966,12 +3502,10 @@ export class FeaturevisorInstance {
|
|
|
2966
3502
|
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
2967
3503
|
}
|
|
2968
3504
|
|
|
2969
|
-
const
|
|
2970
|
-
? this.interceptAttributes(attributes)
|
|
2971
|
-
: attributes;
|
|
3505
|
+
const finalContext = <span class="cstat-no" title="statement not covered" >this.interceptContext ? this.interceptContext(context) : context;</span>
|
|
2972
3506
|
|
|
2973
3507
|
// forced
|
|
2974
|
-
const force = <span class="cstat-no" title="statement not covered" >findForceFromFeature(feature,
|
|
3508
|
+
const force = <span class="cstat-no" title="statement not covered" >findForceFromFeature(feature, context, this.datafileReader);</span>
|
|
2975
3509
|
|
|
2976
3510
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (force && force.variables && typeof force.variables[variableKey] !== "undefined") {</span>
|
|
2977
3511
|
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
@@ -2988,11 +3522,11 @@ export class FeaturevisorInstance {
|
|
|
2988
3522
|
}
|
|
2989
3523
|
|
|
2990
3524
|
// bucketing
|
|
2991
|
-
const bucketValue = <span class="cstat-no" title="statement not covered" >this.getBucketValue(feature,
|
|
3525
|
+
const bucketValue = <span class="cstat-no" title="statement not covered" >this.getBucketValue(feature, finalContext);</span>
|
|
2992
3526
|
|
|
2993
3527
|
const { matchedTraffic, matchedAllocation } = <span class="cstat-no" title="statement not covered" >getMatchedTrafficAndAllocation(</span>
|
|
2994
3528
|
feature.traffic,
|
|
2995
|
-
|
|
3529
|
+
finalContext,
|
|
2996
3530
|
bucketValue,
|
|
2997
3531
|
this.datafileReader,
|
|
2998
3532
|
this.logger,
|
|
@@ -3020,7 +3554,7 @@ export class FeaturevisorInstance {
|
|
|
3020
3554
|
}
|
|
3021
3555
|
|
|
3022
3556
|
// regular allocation
|
|
3023
|
-
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (matchedAllocation && matchedAllocation.variation) {</span>
|
|
3557
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (matchedAllocation && matchedAllocation.variation && Array.isArray(feature.variations)) {</span>
|
|
3024
3558
|
const variation = <span class="cstat-no" title="statement not covered" >feature.variations.find(<span class="fstat-no" title="function not covered" >(v</span>) => <span class="cstat-no" title="statement not covered" >v.value === matchedAllocation.variation)</span>;</span>
|
|
3025
3559
|
|
|
3026
3560
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (variation && variation.variables) {</span>
|
|
@@ -3032,7 +3566,7 @@ export class FeaturevisorInstance {
|
|
|
3032
3566
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (o.conditions) {</span>
|
|
3033
3567
|
<span class="cstat-no" title="statement not covered" > return allConditionsAreMatched(</span>
|
|
3034
3568
|
typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions,
|
|
3035
|
-
|
|
3569
|
+
finalContext,
|
|
3036
3570
|
);
|
|
3037
3571
|
}
|
|
3038
3572
|
|
|
@@ -3041,7 +3575,7 @@ export class FeaturevisorInstance {
|
|
|
3041
3575
|
typeof o.segments === "string" && o.segments !== "*"
|
|
3042
3576
|
? JSON.parse(o.segments)
|
|
3043
3577
|
: o.segments,
|
|
3044
|
-
|
|
3578
|
+
finalContext,
|
|
3045
3579
|
this.datafileReader,
|
|
3046
3580
|
);
|
|
3047
3581
|
}
|
|
@@ -3114,10 +3648,10 @@ export class FeaturevisorInstance {
|
|
|
3114
3648
|
<span class="fstat-no" title="function not covered" > getVariable(</span>
|
|
3115
3649
|
featureKey: FeatureKey | Feature,
|
|
3116
3650
|
variableKey: string,
|
|
3117
|
-
|
|
3651
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3118
3652
|
): VariableValue | undefined {
|
|
3119
3653
|
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
3120
|
-
const evaluation = <span class="cstat-no" title="statement not covered" >this.evaluateVariable(featureKey, variableKey,
|
|
3654
|
+
const evaluation = <span class="cstat-no" title="statement not covered" >this.evaluateVariable(featureKey, variableKey, context);</span>
|
|
3121
3655
|
|
|
3122
3656
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof evaluation.variableValue !== "undefined") {</span>
|
|
3123
3657
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (</span>
|
|
@@ -3142,9 +3676,9 @@ export class FeaturevisorInstance {
|
|
|
3142
3676
|
<span class="fstat-no" title="function not covered" > getVariableBoolean(</span>
|
|
3143
3677
|
featureKey: FeatureKey | Feature,
|
|
3144
3678
|
variableKey: string,
|
|
3145
|
-
|
|
3679
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3146
3680
|
): boolean | undefined {
|
|
3147
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3681
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3148
3682
|
|
|
3149
3683
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "boolean") as boolean | undefined;</span>
|
|
3150
3684
|
}
|
|
@@ -3152,9 +3686,9 @@ export class FeaturevisorInstance {
|
|
|
3152
3686
|
<span class="fstat-no" title="function not covered" > getVariableString(</span>
|
|
3153
3687
|
featureKey: FeatureKey | Feature,
|
|
3154
3688
|
variableKey: string,
|
|
3155
|
-
|
|
3689
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3156
3690
|
): string | undefined {
|
|
3157
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3691
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3158
3692
|
|
|
3159
3693
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "string") as string | undefined;</span>
|
|
3160
3694
|
}
|
|
@@ -3162,9 +3696,9 @@ export class FeaturevisorInstance {
|
|
|
3162
3696
|
<span class="fstat-no" title="function not covered" > getVariableInteger(</span>
|
|
3163
3697
|
featureKey: FeatureKey | Feature,
|
|
3164
3698
|
variableKey: string,
|
|
3165
|
-
|
|
3699
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3166
3700
|
): number | undefined {
|
|
3167
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3701
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3168
3702
|
|
|
3169
3703
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "integer") as number | undefined;</span>
|
|
3170
3704
|
}
|
|
@@ -3172,9 +3706,9 @@ export class FeaturevisorInstance {
|
|
|
3172
3706
|
<span class="fstat-no" title="function not covered" > getVariableDouble(</span>
|
|
3173
3707
|
featureKey: FeatureKey | Feature,
|
|
3174
3708
|
variableKey: string,
|
|
3175
|
-
|
|
3709
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3176
3710
|
): number | undefined {
|
|
3177
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3711
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3178
3712
|
|
|
3179
3713
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "double") as number | undefined;</span>
|
|
3180
3714
|
}
|
|
@@ -3182,9 +3716,9 @@ export class FeaturevisorInstance {
|
|
|
3182
3716
|
<span class="fstat-no" title="function not covered" > getVariableArray(</span>
|
|
3183
3717
|
featureKey: FeatureKey | Feature,
|
|
3184
3718
|
variableKey: string,
|
|
3185
|
-
|
|
3719
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3186
3720
|
): string[] | undefined {
|
|
3187
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3721
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3188
3722
|
|
|
3189
3723
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "array") as string[] | undefined;</span>
|
|
3190
3724
|
}
|
|
@@ -3192,9 +3726,9 @@ export class FeaturevisorInstance {
|
|
|
3192
3726
|
<span class="fstat-no" title="function not covered" > getVariableObject<</span>T>(
|
|
3193
3727
|
featureKey: FeatureKey | Feature,
|
|
3194
3728
|
variableKey: string,
|
|
3195
|
-
|
|
3729
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3196
3730
|
): T | undefined {
|
|
3197
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3731
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3198
3732
|
|
|
3199
3733
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "object") as T | undefined;</span>
|
|
3200
3734
|
}
|
|
@@ -3202,9 +3736,9 @@ export class FeaturevisorInstance {
|
|
|
3202
3736
|
<span class="fstat-no" title="function not covered" > getVariableJSON<</span>T>(
|
|
3203
3737
|
featureKey: FeatureKey | Feature,
|
|
3204
3738
|
variableKey: string,
|
|
3205
|
-
|
|
3739
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3206
3740
|
): T | undefined {
|
|
3207
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3741
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3208
3742
|
|
|
3209
3743
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "json") as T | undefined;</span>
|
|
3210
3744
|
}
|
|
@@ -3220,7 +3754,7 @@ export function createInstance(options: InstanceOptions): FeaturevisorInstance {
|
|
|
3220
3754
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
3221
3755
|
Code coverage generated by
|
|
3222
3756
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
3223
|
-
at 2023-07-
|
|
3757
|
+
at 2023-07-16T19:53:34.344Z
|
|
3224
3758
|
</div>
|
|
3225
3759
|
<script src="prettify.js"></script>
|
|
3226
3760
|
<script>
|