@prosopo/provider 3.12.3 → 3.12.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +173 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +4278 -0
- package/coverage/coverage-final.json +42 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +311 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/api/admin/apiAdminRoutesProvider.ts.html +214 -0
- package/coverage/src/api/admin/apiRegisterSiteKeyEndpoint.ts.html +259 -0
- package/coverage/src/api/admin/apiRemoveDetectorKeyEndpoint.ts.html +283 -0
- package/coverage/src/api/admin/apiToggleMaintenanceModeEndpoint.ts.html +334 -0
- package/coverage/src/api/admin/apiUpdateDetectorKeyEndpoint.ts.html +298 -0
- package/coverage/src/api/admin/createApiAdminRoutesProvider.ts.html +163 -0
- package/coverage/src/api/admin/index.html +191 -0
- package/coverage/src/api/blacklistRequestInspector.ts.html +751 -0
- package/coverage/src/api/block.ts.html +187 -0
- package/coverage/src/api/captcha.ts.html +2803 -0
- package/coverage/src/api/domainMiddleware.ts.html +493 -0
- package/coverage/src/api/headerCheckMiddleware.ts.html +256 -0
- package/coverage/src/api/ignoreMiddleware.ts.html +181 -0
- package/coverage/src/api/index.html +266 -0
- package/coverage/src/api/ja4Middleware.ts.html +400 -0
- package/coverage/src/api/public.ts.html +343 -0
- package/coverage/src/api/robotsMiddleware.ts.html +157 -0
- package/coverage/src/api/validateAddress.ts.html +214 -0
- package/coverage/src/api/verify.ts.html +871 -0
- package/coverage/src/compositeIpAddress.ts.html +340 -0
- package/coverage/src/index.html +161 -0
- package/coverage/src/index.ts.html +175 -0
- package/coverage/src/pairs.ts.html +238 -0
- package/coverage/src/rules/index.html +116 -0
- package/coverage/src/rules/lang.ts.html +187 -0
- package/coverage/src/schedulers/captchaScheduler.ts.html +250 -0
- package/coverage/src/schedulers/getClientList.ts.html +271 -0
- package/coverage/src/schedulers/index.html +131 -0
- package/coverage/src/services/index.html +131 -0
- package/coverage/src/services/ipComparison.ts.html +685 -0
- package/coverage/src/services/ipInfo.ts.html +490 -0
- package/coverage/src/tasks/captchaManager.ts.html +865 -0
- package/coverage/src/tasks/client/clientTasks.ts.html +1381 -0
- package/coverage/src/tasks/client/index.html +116 -0
- package/coverage/src/tasks/dataset/datasetTasks.ts.html +268 -0
- package/coverage/src/tasks/dataset/datasetTasksUtils.ts.html +271 -0
- package/coverage/src/tasks/dataset/index.html +131 -0
- package/coverage/src/tasks/detection/decodePayload.js.html +127 -0
- package/coverage/src/tasks/detection/getBotScore.ts.html +244 -0
- package/coverage/src/tasks/detection/index.html +131 -0
- package/coverage/src/tasks/frictionless/frictionlessTasks.ts.html +1216 -0
- package/coverage/src/tasks/frictionless/frictionlessTasksUtils.ts.html +247 -0
- package/coverage/src/tasks/frictionless/index.html +131 -0
- package/coverage/src/tasks/imgCaptcha/imgCaptchaTasks.ts.html +1972 -0
- package/coverage/src/tasks/imgCaptcha/imgCaptchaTasksUtils.ts.html +232 -0
- package/coverage/src/tasks/imgCaptcha/index.html +131 -0
- package/coverage/src/tasks/index.html +146 -0
- package/coverage/src/tasks/index.ts.html +127 -0
- package/coverage/src/tasks/powCaptcha/index.html +131 -0
- package/coverage/src/tasks/powCaptcha/powTasks.ts.html +961 -0
- package/coverage/src/tasks/powCaptcha/powTasksUtils.ts.html +244 -0
- package/coverage/src/tasks/tasks.ts.html +388 -0
- package/coverage/src/util.ts.html +1627 -0
- package/coverage/src/utils/hashUserAgent.ts.html +184 -0
- package/coverage/src/utils/index.html +116 -0
- package/dist/api/admin/apiAdminRoutesProvider.d.ts +9 -0
- package/dist/api/admin/apiAdminRoutesProvider.d.ts.map +1 -0
- package/dist/api/admin/apiAdminRoutesProvider.js +13 -18
- package/dist/api/admin/apiAdminRoutesProvider.js.map +1 -0
- package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts +14 -0
- package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts.map +1 -0
- package/dist/api/admin/apiRegisterSiteKeyEndpoint.js.map +1 -0
- package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts +23 -0
- package/dist/api/admin/apiRemoveDetectorKeyEndpoint.d.ts.map +1 -0
- package/dist/api/admin/apiRemoveDetectorKeyEndpoint.js.map +1 -0
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts +13 -0
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.d.ts.map +1 -0
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js +40 -0
- package/dist/api/admin/apiToggleMaintenanceModeEndpoint.js.map +1 -0
- package/dist/api/admin/apiUpdateDetectorKeyEndpoint.d.ts +14 -0
- package/dist/api/admin/apiUpdateDetectorKeyEndpoint.d.ts.map +1 -0
- package/dist/api/admin/apiUpdateDetectorKeyEndpoint.js.map +1 -0
- package/dist/api/admin/createApiAdminRoutesProvider.d.ts +4 -0
- package/dist/api/admin/createApiAdminRoutesProvider.d.ts.map +1 -0
- package/dist/api/admin/createApiAdminRoutesProvider.js.map +1 -0
- package/dist/api/blacklistRequestInspector.d.ts +19 -0
- package/dist/api/blacklistRequestInspector.d.ts.map +1 -0
- package/dist/api/blacklistRequestInspector.js +4 -4
- package/dist/api/blacklistRequestInspector.js.map +1 -0
- package/dist/api/block.d.ts +3 -0
- package/dist/api/block.d.ts.map +1 -0
- package/dist/api/block.js.map +1 -0
- package/dist/api/captcha.d.ts +4 -0
- package/dist/api/captcha.d.ts.map +1 -0
- package/dist/api/captcha.js +130 -40
- package/dist/api/captcha.js.map +1 -0
- package/dist/api/domainMiddleware.d.ts +4 -0
- package/dist/api/domainMiddleware.d.ts.map +1 -0
- package/dist/api/domainMiddleware.js.map +1 -0
- package/dist/api/headerCheckMiddleware.d.ts +4 -0
- package/dist/api/headerCheckMiddleware.d.ts.map +1 -0
- package/dist/api/headerCheckMiddleware.js.map +1 -0
- package/dist/api/ignoreMiddleware.d.ts +3 -0
- package/dist/api/ignoreMiddleware.d.ts.map +1 -0
- package/dist/api/ignoreMiddleware.js.map +1 -0
- package/dist/api/ja4Middleware.d.ts +10 -0
- package/dist/api/ja4Middleware.d.ts.map +1 -0
- package/dist/api/ja4Middleware.js.map +1 -0
- package/dist/api/public.d.ts +4 -0
- package/dist/api/public.d.ts.map +1 -0
- package/dist/api/public.js.map +1 -0
- package/dist/api/robotsMiddleware.d.ts +3 -0
- package/dist/api/robotsMiddleware.d.ts.map +1 -0
- package/dist/api/robotsMiddleware.js.map +1 -0
- package/dist/api/validateAddress.d.ts +5 -0
- package/dist/api/validateAddress.d.ts.map +1 -0
- package/dist/api/validateAddress.js.map +1 -0
- package/dist/api/verify.d.ts +4 -0
- package/dist/api/verify.d.ts.map +1 -0
- package/dist/api/verify.js +23 -1
- package/dist/api/verify.js.map +1 -0
- package/dist/cjs/api/admin/apiAdminRoutesProvider.cjs +13 -18
- package/dist/cjs/api/admin/apiRegisterSiteKeyEndpoint.cjs +2 -1
- package/dist/cjs/api/admin/apiRemoveDetectorKeyEndpoint.cjs +3 -2
- package/dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs +41 -0
- package/dist/cjs/api/blacklistRequestInspector.cjs +3 -3
- package/dist/cjs/api/captcha.cjs +130 -40
- package/dist/cjs/api/ja4Middleware.cjs +2 -1
- package/dist/cjs/api/verify.cjs +23 -1
- package/dist/cjs/tasks/captchaManager.cjs +5 -21
- package/dist/cjs/tasks/client/clientTasks.cjs +3 -36
- package/dist/cjs/tasks/detection/decodePayload.cjs +570 -669
- package/dist/cjs/tasks/detection/getBotScore.cjs +15 -2
- package/dist/cjs/tasks/frictionless/frictionlessTasks.cjs +116 -29
- package/dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs +18 -12
- package/dist/cjs/tasks/powCaptcha/powTasks.cjs +6 -6
- package/dist/cjs/util.cjs +14 -1
- package/dist/compositeIpAddress.d.ts +5 -0
- package/dist/compositeIpAddress.d.ts.map +1 -0
- package/dist/compositeIpAddress.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/pairs.d.ts +3 -0
- package/dist/pairs.d.ts.map +1 -0
- package/dist/pairs.js.map +1 -0
- package/dist/rules/lang.d.ts +3 -0
- package/dist/rules/lang.d.ts.map +1 -0
- package/dist/rules/lang.js.map +1 -0
- package/dist/schedulers/captchaScheduler.d.ts +4 -0
- package/dist/schedulers/captchaScheduler.d.ts.map +1 -0
- package/dist/schedulers/captchaScheduler.js.map +1 -0
- package/dist/schedulers/getClientList.d.ts +4 -0
- package/dist/schedulers/getClientList.d.ts.map +1 -0
- package/dist/schedulers/getClientList.js.map +1 -0
- package/dist/schedulers/setClientEntropy.d.ts +4 -0
- package/dist/schedulers/setClientEntropy.d.ts.map +1 -0
- package/dist/schedulers/setClientEntropy.js +31 -0
- package/dist/schedulers/setClientEntropy.js.map +1 -0
- package/dist/services/ipComparison.d.ts +3 -0
- package/dist/services/ipComparison.d.ts.map +1 -0
- package/dist/services/ipComparison.js.map +1 -0
- package/dist/services/ipInfo.d.ts +3 -0
- package/dist/services/ipInfo.d.ts.map +1 -0
- package/dist/services/ipInfo.js.map +1 -0
- package/dist/tasks/captchaManager.d.ts +34 -0
- package/dist/tasks/captchaManager.d.ts.map +1 -0
- package/dist/tasks/captchaManager.js +3 -20
- package/dist/tasks/captchaManager.js.map +1 -0
- package/dist/tasks/client/clientTasks.d.ts +21 -0
- package/dist/tasks/client/clientTasks.d.ts.map +1 -0
- package/dist/tasks/client/clientTasks.js +3 -36
- package/dist/tasks/client/clientTasks.js.map +1 -0
- package/dist/tasks/dataset/datasetTasks.d.ts +13 -0
- package/dist/tasks/dataset/datasetTasks.d.ts.map +1 -0
- package/dist/tasks/dataset/datasetTasks.js.map +1 -0
- package/dist/tasks/dataset/datasetTasksUtils.d.ts +3 -0
- package/dist/tasks/dataset/datasetTasksUtils.d.ts.map +1 -0
- package/dist/tasks/dataset/datasetTasksUtils.js.map +1 -0
- package/dist/tasks/detection/decodePayload.d.ts +5 -0
- package/dist/tasks/detection/decodePayload.d.ts.map +1 -0
- package/dist/tasks/detection/decodePayload.js +570 -669
- package/dist/tasks/detection/decodePayload.js.map +1 -0
- package/dist/tasks/detection/getBotScore.d.ts +20 -0
- package/dist/tasks/detection/getBotScore.d.ts.map +1 -0
- package/dist/tasks/detection/getBotScore.js +17 -4
- package/dist/tasks/detection/getBotScore.js.map +1 -0
- package/dist/tasks/frictionless/frictionlessTasks.d.ts +67 -0
- package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -0
- package/dist/tasks/frictionless/frictionlessTasks.js +116 -29
- package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -0
- package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts +6 -0
- package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts.map +1 -0
- package/dist/tasks/frictionless/frictionlessTasksUtils.js.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +30 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +18 -12
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +7 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +1 -0
- package/dist/tasks/index.d.ts +2 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js.map +1 -0
- package/dist/tasks/powCaptcha/powTasks.d.ts +17 -0
- package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -0
- package/dist/tasks/powCaptcha/powTasks.js +6 -6
- package/dist/tasks/powCaptcha/powTasks.js.map +1 -0
- package/dist/tasks/powCaptcha/powTasksUtils.d.ts +3 -0
- package/dist/tasks/powCaptcha/powTasksUtils.d.ts.map +1 -0
- package/dist/tasks/powCaptcha/powTasksUtils.js.map +1 -0
- package/dist/tasks/tasks.d.ts +25 -0
- package/dist/tasks/tasks.d.ts.map +1 -0
- package/dist/tasks/tasks.js.map +1 -0
- package/dist/tests/index.d.ts +2 -0
- package/dist/tests/index.d.ts.map +1 -0
- package/dist/tests/index.js +2 -0
- package/dist/tests/index.js.map +1 -0
- package/dist/tests/integration/accessRules.integration.test.d.ts +2 -0
- package/dist/tests/integration/accessRules.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/accessRules.integration.test.js +588 -0
- package/dist/tests/integration/accessRules.integration.test.js.map +1 -0
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.d.ts +2 -0
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js +60 -0
- package/dist/tests/integration/api/admin/apiRegisterSiteKeyEndpoint.integration.test.js.map +1 -0
- package/dist/tests/integration/api/blacklistRequestInspector.integration.test.d.ts +2 -0
- package/dist/tests/integration/api/blacklistRequestInspector.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js +368 -0
- package/dist/tests/integration/api/blacklistRequestInspector.integration.test.js.map +1 -0
- package/dist/tests/integration/imgCaptcha.integration.test.d.ts +2 -0
- package/dist/tests/integration/imgCaptcha.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/imgCaptcha.integration.test.js +272 -0
- package/dist/tests/integration/imgCaptcha.integration.test.js.map +1 -0
- package/dist/tests/integration/ipValidation.integration.test.d.ts +2 -0
- package/dist/tests/integration/ipValidation.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/ipValidation.integration.test.js +75 -0
- package/dist/tests/integration/ipValidation.integration.test.js.map +1 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts +32 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.d.ts.map +1 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.js +1046 -0
- package/dist/tests/integration/mocks/solvedTestCaptchas.js.map +1 -0
- package/dist/tests/integration/powCaptcha.integration.test.d.ts +2 -0
- package/dist/tests/integration/powCaptcha.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/powCaptcha.integration.test.js +308 -0
- package/dist/tests/integration/powCaptcha.integration.test.js.map +1 -0
- package/dist/tests/integration/registerSitekey.d.ts +3 -0
- package/dist/tests/integration/registerSitekey.d.ts.map +1 -0
- package/dist/tests/integration/registerSitekey.js +24 -0
- package/dist/tests/integration/registerSitekey.js.map +1 -0
- package/dist/tests/integration/userAccessPolicy.d.ts +2 -0
- package/dist/tests/integration/userAccessPolicy.d.ts.map +1 -0
- package/dist/tests/integration/userAccessPolicy.js +2 -0
- package/dist/tests/integration/userAccessPolicy.js.map +1 -0
- package/dist/tests/unit/api/blacklistRequestInspector.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/blacklistRequestInspector.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js +60 -0
- package/dist/tests/unit/api/blacklistRequestInspector.unit.test.js.map +1 -0
- package/dist/tests/unit/api/ignoreMiddleware.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/ignoreMiddleware.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/ignoreMiddleware.unit.test.js +43 -0
- package/dist/tests/unit/api/ignoreMiddleware.unit.test.js.map +1 -0
- package/dist/tests/unit/api/ja4Middleware.unit.test.d.ts +2 -0
- package/dist/tests/unit/api/ja4Middleware.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/api/ja4Middleware.unit.test.js +57 -0
- package/dist/tests/unit/api/ja4Middleware.unit.test.js.map +1 -0
- package/dist/tests/unit/compositeIpAddress.unit.test.d.ts +2 -0
- package/dist/tests/unit/compositeIpAddress.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/compositeIpAddress.unit.test.js +86 -0
- package/dist/tests/unit/compositeIpAddress.unit.test.js.map +1 -0
- package/dist/tests/unit/pairs.unit.test.d.ts +2 -0
- package/dist/tests/unit/pairs.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/pairs.unit.test.js +83 -0
- package/dist/tests/unit/pairs.unit.test.js.map +1 -0
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts +2 -0
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js +75 -0
- package/dist/tests/unit/schedulers/captchaScheduler.unit.test.js.map +1 -0
- package/dist/tests/unit/services/ipComparison.unit.test.d.ts +2 -0
- package/dist/tests/unit/services/ipComparison.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/services/ipComparison.unit.test.js +258 -0
- package/dist/tests/unit/services/ipComparison.unit.test.js.map +1 -0
- package/dist/tests/unit/services/ipInfo.unit.test.d.ts +2 -0
- package/dist/tests/unit/services/ipInfo.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/services/ipInfo.unit.test.js +210 -0
- package/dist/tests/unit/services/ipInfo.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.js +311 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js +289 -0
- package/dist/tests/unit/tasks/client/clientTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js +92 -0
- package/dist/tests/unit/tasks/dataset/datasetTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js +75 -0
- package/dist/tests/unit/tasks/dataset/datasetTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js +143 -0
- package/dist/tests/unit/tasks/frictionless/decryptPayload.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +145 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js +64 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +388 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +46 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +216 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js +69 -0
- package/dist/tests/unit/tasks/powCaptcha/powTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.d.ts +2 -0
- package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.js +505 -0
- package/dist/tests/unit/util.evaluateIpValidationRules.unit.test.js.map +1 -0
- package/dist/tests/unit/util.ipDistance.unit.test.d.ts +2 -0
- package/dist/tests/unit/util.ipDistance.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/util.ipDistance.unit.test.js +93 -0
- package/dist/tests/unit/util.ipDistance.unit.test.js.map +1 -0
- package/dist/tests/unit/util.unit.test.d.ts +2 -0
- package/dist/tests/unit/util.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/util.unit.test.js +170 -0
- package/dist/tests/unit/util.unit.test.js.map +1 -0
- package/dist/util.d.ts +24 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +14 -1
- package/dist/util.js.map +1 -0
- package/dist/utils/hashUserAgent.d.ts +2 -0
- package/dist/utils/hashUserAgent.d.ts.map +1 -0
- package/dist/utils/hashUserAgent.js.map +1 -0
- package/package.json +24 -25
|
@@ -0,0 +1,1972 @@
|
|
|
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"> </span>
|
|
696
|
+
<span class="cline-any cline-neutral"> </span>
|
|
697
|
+
<span class="cline-any cline-neutral"> </span>
|
|
698
|
+
<span class="cline-any cline-neutral"> </span>
|
|
699
|
+
<span class="cline-any cline-neutral"> </span>
|
|
700
|
+
<span class="cline-any cline-neutral"> </span>
|
|
701
|
+
<span class="cline-any cline-neutral"> </span>
|
|
702
|
+
<span class="cline-any cline-neutral"> </span>
|
|
703
|
+
<span class="cline-any cline-neutral"> </span>
|
|
704
|
+
<span class="cline-any cline-neutral"> </span>
|
|
705
|
+
<span class="cline-any cline-neutral"> </span>
|
|
706
|
+
<span class="cline-any cline-neutral"> </span>
|
|
707
|
+
<span class="cline-any cline-neutral"> </span>
|
|
708
|
+
<span class="cline-any cline-neutral"> </span>
|
|
709
|
+
<span class="cline-any cline-no"> </span>
|
|
710
|
+
<span class="cline-any cline-no"> </span>
|
|
711
|
+
<span class="cline-any cline-no"> </span>
|
|
712
|
+
<span class="cline-any cline-neutral"> </span>
|
|
713
|
+
<span class="cline-any cline-neutral"> </span>
|
|
714
|
+
<span class="cline-any cline-neutral"> </span>
|
|
715
|
+
<span class="cline-any cline-neutral"> </span>
|
|
716
|
+
<span class="cline-any cline-neutral"> </span>
|
|
717
|
+
<span class="cline-any cline-no"> </span>
|
|
718
|
+
<span class="cline-any cline-neutral"> </span>
|
|
719
|
+
<span class="cline-any cline-neutral"> </span>
|
|
720
|
+
<span class="cline-any cline-neutral"> </span>
|
|
721
|
+
<span class="cline-any cline-neutral"> </span>
|
|
722
|
+
<span class="cline-any cline-neutral"> </span>
|
|
723
|
+
<span class="cline-any cline-neutral"> </span>
|
|
724
|
+
<span class="cline-any cline-neutral"> </span>
|
|
725
|
+
<span class="cline-any cline-neutral"> </span>
|
|
726
|
+
<span class="cline-any cline-neutral"> </span>
|
|
727
|
+
<span class="cline-any cline-neutral"> </span>
|
|
728
|
+
<span class="cline-any cline-neutral"> </span>
|
|
729
|
+
<span class="cline-any cline-neutral"> </span>
|
|
730
|
+
<span class="cline-any cline-neutral"> </span>
|
|
731
|
+
<span class="cline-any cline-neutral"> </span>
|
|
732
|
+
<span class="cline-any cline-neutral"> </span>
|
|
733
|
+
<span class="cline-any cline-neutral"> </span>
|
|
734
|
+
<span class="cline-any cline-neutral"> </span>
|
|
735
|
+
<span class="cline-any cline-neutral"> </span>
|
|
736
|
+
<span class="cline-any cline-neutral"> </span>
|
|
737
|
+
<span class="cline-any cline-neutral"> </span>
|
|
738
|
+
<span class="cline-any cline-neutral"> </span>
|
|
739
|
+
<span class="cline-any cline-no"> </span>
|
|
740
|
+
<span class="cline-any cline-no"> </span>
|
|
741
|
+
<span class="cline-any cline-no"> </span>
|
|
742
|
+
<span class="cline-any cline-neutral"> </span>
|
|
743
|
+
<span class="cline-any cline-neutral"> </span>
|
|
744
|
+
<span class="cline-any cline-neutral"> </span>
|
|
745
|
+
<span class="cline-any cline-no"> </span>
|
|
746
|
+
<span class="cline-any cline-no"> </span>
|
|
747
|
+
<span class="cline-any cline-no"> </span>
|
|
748
|
+
<span class="cline-any cline-no"> </span>
|
|
749
|
+
<span class="cline-any cline-no"> </span>
|
|
750
|
+
<span class="cline-any cline-no"> </span>
|
|
751
|
+
<span class="cline-any cline-neutral"> </span>
|
|
752
|
+
<span class="cline-any cline-no"> </span>
|
|
753
|
+
<span class="cline-any cline-neutral"> </span>
|
|
754
|
+
<span class="cline-any cline-neutral"> </span>
|
|
755
|
+
<span class="cline-any cline-no"> </span>
|
|
756
|
+
<span class="cline-any cline-no"> </span>
|
|
757
|
+
<span class="cline-any cline-no"> </span>
|
|
758
|
+
<span class="cline-any cline-no"> </span>
|
|
759
|
+
<span class="cline-any cline-no"> </span>
|
|
760
|
+
<span class="cline-any cline-no"> </span>
|
|
761
|
+
<span class="cline-any cline-no"> </span>
|
|
762
|
+
<span class="cline-any cline-no"> </span>
|
|
763
|
+
<span class="cline-any cline-no"> </span>
|
|
764
|
+
<span class="cline-any cline-neutral"> </span>
|
|
765
|
+
<span class="cline-any cline-no"> </span>
|
|
766
|
+
<span class="cline-any cline-no"> </span>
|
|
767
|
+
<span class="cline-any cline-no"> </span>
|
|
768
|
+
<span class="cline-any cline-no"> </span>
|
|
769
|
+
<span class="cline-any cline-no"> </span>
|
|
770
|
+
<span class="cline-any cline-no"> </span>
|
|
771
|
+
<span class="cline-any cline-no"> </span>
|
|
772
|
+
<span class="cline-any cline-no"> </span>
|
|
773
|
+
<span class="cline-any cline-no"> </span>
|
|
774
|
+
<span class="cline-any cline-no"> </span>
|
|
775
|
+
<span class="cline-any cline-no"> </span>
|
|
776
|
+
<span class="cline-any cline-no"> </span>
|
|
777
|
+
<span class="cline-any cline-no"> </span>
|
|
778
|
+
<span class="cline-any cline-no"> </span>
|
|
779
|
+
<span class="cline-any cline-no"> </span>
|
|
780
|
+
<span class="cline-any cline-no"> </span>
|
|
781
|
+
<span class="cline-any cline-neutral"> </span>
|
|
782
|
+
<span class="cline-any cline-no"> </span>
|
|
783
|
+
<span class="cline-any cline-no"> </span>
|
|
784
|
+
<span class="cline-any cline-neutral"> </span>
|
|
785
|
+
<span class="cline-any cline-no"> </span>
|
|
786
|
+
<span class="cline-any cline-no"> </span>
|
|
787
|
+
<span class="cline-any cline-no"> </span>
|
|
788
|
+
<span class="cline-any cline-no"> </span>
|
|
789
|
+
<span class="cline-any cline-no"> </span>
|
|
790
|
+
<span class="cline-any cline-no"> </span>
|
|
791
|
+
<span class="cline-any cline-no"> </span>
|
|
792
|
+
<span class="cline-any cline-neutral"> </span>
|
|
793
|
+
<span class="cline-any cline-neutral"> </span>
|
|
794
|
+
<span class="cline-any cline-neutral"> </span>
|
|
795
|
+
<span class="cline-any cline-neutral"> </span>
|
|
796
|
+
<span class="cline-any cline-neutral"> </span>
|
|
797
|
+
<span class="cline-any cline-no"> </span>
|
|
798
|
+
<span class="cline-any cline-no"> </span>
|
|
799
|
+
<span class="cline-any cline-no"> </span>
|
|
800
|
+
<span class="cline-any cline-no"> </span>
|
|
801
|
+
<span class="cline-any cline-no"> </span>
|
|
802
|
+
<span class="cline-any cline-no"> </span>
|
|
803
|
+
<span class="cline-any cline-no"> </span>
|
|
804
|
+
<span class="cline-any cline-no"> </span>
|
|
805
|
+
<span class="cline-any cline-no"> </span>
|
|
806
|
+
<span class="cline-any cline-no"> </span>
|
|
807
|
+
<span class="cline-any cline-no"> </span>
|
|
808
|
+
<span class="cline-any cline-neutral"> </span>
|
|
809
|
+
<span class="cline-any cline-no"> </span>
|
|
810
|
+
<span class="cline-any cline-no"> </span>
|
|
811
|
+
<span class="cline-any cline-no"> </span>
|
|
812
|
+
<span class="cline-any cline-no"> </span>
|
|
813
|
+
<span class="cline-any cline-no"> </span>
|
|
814
|
+
<span class="cline-any cline-no"> </span>
|
|
815
|
+
<span class="cline-any cline-neutral"> </span>
|
|
816
|
+
<span class="cline-any cline-no"> </span>
|
|
817
|
+
<span class="cline-any cline-no"> </span>
|
|
818
|
+
<span class="cline-any cline-no"> </span>
|
|
819
|
+
<span class="cline-any cline-neutral"> </span>
|
|
820
|
+
<span class="cline-any cline-no"> </span>
|
|
821
|
+
<span class="cline-any cline-neutral"> </span>
|
|
822
|
+
<span class="cline-any cline-no"> </span>
|
|
823
|
+
<span class="cline-any cline-no"> </span>
|
|
824
|
+
<span class="cline-any cline-no"> </span>
|
|
825
|
+
<span class="cline-any cline-no"> </span>
|
|
826
|
+
<span class="cline-any cline-no"> </span>
|
|
827
|
+
<span class="cline-any cline-no"> </span>
|
|
828
|
+
<span class="cline-any cline-no"> </span>
|
|
829
|
+
<span class="cline-any cline-no"> </span>
|
|
830
|
+
<span class="cline-any cline-no"> </span>
|
|
831
|
+
<span class="cline-any cline-no"> </span>
|
|
832
|
+
<span class="cline-any cline-neutral"> </span>
|
|
833
|
+
<span class="cline-any cline-no"> </span>
|
|
834
|
+
<span class="cline-any cline-no"> </span>
|
|
835
|
+
<span class="cline-any cline-no"> </span>
|
|
836
|
+
<span class="cline-any cline-no"> </span>
|
|
837
|
+
<span class="cline-any cline-no"> </span>
|
|
838
|
+
<span class="cline-any cline-neutral"> </span>
|
|
839
|
+
<span class="cline-any cline-no"> </span>
|
|
840
|
+
<span class="cline-any cline-no"> </span>
|
|
841
|
+
<span class="cline-any cline-no"> </span>
|
|
842
|
+
<span class="cline-any cline-no"> </span>
|
|
843
|
+
<span class="cline-any cline-neutral"> </span>
|
|
844
|
+
<span class="cline-any cline-no"> </span>
|
|
845
|
+
<span class="cline-any cline-neutral"> </span>
|
|
846
|
+
<span class="cline-any cline-no"> </span>
|
|
847
|
+
<span class="cline-any cline-no"> </span>
|
|
848
|
+
<span class="cline-any cline-no"> </span>
|
|
849
|
+
<span class="cline-any cline-neutral"> </span>
|
|
850
|
+
<span class="cline-any cline-no"> </span>
|
|
851
|
+
<span class="cline-any cline-no"> </span>
|
|
852
|
+
<span class="cline-any cline-no"> </span>
|
|
853
|
+
<span class="cline-any cline-no"> </span>
|
|
854
|
+
<span class="cline-any cline-no"> </span>
|
|
855
|
+
<span class="cline-any cline-no"> </span>
|
|
856
|
+
<span class="cline-any cline-no"> </span>
|
|
857
|
+
<span class="cline-any cline-no"> </span>
|
|
858
|
+
<span class="cline-any cline-no"> </span>
|
|
859
|
+
<span class="cline-any cline-no"> </span>
|
|
860
|
+
<span class="cline-any cline-no"> </span>
|
|
861
|
+
<span class="cline-any cline-no"> </span>
|
|
862
|
+
<span class="cline-any cline-no"> </span>
|
|
863
|
+
<span class="cline-any cline-no"> </span>
|
|
864
|
+
<span class="cline-any cline-no"> </span>
|
|
865
|
+
<span class="cline-any cline-no"> </span>
|
|
866
|
+
<span class="cline-any cline-no"> </span>
|
|
867
|
+
<span class="cline-any cline-neutral"> </span>
|
|
868
|
+
<span class="cline-any cline-neutral"> </span>
|
|
869
|
+
<span class="cline-any cline-neutral"> </span>
|
|
870
|
+
<span class="cline-any cline-neutral"> </span>
|
|
871
|
+
<span class="cline-any cline-neutral"> </span>
|
|
872
|
+
<span class="cline-any cline-neutral"> </span>
|
|
873
|
+
<span class="cline-any cline-neutral"> </span>
|
|
874
|
+
<span class="cline-any cline-neutral"> </span>
|
|
875
|
+
<span class="cline-any cline-neutral"> </span>
|
|
876
|
+
<span class="cline-any cline-neutral"> </span>
|
|
877
|
+
<span class="cline-any cline-neutral"> </span>
|
|
878
|
+
<span class="cline-any cline-neutral"> </span>
|
|
879
|
+
<span class="cline-any cline-neutral"> </span>
|
|
880
|
+
<span class="cline-any cline-neutral"> </span>
|
|
881
|
+
<span class="cline-any cline-neutral"> </span>
|
|
882
|
+
<span class="cline-any cline-no"> </span>
|
|
883
|
+
<span class="cline-any cline-no"> </span>
|
|
884
|
+
<span class="cline-any cline-no"> </span>
|
|
885
|
+
<span class="cline-any cline-no"> </span>
|
|
886
|
+
<span class="cline-any cline-no"> </span>
|
|
887
|
+
<span class="cline-any cline-no"> </span>
|
|
888
|
+
<span class="cline-any cline-no"> </span>
|
|
889
|
+
<span class="cline-any cline-no"> </span>
|
|
890
|
+
<span class="cline-any cline-no"> </span>
|
|
891
|
+
<span class="cline-any cline-no"> </span>
|
|
892
|
+
<span class="cline-any cline-no"> </span>
|
|
893
|
+
<span class="cline-any cline-no"> </span>
|
|
894
|
+
<span class="cline-any cline-neutral"> </span>
|
|
895
|
+
<span class="cline-any cline-no"> </span>
|
|
896
|
+
<span class="cline-any cline-no"> </span>
|
|
897
|
+
<span class="cline-any cline-no"> </span>
|
|
898
|
+
<span class="cline-any cline-no"> </span>
|
|
899
|
+
<span class="cline-any cline-no"> </span>
|
|
900
|
+
<span class="cline-any cline-no"> </span>
|
|
901
|
+
<span class="cline-any cline-neutral"> </span>
|
|
902
|
+
<span class="cline-any cline-no"> </span>
|
|
903
|
+
<span class="cline-any cline-no"> </span>
|
|
904
|
+
<span class="cline-any cline-no"> </span>
|
|
905
|
+
<span class="cline-any cline-no"> </span>
|
|
906
|
+
<span class="cline-any cline-no"> </span>
|
|
907
|
+
<span class="cline-any cline-no"> </span>
|
|
908
|
+
<span class="cline-any cline-no"> </span>
|
|
909
|
+
<span class="cline-any cline-no"> </span>
|
|
910
|
+
<span class="cline-any cline-no"> </span>
|
|
911
|
+
<span class="cline-any cline-neutral"> </span>
|
|
912
|
+
<span class="cline-any cline-neutral"> </span>
|
|
913
|
+
<span class="cline-any cline-no"> </span>
|
|
914
|
+
<span class="cline-any cline-no"> </span>
|
|
915
|
+
<span class="cline-any cline-no"> </span>
|
|
916
|
+
<span class="cline-any cline-no"> </span>
|
|
917
|
+
<span class="cline-any cline-no"> </span>
|
|
918
|
+
<span class="cline-any cline-neutral"> </span>
|
|
919
|
+
<span class="cline-any cline-no"> </span>
|
|
920
|
+
<span class="cline-any cline-neutral"> </span>
|
|
921
|
+
<span class="cline-any cline-no"> </span>
|
|
922
|
+
<span class="cline-any cline-no"> </span>
|
|
923
|
+
<span class="cline-any cline-no"> </span>
|
|
924
|
+
<span class="cline-any cline-no"> </span>
|
|
925
|
+
<span class="cline-any cline-no"> </span>
|
|
926
|
+
<span class="cline-any cline-no"> </span>
|
|
927
|
+
<span class="cline-any cline-no"> </span>
|
|
928
|
+
<span class="cline-any cline-no"> </span>
|
|
929
|
+
<span class="cline-any cline-no"> </span>
|
|
930
|
+
<span class="cline-any cline-no"> </span>
|
|
931
|
+
<span class="cline-any cline-no"> </span>
|
|
932
|
+
<span class="cline-any cline-no"> </span>
|
|
933
|
+
<span class="cline-any cline-no"> </span>
|
|
934
|
+
<span class="cline-any cline-neutral"> </span>
|
|
935
|
+
<span class="cline-any cline-no"> </span>
|
|
936
|
+
<span class="cline-any cline-no"> </span>
|
|
937
|
+
<span class="cline-any cline-no"> </span>
|
|
938
|
+
<span class="cline-any cline-no"> </span>
|
|
939
|
+
<span class="cline-any cline-neutral"> </span>
|
|
940
|
+
<span class="cline-any cline-no"> </span>
|
|
941
|
+
<span class="cline-any cline-neutral"> </span>
|
|
942
|
+
<span class="cline-any cline-no"> </span>
|
|
943
|
+
<span class="cline-any cline-no"> </span>
|
|
944
|
+
<span class="cline-any cline-no"> </span>
|
|
945
|
+
<span class="cline-any cline-no"> </span>
|
|
946
|
+
<span class="cline-any cline-no"> </span>
|
|
947
|
+
<span class="cline-any cline-no"> </span>
|
|
948
|
+
<span class="cline-any cline-no"> </span>
|
|
949
|
+
<span class="cline-any cline-no"> </span>
|
|
950
|
+
<span class="cline-any cline-no"> </span>
|
|
951
|
+
<span class="cline-any cline-no"> </span>
|
|
952
|
+
<span class="cline-any cline-neutral"> </span>
|
|
953
|
+
<span class="cline-any cline-no"> </span>
|
|
954
|
+
<span class="cline-any cline-no"> </span>
|
|
955
|
+
<span class="cline-any cline-neutral"> </span>
|
|
956
|
+
<span class="cline-any cline-no"> </span>
|
|
957
|
+
<span class="cline-any cline-no"> </span>
|
|
958
|
+
<span class="cline-any cline-neutral"> </span>
|
|
959
|
+
<span class="cline-any cline-no"> </span>
|
|
960
|
+
<span class="cline-any cline-neutral"> </span>
|
|
961
|
+
<span class="cline-any cline-no"> </span>
|
|
962
|
+
<span class="cline-any cline-no"> </span>
|
|
963
|
+
<span class="cline-any cline-no"> </span>
|
|
964
|
+
<span class="cline-any cline-no"> </span>
|
|
965
|
+
<span class="cline-any cline-no"> </span>
|
|
966
|
+
<span class="cline-any cline-neutral"> </span>
|
|
967
|
+
<span class="cline-any cline-neutral"> </span>
|
|
968
|
+
<span class="cline-any cline-neutral"> </span>
|
|
969
|
+
<span class="cline-any cline-no"> </span>
|
|
970
|
+
<span class="cline-any cline-no"> </span>
|
|
971
|
+
<span class="cline-any cline-no"> </span>
|
|
972
|
+
<span class="cline-any cline-no"> </span>
|
|
973
|
+
<span class="cline-any cline-no"> </span>
|
|
974
|
+
<span class="cline-any cline-no"> </span>
|
|
975
|
+
<span class="cline-any cline-no"> </span>
|
|
976
|
+
<span class="cline-any cline-no"> </span>
|
|
977
|
+
<span class="cline-any cline-no"> </span>
|
|
978
|
+
<span class="cline-any cline-no"> </span>
|
|
979
|
+
<span class="cline-any cline-no"> </span>
|
|
980
|
+
<span class="cline-any cline-no"> </span>
|
|
981
|
+
<span class="cline-any cline-no"> </span>
|
|
982
|
+
<span class="cline-any cline-no"> </span>
|
|
983
|
+
<span class="cline-any cline-no"> </span>
|
|
984
|
+
<span class="cline-any cline-no"> </span>
|
|
985
|
+
<span class="cline-any cline-no"> </span>
|
|
986
|
+
<span class="cline-any cline-no"> </span>
|
|
987
|
+
<span class="cline-any cline-neutral"> </span>
|
|
988
|
+
<span class="cline-any cline-no"> </span>
|
|
989
|
+
<span class="cline-any cline-no"> </span>
|
|
990
|
+
<span class="cline-any cline-no"> </span>
|
|
991
|
+
<span class="cline-any cline-no"> </span>
|
|
992
|
+
<span class="cline-any cline-no"> </span>
|
|
993
|
+
<span class="cline-any cline-no"> </span>
|
|
994
|
+
<span class="cline-any cline-no"> </span>
|
|
995
|
+
<span class="cline-any cline-no"> </span>
|
|
996
|
+
<span class="cline-any cline-no"> </span>
|
|
997
|
+
<span class="cline-any cline-no"> </span>
|
|
998
|
+
<span class="cline-any cline-no"> </span>
|
|
999
|
+
<span class="cline-any cline-no"> </span>
|
|
1000
|
+
<span class="cline-any cline-no"> </span>
|
|
1001
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1002
|
+
<span class="cline-any cline-no"> </span>
|
|
1003
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1004
|
+
<span class="cline-any cline-no"> </span>
|
|
1005
|
+
<span class="cline-any cline-no"> </span>
|
|
1006
|
+
<span class="cline-any cline-no"> </span>
|
|
1007
|
+
<span class="cline-any cline-no"> </span>
|
|
1008
|
+
<span class="cline-any cline-no"> </span>
|
|
1009
|
+
<span class="cline-any cline-no"> </span>
|
|
1010
|
+
<span class="cline-any cline-no"> </span>
|
|
1011
|
+
<span class="cline-any cline-no"> </span>
|
|
1012
|
+
<span class="cline-any cline-no"> </span>
|
|
1013
|
+
<span class="cline-any cline-no"> </span>
|
|
1014
|
+
<span class="cline-any cline-no"> </span>
|
|
1015
|
+
<span class="cline-any cline-no"> </span>
|
|
1016
|
+
<span class="cline-any cline-no"> </span>
|
|
1017
|
+
<span class="cline-any cline-no"> </span>
|
|
1018
|
+
<span class="cline-any cline-no"> </span>
|
|
1019
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1020
|
+
<span class="cline-any cline-no"> </span>
|
|
1021
|
+
<span class="cline-any cline-no"> </span>
|
|
1022
|
+
<span class="cline-any cline-no"> </span>
|
|
1023
|
+
<span class="cline-any cline-no"> </span>
|
|
1024
|
+
<span class="cline-any cline-no"> </span>
|
|
1025
|
+
<span class="cline-any cline-no"> </span>
|
|
1026
|
+
<span class="cline-any cline-no"> </span>
|
|
1027
|
+
<span class="cline-any cline-no"> </span>
|
|
1028
|
+
<span class="cline-any cline-no"> </span>
|
|
1029
|
+
<span class="cline-any cline-no"> </span>
|
|
1030
|
+
<span class="cline-any cline-no"> </span>
|
|
1031
|
+
<span class="cline-any cline-no"> </span>
|
|
1032
|
+
<span class="cline-any cline-no"> </span>
|
|
1033
|
+
<span class="cline-any cline-no"> </span>
|
|
1034
|
+
<span class="cline-any cline-no"> </span>
|
|
1035
|
+
<span class="cline-any cline-no"> </span>
|
|
1036
|
+
<span class="cline-any cline-no"> </span>
|
|
1037
|
+
<span class="cline-any cline-no"> </span>
|
|
1038
|
+
<span class="cline-any cline-no"> </span>
|
|
1039
|
+
<span class="cline-any cline-no"> </span>
|
|
1040
|
+
<span class="cline-any cline-no"> </span>
|
|
1041
|
+
<span class="cline-any cline-no"> </span>
|
|
1042
|
+
<span class="cline-any cline-no"> </span>
|
|
1043
|
+
<span class="cline-any cline-no"> </span>
|
|
1044
|
+
<span class="cline-any cline-no"> </span>
|
|
1045
|
+
<span class="cline-any cline-no"> </span>
|
|
1046
|
+
<span class="cline-any cline-no"> </span>
|
|
1047
|
+
<span class="cline-any cline-no"> </span>
|
|
1048
|
+
<span class="cline-any cline-no"> </span>
|
|
1049
|
+
<span class="cline-any cline-no"> </span>
|
|
1050
|
+
<span class="cline-any cline-no"> </span>
|
|
1051
|
+
<span class="cline-any cline-no"> </span>
|
|
1052
|
+
<span class="cline-any cline-no"> </span>
|
|
1053
|
+
<span class="cline-any cline-no"> </span>
|
|
1054
|
+
<span class="cline-any cline-no"> </span>
|
|
1055
|
+
<span class="cline-any cline-no"> </span>
|
|
1056
|
+
<span class="cline-any cline-no"> </span>
|
|
1057
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1058
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1059
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1060
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1061
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1062
|
+
<span class="cline-any cline-no"> </span>
|
|
1063
|
+
<span class="cline-any cline-no"> </span>
|
|
1064
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1065
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1066
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1067
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1068
|
+
<span class="cline-any cline-no"> </span>
|
|
1069
|
+
<span class="cline-any cline-no"> </span>
|
|
1070
|
+
<span class="cline-any cline-no"> </span>
|
|
1071
|
+
<span class="cline-any cline-no"> </span>
|
|
1072
|
+
<span class="cline-any cline-no"> </span>
|
|
1073
|
+
<span class="cline-any cline-no"> </span>
|
|
1074
|
+
<span class="cline-any cline-no"> </span>
|
|
1075
|
+
<span class="cline-any cline-no"> </span>
|
|
1076
|
+
<span class="cline-any cline-no"> </span>
|
|
1077
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1078
|
+
<span class="cline-any cline-no"> </span>
|
|
1079
|
+
<span class="cline-any cline-no"> </span>
|
|
1080
|
+
<span class="cline-any cline-no"> </span>
|
|
1081
|
+
<span class="cline-any cline-no"> </span>
|
|
1082
|
+
<span class="cline-any cline-no"> </span>
|
|
1083
|
+
<span class="cline-any cline-no"> </span>
|
|
1084
|
+
<span class="cline-any cline-no"> </span>
|
|
1085
|
+
<span class="cline-any cline-no"> </span>
|
|
1086
|
+
<span class="cline-any cline-no"> </span>
|
|
1087
|
+
<span class="cline-any cline-no"> </span>
|
|
1088
|
+
<span class="cline-any cline-no"> </span>
|
|
1089
|
+
<span class="cline-any cline-no"> </span>
|
|
1090
|
+
<span class="cline-any cline-no"> </span>
|
|
1091
|
+
<span class="cline-any cline-no"> </span>
|
|
1092
|
+
<span class="cline-any cline-no"> </span>
|
|
1093
|
+
<span class="cline-any cline-no"> </span>
|
|
1094
|
+
<span class="cline-any cline-no"> </span>
|
|
1095
|
+
<span class="cline-any cline-no"> </span>
|
|
1096
|
+
<span class="cline-any cline-no"> </span>
|
|
1097
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1098
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1099
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1100
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1101
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1102
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1103
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1104
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1105
|
+
<span class="cline-any cline-no"> </span>
|
|
1106
|
+
<span class="cline-any cline-no"> </span>
|
|
1107
|
+
<span class="cline-any cline-no"> </span>
|
|
1108
|
+
<span class="cline-any cline-no"> </span>
|
|
1109
|
+
<span class="cline-any cline-no"> </span>
|
|
1110
|
+
<span class="cline-any cline-no"> </span>
|
|
1111
|
+
<span class="cline-any cline-no"> </span>
|
|
1112
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1113
|
+
<span class="cline-any cline-no"> </span>
|
|
1114
|
+
<span class="cline-any cline-no"> </span>
|
|
1115
|
+
<span class="cline-any cline-no"> </span>
|
|
1116
|
+
<span class="cline-any cline-no"> </span>
|
|
1117
|
+
<span class="cline-any cline-no"> </span>
|
|
1118
|
+
<span class="cline-any cline-no"> </span>
|
|
1119
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1120
|
+
<span class="cline-any cline-no"> </span>
|
|
1121
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1122
|
+
<span class="cline-any cline-no"> </span>
|
|
1123
|
+
<span class="cline-any cline-no"> </span>
|
|
1124
|
+
<span class="cline-any cline-no"> </span>
|
|
1125
|
+
<span class="cline-any cline-no"> </span>
|
|
1126
|
+
<span class="cline-any cline-no"> </span>
|
|
1127
|
+
<span class="cline-any cline-no"> </span>
|
|
1128
|
+
<span class="cline-any cline-no"> </span>
|
|
1129
|
+
<span class="cline-any cline-no"> </span>
|
|
1130
|
+
<span class="cline-any cline-no"> </span>
|
|
1131
|
+
<span class="cline-any cline-no"> </span>
|
|
1132
|
+
<span class="cline-any cline-no"> </span>
|
|
1133
|
+
<span class="cline-any cline-no"> </span>
|
|
1134
|
+
<span class="cline-any cline-no"> </span>
|
|
1135
|
+
<span class="cline-any cline-no"> </span>
|
|
1136
|
+
<span class="cline-any cline-no"> </span>
|
|
1137
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1138
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1139
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1140
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1141
|
+
<span class="cline-any cline-no"> </span>
|
|
1142
|
+
<span class="cline-any cline-no"> </span>
|
|
1143
|
+
<span class="cline-any cline-no"> </span>
|
|
1144
|
+
<span class="cline-any cline-no"> </span>
|
|
1145
|
+
<span class="cline-any cline-no"> </span>
|
|
1146
|
+
<span class="cline-any cline-no"> </span>
|
|
1147
|
+
<span class="cline-any cline-no"> </span>
|
|
1148
|
+
<span class="cline-any cline-no"> </span>
|
|
1149
|
+
<span class="cline-any cline-no"> </span>
|
|
1150
|
+
<span class="cline-any cline-no"> </span>
|
|
1151
|
+
<span class="cline-any cline-no"> </span>
|
|
1152
|
+
<span class="cline-any cline-no"> </span>
|
|
1153
|
+
<span class="cline-any cline-no"> </span>
|
|
1154
|
+
<span class="cline-any cline-no"> </span>
|
|
1155
|
+
<span class="cline-any cline-no"> </span>
|
|
1156
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1157
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1158
|
+
<span class="cline-any cline-no"> </span>
|
|
1159
|
+
<span class="cline-any cline-no"> </span>
|
|
1160
|
+
<span class="cline-any cline-no"> </span>
|
|
1161
|
+
<span class="cline-any cline-no"> </span>
|
|
1162
|
+
<span class="cline-any cline-no"> </span>
|
|
1163
|
+
<span class="cline-any cline-no"> </span>
|
|
1164
|
+
<span class="cline-any cline-no"> </span>
|
|
1165
|
+
<span class="cline-any cline-no"> </span>
|
|
1166
|
+
<span class="cline-any cline-no"> </span>
|
|
1167
|
+
<span class="cline-any cline-no"> </span>
|
|
1168
|
+
<span class="cline-any cline-no"> </span>
|
|
1169
|
+
<span class="cline-any cline-no"> </span>
|
|
1170
|
+
<span class="cline-any cline-no"> </span>
|
|
1171
|
+
<span class="cline-any cline-no"> </span>
|
|
1172
|
+
<span class="cline-any cline-no"> </span>
|
|
1173
|
+
<span class="cline-any cline-no"> </span>
|
|
1174
|
+
<span class="cline-any cline-no"> </span>
|
|
1175
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1176
|
+
<span class="cline-any cline-no"> </span>
|
|
1177
|
+
<span class="cline-any cline-no"> </span>
|
|
1178
|
+
<span class="cline-any cline-no"> </span>
|
|
1179
|
+
<span class="cline-any cline-no"> </span>
|
|
1180
|
+
<span class="cline-any cline-no"> </span>
|
|
1181
|
+
<span class="cline-any cline-no"> </span>
|
|
1182
|
+
<span class="cline-any cline-no"> </span>
|
|
1183
|
+
<span class="cline-any cline-no"> </span>
|
|
1184
|
+
<span class="cline-any cline-no"> </span>
|
|
1185
|
+
<span class="cline-any cline-no"> </span>
|
|
1186
|
+
<span class="cline-any cline-no"> </span>
|
|
1187
|
+
<span class="cline-any cline-no"> </span>
|
|
1188
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1189
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1190
|
+
<span class="cline-any cline-no"> </span>
|
|
1191
|
+
<span class="cline-any cline-no"> </span>
|
|
1192
|
+
<span class="cline-any cline-no"> </span>
|
|
1193
|
+
<span class="cline-any cline-no"> </span>
|
|
1194
|
+
<span class="cline-any cline-no"> </span>
|
|
1195
|
+
<span class="cline-any cline-no"> </span>
|
|
1196
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1197
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1198
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1199
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1200
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1201
|
+
<span class="cline-any cline-no"> </span>
|
|
1202
|
+
<span class="cline-any cline-no"> </span>
|
|
1203
|
+
<span class="cline-any cline-no"> </span>
|
|
1204
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1205
|
+
<span class="cline-any cline-no"> </span>
|
|
1206
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1207
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1208
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1209
|
+
<span class="cline-any cline-no"> </span>
|
|
1210
|
+
<span class="cline-any cline-no"> </span>
|
|
1211
|
+
<span class="cline-any cline-no"> </span>
|
|
1212
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1213
|
+
<span class="cline-any cline-no"> </span>
|
|
1214
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1215
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1216
|
+
<span class="cline-any cline-no"> </span>
|
|
1217
|
+
<span class="cline-any cline-no"> </span>
|
|
1218
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1219
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1220
|
+
<span class="cline-any cline-no"> </span>
|
|
1221
|
+
<span class="cline-any cline-no"> </span>
|
|
1222
|
+
<span class="cline-any cline-no"> </span>
|
|
1223
|
+
<span class="cline-any cline-no"> </span>
|
|
1224
|
+
<span class="cline-any cline-no"> </span>
|
|
1225
|
+
<span class="cline-any cline-no"> </span>
|
|
1226
|
+
<span class="cline-any cline-no"> </span>
|
|
1227
|
+
<span class="cline-any cline-no"> </span>
|
|
1228
|
+
<span class="cline-any cline-no"> </span>
|
|
1229
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1230
|
+
<span class="cline-any cline-no"> </span>
|
|
1231
|
+
<span class="cline-any cline-no"> </span>
|
|
1232
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1233
|
+
<span class="cline-any cline-no"> </span>
|
|
1234
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1235
|
+
<span class="cline-any cline-no"> </span>
|
|
1236
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1237
|
+
<span class="cline-any cline-no"> </span>
|
|
1238
|
+
<span class="cline-any cline-no"> </span>
|
|
1239
|
+
<span class="cline-any cline-no"> </span>
|
|
1240
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1241
|
+
<span class="cline-any cline-no"> </span>
|
|
1242
|
+
<span class="cline-any cline-no"> </span>
|
|
1243
|
+
<span class="cline-any cline-no"> </span>
|
|
1244
|
+
<span class="cline-any cline-no"> </span>
|
|
1245
|
+
<span class="cline-any cline-no"> </span>
|
|
1246
|
+
<span class="cline-any cline-no"> </span>
|
|
1247
|
+
<span class="cline-any cline-no"> </span>
|
|
1248
|
+
<span class="cline-any cline-no"> </span>
|
|
1249
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1250
|
+
<span class="cline-any cline-no"> </span>
|
|
1251
|
+
<span class="cline-any cline-no"> </span>
|
|
1252
|
+
<span class="cline-any cline-no"> </span>
|
|
1253
|
+
<span class="cline-any cline-no"> </span>
|
|
1254
|
+
<span class="cline-any cline-no"> </span>
|
|
1255
|
+
<span class="cline-any cline-no"> </span>
|
|
1256
|
+
<span class="cline-any cline-no"> </span>
|
|
1257
|
+
<span class="cline-any cline-no"> </span>
|
|
1258
|
+
<span class="cline-any cline-no"> </span>
|
|
1259
|
+
<span class="cline-any cline-no"> </span>
|
|
1260
|
+
<span class="cline-any cline-no"> </span>
|
|
1261
|
+
<span class="cline-any cline-no"> </span>
|
|
1262
|
+
<span class="cline-any cline-no"> </span>
|
|
1263
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1264
|
+
<span class="cline-any cline-no"> </span>
|
|
1265
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1266
|
+
<span class="cline-any cline-no"> </span>
|
|
1267
|
+
<span class="cline-any cline-no"> </span>
|
|
1268
|
+
<span class="cline-any cline-no"> </span>
|
|
1269
|
+
<span class="cline-any cline-no"> </span>
|
|
1270
|
+
<span class="cline-any cline-no"> </span>
|
|
1271
|
+
<span class="cline-any cline-no"> </span>
|
|
1272
|
+
<span class="cline-any cline-no"> </span>
|
|
1273
|
+
<span class="cline-any cline-no"> </span>
|
|
1274
|
+
<span class="cline-any cline-no"> </span>
|
|
1275
|
+
<span class="cline-any cline-no"> </span>
|
|
1276
|
+
<span class="cline-any cline-no"> </span>
|
|
1277
|
+
<span class="cline-any cline-no"> </span>
|
|
1278
|
+
<span class="cline-any cline-no"> </span>
|
|
1279
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1280
|
+
<span class="cline-any cline-no"> </span>
|
|
1281
|
+
<span class="cline-any cline-no"> </span>
|
|
1282
|
+
<span class="cline-any cline-no"> </span>
|
|
1283
|
+
<span class="cline-any cline-no"> </span>
|
|
1284
|
+
<span class="cline-any cline-no"> </span>
|
|
1285
|
+
<span class="cline-any cline-no"> </span>
|
|
1286
|
+
<span class="cline-any cline-no"> </span>
|
|
1287
|
+
<span class="cline-any cline-no"> </span>
|
|
1288
|
+
<span class="cline-any cline-no"> </span>
|
|
1289
|
+
<span class="cline-any cline-no"> </span>
|
|
1290
|
+
<span class="cline-any cline-no"> </span>
|
|
1291
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1292
|
+
<span class="cline-any cline-no"> </span>
|
|
1293
|
+
<span class="cline-any cline-no"> </span>
|
|
1294
|
+
<span class="cline-any cline-no"> </span>
|
|
1295
|
+
<span class="cline-any cline-no"> </span>
|
|
1296
|
+
<span class="cline-any cline-no"> </span>
|
|
1297
|
+
<span class="cline-any cline-no"> </span>
|
|
1298
|
+
<span class="cline-any cline-no"> </span>
|
|
1299
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1300
|
+
<span class="cline-any cline-no"> </span>
|
|
1301
|
+
<span class="cline-any cline-no"> </span>
|
|
1302
|
+
<span class="cline-any cline-no"> </span>
|
|
1303
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1304
|
+
<span class="cline-any cline-no"> </span>
|
|
1305
|
+
<span class="cline-any cline-no"> </span>
|
|
1306
|
+
<span class="cline-any cline-no"> </span>
|
|
1307
|
+
<span class="cline-any cline-no"> </span>
|
|
1308
|
+
<span class="cline-any cline-no"> </span>
|
|
1309
|
+
<span class="cline-any cline-no"> </span>
|
|
1310
|
+
<span class="cline-any cline-no"> </span>
|
|
1311
|
+
<span class="cline-any cline-no"> </span>
|
|
1312
|
+
<span class="cline-any cline-no"> </span>
|
|
1313
|
+
<span class="cline-any cline-no"> </span>
|
|
1314
|
+
<span class="cline-any cline-no"> </span>
|
|
1315
|
+
<span class="cline-any cline-no"> </span>
|
|
1316
|
+
<span class="cline-any cline-no"> </span>
|
|
1317
|
+
<span class="cline-any cline-no"> </span>
|
|
1318
|
+
<span class="cline-any cline-no"> </span>
|
|
1319
|
+
<span class="cline-any cline-no"> </span>
|
|
1320
|
+
<span class="cline-any cline-no"> </span>
|
|
1321
|
+
<span class="cline-any cline-no"> </span>
|
|
1322
|
+
<span class="cline-any cline-no"> </span>
|
|
1323
|
+
<span class="cline-any cline-no"> </span>
|
|
1324
|
+
<span class="cline-any cline-neutral"> </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
|
+
|
|
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
|
+
|
|
1381
|
+
<span class="cstat-no" title="statement not covered" >export class ImgCaptchaManager extends CaptchaManager {</span>
|
|
1382
|
+
config: ProsopoConfigOutput;
|
|
1383
|
+
|
|
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
|
+
|
|
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<Captcha[]> {</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
|
+
|
|
1411
|
+
<span class="cstat-no" title="statement not covered" > return captchaDocs;</span>
|
|
1412
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1413
|
+
|
|
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<{
|
|
1422
|
+
captchas: Captcha[];
|
|
1423
|
+
requestHash: string;
|
|
1424
|
+
timestamp: number;
|
|
1425
|
+
signedRequestHash: string;
|
|
1426
|
+
<span class="cstat-no" title="statement not covered" > }> {</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
|
+
|
|
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
|
+
|
|
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
|
+
|
|
1449
|
+
<span class="cstat-no" title="statement not covered" > const solved = await this.getCaptchaWithProof(datasetId, true, solvedCount);</span>
|
|
1450
|
+
|
|
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
|
+
|
|
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) => 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
|
+
|
|
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
|
+
|
|
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) => captcha.timeLimitMs || DEFAULT_IMAGE_CAPTCHA_TIMEOUT)</span>
|
|
1476
|
+
<span class="cstat-no" title="statement not covered" > .reduce((a, b) => a + b, 0);</span>
|
|
1477
|
+
<span class="cstat-no" title="statement not covered" > const deadlineTs = timeLimit + currentTime;</span>
|
|
1478
|
+
|
|
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
|
+
|
|
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<DappUserSolutionResult>} 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<DappUserSolutionResult> {</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(() => ({</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
|
+
|
|
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
|
+
|
|
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(() => ({</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
|
+
|
|
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
|
+
|
|
1569
|
+
<span class="cstat-no" title="statement not covered" > const pendingRecord = await this.db.getPendingImageCommitment(requestHash);</span>
|
|
1570
|
+
|
|
1571
|
+
<span class="cstat-no" title="statement not covered" > const unverifiedCaptchaIds = captchas.map((captcha) => 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
|
+
|
|
1582
|
+
<span class="cstat-no" title="statement not covered" > const flat = receivedCaptchas.map((c) => extractData(c.salt));</span>
|
|
1583
|
+
<span class="cstat-no" title="statement not covered" > const pairs = flat.map((list) => constructPairList(list));</span>
|
|
1584
|
+
|
|
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
|
+
|
|
1588
|
+
<span class="cstat-no" title="statement not covered" > const datasetId = at(storedCaptchas, 0).datasetId;</span>
|
|
1589
|
+
|
|
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
|
+
|
|
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
|
+
|
|
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) => {</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
|
+
|
|
1631
|
+
<span class="cstat-no" title="statement not covered" > const totalImages = storedCaptchas[0]?.items.length || 0;</span>
|
|
1632
|
+
|
|
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) => ({</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
|
+
|
|
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) => ({</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) => ({</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(() => ({</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
|
+
|
|
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<{
|
|
1694
|
+
storedCaptchas: Captcha[];
|
|
1695
|
+
receivedCaptchas: CaptchaSolution[];
|
|
1696
|
+
captchaIds: string[];
|
|
1697
|
+
<span class="cstat-no" title="statement not covered" > }> {</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) => 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
|
+
|
|
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) => 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
|
+
|
|
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<boolean> {</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(() => ({</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
|
+
|
|
1749
|
+
<span class="cstat-no" title="statement not covered" > if (pendingRecord.deadlineTimestamp < currentTime) {</span>
|
|
1750
|
+
// deadline for responding to the captcha has expired
|
|
1751
|
+
<span class="cstat-no" title="statement not covered" > this.logger.info(() => ({</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
|
+
|
|
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<UserCommitment> {</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
|
+
|
|
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<UserCommitment | undefined> {</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 > 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
|
+
|
|
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<ImageVerificationResponse> {</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
|
+
|
|
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(() => ({</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
|
+
|
|
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
|
+
|
|
1834
|
+
<span class="cstat-no" title="statement not covered" > await this.db.markDappUserCommitmentsChecked([solution.id]);</span>
|
|
1835
|
+
// -- END WARNING --
|
|
1836
|
+
|
|
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
|
+
|
|
1842
|
+
<span class="cstat-no" title="statement not covered" > maxVerifiedTime = maxVerifiedTime || 60 * 1000; // Default to 1 minute</span>
|
|
1843
|
+
|
|
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
|
+
|
|
1848
|
+
// A solution exists but has timed out
|
|
1849
|
+
<span class="cstat-no" title="statement not covered" > if (timeSinceCompletion > maxVerifiedTime) {</span>
|
|
1850
|
+
<span class="cstat-no" title="statement not covered" > this.logger.debug(() => ({</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
|
+
|
|
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
|
+
|
|
1864
|
+
<span class="cstat-no" title="statement not covered" > const ipValidationRules = clientRecord?.settings?.ipValidationRules;</span>
|
|
1865
|
+
|
|
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
|
+
|
|
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
|
+
|
|
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(() => ({</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
|
+
|
|
1893
|
+
<span class="cstat-no" title="statement not covered" > const isApproved = solution.result.status === CaptchaStatus.approved;</span>
|
|
1894
|
+
|
|
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(() => ({</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
|
+
|
|
1909
|
+
<span class="cstat-no" title="statement not covered" > if (</span>
|
|
1910
|
+
<span class="cstat-no" title="statement not covered" > disallowWebView === true &&</span>
|
|
1911
|
+
<span class="cstat-no" title="statement not covered" > (tokenRecord.scoreComponents.webView || 0) > 0</span>
|
|
1912
|
+
<span class="cstat-no" title="statement not covered" > ) {</span>
|
|
1913
|
+
<span class="cstat-no" title="statement not covered" > this.logger.info(() => ({</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
|
+
|
|
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 && { score }),</span>
|
|
1926
|
+
<span class="cstat-no" title="statement not covered" > };</span>
|
|
1927
|
+
<span class="cstat-no" title="statement not covered" > }</span>
|
|
1928
|
+
|
|
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
|
+
|
|
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) => 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 && {</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
|
+
</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
|
+
|