@prosopo/provider 3.12.14 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/api/captcha/getFrictionlessCaptchaChallenge.js +338 -0
  3. package/dist/api/captcha/getImageCaptchaChallenge.js +150 -0
  4. package/dist/api/captcha/getPoWCaptchaChallenge.js +156 -0
  5. package/dist/api/captcha/submitImageCaptchaSolution.js +87 -0
  6. package/dist/api/captcha/submitPoWCaptchaSolution.js +77 -0
  7. package/dist/api/captcha.js +18 -696
  8. package/dist/api/verify.js +2 -1
  9. package/dist/cjs/api/captcha/getFrictionlessCaptchaChallenge.cjs +337 -0
  10. package/dist/cjs/api/captcha/getImageCaptchaChallenge.cjs +149 -0
  11. package/dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs +155 -0
  12. package/dist/cjs/api/captcha/submitImageCaptchaSolution.cjs +86 -0
  13. package/dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs +76 -0
  14. package/dist/cjs/api/captcha.cjs +17 -695
  15. package/dist/cjs/api/verify.cjs +2 -1
  16. package/dist/cjs/index.cjs +2 -0
  17. package/dist/cjs/schedulers/setClientEntropy.cjs +36 -0
  18. package/dist/cjs/tasks/captchaManager.cjs +2 -1
  19. package/dist/cjs/tasks/client/clientTasks.cjs +15 -0
  20. package/dist/cjs/tasks/detection/decodePayload.cjs +379 -609
  21. package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +28 -9
  22. package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +8 -2
  23. package/dist/cjs/tasks/powCaptcha/powTasks.cjs +2 -2
  24. package/dist/cjs/tasks/tasks.cjs +1 -0
  25. package/dist/cjs/utils/hashUserIp.cjs +9 -0
  26. package/dist/index.js +2 -0
  27. package/dist/schedulers/setClientEntropy.js +29 -24
  28. package/dist/tasks/captchaManager.js +2 -1
  29. package/dist/tasks/client/clientTasks.js +16 -1
  30. package/dist/tasks/detection/decodePayload.js +379 -609
  31. package/dist/tasks/detection/getBotScore.js +2 -2
  32. package/dist/tasks/frictionless/frictionlessTasks.js +29 -10
  33. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +8 -2
  34. package/dist/tasks/powCaptcha/powTasks.js +2 -2
  35. package/dist/tasks/tasks.js +1 -0
  36. package/dist/utils/hashUserIp.js +9 -0
  37. package/package.json +18 -18
  38. package/coverage/base.css +0 -224
  39. package/coverage/block-navigation.js +0 -87
  40. package/coverage/clover.xml +0 -4278
  41. package/coverage/coverage-final.json +0 -42
  42. package/coverage/favicon.png +0 -0
  43. package/coverage/index.html +0 -311
  44. package/coverage/prettify.css +0 -1
  45. package/coverage/prettify.js +0 -2
  46. package/coverage/sort-arrow-sprite.png +0 -0
  47. package/coverage/sorter.js +0 -210
  48. package/coverage/src/api/admin/apiAdminRoutesProvider.ts.html +0 -214
  49. package/coverage/src/api/admin/apiRegisterSiteKeyEndpoint.ts.html +0 -259
  50. package/coverage/src/api/admin/apiRemoveDetectorKeyEndpoint.ts.html +0 -283
  51. package/coverage/src/api/admin/apiToggleMaintenanceModeEndpoint.ts.html +0 -334
  52. package/coverage/src/api/admin/apiUpdateDetectorKeyEndpoint.ts.html +0 -298
  53. package/coverage/src/api/admin/createApiAdminRoutesProvider.ts.html +0 -163
  54. package/coverage/src/api/admin/index.html +0 -191
  55. package/coverage/src/api/blacklistRequestInspector.ts.html +0 -751
  56. package/coverage/src/api/block.ts.html +0 -187
  57. package/coverage/src/api/captcha.ts.html +0 -2803
  58. package/coverage/src/api/domainMiddleware.ts.html +0 -493
  59. package/coverage/src/api/headerCheckMiddleware.ts.html +0 -256
  60. package/coverage/src/api/ignoreMiddleware.ts.html +0 -181
  61. package/coverage/src/api/index.html +0 -266
  62. package/coverage/src/api/ja4Middleware.ts.html +0 -400
  63. package/coverage/src/api/public.ts.html +0 -343
  64. package/coverage/src/api/robotsMiddleware.ts.html +0 -157
  65. package/coverage/src/api/validateAddress.ts.html +0 -214
  66. package/coverage/src/api/verify.ts.html +0 -871
  67. package/coverage/src/compositeIpAddress.ts.html +0 -340
  68. package/coverage/src/index.html +0 -161
  69. package/coverage/src/index.ts.html +0 -175
  70. package/coverage/src/pairs.ts.html +0 -238
  71. package/coverage/src/rules/index.html +0 -116
  72. package/coverage/src/rules/lang.ts.html +0 -187
  73. package/coverage/src/schedulers/captchaScheduler.ts.html +0 -250
  74. package/coverage/src/schedulers/getClientList.ts.html +0 -271
  75. package/coverage/src/schedulers/index.html +0 -131
  76. package/coverage/src/services/index.html +0 -131
  77. package/coverage/src/services/ipComparison.ts.html +0 -685
  78. package/coverage/src/services/ipInfo.ts.html +0 -490
  79. package/coverage/src/tasks/captchaManager.ts.html +0 -865
  80. package/coverage/src/tasks/client/clientTasks.ts.html +0 -1381
  81. package/coverage/src/tasks/client/index.html +0 -116
  82. package/coverage/src/tasks/dataset/datasetTasks.ts.html +0 -268
  83. package/coverage/src/tasks/dataset/datasetTasksUtils.ts.html +0 -271
  84. package/coverage/src/tasks/dataset/index.html +0 -131
  85. package/coverage/src/tasks/detection/decodePayload.js.html +0 -127
  86. package/coverage/src/tasks/detection/getBotScore.ts.html +0 -244
  87. package/coverage/src/tasks/detection/index.html +0 -131
  88. package/coverage/src/tasks/frictionless/frictionlessTasks.ts.html +0 -1216
  89. package/coverage/src/tasks/frictionless/frictionlessTasksUtils.ts.html +0 -247
  90. package/coverage/src/tasks/frictionless/index.html +0 -131
  91. package/coverage/src/tasks/imgCaptcha/imgCaptchaTasks.ts.html +0 -1972
  92. package/coverage/src/tasks/imgCaptcha/imgCaptchaTasksUtils.ts.html +0 -232
  93. package/coverage/src/tasks/imgCaptcha/index.html +0 -131
  94. package/coverage/src/tasks/index.html +0 -146
  95. package/coverage/src/tasks/index.ts.html +0 -127
  96. package/coverage/src/tasks/powCaptcha/index.html +0 -131
  97. package/coverage/src/tasks/powCaptcha/powTasks.ts.html +0 -961
  98. package/coverage/src/tasks/powCaptcha/powTasksUtils.ts.html +0 -244
  99. package/coverage/src/tasks/tasks.ts.html +0 -388
  100. package/coverage/src/util.ts.html +0 -1627
  101. package/coverage/src/utils/hashUserAgent.ts.html +0 -184
  102. package/coverage/src/utils/index.html +0 -116
  103. package/dist/api/admin/apiAdminRoutesProvider.d.ts +0 -9
  104. package/dist/api/admin/apiAdminRoutesProvider.d.ts.map +0 -1
  105. package/dist/api/admin/apiAdminRoutesProvider.js.map +0 -1
  106. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts +0 -14
  107. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts.map +0 -1
  108. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js.map +0 -1
  109. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts +0 -23
  110. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts.map +0 -1
  111. package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js.map +0 -1
  112. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts +0 -13
  113. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts.map +0 -1
  114. package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js.map +0 -1
  115. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.d.ts +0 -14
  116. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.d.ts.map +0 -1
  117. package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js.map +0 -1
  118. package/dist/api/admin/createApiAdminRoutesProvider.d.ts +0 -4
  119. package/dist/api/admin/createApiAdminRoutesProvider.d.ts.map +0 -1
  120. package/dist/api/admin/createApiAdminRoutesProvider.js.map +0 -1
  121. package/dist/api/blacklistRequestInspector.d.ts +0 -19
  122. package/dist/api/blacklistRequestInspector.d.ts.map +0 -1
  123. package/dist/api/blacklistRequestInspector.js.map +0 -1
  124. package/dist/api/block.d.ts +0 -3
  125. package/dist/api/block.d.ts.map +0 -1
  126. package/dist/api/block.js.map +0 -1
  127. package/dist/api/captcha.d.ts +0 -4
  128. package/dist/api/captcha.d.ts.map +0 -1
  129. package/dist/api/captcha.js.map +0 -1
  130. package/dist/api/domainMiddleware.d.ts +0 -4
  131. package/dist/api/domainMiddleware.d.ts.map +0 -1
  132. package/dist/api/domainMiddleware.js.map +0 -1
  133. package/dist/api/headerCheckMiddleware.d.ts +0 -4
  134. package/dist/api/headerCheckMiddleware.d.ts.map +0 -1
  135. package/dist/api/headerCheckMiddleware.js.map +0 -1
  136. package/dist/api/ignoreMiddleware.d.ts +0 -3
  137. package/dist/api/ignoreMiddleware.d.ts.map +0 -1
  138. package/dist/api/ignoreMiddleware.js.map +0 -1
  139. package/dist/api/ja4Middleware.d.ts +0 -10
  140. package/dist/api/ja4Middleware.d.ts.map +0 -1
  141. package/dist/api/ja4Middleware.js.map +0 -1
  142. package/dist/api/public.d.ts +0 -4
  143. package/dist/api/public.d.ts.map +0 -1
  144. package/dist/api/public.js.map +0 -1
  145. package/dist/api/robotsMiddleware.d.ts +0 -3
  146. package/dist/api/robotsMiddleware.d.ts.map +0 -1
  147. package/dist/api/robotsMiddleware.js.map +0 -1
  148. package/dist/api/validateAddress.d.ts +0 -5
  149. package/dist/api/validateAddress.d.ts.map +0 -1
  150. package/dist/api/validateAddress.js.map +0 -1
  151. package/dist/api/verify.d.ts +0 -4
  152. package/dist/api/verify.d.ts.map +0 -1
  153. package/dist/api/verify.js.map +0 -1
  154. package/dist/compositeIpAddress.d.ts +0 -5
  155. package/dist/compositeIpAddress.d.ts.map +0 -1
  156. package/dist/compositeIpAddress.js.map +0 -1
  157. package/dist/index.d.ts +0 -17
  158. package/dist/index.d.ts.map +0 -1
  159. package/dist/index.js.map +0 -1
  160. package/dist/pairs.d.ts +0 -3
  161. package/dist/pairs.d.ts.map +0 -1
  162. package/dist/pairs.js.map +0 -1
  163. package/dist/rules/lang.d.ts +0 -3
  164. package/dist/rules/lang.d.ts.map +0 -1
  165. package/dist/rules/lang.js.map +0 -1
  166. package/dist/schedulers/captchaScheduler.d.ts +0 -4
  167. package/dist/schedulers/captchaScheduler.d.ts.map +0 -1
  168. package/dist/schedulers/captchaScheduler.js.map +0 -1
  169. package/dist/schedulers/getClientList.d.ts +0 -4
  170. package/dist/schedulers/getClientList.d.ts.map +0 -1
  171. package/dist/schedulers/getClientList.js.map +0 -1
  172. package/dist/schedulers/setClientEntropy.d.ts +0 -4
  173. package/dist/schedulers/setClientEntropy.d.ts.map +0 -1
  174. package/dist/schedulers/setClientEntropy.js.map +0 -1
  175. package/dist/services/ipComparison.d.ts +0 -3
  176. package/dist/services/ipComparison.d.ts.map +0 -1
  177. package/dist/services/ipComparison.js.map +0 -1
  178. package/dist/services/ipInfo.d.ts +0 -3
  179. package/dist/services/ipInfo.d.ts.map +0 -1
  180. package/dist/services/ipInfo.js.map +0 -1
  181. package/dist/tasks/captchaManager.d.ts +0 -34
  182. package/dist/tasks/captchaManager.d.ts.map +0 -1
  183. package/dist/tasks/captchaManager.js.map +0 -1
  184. package/dist/tasks/client/clientTasks.d.ts +0 -21
  185. package/dist/tasks/client/clientTasks.d.ts.map +0 -1
  186. package/dist/tasks/client/clientTasks.js.map +0 -1
  187. package/dist/tasks/dataset/datasetTasks.d.ts +0 -13
  188. package/dist/tasks/dataset/datasetTasks.d.ts.map +0 -1
  189. package/dist/tasks/dataset/datasetTasks.js.map +0 -1
  190. package/dist/tasks/dataset/datasetTasksUtils.d.ts +0 -3
  191. package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +0 -1
  192. package/dist/tasks/dataset/datasetTasksUtils.js.map +0 -1
  193. package/dist/tasks/detection/decodePayload.d.ts +0 -5
  194. package/dist/tasks/detection/decodePayload.d.ts.map +0 -1
  195. package/dist/tasks/detection/decodePayload.js.map +0 -1
  196. package/dist/tasks/detection/getBotScore.d.ts +0 -20
  197. package/dist/tasks/detection/getBotScore.d.ts.map +0 -1
  198. package/dist/tasks/detection/getBotScore.js.map +0 -1
  199. package/dist/tasks/frictionless/frictionlessTasks.d.ts +0 -67
  200. package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +0 -1
  201. package/dist/tasks/frictionless/frictionlessTasks.js.map +0 -1
  202. package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts +0 -6
  203. package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts.map +0 -1
  204. package/dist/tasks/frictionless/frictionlessTasksUtils.js.map +0 -1
  205. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +0 -30
  206. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +0 -1
  207. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +0 -1
  208. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +0 -7
  209. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +0 -1
  210. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +0 -1
  211. package/dist/tasks/index.d.ts +0 -2
  212. package/dist/tasks/index.d.ts.map +0 -1
  213. package/dist/tasks/index.js.map +0 -1
  214. package/dist/tasks/powCaptcha/powTasks.d.ts +0 -17
  215. package/dist/tasks/powCaptcha/powTasks.d.ts.map +0 -1
  216. package/dist/tasks/powCaptcha/powTasks.js.map +0 -1
  217. package/dist/tasks/powCaptcha/powTasksUtils.d.ts +0 -3
  218. package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +0 -1
  219. package/dist/tasks/powCaptcha/powTasksUtils.js.map +0 -1
  220. package/dist/tasks/tasks.d.ts +0 -25
  221. package/dist/tasks/tasks.d.ts.map +0 -1
  222. package/dist/tasks/tasks.js.map +0 -1
  223. package/dist/tests/index.d.ts +0 -2
  224. package/dist/tests/index.d.ts.map +0 -1
  225. package/dist/tests/index.js +0 -2
  226. package/dist/tests/index.js.map +0 -1
  227. package/dist/tests/integration/accessRules.integration.test.d.ts +0 -2
  228. package/dist/tests/integration/accessRules.integration.test.d.ts.map +0 -1
  229. package/dist/tests/integration/accessRules.integration.test.js +0 -588
  230. package/dist/tests/integration/accessRules.integration.test.js.map +0 -1
  231. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.d.ts +0 -2
  232. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.d.ts.map +0 -1
  233. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js +0 -60
  234. package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js.map +0 -1
  235. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.d.ts +0 -2
  236. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.d.ts.map +0 -1
  237. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js +0 -368
  238. package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js.map +0 -1
  239. package/dist/tests/integration/imgCaptcha.integration.test.d.ts +0 -2
  240. package/dist/tests/integration/imgCaptcha.integration.test.d.ts.map +0 -1
  241. package/dist/tests/integration/imgCaptcha.integration.test.js +0 -272
  242. package/dist/tests/integration/imgCaptcha.integration.test.js.map +0 -1
  243. package/dist/tests/integration/ipValidation.integration.test.d.ts +0 -2
  244. package/dist/tests/integration/ipValidation.integration.test.d.ts.map +0 -1
  245. package/dist/tests/integration/ipValidation.integration.test.js +0 -75
  246. package/dist/tests/integration/ipValidation.integration.test.js.map +0 -1
  247. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts +0 -32
  248. package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts.map +0 -1
  249. package/dist/tests/integration/mocks/solvedTestCaptchas.js +0 -1046
  250. package/dist/tests/integration/mocks/solvedTestCaptchas.js.map +0 -1
  251. package/dist/tests/integration/powCaptcha.integration.test.d.ts +0 -2
  252. package/dist/tests/integration/powCaptcha.integration.test.d.ts.map +0 -1
  253. package/dist/tests/integration/powCaptcha.integration.test.js +0 -308
  254. package/dist/tests/integration/powCaptcha.integration.test.js.map +0 -1
  255. package/dist/tests/integration/registerSitekey.d.ts +0 -3
  256. package/dist/tests/integration/registerSitekey.d.ts.map +0 -1
  257. package/dist/tests/integration/registerSitekey.js +0 -24
  258. package/dist/tests/integration/registerSitekey.js.map +0 -1
  259. package/dist/tests/integration/userAccessPolicy.d.ts +0 -2
  260. package/dist/tests/integration/userAccessPolicy.d.ts.map +0 -1
  261. package/dist/tests/integration/userAccessPolicy.js +0 -2
  262. package/dist/tests/integration/userAccessPolicy.js.map +0 -1
  263. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.d.ts +0 -2
  264. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.d.ts.map +0 -1
  265. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js +0 -60
  266. package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js.map +0 -1
  267. package/dist/tests/unit/api/ignoreMiddleware.unit.test.d.ts +0 -2
  268. package/dist/tests/unit/api/ignoreMiddleware.unit.test.d.ts.map +0 -1
  269. package/dist/tests/unit/api/ignoreMiddleware.unit.test.js +0 -43
  270. package/dist/tests/unit/api/ignoreMiddleware.unit.test.js.map +0 -1
  271. package/dist/tests/unit/api/ja4Middleware.unit.test.d.ts +0 -2
  272. package/dist/tests/unit/api/ja4Middleware.unit.test.d.ts.map +0 -1
  273. package/dist/tests/unit/api/ja4Middleware.unit.test.js +0 -57
  274. package/dist/tests/unit/api/ja4Middleware.unit.test.js.map +0 -1
  275. package/dist/tests/unit/compositeIpAddress.unit.test.d.ts +0 -2
  276. package/dist/tests/unit/compositeIpAddress.unit.test.d.ts.map +0 -1
  277. package/dist/tests/unit/compositeIpAddress.unit.test.js +0 -86
  278. package/dist/tests/unit/compositeIpAddress.unit.test.js.map +0 -1
  279. package/dist/tests/unit/pairs.unit.test.d.ts +0 -2
  280. package/dist/tests/unit/pairs.unit.test.d.ts.map +0 -1
  281. package/dist/tests/unit/pairs.unit.test.js +0 -83
  282. package/dist/tests/unit/pairs.unit.test.js.map +0 -1
  283. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts +0 -2
  284. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts.map +0 -1
  285. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +0 -75
  286. package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +0 -1
  287. package/dist/tests/unit/services/ipComparison.unit.test.d.ts +0 -2
  288. package/dist/tests/unit/services/ipComparison.unit.test.d.ts.map +0 -1
  289. package/dist/tests/unit/services/ipComparison.unit.test.js +0 -258
  290. package/dist/tests/unit/services/ipComparison.unit.test.js.map +0 -1
  291. package/dist/tests/unit/services/ipInfo.unit.test.d.ts +0 -2
  292. package/dist/tests/unit/services/ipInfo.unit.test.d.ts.map +0 -1
  293. package/dist/tests/unit/services/ipInfo.unit.test.js +0 -210
  294. package/dist/tests/unit/services/ipInfo.unit.test.js.map +0 -1
  295. package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts +0 -2
  296. package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts.map +0 -1
  297. package/dist/tests/unit/tasks/captchaManager.unit.test.js +0 -311
  298. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +0 -1
  299. package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts +0 -2
  300. package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts.map +0 -1
  301. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +0 -289
  302. package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +0 -1
  303. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts +0 -2
  304. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts.map +0 -1
  305. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js +0 -92
  306. package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js.map +0 -1
  307. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts +0 -2
  308. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts.map +0 -1
  309. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js +0 -75
  310. package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js.map +0 -1
  311. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.d.ts +0 -2
  312. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.d.ts.map +0 -1
  313. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js +0 -143
  314. package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js.map +0 -1
  315. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.d.ts +0 -2
  316. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.d.ts.map +0 -1
  317. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +0 -145
  318. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +0 -1
  319. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts +0 -2
  320. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts.map +0 -1
  321. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js +0 -64
  322. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js.map +0 -1
  323. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts +0 -2
  324. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts.map +0 -1
  325. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +0 -388
  326. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +0 -1
  327. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts +0 -2
  328. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts.map +0 -1
  329. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +0 -46
  330. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +0 -1
  331. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts +0 -2
  332. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts.map +0 -1
  333. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +0 -216
  334. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +0 -1
  335. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts +0 -2
  336. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts.map +0 -1
  337. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +0 -69
  338. package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +0 -1
  339. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.d.ts +0 -2
  340. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.d.ts.map +0 -1
  341. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.js +0 -505
  342. package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.js.map +0 -1
  343. package/dist/tests/unit/util.ipDistance.unit.test.d.ts +0 -2
  344. package/dist/tests/unit/util.ipDistance.unit.test.d.ts.map +0 -1
  345. package/dist/tests/unit/util.ipDistance.unit.test.js +0 -93
  346. package/dist/tests/unit/util.ipDistance.unit.test.js.map +0 -1
  347. package/dist/tests/unit/util.unit.test.d.ts +0 -2
  348. package/dist/tests/unit/util.unit.test.d.ts.map +0 -1
  349. package/dist/tests/unit/util.unit.test.js +0 -170
  350. package/dist/tests/unit/util.unit.test.js.map +0 -1
  351. package/dist/util.d.ts +0 -24
  352. package/dist/util.d.ts.map +0 -1
  353. package/dist/util.js.map +0 -1
  354. package/dist/utils/hashUserAgent.d.ts +0 -2
  355. package/dist/utils/hashUserAgent.d.ts.map +0 -1
  356. package/dist/utils/hashUserAgent.js.map +0 -1
