@mndrk/agx 2.0.45 → 2.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/cloud-runtime/standalone/.next/BUILD_ID +1 -1
  2. package/cloud-runtime/standalone/.next/build-manifest.json +2 -2
  3. package/cloud-runtime/standalone/.next/prerender-manifest.json +3 -3
  4. package/cloud-runtime/standalone/.next/server/app/_global-error.html +2 -2
  5. package/cloud-runtime/standalone/.next/server/app/_global-error.rsc +1 -1
  6. package/cloud-runtime/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/cloud-runtime/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/cloud-runtime/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/cloud-runtime/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/cloud-runtime/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/cloud-runtime/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/cloud-runtime/standalone/.next/server/app/_not-found.html +2 -2
  13. package/cloud-runtime/standalone/.next/server/app/_not-found.rsc +2 -2
  14. package/cloud-runtime/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  15. package/cloud-runtime/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  16. package/cloud-runtime/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  17. package/cloud-runtime/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  18. package/cloud-runtime/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  19. package/cloud-runtime/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  20. package/cloud-runtime/standalone/.next/server/app/agents/[id]/page_client-reference-manifest.js +1 -1
  21. package/cloud-runtime/standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  22. package/cloud-runtime/standalone/.next/server/app/agents.html +2 -2
  23. package/cloud-runtime/standalone/.next/server/app/agents.rsc +2 -2
  24. package/cloud-runtime/standalone/.next/server/app/agents.segments/_full.segment.rsc +2 -2
  25. package/cloud-runtime/standalone/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  26. package/cloud-runtime/standalone/.next/server/app/agents.segments/_index.segment.rsc +2 -2
  27. package/cloud-runtime/standalone/.next/server/app/agents.segments/_tree.segment.rsc +2 -2
  28. package/cloud-runtime/standalone/.next/server/app/agents.segments/agents/__PAGE__.segment.rsc +1 -1
  29. package/cloud-runtime/standalone/.next/server/app/agents.segments/agents.segment.rsc +1 -1
  30. package/cloud-runtime/standalone/.next/server/app/automations/page_client-reference-manifest.js +1 -1
  31. package/cloud-runtime/standalone/.next/server/app/automations.html +2 -2
  32. package/cloud-runtime/standalone/.next/server/app/automations.rsc +2 -2
  33. package/cloud-runtime/standalone/.next/server/app/automations.segments/_full.segment.rsc +2 -2
  34. package/cloud-runtime/standalone/.next/server/app/automations.segments/_head.segment.rsc +1 -1
  35. package/cloud-runtime/standalone/.next/server/app/automations.segments/_index.segment.rsc +2 -2
  36. package/cloud-runtime/standalone/.next/server/app/automations.segments/_tree.segment.rsc +2 -2
  37. package/cloud-runtime/standalone/.next/server/app/automations.segments/automations/__PAGE__.segment.rsc +1 -1
  38. package/cloud-runtime/standalone/.next/server/app/automations.segments/automations.segment.rsc +1 -1
  39. package/cloud-runtime/standalone/.next/server/app/board/page_client-reference-manifest.js +1 -1
  40. package/cloud-runtime/standalone/.next/server/app/board.html +2 -2
  41. package/cloud-runtime/standalone/.next/server/app/board.rsc +2 -2
  42. package/cloud-runtime/standalone/.next/server/app/board.segments/_full.segment.rsc +2 -2
  43. package/cloud-runtime/standalone/.next/server/app/board.segments/_head.segment.rsc +1 -1
  44. package/cloud-runtime/standalone/.next/server/app/board.segments/_index.segment.rsc +2 -2
  45. package/cloud-runtime/standalone/.next/server/app/board.segments/_tree.segment.rsc +2 -2
  46. package/cloud-runtime/standalone/.next/server/app/board.segments/board/__PAGE__.segment.rsc +1 -1
  47. package/cloud-runtime/standalone/.next/server/app/board.segments/board.segment.rsc +1 -1
  48. package/cloud-runtime/standalone/.next/server/app/execution-graph/page_client-reference-manifest.js +1 -1
  49. package/cloud-runtime/standalone/.next/server/app/execution-graph.html +2 -2
  50. package/cloud-runtime/standalone/.next/server/app/execution-graph.rsc +2 -2
  51. package/cloud-runtime/standalone/.next/server/app/execution-graph.segments/_full.segment.rsc +2 -2
  52. package/cloud-runtime/standalone/.next/server/app/execution-graph.segments/_head.segment.rsc +1 -1
  53. package/cloud-runtime/standalone/.next/server/app/execution-graph.segments/_index.segment.rsc +2 -2
  54. package/cloud-runtime/standalone/.next/server/app/execution-graph.segments/_tree.segment.rsc +2 -2
  55. package/cloud-runtime/standalone/.next/server/app/execution-graph.segments/execution-graph/__PAGE__.segment.rsc +1 -1
  56. package/cloud-runtime/standalone/.next/server/app/execution-graph.segments/execution-graph.segment.rsc +1 -1
  57. package/cloud-runtime/standalone/.next/server/app/index.html +2 -2
  58. package/cloud-runtime/standalone/.next/server/app/index.rsc +2 -2
  59. package/cloud-runtime/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  60. package/cloud-runtime/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  61. package/cloud-runtime/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  62. package/cloud-runtime/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  63. package/cloud-runtime/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  64. package/cloud-runtime/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  65. package/cloud-runtime/standalone/.next/server/app/projects/[slug]/automations/page_client-reference-manifest.js +1 -1
  66. package/cloud-runtime/standalone/.next/server/app/projects/[slug]/graph/[taskId]/page_client-reference-manifest.js +1 -1
  67. package/cloud-runtime/standalone/.next/server/app/projects/[slug]/knowledge/page_client-reference-manifest.js +1 -1
  68. package/cloud-runtime/standalone/.next/server/app/projects/[slug]/linear/page_client-reference-manifest.js +1 -1
  69. package/cloud-runtime/standalone/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  70. package/cloud-runtime/standalone/.next/server/app/projects/[slug]/thread/[threadId]/page_client-reference-manifest.js +1 -1
  71. package/cloud-runtime/standalone/.next/server/app/projects/orphans/page_client-reference-manifest.js +1 -1
  72. package/cloud-runtime/standalone/.next/server/app/projects/orphans.html +2 -2
  73. package/cloud-runtime/standalone/.next/server/app/projects/orphans.rsc +2 -2
  74. package/cloud-runtime/standalone/.next/server/app/projects/orphans.segments/_full.segment.rsc +2 -2
  75. package/cloud-runtime/standalone/.next/server/app/projects/orphans.segments/_head.segment.rsc +1 -1
  76. package/cloud-runtime/standalone/.next/server/app/projects/orphans.segments/_index.segment.rsc +2 -2
  77. package/cloud-runtime/standalone/.next/server/app/projects/orphans.segments/_tree.segment.rsc +2 -2
  78. package/cloud-runtime/standalone/.next/server/app/projects/orphans.segments/projects/orphans/__PAGE__.segment.rsc +1 -1
  79. package/cloud-runtime/standalone/.next/server/app/projects/orphans.segments/projects/orphans.segment.rsc +1 -1
  80. package/cloud-runtime/standalone/.next/server/app/projects/orphans.segments/projects.segment.rsc +1 -1
  81. package/cloud-runtime/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  82. package/cloud-runtime/standalone/.next/server/app/projects.html +2 -2
  83. package/cloud-runtime/standalone/.next/server/app/projects.rsc +2 -2
  84. package/cloud-runtime/standalone/.next/server/app/projects.segments/_full.segment.rsc +2 -2
  85. package/cloud-runtime/standalone/.next/server/app/projects.segments/_head.segment.rsc +1 -1
  86. package/cloud-runtime/standalone/.next/server/app/projects.segments/_index.segment.rsc +2 -2
  87. package/cloud-runtime/standalone/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
  88. package/cloud-runtime/standalone/.next/server/app/projects.segments/projects/__PAGE__.segment.rsc +1 -1
  89. package/cloud-runtime/standalone/.next/server/app/projects.segments/projects.segment.rsc +1 -1
  90. package/cloud-runtime/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  91. package/cloud-runtime/standalone/.next/server/app/settings.html +2 -2
  92. package/cloud-runtime/standalone/.next/server/app/settings.rsc +2 -2
  93. package/cloud-runtime/standalone/.next/server/app/settings.segments/_full.segment.rsc +2 -2
  94. package/cloud-runtime/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  95. package/cloud-runtime/standalone/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  96. package/cloud-runtime/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  97. package/cloud-runtime/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  98. package/cloud-runtime/standalone/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  99. package/cloud-runtime/standalone/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  100. package/cloud-runtime/standalone/.next/server/app/skills.html +2 -2
  101. package/cloud-runtime/standalone/.next/server/app/skills.rsc +2 -2
  102. package/cloud-runtime/standalone/.next/server/app/skills.segments/_full.segment.rsc +2 -2
  103. package/cloud-runtime/standalone/.next/server/app/skills.segments/_head.segment.rsc +1 -1
  104. package/cloud-runtime/standalone/.next/server/app/skills.segments/_index.segment.rsc +2 -2
  105. package/cloud-runtime/standalone/.next/server/app/skills.segments/_tree.segment.rsc +2 -2
  106. package/cloud-runtime/standalone/.next/server/app/skills.segments/skills/__PAGE__.segment.rsc +1 -1
  107. package/cloud-runtime/standalone/.next/server/app/skills.segments/skills.segment.rsc +1 -1
  108. package/cloud-runtime/standalone/.next/server/app/status/page_client-reference-manifest.js +1 -1
  109. package/cloud-runtime/standalone/.next/server/app/status.html +2 -2
  110. package/cloud-runtime/standalone/.next/server/app/status.rsc +2 -2
  111. package/cloud-runtime/standalone/.next/server/app/status.segments/_full.segment.rsc +2 -2
  112. package/cloud-runtime/standalone/.next/server/app/status.segments/_head.segment.rsc +1 -1
  113. package/cloud-runtime/standalone/.next/server/app/status.segments/_index.segment.rsc +2 -2
  114. package/cloud-runtime/standalone/.next/server/app/status.segments/_tree.segment.rsc +2 -2
  115. package/cloud-runtime/standalone/.next/server/app/status.segments/status/__PAGE__.segment.rsc +1 -1
  116. package/cloud-runtime/standalone/.next/server/app/status.segments/status.segment.rsc +1 -1
  117. package/cloud-runtime/standalone/.next/server/app/thread/[id]/page_client-reference-manifest.js +1 -1
  118. package/cloud-runtime/standalone/.next/server/app/welcome/page_client-reference-manifest.js +1 -1
  119. package/cloud-runtime/standalone/.next/server/app/welcome.html +2 -2
  120. package/cloud-runtime/standalone/.next/server/app/welcome.rsc +2 -2
  121. package/cloud-runtime/standalone/.next/server/app/welcome.segments/_full.segment.rsc +2 -2
  122. package/cloud-runtime/standalone/.next/server/app/welcome.segments/_head.segment.rsc +1 -1
  123. package/cloud-runtime/standalone/.next/server/app/welcome.segments/_index.segment.rsc +2 -2
  124. package/cloud-runtime/standalone/.next/server/app/welcome.segments/_tree.segment.rsc +2 -2
  125. package/cloud-runtime/standalone/.next/server/app/welcome.segments/welcome/__PAGE__.segment.rsc +1 -1
  126. package/cloud-runtime/standalone/.next/server/app/welcome.segments/welcome.segment.rsc +1 -1
  127. package/cloud-runtime/standalone/.next/server/chunks/[root-of-the-server]__3b83b657._.js +2 -2
  128. package/cloud-runtime/standalone/.next/server/chunks/[root-of-the-server]__748c718f._.js +1 -1
  129. package/cloud-runtime/standalone/.next/server/chunks/ssr/app_projects_[slug]_linear_page_tsx_971a6ba7._.js +2 -2
  130. package/cloud-runtime/standalone/.next/server/middleware-manifest.json +5 -5
  131. package/cloud-runtime/standalone/.next/server/pages/404.html +2 -2
  132. package/cloud-runtime/standalone/.next/server/pages/500.html +2 -2
  133. package/cloud-runtime/standalone/.next/server/server-reference-manifest.js +1 -1
  134. package/cloud-runtime/standalone/.next/server/server-reference-manifest.json +1 -1
  135. package/cloud-runtime/standalone/.next/static/chunks/37f07896b044d69f.css +1 -0
  136. package/cloud-runtime/standalone/.next/static/chunks/{00716478a3ee55a2.js → cca7c8e4ade050f0.js} +2 -2
  137. package/cloud-runtime/standalone/app/api/linear/issues/route.ts +9 -2
  138. package/cloud-runtime/standalone/components/LinearBoard.tsx +256 -10
  139. package/cloud-runtime/standalone/hooks/useLinearIssues.ts +7 -3
  140. package/cloud-runtime/standalone/lib/linear-issue-store.ts +11 -5
  141. package/cloud-runtime/standalone/state/automations/.state/24a6a5db-3b14-49c4-841f-29f10f015fbb.json +3 -3
  142. package/package.json +1 -1
  143. package/cloud-runtime/standalone/.linear-token.json +0 -4
  144. package/cloud-runtime/standalone/.next/static/chunks/3091043e8c282dce.css +0 -1
  145. package/cloud-runtime/standalone/coverage/clover.xml +0 -1208
  146. package/cloud-runtime/standalone/coverage/coverage-final.json +0 -29
  147. package/cloud-runtime/standalone/coverage/lcov-report/app/api/audit/index.html +0 -116
  148. package/cloud-runtime/standalone/coverage/lcov-report/app/api/audit/route.ts.html +0 -208
  149. package/cloud-runtime/standalone/coverage/lcov-report/app/api/auth/[...nextauth]/index.html +0 -116
  150. package/cloud-runtime/standalone/coverage/lcov-report/app/api/auth/[...nextauth]/route.ts.html +0 -166
  151. package/cloud-runtime/standalone/coverage/lcov-report/app/api/auth/daemon-secret/index.html +0 -116
  152. package/cloud-runtime/standalone/coverage/lcov-report/app/api/auth/daemon-secret/route.ts.html +0 -532
  153. package/cloud-runtime/standalone/coverage/lcov-report/app/api/auth/status/index.html +0 -116
  154. package/cloud-runtime/standalone/coverage/lcov-report/app/api/auth/status/route.ts.html +0 -178
  155. package/cloud-runtime/standalone/coverage/lcov-report/app/api/learnings/index.html +0 -116
  156. package/cloud-runtime/standalone/coverage/lcov-report/app/api/learnings/route.ts.html +0 -262
  157. package/cloud-runtime/standalone/coverage/lcov-report/app/api/logs/stream/index.html +0 -116
  158. package/cloud-runtime/standalone/coverage/lcov-report/app/api/logs/stream/route.ts.html +0 -448
  159. package/cloud-runtime/standalone/coverage/lcov-report/app/api/queue/complete/index.html +0 -116
  160. package/cloud-runtime/standalone/coverage/lcov-report/app/api/queue/complete/route.ts.html +0 -331
  161. package/cloud-runtime/standalone/coverage/lcov-report/app/api/queue/index.html +0 -116
  162. package/cloud-runtime/standalone/coverage/lcov-report/app/api/queue/route.ts.html +0 -505
  163. package/cloud-runtime/standalone/coverage/lcov-report/app/api/stage-prompts/index.html +0 -116
  164. package/cloud-runtime/standalone/coverage/lcov-report/app/api/stage-prompts/route.ts.html +0 -412
  165. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/[id]/advance/index.html +0 -116
  166. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/[id]/advance/route.ts.html +0 -304
  167. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/[id]/index.html +0 -116
  168. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/[id]/logs/index.html +0 -116
  169. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/[id]/logs/route.ts.html +0 -202
  170. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/[id]/route.ts.html +0 -373
  171. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/index.html +0 -116
  172. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/route.ts.html +0 -499
  173. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/stream/index.html +0 -116
  174. package/cloud-runtime/standalone/coverage/lcov-report/app/api/tasks/stream/route.ts.html +0 -349
  175. package/cloud-runtime/standalone/coverage/lcov-report/base.css +0 -224
  176. package/cloud-runtime/standalone/coverage/lcov-report/block-navigation.js +0 -87
  177. package/cloud-runtime/standalone/coverage/lcov-report/components/AuthProvider.tsx.html +0 -259
  178. package/cloud-runtime/standalone/coverage/lcov-report/components/ChatInterface.tsx.html +0 -1228
  179. package/cloud-runtime/standalone/coverage/lcov-report/components/KanbanBoard.tsx.html +0 -1024
  180. package/cloud-runtime/standalone/coverage/lcov-report/components/Layout.tsx.html +0 -211
  181. package/cloud-runtime/standalone/coverage/lcov-report/components/LearningsPanel.tsx.html +0 -535
  182. package/cloud-runtime/standalone/coverage/lcov-report/components/LogTimeline.tsx.html +0 -415
  183. package/cloud-runtime/standalone/coverage/lcov-report/components/SortableTaskCard.tsx.html +0 -358
  184. package/cloud-runtime/standalone/coverage/lcov-report/components/StagePills.tsx.html +0 -439
  185. package/cloud-runtime/standalone/coverage/lcov-report/components/TaskCard.tsx.html +0 -514
  186. package/cloud-runtime/standalone/coverage/lcov-report/components/TaskCardOverlay.tsx.html +0 -256
  187. package/cloud-runtime/standalone/coverage/lcov-report/components/TaskDetail.tsx.html +0 -622
  188. package/cloud-runtime/standalone/coverage/lcov-report/components/TaskList.tsx.html +0 -253
  189. package/cloud-runtime/standalone/coverage/lcov-report/components/index.html +0 -281
  190. package/cloud-runtime/standalone/coverage/lcov-report/favicon.png +0 -0
  191. package/cloud-runtime/standalone/coverage/lcov-report/hooks/index.html +0 -116
  192. package/cloud-runtime/standalone/coverage/lcov-report/hooks/useTasks.ts.html +0 -1042
  193. package/cloud-runtime/standalone/coverage/lcov-report/index.html +0 -341
  194. package/cloud-runtime/standalone/coverage/lcov-report/lib/auth-client.ts.html +0 -202
  195. package/cloud-runtime/standalone/coverage/lcov-report/lib/auth-server.ts.html +0 -172
  196. package/cloud-runtime/standalone/coverage/lcov-report/lib/auth.ts.html +0 -265
  197. package/cloud-runtime/standalone/coverage/lcov-report/lib/db.ts.html +0 -1252
  198. package/cloud-runtime/standalone/coverage/lcov-report/lib/index.html +0 -131
  199. package/cloud-runtime/standalone/coverage/lcov-report/lib/orchestrator.ts.html +0 -409
  200. package/cloud-runtime/standalone/coverage/lcov-report/lib/security.ts.html +0 -1165
  201. package/cloud-runtime/standalone/coverage/lcov-report/lib/supabase-server.ts.html +0 -175
  202. package/cloud-runtime/standalone/coverage/lcov-report/lib/supabase.ts.html +0 -157
  203. package/cloud-runtime/standalone/coverage/lcov-report/prettify.css +0 -1
  204. package/cloud-runtime/standalone/coverage/lcov-report/prettify.js +0 -2
  205. package/cloud-runtime/standalone/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  206. package/cloud-runtime/standalone/coverage/lcov-report/sorter.js +0 -210
  207. package/cloud-runtime/standalone/coverage/lcov.info +0 -2386
  208. /package/cloud-runtime/standalone/.next/static/{Y8QdDdLJI3yzNjkyPjuJ- → 1Q0q2lXllTpqCvmNQYtpD}/_buildManifest.js +0 -0
  209. /package/cloud-runtime/standalone/.next/static/{Y8QdDdLJI3yzNjkyPjuJ- → 1Q0q2lXllTpqCvmNQYtpD}/_clientMiddlewareManifest.json +0 -0
  210. /package/cloud-runtime/standalone/.next/static/{Y8QdDdLJI3yzNjkyPjuJ- → 1Q0q2lXllTpqCvmNQYtpD}/_ssgManifest.js +0 -0
