repoburg 1.0.39 → 1.0.40
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/backend/.env +1 -7
- package/backend/coverage/clover.xml +3380 -0
- package/backend/coverage/coverage-final.json +117 -0
- package/backend/coverage/lcov-report/base.css +224 -0
- package/backend/coverage/lcov-report/block-navigation.js +87 -0
- package/backend/coverage/lcov-report/favicon.png +0 -0
- package/backend/coverage/lcov-report/index.html +686 -0
- package/backend/coverage/lcov-report/prettify.css +1 -0
- package/backend/coverage/lcov-report/prettify.js +2 -0
- package/backend/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/backend/coverage/lcov-report/sorter.js +196 -0
- package/backend/coverage/lcov-report/src/action-execution/action-execution.module.ts.html +109 -0
- package/backend/coverage/lcov-report/src/action-execution/action-execution.service.ts.html +370 -0
- package/backend/coverage/lcov-report/src/action-execution/index.html +131 -0
- package/backend/coverage/lcov-report/src/ai-actions/ai-action-batch.service.ts.html +940 -0
- package/backend/coverage/lcov-report/src/ai-actions/ai-action-creation.service.ts.html +1195 -0
- package/backend/coverage/lcov-report/src/ai-actions/ai-actions.controller.ts.html +664 -0
- package/backend/coverage/lcov-report/src/ai-actions/ai-actions.module.ts.html +154 -0
- package/backend/coverage/lcov-report/src/ai-actions/ai-actions.service.ts.html +859 -0
- package/backend/coverage/lcov-report/src/ai-actions/index.html +176 -0
- package/backend/coverage/lcov-report/src/app.controller.ts.html +151 -0
- package/backend/coverage/lcov-report/src/app.module.ts.html +370 -0
- package/backend/coverage/lcov-report/src/app.service.ts.html +163 -0
- package/backend/coverage/lcov-report/src/application-state/application-state.controller.ts.html +265 -0
- package/backend/coverage/lcov-report/src/application-state/application-state.module.ts.html +124 -0
- package/backend/coverage/lcov-report/src/application-state/application-state.service.ts.html +394 -0
- package/backend/coverage/lcov-report/src/application-state/dto/index.html +146 -0
- package/backend/coverage/lcov-report/src/application-state/dto/set-auto-context-fetch-enabled.dto.ts.html +103 -0
- package/backend/coverage/lcov-report/src/application-state/dto/set-theme.dto.ts.html +106 -0
- package/backend/coverage/lcov-report/src/application-state/dto/set-websocket-enabled.dto.ts.html +103 -0
- package/backend/coverage/lcov-report/src/application-state/index.html +146 -0
- package/backend/coverage/lcov-report/src/context-generation/context-generation.module.ts.html +118 -0
- package/backend/coverage/lcov-report/src/context-generation/context-generation.service.ts.html +1348 -0
- package/backend/coverage/lcov-report/src/context-generation/index.html +131 -0
- package/backend/coverage/lcov-report/src/context-snippets/context-snippets.controller.ts.html +289 -0
- package/backend/coverage/lcov-report/src/context-snippets/context-snippets.module.ts.html +136 -0
- package/backend/coverage/lcov-report/src/context-snippets/context-snippets.service.ts.html +400 -0
- package/backend/coverage/lcov-report/src/context-snippets/dto/context-snippet.dto.ts.html +211 -0
- package/backend/coverage/lcov-report/src/context-snippets/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/context-snippets/index.html +146 -0
- package/backend/coverage/lcov-report/src/context-templates/context-templates.controller.ts.html +397 -0
- package/backend/coverage/lcov-report/src/context-templates/context-templates.module.ts.html +136 -0
- package/backend/coverage/lcov-report/src/context-templates/context-templates.service.ts.html +832 -0
- package/backend/coverage/lcov-report/src/context-templates/dto/context-template.dto.ts.html +358 -0
- package/backend/coverage/lcov-report/src/context-templates/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/context-templates/index.html +146 -0
- package/backend/coverage/lcov-report/src/core-entities/ai-action.entity.ts.html +241 -0
- package/backend/coverage/lcov-report/src/core-entities/application-state.entity.ts.html +115 -0
- package/backend/coverage/lcov-report/src/core-entities/base.entity.ts.html +145 -0
- package/backend/coverage/lcov-report/src/core-entities/context-snippet.entity.ts.html +130 -0
- package/backend/coverage/lcov-report/src/core-entities/context-template.entity.ts.html +223 -0
- package/backend/coverage/lcov-report/src/core-entities/custom-snippet.entity.ts.html +136 -0
- package/backend/coverage/lcov-report/src/core-entities/execution-log.entity.ts.html +157 -0
- package/backend/coverage/lcov-report/src/core-entities/index.html +281 -0
- package/backend/coverage/lcov-report/src/core-entities/index.ts.html +118 -0
- package/backend/coverage/lcov-report/src/core-entities/project.entity.ts.html +130 -0
- package/backend/coverage/lcov-report/src/core-entities/session-input.entity.ts.html +280 -0
- package/backend/coverage/lcov-report/src/core-entities/session.entity.ts.html +280 -0
- package/backend/coverage/lcov-report/src/core-entities/system-prompt.entity.ts.html +148 -0
- package/backend/coverage/lcov-report/src/custom-snippets/custom-snippets.controller.ts.html +277 -0
- package/backend/coverage/lcov-report/src/custom-snippets/custom-snippets.module.ts.html +124 -0
- package/backend/coverage/lcov-report/src/custom-snippets/custom-snippets.service.ts.html +304 -0
- package/backend/coverage/lcov-report/src/custom-snippets/dto/custom-snippet.dto.ts.html +205 -0
- package/backend/coverage/lcov-report/src/custom-snippets/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/custom-snippets/index.html +146 -0
- package/backend/coverage/lcov-report/src/events/events.gateway.ts.html +292 -0
- package/backend/coverage/lcov-report/src/events/events.module.ts.html +109 -0
- package/backend/coverage/lcov-report/src/events/index.html +131 -0
- package/backend/coverage/lcov-report/src/execution-logs/dto/execution-log.dto.ts.html +130 -0
- package/backend/coverage/lcov-report/src/execution-logs/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/execution-logs/execution-logs.controller.ts.html +130 -0
- package/backend/coverage/lcov-report/src/execution-logs/execution-logs.module.ts.html +124 -0
- package/backend/coverage/lcov-report/src/execution-logs/execution-logs.service.ts.html +238 -0
- package/backend/coverage/lcov-report/src/execution-logs/index.html +146 -0
- package/backend/coverage/lcov-report/src/http-exception.filter.ts.html +340 -0
- package/backend/coverage/lcov-report/src/index.html +191 -0
- package/backend/coverage/lcov-report/src/llm-response-parser/dto/ai-action.dto.ts.html +400 -0
- package/backend/coverage/lcov-report/src/llm-response-parser/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/llm-response-parser/errors/index.html +116 -0
- package/backend/coverage/lcov-report/src/llm-response-parser/errors/parsing.error.ts.html +118 -0
- package/backend/coverage/lcov-report/src/llm-response-parser/index.html +146 -0
- package/backend/coverage/lcov-report/src/llm-response-parser/llm-response-parser.module.ts.html +109 -0
- package/backend/coverage/lcov-report/src/llm-response-parser/llm-response-parser.service.ts.html +808 -0
- package/backend/coverage/lcov-report/src/llm-response-parser/parsing.constants.ts.html +139 -0
- package/backend/coverage/lcov-report/src/llm-responses/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/llm-responses/dto/submit-llm-response.dto.ts.html +172 -0
- package/backend/coverage/lcov-report/src/llm-responses/index.html +146 -0
- package/backend/coverage/lcov-report/src/llm-responses/llm-responses.controller.ts.html +154 -0
- package/backend/coverage/lcov-report/src/llm-responses/llm-responses.module.ts.html +163 -0
- package/backend/coverage/lcov-report/src/llm-responses/llm-responses.service.ts.html +766 -0
- package/backend/coverage/lcov-report/src/main.ts.html +382 -0
- package/backend/coverage/lcov-report/src/orchestration/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/orchestration/dto/orchestration.dto.ts.html +184 -0
- package/backend/coverage/lcov-report/src/orchestration/index.html +191 -0
- package/backend/coverage/lcov-report/src/orchestration/orchestration-fs.service.ts.html +478 -0
- package/backend/coverage/lcov-report/src/orchestration/orchestration-parser.service.ts.html +310 -0
- package/backend/coverage/lcov-report/src/orchestration/orchestration.controller.ts.html +436 -0
- package/backend/coverage/lcov-report/src/orchestration/orchestration.module.ts.html +172 -0
- package/backend/coverage/lcov-report/src/orchestration/orchestration.service.ts.html +1201 -0
- package/backend/coverage/lcov-report/src/orchestration/orchestration.types.ts.html +169 -0
- package/backend/coverage/lcov-report/src/projects/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/projects/dto/project.dto.ts.html +154 -0
- package/backend/coverage/lcov-report/src/projects/index.html +146 -0
- package/backend/coverage/lcov-report/src/projects/projects.controller.ts.html +232 -0
- package/backend/coverage/lcov-report/src/projects/projects.module.ts.html +124 -0
- package/backend/coverage/lcov-report/src/projects/projects.service.ts.html +223 -0
- package/backend/coverage/lcov-report/src/seeding/context-template-seeding.service.ts.html +355 -0
- package/backend/coverage/lcov-report/src/seeding/custom-snippet-seeding.service.ts.html +271 -0
- package/backend/coverage/lcov-report/src/seeding/data/context-templates/default-followup_ad-hoc-focused-context.ts.html +136 -0
- package/backend/coverage/lcov-report/src/seeding/data/context-templates/default-initial_condensed-project-context.ts.html +148 -0
- package/backend/coverage/lcov-report/src/seeding/data/context-templates/default-initial_full-project-context.ts.html +247 -0
- package/backend/coverage/lcov-report/src/seeding/data/context-templates/index.html +191 -0
- package/backend/coverage/lcov-report/src/seeding/data/context-templates/pm-context.ts.html +250 -0
- package/backend/coverage/lcov-report/src/seeding/data/context-templates/pr-description.ts.html +187 -0
- package/backend/coverage/lcov-report/src/seeding/data/context-templates/sample_focused-tree.ts.html +124 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/default_rglob.ts.html +94 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/git-diff.ts.html +94 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/index.html +236 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/rg-exclude.ts.html +94 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/rg-search-glob.ts.html +94 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/rg-search.ts.html +94 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/run-command.ts.html +94 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/tree.ts.html +94 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/usr-adhoc-incl.ts.html +100 -0
- package/backend/coverage/lcov-report/src/seeding/data/custom-snippets/usr-input-incl.ts.html +94 -0
- package/backend/coverage/lcov-report/src/seeding/data/system-prompts/codebase-explorer.ts.html +331 -0
- package/backend/coverage/lcov-report/src/seeding/data/system-prompts/default_multi-file-action-generator-with-requester.ts.html +670 -0
- package/backend/coverage/lcov-report/src/seeding/data/system-prompts/index.html +161 -0
- package/backend/coverage/lcov-report/src/seeding/data/system-prompts/multi-file-action-generator.ts.html +550 -0
- package/backend/coverage/lcov-report/src/seeding/data/system-prompts/packup.ts.html +184 -0
- package/backend/coverage/lcov-report/src/seeding/index.html +176 -0
- package/backend/coverage/lcov-report/src/seeding/seeding.module.ts.html +145 -0
- package/backend/coverage/lcov-report/src/seeding/seeding.service.ts.html +151 -0
- package/backend/coverage/lcov-report/src/seeding/system-prompt-seeding.service.ts.html +289 -0
- package/backend/coverage/lcov-report/src/session-followup/index.html +131 -0
- package/backend/coverage/lcov-report/src/session-followup/session-followup.module.ts.html +130 -0
- package/backend/coverage/lcov-report/src/session-followup/session-followup.service.ts.html +667 -0
- package/backend/coverage/lcov-report/src/session-inputs/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/session-inputs/dto/session-input.dto.ts.html +235 -0
- package/backend/coverage/lcov-report/src/session-inputs/index.html +161 -0
- package/backend/coverage/lcov-report/src/session-inputs/session-input-context.service.ts.html +751 -0
- package/backend/coverage/lcov-report/src/session-inputs/session-inputs.controller.ts.html +337 -0
- package/backend/coverage/lcov-report/src/session-inputs/session-inputs.module.ts.html +202 -0
- package/backend/coverage/lcov-report/src/session-inputs/session-inputs.service.ts.html +1615 -0
- package/backend/coverage/lcov-report/src/session-transfer/index.html +131 -0
- package/backend/coverage/lcov-report/src/session-transfer/session-transfer.module.ts.html +172 -0
- package/backend/coverage/lcov-report/src/session-transfer/session-transfer.service.ts.html +574 -0
- package/backend/coverage/lcov-report/src/sessions/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/sessions/dto/session.dto.ts.html +340 -0
- package/backend/coverage/lcov-report/src/sessions/index.html +146 -0
- package/backend/coverage/lcov-report/src/sessions/sessions.controller.ts.html +457 -0
- package/backend/coverage/lcov-report/src/sessions/sessions.module.ts.html +214 -0
- package/backend/coverage/lcov-report/src/sessions/sessions.service.ts.html +844 -0
- package/backend/coverage/lcov-report/src/system-prompts/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/system-prompts/dto/system-prompt.dto.ts.html +208 -0
- package/backend/coverage/lcov-report/src/system-prompts/index.html +146 -0
- package/backend/coverage/lcov-report/src/system-prompts/system-prompts.controller.ts.html +298 -0
- package/backend/coverage/lcov-report/src/system-prompts/system-prompts.module.ts.html +127 -0
- package/backend/coverage/lcov-report/src/system-prompts/system-prompts.service.ts.html +352 -0
- package/backend/coverage/lcov-report/src/timeout.interceptor.ts.html +178 -0
- package/backend/coverage/lcov-report/src/workspace/dto/index.html +116 -0
- package/backend/coverage/lcov-report/src/workspace/dto/search-workspace.dto.ts.html +193 -0
- package/backend/coverage/lcov-report/src/workspace/index.html +146 -0
- package/backend/coverage/lcov-report/src/workspace/workspace.controller.ts.html +247 -0
- package/backend/coverage/lcov-report/src/workspace/workspace.module.ts.html +121 -0
- package/backend/coverage/lcov-report/src/workspace/workspace.service.ts.html +700 -0
- package/backend/coverage/lcov.info +5492 -0
- package/backend/dist/ai-actions/ai-action-creation.service.d.ts +2 -0
- package/backend/dist/ai-actions/ai-action-creation.service.js +65 -0
- package/backend/dist/ai-actions/ai-action-creation.service.js.map +1 -1
- package/backend/dist/app.module.js +2 -0
- package/backend/dist/app.module.js.map +1 -1
- package/backend/dist/application-state/application-state.service.d.ts +4 -0
- package/backend/dist/application-state/application-state.service.js +25 -0
- package/backend/dist/application-state/application-state.service.js.map +1 -1
- package/backend/dist/context-templates/context-templates.service.d.ts +1 -0
- package/backend/dist/context-templates/context-templates.service.js +3 -0
- package/backend/dist/context-templates/context-templates.service.js.map +1 -1
- package/backend/dist/llm-responses/llm-responses.module.js +4 -1
- package/backend/dist/llm-responses/llm-responses.module.js.map +1 -1
- package/backend/dist/llm-responses/llm-responses.service.d.ts +3 -1
- package/backend/dist/llm-responses/llm-responses.service.js +29 -2
- package/backend/dist/llm-responses/llm-responses.service.js.map +1 -1
- package/backend/dist/orchestration/dto/orchestration.dto.d.ts +15 -0
- package/backend/dist/orchestration/dto/orchestration.dto.js +58 -0
- package/backend/dist/orchestration/dto/orchestration.dto.js.map +1 -0
- package/backend/dist/orchestration/orchestration-fs.service.d.ts +18 -0
- package/backend/dist/orchestration/orchestration-fs.service.js +124 -0
- package/backend/dist/orchestration/orchestration-fs.service.js.map +1 -0
- package/backend/dist/orchestration/orchestration-parser.service.d.ts +16 -0
- package/backend/dist/orchestration/orchestration-parser.service.js +78 -0
- package/backend/dist/orchestration/orchestration-parser.service.js.map +1 -0
- package/backend/dist/orchestration/orchestration.controller.d.ts +28 -0
- package/backend/dist/orchestration/orchestration.controller.js +158 -0
- package/backend/dist/orchestration/orchestration.controller.js.map +1 -0
- package/backend/dist/orchestration/orchestration.module.d.ts +2 -0
- package/backend/dist/orchestration/orchestration.module.js +43 -0
- package/backend/dist/orchestration/orchestration.module.js.map +1 -0
- package/backend/dist/orchestration/orchestration.service.d.ts +38 -0
- package/backend/dist/orchestration/orchestration.service.js +301 -0
- package/backend/dist/orchestration/orchestration.service.js.map +1 -0
- package/backend/dist/orchestration/orchestration.types.d.ts +27 -0
- package/backend/dist/orchestration/orchestration.types.js +20 -0
- package/backend/dist/orchestration/orchestration.types.js.map +1 -0
- package/backend/dist/session-inputs/session-inputs.module.js +2 -0
- package/backend/dist/session-inputs/session-inputs.module.js.map +1 -1
- package/backend/dist/session-inputs/session-inputs.service.d.ts +3 -1
- package/backend/dist/session-inputs/session-inputs.service.js +13 -2
- package/backend/dist/session-inputs/session-inputs.service.js.map +1 -1
- package/backend/dist/tsconfig.build.tsbuildinfo +1 -1
- package/backend/orchestration-test-2.txt +1 -0
- package/backend/orchestration-test.txt +1 -0
- package/backend/package.json +1 -1
- package/orchestration-test.txt +3 -0
- package/package.json +1 -1
package/backend/coverage/lcov-report/src/context-generation/context-generation.service.ts.html
ADDED
|
@@ -0,0 +1,1348 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/context-generation/context-generation.service.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/context-generation</a> context-generation.service.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/164</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">0% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>0/45</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">0% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>0/19</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/160</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></td><td class="line-coverage quiet"><span class="cline-any cline-no"> </span>
|
|
488
|
+
<span class="cline-any cline-neutral"> </span>
|
|
489
|
+
<span class="cline-any cline-neutral"> </span>
|
|
490
|
+
<span class="cline-any cline-neutral"> </span>
|
|
491
|
+
<span class="cline-any cline-neutral"> </span>
|
|
492
|
+
<span class="cline-any cline-neutral"> </span>
|
|
493
|
+
<span class="cline-any cline-no"> </span>
|
|
494
|
+
<span class="cline-any cline-no"> </span>
|
|
495
|
+
<span class="cline-any cline-no"> </span>
|
|
496
|
+
<span class="cline-any cline-no"> </span>
|
|
497
|
+
<span class="cline-any cline-no"> </span>
|
|
498
|
+
<span class="cline-any cline-no"> </span>
|
|
499
|
+
<span class="cline-any cline-no"> </span>
|
|
500
|
+
<span class="cline-any cline-no"> </span>
|
|
501
|
+
<span class="cline-any cline-no"> </span>
|
|
502
|
+
<span class="cline-any cline-neutral"> </span>
|
|
503
|
+
<span class="cline-any cline-neutral"> </span>
|
|
504
|
+
<span class="cline-any cline-no"> </span>
|
|
505
|
+
<span class="cline-any cline-no"> </span>
|
|
506
|
+
<span class="cline-any cline-neutral"> </span>
|
|
507
|
+
<span class="cline-any cline-no"> </span>
|
|
508
|
+
<span class="cline-any cline-neutral"> </span>
|
|
509
|
+
<span class="cline-any cline-neutral"> </span>
|
|
510
|
+
<span class="cline-any cline-no"> </span>
|
|
511
|
+
<span class="cline-any cline-neutral"> </span>
|
|
512
|
+
<span class="cline-any cline-neutral"> </span>
|
|
513
|
+
<span class="cline-any cline-neutral"> </span>
|
|
514
|
+
<span class="cline-any cline-no"> </span>
|
|
515
|
+
<span class="cline-any cline-neutral"> </span>
|
|
516
|
+
<span class="cline-any cline-no"> </span>
|
|
517
|
+
<span class="cline-any cline-neutral"> </span>
|
|
518
|
+
<span class="cline-any cline-neutral"> </span>
|
|
519
|
+
<span class="cline-any cline-neutral"> </span>
|
|
520
|
+
<span class="cline-any cline-neutral"> </span>
|
|
521
|
+
<span class="cline-any cline-no"> </span>
|
|
522
|
+
<span class="cline-any cline-neutral"> </span>
|
|
523
|
+
<span class="cline-any cline-neutral"> </span>
|
|
524
|
+
<span class="cline-any cline-neutral"> </span>
|
|
525
|
+
<span class="cline-any cline-neutral"> </span>
|
|
526
|
+
<span class="cline-any cline-neutral"> </span>
|
|
527
|
+
<span class="cline-any cline-neutral"> </span>
|
|
528
|
+
<span class="cline-any cline-neutral"> </span>
|
|
529
|
+
<span class="cline-any cline-neutral"> </span>
|
|
530
|
+
<span class="cline-any cline-neutral"> </span>
|
|
531
|
+
<span class="cline-any cline-neutral"> </span>
|
|
532
|
+
<span class="cline-any cline-neutral"> </span>
|
|
533
|
+
<span class="cline-any cline-neutral"> </span>
|
|
534
|
+
<span class="cline-any cline-neutral"> </span>
|
|
535
|
+
<span class="cline-any cline-neutral"> </span>
|
|
536
|
+
<span class="cline-any cline-neutral"> </span>
|
|
537
|
+
<span class="cline-any cline-neutral"> </span>
|
|
538
|
+
<span class="cline-any cline-no"> </span>
|
|
539
|
+
<span class="cline-any cline-no"> </span>
|
|
540
|
+
<span class="cline-any cline-no"> </span>
|
|
541
|
+
<span class="cline-any cline-neutral"> </span>
|
|
542
|
+
<span class="cline-any cline-neutral"> </span>
|
|
543
|
+
<span class="cline-any cline-no"> </span>
|
|
544
|
+
<span class="cline-any cline-no"> </span>
|
|
545
|
+
<span class="cline-any cline-no"> </span>
|
|
546
|
+
<span class="cline-any cline-no"> </span>
|
|
547
|
+
<span class="cline-any cline-neutral"> </span>
|
|
548
|
+
<span class="cline-any cline-no"> </span>
|
|
549
|
+
<span class="cline-any cline-neutral"> </span>
|
|
550
|
+
<span class="cline-any cline-neutral"> </span>
|
|
551
|
+
<span class="cline-any cline-neutral"> </span>
|
|
552
|
+
<span class="cline-any cline-neutral"> </span>
|
|
553
|
+
<span class="cline-any cline-neutral"> </span>
|
|
554
|
+
<span class="cline-any cline-neutral"> </span>
|
|
555
|
+
<span class="cline-any cline-neutral"> </span>
|
|
556
|
+
<span class="cline-any cline-neutral"> </span>
|
|
557
|
+
<span class="cline-any cline-neutral"> </span>
|
|
558
|
+
<span class="cline-any cline-neutral"> </span>
|
|
559
|
+
<span class="cline-any cline-neutral"> </span>
|
|
560
|
+
<span class="cline-any cline-no"> </span>
|
|
561
|
+
<span class="cline-any cline-neutral"> </span>
|
|
562
|
+
<span class="cline-any cline-neutral"> </span>
|
|
563
|
+
<span class="cline-any cline-neutral"> </span>
|
|
564
|
+
<span class="cline-any cline-no"> </span>
|
|
565
|
+
<span class="cline-any cline-neutral"> </span>
|
|
566
|
+
<span class="cline-any cline-neutral"> </span>
|
|
567
|
+
<span class="cline-any cline-neutral"> </span>
|
|
568
|
+
<span class="cline-any cline-no"> </span>
|
|
569
|
+
<span class="cline-any cline-neutral"> </span>
|
|
570
|
+
<span class="cline-any cline-no"> </span>
|
|
571
|
+
<span class="cline-any cline-no"> </span>
|
|
572
|
+
<span class="cline-any cline-no"> </span>
|
|
573
|
+
<span class="cline-any cline-neutral"> </span>
|
|
574
|
+
<span class="cline-any cline-neutral"> </span>
|
|
575
|
+
<span class="cline-any cline-neutral"> </span>
|
|
576
|
+
<span class="cline-any cline-no"> </span>
|
|
577
|
+
<span class="cline-any cline-neutral"> </span>
|
|
578
|
+
<span class="cline-any cline-no"> </span>
|
|
579
|
+
<span class="cline-any cline-neutral"> </span>
|
|
580
|
+
<span class="cline-any cline-neutral"> </span>
|
|
581
|
+
<span class="cline-any cline-no"> </span>
|
|
582
|
+
<span class="cline-any cline-neutral"> </span>
|
|
583
|
+
<span class="cline-any cline-neutral"> </span>
|
|
584
|
+
<span class="cline-any cline-neutral"> </span>
|
|
585
|
+
<span class="cline-any cline-neutral"> </span>
|
|
586
|
+
<span class="cline-any cline-neutral"> </span>
|
|
587
|
+
<span class="cline-any cline-neutral"> </span>
|
|
588
|
+
<span class="cline-any cline-neutral"> </span>
|
|
589
|
+
<span class="cline-any cline-neutral"> </span>
|
|
590
|
+
<span class="cline-any cline-neutral"> </span>
|
|
591
|
+
<span class="cline-any cline-neutral"> </span>
|
|
592
|
+
<span class="cline-any cline-no"> </span>
|
|
593
|
+
<span class="cline-any cline-no"> </span>
|
|
594
|
+
<span class="cline-any cline-no"> </span>
|
|
595
|
+
<span class="cline-any cline-neutral"> </span>
|
|
596
|
+
<span class="cline-any cline-neutral"> </span>
|
|
597
|
+
<span class="cline-any cline-neutral"> </span>
|
|
598
|
+
<span class="cline-any cline-no"> </span>
|
|
599
|
+
<span class="cline-any cline-neutral"> </span>
|
|
600
|
+
<span class="cline-any cline-no"> </span>
|
|
601
|
+
<span class="cline-any cline-no"> </span>
|
|
602
|
+
<span class="cline-any cline-no"> </span>
|
|
603
|
+
<span class="cline-any cline-neutral"> </span>
|
|
604
|
+
<span class="cline-any cline-neutral"> </span>
|
|
605
|
+
<span class="cline-any cline-neutral"> </span>
|
|
606
|
+
<span class="cline-any cline-no"> </span>
|
|
607
|
+
<span class="cline-any cline-neutral"> </span>
|
|
608
|
+
<span class="cline-any cline-neutral"> </span>
|
|
609
|
+
<span class="cline-any cline-neutral"> </span>
|
|
610
|
+
<span class="cline-any cline-no"> </span>
|
|
611
|
+
<span class="cline-any cline-no"> </span>
|
|
612
|
+
<span class="cline-any cline-no"> </span>
|
|
613
|
+
<span class="cline-any cline-no"> </span>
|
|
614
|
+
<span class="cline-any cline-neutral"> </span>
|
|
615
|
+
<span class="cline-any cline-no"> </span>
|
|
616
|
+
<span class="cline-any cline-no"> </span>
|
|
617
|
+
<span class="cline-any cline-neutral"> </span>
|
|
618
|
+
<span class="cline-any cline-no"> </span>
|
|
619
|
+
<span class="cline-any cline-neutral"> </span>
|
|
620
|
+
<span class="cline-any cline-no"> </span>
|
|
621
|
+
<span class="cline-any cline-neutral"> </span>
|
|
622
|
+
<span class="cline-any cline-no"> </span>
|
|
623
|
+
<span class="cline-any cline-neutral"> </span>
|
|
624
|
+
<span class="cline-any cline-neutral"> </span>
|
|
625
|
+
<span class="cline-any cline-neutral"> </span>
|
|
626
|
+
<span class="cline-any cline-neutral"> </span>
|
|
627
|
+
<span class="cline-any cline-no"> </span>
|
|
628
|
+
<span class="cline-any cline-no"> </span>
|
|
629
|
+
<span class="cline-any cline-no"> </span>
|
|
630
|
+
<span class="cline-any cline-no"> </span>
|
|
631
|
+
<span class="cline-any cline-neutral"> </span>
|
|
632
|
+
<span class="cline-any cline-no"> </span>
|
|
633
|
+
<span class="cline-any cline-no"> </span>
|
|
634
|
+
<span class="cline-any cline-neutral"> </span>
|
|
635
|
+
<span class="cline-any cline-neutral"> </span>
|
|
636
|
+
<span class="cline-any cline-no"> </span>
|
|
637
|
+
<span class="cline-any cline-neutral"> </span>
|
|
638
|
+
<span class="cline-any cline-no"> </span>
|
|
639
|
+
<span class="cline-any cline-neutral"> </span>
|
|
640
|
+
<span class="cline-any cline-neutral"> </span>
|
|
641
|
+
<span class="cline-any cline-no"> </span>
|
|
642
|
+
<span class="cline-any cline-neutral"> </span>
|
|
643
|
+
<span class="cline-any cline-neutral"> </span>
|
|
644
|
+
<span class="cline-any cline-neutral"> </span>
|
|
645
|
+
<span class="cline-any cline-neutral"> </span>
|
|
646
|
+
<span class="cline-any cline-no"> </span>
|
|
647
|
+
<span class="cline-any cline-no"> </span>
|
|
648
|
+
<span class="cline-any cline-no"> </span>
|
|
649
|
+
<span class="cline-any cline-neutral"> </span>
|
|
650
|
+
<span class="cline-any cline-no"> </span>
|
|
651
|
+
<span class="cline-any cline-neutral"> </span>
|
|
652
|
+
<span class="cline-any cline-no"> </span>
|
|
653
|
+
<span class="cline-any cline-no"> </span>
|
|
654
|
+
<span class="cline-any cline-no"> </span>
|
|
655
|
+
<span class="cline-any cline-neutral"> </span>
|
|
656
|
+
<span class="cline-any cline-no"> </span>
|
|
657
|
+
<span class="cline-any cline-neutral"> </span>
|
|
658
|
+
<span class="cline-any cline-neutral"> </span>
|
|
659
|
+
<span class="cline-any cline-no"> </span>
|
|
660
|
+
<span class="cline-any cline-neutral"> </span>
|
|
661
|
+
<span class="cline-any cline-neutral"> </span>
|
|
662
|
+
<span class="cline-any cline-neutral"> </span>
|
|
663
|
+
<span class="cline-any cline-neutral"> </span>
|
|
664
|
+
<span class="cline-any cline-no"> </span>
|
|
665
|
+
<span class="cline-any cline-no"> </span>
|
|
666
|
+
<span class="cline-any cline-neutral"> </span>
|
|
667
|
+
<span class="cline-any cline-neutral"> </span>
|
|
668
|
+
<span class="cline-any cline-neutral"> </span>
|
|
669
|
+
<span class="cline-any cline-neutral"> </span>
|
|
670
|
+
<span class="cline-any cline-no"> </span>
|
|
671
|
+
<span class="cline-any cline-no"> </span>
|
|
672
|
+
<span class="cline-any cline-neutral"> </span>
|
|
673
|
+
<span class="cline-any cline-neutral"> </span>
|
|
674
|
+
<span class="cline-any cline-neutral"> </span>
|
|
675
|
+
<span class="cline-any cline-neutral"> </span>
|
|
676
|
+
<span class="cline-any cline-no"> </span>
|
|
677
|
+
<span class="cline-any cline-neutral"> </span>
|
|
678
|
+
<span class="cline-any cline-no"> </span>
|
|
679
|
+
<span class="cline-any cline-neutral"> </span>
|
|
680
|
+
<span class="cline-any cline-neutral"> </span>
|
|
681
|
+
<span class="cline-any cline-no"> </span>
|
|
682
|
+
<span class="cline-any cline-neutral"> </span>
|
|
683
|
+
<span class="cline-any cline-neutral"> </span>
|
|
684
|
+
<span class="cline-any cline-neutral"> </span>
|
|
685
|
+
<span class="cline-any cline-neutral"> </span>
|
|
686
|
+
<span class="cline-any cline-no"> </span>
|
|
687
|
+
<span class="cline-any cline-no"> </span>
|
|
688
|
+
<span class="cline-any cline-no"> </span>
|
|
689
|
+
<span class="cline-any cline-no"> </span>
|
|
690
|
+
<span class="cline-any cline-no"> </span>
|
|
691
|
+
<span class="cline-any cline-neutral"> </span>
|
|
692
|
+
<span class="cline-any cline-neutral"> </span>
|
|
693
|
+
<span class="cline-any cline-neutral"> </span>
|
|
694
|
+
<span class="cline-any cline-neutral"> </span>
|
|
695
|
+
<span class="cline-any cline-no"> </span>
|
|
696
|
+
<span class="cline-any cline-neutral"> </span>
|
|
697
|
+
<span class="cline-any cline-no"> </span>
|
|
698
|
+
<span class="cline-any cline-no"> </span>
|
|
699
|
+
<span class="cline-any cline-no"> </span>
|
|
700
|
+
<span class="cline-any cline-neutral"> </span>
|
|
701
|
+
<span class="cline-any cline-no"> </span>
|
|
702
|
+
<span class="cline-any cline-no"> </span>
|
|
703
|
+
<span class="cline-any cline-neutral"> </span>
|
|
704
|
+
<span class="cline-any cline-neutral"> </span>
|
|
705
|
+
<span class="cline-any cline-no"> </span>
|
|
706
|
+
<span class="cline-any cline-neutral"> </span>
|
|
707
|
+
<span class="cline-any cline-no"> </span>
|
|
708
|
+
<span class="cline-any cline-neutral"> </span>
|
|
709
|
+
<span class="cline-any cline-neutral"> </span>
|
|
710
|
+
<span class="cline-any cline-neutral"> </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-no"> </span>
|
|
717
|
+
<span class="cline-any cline-no"> </span>
|
|
718
|
+
<span class="cline-any cline-no"> </span>
|
|
719
|
+
<span class="cline-any cline-no"> </span>
|
|
720
|
+
<span class="cline-any cline-no"> </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-no"> </span>
|
|
726
|
+
<span class="cline-any cline-neutral"> </span>
|
|
727
|
+
<span class="cline-any cline-no"> </span>
|
|
728
|
+
<span class="cline-any cline-no"> </span>
|
|
729
|
+
<span class="cline-any cline-no"> </span>
|
|
730
|
+
<span class="cline-any cline-neutral"> </span>
|
|
731
|
+
<span class="cline-any cline-no"> </span>
|
|
732
|
+
<span class="cline-any cline-neutral"> </span>
|
|
733
|
+
<span class="cline-any cline-no"> </span>
|
|
734
|
+
<span class="cline-any cline-neutral"> </span>
|
|
735
|
+
<span class="cline-any cline-no"> </span>
|
|
736
|
+
<span class="cline-any cline-no"> </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-neutral"> </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-neutral"> </span>
|
|
747
|
+
<span class="cline-any cline-neutral"> </span>
|
|
748
|
+
<span class="cline-any cline-neutral"> </span>
|
|
749
|
+
<span class="cline-any cline-neutral"> </span>
|
|
750
|
+
<span class="cline-any cline-neutral"> </span>
|
|
751
|
+
<span class="cline-any cline-neutral"> </span>
|
|
752
|
+
<span class="cline-any cline-no"> </span>
|
|
753
|
+
<span class="cline-any cline-no"> </span>
|
|
754
|
+
<span class="cline-any cline-neutral"> </span>
|
|
755
|
+
<span class="cline-any cline-neutral"> </span>
|
|
756
|
+
<span class="cline-any cline-no"> </span>
|
|
757
|
+
<span class="cline-any cline-neutral"> </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-neutral"> </span>
|
|
763
|
+
<span class="cline-any cline-neutral"> </span>
|
|
764
|
+
<span class="cline-any cline-neutral"> </span>
|
|
765
|
+
<span class="cline-any cline-neutral"> </span>
|
|
766
|
+
<span class="cline-any cline-no"> </span>
|
|
767
|
+
<span class="cline-any cline-neutral"> </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-neutral"> </span>
|
|
772
|
+
<span class="cline-any cline-no"> </span>
|
|
773
|
+
<span class="cline-any cline-no"> </span>
|
|
774
|
+
<span class="cline-any cline-neutral"> </span>
|
|
775
|
+
<span class="cline-any cline-neutral"> </span>
|
|
776
|
+
<span class="cline-any cline-no"> </span>
|
|
777
|
+
<span class="cline-any cline-neutral"> </span>
|
|
778
|
+
<span class="cline-any cline-no"> </span>
|
|
779
|
+
<span class="cline-any cline-neutral"> </span>
|
|
780
|
+
<span class="cline-any cline-neutral"> </span>
|
|
781
|
+
<span class="cline-any cline-neutral"> </span>
|
|
782
|
+
<span class="cline-any cline-no"> </span>
|
|
783
|
+
<span class="cline-any cline-neutral"> </span>
|
|
784
|
+
<span class="cline-any cline-neutral"> </span>
|
|
785
|
+
<span class="cline-any cline-neutral"> </span>
|
|
786
|
+
<span class="cline-any cline-neutral"> </span>
|
|
787
|
+
<span class="cline-any cline-neutral"> </span>
|
|
788
|
+
<span class="cline-any cline-neutral"> </span>
|
|
789
|
+
<span class="cline-any cline-no"> </span>
|
|
790
|
+
<span class="cline-any cline-no"> </span>
|
|
791
|
+
<span class="cline-any cline-neutral"> </span>
|
|
792
|
+
<span class="cline-any cline-neutral"> </span>
|
|
793
|
+
<span class="cline-any cline-no"> </span>
|
|
794
|
+
<span class="cline-any cline-no"> </span>
|
|
795
|
+
<span class="cline-any cline-no"> </span>
|
|
796
|
+
<span class="cline-any cline-neutral"> </span>
|
|
797
|
+
<span class="cline-any cline-neutral"> </span>
|
|
798
|
+
<span class="cline-any cline-neutral"> </span>
|
|
799
|
+
<span class="cline-any cline-neutral"> </span>
|
|
800
|
+
<span class="cline-any cline-no"> </span>
|
|
801
|
+
<span class="cline-any cline-no"> </span>
|
|
802
|
+
<span class="cline-any cline-neutral"> </span>
|
|
803
|
+
<span class="cline-any cline-neutral"> </span>
|
|
804
|
+
<span class="cline-any cline-no"> </span>
|
|
805
|
+
<span class="cline-any cline-neutral"> </span>
|
|
806
|
+
<span class="cline-any cline-no"> </span>
|
|
807
|
+
<span class="cline-any cline-neutral"> </span>
|
|
808
|
+
<span class="cline-any cline-no"> </span>
|
|
809
|
+
<span class="cline-any cline-no"> </span>
|
|
810
|
+
<span class="cline-any cline-neutral"> </span>
|
|
811
|
+
<span class="cline-any cline-neutral"> </span>
|
|
812
|
+
<span class="cline-any cline-no"> </span>
|
|
813
|
+
<span class="cline-any cline-neutral"> </span>
|
|
814
|
+
<span class="cline-any cline-no"> </span>
|
|
815
|
+
<span class="cline-any cline-neutral"> </span>
|
|
816
|
+
<span class="cline-any cline-neutral"> </span>
|
|
817
|
+
<span class="cline-any cline-neutral"> </span>
|
|
818
|
+
<span class="cline-any cline-no"> </span>
|
|
819
|
+
<span class="cline-any cline-neutral"> </span>
|
|
820
|
+
<span class="cline-any cline-neutral"> </span>
|
|
821
|
+
<span class="cline-any cline-neutral"> </span>
|
|
822
|
+
<span class="cline-any cline-neutral"> </span>
|
|
823
|
+
<span class="cline-any cline-neutral"> </span>
|
|
824
|
+
<span class="cline-any cline-neutral"> </span>
|
|
825
|
+
<span class="cline-any cline-neutral"> </span>
|
|
826
|
+
<span class="cline-any cline-no"> </span>
|
|
827
|
+
<span class="cline-any cline-no"> </span>
|
|
828
|
+
<span class="cline-any cline-neutral"> </span>
|
|
829
|
+
<span class="cline-any cline-neutral"> </span>
|
|
830
|
+
<span class="cline-any cline-no"> </span>
|
|
831
|
+
<span class="cline-any cline-neutral"> </span>
|
|
832
|
+
<span class="cline-any cline-neutral"> </span>
|
|
833
|
+
<span class="cline-any cline-no"> </span>
|
|
834
|
+
<span class="cline-any cline-neutral"> </span>
|
|
835
|
+
<span class="cline-any cline-no"> </span>
|
|
836
|
+
<span class="cline-any cline-no"> </span>
|
|
837
|
+
<span class="cline-any cline-neutral"> </span>
|
|
838
|
+
<span class="cline-any cline-neutral"> </span>
|
|
839
|
+
<span class="cline-any cline-no"> </span>
|
|
840
|
+
<span class="cline-any cline-neutral"> </span>
|
|
841
|
+
<span class="cline-any cline-neutral"> </span>
|
|
842
|
+
<span class="cline-any cline-neutral"> </span>
|
|
843
|
+
<span class="cline-any cline-no"> </span>
|
|
844
|
+
<span class="cline-any cline-neutral"> </span>
|
|
845
|
+
<span class="cline-any cline-no"> </span>
|
|
846
|
+
<span class="cline-any cline-neutral"> </span>
|
|
847
|
+
<span class="cline-any cline-neutral"> </span>
|
|
848
|
+
<span class="cline-any cline-no"> </span>
|
|
849
|
+
<span class="cline-any cline-no"> </span>
|
|
850
|
+
<span class="cline-any cline-neutral"> </span>
|
|
851
|
+
<span class="cline-any cline-neutral"> </span>
|
|
852
|
+
<span class="cline-any cline-no"> </span>
|
|
853
|
+
<span class="cline-any cline-neutral"> </span>
|
|
854
|
+
<span class="cline-any cline-neutral"> </span>
|
|
855
|
+
<span class="cline-any cline-neutral"> </span>
|
|
856
|
+
<span class="cline-any cline-no"> </span>
|
|
857
|
+
<span class="cline-any cline-neutral"> </span>
|
|
858
|
+
<span class="cline-any cline-neutral"> </span>
|
|
859
|
+
<span class="cline-any cline-no"> </span>
|
|
860
|
+
<span class="cline-any cline-neutral"> </span>
|
|
861
|
+
<span class="cline-any cline-neutral"> </span>
|
|
862
|
+
<span class="cline-any cline-neutral"> </span>
|
|
863
|
+
<span class="cline-any cline-neutral"> </span>
|
|
864
|
+
<span class="cline-any cline-neutral"> </span>
|
|
865
|
+
<span class="cline-any cline-no"> </span>
|
|
866
|
+
<span class="cline-any cline-neutral"> </span>
|
|
867
|
+
<span class="cline-any cline-no"> </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-no"> </span>
|
|
881
|
+
<span class="cline-any cline-no"> </span>
|
|
882
|
+
<span class="cline-any cline-neutral"> </span>
|
|
883
|
+
<span class="cline-any cline-neutral"> </span>
|
|
884
|
+
<span class="cline-any cline-neutral"> </span>
|
|
885
|
+
<span class="cline-any cline-neutral"> </span>
|
|
886
|
+
<span class="cline-any cline-neutral"> </span>
|
|
887
|
+
<span class="cline-any cline-neutral"> </span>
|
|
888
|
+
<span class="cline-any cline-neutral"> </span>
|
|
889
|
+
<span class="cline-any cline-neutral"> </span>
|
|
890
|
+
<span class="cline-any cline-neutral"> </span>
|
|
891
|
+
<span class="cline-any cline-no"> </span>
|
|
892
|
+
<span class="cline-any cline-no"> </span>
|
|
893
|
+
<span class="cline-any cline-neutral"> </span>
|
|
894
|
+
<span class="cline-any cline-no"> </span>
|
|
895
|
+
<span class="cline-any cline-neutral"> </span>
|
|
896
|
+
<span class="cline-any cline-neutral"> </span>
|
|
897
|
+
<span class="cline-any cline-neutral"> </span>
|
|
898
|
+
<span class="cline-any cline-no"> </span>
|
|
899
|
+
<span class="cline-any cline-neutral"> </span>
|
|
900
|
+
<span class="cline-any cline-no"> </span>
|
|
901
|
+
<span class="cline-any cline-neutral"> </span>
|
|
902
|
+
<span class="cline-any cline-neutral"> </span>
|
|
903
|
+
<span class="cline-any cline-neutral"> </span>
|
|
904
|
+
<span class="cline-any cline-no"> </span>
|
|
905
|
+
<span class="cline-any cline-neutral"> </span>
|
|
906
|
+
<span class="cline-any cline-neutral"> </span>
|
|
907
|
+
<span class="cline-any cline-neutral"> </span>
|
|
908
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" >import {</span>
|
|
909
|
+
Injectable,
|
|
910
|
+
Logger,
|
|
911
|
+
BadRequestException,
|
|
912
|
+
NotFoundException,
|
|
913
|
+
} from '@nestjs/common';
|
|
914
|
+
<span class="cstat-no" title="statement not covered" >import { Eta } from 'eta';</span>
|
|
915
|
+
<span class="cstat-no" title="statement not covered" >import * as fs from 'fs/promises';</span>
|
|
916
|
+
<span class="cstat-no" title="statement not covered" >import { glob } from 'glob';</span>
|
|
917
|
+
<span class="cstat-no" title="statement not covered" >import * as path from 'path';</span>
|
|
918
|
+
<span class="cstat-no" title="statement not covered" >import { exec, ExecOptions } from 'child_process';</span>
|
|
919
|
+
<span class="cstat-no" title="statement not covered" >import { InjectRepository } from '@nestjs/typeorm';</span>
|
|
920
|
+
<span class="cstat-no" title="statement not covered" >import { ContextTemplate } from '../core-entities';</span>
|
|
921
|
+
<span class="cstat-no" title="statement not covered" >import { Repository } from 'typeorm';</span>
|
|
922
|
+
<span class="cstat-no" title="statement not covered" >import { TemplateType } from '../core-entities/context-template.entity';</span>
|
|
923
|
+
|
|
924
|
+
@Injectable()
|
|
925
|
+
export class <span class="cstat-no" title="statement not covered" ><span class="cstat-no" title="statement not covered" >ContextGenerationService<span class="cstat-no" title="statement not covered" > </span>{</span></span>
|
|
926
|
+
private readonly <span class="cstat-no" title="statement not covered" >logger = new Logger(ContextGenerationService.name);</span>
|
|
927
|
+
private eta: Eta;
|
|
928
|
+
private <span class="cstat-no" title="statement not covered" >projectRoot: string =</span>
|
|
929
|
+
process.env.REPOBURG_PROJECT_PATH || process.cwd();
|
|
930
|
+
private templateHelpers: { [key: string]: (...args: any[]) => Promise<any> };
|
|
931
|
+
private <span class="cstat-no" title="statement not covered" >partialCache = new Map<string, ContextTemplate | null>();</span>
|
|
932
|
+
|
|
933
|
+
<span class="fstat-no" title="function not covered" > constructor(</span>
|
|
934
|
+
@InjectRepository(ContextTemplate)
|
|
935
|
+
private <span class="cstat-no" title="statement not covered" >contextTemplatesRepository: R</span>epository<ContextTemplate>,
|
|
936
|
+
) {
|
|
937
|
+
<span class="cstat-no" title="statement not covered" > this.eta = new Eta({</span>
|
|
938
|
+
views: this.projectRoot, // Using 'views' path as a security measure for includes/layouts
|
|
939
|
+
useWith: true, // Allows using properties of data object as local variables
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
<span class="cstat-no" title="statement not covered" > this.templateHelpers = {</span>
|
|
943
|
+
readFile: this.secureReadFile.bind(this),
|
|
944
|
+
readDir: this.secureReadDir.bind(this),
|
|
945
|
+
glob: this.secureGlob.bind(this),
|
|
946
|
+
tree: this.secureTree.bind(this),
|
|
947
|
+
ripGrep: this.secureRipGrep.bind(this),
|
|
948
|
+
gitDiff: this.secureGitDiff.bind(this),
|
|
949
|
+
runCommand: this.runCommand.bind(this),
|
|
950
|
+
include: this.include.bind(this),
|
|
951
|
+
fetchFileContent: this.fetchFileContent.bind(this),
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
private <span class="fstat-no" title="function not covered" >execPromise(</span>
|
|
956
|
+
command: string,
|
|
957
|
+
options: ExecOptions,
|
|
958
|
+
): Promise<{ stdout: string; stderr: string }> {
|
|
959
|
+
<span class="cstat-no" title="statement not covered" > return new Promise(<span class="fstat-no" title="function not covered" >(r</span>esolve, reject) => {</span>
|
|
960
|
+
<span class="cstat-no" title="statement not covered" > exec(command, options, <span class="fstat-no" title="function not covered" >(e</span>rror, stdout, stderr) => {</span>
|
|
961
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error) {</span>
|
|
962
|
+
// Attach stdout and stderr to the error object for more context in catch block.
|
|
963
|
+
// This mirrors the behavior of the promisified exec.
|
|
964
|
+
<span class="cstat-no" title="statement not covered" > error['stdout'] = stdout;</span>
|
|
965
|
+
<span class="cstat-no" title="statement not covered" > error['stderr'] = stderr;</span>
|
|
966
|
+
<span class="cstat-no" title="statement not covered" > reject(error);</span>
|
|
967
|
+
<span class="cstat-no" title="statement not covered" > return;</span>
|
|
968
|
+
}
|
|
969
|
+
<span class="cstat-no" title="statement not covered" > resolve({ stdout, stderr });</span>
|
|
970
|
+
});
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Helper function to resolve the command path.
|
|
976
|
+
* Tries to find the executable in the local `bin` directory first.
|
|
977
|
+
* The path is resolved relative to this file's location, which works for both `src` and `dist`.
|
|
978
|
+
*/
|
|
979
|
+
private <span class="fstat-no" title="function not covered" >async </span>getCommandPath(commandName: string): Promise<string> {
|
|
980
|
+
// Check if running from the compiled 'dist' directory
|
|
981
|
+
const inDist = <span class="cstat-no" title="statement not covered" >__dirname.includes(path.join('backend', 'dist'));</span>
|
|
982
|
+
|
|
983
|
+
// In 'dist', bin is a sibling: `dist/context-generation` -> `dist/bin`
|
|
984
|
+
// In 'src', bin is in the parent: `src/context-generation` -> `../bin`
|
|
985
|
+
const relativePath = <span class="cstat-no" title="statement not covered" >inDist</span>
|
|
986
|
+
? path.join(__dirname, '..', 'bin', commandName)
|
|
987
|
+
: path.join(__dirname, '..', '..', 'src', 'bin', commandName);
|
|
988
|
+
|
|
989
|
+
const bundledPath = <span class="cstat-no" title="statement not covered" >path.resolve(relativePath);</span>
|
|
990
|
+
|
|
991
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
992
|
+
<span class="cstat-no" title="statement not covered" > await fs.access(bundledPath, fs.constants.X_OK);</span>
|
|
993
|
+
<span class="cstat-no" title="statement not covered" > this.logger.log(</span>
|
|
994
|
+
`Using bundled executable for '${commandName}' at: ${bundledPath}`,
|
|
995
|
+
);
|
|
996
|
+
// Return the absolute, quoted path to be safe.
|
|
997
|
+
<span class="cstat-no" title="statement not covered" > return `'${bundledPath}'`;</span>
|
|
998
|
+
} catch (error) {
|
|
999
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1000
|
+
`Bundled executable for '${commandName}' not found or not executable at '${bundledPath}'. Falling back to system PATH.`,
|
|
1001
|
+
);
|
|
1002
|
+
<span class="cstat-no" title="statement not covered" > return commandName; </span>// Fallback to system command
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Resolves a given path against the project root and ensures it does not traverse outside.
|
|
1008
|
+
* @param unsafePath The user-provided path.
|
|
1009
|
+
* @returns A validated, absolute path.
|
|
1010
|
+
* @throws BadRequestException if path traversal is detected.
|
|
1011
|
+
*/
|
|
1012
|
+
private <span class="fstat-no" title="function not covered" >resolveAndValidatePath(</span>unsafePath: string): string {
|
|
1013
|
+
const normalizedPath = <span class="cstat-no" title="statement not covered" >path.normalize(unsafePath);</span>
|
|
1014
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (path.isAbsolute(normalizedPath)) {</span>
|
|
1015
|
+
<span class="cstat-no" title="statement not covered" > throw new BadRequestException(</span>
|
|
1016
|
+
`Absolute paths are not allowed: ${unsafePath}`,
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
const resolvedPath = <span class="cstat-no" title="statement not covered" >path.resolve(this.projectRoot, normalizedPath);</span>
|
|
1020
|
+
|
|
1021
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!resolvedPath.startsWith(this.projectRoot)) {</span>
|
|
1022
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(`Path traversal attempt detected: ${unsafePath}`);</span>
|
|
1023
|
+
<span class="cstat-no" title="statement not covered" > throw new BadRequestException(</span>
|
|
1024
|
+
`Path traversal is not allowed. Access denied for path: ${unsafePath}`,
|
|
1025
|
+
);
|
|
1026
|
+
}
|
|
1027
|
+
<span class="cstat-no" title="statement not covered" > return resolvedPath;</span>
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
public <span class="fstat-no" title="function not covered" >async </span>secureReadFile(filePath: string): Promise<string> {
|
|
1031
|
+
const safePath = <span class="cstat-no" title="statement not covered" >this.resolveAndValidatePath(filePath);</span>
|
|
1032
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1033
|
+
const content = <span class="cstat-no" title="statement not covered" >await fs.readFile(safePath, 'utf8');</span>
|
|
1034
|
+
<span class="cstat-no" title="statement not covered" > return `// File: ${filePath}\n\`\`\`\n${content}\n\`\`\``;</span>
|
|
1035
|
+
} catch (error) {
|
|
1036
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.code === 'ENOENT') {</span>
|
|
1037
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(`File not found in template render: ${safePath}`);</span>
|
|
1038
|
+
// Return a user-friendly error message within the template
|
|
1039
|
+
<span class="cstat-no" title="statement not covered" > return `Error: File not found at '${filePath}'`;</span>
|
|
1040
|
+
}
|
|
1041
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(`Error reading file ${safePath}: ${error.message}`);</span>
|
|
1042
|
+
// Re-throwing will cause template rendering to fail, which is appropriate here.
|
|
1043
|
+
<span class="cstat-no" title="statement not covered" > throw error;</span>
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
public <span class="fstat-no" title="function not covered" >async </span>fetchFileContent(filePath: string): Promise<string> {
|
|
1048
|
+
const safePath = <span class="cstat-no" title="statement not covered" >this.resolveAndValidatePath(filePath);</span>
|
|
1049
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1050
|
+
const content = <span class="cstat-no" title="statement not covered" >await fs.readFile(safePath, 'utf8');</span>
|
|
1051
|
+
<span class="cstat-no" title="statement not covered" > return content;</span>
|
|
1052
|
+
} catch (error) {
|
|
1053
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.code === 'ENOENT') {</span>
|
|
1054
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1055
|
+
`File not found when fetching raw content: ${safePath}`,
|
|
1056
|
+
);
|
|
1057
|
+
<span class="cstat-no" title="statement not covered" > throw new NotFoundException(`File not found: ${filePath}`);</span>
|
|
1058
|
+
}
|
|
1059
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1060
|
+
`Error fetching raw file content from ${safePath}: ${error.message}`,
|
|
1061
|
+
);
|
|
1062
|
+
<span class="cstat-no" title="statement not covered" > throw error;</span>
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
private <span class="fstat-no" title="function not covered" >async </span>secureReadDir(dirPath: string): Promise<string[]> {
|
|
1067
|
+
const safePath = <span class="cstat-no" title="statement not covered" >this.resolveAndValidatePath(dirPath);</span>
|
|
1068
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1069
|
+
const entries = <span class="cstat-no" title="statement not covered" >await fs.readdir(safePath, { withFileTypes: true });</span>
|
|
1070
|
+
// Return file names within the directory
|
|
1071
|
+
<span class="cstat-no" title="statement not covered" > return entries.filter(<span class="fstat-no" title="function not covered" >(e</span>) => <span class="cstat-no" title="statement not covered" >e.isFile())</span>.map(<span class="fstat-no" title="function not covered" >(e</span>ntry) => <span class="cstat-no" title="statement not covered" >entry.name)</span>;</span>
|
|
1072
|
+
} catch (error) {
|
|
1073
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.code === 'ENOENT') {</span>
|
|
1074
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(`Directory not found in template render: ${safePath}`);</span>
|
|
1075
|
+
<span class="cstat-no" title="statement not covered" > return [`Error: Directory not found at '${dirPath}'`];</span>
|
|
1076
|
+
}
|
|
1077
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1078
|
+
`Error reading directory ${safePath}: ${error.message}`,
|
|
1079
|
+
);
|
|
1080
|
+
<span class="cstat-no" title="statement not covered" > throw error;</span>
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
public <span class="fstat-no" title="function not covered" >async </span>secureGlob(pattern: string): Promise<string[]> {
|
|
1085
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (path.isAbsolute(pattern)) {</span>
|
|
1086
|
+
<span class="cstat-no" title="statement not covered" > throw new BadRequestException(</span>
|
|
1087
|
+
`Absolute paths are not allowed in glob patterns: ${pattern}`,
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1092
|
+
const files: string[] = <span class="cstat-no" title="statement not covered" >await glob(pattern, {</span>
|
|
1093
|
+
cwd: this.projectRoot,
|
|
1094
|
+
nodir: true, // we only want files
|
|
1095
|
+
absolute: false, // return paths relative to cwd
|
|
1096
|
+
});
|
|
1097
|
+
<span class="cstat-no" title="statement not covered" > return files;</span>
|
|
1098
|
+
} catch (error) {
|
|
1099
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1100
|
+
`Error resolving glob pattern "${pattern}": ${error.message}`,
|
|
1101
|
+
);
|
|
1102
|
+
<span class="cstat-no" title="statement not covered" > throw error;</span>
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
public <span class="fstat-no" title="function not covered" >async </span>secureTree(args?: string): Promise<string> {
|
|
1107
|
+
const treeCommand = <span class="cstat-no" title="statement not covered" >await this.getCommandPath('tree');</span>
|
|
1108
|
+
const command = <span class="cstat-no" title="statement not covered" >`${treeCommand} ${args || ''}`;</span>
|
|
1109
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1110
|
+
<span class="cstat-no" title="statement not covered" > this.logger.log(`Executing command: ${command}`);</span>
|
|
1111
|
+
const { stdout } = <span class="cstat-no" title="statement not covered" >await this.execPromise(command, {</span>
|
|
1112
|
+
cwd: this.projectRoot,
|
|
1113
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
1114
|
+
timeout: 3000,
|
|
1115
|
+
});
|
|
1116
|
+
<span class="cstat-no" title="statement not covered" > return stdout;</span>
|
|
1117
|
+
} catch (error) {
|
|
1118
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.signal === 'SIGTERM') {</span>
|
|
1119
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(`'tree' command timed out after 3 seconds.`);</span>
|
|
1120
|
+
<span class="cstat-no" title="statement not covered" > return `'tree' command timed out after 3 seconds.`;</span>
|
|
1121
|
+
}
|
|
1122
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.message.includes('command not found')) {</span>
|
|
1123
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1124
|
+
`'tree' command not found. Please ensure it is installed and in your PATH or bundled in 'backend/bin'.`,
|
|
1125
|
+
);
|
|
1126
|
+
<span class="cstat-no" title="statement not covered" > return `'tree' command not found. Please ensure it is installed and in your PATH or bundled in 'backend/bin'.`;</span>
|
|
1127
|
+
}
|
|
1128
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1129
|
+
`Error executing tree command: ${error.message}`,
|
|
1130
|
+
error,
|
|
1131
|
+
);
|
|
1132
|
+
<span class="cstat-no" title="statement not covered" > return `Error executing tree command: ${error.stderr || error.message}`;</span>
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
private <span class="fstat-no" title="function not covered" >async </span>secureRipGrep(args?: string): Promise<string> {
|
|
1137
|
+
const rgCommand = <span class="cstat-no" title="statement not covered" >await this.getCommandPath('rg');</span>
|
|
1138
|
+
const command = <span class="cstat-no" title="statement not covered" >`${rgCommand} ${args || ''}`;</span>
|
|
1139
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1140
|
+
<span class="cstat-no" title="statement not covered" > this.logger.log(`Executing command: ${command}`);</span>
|
|
1141
|
+
const { stdout } = <span class="cstat-no" title="statement not covered" >await this.execPromise(command, {</span>
|
|
1142
|
+
cwd: this.projectRoot,
|
|
1143
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
1144
|
+
timeout: 3000,
|
|
1145
|
+
});
|
|
1146
|
+
<span class="cstat-no" title="statement not covered" > return stdout;</span>
|
|
1147
|
+
} catch (error) {
|
|
1148
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.signal === 'SIGTERM') {</span>
|
|
1149
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(`'rg' command timed out after 3 seconds.`);</span>
|
|
1150
|
+
<span class="cstat-no" title="statement not covered" > return `'rg' command timed out after 3 seconds.`;</span>
|
|
1151
|
+
}
|
|
1152
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.code === 1) {</span>
|
|
1153
|
+
// Exit code 1 means no matches were found, which is not a failure.
|
|
1154
|
+
<span class="cstat-no" title="statement not covered" > return error.stdout; </span>// Return stdout, which is likely empty.
|
|
1155
|
+
}
|
|
1156
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.message.includes('command not found')) {</span>
|
|
1157
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1158
|
+
`'rg' (ripgrep) command not found. Please ensure it is installed and in your PATH or bundled in 'backend/bin'.`,
|
|
1159
|
+
);
|
|
1160
|
+
<span class="cstat-no" title="statement not covered" > return `'rg' (ripgrep) command not found. Please ensure it is installed and in your PATH or bundled in 'backend/bin'.`;</span>
|
|
1161
|
+
}
|
|
1162
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1163
|
+
`Error executing ripgrep command: ${error.message}`,
|
|
1164
|
+
error,
|
|
1165
|
+
);
|
|
1166
|
+
<span class="cstat-no" title="statement not covered" > return `Error executing ripgrep command: ${</span>
|
|
1167
|
+
error.stderr || error.message
|
|
1168
|
+
}`;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
private <span class="fstat-no" title="function not covered" >async </span>secureGitDiff(args?: string): Promise<string> {
|
|
1173
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (args && /[`$&|;()<>*]/.test(args)) {</span>
|
|
1174
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1175
|
+
`Potential command injection attempt in gitDiff args: ${args}`,
|
|
1176
|
+
);
|
|
1177
|
+
<span class="cstat-no" title="statement not covered" > return `Error: Invalid characters in gitDiff arguments.`;</span>
|
|
1178
|
+
}
|
|
1179
|
+
const command = <span class="cstat-no" title="statement not covered" >`git --no-pager diff ${args || ''}`;</span>
|
|
1180
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1181
|
+
<span class="cstat-no" title="statement not covered" > this.logger.log(`Executing command: ${command}`);</span>
|
|
1182
|
+
const { stdout } = <span class="cstat-no" title="statement not covered" >await this.execPromise(command, {</span>
|
|
1183
|
+
cwd: this.projectRoot,
|
|
1184
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
1185
|
+
timeout: 3000,
|
|
1186
|
+
});
|
|
1187
|
+
<span class="cstat-no" title="statement not covered" > return stdout;</span>
|
|
1188
|
+
} catch (error) {
|
|
1189
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.signal === 'SIGTERM') {</span>
|
|
1190
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(`'git diff' command timed out after 3 seconds.`);</span>
|
|
1191
|
+
<span class="cstat-no" title="statement not covered" > return `'git diff' command timed out after 3 seconds.`;</span>
|
|
1192
|
+
}
|
|
1193
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.message.includes('command not found')) {</span>
|
|
1194
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1195
|
+
`'git' command not found. Please ensure it is installed and in your PATH.`,
|
|
1196
|
+
);
|
|
1197
|
+
<span class="cstat-no" title="statement not covered" > return `'git' command not found. Please ensure it is installed and in your PATH.`;</span>
|
|
1198
|
+
}
|
|
1199
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1200
|
+
`Error executing git diff command: ${error.message}`,
|
|
1201
|
+
error,
|
|
1202
|
+
);
|
|
1203
|
+
<span class="cstat-no" title="statement not covered" > return `Error executing git diff command: ${</span>
|
|
1204
|
+
error.stderr || error.message
|
|
1205
|
+
}`;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
public <span class="fstat-no" title="function not covered" >async </span>runCommand(commandString: string): Promise<string> {
|
|
1210
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!commandString) {</span>
|
|
1211
|
+
<span class="cstat-no" title="statement not covered" > return 'Error: command cannot be empty.';</span>
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1215
|
+
<span class="cstat-no" title="statement not covered" > this.logger.log(`Executing command from template: ${commandString}`);</span>
|
|
1216
|
+
const { stdout, stderr } = <span class="cstat-no" title="statement not covered" >await this.execPromise(commandString, {</span>
|
|
1217
|
+
cwd: this.projectRoot,
|
|
1218
|
+
maxBuffer: 8 * 1024 * 1024, // 8MB buffer
|
|
1219
|
+
timeout: 5000, // 5 second timeout
|
|
1220
|
+
});
|
|
1221
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (stderr) {</span>
|
|
1222
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1223
|
+
`Command "${commandString}" produced stderr: ${stderr}`,
|
|
1224
|
+
);
|
|
1225
|
+
<span class="cstat-no" title="statement not covered" > return `STDOUT:\n${stdout}\n\nSTDERR:\n${stderr}`;</span>
|
|
1226
|
+
}
|
|
1227
|
+
<span class="cstat-no" title="statement not covered" > return stdout;</span>
|
|
1228
|
+
} catch (error) {
|
|
1229
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (error.signal === 'SIGTERM') {</span>
|
|
1230
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1231
|
+
`Command "${commandString}" timed out after 5 seconds.`,
|
|
1232
|
+
);
|
|
1233
|
+
<span class="cstat-no" title="statement not covered" > return `Error: Command "${commandString}" timed out after 5 seconds.`;</span>
|
|
1234
|
+
}
|
|
1235
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1236
|
+
`Error executing command "${commandString}": ${error.message}`,
|
|
1237
|
+
error,
|
|
1238
|
+
);
|
|
1239
|
+
<span class="cstat-no" title="statement not covered" > return `Error executing command "${commandString}": ${</span>
|
|
1240
|
+
error.stderr || error.message
|
|
1241
|
+
}`;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
private <span class="fstat-no" title="function not covered" >async </span>include(templateName: string, data: any): Promise<string> {
|
|
1246
|
+
// Recursion check
|
|
1247
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (data.__included_partials.has(templateName)) {</span>
|
|
1248
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1249
|
+
`Recursive inclusion of partial "${templateName}" detected.`,
|
|
1250
|
+
);
|
|
1251
|
+
<span class="cstat-no" title="statement not covered" > return `[Error: Recursive inclusion of partial "${templateName}" detected]`;</span>
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
let partial = <span class="cstat-no" title="statement not covered" >this.partialCache.get(templateName);</span>
|
|
1255
|
+
|
|
1256
|
+
<span class="cstat-no" title="statement not covered" > if (partial === undefined) {</span>
|
|
1257
|
+
<span class="cstat-no" title="statement not covered" > this.logger.log(</span>
|
|
1258
|
+
`Cache miss for partial: "${templateName}". Fetching from DB.`,
|
|
1259
|
+
);
|
|
1260
|
+
<span class="cstat-no" title="statement not covered" > partial = await this.contextTemplatesRepository.findOneBy({</span>
|
|
1261
|
+
template_name: templateName,
|
|
1262
|
+
template_type: TemplateType.PARTIAL,
|
|
1263
|
+
});
|
|
1264
|
+
<span class="cstat-no" title="statement not covered" > this.partialCache.set(templateName, partial || null);</span>
|
|
1265
|
+
} else {
|
|
1266
|
+
<span class="cstat-no" title="statement not covered" > this.logger.log(`Cache hit for partial: "${templateName}".`);</span>
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!partial) {</span>
|
|
1270
|
+
<span class="cstat-no" title="statement not covered" > this.logger.warn(</span>
|
|
1271
|
+
`Partial template "${templateName}" not found or is not of type 'partial'.`,
|
|
1272
|
+
);
|
|
1273
|
+
<span class="cstat-no" title="statement not covered" > return `[Error: Partial template "${templateName}" not found]`;</span>
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
// Add to the set for the duration of this sub-render
|
|
1277
|
+
<span class="cstat-no" title="statement not covered" > data.__included_partials.add(templateName);</span>
|
|
1278
|
+
|
|
1279
|
+
// Render the partial with the same data context
|
|
1280
|
+
const result = <span class="cstat-no" title="statement not covered" >await this.eta.renderStringAsync(</span>
|
|
1281
|
+
partial.template_content,
|
|
1282
|
+
data,
|
|
1283
|
+
);
|
|
1284
|
+
|
|
1285
|
+
// Backtrack: remove from the set after rendering is complete
|
|
1286
|
+
<span class="cstat-no" title="statement not covered" > data.__included_partials.delete(templateName);</span>
|
|
1287
|
+
|
|
1288
|
+
<span class="cstat-no" title="statement not covered" > return result;</span>
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
/**
|
|
1292
|
+
* Renders a context string from an Eta template and provided data.
|
|
1293
|
+
* @param templateContent The Eta template string.
|
|
1294
|
+
* @param data An object containing data to be injected into the template.
|
|
1295
|
+
* @returns The rendered string.
|
|
1296
|
+
*/
|
|
1297
|
+
public <span class="fstat-no" title="function not covered" >async </span>render(
|
|
1298
|
+
templateContent: string,
|
|
1299
|
+
data: object = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
1300
|
+
): Promise<string> {
|
|
1301
|
+
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
1302
|
+
const renderData = <span class="cstat-no" title="statement not covered" >{</span>
|
|
1303
|
+
...data,
|
|
1304
|
+
...this.templateHelpers,
|
|
1305
|
+
// Add a property to the data object to track included partials and prevent recursion
|
|
1306
|
+
__included_partials: new Set<string>(),
|
|
1307
|
+
};
|
|
1308
|
+
|
|
1309
|
+
// The `include` helper expects the data object as its second argument.
|
|
1310
|
+
// The template author must call it like: <%~ await it.include('my-partial', it) %>
|
|
1311
|
+
// We are binding `this` to the `include` function, so it has access to the repository and cache.
|
|
1312
|
+
<span class="cstat-no" title="statement not covered" > renderData['include'] = <span class="fstat-no" title="function not covered" >(t</span>emplateName: string) =></span>
|
|
1313
|
+
<span class="cstat-no" title="statement not covered" > this.include(templateName, renderData);</span>
|
|
1314
|
+
|
|
1315
|
+
const result = <span class="cstat-no" title="statement not covered" >await this.eta.renderStringAsync(</span>
|
|
1316
|
+
templateContent,
|
|
1317
|
+
renderData,
|
|
1318
|
+
);
|
|
1319
|
+
<span class="cstat-no" title="statement not covered" > return result;</span>
|
|
1320
|
+
} catch (error) {
|
|
1321
|
+
<span class="cstat-no" title="statement not covered" > this.logger.error(</span>
|
|
1322
|
+
`Error rendering Eta template: ${error.message}`,
|
|
1323
|
+
error.stack,
|
|
1324
|
+
);
|
|
1325
|
+
<span class="cstat-no" title="statement not covered" > throw new Error(`Template rendering failed: ${error.message}`);</span>
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
</pre></td></tr></table></pre>
|
|
1330
|
+
|
|
1331
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
1332
|
+
</div><!-- /wrapper -->
|
|
1333
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
1334
|
+
Code coverage generated by
|
|
1335
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
1336
|
+
at 2025-07-30T23:37:05.373Z
|
|
1337
|
+
</div>
|
|
1338
|
+
<script src="../../prettify.js"></script>
|
|
1339
|
+
<script>
|
|
1340
|
+
window.onload = function () {
|
|
1341
|
+
prettyPrint();
|
|
1342
|
+
};
|
|
1343
|
+
</script>
|
|
1344
|
+
<script src="../../sorter.js"></script>
|
|
1345
|
+
<script src="../../block-navigation.js"></script>
|
|
1346
|
+
</body>
|
|
1347
|
+
</html>
|
|
1348
|
+
|