@@ -1,1972 +0,0 @@
1
-
2
- <!doctype html>
3
- <html lang="en">
4
-
5
- <head>
6
- <title>Code coverage report for src/tasks/imgCaptcha/imgCaptchaTasks.ts</title>
7
- <meta charset="utf-8" />
8
- <link rel="stylesheet" href="../../../prettify.css" />
9
- <link rel="stylesheet" href="../../../base.css" />
10
- <link rel="shortcut icon" type="image/x-icon" href="../../../favicon.png" />
11
- <meta name="viewport" content="width=device-width, initial-scale=1" />
12
- <style type='text/css'>
13
- .coverage-summary .sorter {
14
- background-image: url(../../../sort-arrow-sprite.png);
15
- }
16
- </style>
17
- </head>
18
-
19
- <body>
20
- <div class='wrapper'>
21
- <div class='pad1'>
22
- <h1><a href="../../../index.html">All files</a> / <a href="index.html">src/tasks/imgCaptcha</a> imgCaptchaTasks.ts</h1>
23
- <div class='clearfix'>
24
-
25
- <div class='fl pad1y space-right2'>
26
- <span class="strong">0% </span>
27
- <span class="quiet">Statements</span>
28
- <span class='fraction'>0/475</span>
29
- </div>
30
-
31
-
32
- <div class='fl pad1y space-right2'>
33
- <span class="strong">100% </span>
34
- <span class="quiet">Branches</span>
35
- <span class='fraction'>1/1</span>
36
- </div>
37
-
38
-
39
- <div class='fl pad1y space-right2'>
40
- <span class="strong">100% </span>
41
- <span class="quiet">Functions</span>
42
- <span class='fraction'>1/1</span>
43
- </div>
44
-
45
-
46
- <div class='fl pad1y space-right2'>
47
- <span class="strong">0% </span>
48
- <span class="quiet">Lines</span>
49
- <span class='fraction'>0/475</span>
50
- </div>
51
-
52
-
53
- </div>
54
- <p class="quiet">
55
- Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
- </p>
57
- <template id="filterTemplate">
58
- <div class="quiet">
59
- Filter:
60
- <input type="search" id="fileSearch">
61
- </div>
62
- </template>
63
- </div>
64
- <div class='status-line low'></div>
65
- <pre><table class="coverage">
66
- <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
- <a name='L2'></a><a href='#L2'>2</a>
68
- <a name='L3'></a><a href='#L3'>3</a>
69
- <a name='L4'></a><a href='#L4'>4</a>
70
- <a name='L5'></a><a href='#L5'>5</a>
71
- <a name='L6'></a><a href='#L6'>6</a>
72
- <a name='L7'></a><a href='#L7'>7</a>
73
- <a name='L8'></a><a href='#L8'>8</a>
74
- <a name='L9'></a><a href='#L9'>9</a>
75
- <a name='L10'></a><a href='#L10'>10</a>
76
- <a name='L11'></a><a href='#L11'>11</a>
77
- <a name='L12'></a><a href='#L12'>12</a>
78
- <a name='L13'></a><a href='#L13'>13</a>
79
- <a name='L14'></a><a href='#L14'>14</a>
80
- <a name='L15'></a><a href='#L15'>15</a>
81
- <a name='L16'></a><a href='#L16'>16</a>
82
- <a name='L17'></a><a href='#L17'>17</a>
83
- <a name='L18'></a><a href='#L18'>18</a>
84
- <a name='L19'></a><a href='#L19'>19</a>
85
- <a name='L20'></a><a href='#L20'>20</a>
86
- <a name='L21'></a><a href='#L21'>21</a>
87
- <a name='L22'></a><a href='#L22'>22</a>
88
- <a name='L23'></a><a href='#L23'>23</a>
89
- <a name='L24'></a><a href='#L24'>24</a>
90
- <a name='L25'></a><a href='#L25'>25</a>
91
- <a name='L26'></a><a href='#L26'>26</a>
92
- <a name='L27'></a><a href='#L27'>27</a>
93
- <a name='L28'></a><a href='#L28'>28</a>
94
- <a name='L29'></a><a href='#L29'>29</a>
95
- <a name='L30'></a><a href='#L30'>30</a>
96
- <a name='L31'></a><a href='#L31'>31</a>
97
- <a name='L32'></a><a href='#L32'>32</a>
98
- <a name='L33'></a><a href='#L33'>33</a>
99
- <a name='L34'></a><a href='#L34'>34</a>
100
- <a name='L35'></a><a href='#L35'>35</a>
101
- <a name='L36'></a><a href='#L36'>36</a>
102
- <a name='L37'></a><a href='#L37'>37</a>
103
- <a name='L38'></a><a href='#L38'>38</a>
104
- <a name='L39'></a><a href='#L39'>39</a>
105
- <a name='L40'></a><a href='#L40'>40</a>
106
- <a name='L41'></a><a href='#L41'>41</a>
107
- <a name='L42'></a><a href='#L42'>42</a>
108
- <a name='L43'></a><a href='#L43'>43</a>
109
- <a name='L44'></a><a href='#L44'>44</a>
110
- <a name='L45'></a><a href='#L45'>45</a>
111
- <a name='L46'></a><a href='#L46'>46</a>
112
- <a name='L47'></a><a href='#L47'>47</a>
113
- <a name='L48'></a><a href='#L48'>48</a>
114
- <a name='L49'></a><a href='#L49'>49</a>
115
- <a name='L50'></a><a href='#L50'>50</a>
116
- <a name='L51'></a><a href='#L51'>51</a>
117
- <a name='L52'></a><a href='#L52'>52</a>
118
- <a name='L53'></a><a href='#L53'>53</a>
119
- <a name='L54'></a><a href='#L54'>54</a>
120
- <a name='L55'></a><a href='#L55'>55</a>
121
- <a name='L56'></a><a href='#L56'>56</a>
122
- <a name='L57'></a><a href='#L57'>57</a>
123
- <a name='L58'></a><a href='#L58'>58</a>
124
- <a name='L59'></a><a href='#L59'>59</a>
125
- <a name='L60'></a><a href='#L60'>60</a>
126
- <a name='L61'></a><a href='#L61'>61</a>
127
- <a name='L62'></a><a href='#L62'>62</a>
128
- <a name='L63'></a><a href='#L63'>63</a>
129
- <a name='L64'></a><a href='#L64'>64</a>
130
- <a name='L65'></a><a href='#L65'>65</a>
131
- <a name='L66'></a><a href='#L66'>66</a>
132
- <a name='L67'></a><a href='#L67'>67</a>
133
- <a name='L68'></a><a href='#L68'>68</a>
134
- <a name='L69'></a><a href='#L69'>69</a>
135
- <a name='L70'></a><a href='#L70'>70</a>
136
- <a name='L71'></a><a href='#L71'>71</a>
137
- <a name='L72'></a><a href='#L72'>72</a>
138
- <a name='L73'></a><a href='#L73'>73</a>
139
- <a name='L74'></a><a href='#L74'>74</a>
140
- <a name='L75'></a><a href='#L75'>75</a>
141
- <a name='L76'></a><a href='#L76'>76</a>
142
- <a name='L77'></a><a href='#L77'>77</a>
143
- <a name='L78'></a><a href='#L78'>78</a>
144
- <a name='L79'></a><a href='#L79'>79</a>
145
- <a name='L80'></a><a href='#L80'>80</a>
146
- <a name='L81'></a><a href='#L81'>81</a>
147
- <a name='L82'></a><a href='#L82'>82</a>
148
- <a name='L83'></a><a href='#L83'>83</a>
149
- <a name='L84'></a><a href='#L84'>84</a>
150
- <a name='L85'></a><a href='#L85'>85</a>
151
- <a name='L86'></a><a href='#L86'>86</a>
152
- <a name='L87'></a><a href='#L87'>87</a>
153
- <a name='L88'></a><a href='#L88'>88</a>
154
- <a name='L89'></a><a href='#L89'>89</a>
155
- <a name='L90'></a><a href='#L90'>90</a>
156
- <a name='L91'></a><a href='#L91'>91</a>
157
- <a name='L92'></a><a href='#L92'>92</a>
158
- <a name='L93'></a><a href='#L93'>93</a>
159
- <a name='L94'></a><a href='#L94'>94</a>
160
- <a name='L95'></a><a href='#L95'>95</a>
161
- <a name='L96'></a><a href='#L96'>96</a>
162
- <a name='L97'></a><a href='#L97'>97</a>
163
- <a name='L98'></a><a href='#L98'>98</a>
164
- <a name='L99'></a><a href='#L99'>99</a>
165
- <a name='L100'></a><a href='#L100'>100</a>
166
- <a name='L101'></a><a href='#L101'>101</a>
167
- <a name='L102'></a><a href='#L102'>102</a>
168
- <a name='L103'></a><a href='#L103'>103</a>
169
- <a name='L104'></a><a href='#L104'>104</a>
170
- <a name='L105'></a><a href='#L105'>105</a>
171
- <a name='L106'></a><a href='#L106'>106</a>
172
- <a name='L107'></a><a href='#L107'>107</a>
173
- <a name='L108'></a><a href='#L108'>108</a>
174
- <a name='L109'></a><a href='#L109'>109</a>
175
- <a name='L110'></a><a href='#L110'>110</a>
176
- <a name='L111'></a><a href='#L111'>111</a>
177
- <a name='L112'></a><a href='#L112'>112</a>
178
- <a name='L113'></a><a href='#L113'>113</a>
179
- <a name='L114'></a><a href='#L114'>114</a>
180
- <a name='L115'></a><a href='#L115'>115</a>
181
- <a name='L116'></a><a href='#L116'>116</a>
182
- <a name='L117'></a><a href='#L117'>117</a>
183
- <a name='L118'></a><a href='#L118'>118</a>
184
- <a name='L119'></a><a href='#L119'>119</a>
185
- <a name='L120'></a><a href='#L120'>120</a>
186
- <a name='L121'></a><a href='#L121'>121</a>
187
- <a name='L122'></a><a href='#L122'>122</a>
188
- <a name='L123'></a><a href='#L123'>123</a>
189
- <a name='L124'></a><a href='#L124'>124</a>
190
- <a name='L125'></a><a href='#L125'>125</a>
191
- <a name='L126'></a><a href='#L126'>126</a>
192
- <a name='L127'></a><a href='#L127'>127</a>
193
- <a name='L128'></a><a href='#L128'>128</a>
194
- <a name='L129'></a><a href='#L129'>129</a>
195
- <a name='L130'></a><a href='#L130'>130</a>
196
- <a name='L131'></a><a href='#L131'>131</a>
197
- <a name='L132'></a><a href='#L132'>132</a>
198
- <a name='L133'></a><a href='#L133'>133</a>
199
- <a name='L134'></a><a href='#L134'>134</a>
200
- <a name='L135'></a><a href='#L135'>135</a>
201
- <a name='L136'></a><a href='#L136'>136</a>
202
- <a name='L137'></a><a href='#L137'>137</a>
203
- <a name='L138'></a><a href='#L138'>138</a>
204
- <a name='L139'></a><a href='#L139'>139</a>
205
- <a name='L140'></a><a href='#L140'>140</a>
206
- <a name='L141'></a><a href='#L141'>141</a>
207
- <a name='L142'></a><a href='#L142'>142</a>
208
- <a name='L143'></a><a href='#L143'>143</a>
209
- <a name='L144'></a><a href='#L144'>144</a>
210
- <a name='L145'></a><a href='#L145'>145</a>
211
- <a name='L146'></a><a href='#L146'>146</a>
212
- <a name='L147'></a><a href='#L147'>147</a>
213
- <a name='L148'></a><a href='#L148'>148</a>
214
- <a name='L149'></a><a href='#L149'>149</a>
215
- <a name='L150'></a><a href='#L150'>150</a>
216
- <a name='L151'></a><a href='#L151'>151</a>
217
- <a name='L152'></a><a href='#L152'>152</a>
218
- <a name='L153'></a><a href='#L153'>153</a>
219
- <a name='L154'></a><a href='#L154'>154</a>
220
- <a name='L155'></a><a href='#L155'>155</a>
221
- <a name='L156'></a><a href='#L156'>156</a>
222
- <a name='L157'></a><a href='#L157'>157</a>
223
- <a name='L158'></a><a href='#L158'>158</a>
224
- <a name='L159'></a><a href='#L159'>159</a>
225
- <a name='L160'></a><a href='#L160'>160</a>
226
- <a name='L161'></a><a href='#L161'>161</a>
227
- <a name='L162'></a><a href='#L162'>162</a>
228
- <a name='L163'></a><a href='#L163'>163</a>
229
- <a name='L164'></a><a href='#L164'>164</a>
230
- <a name='L165'></a><a href='#L165'>165</a>
231
- <a name='L166'></a><a href='#L166'>166</a>
232
- <a name='L167'></a><a href='#L167'>167</a>
233
- <a name='L168'></a><a href='#L168'>168</a>
234
- <a name='L169'></a><a href='#L169'>169</a>
235
- <a name='L170'></a><a href='#L170'>170</a>
236
- <a name='L171'></a><a href='#L171'>171</a>
237
- <a name='L172'></a><a href='#L172'>172</a>
238
- <a name='L173'></a><a href='#L173'>173</a>
239
- <a name='L174'></a><a href='#L174'>174</a>
240
- <a name='L175'></a><a href='#L175'>175</a>
241
- <a name='L176'></a><a href='#L176'>176</a>
242
- <a name='L177'></a><a href='#L177'>177</a>
243
- <a name='L178'></a><a href='#L178'>178</a>
244
- <a name='L179'></a><a href='#L179'>179</a>
245
- <a name='L180'></a><a href='#L180'>180</a>
246
- <a name='L181'></a><a href='#L181'>181</a>
247
- <a name='L182'></a><a href='#L182'>182</a>
248
- <a name='L183'></a><a href='#L183'>183</a>
249
- <a name='L184'></a><a href='#L184'>184</a>
250
- <a name='L185'></a><a href='#L185'>185</a>
251
- <a name='L186'></a><a href='#L186'>186</a>
252
- <a name='L187'></a><a href='#L187'>187</a>
253
- <a name='L188'></a><a href='#L188'>188</a>
254
- <a name='L189'></a><a href='#L189'>189</a>
255
- <a name='L190'></a><a href='#L190'>190</a>
256
- <a name='L191'></a><a href='#L191'>191</a>
257
- <a name='L192'></a><a href='#L192'>192</a>
258
- <a name='L193'></a><a href='#L193'>193</a>
259
- <a name='L194'></a><a href='#L194'>194</a>
260
- <a name='L195'></a><a href='#L195'>195</a>
261
- <a name='L196'></a><a href='#L196'>196</a>
262
- <a name='L197'></a><a href='#L197'>197</a>
263
- <a name='L198'></a><a href='#L198'>198</a>
264
- <a name='L199'></a><a href='#L199'>199</a>
265
- <a name='L200'></a><a href='#L200'>200</a>
266
- <a name='L201'></a><a href='#L201'>201</a>
267
- <a name='L202'></a><a href='#L202'>202</a>
268
- <a name='L203'></a><a href='#L203'>203</a>
269
- <a name='L204'></a><a href='#L204'>204</a>
270
- <a name='L205'></a><a href='#L205'>205</a>
271
- <a name='L206'></a><a href='#L206'>206</a>
272
- <a name='L207'></a><a href='#L207'>207</a>
273
- <a name='L208'></a><a href='#L208'>208</a>
274
- <a name='L209'></a><a href='#L209'>209</a>
275
- <a name='L210'></a><a href='#L210'>210</a>
276
- <a name='L211'></a><a href='#L211'>211</a>
277
- <a name='L212'></a><a href='#L212'>212</a>
278
- <a name='L213'></a><a href='#L213'>213</a>
279
- <a name='L214'></a><a href='#L214'>214</a>
280
- <a name='L215'></a><a href='#L215'>215</a>
281
- <a name='L216'></a><a href='#L216'>216</a>
282
- <a name='L217'></a><a href='#L217'>217</a>
283
- <a name='L218'></a><a href='#L218'>218</a>
284
- <a name='L219'></a><a href='#L219'>219</a>
285
- <a name='L220'></a><a href='#L220'>220</a>
286
- <a name='L221'></a><a href='#L221'>221</a>
287
- <a name='L222'></a><a href='#L222'>222</a>
288
- <a name='L223'></a><a href='#L223'>223</a>
289
- <a name='L224'></a><a href='#L224'>224</a>
290
- <a name='L225'></a><a href='#L225'>225</a>
291
- <a name='L226'></a><a href='#L226'>226</a>
292
- <a name='L227'></a><a href='#L227'>227</a>
293
- <a name='L228'></a><a href='#L228'>228</a>
294
- <a name='L229'></a><a href='#L229'>229</a>
295
- <a name='L230'></a><a href='#L230'>230</a>
296
- <a name='L231'></a><a href='#L231'>231</a>
297
- <a name='L232'></a><a href='#L232'>232</a>
298
- <a name='L233'></a><a href='#L233'>233</a>
299
- <a name='L234'></a><a href='#L234'>234</a>
300
- <a name='L235'></a><a href='#L235'>235</a>
301
- <a name='L236'></a><a href='#L236'>236</a>
302
- <a name='L237'></a><a href='#L237'>237</a>
303
- <a name='L238'></a><a href='#L238'>238</a>
304
- <a name='L239'></a><a href='#L239'>239</a>
305
- <a name='L240'></a><a href='#L240'>240</a>
306
- <a name='L241'></a><a href='#L241'>241</a>
307
- <a name='L242'></a><a href='#L242'>242</a>
308
- <a name='L243'></a><a href='#L243'>243</a>
309
- <a name='L244'></a><a href='#L244'>244</a>
310
- <a name='L245'></a><a href='#L245'>245</a>
311
- <a name='L246'></a><a href='#L246'>246</a>
312
- <a name='L247'></a><a href='#L247'>247</a>
313
- <a name='L248'></a><a href='#L248'>248</a>
314
- <a name='L249'></a><a href='#L249'>249</a>
315
- <a name='L250'></a><a href='#L250'>250</a>
316
- <a name='L251'></a><a href='#L251'>251</a>
317
- <a name='L252'></a><a href='#L252'>252</a>
318
- <a name='L253'></a><a href='#L253'>253</a>
319
- <a name='L254'></a><a href='#L254'>254</a>
320
- <a name='L255'></a><a href='#L255'>255</a>
321
- <a name='L256'></a><a href='#L256'>256</a>
322
- <a name='L257'></a><a href='#L257'>257</a>
323
- <a name='L258'></a><a href='#L258'>258</a>
324
- <a name='L259'></a><a href='#L259'>259</a>
325
- <a name='L260'></a><a href='#L260'>260</a>
326
- <a name='L261'></a><a href='#L261'>261</a>
327
- <a name='L262'></a><a href='#L262'>262</a>
328
- <a name='L263'></a><a href='#L263'>263</a>
329
- <a name='L264'></a><a href='#L264'>264</a>
330
- <a name='L265'></a><a href='#L265'>265</a>
331
- <a name='L266'></a><a href='#L266'>266</a>
332
- <a name='L267'></a><a href='#L267'>267</a>
333
- <a name='L268'></a><a href='#L268'>268</a>
334
- <a name='L269'></a><a href='#L269'>269</a>
335
- <a name='L270'></a><a href='#L270'>270</a>
336
- <a name='L271'></a><a href='#L271'>271</a>
337
- <a name='L272'></a><a href='#L272'>272</a>
338
- <a name='L273'></a><a href='#L273'>273</a>
339
- <a name='L274'></a><a href='#L274'>274</a>
340
- <a name='L275'></a><a href='#L275'>275</a>
341
- <a name='L276'></a><a href='#L276'>276</a>
342
- <a name='L277'></a><a href='#L277'>277</a>
343
- <a name='L278'></a><a href='#L278'>278</a>
344
- <a name='L279'></a><a href='#L279'>279</a>
345
- <a name='L280'></a><a href='#L280'>280</a>
346
- <a name='L281'></a><a href='#L281'>281</a>
347
- <a name='L282'></a><a href='#L282'>282</a>
348
- <a name='L283'></a><a href='#L283'>283</a>
349
- <a name='L284'></a><a href='#L284'>284</a>
350
- <a name='L285'></a><a href='#L285'>285</a>
351
- <a name='L286'></a><a href='#L286'>286</a>
352
- <a name='L287'></a><a href='#L287'>287</a>
353
- <a name='L288'></a><a href='#L288'>288</a>
354
- <a name='L289'></a><a href='#L289'>289</a>
355
- <a name='L290'></a><a href='#L290'>290</a>
356
- <a name='L291'></a><a href='#L291'>291</a>
357
- <a name='L292'></a><a href='#L292'>292</a>
358
- <a name='L293'></a><a href='#L293'>293</a>
359
- <a name='L294'></a><a href='#L294'>294</a>
360
- <a name='L295'></a><a href='#L295'>295</a>
361
- <a name='L296'></a><a href='#L296'>296</a>
362
- <a name='L297'></a><a href='#L297'>297</a>
363
- <a name='L298'></a><a href='#L298'>298</a>
364
- <a name='L299'></a><a href='#L299'>299</a>
365
- <a name='L300'></a><a href='#L300'>300</a>
366
- <a name='L301'></a><a href='#L301'>301</a>
367
- <a name='L302'></a><a href='#L302'>302</a>
368
- <a name='L303'></a><a href='#L303'>303</a>
369
- <a name='L304'></a><a href='#L304'>304</a>
370
- <a name='L305'></a><a href='#L305'>305</a>
371
- <a name='L306'></a><a href='#L306'>306</a>
372
- <a name='L307'></a><a href='#L307'>307</a>
373
- <a name='L308'></a><a href='#L308'>308</a>
374
- <a name='L309'></a><a href='#L309'>309</a>
375
- <a name='L310'></a><a href='#L310'>310</a>
376
- <a name='L311'></a><a href='#L311'>311</a>
377
- <a name='L312'></a><a href='#L312'>312</a>
378
- <a name='L313'></a><a href='#L313'>313</a>
379
- <a name='L314'></a><a href='#L314'>314</a>
380
- <a name='L315'></a><a href='#L315'>315</a>
381
- <a name='L316'></a><a href='#L316'>316</a>
382
- <a name='L317'></a><a href='#L317'>317</a>
383
- <a name='L318'></a><a href='#L318'>318</a>
384
- <a name='L319'></a><a href='#L319'>319</a>
385
- <a name='L320'></a><a href='#L320'>320</a>
386
- <a name='L321'></a><a href='#L321'>321</a>
387
- <a name='L322'></a><a href='#L322'>322</a>
388
- <a name='L323'></a><a href='#L323'>323</a>
389
- <a name='L324'></a><a href='#L324'>324</a>
390
- <a name='L325'></a><a href='#L325'>325</a>
391
- <a name='L326'></a><a href='#L326'>326</a>
392
- <a name='L327'></a><a href='#L327'>327</a>
393
- <a name='L328'></a><a href='#L328'>328</a>
394
- <a name='L329'></a><a href='#L329'>329</a>
395
- <a name='L330'></a><a href='#L330'>330</a>
396
- <a name='L331'></a><a href='#L331'>331</a>
397
- <a name='L332'></a><a href='#L332'>332</a>
398
- <a name='L333'></a><a href='#L333'>333</a>
399
- <a name='L334'></a><a href='#L334'>334</a>
400
- <a name='L335'></a><a href='#L335'>335</a>
401
- <a name='L336'></a><a href='#L336'>336</a>
402
- <a name='L337'></a><a href='#L337'>337</a>
403
- <a name='L338'></a><a href='#L338'>338</a>
404
- <a name='L339'></a><a href='#L339'>339</a>
405
- <a name='L340'></a><a href='#L340'>340</a>
406
- <a name='L341'></a><a href='#L341'>341</a>
407
- <a name='L342'></a><a href='#L342'>342</a>
408
- <a name='L343'></a><a href='#L343'>343</a>
409
- <a name='L344'></a><a href='#L344'>344</a>
410
- <a name='L345'></a><a href='#L345'>345</a>
411
- <a name='L346'></a><a href='#L346'>346</a>
412
- <a name='L347'></a><a href='#L347'>347</a>
413
- <a name='L348'></a><a href='#L348'>348</a>
414
- <a name='L349'></a><a href='#L349'>349</a>
415
- <a name='L350'></a><a href='#L350'>350</a>
416
- <a name='L351'></a><a href='#L351'>351</a>
417
- <a name='L352'></a><a href='#L352'>352</a>
418
- <a name='L353'></a><a href='#L353'>353</a>
419
- <a name='L354'></a><a href='#L354'>354</a>
420
- <a name='L355'></a><a href='#L355'>355</a>
421
- <a name='L356'></a><a href='#L356'>356</a>
422
- <a name='L357'></a><a href='#L357'>357</a>
423
- <a name='L358'></a><a href='#L358'>358</a>
424
- <a name='L359'></a><a href='#L359'>359</a>
425
- <a name='L360'></a><a href='#L360'>360</a>
426
- <a name='L361'></a><a href='#L361'>361</a>
427
- <a name='L362'></a><a href='#L362'>362</a>
428
- <a name='L363'></a><a href='#L363'>363</a>
429
- <a name='L364'></a><a href='#L364'>364</a>
430
- <a name='L365'></a><a href='#L365'>365</a>
431
- <a name='L366'></a><a href='#L366'>366</a>
432
- <a name='L367'></a><a href='#L367'>367</a>
433
- <a name='L368'></a><a href='#L368'>368</a>
434
- <a name='L369'></a><a href='#L369'>369</a>
435
- <a name='L370'></a><a href='#L370'>370</a>
436
- <a name='L371'></a><a href='#L371'>371</a>
437
- <a name='L372'></a><a href='#L372'>372</a>
438
- <a name='L373'></a><a href='#L373'>373</a>
439
- <a name='L374'></a><a href='#L374'>374</a>
440
- <a name='L375'></a><a href='#L375'>375</a>
441
- <a name='L376'></a><a href='#L376'>376</a>
442
- <a name='L377'></a><a href='#L377'>377</a>
443
- <a name='L378'></a><a href='#L378'>378</a>
444
- <a name='L379'></a><a href='#L379'>379</a>
445
- <a name='L380'></a><a href='#L380'>380</a>
446
- <a name='L381'></a><a href='#L381'>381</a>
447
- <a name='L382'></a><a href='#L382'>382</a>
448
- <a name='L383'></a><a href='#L383'>383</a>
449
- <a name='L384'></a><a href='#L384'>384</a>
450
- <a name='L385'></a><a href='#L385'>385</a>
451
- <a name='L386'></a><a href='#L386'>386</a>
452
- <a name='L387'></a><a href='#L387'>387</a>
453
- <a name='L388'></a><a href='#L388'>388</a>
454
- <a name='L389'></a><a href='#L389'>389</a>
455
- <a name='L390'></a><a href='#L390'>390</a>
456
- <a name='L391'></a><a href='#L391'>391</a>
457
- <a name='L392'></a><a href='#L392'>392</a>
458
- <a name='L393'></a><a href='#L393'>393</a>
459
- <a name='L394'></a><a href='#L394'>394</a>
460
- <a name='L395'></a><a href='#L395'>395</a>
461
- <a name='L396'></a><a href='#L396'>396</a>
462
- <a name='L397'></a><a href='#L397'>397</a>
463
- <a name='L398'></a><a href='#L398'>398</a>
464
- <a name='L399'></a><a href='#L399'>399</a>
465
- <a name='L400'></a><a href='#L400'>400</a>
466
- <a name='L401'></a><a href='#L401'>401</a>
467
- <a name='L402'></a><a href='#L402'>402</a>
468
- <a name='L403'></a><a href='#L403'>403</a>
469
- <a name='L404'></a><a href='#L404'>404</a>
470
- <a name='L405'></a><a href='#L405'>405</a>
471
- <a name='L406'></a><a href='#L406'>406</a>
472
- <a name='L407'></a><a href='#L407'>407</a>
473
- <a name='L408'></a><a href='#L408'>408</a>
474
- <a name='L409'></a><a href='#L409'>409</a>
475
- <a name='L410'></a><a href='#L410'>410</a>
476
- <a name='L411'></a><a href='#L411'>411</a>
477
- <a name='L412'></a><a href='#L412'>412</a>
478
- <a name='L413'></a><a href='#L413'>413</a>
479
- <a name='L414'></a><a href='#L414'>414</a>
480
- <a name='L415'></a><a href='#L415'>415</a>
481
- <a name='L416'></a><a href='#L416'>416</a>
482
- <a name='L417'></a><a href='#L417'>417</a>
483
- <a name='L418'></a><a href='#L418'>418</a>
484
- <a name='L419'></a><a href='#L419'>419</a>
485
- <a name='L420'></a><a href='#L420'>420</a>
486
- <a name='L421'></a><a href='#L421'>421</a>
487
- <a name='L422'></a><a href='#L422'>422</a>
488
- <a name='L423'></a><a href='#L423'>423</a>
489
- <a name='L424'></a><a href='#L424'>424</a>
490
- <a name='L425'></a><a href='#L425'>425</a>
491
- <a name='L426'></a><a href='#L426'>426</a>
492
- <a name='L427'></a><a href='#L427'>427</a>
493
- <a name='L428'></a><a href='#L428'>428</a>
494
- <a name='L429'></a><a href='#L429'>429</a>
495
- <a name='L430'></a><a href='#L430'>430</a>
496
- <a name='L431'></a><a href='#L431'>431</a>
497
- <a name='L432'></a><a href='#L432'>432</a>
498
- <a name='L433'></a><a href='#L433'>433</a>
499
- <a name='L434'></a><a href='#L434'>434</a>
500
- <a name='L435'></a><a href='#L435'>435</a>
501
- <a name='L436'></a><a href='#L436'>436</a>
502
- <a name='L437'></a><a href='#L437'>437</a>
503
- <a name='L438'></a><a href='#L438'>438</a>
504
- <a name='L439'></a><a href='#L439'>439</a>
505
- <a name='L440'></a><a href='#L440'>440</a>
506
- <a name='L441'></a><a href='#L441'>441</a>
507
- <a name='L442'></a><a href='#L442'>442</a>
508
- <a name='L443'></a><a href='#L443'>443</a>
509
- <a name='L444'></a><a href='#L444'>444</a>
510
- <a name='L445'></a><a href='#L445'>445</a>
511
- <a name='L446'></a><a href='#L446'>446</a>
512
- <a name='L447'></a><a href='#L447'>447</a>
513
- <a name='L448'></a><a href='#L448'>448</a>
514
- <a name='L449'></a><a href='#L449'>449</a>
515
- <a name='L450'></a><a href='#L450'>450</a>
516
- <a name='L451'></a><a href='#L451'>451</a>
517
- <a name='L452'></a><a href='#L452'>452</a>
518
- <a name='L453'></a><a href='#L453'>453</a>
519
- <a name='L454'></a><a href='#L454'>454</a>
520
- <a name='L455'></a><a href='#L455'>455</a>
521
- <a name='L456'></a><a href='#L456'>456</a>
522
- <a name='L457'></a><a href='#L457'>457</a>
523
- <a name='L458'></a><a href='#L458'>458</a>
524
- <a name='L459'></a><a href='#L459'>459</a>
525
- <a name='L460'></a><a href='#L460'>460</a>
526
- <a name='L461'></a><a href='#L461'>461</a>
527
- <a name='L462'></a><a href='#L462'>462</a>
528
- <a name='L463'></a><a href='#L463'>463</a>
529
- <a name='L464'></a><a href='#L464'>464</a>
530
- <a name='L465'></a><a href='#L465'>465</a>
531
- <a name='L466'></a><a href='#L466'>466</a>
532
- <a name='L467'></a><a href='#L467'>467</a>
533
- <a name='L468'></a><a href='#L468'>468</a>
534
- <a name='L469'></a><a href='#L469'>469</a>
535
- <a name='L470'></a><a href='#L470'>470</a>
536
- <a name='L471'></a><a href='#L471'>471</a>
537
- <a name='L472'></a><a href='#L472'>472</a>
538
- <a name='L473'></a><a href='#L473'>473</a>
539
- <a name='L474'></a><a href='#L474'>474</a>
540
- <a name='L475'></a><a href='#L475'>475</a>
541
- <a name='L476'></a><a href='#L476'>476</a>
542
- <a name='L477'></a><a href='#L477'>477</a>
543
- <a name='L478'></a><a href='#L478'>478</a>
544
- <a name='L479'></a><a href='#L479'>479</a>
545
- <a name='L480'></a><a href='#L480'>480</a>
546
- <a name='L481'></a><a href='#L481'>481</a>
547
- <a name='L482'></a><a href='#L482'>482</a>
548
- <a name='L483'></a><a href='#L483'>483</a>
549
- <a name='L484'></a><a href='#L484'>484</a>
550
- <a name='L485'></a><a href='#L485'>485</a>
551
- <a name='L486'></a><a href='#L486'>486</a>
552
- <a name='L487'></a><a href='#L487'>487</a>
553
- <a name='L488'></a><a href='#L488'>488</a>
554
- <a name='L489'></a><a href='#L489'>489</a>
555
- <a name='L490'></a><a href='#L490'>490</a>
556
- <a name='L491'></a><a href='#L491'>491</a>
557
- <a name='L492'></a><a href='#L492'>492</a>
558
- <a name='L493'></a><a href='#L493'>493</a>
559
- <a name='L494'></a><a href='#L494'>494</a>
560
- <a name='L495'></a><a href='#L495'>495</a>
561
- <a name='L496'></a><a href='#L496'>496</a>
562
- <a name='L497'></a><a href='#L497'>497</a>
563
- <a name='L498'></a><a href='#L498'>498</a>
564
- <a name='L499'></a><a href='#L499'>499</a>
565
- <a name='L500'></a><a href='#L500'>500</a>
566
- <a name='L501'></a><a href='#L501'>501</a>
567
- <a name='L502'></a><a href='#L502'>502</a>
568
- <a name='L503'></a><a href='#L503'>503</a>
569
- <a name='L504'></a><a href='#L504'>504</a>
570
- <a name='L505'></a><a href='#L505'>505</a>
571
- <a name='L506'></a><a href='#L506'>506</a>
572
- <a name='L507'></a><a href='#L507'>507</a>
573
- <a name='L508'></a><a href='#L508'>508</a>
574
- <a name='L509'></a><a href='#L509'>509</a>
575
- <a name='L510'></a><a href='#L510'>510</a>
576
- <a name='L511'></a><a href='#L511'>511</a>
577
- <a name='L512'></a><a href='#L512'>512</a>
578
- <a name='L513'></a><a href='#L513'>513</a>
579
- <a name='L514'></a><a href='#L514'>514</a>
580
- <a name='L515'></a><a href='#L515'>515</a>
581
- <a name='L516'></a><a href='#L516'>516</a>
582
- <a name='L517'></a><a href='#L517'>517</a>
583
- <a name='L518'></a><a href='#L518'>518</a>
584
- <a name='L519'></a><a href='#L519'>519</a>
585
- <a name='L520'></a><a href='#L520'>520</a>
586
- <a name='L521'></a><a href='#L521'>521</a>
587
- <a name='L522'></a><a href='#L522'>522</a>
588
- <a name='L523'></a><a href='#L523'>523</a>
589
- <a name='L524'></a><a href='#L524'>524</a>
590
- <a name='L525'></a><a href='#L525'>525</a>
591
- <a name='L526'></a><a href='#L526'>526</a>
592
- <a name='L527'></a><a href='#L527'>527</a>
593
- <a name='L528'></a><a href='#L528'>528</a>
594
- <a name='L529'></a><a href='#L529'>529</a>
595
- <a name='L530'></a><a href='#L530'>530</a>
596
- <a name='L531'></a><a href='#L531'>531</a>
597
- <a name='L532'></a><a href='#L532'>532</a>
598
- <a name='L533'></a><a href='#L533'>533</a>
599
- <a name='L534'></a><a href='#L534'>534</a>
600
- <a name='L535'></a><a href='#L535'>535</a>
601
- <a name='L536'></a><a href='#L536'>536</a>
602
- <a name='L537'></a><a href='#L537'>537</a>
603
- <a name='L538'></a><a href='#L538'>538</a>
604
- <a name='L539'></a><a href='#L539'>539</a>
605
- <a name='L540'></a><a href='#L540'>540</a>
606
- <a name='L541'></a><a href='#L541'>541</a>
607
- <a name='L542'></a><a href='#L542'>542</a>
608
- <a name='L543'></a><a href='#L543'>543</a>
609
- <a name='L544'></a><a href='#L544'>544</a>
610
- <a name='L545'></a><a href='#L545'>545</a>
611
- <a name='L546'></a><a href='#L546'>546</a>
612
- <a name='L547'></a><a href='#L547'>547</a>
613
- <a name='L548'></a><a href='#L548'>548</a>
614
- <a name='L549'></a><a href='#L549'>549</a>
615
- <a name='L550'></a><a href='#L550'>550</a>
616
- <a name='L551'></a><a href='#L551'>551</a>
617
- <a name='L552'></a><a href='#L552'>552</a>
618
- <a name='L553'></a><a href='#L553'>553</a>
619
- <a name='L554'></a><a href='#L554'>554</a>
620
- <a name='L555'></a><a href='#L555'>555</a>
621
- <a name='L556'></a><a href='#L556'>556</a>
622
- <a name='L557'></a><a href='#L557'>557</a>
623
- <a name='L558'></a><a href='#L558'>558</a>
624
- <a name='L559'></a><a href='#L559'>559</a>
625
- <a name='L560'></a><a href='#L560'>560</a>
626
- <a name='L561'></a><a href='#L561'>561</a>
627
- <a name='L562'></a><a href='#L562'>562</a>
628
- <a name='L563'></a><a href='#L563'>563</a>
629
- <a name='L564'></a><a href='#L564'>564</a>
630
- <a name='L565'></a><a href='#L565'>565</a>
631
- <a name='L566'></a><a href='#L566'>566</a>
632
- <a name='L567'></a><a href='#L567'>567</a>
633
- <a name='L568'></a><a href='#L568'>568</a>
634
- <a name='L569'></a><a href='#L569'>569</a>
635
- <a name='L570'></a><a href='#L570'>570</a>
636
- <a name='L571'></a><a href='#L571'>571</a>
637
- <a name='L572'></a><a href='#L572'>572</a>
638
- <a name='L573'></a><a href='#L573'>573</a>
639
- <a name='L574'></a><a href='#L574'>574</a>
640
- <a name='L575'></a><a href='#L575'>575</a>
641
- <a name='L576'></a><a href='#L576'>576</a>
642
- <a name='L577'></a><a href='#L577'>577</a>
643
- <a name='L578'></a><a href='#L578'>578</a>
644
- <a name='L579'></a><a href='#L579'>579</a>
645
- <a name='L580'></a><a href='#L580'>580</a>
646
- <a name='L581'></a><a href='#L581'>581</a>
647
- <a name='L582'></a><a href='#L582'>582</a>
648
- <a name='L583'></a><a href='#L583'>583</a>
649
- <a name='L584'></a><a href='#L584'>584</a>
650
- <a name='L585'></a><a href='#L585'>585</a>
651
- <a name='L586'></a><a href='#L586'>586</a>
652
- <a name='L587'></a><a href='#L587'>587</a>
653
- <a name='L588'></a><a href='#L588'>588</a>
654
- <a name='L589'></a><a href='#L589'>589</a>
655
- <a name='L590'></a><a href='#L590'>590</a>
656
- <a name='L591'></a><a href='#L591'>591</a>
657
- <a name='L592'></a><a href='#L592'>592</a>
658
- <a name='L593'></a><a href='#L593'>593</a>
659
- <a name='L594'></a><a href='#L594'>594</a>
660
- <a name='L595'></a><a href='#L595'>595</a>
661
- <a name='L596'></a><a href='#L596'>596</a>
662
- <a name='L597'></a><a href='#L597'>597</a>
663
- <a name='L598'></a><a href='#L598'>598</a>
664
- <a name='L599'></a><a href='#L599'>599</a>
665
- <a name='L600'></a><a href='#L600'>600</a>
666
- <a name='L601'></a><a href='#L601'>601</a>
667
- <a name='L602'></a><a href='#L602'>602</a>
668
- <a name='L603'></a><a href='#L603'>603</a>
669
- <a name='L604'></a><a href='#L604'>604</a>
670
- <a name='L605'></a><a href='#L605'>605</a>
671
- <a name='L606'></a><a href='#L606'>606</a>
672
- <a name='L607'></a><a href='#L607'>607</a>
673
- <a name='L608'></a><a href='#L608'>608</a>
674
- <a name='L609'></a><a href='#L609'>609</a>
675
- <a name='L610'></a><a href='#L610'>610</a>
676
- <a name='L611'></a><a href='#L611'>611</a>
677
- <a name='L612'></a><a href='#L612'>612</a>
678
- <a name='L613'></a><a href='#L613'>613</a>
679
- <a name='L614'></a><a href='#L614'>614</a>
680
- <a name='L615'></a><a href='#L615'>615</a>
681
- <a name='L616'></a><a href='#L616'>616</a>
682
- <a name='L617'></a><a href='#L617'>617</a>
683
- <a name='L618'></a><a href='#L618'>618</a>
684
- <a name='L619'></a><a href='#L619'>619</a>
685
- <a name='L620'></a><a href='#L620'>620</a>
686
- <a name='L621'></a><a href='#L621'>621</a>
687
- <a name='L622'></a><a href='#L622'>622</a>
688
- <a name='L623'></a><a href='#L623'>623</a>
689
- <a name='L624'></a><a href='#L624'>624</a>
690
- <a name='L625'></a><a href='#L625'>625</a>
691
- <a name='L626'></a><a href='#L626'>626</a>
692
- <a name='L627'></a><a href='#L627'>627</a>
693
- <a name='L628'></a><a href='#L628'>628</a>
694
- <a name='L629'></a><a href='#L629'>629</a>
695
- <a name='L630'></a><a href='#L630'>630</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
696
- <span class="cline-any cline-neutral">&nbsp;</span>
697
- <span class="cline-any cline-neutral">&nbsp;</span>
698
- <span class="cline-any cline-neutral">&nbsp;</span>
699
- <span class="cline-any cline-neutral">&nbsp;</span>
700
- <span class="cline-any cline-neutral">&nbsp;</span>
701
- <span class="cline-any cline-neutral">&nbsp;</span>
702
- <span class="cline-any cline-neutral">&nbsp;</span>
703
- <span class="cline-any cline-neutral">&nbsp;</span>
704
- <span class="cline-any cline-neutral">&nbsp;</span>
705
- <span class="cline-any cline-neutral">&nbsp;</span>
706
- <span class="cline-any cline-neutral">&nbsp;</span>
707
- <span class="cline-any cline-neutral">&nbsp;</span>
708
- <span class="cline-any cline-neutral">&nbsp;</span>
709
- <span class="cline-any cline-no">&nbsp;</span>
710
- <span class="cline-any cline-no">&nbsp;</span>
711
- <span class="cline-any cline-no">&nbsp;</span>
712
- <span class="cline-any cline-neutral">&nbsp;</span>
713
- <span class="cline-any cline-neutral">&nbsp;</span>
714
- <span class="cline-any cline-neutral">&nbsp;</span>
715
- <span class="cline-any cline-neutral">&nbsp;</span>
716
- <span class="cline-any cline-neutral">&nbsp;</span>
717
- <span class="cline-any cline-no">&nbsp;</span>
718
- <span class="cline-any cline-neutral">&nbsp;</span>
719
- <span class="cline-any cline-neutral">&nbsp;</span>
720
- <span class="cline-any cline-neutral">&nbsp;</span>
721
- <span class="cline-any cline-neutral">&nbsp;</span>
722
- <span class="cline-any cline-neutral">&nbsp;</span>
723
- <span class="cline-any cline-neutral">&nbsp;</span>
724
- <span class="cline-any cline-neutral">&nbsp;</span>
725
- <span class="cline-any cline-neutral">&nbsp;</span>
726
- <span class="cline-any cline-neutral">&nbsp;</span>
727
- <span class="cline-any cline-neutral">&nbsp;</span>
728
- <span class="cline-any cline-neutral">&nbsp;</span>
729
- <span class="cline-any cline-neutral">&nbsp;</span>
730
- <span class="cline-any cline-neutral">&nbsp;</span>
731
- <span class="cline-any cline-neutral">&nbsp;</span>
732
- <span class="cline-any cline-neutral">&nbsp;</span>
733
- <span class="cline-any cline-neutral">&nbsp;</span>
734
- <span class="cline-any cline-neutral">&nbsp;</span>
735
- <span class="cline-any cline-neutral">&nbsp;</span>
736
- <span class="cline-any cline-neutral">&nbsp;</span>
737
- <span class="cline-any cline-neutral">&nbsp;</span>
738
- <span class="cline-any cline-neutral">&nbsp;</span>
739
- <span class="cline-any cline-no">&nbsp;</span>
740
- <span class="cline-any cline-no">&nbsp;</span>
741
- <span class="cline-any cline-no">&nbsp;</span>
742
- <span class="cline-any cline-neutral">&nbsp;</span>
743
- <span class="cline-any cline-neutral">&nbsp;</span>
744
- <span class="cline-any cline-neutral">&nbsp;</span>
745
- <span class="cline-any cline-no">&nbsp;</span>
746
- <span class="cline-any cline-no">&nbsp;</span>
747
- <span class="cline-any cline-no">&nbsp;</span>
748
- <span class="cline-any cline-no">&nbsp;</span>
749
- <span class="cline-any cline-no">&nbsp;</span>
750
- <span class="cline-any cline-no">&nbsp;</span>
751
- <span class="cline-any cline-neutral">&nbsp;</span>
752
- <span class="cline-any cline-no">&nbsp;</span>
753
- <span class="cline-any cline-neutral">&nbsp;</span>
754
- <span class="cline-any cline-neutral">&nbsp;</span>
755
- <span class="cline-any cline-no">&nbsp;</span>
756
- <span class="cline-any cline-no">&nbsp;</span>
757
- <span class="cline-any cline-no">&nbsp;</span>
758
- <span class="cline-any cline-no">&nbsp;</span>
759
- <span class="cline-any cline-no">&nbsp;</span>
760
- <span class="cline-any cline-no">&nbsp;</span>
761
- <span class="cline-any cline-no">&nbsp;</span>
762
- <span class="cline-any cline-no">&nbsp;</span>
763
- <span class="cline-any cline-no">&nbsp;</span>
764
- <span class="cline-any cline-neutral">&nbsp;</span>
765
- <span class="cline-any cline-no">&nbsp;</span>
766
- <span class="cline-any cline-no">&nbsp;</span>
767
- <span class="cline-any cline-no">&nbsp;</span>
768
- <span class="cline-any cline-no">&nbsp;</span>
769
- <span class="cline-any cline-no">&nbsp;</span>
770
- <span class="cline-any cline-no">&nbsp;</span>
771
- <span class="cline-any cline-no">&nbsp;</span>
772
- <span class="cline-any cline-no">&nbsp;</span>
773
- <span class="cline-any cline-no">&nbsp;</span>
774
- <span class="cline-any cline-no">&nbsp;</span>
775
- <span class="cline-any cline-no">&nbsp;</span>
776
- <span class="cline-any cline-no">&nbsp;</span>
777
- <span class="cline-any cline-no">&nbsp;</span>
778
- <span class="cline-any cline-no">&nbsp;</span>
779
- <span class="cline-any cline-no">&nbsp;</span>
780
- <span class="cline-any cline-no">&nbsp;</span>
781
- <span class="cline-any cline-neutral">&nbsp;</span>
782
- <span class="cline-any cline-no">&nbsp;</span>
783
- <span class="cline-any cline-no">&nbsp;</span>
784
- <span class="cline-any cline-neutral">&nbsp;</span>
785
- <span class="cline-any cline-no">&nbsp;</span>
786
- <span class="cline-any cline-no">&nbsp;</span>
787
- <span class="cline-any cline-no">&nbsp;</span>
788
- <span class="cline-any cline-no">&nbsp;</span>
789
- <span class="cline-any cline-no">&nbsp;</span>
790
- <span class="cline-any cline-no">&nbsp;</span>
791
- <span class="cline-any cline-no">&nbsp;</span>
792
- <span class="cline-any cline-neutral">&nbsp;</span>
793
- <span class="cline-any cline-neutral">&nbsp;</span>
794
- <span class="cline-any cline-neutral">&nbsp;</span>
795
- <span class="cline-any cline-neutral">&nbsp;</span>
796
- <span class="cline-any cline-neutral">&nbsp;</span>
797
- <span class="cline-any cline-no">&nbsp;</span>
798
- <span class="cline-any cline-no">&nbsp;</span>
799
- <span class="cline-any cline-no">&nbsp;</span>
800
- <span class="cline-any cline-no">&nbsp;</span>
801
- <span class="cline-any cline-no">&nbsp;</span>
802
- <span class="cline-any cline-no">&nbsp;</span>
803
- <span class="cline-any cline-no">&nbsp;</span>
804
- <span class="cline-any cline-no">&nbsp;</span>
805
- <span class="cline-any cline-no">&nbsp;</span>
806
- <span class="cline-any cline-no">&nbsp;</span>
807
- <span class="cline-any cline-no">&nbsp;</span>
808
- <span class="cline-any cline-neutral">&nbsp;</span>
809
- <span class="cline-any cline-no">&nbsp;</span>
810
- <span class="cline-any cline-no">&nbsp;</span>
811
- <span class="cline-any cline-no">&nbsp;</span>
812
- <span class="cline-any cline-no">&nbsp;</span>
813
- <span class="cline-any cline-no">&nbsp;</span>
814
- <span class="cline-any cline-no">&nbsp;</span>
815
- <span class="cline-any cline-neutral">&nbsp;</span>
816
- <span class="cline-any cline-no">&nbsp;</span>
817
- <span class="cline-any cline-no">&nbsp;</span>
818
- <span class="cline-any cline-no">&nbsp;</span>
819
- <span class="cline-any cline-neutral">&nbsp;</span>
820
- <span class="cline-any cline-no">&nbsp;</span>
821
- <span class="cline-any cline-neutral">&nbsp;</span>
822
- <span class="cline-any cline-no">&nbsp;</span>
823
- <span class="cline-any cline-no">&nbsp;</span>
824
- <span class="cline-any cline-no">&nbsp;</span>
825
- <span class="cline-any cline-no">&nbsp;</span>
826
- <span class="cline-any cline-no">&nbsp;</span>
827
- <span class="cline-any cline-no">&nbsp;</span>
828
- <span class="cline-any cline-no">&nbsp;</span>
829
- <span class="cline-any cline-no">&nbsp;</span>
830
- <span class="cline-any cline-no">&nbsp;</span>
831
- <span class="cline-any cline-no">&nbsp;</span>
832
- <span class="cline-any cline-neutral">&nbsp;</span>
833
- <span class="cline-any cline-no">&nbsp;</span>
834
- <span class="cline-any cline-no">&nbsp;</span>
835
- <span class="cline-any cline-no">&nbsp;</span>
836
- <span class="cline-any cline-no">&nbsp;</span>
837
- <span class="cline-any cline-no">&nbsp;</span>
838
- <span class="cline-any cline-neutral">&nbsp;</span>
839
- <span class="cline-any cline-no">&nbsp;</span>
840
- <span class="cline-any cline-no">&nbsp;</span>
841
- <span class="cline-any cline-no">&nbsp;</span>
842
- <span class="cline-any cline-no">&nbsp;</span>
843
- <span class="cline-any cline-neutral">&nbsp;</span>
844
- <span class="cline-any cline-no">&nbsp;</span>
845
- <span class="cline-any cline-neutral">&nbsp;</span>
846
- <span class="cline-any cline-no">&nbsp;</span>
847
- <span class="cline-any cline-no">&nbsp;</span>
848
- <span class="cline-any cline-no">&nbsp;</span>
849
- <span class="cline-any cline-neutral">&nbsp;</span>
850
- <span class="cline-any cline-no">&nbsp;</span>
851
- <span class="cline-any cline-no">&nbsp;</span>
852
- <span class="cline-any cline-no">&nbsp;</span>
853
- <span class="cline-any cline-no">&nbsp;</span>
854
- <span class="cline-any cline-no">&nbsp;</span>
855
- <span class="cline-any cline-no">&nbsp;</span>
856
- <span class="cline-any cline-no">&nbsp;</span>
857
- <span class="cline-any cline-no">&nbsp;</span>
858
- <span class="cline-any cline-no">&nbsp;</span>
859
- <span class="cline-any cline-no">&nbsp;</span>
860
- <span class="cline-any cline-no">&nbsp;</span>
861
- <span class="cline-any cline-no">&nbsp;</span>
862
- <span class="cline-any cline-no">&nbsp;</span>
863
- <span class="cline-any cline-no">&nbsp;</span>
864
- <span class="cline-any cline-no">&nbsp;</span>
865
- <span class="cline-any cline-no">&nbsp;</span>
866
- <span class="cline-any cline-no">&nbsp;</span>
867
- <span class="cline-any cline-neutral">&nbsp;</span>
868
- <span class="cline-any cline-neutral">&nbsp;</span>
869
- <span class="cline-any cline-neutral">&nbsp;</span>
870
- <span class="cline-any cline-neutral">&nbsp;</span>
871
- <span class="cline-any cline-neutral">&nbsp;</span>
872
- <span class="cline-any cline-neutral">&nbsp;</span>
873
- <span class="cline-any cline-neutral">&nbsp;</span>
874
- <span class="cline-any cline-neutral">&nbsp;</span>
875
- <span class="cline-any cline-neutral">&nbsp;</span>
876
- <span class="cline-any cline-neutral">&nbsp;</span>
877
- <span class="cline-any cline-neutral">&nbsp;</span>
878
- <span class="cline-any cline-neutral">&nbsp;</span>
879
- <span class="cline-any cline-neutral">&nbsp;</span>
880
- <span class="cline-any cline-neutral">&nbsp;</span>
881
- <span class="cline-any cline-neutral">&nbsp;</span>
882
- <span class="cline-any cline-no">&nbsp;</span>
883
- <span class="cline-any cline-no">&nbsp;</span>
884
- <span class="cline-any cline-no">&nbsp;</span>
885
- <span class="cline-any cline-no">&nbsp;</span>
886
- <span class="cline-any cline-no">&nbsp;</span>
887
- <span class="cline-any cline-no">&nbsp;</span>
888
- <span class="cline-any cline-no">&nbsp;</span>
889
- <span class="cline-any cline-no">&nbsp;</span>
890
- <span class="cline-any cline-no">&nbsp;</span>
891
- <span class="cline-any cline-no">&nbsp;</span>
892
- <span class="cline-any cline-no">&nbsp;</span>
893
- <span class="cline-any cline-no">&nbsp;</span>
894
- <span class="cline-any cline-neutral">&nbsp;</span>
895
- <span class="cline-any cline-no">&nbsp;</span>
896
- <span class="cline-any cline-no">&nbsp;</span>
897
- <span class="cline-any cline-no">&nbsp;</span>
898
- <span class="cline-any cline-no">&nbsp;</span>
899
- <span class="cline-any cline-no">&nbsp;</span>
900
- <span class="cline-any cline-no">&nbsp;</span>
901
- <span class="cline-any cline-neutral">&nbsp;</span>
902
- <span class="cline-any cline-no">&nbsp;</span>
903
- <span class="cline-any cline-no">&nbsp;</span>
904
- <span class="cline-any cline-no">&nbsp;</span>
905
- <span class="cline-any cline-no">&nbsp;</span>
906
- <span class="cline-any cline-no">&nbsp;</span>
907
- <span class="cline-any cline-no">&nbsp;</span>
908
- <span class="cline-any cline-no">&nbsp;</span>
909
- <span class="cline-any cline-no">&nbsp;</span>
910
- <span class="cline-any cline-no">&nbsp;</span>
911
- <span class="cline-any cline-neutral">&nbsp;</span>
912
- <span class="cline-any cline-neutral">&nbsp;</span>
913
- <span class="cline-any cline-no">&nbsp;</span>
914
- <span class="cline-any cline-no">&nbsp;</span>
915
- <span class="cline-any cline-no">&nbsp;</span>
916
- <span class="cline-any cline-no">&nbsp;</span>
917
- <span class="cline-any cline-no">&nbsp;</span>
918
- <span class="cline-any cline-neutral">&nbsp;</span>
919
- <span class="cline-any cline-no">&nbsp;</span>
920
- <span class="cline-any cline-neutral">&nbsp;</span>
921
- <span class="cline-any cline-no">&nbsp;</span>
922
- <span class="cline-any cline-no">&nbsp;</span>
923
- <span class="cline-any cline-no">&nbsp;</span>
924
- <span class="cline-any cline-no">&nbsp;</span>
925
- <span class="cline-any cline-no">&nbsp;</span>
926
- <span class="cline-any cline-no">&nbsp;</span>
927
- <span class="cline-any cline-no">&nbsp;</span>
928
- <span class="cline-any cline-no">&nbsp;</span>
929
- <span class="cline-any cline-no">&nbsp;</span>
930
- <span class="cline-any cline-no">&nbsp;</span>
931
- <span class="cline-any cline-no">&nbsp;</span>
932
- <span class="cline-any cline-no">&nbsp;</span>
933
- <span class="cline-any cline-no">&nbsp;</span>
934
- <span class="cline-any cline-neutral">&nbsp;</span>
935
- <span class="cline-any cline-no">&nbsp;</span>
936
- <span class="cline-any cline-no">&nbsp;</span>
937
- <span class="cline-any cline-no">&nbsp;</span>
938
- <span class="cline-any cline-no">&nbsp;</span>
939
- <span class="cline-any cline-neutral">&nbsp;</span>
940
- <span class="cline-any cline-no">&nbsp;</span>
941
- <span class="cline-any cline-neutral">&nbsp;</span>
942
- <span class="cline-any cline-no">&nbsp;</span>
943
- <span class="cline-any cline-no">&nbsp;</span>
944
- <span class="cline-any cline-no">&nbsp;</span>
945
- <span class="cline-any cline-no">&nbsp;</span>
946
- <span class="cline-any cline-no">&nbsp;</span>
947
- <span class="cline-any cline-no">&nbsp;</span>
948
- <span class="cline-any cline-no">&nbsp;</span>
949
- <span class="cline-any cline-no">&nbsp;</span>
950
- <span class="cline-any cline-no">&nbsp;</span>
951
- <span class="cline-any cline-no">&nbsp;</span>
952
- <span class="cline-any cline-neutral">&nbsp;</span>
953
- <span class="cline-any cline-no">&nbsp;</span>
954
- <span class="cline-any cline-no">&nbsp;</span>
955
- <span class="cline-any cline-neutral">&nbsp;</span>
956
- <span class="cline-any cline-no">&nbsp;</span>
957
- <span class="cline-any cline-no">&nbsp;</span>
958
- <span class="cline-any cline-neutral">&nbsp;</span>
959
- <span class="cline-any cline-no">&nbsp;</span>
960
- <span class="cline-any cline-neutral">&nbsp;</span>
961
- <span class="cline-any cline-no">&nbsp;</span>
962
- <span class="cline-any cline-no">&nbsp;</span>
963
- <span class="cline-any cline-no">&nbsp;</span>
964
- <span class="cline-any cline-no">&nbsp;</span>
965
- <span class="cline-any cline-no">&nbsp;</span>
966
- <span class="cline-any cline-neutral">&nbsp;</span>
967
- <span class="cline-any cline-neutral">&nbsp;</span>
968
- <span class="cline-any cline-neutral">&nbsp;</span>
969
- <span class="cline-any cline-no">&nbsp;</span>
970
- <span class="cline-any cline-no">&nbsp;</span>
971
- <span class="cline-any cline-no">&nbsp;</span>
972
- <span class="cline-any cline-no">&nbsp;</span>
973
- <span class="cline-any cline-no">&nbsp;</span>
974
- <span class="cline-any cline-no">&nbsp;</span>
975
- <span class="cline-any cline-no">&nbsp;</span>
976
- <span class="cline-any cline-no">&nbsp;</span>
977
- <span class="cline-any cline-no">&nbsp;</span>
978
- <span class="cline-any cline-no">&nbsp;</span>
979
- <span class="cline-any cline-no">&nbsp;</span>
980
- <span class="cline-any cline-no">&nbsp;</span>
981
- <span class="cline-any cline-no">&nbsp;</span>
982
- <span class="cline-any cline-no">&nbsp;</span>
983
- <span class="cline-any cline-no">&nbsp;</span>
984
- <span class="cline-any cline-no">&nbsp;</span>
985
- <span class="cline-any cline-no">&nbsp;</span>
986
- <span class="cline-any cline-no">&nbsp;</span>
987
- <span class="cline-any cline-neutral">&nbsp;</span>
988
- <span class="cline-any cline-no">&nbsp;</span>
989
- <span class="cline-any cline-no">&nbsp;</span>
990
- <span class="cline-any cline-no">&nbsp;</span>
991
- <span class="cline-any cline-no">&nbsp;</span>
992
- <span class="cline-any cline-no">&nbsp;</span>
993
- <span class="cline-any cline-no">&nbsp;</span>
994
- <span class="cline-any cline-no">&nbsp;</span>
995
- <span class="cline-any cline-no">&nbsp;</span>
996
- <span class="cline-any cline-no">&nbsp;</span>
997
- <span class="cline-any cline-no">&nbsp;</span>
998
- <span class="cline-any cline-no">&nbsp;</span>
999
- <span class="cline-any cline-no">&nbsp;</span>
1000
- <span class="cline-any cline-no">&nbsp;</span>
1001
- <span class="cline-any cline-neutral">&nbsp;</span>
1002
- <span class="cline-any cline-no">&nbsp;</span>
1003
- <span class="cline-any cline-neutral">&nbsp;</span>
1004
- <span class="cline-any cline-no">&nbsp;</span>
1005
- <span class="cline-any cline-no">&nbsp;</span>
1006
- <span class="cline-any cline-no">&nbsp;</span>
1007
- <span class="cline-any cline-no">&nbsp;</span>
1008
- <span class="cline-any cline-no">&nbsp;</span>
1009
- <span class="cline-any cline-no">&nbsp;</span>
1010
- <span class="cline-any cline-no">&nbsp;</span>
1011
- <span class="cline-any cline-no">&nbsp;</span>
1012
- <span class="cline-any cline-no">&nbsp;</span>
1013
- <span class="cline-any cline-no">&nbsp;</span>
1014
- <span class="cline-any cline-no">&nbsp;</span>
1015
- <span class="cline-any cline-no">&nbsp;</span>
1016
- <span class="cline-any cline-no">&nbsp;</span>
1017
- <span class="cline-any cline-no">&nbsp;</span>
1018
- <span class="cline-any cline-no">&nbsp;</span>
1019
- <span class="cline-any cline-neutral">&nbsp;</span>
1020
- <span class="cline-any cline-no">&nbsp;</span>
1021
- <span class="cline-any cline-no">&nbsp;</span>
1022
- <span class="cline-any cline-no">&nbsp;</span>
1023
- <span class="cline-any cline-no">&nbsp;</span>
1024
- <span class="cline-any cline-no">&nbsp;</span>
1025
- <span class="cline-any cline-no">&nbsp;</span>
1026
- <span class="cline-any cline-no">&nbsp;</span>
1027
- <span class="cline-any cline-no">&nbsp;</span>
1028
- <span class="cline-any cline-no">&nbsp;</span>
1029
- <span class="cline-any cline-no">&nbsp;</span>
1030
- <span class="cline-any cline-no">&nbsp;</span>
1031
- <span class="cline-any cline-no">&nbsp;</span>
1032
- <span class="cline-any cline-no">&nbsp;</span>
1033
- <span class="cline-any cline-no">&nbsp;</span>
1034
- <span class="cline-any cline-no">&nbsp;</span>
1035
- <span class="cline-any cline-no">&nbsp;</span>
1036
- <span class="cline-any cline-no">&nbsp;</span>
1037
- <span class="cline-any cline-no">&nbsp;</span>
1038
- <span class="cline-any cline-no">&nbsp;</span>
1039
- <span class="cline-any cline-no">&nbsp;</span>
1040
- <span class="cline-any cline-no">&nbsp;</span>
1041
- <span class="cline-any cline-no">&nbsp;</span>
1042
- <span class="cline-any cline-no">&nbsp;</span>
1043
- <span class="cline-any cline-no">&nbsp;</span>
1044
- <span class="cline-any cline-no">&nbsp;</span>
1045
- <span class="cline-any cline-no">&nbsp;</span>
1046
- <span class="cline-any cline-no">&nbsp;</span>
1047
- <span class="cline-any cline-no">&nbsp;</span>
1048
- <span class="cline-any cline-no">&nbsp;</span>
1049
- <span class="cline-any cline-no">&nbsp;</span>
1050
- <span class="cline-any cline-no">&nbsp;</span>
1051
- <span class="cline-any cline-no">&nbsp;</span>
1052
- <span class="cline-any cline-no">&nbsp;</span>
1053
- <span class="cline-any cline-no">&nbsp;</span>
1054
- <span class="cline-any cline-no">&nbsp;</span>
1055
- <span class="cline-any cline-no">&nbsp;</span>
1056
- <span class="cline-any cline-no">&nbsp;</span>
1057
- <span class="cline-any cline-neutral">&nbsp;</span>
1058
- <span class="cline-any cline-neutral">&nbsp;</span>
1059
- <span class="cline-any cline-neutral">&nbsp;</span>
1060
- <span class="cline-any cline-neutral">&nbsp;</span>
1061
- <span class="cline-any cline-neutral">&nbsp;</span>
1062
- <span class="cline-any cline-no">&nbsp;</span>
1063
- <span class="cline-any cline-no">&nbsp;</span>
1064
- <span class="cline-any cline-neutral">&nbsp;</span>
1065
- <span class="cline-any cline-neutral">&nbsp;</span>
1066
- <span class="cline-any cline-neutral">&nbsp;</span>
1067
- <span class="cline-any cline-neutral">&nbsp;</span>
1068
- <span class="cline-any cline-no">&nbsp;</span>
1069
- <span class="cline-any cline-no">&nbsp;</span>
1070
- <span class="cline-any cline-no">&nbsp;</span>
1071
- <span class="cline-any cline-no">&nbsp;</span>
1072
- <span class="cline-any cline-no">&nbsp;</span>
1073
- <span class="cline-any cline-no">&nbsp;</span>
1074
- <span class="cline-any cline-no">&nbsp;</span>
1075
- <span class="cline-any cline-no">&nbsp;</span>
1076
- <span class="cline-any cline-no">&nbsp;</span>
1077
- <span class="cline-any cline-neutral">&nbsp;</span>
1078
- <span class="cline-any cline-no">&nbsp;</span>
1079
- <span class="cline-any cline-no">&nbsp;</span>
1080
- <span class="cline-any cline-no">&nbsp;</span>
1081
- <span class="cline-any cline-no">&nbsp;</span>
1082
- <span class="cline-any cline-no">&nbsp;</span>
1083
- <span class="cline-any cline-no">&nbsp;</span>
1084
- <span class="cline-any cline-no">&nbsp;</span>
1085
- <span class="cline-any cline-no">&nbsp;</span>
1086
- <span class="cline-any cline-no">&nbsp;</span>
1087
- <span class="cline-any cline-no">&nbsp;</span>
1088
- <span class="cline-any cline-no">&nbsp;</span>
1089
- <span class="cline-any cline-no">&nbsp;</span>
1090
- <span class="cline-any cline-no">&nbsp;</span>
1091
- <span class="cline-any cline-no">&nbsp;</span>
1092
- <span class="cline-any cline-no">&nbsp;</span>
1093
- <span class="cline-any cline-no">&nbsp;</span>
1094
- <span class="cline-any cline-no">&nbsp;</span>
1095
- <span class="cline-any cline-no">&nbsp;</span>
1096
- <span class="cline-any cline-no">&nbsp;</span>
1097
- <span class="cline-any cline-neutral">&nbsp;</span>
1098
- <span class="cline-any cline-neutral">&nbsp;</span>
1099
- <span class="cline-any cline-neutral">&nbsp;</span>
1100
- <span class="cline-any cline-neutral">&nbsp;</span>
1101
- <span class="cline-any cline-neutral">&nbsp;</span>
1102
- <span class="cline-any cline-neutral">&nbsp;</span>
1103
- <span class="cline-any cline-neutral">&nbsp;</span>
1104
- <span class="cline-any cline-neutral">&nbsp;</span>
1105
- <span class="cline-any cline-no">&nbsp;</span>
1106
- <span class="cline-any cline-no">&nbsp;</span>
1107
- <span class="cline-any cline-no">&nbsp;</span>
1108
- <span class="cline-any cline-no">&nbsp;</span>
1109
- <span class="cline-any cline-no">&nbsp;</span>
1110
- <span class="cline-any cline-no">&nbsp;</span>
1111
- <span class="cline-any cline-no">&nbsp;</span>
1112
- <span class="cline-any cline-neutral">&nbsp;</span>
1113
- <span class="cline-any cline-no">&nbsp;</span>
1114
- <span class="cline-any cline-no">&nbsp;</span>
1115
- <span class="cline-any cline-no">&nbsp;</span>
1116
- <span class="cline-any cline-no">&nbsp;</span>
1117
- <span class="cline-any cline-no">&nbsp;</span>
1118
- <span class="cline-any cline-no">&nbsp;</span>
1119
- <span class="cline-any cline-neutral">&nbsp;</span>
1120
- <span class="cline-any cline-no">&nbsp;</span>
1121
- <span class="cline-any cline-neutral">&nbsp;</span>
1122
- <span class="cline-any cline-no">&nbsp;</span>
1123
- <span class="cline-any cline-no">&nbsp;</span>
1124
- <span class="cline-any cline-no">&nbsp;</span>
1125
- <span class="cline-any cline-no">&nbsp;</span>
1126
- <span class="cline-any cline-no">&nbsp;</span>
1127
- <span class="cline-any cline-no">&nbsp;</span>
1128
- <span class="cline-any cline-no">&nbsp;</span>
1129
- <span class="cline-any cline-no">&nbsp;</span>
1130
- <span class="cline-any cline-no">&nbsp;</span>
1131
- <span class="cline-any cline-no">&nbsp;</span>
1132
- <span class="cline-any cline-no">&nbsp;</span>
1133
- <span class="cline-any cline-no">&nbsp;</span>
1134
- <span class="cline-any cline-no">&nbsp;</span>
1135
- <span class="cline-any cline-no">&nbsp;</span>
1136
- <span class="cline-any cline-no">&nbsp;</span>
1137
- <span class="cline-any cline-neutral">&nbsp;</span>
1138
- <span class="cline-any cline-neutral">&nbsp;</span>
1139
- <span class="cline-any cline-neutral">&nbsp;</span>
1140
- <span class="cline-any cline-neutral">&nbsp;</span>
1141
- <span class="cline-any cline-no">&nbsp;</span>
1142
- <span class="cline-any cline-no">&nbsp;</span>
1143
- <span class="cline-any cline-no">&nbsp;</span>
1144
- <span class="cline-any cline-no">&nbsp;</span>
1145
- <span class="cline-any cline-no">&nbsp;</span>
1146
- <span class="cline-any cline-no">&nbsp;</span>
1147
- <span class="cline-any cline-no">&nbsp;</span>
1148
- <span class="cline-any cline-no">&nbsp;</span>
1149
- <span class="cline-any cline-no">&nbsp;</span>
1150
- <span class="cline-any cline-no">&nbsp;</span>
1151
- <span class="cline-any cline-no">&nbsp;</span>
1152
- <span class="cline-any cline-no">&nbsp;</span>
1153
- <span class="cline-any cline-no">&nbsp;</span>
1154
- <span class="cline-any cline-no">&nbsp;</span>
1155
- <span class="cline-any cline-no">&nbsp;</span>
1156
- <span class="cline-any cline-neutral">&nbsp;</span>
1157
- <span class="cline-any cline-neutral">&nbsp;</span>
1158
- <span class="cline-any cline-no">&nbsp;</span>
1159
- <span class="cline-any cline-no">&nbsp;</span>
1160
- <span class="cline-any cline-no">&nbsp;</span>
1161
- <span class="cline-any cline-no">&nbsp;</span>
1162
- <span class="cline-any cline-no">&nbsp;</span>
1163
- <span class="cline-any cline-no">&nbsp;</span>
1164
- <span class="cline-any cline-no">&nbsp;</span>
1165
- <span class="cline-any cline-no">&nbsp;</span>
1166
- <span class="cline-any cline-no">&nbsp;</span>
1167
- <span class="cline-any cline-no">&nbsp;</span>
1168
- <span class="cline-any cline-no">&nbsp;</span>
1169
- <span class="cline-any cline-no">&nbsp;</span>
1170
- <span class="cline-any cline-no">&nbsp;</span>
1171
- <span class="cline-any cline-no">&nbsp;</span>
1172
- <span class="cline-any cline-no">&nbsp;</span>
1173
- <span class="cline-any cline-no">&nbsp;</span>
1174
- <span class="cline-any cline-no">&nbsp;</span>
1175
- <span class="cline-any cline-neutral">&nbsp;</span>
1176
- <span class="cline-any cline-no">&nbsp;</span>
1177
- <span class="cline-any cline-no">&nbsp;</span>
1178
- <span class="cline-any cline-no">&nbsp;</span>
1179
- <span class="cline-any cline-no">&nbsp;</span>
1180
- <span class="cline-any cline-no">&nbsp;</span>
1181
- <span class="cline-any cline-no">&nbsp;</span>
1182
- <span class="cline-any cline-no">&nbsp;</span>
1183
- <span class="cline-any cline-no">&nbsp;</span>
1184
- <span class="cline-any cline-no">&nbsp;</span>
1185
- <span class="cline-any cline-no">&nbsp;</span>
1186
- <span class="cline-any cline-no">&nbsp;</span>
1187
- <span class="cline-any cline-no">&nbsp;</span>
1188
- <span class="cline-any cline-neutral">&nbsp;</span>
1189
- <span class="cline-any cline-neutral">&nbsp;</span>
1190
- <span class="cline-any cline-no">&nbsp;</span>
1191
- <span class="cline-any cline-no">&nbsp;</span>
1192
- <span class="cline-any cline-no">&nbsp;</span>
1193
- <span class="cline-any cline-no">&nbsp;</span>
1194
- <span class="cline-any cline-no">&nbsp;</span>
1195
- <span class="cline-any cline-no">&nbsp;</span>
1196
- <span class="cline-any cline-neutral">&nbsp;</span>
1197
- <span class="cline-any cline-neutral">&nbsp;</span>
1198
- <span class="cline-any cline-neutral">&nbsp;</span>
1199
- <span class="cline-any cline-neutral">&nbsp;</span>
1200
- <span class="cline-any cline-neutral">&nbsp;</span>
1201
- <span class="cline-any cline-no">&nbsp;</span>
1202
- <span class="cline-any cline-no">&nbsp;</span>
1203
- <span class="cline-any cline-no">&nbsp;</span>
1204
- <span class="cline-any cline-neutral">&nbsp;</span>
1205
- <span class="cline-any cline-no">&nbsp;</span>
1206
- <span class="cline-any cline-neutral">&nbsp;</span>
1207
- <span class="cline-any cline-neutral">&nbsp;</span>
1208
- <span class="cline-any cline-neutral">&nbsp;</span>
1209
- <span class="cline-any cline-no">&nbsp;</span>
1210
- <span class="cline-any cline-no">&nbsp;</span>
1211
- <span class="cline-any cline-no">&nbsp;</span>
1212
- <span class="cline-any cline-neutral">&nbsp;</span>
1213
- <span class="cline-any cline-no">&nbsp;</span>
1214
- <span class="cline-any cline-neutral">&nbsp;</span>
1215
- <span class="cline-any cline-neutral">&nbsp;</span>
1216
- <span class="cline-any cline-no">&nbsp;</span>
1217
- <span class="cline-any cline-no">&nbsp;</span>
1218
- <span class="cline-any cline-neutral">&nbsp;</span>
1219
- <span class="cline-any cline-neutral">&nbsp;</span>
1220
- <span class="cline-any cline-no">&nbsp;</span>
1221
- <span class="cline-any cline-no">&nbsp;</span>
1222
- <span class="cline-any cline-no">&nbsp;</span>
1223
- <span class="cline-any cline-no">&nbsp;</span>
1224
- <span class="cline-any cline-no">&nbsp;</span>
1225
- <span class="cline-any cline-no">&nbsp;</span>
1226
- <span class="cline-any cline-no">&nbsp;</span>
1227
- <span class="cline-any cline-no">&nbsp;</span>
1228
- <span class="cline-any cline-no">&nbsp;</span>
1229
- <span class="cline-any cline-neutral">&nbsp;</span>
1230
- <span class="cline-any cline-no">&nbsp;</span>
1231
- <span class="cline-any cline-no">&nbsp;</span>
1232
- <span class="cline-any cline-neutral">&nbsp;</span>
1233
- <span class="cline-any cline-no">&nbsp;</span>
1234
- <span class="cline-any cline-neutral">&nbsp;</span>
1235
- <span class="cline-any cline-no">&nbsp;</span>
1236
- <span class="cline-any cline-neutral">&nbsp;</span>
1237
- <span class="cline-any cline-no">&nbsp;</span>
1238
- <span class="cline-any cline-no">&nbsp;</span>
1239
- <span class="cline-any cline-no">&nbsp;</span>
1240
- <span class="cline-any cline-neutral">&nbsp;</span>
1241
- <span class="cline-any cline-no">&nbsp;</span>
1242
- <span class="cline-any cline-no">&nbsp;</span>
1243
- <span class="cline-any cline-no">&nbsp;</span>
1244
- <span class="cline-any cline-no">&nbsp;</span>
1245
- <span class="cline-any cline-no">&nbsp;</span>
1246
- <span class="cline-any cline-no">&nbsp;</span>
1247
- <span class="cline-any cline-no">&nbsp;</span>
1248
- <span class="cline-any cline-no">&nbsp;</span>
1249
- <span class="cline-any cline-neutral">&nbsp;</span>
1250
- <span class="cline-any cline-no">&nbsp;</span>
1251
- <span class="cline-any cline-no">&nbsp;</span>
1252
- <span class="cline-any cline-no">&nbsp;</span>
1253
- <span class="cline-any cline-no">&nbsp;</span>
1254
- <span class="cline-any cline-no">&nbsp;</span>
1255
- <span class="cline-any cline-no">&nbsp;</span>
1256
- <span class="cline-any cline-no">&nbsp;</span>
1257
- <span class="cline-any cline-no">&nbsp;</span>
1258
- <span class="cline-any cline-no">&nbsp;</span>
1259
- <span class="cline-any cline-no">&nbsp;</span>
1260
- <span class="cline-any cline-no">&nbsp;</span>
1261
- <span class="cline-any cline-no">&nbsp;</span>
1262
- <span class="cline-any cline-no">&nbsp;</span>
1263
- <span class="cline-any cline-neutral">&nbsp;</span>
1264
- <span class="cline-any cline-no">&nbsp;</span>
1265
- <span class="cline-any cline-neutral">&nbsp;</span>
1266
- <span class="cline-any cline-no">&nbsp;</span>
1267
- <span class="cline-any cline-no">&nbsp;</span>
1268
- <span class="cline-any cline-no">&nbsp;</span>
1269
- <span class="cline-any cline-no">&nbsp;</span>
1270
- <span class="cline-any cline-no">&nbsp;</span>
1271
- <span class="cline-any cline-no">&nbsp;</span>
1272
- <span class="cline-any cline-no">&nbsp;</span>
1273
- <span class="cline-any cline-no">&nbsp;</span>
1274
- <span class="cline-any cline-no">&nbsp;</span>
1275
- <span class="cline-any cline-no">&nbsp;</span>
1276
- <span class="cline-any cline-no">&nbsp;</span>
1277
- <span class="cline-any cline-no">&nbsp;</span>
1278
- <span class="cline-any cline-no">&nbsp;</span>
1279
- <span class="cline-any cline-neutral">&nbsp;</span>
1280
- <span class="cline-any cline-no">&nbsp;</span>
1281
- <span class="cline-any cline-no">&nbsp;</span>
1282
- <span class="cline-any cline-no">&nbsp;</span>
1283
- <span class="cline-any cline-no">&nbsp;</span>
1284
- <span class="cline-any cline-no">&nbsp;</span>
1285
- <span class="cline-any cline-no">&nbsp;</span>
1286
- <span class="cline-any cline-no">&nbsp;</span>
1287
- <span class="cline-any cline-no">&nbsp;</span>
1288
- <span class="cline-any cline-no">&nbsp;</span>
1289
- <span class="cline-any cline-no">&nbsp;</span>
1290
- <span class="cline-any cline-no">&nbsp;</span>
1291
- <span class="cline-any cline-neutral">&nbsp;</span>
1292
- <span class="cline-any cline-no">&nbsp;</span>
1293
- <span class="cline-any cline-no">&nbsp;</span>
1294
- <span class="cline-any cline-no">&nbsp;</span>
1295
- <span class="cline-any cline-no">&nbsp;</span>
1296
- <span class="cline-any cline-no">&nbsp;</span>
1297
- <span class="cline-any cline-no">&nbsp;</span>
1298
- <span class="cline-any cline-no">&nbsp;</span>
1299
- <span class="cline-any cline-neutral">&nbsp;</span>
1300
- <span class="cline-any cline-no">&nbsp;</span>
1301
- <span class="cline-any cline-no">&nbsp;</span>
1302
- <span class="cline-any cline-no">&nbsp;</span>
1303
- <span class="cline-any cline-neutral">&nbsp;</span>
1304
- <span class="cline-any cline-no">&nbsp;</span>
1305
- <span class="cline-any cline-no">&nbsp;</span>
1306
- <span class="cline-any cline-no">&nbsp;</span>
1307
- <span class="cline-any cline-no">&nbsp;</span>
1308
- <span class="cline-any cline-no">&nbsp;</span>
1309
- <span class="cline-any cline-no">&nbsp;</span>
1310
- <span class="cline-any cline-no">&nbsp;</span>
1311
- <span class="cline-any cline-no">&nbsp;</span>
1312
- <span class="cline-any cline-no">&nbsp;</span>
1313
- <span class="cline-any cline-no">&nbsp;</span>
1314
- <span class="cline-any cline-no">&nbsp;</span>
1315
- <span class="cline-any cline-no">&nbsp;</span>
1316
- <span class="cline-any cline-no">&nbsp;</span>
1317
- <span class="cline-any cline-no">&nbsp;</span>
1318
- <span class="cline-any cline-no">&nbsp;</span>
1319
- <span class="cline-any cline-no">&nbsp;</span>
1320
- <span class="cline-any cline-no">&nbsp;</span>
1321
- <span class="cline-any cline-no">&nbsp;</span>
1322
- <span class="cline-any cline-no">&nbsp;</span>
1323
- <span class="cline-any cline-no">&nbsp;</span>
1324
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">// Copyright 2021-2025 Prosopo (UK) Ltd.
1325
- //
1326
- // Licensed under the Apache License, Version 2.0 (the "License");
1327
- // you may not use this file except in compliance with the License.
1328
- // You may obtain a copy of the License at
1329
- //
1330
- // http://www.apache.org/licenses/LICENSE-2.0
1331
- //
1332
- // Unless required by applicable law or agreed to in writing, software
1333
- // distributed under the License is distributed on an "AS IS" BASIS,
1334
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1335
- // See the License for the specific language governing permissions and
1336
- // limitations under the License.
1337
- &nbsp;
1338
- <span class="cstat-no" title="statement not covered" >import { stringToHex, u8aToHex } from "@polkadot/util";</span>
1339
- <span class="cstat-no" title="statement not covered" >import { type Logger, ProsopoEnvError } from "@prosopo/common";</span>
1340
- <span class="cstat-no" title="statement not covered" >import {</span>
1341
- compareCaptchaSolutions,
1342
- computePendingRequestHash,
1343
- parseAndSortCaptchaSolutions,
1344
- } from "@prosopo/datasets";
1345
- import type { KeyringPair } from "@prosopo/types";
1346
- <span class="cstat-no" title="statement not covered" >import {</span>
1347
- ApiParams,
1348
- type Captcha,
1349
- type CaptchaSolution,
1350
- CaptchaStatus,
1351
- DEFAULT_IMAGE_CAPTCHA_TIMEOUT,
1352
- type DappUserSolutionResult,
1353
- type Hash,
1354
- type IPAddress,
1355
- type ImageVerificationResponse,
1356
- type ProsopoCaptchaCountConfigSchemaOutput,
1357
- type ProsopoConfigOutput,
1358
- type RequestHeaders,
1359
- } from "@prosopo/types";
1360
- import type {
1361
- ClientRecord,
1362
- FrictionlessTokenId,
1363
- IProviderDatabase,
1364
- PendingCaptchaRequest,
1365
- UserCommitment,
1366
- } from "@prosopo/types-database";
1367
- import type { ProviderEnvironment } from "@prosopo/types-env";
1368
- <span class="cstat-no" title="statement not covered" >import { at, extractData } from "@prosopo/util";</span>
1369
- <span class="cstat-no" title="statement not covered" >import { randomAsHex, signatureVerify } from "@prosopo/util-crypto";</span>
1370
- <span class="cstat-no" title="statement not covered" >import {</span>
1371
- getCompositeIpAddress,
1372
- getIpAddressFromComposite,
1373
- } from "../../compositeIpAddress.js";
1374
- <span class="cstat-no" title="statement not covered" >import { constructPairList, containsIdenticalPairs } from "../../pairs.js";</span>
1375
- <span class="cstat-no" title="statement not covered" >import { checkLangRules } from "../../rules/lang.js";</span>
1376
- <span class="cstat-no" title="statement not covered" >import { deepValidateIpAddress, shuffleArray } from "../../util.js";</span>
1377
- <span class="cstat-no" title="statement not covered" >import { CaptchaManager } from "../captchaManager.js";</span>
1378
- <span class="cstat-no" title="statement not covered" >import { computeFrictionlessScore } from "../frictionless/frictionlessTasksUtils.js";</span>
1379
- <span class="cstat-no" title="statement not covered" >import { buildTreeAndGetCommitmentId } from "./imgCaptchaTasksUtils.js";</span>
1380
- &nbsp;
1381
- <span class="cstat-no" title="statement not covered" >export class ImgCaptchaManager extends CaptchaManager {</span>
1382
- config: ProsopoConfigOutput;
1383
- &nbsp;
1384
- <span class="cstat-no" title="statement not covered" > constructor(</span>
1385
- <span class="cstat-no" title="statement not covered" > db: IProviderDatabase,</span>
1386
- <span class="cstat-no" title="statement not covered" > pair: KeyringPair,</span>
1387
- <span class="cstat-no" title="statement not covered" > config: ProsopoConfigOutput,</span>
1388
- <span class="cstat-no" title="statement not covered" > logger?: Logger,</span>
1389
- <span class="cstat-no" title="statement not covered" > ) {</span>
1390
- <span class="cstat-no" title="statement not covered" > super(db, pair, logger);</span>
1391
- <span class="cstat-no" title="statement not covered" > this.config = config;</span>
1392
- <span class="cstat-no" title="statement not covered" > }</span>
1393
- &nbsp;
1394
- <span class="cstat-no" title="statement not covered" > async getCaptchaWithProof(</span>
1395
- <span class="cstat-no" title="statement not covered" > datasetId: Hash,</span>
1396
- <span class="cstat-no" title="statement not covered" > solved: boolean,</span>
1397
- <span class="cstat-no" title="statement not covered" > size: number,</span>
1398
- <span class="cstat-no" title="statement not covered" > ): Promise&lt;Captcha[]&gt; {</span>
1399
- <span class="cstat-no" title="statement not covered" > const captchaDocs = await this.db.getRandomCaptcha(solved, datasetId, size);</span>
1400
- <span class="cstat-no" title="statement not covered" > if (!captchaDocs) {</span>
1401
- <span class="cstat-no" title="statement not covered" > throw new ProsopoEnvError("DATABASE.CAPTCHA_GET_FAILED", {</span>
1402
- <span class="cstat-no" title="statement not covered" > context: {</span>
1403
- <span class="cstat-no" title="statement not covered" > failedFuncName: this.getCaptchaWithProof.name,</span>
1404
- <span class="cstat-no" title="statement not covered" > datasetId,</span>
1405
- <span class="cstat-no" title="statement not covered" > solved,</span>
1406
- <span class="cstat-no" title="statement not covered" > size,</span>
1407
- <span class="cstat-no" title="statement not covered" > },</span>
1408
- <span class="cstat-no" title="statement not covered" > });</span>
1409
- <span class="cstat-no" title="statement not covered" > }</span>
1410
- &nbsp;
1411
- <span class="cstat-no" title="statement not covered" > return captchaDocs;</span>
1412
- <span class="cstat-no" title="statement not covered" > }</span>
1413
- &nbsp;
1414
- <span class="cstat-no" title="statement not covered" > async getRandomCaptchasAndRequestHash(</span>
1415
- <span class="cstat-no" title="statement not covered" > datasetId: Hash,</span>
1416
- <span class="cstat-no" title="statement not covered" > userAccount: string,</span>
1417
- <span class="cstat-no" title="statement not covered" > ipAddress: IPAddress,</span>
1418
- <span class="cstat-no" title="statement not covered" > captchaConfig: ProsopoCaptchaCountConfigSchemaOutput,</span>
1419
- <span class="cstat-no" title="statement not covered" > threshold: number,</span>
1420
- <span class="cstat-no" title="statement not covered" > frictionlessTokenId?: FrictionlessTokenId,</span>
1421
- ): Promise&lt;{
1422
- captchas: Captcha[];
1423
- requestHash: string;
1424
- timestamp: number;
1425
- signedRequestHash: string;
1426
- <span class="cstat-no" title="statement not covered" > }&gt; {</span>
1427
- <span class="cstat-no" title="statement not covered" > const dataset = await this.db.getDatasetDetails(datasetId);</span>
1428
- <span class="cstat-no" title="statement not covered" > if (!dataset) {</span>
1429
- <span class="cstat-no" title="statement not covered" > throw new ProsopoEnvError("DATABASE.DATASET_GET_FAILED", {</span>
1430
- <span class="cstat-no" title="statement not covered" > context: {</span>
1431
- <span class="cstat-no" title="statement not covered" > failedFuncName: this.getRandomCaptchasAndRequestHash.name,</span>
1432
- <span class="cstat-no" title="statement not covered" > dataset,</span>
1433
- <span class="cstat-no" title="statement not covered" > datasetId,</span>
1434
- <span class="cstat-no" title="statement not covered" > },</span>
1435
- <span class="cstat-no" title="statement not covered" > });</span>
1436
- <span class="cstat-no" title="statement not covered" > }</span>
1437
- &nbsp;
1438
- <span class="cstat-no" title="statement not covered" > const unsolvedCount: number = Math.abs(</span>
1439
- <span class="cstat-no" title="statement not covered" > Math.trunc(captchaConfig.unsolved.count),</span>
1440
- <span class="cstat-no" title="statement not covered" > );</span>
1441
- <span class="cstat-no" title="statement not covered" > const solvedCount: number = Math.abs(</span>
1442
- <span class="cstat-no" title="statement not covered" > Math.trunc(captchaConfig.solved.count),</span>
1443
- <span class="cstat-no" title="statement not covered" > );</span>
1444
- &nbsp;
1445
- <span class="cstat-no" title="statement not covered" > if (!solvedCount) {</span>
1446
- <span class="cstat-no" title="statement not covered" > throw new ProsopoEnvError("CONFIG.INVALID_CAPTCHA_NUMBER");</span>
1447
- <span class="cstat-no" title="statement not covered" > }</span>
1448
- &nbsp;
1449
- <span class="cstat-no" title="statement not covered" > const solved = await this.getCaptchaWithProof(datasetId, true, solvedCount);</span>
1450
- &nbsp;
1451
- <span class="cstat-no" title="statement not covered" > let unsolved: Captcha[] = [];</span>
1452
- <span class="cstat-no" title="statement not covered" > if (unsolvedCount) {</span>
1453
- <span class="cstat-no" title="statement not covered" > unsolved = await this.getCaptchaWithProof(</span>
1454
- <span class="cstat-no" title="statement not covered" > datasetId,</span>
1455
- <span class="cstat-no" title="statement not covered" > false,</span>
1456
- <span class="cstat-no" title="statement not covered" > unsolvedCount,</span>
1457
- <span class="cstat-no" title="statement not covered" > );</span>
1458
- <span class="cstat-no" title="statement not covered" > }</span>
1459
- <span class="cstat-no" title="statement not covered" > const captchas: Captcha[] = shuffleArray([...solved, ...unsolved]);</span>
1460
- <span class="cstat-no" title="statement not covered" > const salt = randomAsHex();</span>
1461
- &nbsp;
1462
- <span class="cstat-no" title="statement not covered" > const requestHash = computePendingRequestHash(</span>
1463
- <span class="cstat-no" title="statement not covered" > captchas.map((c) =&gt; c.captchaId),</span>
1464
- <span class="cstat-no" title="statement not covered" > userAccount,</span>
1465
- <span class="cstat-no" title="statement not covered" > salt,</span>
1466
- <span class="cstat-no" title="statement not covered" > );</span>
1467
- &nbsp;
1468
- <span class="cstat-no" title="statement not covered" > const currentTime = Date.now();</span>
1469
- <span class="cstat-no" title="statement not covered" > const signedRequestHash = u8aToHex(</span>
1470
- <span class="cstat-no" title="statement not covered" > this.pair.sign(stringToHex(requestHash)),</span>
1471
- <span class="cstat-no" title="statement not covered" > );</span>
1472
- &nbsp;
1473
- <span class="cstat-no" title="statement not covered" > const timeLimit = captchas</span>
1474
- // if 2 captchas with 30s time limit, this will add to 1 minute (30s * 2)
1475
- <span class="cstat-no" title="statement not covered" > .map((captcha) =&gt; captcha.timeLimitMs || DEFAULT_IMAGE_CAPTCHA_TIMEOUT)</span>
1476
- <span class="cstat-no" title="statement not covered" > .reduce((a, b) =&gt; a + b, 0);</span>
1477
- <span class="cstat-no" title="statement not covered" > const deadlineTs = timeLimit + currentTime;</span>
1478
- &nbsp;
1479
- <span class="cstat-no" title="statement not covered" > await this.db.storePendingImageCommitment(</span>
1480
- <span class="cstat-no" title="statement not covered" > userAccount,</span>
1481
- <span class="cstat-no" title="statement not covered" > requestHash,</span>
1482
- <span class="cstat-no" title="statement not covered" > salt,</span>
1483
- <span class="cstat-no" title="statement not covered" > deadlineTs,</span>
1484
- <span class="cstat-no" title="statement not covered" > currentTime,</span>
1485
- <span class="cstat-no" title="statement not covered" > getCompositeIpAddress(ipAddress),</span>
1486
- <span class="cstat-no" title="statement not covered" > threshold,</span>
1487
- <span class="cstat-no" title="statement not covered" > frictionlessTokenId,</span>
1488
- <span class="cstat-no" title="statement not covered" > );</span>
1489
- <span class="cstat-no" title="statement not covered" > return {</span>
1490
- <span class="cstat-no" title="statement not covered" > captchas,</span>
1491
- <span class="cstat-no" title="statement not covered" > requestHash,</span>
1492
- <span class="cstat-no" title="statement not covered" > timestamp: currentTime,</span>
1493
- <span class="cstat-no" title="statement not covered" > signedRequestHash,</span>
1494
- <span class="cstat-no" title="statement not covered" > };</span>
1495
- <span class="cstat-no" title="statement not covered" > }</span>
1496
- &nbsp;
1497
- /**
1498
- * Validate and store the text captcha solution(s) from the Dapp User in a web2 environment
1499
- * @param {string} userAccount
1500
- * @param {string} dappAccount
1501
- * @param {string} requestHash
1502
- * @param {JSON} captchas
1503
- * @param userTimestampSignature
1504
- * @param timestamp
1505
- * @param providerRequestHashSignature
1506
- * @param ipAddress
1507
- * @param headers
1508
- * @param ja4
1509
- * @return {Promise&lt;DappUserSolutionResult&gt;} result containing the contract event
1510
- */
1511
- <span class="cstat-no" title="statement not covered" > async dappUserSolution(</span>
1512
- <span class="cstat-no" title="statement not covered" > userAccount: string,</span>
1513
- <span class="cstat-no" title="statement not covered" > dappAccount: string,</span>
1514
- <span class="cstat-no" title="statement not covered" > requestHash: string,</span>
1515
- <span class="cstat-no" title="statement not covered" > captchas: CaptchaSolution[],</span>
1516
- <span class="cstat-no" title="statement not covered" > userTimestampSignature: string, // the signature to indicate ownership of account</span>
1517
- <span class="cstat-no" title="statement not covered" > timestamp: number,</span>
1518
- <span class="cstat-no" title="statement not covered" > providerRequestHashSignature: string,</span>
1519
- <span class="cstat-no" title="statement not covered" > ipAddress: IPAddress,</span>
1520
- <span class="cstat-no" title="statement not covered" > headers: RequestHeaders,</span>
1521
- <span class="cstat-no" title="statement not covered" > ja4: string,</span>
1522
- <span class="cstat-no" title="statement not covered" > ): Promise&lt;DappUserSolutionResult&gt; {</span>
1523
- // check that the signature is valid (i.e. the user has signed the request hash with their private key, proving they own their account)
1524
- <span class="cstat-no" title="statement not covered" > const verification = signatureVerify(</span>
1525
- <span class="cstat-no" title="statement not covered" > stringToHex(timestamp.toString()),</span>
1526
- <span class="cstat-no" title="statement not covered" > userTimestampSignature,</span>
1527
- <span class="cstat-no" title="statement not covered" > userAccount,</span>
1528
- <span class="cstat-no" title="statement not covered" > );</span>
1529
- <span class="cstat-no" title="statement not covered" > if (!verification.isValid) {</span>
1530
- // the signature is not valid, so the user is not the owner of the account. May have given a false account address with good reputation in an attempt to impersonate
1531
- <span class="cstat-no" title="statement not covered" > const err = new ProsopoEnvError("GENERAL.INVALID_SIGNATURE", {</span>
1532
- <span class="cstat-no" title="statement not covered" > context: { failedFuncName: this.dappUserSolution.name, userAccount },</span>
1533
- <span class="cstat-no" title="statement not covered" > });</span>
1534
- <span class="cstat-no" title="statement not covered" > this.logger.info(() =&gt; ({</span>
1535
- <span class="cstat-no" title="statement not covered" > err,</span>
1536
- <span class="cstat-no" title="statement not covered" > msg: "Invalid user timestamp signature",</span>
1537
- <span class="cstat-no" title="statement not covered" > }));</span>
1538
- <span class="cstat-no" title="statement not covered" > throw err;</span>
1539
- <span class="cstat-no" title="statement not covered" > }</span>
1540
- &nbsp;
1541
- // check that the requestHash signature is valid and signed by the provider
1542
- <span class="cstat-no" title="statement not covered" > const providerRequestHashSignatureVerify = signatureVerify(</span>
1543
- <span class="cstat-no" title="statement not covered" > stringToHex(requestHash.toString()),</span>
1544
- <span class="cstat-no" title="statement not covered" > providerRequestHashSignature,</span>
1545
- <span class="cstat-no" title="statement not covered" > this.pair.address,</span>
1546
- <span class="cstat-no" title="statement not covered" > );</span>
1547
- &nbsp;
1548
- <span class="cstat-no" title="statement not covered" > if (!providerRequestHashSignatureVerify.isValid) {</span>
1549
- // the signature is not valid, so the user is not the owner of the account. May have given a false account address with good reputation in an attempt to impersonate
1550
- <span class="cstat-no" title="statement not covered" > const err = new ProsopoEnvError("GENERAL.INVALID_SIGNATURE", {</span>
1551
- <span class="cstat-no" title="statement not covered" > context: {</span>
1552
- <span class="cstat-no" title="statement not covered" > failedFuncName: this.dappUserSolution.name,</span>
1553
- <span class="cstat-no" title="statement not covered" > userAccount,</span>
1554
- <span class="cstat-no" title="statement not covered" > error: "requestHash signature is invalid",</span>
1555
- <span class="cstat-no" title="statement not covered" > },</span>
1556
- <span class="cstat-no" title="statement not covered" > });</span>
1557
- <span class="cstat-no" title="statement not covered" > this.logger.info(() =&gt; ({</span>
1558
- <span class="cstat-no" title="statement not covered" > err,</span>
1559
- <span class="cstat-no" title="statement not covered" > msg: "Invalid provider requestHash signature",</span>
1560
- <span class="cstat-no" title="statement not covered" > }));</span>
1561
- <span class="cstat-no" title="statement not covered" > throw err;</span>
1562
- <span class="cstat-no" title="statement not covered" > }</span>
1563
- &nbsp;
1564
- <span class="cstat-no" title="statement not covered" > let response: DappUserSolutionResult = {</span>
1565
- <span class="cstat-no" title="statement not covered" > captchas: [],</span>
1566
- <span class="cstat-no" title="statement not covered" > verified: false,</span>
1567
- <span class="cstat-no" title="statement not covered" > };</span>
1568
- &nbsp;
1569
- <span class="cstat-no" title="statement not covered" > const pendingRecord = await this.db.getPendingImageCommitment(requestHash);</span>
1570
- &nbsp;
1571
- <span class="cstat-no" title="statement not covered" > const unverifiedCaptchaIds = captchas.map((captcha) =&gt; captcha.captchaId);</span>
1572
- <span class="cstat-no" title="statement not covered" > const pendingRequest = await this.validateDappUserSolutionRequestIsPending(</span>
1573
- <span class="cstat-no" title="statement not covered" > requestHash,</span>
1574
- <span class="cstat-no" title="statement not covered" > pendingRecord,</span>
1575
- <span class="cstat-no" title="statement not covered" > userAccount,</span>
1576
- <span class="cstat-no" title="statement not covered" > unverifiedCaptchaIds,</span>
1577
- <span class="cstat-no" title="statement not covered" > );</span>
1578
- <span class="cstat-no" title="statement not covered" > if (pendingRequest) {</span>
1579
- <span class="cstat-no" title="statement not covered" > const { storedCaptchas, receivedCaptchas, captchaIds } =</span>
1580
- <span class="cstat-no" title="statement not covered" > await this.validateReceivedCaptchasAgainstStoredCaptchas(captchas);</span>
1581
- &nbsp;
1582
- <span class="cstat-no" title="statement not covered" > const flat = receivedCaptchas.map((c) =&gt; extractData(c.salt));</span>
1583
- <span class="cstat-no" title="statement not covered" > const pairs = flat.map((list) =&gt; constructPairList(list));</span>
1584
- &nbsp;
1585
- <span class="cstat-no" title="statement not covered" > const { tree, commitmentId } =</span>
1586
- <span class="cstat-no" title="statement not covered" > buildTreeAndGetCommitmentId(receivedCaptchas);</span>
1587
- &nbsp;
1588
- <span class="cstat-no" title="statement not covered" > const datasetId = at(storedCaptchas, 0).datasetId;</span>
1589
- &nbsp;
1590
- <span class="cstat-no" title="statement not covered" > if (!datasetId) {</span>
1591
- <span class="cstat-no" title="statement not covered" > throw new ProsopoEnvError("CAPTCHA.ID_MISMATCH", {</span>
1592
- <span class="cstat-no" title="statement not covered" > context: { failedFuncName: this.dappUserSolution.name },</span>
1593
- <span class="cstat-no" title="statement not covered" > });</span>
1594
- <span class="cstat-no" title="statement not covered" > }</span>
1595
- &nbsp;
1596
- // Only do stuff if the request is in the local DB
1597
- // prevent this request hash from being used twice
1598
- <span class="cstat-no" title="statement not covered" > await this.db.updatePendingImageCommitmentStatus(requestHash);</span>
1599
- <span class="cstat-no" title="statement not covered" > const commit: UserCommitment = {</span>
1600
- <span class="cstat-no" title="statement not covered" > id: commitmentId,</span>
1601
- <span class="cstat-no" title="statement not covered" > userAccount: userAccount,</span>
1602
- <span class="cstat-no" title="statement not covered" > dappAccount,</span>
1603
- <span class="cstat-no" title="statement not covered" > providerAccount: this.pair.address,</span>
1604
- <span class="cstat-no" title="statement not covered" > datasetId,</span>
1605
- <span class="cstat-no" title="statement not covered" > result: { status: CaptchaStatus.pending },</span>
1606
- <span class="cstat-no" title="statement not covered" > userSignature: userTimestampSignature,</span>
1607
- <span class="cstat-no" title="statement not covered" > userSubmitted: true,</span>
1608
- <span class="cstat-no" title="statement not covered" > serverChecked: false,</span>
1609
- <span class="cstat-no" title="statement not covered" > requestedAtTimestamp: timestamp,</span>
1610
- <span class="cstat-no" title="statement not covered" > ipAddress: getCompositeIpAddress(ipAddress),</span>
1611
- <span class="cstat-no" title="statement not covered" > headers,</span>
1612
- <span class="cstat-no" title="statement not covered" > frictionlessTokenId: pendingRecord.frictionlessTokenId,</span>
1613
- <span class="cstat-no" title="statement not covered" > ja4,</span>
1614
- <span class="cstat-no" title="statement not covered" > };</span>
1615
- <span class="cstat-no" title="statement not covered" > await this.db.storeUserImageCaptchaSolution(receivedCaptchas, commit);</span>
1616
- &nbsp;
1617
- <span class="cstat-no" title="statement not covered" > const solutionRecords = await Promise.all(</span>
1618
- <span class="cstat-no" title="statement not covered" > storedCaptchas.map(async (captcha) =&gt; {</span>
1619
- <span class="cstat-no" title="statement not covered" > const solutionRecord = await this.db.getSolutionByCaptchaId(</span>
1620
- <span class="cstat-no" title="statement not covered" > captcha.captchaId,</span>
1621
- <span class="cstat-no" title="statement not covered" > );</span>
1622
- <span class="cstat-no" title="statement not covered" > if (!solutionRecord) {</span>
1623
- <span class="cstat-no" title="statement not covered" > throw new ProsopoEnvError("CAPTCHA.SOLUTION_NOT_FOUND", {</span>
1624
- <span class="cstat-no" title="statement not covered" > context: { failedFuncName: this.dappUserSolution.name },</span>
1625
- <span class="cstat-no" title="statement not covered" > });</span>
1626
- <span class="cstat-no" title="statement not covered" > }</span>
1627
- <span class="cstat-no" title="statement not covered" > return solutionRecord;</span>
1628
- <span class="cstat-no" title="statement not covered" > }),</span>
1629
- <span class="cstat-no" title="statement not covered" > );</span>
1630
- &nbsp;
1631
- <span class="cstat-no" title="statement not covered" > const totalImages = storedCaptchas[0]?.items.length || 0;</span>
1632
- &nbsp;
1633
- <span class="cstat-no" title="statement not covered" > if (containsIdenticalPairs(pairs)) {</span>
1634
- <span class="cstat-no" title="statement not covered" > await this.db.disapproveDappUserCommitment(</span>
1635
- <span class="cstat-no" title="statement not covered" > commitmentId,</span>
1636
- <span class="cstat-no" title="statement not covered" > "CAPTCHA.INVALID_SOLUTION",</span>
1637
- <span class="cstat-no" title="statement not covered" > pairs,</span>
1638
- <span class="cstat-no" title="statement not covered" > );</span>
1639
- <span class="cstat-no" title="statement not covered" > response = {</span>
1640
- <span class="cstat-no" title="statement not covered" > captchas: captchaIds.map((id) =&gt; ({</span>
1641
- <span class="cstat-no" title="statement not covered" > captchaId: id,</span>
1642
- <span class="cstat-no" title="statement not covered" > proof: [[]],</span>
1643
- <span class="cstat-no" title="statement not covered" > })),</span>
1644
- <span class="cstat-no" title="statement not covered" > verified: false,</span>
1645
- <span class="cstat-no" title="statement not covered" > };</span>
1646
- <span class="cstat-no" title="statement not covered" > return response;</span>
1647
- <span class="cstat-no" title="statement not covered" > }</span>
1648
- &nbsp;
1649
- <span class="cstat-no" title="statement not covered" > if (</span>
1650
- <span class="cstat-no" title="statement not covered" > compareCaptchaSolutions(</span>
1651
- <span class="cstat-no" title="statement not covered" > receivedCaptchas,</span>
1652
- <span class="cstat-no" title="statement not covered" > solutionRecords,</span>
1653
- <span class="cstat-no" title="statement not covered" > totalImages,</span>
1654
- <span class="cstat-no" title="statement not covered" > pendingRecord.threshold,</span>
1655
- <span class="cstat-no" title="statement not covered" > )</span>
1656
- <span class="cstat-no" title="statement not covered" > ) {</span>
1657
- <span class="cstat-no" title="statement not covered" > response = {</span>
1658
- <span class="cstat-no" title="statement not covered" > captchas: captchaIds.map((id) =&gt; ({</span>
1659
- <span class="cstat-no" title="statement not covered" > captchaId: id,</span>
1660
- <span class="cstat-no" title="statement not covered" > proof: tree.proof(id),</span>
1661
- <span class="cstat-no" title="statement not covered" > })),</span>
1662
- <span class="cstat-no" title="statement not covered" > verified: true,</span>
1663
- <span class="cstat-no" title="statement not covered" > };</span>
1664
- <span class="cstat-no" title="statement not covered" > await this.db.approveDappUserCommitment(commitmentId, pairs);</span>
1665
- <span class="cstat-no" title="statement not covered" > } else {</span>
1666
- <span class="cstat-no" title="statement not covered" > await this.db.disapproveDappUserCommitment(</span>
1667
- <span class="cstat-no" title="statement not covered" > commitmentId,</span>
1668
- <span class="cstat-no" title="statement not covered" > "CAPTCHA.INVALID_SOLUTION",</span>
1669
- <span class="cstat-no" title="statement not covered" > pairs,</span>
1670
- <span class="cstat-no" title="statement not covered" > );</span>
1671
- <span class="cstat-no" title="statement not covered" > response = {</span>
1672
- <span class="cstat-no" title="statement not covered" > captchas: captchaIds.map((id) =&gt; ({</span>
1673
- <span class="cstat-no" title="statement not covered" > captchaId: id,</span>
1674
- <span class="cstat-no" title="statement not covered" > proof: [[]],</span>
1675
- <span class="cstat-no" title="statement not covered" > })),</span>
1676
- <span class="cstat-no" title="statement not covered" > verified: false,</span>
1677
- <span class="cstat-no" title="statement not covered" > };</span>
1678
- <span class="cstat-no" title="statement not covered" > }</span>
1679
- <span class="cstat-no" title="statement not covered" > } else {</span>
1680
- <span class="cstat-no" title="statement not covered" > this.logger.info(() =&gt; ({</span>
1681
- <span class="cstat-no" title="statement not covered" > msg: "Request hash not found",</span>
1682
- <span class="cstat-no" title="statement not covered" > }));</span>
1683
- <span class="cstat-no" title="statement not covered" > }</span>
1684
- <span class="cstat-no" title="statement not covered" > return response;</span>
1685
- <span class="cstat-no" title="statement not covered" > }</span>
1686
- &nbsp;
1687
- /**
1688
- * Validate length of received captchas array matches length of captchas found in database
1689
- * Validate that the datasetId is the same for all captchas and is equal to the datasetId on the stored captchas
1690
- */
1691
- <span class="cstat-no" title="statement not covered" > async validateReceivedCaptchasAgainstStoredCaptchas(</span>
1692
- <span class="cstat-no" title="statement not covered" > captchas: CaptchaSolution[],</span>
1693
- ): Promise&lt;{
1694
- storedCaptchas: Captcha[];
1695
- receivedCaptchas: CaptchaSolution[];
1696
- captchaIds: string[];
1697
- <span class="cstat-no" title="statement not covered" > }&gt; {</span>
1698
- <span class="cstat-no" title="statement not covered" > const receivedCaptchas = parseAndSortCaptchaSolutions(captchas);</span>
1699
- <span class="cstat-no" title="statement not covered" > const captchaIds = receivedCaptchas.map((captcha) =&gt; captcha.captchaId);</span>
1700
- <span class="cstat-no" title="statement not covered" > const storedCaptchas = await this.db.getCaptchaById(captchaIds);</span>
1701
- <span class="cstat-no" title="statement not covered" > if (!storedCaptchas || receivedCaptchas.length !== storedCaptchas.length) {</span>
1702
- <span class="cstat-no" title="statement not covered" > throw new ProsopoEnvError("CAPTCHA.INVALID_CAPTCHA_ID", {</span>
1703
- <span class="cstat-no" title="statement not covered" > context: {</span>
1704
- <span class="cstat-no" title="statement not covered" > failedFuncName:</span>
1705
- <span class="cstat-no" title="statement not covered" > this.validateReceivedCaptchasAgainstStoredCaptchas.name,</span>
1706
- &nbsp;
1707
- <span class="cstat-no" title="statement not covered" > captchas,</span>
1708
- <span class="cstat-no" title="statement not covered" > },</span>
1709
- <span class="cstat-no" title="statement not covered" > });</span>
1710
- <span class="cstat-no" title="statement not covered" > }</span>
1711
- <span class="cstat-no" title="statement not covered" > if (</span>
1712
- <span class="cstat-no" title="statement not covered" > !storedCaptchas.every(</span>
1713
- <span class="cstat-no" title="statement not covered" > (captcha) =&gt; captcha.datasetId === at(storedCaptchas, 0).datasetId,</span>
1714
- <span class="cstat-no" title="statement not covered" > )</span>
1715
- <span class="cstat-no" title="statement not covered" > ) {</span>
1716
- <span class="cstat-no" title="statement not covered" > throw new ProsopoEnvError("CAPTCHA.DIFFERENT_DATASET_IDS", {</span>
1717
- <span class="cstat-no" title="statement not covered" > context: {</span>
1718
- <span class="cstat-no" title="statement not covered" > failedFuncName:</span>
1719
- <span class="cstat-no" title="statement not covered" > this.validateReceivedCaptchasAgainstStoredCaptchas.name,</span>
1720
- <span class="cstat-no" title="statement not covered" > captchas,</span>
1721
- <span class="cstat-no" title="statement not covered" > },</span>
1722
- <span class="cstat-no" title="statement not covered" > });</span>
1723
- <span class="cstat-no" title="statement not covered" > }</span>
1724
- <span class="cstat-no" title="statement not covered" > return { storedCaptchas, receivedCaptchas, captchaIds };</span>
1725
- <span class="cstat-no" title="statement not covered" > }</span>
1726
- &nbsp;
1727
- /**
1728
- * Validate that a Dapp User is responding to their own pending captcha request
1729
- * @param {string} requestHash
1730
- * @param {PendingCaptchaRequest} pendingRecord
1731
- * @param {string} userAccount
1732
- * @param {string[]} captchaIds
1733
- */
1734
- <span class="cstat-no" title="statement not covered" > async validateDappUserSolutionRequestIsPending(</span>
1735
- <span class="cstat-no" title="statement not covered" > requestHash: string,</span>
1736
- <span class="cstat-no" title="statement not covered" > pendingRecord: PendingCaptchaRequest,</span>
1737
- <span class="cstat-no" title="statement not covered" > userAccount: string,</span>
1738
- <span class="cstat-no" title="statement not covered" > captchaIds: string[],</span>
1739
- <span class="cstat-no" title="statement not covered" > ): Promise&lt;boolean&gt; {</span>
1740
- <span class="cstat-no" title="statement not covered" > const currentTime = Date.now();</span>
1741
- // only proceed if there is a pending record
1742
- <span class="cstat-no" title="statement not covered" > if (!pendingRecord) {</span>
1743
- <span class="cstat-no" title="statement not covered" > this.logger.info(() =&gt; ({</span>
1744
- <span class="cstat-no" title="statement not covered" > msg: "No pending record found",</span>
1745
- <span class="cstat-no" title="statement not covered" > }));</span>
1746
- <span class="cstat-no" title="statement not covered" > return false;</span>
1747
- <span class="cstat-no" title="statement not covered" > }</span>
1748
- &nbsp;
1749
- <span class="cstat-no" title="statement not covered" > if (pendingRecord.deadlineTimestamp &lt; currentTime) {</span>
1750
- // deadline for responding to the captcha has expired
1751
- <span class="cstat-no" title="statement not covered" > this.logger.info(() =&gt; ({</span>
1752
- <span class="cstat-no" title="statement not covered" > msg: "Deadline for responding to captcha has expired",</span>
1753
- <span class="cstat-no" title="statement not covered" > }));</span>
1754
- <span class="cstat-no" title="statement not covered" > return false;</span>
1755
- <span class="cstat-no" title="statement not covered" > }</span>
1756
- <span class="cstat-no" title="statement not covered" > if (pendingRecord) {</span>
1757
- <span class="cstat-no" title="statement not covered" > const pendingHashComputed = computePendingRequestHash(</span>
1758
- <span class="cstat-no" title="statement not covered" > captchaIds,</span>
1759
- <span class="cstat-no" title="statement not covered" > userAccount,</span>
1760
- <span class="cstat-no" title="statement not covered" > pendingRecord.salt,</span>
1761
- <span class="cstat-no" title="statement not covered" > );</span>
1762
- <span class="cstat-no" title="statement not covered" > return requestHash === pendingHashComputed;</span>
1763
- <span class="cstat-no" title="statement not covered" > }</span>
1764
- <span class="cstat-no" title="statement not covered" > return false;</span>
1765
- <span class="cstat-no" title="statement not covered" > }</span>
1766
- &nbsp;
1767
- /*
1768
- * Get dapp user solution from database
1769
- */
1770
- <span class="cstat-no" title="statement not covered" > async getDappUserCommitmentById(</span>
1771
- <span class="cstat-no" title="statement not covered" > commitmentId: string,</span>
1772
- <span class="cstat-no" title="statement not covered" > ): Promise&lt;UserCommitment&gt; {</span>
1773
- <span class="cstat-no" title="statement not covered" > const dappUserSolution =</span>
1774
- <span class="cstat-no" title="statement not covered" > await this.db.getDappUserCommitmentById(commitmentId);</span>
1775
- <span class="cstat-no" title="statement not covered" > if (!dappUserSolution) {</span>
1776
- <span class="cstat-no" title="statement not covered" > throw new ProsopoEnvError("CAPTCHA.DAPP_USER_SOLUTION_NOT_FOUND", {</span>
1777
- <span class="cstat-no" title="statement not covered" > context: {</span>
1778
- <span class="cstat-no" title="statement not covered" > failedFuncName: this.getDappUserCommitmentById.name,</span>
1779
- <span class="cstat-no" title="statement not covered" > commitmentId: commitmentId,</span>
1780
- <span class="cstat-no" title="statement not covered" > },</span>
1781
- <span class="cstat-no" title="statement not covered" > });</span>
1782
- <span class="cstat-no" title="statement not covered" > }</span>
1783
- <span class="cstat-no" title="statement not covered" > return dappUserSolution;</span>
1784
- <span class="cstat-no" title="statement not covered" > }</span>
1785
- &nbsp;
1786
- /* Check if dapp user has verified solution in cache */
1787
- <span class="cstat-no" title="statement not covered" > async getDappUserCommitmentByAccount(</span>
1788
- <span class="cstat-no" title="statement not covered" > userAccount: string,</span>
1789
- <span class="cstat-no" title="statement not covered" > dappAccount: string,</span>
1790
- <span class="cstat-no" title="statement not covered" > ): Promise&lt;UserCommitment | undefined&gt; {</span>
1791
- <span class="cstat-no" title="statement not covered" > const dappUserSolutions = await this.db.getDappUserCommitmentByAccount(</span>
1792
- <span class="cstat-no" title="statement not covered" > userAccount,</span>
1793
- <span class="cstat-no" title="statement not covered" > dappAccount,</span>
1794
- <span class="cstat-no" title="statement not covered" > );</span>
1795
- <span class="cstat-no" title="statement not covered" > if (dappUserSolutions.length &gt; 0) {</span>
1796
- <span class="cstat-no" title="statement not covered" > for (const dappUserSolution of dappUserSolutions) {</span>
1797
- <span class="cstat-no" title="statement not covered" > if (dappUserSolution.result.status === CaptchaStatus.approved) {</span>
1798
- <span class="cstat-no" title="statement not covered" > return dappUserSolution;</span>
1799
- <span class="cstat-no" title="statement not covered" > }</span>
1800
- <span class="cstat-no" title="statement not covered" > }</span>
1801
- <span class="cstat-no" title="statement not covered" > }</span>
1802
- <span class="cstat-no" title="statement not covered" > return undefined;</span>
1803
- <span class="cstat-no" title="statement not covered" > }</span>
1804
- &nbsp;
1805
- <span class="cstat-no" title="statement not covered" > async verifyImageCaptchaSolution(</span>
1806
- <span class="cstat-no" title="statement not covered" > user: string,</span>
1807
- <span class="cstat-no" title="statement not covered" > dapp: string,</span>
1808
- <span class="cstat-no" title="statement not covered" > commitmentId: string | undefined,</span>
1809
- <span class="cstat-no" title="statement not covered" > env: ProviderEnvironment,</span>
1810
- <span class="cstat-no" title="statement not covered" > maxVerifiedTime?: number,</span>
1811
- <span class="cstat-no" title="statement not covered" > ip?: string,</span>
1812
- <span class="cstat-no" title="statement not covered" > disallowWebView?: boolean,</span>
1813
- <span class="cstat-no" title="statement not covered" > ): Promise&lt;ImageVerificationResponse&gt; {</span>
1814
- <span class="cstat-no" title="statement not covered" > const solution = await (commitmentId</span>
1815
- <span class="cstat-no" title="statement not covered" > ? this.getDappUserCommitmentById(commitmentId)</span>
1816
- <span class="cstat-no" title="statement not covered" > : this.getDappUserCommitmentByAccount(user, dapp));</span>
1817
- &nbsp;
1818
- // No solution exists
1819
- <span class="cstat-no" title="statement not covered" > if (!solution) {</span>
1820
- <span class="cstat-no" title="statement not covered" > this.logger.debug(() =&gt; ({</span>
1821
- <span class="cstat-no" title="statement not covered" > msg: "Not verified - no solution found",</span>
1822
- <span class="cstat-no" title="statement not covered" > }));</span>
1823
- <span class="cstat-no" title="statement not covered" > return { status: "API.USER_NOT_VERIFIED_NO_SOLUTION", verified: false };</span>
1824
- <span class="cstat-no" title="statement not covered" > }</span>
1825
- &nbsp;
1826
- // -- WARNING ---- WARNING ---- WARNING ---- WARNING ---- WARNING ---- WARNING ---- WARNING ---- WARNING --
1827
- // Do not move this code down or put any other code before it. We want to drop out as early as possible if the
1828
- // solution has already been checked by the server. Moving this code around could result in solutions being
1829
- // re-usable.
1830
- <span class="cstat-no" title="statement not covered" > if (solution.serverChecked) {</span>
1831
- <span class="cstat-no" title="statement not covered" > return { status: "API.USER_ALREADY_VERIFIED", verified: false };</span>
1832
- <span class="cstat-no" title="statement not covered" > }</span>
1833
- &nbsp;
1834
- <span class="cstat-no" title="statement not covered" > await this.db.markDappUserCommitmentsChecked([solution.id]);</span>
1835
- // -- END WARNING --
1836
- &nbsp;
1837
- // A solution exists but is disapproved
1838
- <span class="cstat-no" title="statement not covered" > if (solution.result.status === CaptchaStatus.disapproved) {</span>
1839
- <span class="cstat-no" title="statement not covered" > return { status: "API.USER_NOT_VERIFIED", verified: false };</span>
1840
- <span class="cstat-no" title="statement not covered" > }</span>
1841
- &nbsp;
1842
- <span class="cstat-no" title="statement not covered" > maxVerifiedTime = maxVerifiedTime || 60 * 1000; // Default to 1 minute</span>
1843
- &nbsp;
1844
- // Check if solution was completed recently
1845
- <span class="cstat-no" title="statement not covered" > const currentTime = Date.now();</span>
1846
- <span class="cstat-no" title="statement not covered" > const timeSinceCompletion = currentTime - solution.requestedAtTimestamp;</span>
1847
- &nbsp;
1848
- // A solution exists but has timed out
1849
- <span class="cstat-no" title="statement not covered" > if (timeSinceCompletion &gt; maxVerifiedTime) {</span>
1850
- <span class="cstat-no" title="statement not covered" > this.logger.debug(() =&gt; ({</span>
1851
- <span class="cstat-no" title="statement not covered" > msg: "Not verified - timed out",</span>
1852
- <span class="cstat-no" title="statement not covered" > }));</span>
1853
- <span class="cstat-no" title="statement not covered" > return {</span>
1854
- <span class="cstat-no" title="statement not covered" > status: "API.USER_NOT_VERIFIED_TIME_EXPIRED",</span>
1855
- <span class="cstat-no" title="statement not covered" > verified: false,</span>
1856
- <span class="cstat-no" title="statement not covered" > };</span>
1857
- <span class="cstat-no" title="statement not covered" > }</span>
1858
- &nbsp;
1859
- <span class="cstat-no" title="statement not covered" > if (ip) {</span>
1860
- <span class="cstat-no" title="statement not covered" > const solutionIpAddress = getIpAddressFromComposite(solution.ipAddress);</span>
1861
- // Get client settings for IP validation rules
1862
- <span class="cstat-no" title="statement not covered" > const clientRecord = await this.db.getClientRecord(dapp);</span>
1863
- &nbsp;
1864
- <span class="cstat-no" title="statement not covered" > const ipValidationRules = clientRecord?.settings?.ipValidationRules;</span>
1865
- &nbsp;
1866
- <span class="cstat-no" title="statement not covered" > await this.db.updateDappUserCommitment(solution.id, {</span>
1867
- <span class="cstat-no" title="statement not covered" > providedIp: getCompositeIpAddress(ip),</span>
1868
- <span class="cstat-no" title="statement not covered" > });</span>
1869
- &nbsp;
1870
- <span class="cstat-no" title="statement not covered" > const ipValidation = await deepValidateIpAddress(</span>
1871
- <span class="cstat-no" title="statement not covered" > ip,</span>
1872
- <span class="cstat-no" title="statement not covered" > solutionIpAddress,</span>
1873
- <span class="cstat-no" title="statement not covered" > this.logger,</span>
1874
- <span class="cstat-no" title="statement not covered" > env.config.ipApi.apiKey,</span>
1875
- <span class="cstat-no" title="statement not covered" > env.config.ipApi.baseUrl,</span>
1876
- <span class="cstat-no" title="statement not covered" > ipValidationRules,</span>
1877
- <span class="cstat-no" title="statement not covered" > );</span>
1878
- &nbsp;
1879
- <span class="cstat-no" title="statement not covered" > if (!ipValidation.isValid) {</span>
1880
- <span class="cstat-no" title="statement not covered" > this.logger.error(() =&gt; ({</span>
1881
- <span class="cstat-no" title="statement not covered" > msg: "IP validation failed for image captcha",</span>
1882
- <span class="cstat-no" title="statement not covered" > data: {</span>
1883
- <span class="cstat-no" title="statement not covered" > ip,</span>
1884
- <span class="cstat-no" title="statement not covered" > solutionIp: solutionIpAddress.address,</span>
1885
- <span class="cstat-no" title="statement not covered" > error: ipValidation.errorMessage,</span>
1886
- <span class="cstat-no" title="statement not covered" > distanceKm: ipValidation.distanceKm,</span>
1887
- <span class="cstat-no" title="statement not covered" > },</span>
1888
- <span class="cstat-no" title="statement not covered" > }));</span>
1889
- <span class="cstat-no" title="statement not covered" > return { status: "API.USER_NOT_VERIFIED", verified: false };</span>
1890
- <span class="cstat-no" title="statement not covered" > }</span>
1891
- <span class="cstat-no" title="statement not covered" > }</span>
1892
- &nbsp;
1893
- <span class="cstat-no" title="statement not covered" > const isApproved = solution.result.status === CaptchaStatus.approved;</span>
1894
- &nbsp;
1895
- <span class="cstat-no" title="statement not covered" > let score: number | undefined;</span>
1896
- <span class="cstat-no" title="statement not covered" > if (solution.frictionlessTokenId) {</span>
1897
- <span class="cstat-no" title="statement not covered" > const tokenRecord = await this.db.getFrictionlessTokenRecordByTokenId(</span>
1898
- <span class="cstat-no" title="statement not covered" > solution.frictionlessTokenId,</span>
1899
- <span class="cstat-no" title="statement not covered" > );</span>
1900
- <span class="cstat-no" title="statement not covered" > if (tokenRecord) {</span>
1901
- <span class="cstat-no" title="statement not covered" > score = computeFrictionlessScore(tokenRecord?.scoreComponents);</span>
1902
- <span class="cstat-no" title="statement not covered" > this.logger.info(() =&gt; ({</span>
1903
- <span class="cstat-no" title="statement not covered" > data: {</span>
1904
- <span class="cstat-no" title="statement not covered" > tscoreComponents: tokenRecord?.scoreComponents,</span>
1905
- <span class="cstat-no" title="statement not covered" > score: score,</span>
1906
- <span class="cstat-no" title="statement not covered" > },</span>
1907
- <span class="cstat-no" title="statement not covered" > }));</span>
1908
- &nbsp;
1909
- <span class="cstat-no" title="statement not covered" > if (</span>
1910
- <span class="cstat-no" title="statement not covered" > disallowWebView === true &amp;&amp;</span>
1911
- <span class="cstat-no" title="statement not covered" > (tokenRecord.scoreComponents.webView || 0) &gt; 0</span>
1912
- <span class="cstat-no" title="statement not covered" > ) {</span>
1913
- <span class="cstat-no" title="statement not covered" > this.logger.info(() =&gt; ({</span>
1914
- <span class="cstat-no" title="statement not covered" > msg: "Disallowing webview access - user not verified",</span>
1915
- <span class="cstat-no" title="statement not covered" > }));</span>
1916
- <span class="cstat-no" title="statement not covered" > return { status: "API.USER_NOT_VERIFIED", verified: false };</span>
1917
- <span class="cstat-no" title="statement not covered" > }</span>
1918
- <span class="cstat-no" title="statement not covered" > }</span>
1919
- <span class="cstat-no" title="statement not covered" > }</span>
1920
- &nbsp;
1921
- <span class="cstat-no" title="statement not covered" > return {</span>
1922
- <span class="cstat-no" title="statement not covered" > status: isApproved ? "API.USER_VERIFIED" : "API.USER_NOT_VERIFIED",</span>
1923
- <span class="cstat-no" title="statement not covered" > verified: isApproved,</span>
1924
- <span class="cstat-no" title="statement not covered" > commitmentId: solution.id.toString(),</span>
1925
- <span class="cstat-no" title="statement not covered" > ...(score &amp;&amp; { score }),</span>
1926
- <span class="cstat-no" title="statement not covered" > };</span>
1927
- <span class="cstat-no" title="statement not covered" > }</span>
1928
- &nbsp;
1929
- <span class="cstat-no" title="statement not covered" > checkLangRules(acceptLanguage: string): number {</span>
1930
- <span class="cstat-no" title="statement not covered" > return checkLangRules(this.config, acceptLanguage);</span>
1931
- <span class="cstat-no" title="statement not covered" > }</span>
1932
- &nbsp;
1933
- <span class="cstat-no" title="statement not covered" > override getVerificationResponse(</span>
1934
- <span class="cstat-no" title="statement not covered" > verified: boolean,</span>
1935
- <span class="cstat-no" title="statement not covered" > clientRecord: ClientRecord,</span>
1936
- <span class="cstat-no" title="statement not covered" > translateFn: (key: string) =&gt; string,</span>
1937
- <span class="cstat-no" title="statement not covered" > score?: number,</span>
1938
- <span class="cstat-no" title="statement not covered" > commitmentId?: Hash,</span>
1939
- <span class="cstat-no" title="statement not covered" > ): ImageVerificationResponse {</span>
1940
- <span class="cstat-no" title="statement not covered" > return {</span>
1941
- <span class="cstat-no" title="statement not covered" > ...super.getVerificationResponse(</span>
1942
- <span class="cstat-no" title="statement not covered" > verified,</span>
1943
- <span class="cstat-no" title="statement not covered" > clientRecord,</span>
1944
- <span class="cstat-no" title="statement not covered" > translateFn,</span>
1945
- <span class="cstat-no" title="statement not covered" > score,</span>
1946
- <span class="cstat-no" title="statement not covered" > ),</span>
1947
- <span class="cstat-no" title="statement not covered" > ...(commitmentId &amp;&amp; {</span>
1948
- <span class="cstat-no" title="statement not covered" > [ApiParams.commitmentId]: commitmentId,</span>
1949
- <span class="cstat-no" title="statement not covered" > }),</span>
1950
- <span class="cstat-no" title="statement not covered" > };</span>
1951
- <span class="cstat-no" title="statement not covered" > }</span>
1952
- <span class="cstat-no" title="statement not covered" >}</span>
1953
- &nbsp;</pre></td></tr></table></pre>
1954
-
1955
- <div class='push'></div><!-- for sticky footer -->
1956
- </div><!-- /wrapper -->
1957
- <div class='footer quiet pad2 space-top1 center small'>
1958
- Code coverage generated by
1959
- <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1960
- at 2025-10-22T12:32:26.285Z
1961
- </div>
1962
- <script src="../../../prettify.js"></script>
1963
- <script>
1964
- window.onload = function () {
1965
- prettyPrint();
1966
- };
1967
- </script>
1968
- <script src="../../../sorter.js"></script>
1969
- <script src="../../../block-navigation.js"></script>
1970
- </body>
1971
- </html>
1972
-