@@ -1,1165 +0,0 @@
1
-
2
- <!doctype html>
3
- <html lang="en">
4
-
5
- <head>
6
- <title>Code coverage report for lib/security.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">lib</a> security.ts</h1>
23
- <div class='clearfix'>
24
-
25
- <div class='fl pad1y space-right2'>
26
- <span class="strong">88.37% </span>
27
- <span class="quiet">Statements</span>
28
- <span class='fraction'>76/86</span>
29
- </div>
30
-
31
-
32
- <div class='fl pad1y space-right2'>
33
- <span class="strong">75% </span>
34
- <span class="quiet">Branches</span>
35
- <span class='fraction'>33/44</span>
36
- </div>
37
-
38
-
39
- <div class='fl pad1y space-right2'>
40
- <span class="strong">100% </span>
41
- <span class="quiet">Functions</span>
42
- <span class='fraction'>12/12</span>
43
- </div>
44
-
45
-
46
- <div class='fl pad1y space-right2'>
47
- <span class="strong">88.09% </span>
48
- <span class="quiet">Lines</span>
49
- <span class='fraction'>74/84</span>
50
- </div>
51
-
52
-
53
- </div>
54
- <p class="quiet">
55
- Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
- </p>
57
- <template id="filterTemplate">
58
- <div class="quiet">
59
- Filter:
60
- <input type="search" id="fileSearch">
61
- </div>
62
- </template>
63
- </div>
64
- <div class='status-line high'></div>
65
- <pre><table class="coverage">
66
- <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
- <a name='L2'></a><a href='#L2'>2</a>
68
- <a name='L3'></a><a href='#L3'>3</a>
69
- <a name='L4'></a><a href='#L4'>4</a>
70
- <a name='L5'></a><a href='#L5'>5</a>
71
- <a name='L6'></a><a href='#L6'>6</a>
72
- <a name='L7'></a><a href='#L7'>7</a>
73
- <a name='L8'></a><a href='#L8'>8</a>
74
- <a name='L9'></a><a href='#L9'>9</a>
75
- <a name='L10'></a><a href='#L10'>10</a>
76
- <a name='L11'></a><a href='#L11'>11</a>
77
- <a name='L12'></a><a href='#L12'>12</a>
78
- <a name='L13'></a><a href='#L13'>13</a>
79
- <a name='L14'></a><a href='#L14'>14</a>
80
- <a name='L15'></a><a href='#L15'>15</a>
81
- <a name='L16'></a><a href='#L16'>16</a>
82
- <a name='L17'></a><a href='#L17'>17</a>
83
- <a name='L18'></a><a href='#L18'>18</a>
84
- <a name='L19'></a><a href='#L19'>19</a>
85
- <a name='L20'></a><a href='#L20'>20</a>
86
- <a name='L21'></a><a href='#L21'>21</a>
87
- <a name='L22'></a><a href='#L22'>22</a>
88
- <a name='L23'></a><a href='#L23'>23</a>
89
- <a name='L24'></a><a href='#L24'>24</a>
90
- <a name='L25'></a><a href='#L25'>25</a>
91
- <a name='L26'></a><a href='#L26'>26</a>
92
- <a name='L27'></a><a href='#L27'>27</a>
93
- <a name='L28'></a><a href='#L28'>28</a>
94
- <a name='L29'></a><a href='#L29'>29</a>
95
- <a name='L30'></a><a href='#L30'>30</a>
96
- <a name='L31'></a><a href='#L31'>31</a>
97
- <a name='L32'></a><a href='#L32'>32</a>
98
- <a name='L33'></a><a href='#L33'>33</a>
99
- <a name='L34'></a><a href='#L34'>34</a>
100
- <a name='L35'></a><a href='#L35'>35</a>
101
- <a name='L36'></a><a href='#L36'>36</a>
102
- <a name='L37'></a><a href='#L37'>37</a>
103
- <a name='L38'></a><a href='#L38'>38</a>
104
- <a name='L39'></a><a href='#L39'>39</a>
105
- <a name='L40'></a><a href='#L40'>40</a>
106
- <a name='L41'></a><a href='#L41'>41</a>
107
- <a name='L42'></a><a href='#L42'>42</a>
108
- <a name='L43'></a><a href='#L43'>43</a>
109
- <a name='L44'></a><a href='#L44'>44</a>
110
- <a name='L45'></a><a href='#L45'>45</a>
111
- <a name='L46'></a><a href='#L46'>46</a>
112
- <a name='L47'></a><a href='#L47'>47</a>
113
- <a name='L48'></a><a href='#L48'>48</a>
114
- <a name='L49'></a><a href='#L49'>49</a>
115
- <a name='L50'></a><a href='#L50'>50</a>
116
- <a name='L51'></a><a href='#L51'>51</a>
117
- <a name='L52'></a><a href='#L52'>52</a>
118
- <a name='L53'></a><a href='#L53'>53</a>
119
- <a name='L54'></a><a href='#L54'>54</a>
120
- <a name='L55'></a><a href='#L55'>55</a>
121
- <a name='L56'></a><a href='#L56'>56</a>
122
- <a name='L57'></a><a href='#L57'>57</a>
123
- <a name='L58'></a><a href='#L58'>58</a>
124
- <a name='L59'></a><a href='#L59'>59</a>
125
- <a name='L60'></a><a href='#L60'>60</a>
126
- <a name='L61'></a><a href='#L61'>61</a>
127
- <a name='L62'></a><a href='#L62'>62</a>
128
- <a name='L63'></a><a href='#L63'>63</a>
129
- <a name='L64'></a><a href='#L64'>64</a>
130
- <a name='L65'></a><a href='#L65'>65</a>
131
- <a name='L66'></a><a href='#L66'>66</a>
132
- <a name='L67'></a><a href='#L67'>67</a>
133
- <a name='L68'></a><a href='#L68'>68</a>
134
- <a name='L69'></a><a href='#L69'>69</a>
135
- <a name='L70'></a><a href='#L70'>70</a>
136
- <a name='L71'></a><a href='#L71'>71</a>
137
- <a name='L72'></a><a href='#L72'>72</a>
138
- <a name='L73'></a><a href='#L73'>73</a>
139
- <a name='L74'></a><a href='#L74'>74</a>
140
- <a name='L75'></a><a href='#L75'>75</a>
141
- <a name='L76'></a><a href='#L76'>76</a>
142
- <a name='L77'></a><a href='#L77'>77</a>
143
- <a name='L78'></a><a href='#L78'>78</a>
144
- <a name='L79'></a><a href='#L79'>79</a>
145
- <a name='L80'></a><a href='#L80'>80</a>
146
- <a name='L81'></a><a href='#L81'>81</a>
147
- <a name='L82'></a><a href='#L82'>82</a>
148
- <a name='L83'></a><a href='#L83'>83</a>
149
- <a name='L84'></a><a href='#L84'>84</a>
150
- <a name='L85'></a><a href='#L85'>85</a>
151
- <a name='L86'></a><a href='#L86'>86</a>
152
- <a name='L87'></a><a href='#L87'>87</a>
153
- <a name='L88'></a><a href='#L88'>88</a>
154
- <a name='L89'></a><a href='#L89'>89</a>
155
- <a name='L90'></a><a href='#L90'>90</a>
156
- <a name='L91'></a><a href='#L91'>91</a>
157
- <a name='L92'></a><a href='#L92'>92</a>
158
- <a name='L93'></a><a href='#L93'>93</a>
159
- <a name='L94'></a><a href='#L94'>94</a>
160
- <a name='L95'></a><a href='#L95'>95</a>
161
- <a name='L96'></a><a href='#L96'>96</a>
162
- <a name='L97'></a><a href='#L97'>97</a>
163
- <a name='L98'></a><a href='#L98'>98</a>
164
- <a name='L99'></a><a href='#L99'>99</a>
165
- <a name='L100'></a><a href='#L100'>100</a>
166
- <a name='L101'></a><a href='#L101'>101</a>
167
- <a name='L102'></a><a href='#L102'>102</a>
168
- <a name='L103'></a><a href='#L103'>103</a>
169
- <a name='L104'></a><a href='#L104'>104</a>
170
- <a name='L105'></a><a href='#L105'>105</a>
171
- <a name='L106'></a><a href='#L106'>106</a>
172
- <a name='L107'></a><a href='#L107'>107</a>
173
- <a name='L108'></a><a href='#L108'>108</a>
174
- <a name='L109'></a><a href='#L109'>109</a>
175
- <a name='L110'></a><a href='#L110'>110</a>
176
- <a name='L111'></a><a href='#L111'>111</a>
177
- <a name='L112'></a><a href='#L112'>112</a>
178
- <a name='L113'></a><a href='#L113'>113</a>
179
- <a name='L114'></a><a href='#L114'>114</a>
180
- <a name='L115'></a><a href='#L115'>115</a>
181
- <a name='L116'></a><a href='#L116'>116</a>
182
- <a name='L117'></a><a href='#L117'>117</a>
183
- <a name='L118'></a><a href='#L118'>118</a>
184
- <a name='L119'></a><a href='#L119'>119</a>
185
- <a name='L120'></a><a href='#L120'>120</a>
186
- <a name='L121'></a><a href='#L121'>121</a>
187
- <a name='L122'></a><a href='#L122'>122</a>
188
- <a name='L123'></a><a href='#L123'>123</a>
189
- <a name='L124'></a><a href='#L124'>124</a>
190
- <a name='L125'></a><a href='#L125'>125</a>
191
- <a name='L126'></a><a href='#L126'>126</a>
192
- <a name='L127'></a><a href='#L127'>127</a>
193
- <a name='L128'></a><a href='#L128'>128</a>
194
- <a name='L129'></a><a href='#L129'>129</a>
195
- <a name='L130'></a><a href='#L130'>130</a>
196
- <a name='L131'></a><a href='#L131'>131</a>
197
- <a name='L132'></a><a href='#L132'>132</a>
198
- <a name='L133'></a><a href='#L133'>133</a>
199
- <a name='L134'></a><a href='#L134'>134</a>
200
- <a name='L135'></a><a href='#L135'>135</a>
201
- <a name='L136'></a><a href='#L136'>136</a>
202
- <a name='L137'></a><a href='#L137'>137</a>
203
- <a name='L138'></a><a href='#L138'>138</a>
204
- <a name='L139'></a><a href='#L139'>139</a>
205
- <a name='L140'></a><a href='#L140'>140</a>
206
- <a name='L141'></a><a href='#L141'>141</a>
207
- <a name='L142'></a><a href='#L142'>142</a>
208
- <a name='L143'></a><a href='#L143'>143</a>
209
- <a name='L144'></a><a href='#L144'>144</a>
210
- <a name='L145'></a><a href='#L145'>145</a>
211
- <a name='L146'></a><a href='#L146'>146</a>
212
- <a name='L147'></a><a href='#L147'>147</a>
213
- <a name='L148'></a><a href='#L148'>148</a>
214
- <a name='L149'></a><a href='#L149'>149</a>
215
- <a name='L150'></a><a href='#L150'>150</a>
216
- <a name='L151'></a><a href='#L151'>151</a>
217
- <a name='L152'></a><a href='#L152'>152</a>
218
- <a name='L153'></a><a href='#L153'>153</a>
219
- <a name='L154'></a><a href='#L154'>154</a>
220
- <a name='L155'></a><a href='#L155'>155</a>
221
- <a name='L156'></a><a href='#L156'>156</a>
222
- <a name='L157'></a><a href='#L157'>157</a>
223
- <a name='L158'></a><a href='#L158'>158</a>
224
- <a name='L159'></a><a href='#L159'>159</a>
225
- <a name='L160'></a><a href='#L160'>160</a>
226
- <a name='L161'></a><a href='#L161'>161</a>
227
- <a name='L162'></a><a href='#L162'>162</a>
228
- <a name='L163'></a><a href='#L163'>163</a>
229
- <a name='L164'></a><a href='#L164'>164</a>
230
- <a name='L165'></a><a href='#L165'>165</a>
231
- <a name='L166'></a><a href='#L166'>166</a>
232
- <a name='L167'></a><a href='#L167'>167</a>
233
- <a name='L168'></a><a href='#L168'>168</a>
234
- <a name='L169'></a><a href='#L169'>169</a>
235
- <a name='L170'></a><a href='#L170'>170</a>
236
- <a name='L171'></a><a href='#L171'>171</a>
237
- <a name='L172'></a><a href='#L172'>172</a>
238
- <a name='L173'></a><a href='#L173'>173</a>
239
- <a name='L174'></a><a href='#L174'>174</a>
240
- <a name='L175'></a><a href='#L175'>175</a>
241
- <a name='L176'></a><a href='#L176'>176</a>
242
- <a name='L177'></a><a href='#L177'>177</a>
243
- <a name='L178'></a><a href='#L178'>178</a>
244
- <a name='L179'></a><a href='#L179'>179</a>
245
- <a name='L180'></a><a href='#L180'>180</a>
246
- <a name='L181'></a><a href='#L181'>181</a>
247
- <a name='L182'></a><a href='#L182'>182</a>
248
- <a name='L183'></a><a href='#L183'>183</a>
249
- <a name='L184'></a><a href='#L184'>184</a>
250
- <a name='L185'></a><a href='#L185'>185</a>
251
- <a name='L186'></a><a href='#L186'>186</a>
252
- <a name='L187'></a><a href='#L187'>187</a>
253
- <a name='L188'></a><a href='#L188'>188</a>
254
- <a name='L189'></a><a href='#L189'>189</a>
255
- <a name='L190'></a><a href='#L190'>190</a>
256
- <a name='L191'></a><a href='#L191'>191</a>
257
- <a name='L192'></a><a href='#L192'>192</a>
258
- <a name='L193'></a><a href='#L193'>193</a>
259
- <a name='L194'></a><a href='#L194'>194</a>
260
- <a name='L195'></a><a href='#L195'>195</a>
261
- <a name='L196'></a><a href='#L196'>196</a>
262
- <a name='L197'></a><a href='#L197'>197</a>
263
- <a name='L198'></a><a href='#L198'>198</a>
264
- <a name='L199'></a><a href='#L199'>199</a>
265
- <a name='L200'></a><a href='#L200'>200</a>
266
- <a name='L201'></a><a href='#L201'>201</a>
267
- <a name='L202'></a><a href='#L202'>202</a>
268
- <a name='L203'></a><a href='#L203'>203</a>
269
- <a name='L204'></a><a href='#L204'>204</a>
270
- <a name='L205'></a><a href='#L205'>205</a>
271
- <a name='L206'></a><a href='#L206'>206</a>
272
- <a name='L207'></a><a href='#L207'>207</a>
273
- <a name='L208'></a><a href='#L208'>208</a>
274
- <a name='L209'></a><a href='#L209'>209</a>
275
- <a name='L210'></a><a href='#L210'>210</a>
276
- <a name='L211'></a><a href='#L211'>211</a>
277
- <a name='L212'></a><a href='#L212'>212</a>
278
- <a name='L213'></a><a href='#L213'>213</a>
279
- <a name='L214'></a><a href='#L214'>214</a>
280
- <a name='L215'></a><a href='#L215'>215</a>
281
- <a name='L216'></a><a href='#L216'>216</a>
282
- <a name='L217'></a><a href='#L217'>217</a>
283
- <a name='L218'></a><a href='#L218'>218</a>
284
- <a name='L219'></a><a href='#L219'>219</a>
285
- <a name='L220'></a><a href='#L220'>220</a>
286
- <a name='L221'></a><a href='#L221'>221</a>
287
- <a name='L222'></a><a href='#L222'>222</a>
288
- <a name='L223'></a><a href='#L223'>223</a>
289
- <a name='L224'></a><a href='#L224'>224</a>
290
- <a name='L225'></a><a href='#L225'>225</a>
291
- <a name='L226'></a><a href='#L226'>226</a>
292
- <a name='L227'></a><a href='#L227'>227</a>
293
- <a name='L228'></a><a href='#L228'>228</a>
294
- <a name='L229'></a><a href='#L229'>229</a>
295
- <a name='L230'></a><a href='#L230'>230</a>
296
- <a name='L231'></a><a href='#L231'>231</a>
297
- <a name='L232'></a><a href='#L232'>232</a>
298
- <a name='L233'></a><a href='#L233'>233</a>
299
- <a name='L234'></a><a href='#L234'>234</a>
300
- <a name='L235'></a><a href='#L235'>235</a>
301
- <a name='L236'></a><a href='#L236'>236</a>
302
- <a name='L237'></a><a href='#L237'>237</a>
303
- <a name='L238'></a><a href='#L238'>238</a>
304
- <a name='L239'></a><a href='#L239'>239</a>
305
- <a name='L240'></a><a href='#L240'>240</a>
306
- <a name='L241'></a><a href='#L241'>241</a>
307
- <a name='L242'></a><a href='#L242'>242</a>
308
- <a name='L243'></a><a href='#L243'>243</a>
309
- <a name='L244'></a><a href='#L244'>244</a>
310
- <a name='L245'></a><a href='#L245'>245</a>
311
- <a name='L246'></a><a href='#L246'>246</a>
312
- <a name='L247'></a><a href='#L247'>247</a>
313
- <a name='L248'></a><a href='#L248'>248</a>
314
- <a name='L249'></a><a href='#L249'>249</a>
315
- <a name='L250'></a><a href='#L250'>250</a>
316
- <a name='L251'></a><a href='#L251'>251</a>
317
- <a name='L252'></a><a href='#L252'>252</a>
318
- <a name='L253'></a><a href='#L253'>253</a>
319
- <a name='L254'></a><a href='#L254'>254</a>
320
- <a name='L255'></a><a href='#L255'>255</a>
321
- <a name='L256'></a><a href='#L256'>256</a>
322
- <a name='L257'></a><a href='#L257'>257</a>
323
- <a name='L258'></a><a href='#L258'>258</a>
324
- <a name='L259'></a><a href='#L259'>259</a>
325
- <a name='L260'></a><a href='#L260'>260</a>
326
- <a name='L261'></a><a href='#L261'>261</a>
327
- <a name='L262'></a><a href='#L262'>262</a>
328
- <a name='L263'></a><a href='#L263'>263</a>
329
- <a name='L264'></a><a href='#L264'>264</a>
330
- <a name='L265'></a><a href='#L265'>265</a>
331
- <a name='L266'></a><a href='#L266'>266</a>
332
- <a name='L267'></a><a href='#L267'>267</a>
333
- <a name='L268'></a><a href='#L268'>268</a>
334
- <a name='L269'></a><a href='#L269'>269</a>
335
- <a name='L270'></a><a href='#L270'>270</a>
336
- <a name='L271'></a><a href='#L271'>271</a>
337
- <a name='L272'></a><a href='#L272'>272</a>
338
- <a name='L273'></a><a href='#L273'>273</a>
339
- <a name='L274'></a><a href='#L274'>274</a>
340
- <a name='L275'></a><a href='#L275'>275</a>
341
- <a name='L276'></a><a href='#L276'>276</a>
342
- <a name='L277'></a><a href='#L277'>277</a>
343
- <a name='L278'></a><a href='#L278'>278</a>
344
- <a name='L279'></a><a href='#L279'>279</a>
345
- <a name='L280'></a><a href='#L280'>280</a>
346
- <a name='L281'></a><a href='#L281'>281</a>
347
- <a name='L282'></a><a href='#L282'>282</a>
348
- <a name='L283'></a><a href='#L283'>283</a>
349
- <a name='L284'></a><a href='#L284'>284</a>
350
- <a name='L285'></a><a href='#L285'>285</a>
351
- <a name='L286'></a><a href='#L286'>286</a>
352
- <a name='L287'></a><a href='#L287'>287</a>
353
- <a name='L288'></a><a href='#L288'>288</a>
354
- <a name='L289'></a><a href='#L289'>289</a>
355
- <a name='L290'></a><a href='#L290'>290</a>
356
- <a name='L291'></a><a href='#L291'>291</a>
357
- <a name='L292'></a><a href='#L292'>292</a>
358
- <a name='L293'></a><a href='#L293'>293</a>
359
- <a name='L294'></a><a href='#L294'>294</a>
360
- <a name='L295'></a><a href='#L295'>295</a>
361
- <a name='L296'></a><a href='#L296'>296</a>
362
- <a name='L297'></a><a href='#L297'>297</a>
363
- <a name='L298'></a><a href='#L298'>298</a>
364
- <a name='L299'></a><a href='#L299'>299</a>
365
- <a name='L300'></a><a href='#L300'>300</a>
366
- <a name='L301'></a><a href='#L301'>301</a>
367
- <a name='L302'></a><a href='#L302'>302</a>
368
- <a name='L303'></a><a href='#L303'>303</a>
369
- <a name='L304'></a><a href='#L304'>304</a>
370
- <a name='L305'></a><a href='#L305'>305</a>
371
- <a name='L306'></a><a href='#L306'>306</a>
372
- <a name='L307'></a><a href='#L307'>307</a>
373
- <a name='L308'></a><a href='#L308'>308</a>
374
- <a name='L309'></a><a href='#L309'>309</a>
375
- <a name='L310'></a><a href='#L310'>310</a>
376
- <a name='L311'></a><a href='#L311'>311</a>
377
- <a name='L312'></a><a href='#L312'>312</a>
378
- <a name='L313'></a><a href='#L313'>313</a>
379
- <a name='L314'></a><a href='#L314'>314</a>
380
- <a name='L315'></a><a href='#L315'>315</a>
381
- <a name='L316'></a><a href='#L316'>316</a>
382
- <a name='L317'></a><a href='#L317'>317</a>
383
- <a name='L318'></a><a href='#L318'>318</a>
384
- <a name='L319'></a><a href='#L319'>319</a>
385
- <a name='L320'></a><a href='#L320'>320</a>
386
- <a name='L321'></a><a href='#L321'>321</a>
387
- <a name='L322'></a><a href='#L322'>322</a>
388
- <a name='L323'></a><a href='#L323'>323</a>
389
- <a name='L324'></a><a href='#L324'>324</a>
390
- <a name='L325'></a><a href='#L325'>325</a>
391
- <a name='L326'></a><a href='#L326'>326</a>
392
- <a name='L327'></a><a href='#L327'>327</a>
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></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
427
- <span class="cline-any cline-yes">1x</span>
428
- <span class="cline-any cline-neutral">&nbsp;</span>
429
- <span class="cline-any cline-neutral">&nbsp;</span>
430
- <span class="cline-any cline-neutral">&nbsp;</span>
431
- <span class="cline-any cline-neutral">&nbsp;</span>
432
- <span class="cline-any cline-neutral">&nbsp;</span>
433
- <span class="cline-any cline-neutral">&nbsp;</span>
434
- <span class="cline-any cline-neutral">&nbsp;</span>
435
- <span class="cline-any cline-neutral">&nbsp;</span>
436
- <span class="cline-any cline-neutral">&nbsp;</span>
437
- <span class="cline-any cline-neutral">&nbsp;</span>
438
- <span class="cline-any cline-neutral">&nbsp;</span>
439
- <span class="cline-any cline-neutral">&nbsp;</span>
440
- <span class="cline-any cline-neutral">&nbsp;</span>
441
- <span class="cline-any cline-neutral">&nbsp;</span>
442
- <span class="cline-any cline-neutral">&nbsp;</span>
443
- <span class="cline-any cline-neutral">&nbsp;</span>
444
- <span class="cline-any cline-yes">9x</span>
445
- <span class="cline-any cline-yes">16x</span>
446
- <span class="cline-any cline-neutral">&nbsp;</span>
447
- <span class="cline-any cline-neutral">&nbsp;</span>
448
- <span class="cline-any cline-neutral">&nbsp;</span>
449
- <span class="cline-any cline-neutral">&nbsp;</span>
450
- <span class="cline-any cline-neutral">&nbsp;</span>
451
- <span class="cline-any cline-neutral">&nbsp;</span>
452
- <span class="cline-any cline-neutral">&nbsp;</span>
453
- <span class="cline-any cline-neutral">&nbsp;</span>
454
- <span class="cline-any cline-yes">16x</span>
455
- <span class="cline-any cline-neutral">&nbsp;</span>
456
- <span class="cline-any cline-neutral">&nbsp;</span>
457
- <span class="cline-any cline-neutral">&nbsp;</span>
458
- <span class="cline-any cline-neutral">&nbsp;</span>
459
- <span class="cline-any cline-neutral">&nbsp;</span>
460
- <span class="cline-any cline-neutral">&nbsp;</span>
461
- <span class="cline-any cline-neutral">&nbsp;</span>
462
- <span class="cline-any cline-neutral">&nbsp;</span>
463
- <span class="cline-any cline-yes">7x</span>
464
- <span class="cline-any cline-neutral">&nbsp;</span>
465
- <span class="cline-any cline-neutral">&nbsp;</span>
466
- <span class="cline-any cline-neutral">&nbsp;</span>
467
- <span class="cline-any cline-neutral">&nbsp;</span>
468
- <span class="cline-any cline-yes">7x</span>
469
- <span class="cline-any cline-neutral">&nbsp;</span>
470
- <span class="cline-any cline-yes">7x</span>
471
- <span class="cline-any cline-yes">7x</span>
472
- <span class="cline-any cline-neutral">&nbsp;</span>
473
- <span class="cline-any cline-neutral">&nbsp;</span>
474
- <span class="cline-any cline-neutral">&nbsp;</span>
475
- <span class="cline-any cline-neutral">&nbsp;</span>
476
- <span class="cline-any cline-yes">4x</span>
477
- <span class="cline-any cline-neutral">&nbsp;</span>
478
- <span class="cline-any cline-neutral">&nbsp;</span>
479
- <span class="cline-any cline-neutral">&nbsp;</span>
480
- <span class="cline-any cline-neutral">&nbsp;</span>
481
- <span class="cline-any cline-neutral">&nbsp;</span>
482
- <span class="cline-any cline-neutral">&nbsp;</span>
483
- <span class="cline-any cline-neutral">&nbsp;</span>
484
- <span class="cline-any cline-neutral">&nbsp;</span>
485
- <span class="cline-any cline-yes">103x</span>
486
- <span class="cline-any cline-yes">103x</span>
487
- <span class="cline-any cline-neutral">&nbsp;</span>
488
- <span class="cline-any cline-neutral">&nbsp;</span>
489
- <span class="cline-any cline-neutral">&nbsp;</span>
490
- <span class="cline-any cline-neutral">&nbsp;</span>
491
- <span class="cline-any cline-neutral">&nbsp;</span>
492
- <span class="cline-any cline-neutral">&nbsp;</span>
493
- <span class="cline-any cline-yes">6x</span>
494
- <span class="cline-any cline-yes">11x</span>
495
- <span class="cline-any cline-neutral">&nbsp;</span>
496
- <span class="cline-any cline-neutral">&nbsp;</span>
497
- <span class="cline-any cline-neutral">&nbsp;</span>
498
- <span class="cline-any cline-neutral">&nbsp;</span>
499
- <span class="cline-any cline-neutral">&nbsp;</span>
500
- <span class="cline-any cline-neutral">&nbsp;</span>
501
- <span class="cline-any cline-neutral">&nbsp;</span>
502
- <span class="cline-any cline-yes">5x</span>
503
- <span class="cline-any cline-yes">5x</span>
504
- <span class="cline-any cline-neutral">&nbsp;</span>
505
- <span class="cline-any cline-yes">5x</span>
506
- <span class="cline-any cline-yes">5x</span>
507
- <span class="cline-any cline-neutral">&nbsp;</span>
508
- <span class="cline-any cline-neutral">&nbsp;</span>
509
- <span class="cline-any cline-neutral">&nbsp;</span>
510
- <span class="cline-any cline-neutral">&nbsp;</span>
511
- <span class="cline-any cline-yes">3x</span>
512
- <span class="cline-any cline-neutral">&nbsp;</span>
513
- <span class="cline-any cline-neutral">&nbsp;</span>
514
- <span class="cline-any cline-neutral">&nbsp;</span>
515
- <span class="cline-any cline-neutral">&nbsp;</span>
516
- <span class="cline-any cline-neutral">&nbsp;</span>
517
- <span class="cline-any cline-yes">1x</span>
518
- <span class="cline-any cline-neutral">&nbsp;</span>
519
- <span class="cline-any cline-neutral">&nbsp;</span>
520
- <span class="cline-any cline-neutral">&nbsp;</span>
521
- <span class="cline-any cline-neutral">&nbsp;</span>
522
- <span class="cline-any cline-neutral">&nbsp;</span>
523
- <span class="cline-any cline-neutral">&nbsp;</span>
524
- <span class="cline-any cline-neutral">&nbsp;</span>
525
- <span class="cline-any cline-neutral">&nbsp;</span>
526
- <span class="cline-any cline-neutral">&nbsp;</span>
527
- <span class="cline-any cline-neutral">&nbsp;</span>
528
- <span class="cline-any cline-neutral">&nbsp;</span>
529
- <span class="cline-any cline-neutral">&nbsp;</span>
530
- <span class="cline-any cline-neutral">&nbsp;</span>
531
- <span class="cline-any cline-neutral">&nbsp;</span>
532
- <span class="cline-any cline-neutral">&nbsp;</span>
533
- <span class="cline-any cline-neutral">&nbsp;</span>
534
- <span class="cline-any cline-neutral">&nbsp;</span>
535
- <span class="cline-any cline-neutral">&nbsp;</span>
536
- <span class="cline-any cline-neutral">&nbsp;</span>
537
- <span class="cline-any cline-neutral">&nbsp;</span>
538
- <span class="cline-any cline-neutral">&nbsp;</span>
539
- <span class="cline-any cline-neutral">&nbsp;</span>
540
- <span class="cline-any cline-neutral">&nbsp;</span>
541
- <span class="cline-any cline-neutral">&nbsp;</span>
542
- <span class="cline-any cline-neutral">&nbsp;</span>
543
- <span class="cline-any cline-neutral">&nbsp;</span>
544
- <span class="cline-any cline-neutral">&nbsp;</span>
545
- <span class="cline-any cline-neutral">&nbsp;</span>
546
- <span class="cline-any cline-neutral">&nbsp;</span>
547
- <span class="cline-any cline-neutral">&nbsp;</span>
548
- <span class="cline-any cline-neutral">&nbsp;</span>
549
- <span class="cline-any cline-neutral">&nbsp;</span>
550
- <span class="cline-any cline-neutral">&nbsp;</span>
551
- <span class="cline-any cline-neutral">&nbsp;</span>
552
- <span class="cline-any cline-neutral">&nbsp;</span>
553
- <span class="cline-any cline-neutral">&nbsp;</span>
554
- <span class="cline-any cline-neutral">&nbsp;</span>
555
- <span class="cline-any cline-neutral">&nbsp;</span>
556
- <span class="cline-any cline-neutral">&nbsp;</span>
557
- <span class="cline-any cline-neutral">&nbsp;</span>
558
- <span class="cline-any cline-neutral">&nbsp;</span>
559
- <span class="cline-any cline-neutral">&nbsp;</span>
560
- <span class="cline-any cline-neutral">&nbsp;</span>
561
- <span class="cline-any cline-neutral">&nbsp;</span>
562
- <span class="cline-any cline-neutral">&nbsp;</span>
563
- <span class="cline-any cline-neutral">&nbsp;</span>
564
- <span class="cline-any cline-neutral">&nbsp;</span>
565
- <span class="cline-any cline-neutral">&nbsp;</span>
566
- <span class="cline-any cline-yes">45x</span>
567
- <span class="cline-any cline-yes">45x</span>
568
- <span class="cline-any cline-neutral">&nbsp;</span>
569
- <span class="cline-any cline-yes">45x</span>
570
- <span class="cline-any cline-yes">1170x</span>
571
- <span class="cline-any cline-yes">40x</span>
572
- <span class="cline-any cline-neutral">&nbsp;</span>
573
- <span class="cline-any cline-neutral">&nbsp;</span>
574
- <span class="cline-any cline-neutral">&nbsp;</span>
575
- <span class="cline-any cline-neutral">&nbsp;</span>
576
- <span class="cline-any cline-yes">45x</span>
577
- <span class="cline-any cline-neutral">&nbsp;</span>
578
- <span class="cline-any cline-neutral">&nbsp;</span>
579
- <span class="cline-any cline-yes">45x</span>
580
- <span class="cline-any cline-yes">10x</span>
581
- <span class="cline-any cline-neutral">&nbsp;</span>
582
- <span class="cline-any cline-yes">35x</span>
583
- <span class="cline-any cline-yes">7x</span>
584
- <span class="cline-any cline-neutral">&nbsp;</span>
585
- <span class="cline-any cline-yes">28x</span>
586
- <span class="cline-any cline-yes">11x</span>
587
- <span class="cline-any cline-neutral">&nbsp;</span>
588
- <span class="cline-any cline-neutral">&nbsp;</span>
589
- <span class="cline-any cline-yes">45x</span>
590
- <span class="cline-any cline-neutral">&nbsp;</span>
591
- <span class="cline-any cline-neutral">&nbsp;</span>
592
- <span class="cline-any cline-neutral">&nbsp;</span>
593
- <span class="cline-any cline-neutral">&nbsp;</span>
594
- <span class="cline-any cline-neutral">&nbsp;</span>
595
- <span class="cline-any cline-neutral">&nbsp;</span>
596
- <span class="cline-any cline-neutral">&nbsp;</span>
597
- <span class="cline-any cline-neutral">&nbsp;</span>
598
- <span class="cline-any cline-neutral">&nbsp;</span>
599
- <span class="cline-any cline-neutral">&nbsp;</span>
600
- <span class="cline-any cline-neutral">&nbsp;</span>
601
- <span class="cline-any cline-neutral">&nbsp;</span>
602
- <span class="cline-any cline-neutral">&nbsp;</span>
603
- <span class="cline-any cline-neutral">&nbsp;</span>
604
- <span class="cline-any cline-neutral">&nbsp;</span>
605
- <span class="cline-any cline-neutral">&nbsp;</span>
606
- <span class="cline-any cline-neutral">&nbsp;</span>
607
- <span class="cline-any cline-neutral">&nbsp;</span>
608
- <span class="cline-any cline-neutral">&nbsp;</span>
609
- <span class="cline-any cline-neutral">&nbsp;</span>
610
- <span class="cline-any cline-neutral">&nbsp;</span>
611
- <span class="cline-any cline-neutral">&nbsp;</span>
612
- <span class="cline-any cline-neutral">&nbsp;</span>
613
- <span class="cline-any cline-yes">1x</span>
614
- <span class="cline-any cline-yes">1x</span>
615
- <span class="cline-any cline-neutral">&nbsp;</span>
616
- <span class="cline-any cline-yes">1x</span>
617
- <span class="cline-any cline-neutral">&nbsp;</span>
618
- <span class="cline-any cline-neutral">&nbsp;</span>
619
- <span class="cline-any cline-neutral">&nbsp;</span>
620
- <span class="cline-any cline-neutral">&nbsp;</span>
621
- <span class="cline-any cline-neutral">&nbsp;</span>
622
- <span class="cline-any cline-neutral">&nbsp;</span>
623
- <span class="cline-any cline-neutral">&nbsp;</span>
624
- <span class="cline-any cline-neutral">&nbsp;</span>
625
- <span class="cline-any cline-neutral">&nbsp;</span>
626
- <span class="cline-any cline-neutral">&nbsp;</span>
627
- <span class="cline-any cline-neutral">&nbsp;</span>
628
- <span class="cline-any cline-neutral">&nbsp;</span>
629
- <span class="cline-any cline-neutral">&nbsp;</span>
630
- <span class="cline-any cline-neutral">&nbsp;</span>
631
- <span class="cline-any cline-yes">1x</span>
632
- <span class="cline-any cline-no">&nbsp;</span>
633
- <span class="cline-any cline-no">&nbsp;</span>
634
- <span class="cline-any cline-neutral">&nbsp;</span>
635
- <span class="cline-any cline-neutral">&nbsp;</span>
636
- <span class="cline-any cline-yes">1x</span>
637
- <span class="cline-any cline-neutral">&nbsp;</span>
638
- <span class="cline-any cline-neutral">&nbsp;</span>
639
- <span class="cline-any cline-neutral">&nbsp;</span>
640
- <span class="cline-any cline-neutral">&nbsp;</span>
641
- <span class="cline-any cline-neutral">&nbsp;</span>
642
- <span class="cline-any cline-yes">4x</span>
643
- <span class="cline-any cline-neutral">&nbsp;</span>
644
- <span class="cline-any cline-neutral">&nbsp;</span>
645
- <span class="cline-any cline-neutral">&nbsp;</span>
646
- <span class="cline-any cline-neutral">&nbsp;</span>
647
- <span class="cline-any cline-yes">4x</span>
648
- <span class="cline-any cline-neutral">&nbsp;</span>
649
- <span class="cline-any cline-yes">4x</span>
650
- <span class="cline-any cline-neutral">&nbsp;</span>
651
- <span class="cline-any cline-neutral">&nbsp;</span>
652
- <span class="cline-any cline-neutral">&nbsp;</span>
653
- <span class="cline-any cline-neutral">&nbsp;</span>
654
- <span class="cline-any cline-neutral">&nbsp;</span>
655
- <span class="cline-any cline-neutral">&nbsp;</span>
656
- <span class="cline-any cline-neutral">&nbsp;</span>
657
- <span class="cline-any cline-yes">4x</span>
658
- <span class="cline-any cline-no">&nbsp;</span>
659
- <span class="cline-any cline-no">&nbsp;</span>
660
- <span class="cline-any cline-neutral">&nbsp;</span>
661
- <span class="cline-any cline-neutral">&nbsp;</span>
662
- <span class="cline-any cline-neutral">&nbsp;</span>
663
- <span class="cline-any cline-neutral">&nbsp;</span>
664
- <span class="cline-any cline-neutral">&nbsp;</span>
665
- <span class="cline-any cline-neutral">&nbsp;</span>
666
- <span class="cline-any cline-yes">2x</span>
667
- <span class="cline-any cline-neutral">&nbsp;</span>
668
- <span class="cline-any cline-neutral">&nbsp;</span>
669
- <span class="cline-any cline-neutral">&nbsp;</span>
670
- <span class="cline-any cline-yes">2x</span>
671
- <span class="cline-any cline-neutral">&nbsp;</span>
672
- <span class="cline-any cline-yes">2x</span>
673
- <span class="cline-any cline-neutral">&nbsp;</span>
674
- <span class="cline-any cline-neutral">&nbsp;</span>
675
- <span class="cline-any cline-neutral">&nbsp;</span>
676
- <span class="cline-any cline-neutral">&nbsp;</span>
677
- <span class="cline-any cline-neutral">&nbsp;</span>
678
- <span class="cline-any cline-yes">2x</span>
679
- <span class="cline-any cline-yes">1x</span>
680
- <span class="cline-any cline-neutral">&nbsp;</span>
681
- <span class="cline-any cline-yes">2x</span>
682
- <span class="cline-any cline-yes">1x</span>
683
- <span class="cline-any cline-neutral">&nbsp;</span>
684
- <span class="cline-any cline-yes">2x</span>
685
- <span class="cline-any cline-no">&nbsp;</span>
686
- <span class="cline-any cline-neutral">&nbsp;</span>
687
- <span class="cline-any cline-neutral">&nbsp;</span>
688
- <span class="cline-any cline-yes">2x</span>
689
- <span class="cline-any cline-neutral">&nbsp;</span>
690
- <span class="cline-any cline-yes">2x</span>
691
- <span class="cline-any cline-no">&nbsp;</span>
692
- <span class="cline-any cline-no">&nbsp;</span>
693
- <span class="cline-any cline-neutral">&nbsp;</span>
694
- <span class="cline-any cline-neutral">&nbsp;</span>
695
- <span class="cline-any cline-yes">2x</span>
696
- <span class="cline-any cline-neutral">&nbsp;</span>
697
- <span class="cline-any cline-neutral">&nbsp;</span>
698
- <span class="cline-any cline-neutral">&nbsp;</span>
699
- <span class="cline-any cline-neutral">&nbsp;</span>
700
- <span class="cline-any cline-neutral">&nbsp;</span>
701
- <span class="cline-any cline-neutral">&nbsp;</span>
702
- <span class="cline-any cline-neutral">&nbsp;</span>
703
- <span class="cline-any cline-neutral">&nbsp;</span>
704
- <span class="cline-any cline-neutral">&nbsp;</span>
705
- <span class="cline-any cline-neutral">&nbsp;</span>
706
- <span class="cline-any cline-neutral">&nbsp;</span>
707
- <span class="cline-any cline-yes">5x</span>
708
- <span class="cline-any cline-neutral">&nbsp;</span>
709
- <span class="cline-any cline-neutral">&nbsp;</span>
710
- <span class="cline-any cline-neutral">&nbsp;</span>
711
- <span class="cline-any cline-neutral">&nbsp;</span>
712
- <span class="cline-any cline-neutral">&nbsp;</span>
713
- <span class="cline-any cline-neutral">&nbsp;</span>
714
- <span class="cline-any cline-neutral">&nbsp;</span>
715
- <span class="cline-any cline-neutral">&nbsp;</span>
716
- <span class="cline-any cline-neutral">&nbsp;</span>
717
- <span class="cline-any cline-neutral">&nbsp;</span>
718
- <span class="cline-any cline-yes">2x</span>
719
- <span class="cline-any cline-neutral">&nbsp;</span>
720
- <span class="cline-any cline-neutral">&nbsp;</span>
721
- <span class="cline-any cline-neutral">&nbsp;</span>
722
- <span class="cline-any cline-yes">2x</span>
723
- <span class="cline-any cline-yes">2x</span>
724
- <span class="cline-any cline-neutral">&nbsp;</span>
725
- <span class="cline-any cline-neutral">&nbsp;</span>
726
- <span class="cline-any cline-yes">2x</span>
727
- <span class="cline-any cline-neutral">&nbsp;</span>
728
- <span class="cline-any cline-neutral">&nbsp;</span>
729
- <span class="cline-any cline-neutral">&nbsp;</span>
730
- <span class="cline-any cline-neutral">&nbsp;</span>
731
- <span class="cline-any cline-neutral">&nbsp;</span>
732
- <span class="cline-any cline-neutral">&nbsp;</span>
733
- <span class="cline-any cline-yes">2x</span>
734
- <span class="cline-any cline-no">&nbsp;</span>
735
- <span class="cline-any cline-neutral">&nbsp;</span>
736
- <span class="cline-any cline-no">&nbsp;</span>
737
- <span class="cline-any cline-neutral">&nbsp;</span>
738
- <span class="cline-any cline-neutral">&nbsp;</span>
739
- <span class="cline-any cline-yes">2x</span>
740
- <span class="cline-any cline-yes">2x</span>
741
- <span class="cline-any cline-neutral">&nbsp;</span>
742
- <span class="cline-any cline-yes">2x</span>
743
- <span class="cline-any cline-neutral">&nbsp;</span>
744
- <span class="cline-any cline-neutral">&nbsp;</span>
745
- <span class="cline-any cline-neutral">&nbsp;</span>
746
- <span class="cline-any cline-neutral">&nbsp;</span>
747
- <span class="cline-any cline-neutral">&nbsp;</span>
748
- <span class="cline-any cline-neutral">&nbsp;</span>
749
- <span class="cline-any cline-neutral">&nbsp;</span>
750
- <span class="cline-any cline-neutral">&nbsp;</span>
751
- <span class="cline-any cline-yes">1x</span>
752
- <span class="cline-any cline-neutral">&nbsp;</span>
753
- <span class="cline-any cline-neutral">&nbsp;</span>
754
- <span class="cline-any cline-neutral">&nbsp;</span>
755
- <span class="cline-any cline-neutral">&nbsp;</span>
756
- <span class="cline-any cline-neutral">&nbsp;</span>
757
- <span class="cline-any cline-neutral">&nbsp;</span>
758
- <span class="cline-any cline-neutral">&nbsp;</span>
759
- <span class="cline-any cline-neutral">&nbsp;</span>
760
- <span class="cline-any cline-yes">8x</span>
761
- <span class="cline-any cline-yes">8x</span>
762
- <span class="cline-any cline-yes">6x</span>
763
- <span class="cline-any cline-neutral">&nbsp;</span>
764
- <span class="cline-any cline-neutral">&nbsp;</span>
765
- <span class="cline-any cline-neutral">&nbsp;</span>
766
- <span class="cline-any cline-neutral">&nbsp;</span>
767
- <span class="cline-any cline-neutral">&nbsp;</span>
768
- <span class="cline-any cline-yes">4x</span>
769
- <span class="cline-any cline-neutral">&nbsp;</span>
770
- <span class="cline-any cline-neutral">&nbsp;</span>
771
- <span class="cline-any cline-yes">4x</span>
772
- <span class="cline-any cline-yes">3x</span>
773
- <span class="cline-any cline-neutral">&nbsp;</span>
774
- <span class="cline-any cline-neutral">&nbsp;</span>
775
- <span class="cline-any cline-yes">1x</span>
776
- <span class="cline-any cline-yes">1x</span>
777
- <span class="cline-any cline-neutral">&nbsp;</span>
778
- <span class="cline-any cline-yes">1x</span>
779
- <span class="cline-any cline-neutral">&nbsp;</span>
780
- <span class="cline-any cline-yes">1x</span>
781
- <span class="cline-any cline-no">&nbsp;</span>
782
- <span class="cline-any cline-neutral">&nbsp;</span>
783
- <span class="cline-any cline-neutral">&nbsp;</span>
784
- <span class="cline-any cline-yes">1x</span>
785
- <span class="cline-any cline-neutral">&nbsp;</span>
786
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { createHmac, randomBytes, timingSafeEqual } from "crypto";
787
- import { createAdminDb } from "./db";
788
- &nbsp;
789
- // ============ TASK SIGNING (HMAC-SHA256) ============
790
- &nbsp;
791
- export interface SignableTask {
792
- id: string;
793
- user_id: string;
794
- content: string;
795
- stage: string;
796
- engine: string;
797
- created_at: string;
798
- }
799
- &nbsp;
800
- /**
801
- * Create HMAC-SHA256 signature for a task payload
802
- * Used by cloud to sign tasks before dispatch
803
- */
804
- export function signTask(task: SignableTask, secret: string): string {
805
- const payload = JSON.stringify({
806
- id: task.id,
807
- user_id: task.user_id,
808
- content: task.content,
809
- stage: task.stage,
810
- engine: task.engine,
811
- created_at: task.created_at,
812
- });
813
-
814
- return createHmac("sha256", secret)
815
- .update(payload)
816
- .digest("hex");
817
- }
818
- &nbsp;
819
- /**
820
- * Verify task signature (for daemon to validate)
821
- * Uses timing-safe comparison to prevent timing attacks
822
- */
823
- export function verifyTaskSignature(
824
- task: SignableTask,
825
- signature: string,
826
- secret: string
827
- ): boolean {
828
- const expectedSignature = signTask(task, secret);
829
-
830
- try {
831
- return timingSafeEqual(
832
- Buffer.from(signature, "hex"),
833
- Buffer.from(expectedSignature, "hex")
834
- );
835
- } catch {
836
- return false;
837
- }
838
- }
839
- &nbsp;
840
- // ============ DAEMON SECRET MANAGEMENT ============
841
- &nbsp;
842
- /**
843
- * Generate a secure daemon secret (256-bit)
844
- */
845
- export function generateDaemonSecret(): string {
846
- return randomBytes(32).toString("hex");
847
- }
848
- &nbsp;
849
- /**
850
- * Hash daemon secret for storage (using SHA-256)
851
- * Note: In production, consider bcrypt for additional security
852
- */
853
- export function hashDaemonSecret(secret: string): string {
854
- return createHmac("sha256", process.env.SECRET_SALT || <span class="branch-1 cbranch-no" title="branch not covered" >"agx-cloud-salt")</span>
855
- .update(secret)
856
- .digest("hex");
857
- }
858
- &nbsp;
859
- /**
860
- * Verify daemon secret against stored hash
861
- */
862
- export function verifyDaemonSecret(secret: string, hash: string): boolean {
863
- const expectedHash = hashDaemonSecret(secret);
864
-
865
- try {
866
- return timingSafeEqual(
867
- Buffer.from(hash, "hex"),
868
- Buffer.from(expectedHash, "hex")
869
- );
870
- } catch {
871
- return false;
872
- }
873
- }
874
- &nbsp;
875
- // ============ DANGEROUS OPERATION DETECTION ============
876
- &nbsp;
877
- const DANGEROUS_PATTERNS = [
878
- // File system dangers
879
- /rm\s+(-rf?|--recursive)\s+[\/~]/i, // rm -rf /
880
- /rm\s+-rf?\s+\*/i, // rm -rf *
881
- /chmod\s+(777|a\+rwx)/i, // chmod 777
882
- /chown\s+.*\s+\//i, // chown on root
883
- /&gt;\s*\/dev\/sd[a-z]/i, // write to disk device
884
-
885
- // Credential exposure
886
- /\.env/i, // .env files
887
- /credentials?\.json/i, // credential files
888
- /api[_-]?key/i, // API keys
889
- /secret[_-]?key/i, // Secret keys
890
- /private[_-]?key/i, // Private keys
891
- /password/i, // Passwords
892
-
893
- // Network dangers
894
- /curl.*\|\s*(ba)?sh/i, // curl | sh
895
- /wget.*\|\s*(ba)?sh/i, // wget | sh
896
- /nc\s+-l/i, // netcat listener
897
- /socat/i, // socat
898
-
899
- // System dangers
900
- /sudo\s+/i, // sudo commands
901
- /su\s+-/i, // su - (switch user)
902
- /mkfs\./i, // format filesystem
903
- /dd\s+if=/i, // dd command
904
-
905
- // Code execution
906
- /eval\s*\(/i, // eval()
907
- /exec\s*\(/i, // exec()
908
- /child_process/i, // Node child_process
909
- /__import__/i, // Python import
910
-
911
- // Exfiltration
912
- /base64.*&gt;/i, // base64 encode to file
913
- /xxd/i, // hex dump
914
- /tar.*-c.*\|.*curl/i, // tar and send
915
- ];
916
- &nbsp;
917
- export interface DangerousOperationResult {
918
- isDangerous: boolean;
919
- patterns: string[];
920
- severity: "low" | "medium" | "high" | "critical";
921
- }
922
- &nbsp;
923
- /**
924
- * Check if task content contains dangerous operations
925
- */
926
- export function detectDangerousOperations(content: string): DangerousOperationResult {
927
- const matchedPatterns: string[] = [];
928
-
929
- for (const pattern of DANGEROUS_PATTERNS) {
930
- if (pattern.test(content)) {
931
- matchedPatterns.push(pattern.source);
932
- }
933
- }
934
-
935
- // Determine severity based on the original content (not the regex source strings)
936
- let severity: DangerousOperationResult["severity"] = "low";
937
-
938
- // Critical: destructive system commands
939
- if (/rm\s+(-rf?|--recursive)\s*[\/~\*]|sudo\s+|mkfs\.|dd\s+if=/i.test(content)) {
940
- severity = "critical";
941
- // High: remote execution and insecure permissions
942
- } else if (/curl.*\|\s*(ba)?sh|wget.*\|\s*(ba)?sh|chmod\s+(777|a\+rwx)|\.env\b/i.test(content)) {
943
- severity = "high";
944
- // Medium: credential exposure
945
- } else if (/password|api[_-]?key|secret[_-]?key|private[_-]?key|credentials?\.json/i.test(content)) {
946
- severity = "medium";
947
- }
948
-
949
- return {
950
- isDangerous: matchedPatterns.length &gt; 0,
951
- patterns: matchedPatterns,
952
- severity,
953
- };
954
- }
955
- &nbsp;
956
- // ============ AUDIT LOGGING ============
957
- &nbsp;
958
- export interface AuditLogEntry {
959
- user_id: string;
960
- task_id: string;
961
- action: "dispatch" | "execute" | "complete" | "reject" | "fail";
962
- payload: Record&lt;string, unknown&gt;;
963
- signature: string;
964
- ip_address?: string;
965
- user_agent?: string;
966
- result?: "pending" | "success" | "rejected" | "failed";
967
- }
968
- &nbsp;
969
- /**
970
- * Write to immutable audit log
971
- * Only service role can write to this table
972
- */
973
- export async function writeAuditLog(entry: AuditLogEntry): Promise&lt;string&gt; {
974
- const db = createAdminDb();
975
-
976
- const { data, error } = await db
977
- .from("task_audit_log")
978
- .insert({
979
- user_id: entry.user_id,
980
- task_id: entry.task_id,
981
- action: entry.action,
982
- payload: entry.payload,
983
- signature: entry.signature,
984
- ip_address: entry.ip_address,
985
- user_agent: entry.user_agent,
986
- result: entry.result || <span class="branch-1 cbranch-no" title="branch not covered" >"pending",</span>
987
- })
988
- .select("id")
989
- .single();
990
-
991
- <span class="missing-if-branch" title="if path not taken" >I</span>if (error) {
992
- <span class="cstat-no" title="statement not covered" > console.error("Failed to write audit log:", error);</span>
993
- <span class="cstat-no" title="statement not covered" > throw new Error("Audit log write failed");</span>
994
- }
995
-
996
- return data.id;
997
- }
998
- &nbsp;
999
- /**
1000
- * Update audit log with execution result
1001
- */
1002
- export async function updateAuditLogResult(
1003
- auditId: string,
1004
- result: "success" | "rejected" | "failed",
1005
- executedAt?: Date
1006
- ): Promise&lt;void&gt; {
1007
- const db = createAdminDb();
1008
-
1009
- const { error } = await db
1010
- .from("task_audit_log")
1011
- .update({
1012
- result,
1013
- executed_at: executedAt?.toISOString() || new Date().toISOString(),
1014
- })
1015
- .eq("id", auditId);
1016
-
1017
- <span class="missing-if-branch" title="if path not taken" >I</span>if (error) {
1018
- <span class="cstat-no" title="statement not covered" > console.error("Failed to update audit log:", error);</span>
1019
- <span class="cstat-no" title="statement not covered" > throw new Error("Audit log update failed");</span>
1020
- }
1021
- }
1022
- &nbsp;
1023
- /**
1024
- * Get audit logs for a user
1025
- */
1026
- export async function getAuditLogs(
1027
- userId: string,
1028
- options?: { limit?: number; offset?: number; taskId?: string }
1029
- ): Promise&lt;AuditLogEntry[]&gt; {
1030
- const db = createAdminDb();
1031
-
1032
- let query = db
1033
- .from("task_audit_log")
1034
- .select("*")
1035
- .eq("user_id", userId)
1036
- .order("dispatched_at", { ascending: false });
1037
-
1038
- if (options?.taskId) {
1039
- query = query.eq("task_id", options.taskId);
1040
- }
1041
- if (options?.limit) {
1042
- query = query.limit(options.limit);
1043
- }
1044
- <span class="missing-if-branch" title="if path not taken" >I</span>if (options?.offset) {
1045
- <span class="cstat-no" title="statement not covered" > query = query.range(options.offset, options.offset + (options.limit || 50) - 1);</span>
1046
- }
1047
-
1048
- const { data, error } = await query;
1049
-
1050
- <span class="missing-if-branch" title="if path not taken" >I</span>if (error) {
1051
- <span class="cstat-no" title="statement not covered" > console.error("Failed to get audit logs:", error);</span>
1052
- <span class="cstat-no" title="statement not covered" > throw error;</span>
1053
- }
1054
-
1055
- return data || [];
1056
- }
1057
- &nbsp;
1058
- // ============ RATE LIMITING ============
1059
- &nbsp;
1060
- export interface RateLimitConfig {
1061
- endpoint: string;
1062
- maxRequests: number;
1063
- windowSeconds: number;
1064
- }
1065
- &nbsp;
1066
- // Default rate limits per endpoint
1067
- export const RATE_LIMITS: Record&lt;string, RateLimitConfig&gt; = {
1068
- "tasks/create": { endpoint: "tasks/create", maxRequests: 10, windowSeconds: 60 },
1069
- "chat/message": { endpoint: "chat/message", maxRequests: 100, windowSeconds: 3600 },
1070
- "daemon/poll": { endpoint: "daemon/poll", maxRequests: 60, windowSeconds: 60 },
1071
- "default": { endpoint: "default", maxRequests: 100, windowSeconds: 60 },
1072
- };
1073
- &nbsp;
1074
- /**
1075
- * Check if request is within rate limit
1076
- * Returns true if allowed, false if rate limited
1077
- */
1078
- export async function checkRateLimit(
1079
- userId: string,
1080
- endpoint: string
1081
- ): Promise&lt;{ allowed: boolean; remaining: number; resetAt: Date }&gt; {
1082
- const config = RATE_LIMITS[endpoint] || RATE_LIMITS["default"];
1083
- const db = createAdminDb();
1084
-
1085
- // Call the database function
1086
- const { data, error } = await db.rpc("check_rate_limit", {
1087
- p_user_id: userId,
1088
- p_endpoint: config.endpoint,
1089
- p_max_requests: config.maxRequests,
1090
- p_window_seconds: config.windowSeconds,
1091
- });
1092
-
1093
- <span class="missing-if-branch" title="if path not taken" >I</span>if (error) {
1094
- <span class="cstat-no" title="statement not covered" > console.error("Rate limit check failed:", error);</span>
1095
- // Fail open (allow) on error to prevent blocking users
1096
- <span class="cstat-no" title="statement not covered" > return { allowed: true, remaining: config.maxRequests, resetAt: new Date() };</span>
1097
- }
1098
-
1099
- const allowed = data as boolean;
1100
- const resetAt = new Date(Date.now() + config.windowSeconds * 1000);
1101
-
1102
- return {
1103
- allowed,
1104
- remaining: allowed ? config.maxRequests - 1 : <span class="branch-1 cbranch-no" title="branch not covered" >0,</span>
1105
- resetAt,
1106
- };
1107
- }
1108
- &nbsp;
1109
- // ============ ORIGIN VALIDATION ============
1110
- &nbsp;
1111
- const ALLOWED_ORIGINS = [
1112
- "https://agx-cloud.vercel.app",
1113
- "http://localhost:3000",
1114
- "http://localhost:3333",
1115
- ];
1116
- &nbsp;
1117
- /**
1118
- * Validate request origin
1119
- */
1120
- export function isValidOrigin(origin: string | null): boolean {
1121
- if (!origin) return false;
1122
- return ALLOWED_ORIGINS.includes(origin);
1123
- }
1124
- &nbsp;
1125
- /**
1126
- * Validate bearer token and get user
1127
- */
1128
- export async function validateBearerToken(
1129
- authHeader: string | null
1130
- ): Promise&lt;{ valid: boolean; userId?: string }&gt; {
1131
- if (!authHeader?.startsWith("Bearer ")) {
1132
- return { valid: false };
1133
- }
1134
-
1135
- const token = authHeader.slice(7);
1136
- const db = createAdminDb();
1137
-
1138
- const { data: { user }, error } = await db.auth.getUser(token);
1139
-
1140
- <span class="missing-if-branch" title="if path not taken" >I</span>if (error || !user) {
1141
- <span class="cstat-no" title="statement not covered" > return { valid: false };</span>
1142
- }
1143
-
1144
- return { valid: true, userId: user.id };
1145
- }
1146
- &nbsp;</pre></td></tr></table></pre>
1147
-
1148
- <div class='push'></div><!-- for sticky footer -->
1149
- </div><!-- /wrapper -->
1150
- <div class='footer quiet pad2 space-top1 center small'>
1151
- Code coverage generated by
1152
- <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1153
- at 2026-02-05T12:19:35.287Z
1154
- </div>
1155
- <script src="../prettify.js"></script>
1156
- <script>
1157
- window.onload = function () {
1158
- prettyPrint();
1159
- };
1160
- </script>
1161
- <script src="../sorter.js"></script>
1162
- <script src="../block-navigation.js"></script>
1163
- </body>
1164
- </html>
1165
-