@atlascrew/apparatus 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/bin/apparatus.mjs +2 -0
  2. package/certs/server.crt +17 -0
  3. package/certs/server.key +28 -0
  4. package/dist/ai/client.js +104 -0
  5. package/dist/ai/client.js.map +1 -0
  6. package/dist/ai/personas.js +104 -0
  7. package/dist/ai/personas.js.map +1 -0
  8. package/dist/ai/redteam.js +1404 -0
  9. package/dist/ai/redteam.js.map +1 -0
  10. package/dist/ai/report-store.js +309 -0
  11. package/dist/ai/report-store.js.map +1 -0
  12. package/dist/app.js +525 -0
  13. package/dist/app.js.map +1 -0
  14. package/dist/attack-sim.js +69 -0
  15. package/dist/attack-sim.js.map +1 -0
  16. package/dist/attacker-tracker.js +276 -0
  17. package/dist/attacker-tracker.js.map +1 -0
  18. package/dist/blackhole.js +95 -0
  19. package/dist/blackhole.js.map +1 -0
  20. package/dist/chaos.js +88 -0
  21. package/dist/chaos.js.map +1 -0
  22. package/dist/cluster.js +462 -0
  23. package/dist/cluster.js.map +1 -0
  24. package/dist/config.js +61 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/deception.js +205 -0
  27. package/dist/deception.js.map +1 -0
  28. package/dist/demo-mode.js +109 -0
  29. package/dist/demo-mode.js.map +1 -0
  30. package/dist/dist-dashboard/assets/index-BsMhEnGu.js +648 -0
  31. package/dist/dist-dashboard/assets/index-CNOkYC_Q.css +10 -0
  32. package/dist/dist-dashboard/assets/index-CW2grvPC.js +648 -0
  33. package/dist/dist-dashboard/assets/logo/apparatus-favicon.svg +15 -0
  34. package/dist/dist-dashboard/assets/logo/apparatus-icon-dark.svg +24 -0
  35. package/dist/dist-dashboard/assets/logo/apparatus-icon-light.svg +24 -0
  36. package/dist/dist-dashboard/assets/logo/apparatus-logo-512.png +0 -0
  37. package/dist/dist-dashboard/assets/logo/apparatus-logo-dark.svg +18 -0
  38. package/dist/dist-dashboard/assets/logo/apparatus-logo.svg +17 -0
  39. package/dist/dist-dashboard/assets/logo/apple-touch-icon.png +0 -0
  40. package/dist/dist-dashboard/assets/logo/favicon-192.png +0 -0
  41. package/dist/dist-dashboard/assets/logo/favicon-32.png +0 -0
  42. package/dist/dist-dashboard/assets/logo/favicon.ico +0 -0
  43. package/dist/dist-dashboard/assets/logo/icon-192.png +0 -0
  44. package/dist/dist-dashboard/assets/logo/icon-512.png +0 -0
  45. package/dist/dist-dashboard/assets/logo/icon-light-512.png +0 -0
  46. package/dist/dist-dashboard/assets/react-vendor-DpRMSntD.js +1 -0
  47. package/dist/dist-dashboard/assets/router-DSc5pRwN.js +59 -0
  48. package/dist/dist-dashboard/docs-index.json +1577 -0
  49. package/dist/dist-dashboard/index.html +21 -0
  50. package/dist/dlp.js +40 -0
  51. package/dist/dlp.js.map +1 -0
  52. package/dist/drills.js +770 -0
  53. package/dist/drills.js.map +1 -0
  54. package/dist/echoHandler.js +113 -0
  55. package/dist/echoHandler.js.map +1 -0
  56. package/dist/escape/index.js +225 -0
  57. package/dist/escape/index.js.map +1 -0
  58. package/dist/escape/methods/dns.js +74 -0
  59. package/dist/escape/methods/dns.js.map +1 -0
  60. package/dist/escape/methods/http.js +81 -0
  61. package/dist/escape/methods/http.js.map +1 -0
  62. package/dist/escape/methods/icmp.js +36 -0
  63. package/dist/escape/methods/icmp.js.map +1 -0
  64. package/dist/escape/methods/tcp.js +38 -0
  65. package/dist/escape/methods/tcp.js.map +1 -0
  66. package/dist/escape/methods/udp.js +27 -0
  67. package/dist/escape/methods/udp.js.map +1 -0
  68. package/dist/escape/methods/websocket.js +37 -0
  69. package/dist/escape/methods/websocket.js.map +1 -0
  70. package/dist/forensics.js +111 -0
  71. package/dist/forensics.js.map +1 -0
  72. package/dist/generator.js +67 -0
  73. package/dist/generator.js.map +1 -0
  74. package/dist/ghosting.js +414 -0
  75. package/dist/ghosting.js.map +1 -0
  76. package/dist/graphql.js +44 -0
  77. package/dist/graphql.js.map +1 -0
  78. package/dist/history.js +40 -0
  79. package/dist/history.js.map +1 -0
  80. package/dist/imposter/creds.js +16 -0
  81. package/dist/imposter/creds.js.map +1 -0
  82. package/dist/imposter/index.js +44 -0
  83. package/dist/imposter/index.js.map +1 -0
  84. package/dist/imposter/providers/aws.js +103 -0
  85. package/dist/imposter/providers/aws.js.map +1 -0
  86. package/dist/imposter/providers/gcp.js +26 -0
  87. package/dist/imposter/providers/gcp.js.map +1 -0
  88. package/dist/index.js +53 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/infra-debug.js +68 -0
  91. package/dist/infra-debug.js.map +1 -0
  92. package/dist/jwt-debug.js +272 -0
  93. package/dist/jwt-debug.js.map +1 -0
  94. package/dist/kv.js +22 -0
  95. package/dist/kv.js.map +1 -0
  96. package/dist/lib/generators.js +43 -0
  97. package/dist/lib/generators.js.map +1 -0
  98. package/dist/lib/json.js +26 -0
  99. package/dist/lib/json.js.map +1 -0
  100. package/dist/logger.js +9 -0
  101. package/dist/logger.js.map +1 -0
  102. package/dist/metrics.js +20 -0
  103. package/dist/metrics.js.map +1 -0
  104. package/dist/mtd.js +30 -0
  105. package/dist/mtd.js.map +1 -0
  106. package/dist/oidc.js +69 -0
  107. package/dist/oidc.js.map +1 -0
  108. package/dist/persistence/cluster-state.js +47 -0
  109. package/dist/persistence/cluster-state.js.map +1 -0
  110. package/dist/persistence/deception-history.js +65 -0
  111. package/dist/persistence/deception-history.js.map +1 -0
  112. package/dist/persistence/drill-runs.js +138 -0
  113. package/dist/persistence/drill-runs.js.map +1 -0
  114. package/dist/persistence/request-history.js +41 -0
  115. package/dist/persistence/request-history.js.map +1 -0
  116. package/dist/persistence/scenario-catalog.js +73 -0
  117. package/dist/persistence/scenario-catalog.js.map +1 -0
  118. package/dist/persistence/status.js +51 -0
  119. package/dist/persistence/status.js.map +1 -0
  120. package/dist/persistence/tarpit-state.js +47 -0
  121. package/dist/persistence/tarpit-state.js.map +1 -0
  122. package/dist/persistence/webhook-store.js +69 -0
  123. package/dist/persistence/webhook-store.js.map +1 -0
  124. package/dist/proxy.js +28 -0
  125. package/dist/proxy.js.map +1 -0
  126. package/dist/ratelimit.js +32 -0
  127. package/dist/ratelimit.js.map +1 -0
  128. package/dist/redteam.js +442 -0
  129. package/dist/redteam.js.map +1 -0
  130. package/dist/scenarios.js +229 -0
  131. package/dist/scenarios.js.map +1 -0
  132. package/dist/scripting.js +30 -0
  133. package/dist/scripting.js.map +1 -0
  134. package/dist/self-healing.js +42 -0
  135. package/dist/self-healing.js.map +1 -0
  136. package/dist/sentinel.js +50 -0
  137. package/dist/sentinel.js.map +1 -0
  138. package/dist/server-bad-ssl.js +47 -0
  139. package/dist/server-bad-ssl.js.map +1 -0
  140. package/dist/server-grpc.js +66 -0
  141. package/dist/server-grpc.js.map +1 -0
  142. package/dist/server-http1.js +5 -0
  143. package/dist/server-http1.js.map +1 -0
  144. package/dist/server-http2.js +27 -0
  145. package/dist/server-http2.js.map +1 -0
  146. package/dist/server-icap.js +46 -0
  147. package/dist/server-icap.js.map +1 -0
  148. package/dist/server-l4.js +30 -0
  149. package/dist/server-l4.js.map +1 -0
  150. package/dist/server-mqtt.js +29 -0
  151. package/dist/server-mqtt.js.map +1 -0
  152. package/dist/server-protocols.js +18 -0
  153. package/dist/server-protocols.js.map +1 -0
  154. package/dist/server-redis.js +112 -0
  155. package/dist/server-redis.js.map +1 -0
  156. package/dist/server-smtp.js +66 -0
  157. package/dist/server-smtp.js.map +1 -0
  158. package/dist/server-syslog.js +23 -0
  159. package/dist/server-syslog.js.map +1 -0
  160. package/dist/server-ws.js +18 -0
  161. package/dist/server-ws.js.map +1 -0
  162. package/dist/sidecar/chaos/engine.js +41 -0
  163. package/dist/sidecar/chaos/engine.js.map +1 -0
  164. package/dist/sidecar/index.js +98 -0
  165. package/dist/sidecar/index.js.map +1 -0
  166. package/dist/simulator/dependency-graph.js +102 -0
  167. package/dist/simulator/dependency-graph.js.map +1 -0
  168. package/dist/simulator/supply-chain.js +67 -0
  169. package/dist/simulator/supply-chain.js.map +1 -0
  170. package/dist/sink.js +24 -0
  171. package/dist/sink.js.map +1 -0
  172. package/dist/sse-broadcast.js +105 -0
  173. package/dist/sse-broadcast.js.map +1 -0
  174. package/dist/swagger.js +309 -0
  175. package/dist/swagger.js.map +1 -0
  176. package/dist/sysinfo.js +36 -0
  177. package/dist/sysinfo.js.map +1 -0
  178. package/dist/tarpit.js +126 -0
  179. package/dist/tarpit.js.map +1 -0
  180. package/dist/tool-executor.js +315 -0
  181. package/dist/tool-executor.js.map +1 -0
  182. package/dist/tui/api-client.js +341 -0
  183. package/dist/tui/api-client.js.map +1 -0
  184. package/dist/tui/core/action-handler.js +302 -0
  185. package/dist/tui/core/action-handler.js.map +1 -0
  186. package/dist/tui/core/index.js +18 -0
  187. package/dist/tui/core/index.js.map +1 -0
  188. package/dist/tui/core/keyboard.js +329 -0
  189. package/dist/tui/core/keyboard.js.map +1 -0
  190. package/dist/tui/core/modal.js +397 -0
  191. package/dist/tui/core/modal.js.map +1 -0
  192. package/dist/tui/core/screen-manager.js +262 -0
  193. package/dist/tui/core/screen-manager.js.map +1 -0
  194. package/dist/tui/core/store.js +254 -0
  195. package/dist/tui/core/store.js.map +1 -0
  196. package/dist/tui/core/widget.js +167 -0
  197. package/dist/tui/core/widget.js.map +1 -0
  198. package/dist/tui/dashboard.js +649 -0
  199. package/dist/tui/dashboard.js.map +1 -0
  200. package/dist/tui/index.js +118 -0
  201. package/dist/tui/index.js.map +1 -0
  202. package/dist/tui/modals/add-rule-modal.js +190 -0
  203. package/dist/tui/modals/add-rule-modal.js.map +1 -0
  204. package/dist/tui/modals/dlp-output-modal.js +102 -0
  205. package/dist/tui/modals/dlp-output-modal.js.map +1 -0
  206. package/dist/tui/modals/dns-form-modal.js +26 -0
  207. package/dist/tui/modals/dns-form-modal.js.map +1 -0
  208. package/dist/tui/modals/ghost-config-modal.js +35 -0
  209. package/dist/tui/modals/ghost-config-modal.js.map +1 -0
  210. package/dist/tui/modals/har-results-modal.js +41 -0
  211. package/dist/tui/modals/har-results-modal.js.map +1 -0
  212. package/dist/tui/modals/index.js +15 -0
  213. package/dist/tui/modals/index.js.map +1 -0
  214. package/dist/tui/modals/jwt-decode-modal.js +45 -0
  215. package/dist/tui/modals/jwt-decode-modal.js.map +1 -0
  216. package/dist/tui/modals/jwt-mint-modal.js +70 -0
  217. package/dist/tui/modals/jwt-mint-modal.js.map +1 -0
  218. package/dist/tui/modals/ping-form-modal.js +19 -0
  219. package/dist/tui/modals/ping-form-modal.js.map +1 -0
  220. package/dist/tui/modals/redteam-results-modal.js +43 -0
  221. package/dist/tui/modals/redteam-results-modal.js.map +1 -0
  222. package/dist/tui/modals/scan-form-modal.js +26 -0
  223. package/dist/tui/modals/scan-form-modal.js.map +1 -0
  224. package/dist/tui/screens/defense-screen.js +281 -0
  225. package/dist/tui/screens/defense-screen.js.map +1 -0
  226. package/dist/tui/screens/forensics-screen.js +81 -0
  227. package/dist/tui/screens/forensics-screen.js.map +1 -0
  228. package/dist/tui/screens/index.js +140 -0
  229. package/dist/tui/screens/index.js.map +1 -0
  230. package/dist/tui/screens/system-screen.js +81 -0
  231. package/dist/tui/screens/system-screen.js.map +1 -0
  232. package/dist/tui/screens/testing-screen.js +429 -0
  233. package/dist/tui/screens/testing-screen.js.map +1 -0
  234. package/dist/tui/screens/traffic-screen.js +76 -0
  235. package/dist/tui/screens/traffic-screen.js.map +1 -0
  236. package/dist/tui/sse-client.js +130 -0
  237. package/dist/tui/sse-client.js.map +1 -0
  238. package/dist/tui/state/metrics-buffer.js +195 -0
  239. package/dist/tui/state/metrics-buffer.js.map +1 -0
  240. package/dist/tui/state/metrics-buffer.test.js +102 -0
  241. package/dist/tui/state/metrics-buffer.test.js.map +1 -0
  242. package/dist/tui/theme.js +136 -0
  243. package/dist/tui/theme.js.map +1 -0
  244. package/dist/tui/types.js +6 -0
  245. package/dist/tui/types.js.map +1 -0
  246. package/dist/tui/widgets/chaos-widget.js +152 -0
  247. package/dist/tui/widgets/chaos-widget.js.map +1 -0
  248. package/dist/tui/widgets/cluster-widget.js +156 -0
  249. package/dist/tui/widgets/cluster-widget.js.map +1 -0
  250. package/dist/tui/widgets/dlp-widget.js +161 -0
  251. package/dist/tui/widgets/dlp-widget.js.map +1 -0
  252. package/dist/tui/widgets/ghost-widget.js +169 -0
  253. package/dist/tui/widgets/ghost-widget.js.map +1 -0
  254. package/dist/tui/widgets/har-widget.js +173 -0
  255. package/dist/tui/widgets/har-widget.js.map +1 -0
  256. package/dist/tui/widgets/index.js +122 -0
  257. package/dist/tui/widgets/index.js.map +1 -0
  258. package/dist/tui/widgets/jwt-widget.js +177 -0
  259. package/dist/tui/widgets/jwt-widget.js.map +1 -0
  260. package/dist/tui/widgets/kv-widget.js +261 -0
  261. package/dist/tui/widgets/kv-widget.js.map +1 -0
  262. package/dist/tui/widgets/mtd-widget.js +181 -0
  263. package/dist/tui/widgets/mtd-widget.js.map +1 -0
  264. package/dist/tui/widgets/netdiag-widget.js +155 -0
  265. package/dist/tui/widgets/netdiag-widget.js.map +1 -0
  266. package/dist/tui/widgets/oidc-widget.js +162 -0
  267. package/dist/tui/widgets/oidc-widget.js.map +1 -0
  268. package/dist/tui/widgets/pcap-widget.js +239 -0
  269. package/dist/tui/widgets/pcap-widget.js.map +1 -0
  270. package/dist/tui/widgets/redteam-widget.js +155 -0
  271. package/dist/tui/widgets/redteam-widget.js.map +1 -0
  272. package/dist/tui/widgets/rps-gauge-widget.js +124 -0
  273. package/dist/tui/widgets/rps-gauge-widget.js.map +1 -0
  274. package/dist/tui/widgets/sentinel-widget.js +171 -0
  275. package/dist/tui/widgets/sentinel-widget.js.map +1 -0
  276. package/dist/tui/widgets/sparklines-widget.js +127 -0
  277. package/dist/tui/widgets/sparklines-widget.js.map +1 -0
  278. package/dist/tui/widgets/sysinfo-widget.js +197 -0
  279. package/dist/tui/widgets/sysinfo-widget.js.map +1 -0
  280. package/dist/tui/widgets/traffic-chart-widget.js +170 -0
  281. package/dist/tui/widgets/traffic-chart-widget.js.map +1 -0
  282. package/dist/tui/widgets/webhook-widget.js +259 -0
  283. package/dist/tui/widgets/webhook-widget.js.map +1 -0
  284. package/dist/utils/ip.js +18 -0
  285. package/dist/utils/ip.js.map +1 -0
  286. package/dist/victim/index.js +71 -0
  287. package/dist/victim/index.js.map +1 -0
  288. package/dist/webhook.js +88 -0
  289. package/dist/webhook.js.map +1 -0
  290. package/package.json +90 -0
  291. package/proto/echo.proto +19 -0
@@ -0,0 +1,103 @@
1
+ import { Router } from "express";
2
+ import { generateAwsCreds } from "../creds.js";
3
+ import { logger } from "../../logger.js";
4
+ const router = Router();
5
+ const START_TIME = new Date().toISOString();
6
+ // Simulated State
7
+ let instanceId = `i-${Math.random().toString(16).substring(2, 10)}`;
8
+ let region = process.env.IMPOSTER_REGION || "us-east-1";
9
+ let az = `${region}a`;
10
+ let privateIp = "10.0.0.50";
11
+ let instanceType = "t3.micro";
12
+ // Honey Creds are generated once per session usually, or rotated
13
+ const currentCreds = generateAwsCreds("imposter-role");
14
+ // IMDSv2 Token (Mock)
15
+ const activeTokens = new Set();
16
+ router.put("/latest/api/token", (req, res) => {
17
+ const ttl = req.headers["x-aws-ec2-metadata-token-ttl-seconds"];
18
+ const token = Buffer.from(`imposterv2-${Date.now()}`).toString("base64");
19
+ activeTokens.add(token);
20
+ logger.info({ ip: req.ip, ttl }, "Cloud Imposter: Minted IMDSv2 Token");
21
+ res.send(token);
22
+ });
23
+ // Middleware to check IMDSv2 Token if strict mode is simulated
24
+ // (Skipping strict enforcement to be compatible with v1 apps, but logging usage)
25
+ // Metadata Categories
26
+ router.get("/latest/meta-data/", (req, res) => {
27
+ res.send(`ami-id
28
+ ami-launch-index
29
+ ami-manifest-path
30
+ block-device-mapping/
31
+ events/
32
+ hostname
33
+ iam/
34
+ instance-action
35
+ instance-id
36
+ instance-type
37
+ local-hostname
38
+ local-ipv4
39
+ mac
40
+ metrics/
41
+ network/
42
+ placement/
43
+ profile
44
+ public-hostname
45
+ public-ipv4
46
+ public-keys/
47
+ reservation-id
48
+ security-groups
49
+ services/
50
+ spot/`);
51
+ });
52
+ router.get("/latest/meta-data/instance-id", (req, res) => res.send(instanceId));
53
+ router.get("/latest/meta-data/instance-type", (req, res) => res.send(instanceType));
54
+ router.get("/latest/meta-data/local-ipv4", (req, res) => res.send(privateIp));
55
+ router.get("/latest/meta-data/placement/availability-zone", (req, res) => res.send(az));
56
+ router.get("/latest/meta-data/placement/region", (req, res) => res.send(region));
57
+ // IAM Credentials (The Honey)
58
+ router.get("/latest/meta-data/iam/security-credentials", (req, res) => {
59
+ res.send("imposter-role");
60
+ });
61
+ router.get("/latest/meta-data/iam/security-credentials/:role", (req, res) => {
62
+ const role = req.params.role;
63
+ logger.warn({ ip: req.ip, role }, "Cloud Imposter: Client requested IAM Credentials (Honey-Creds served)");
64
+ res.json({
65
+ Code: "Success",
66
+ LastUpdated: START_TIME,
67
+ Type: "AWS-HMAC",
68
+ AccessKeyId: currentCreds.AccessKeyId,
69
+ SecretAccessKey: currentCreds.SecretAccessKey,
70
+ Token: currentCreds.Token,
71
+ Expiration: currentCreds.Expiration
72
+ });
73
+ });
74
+ // Spot Termination Simulation
75
+ // To simulate termination, the user can call a control endpoint, or we just randomly return it?
76
+ // Let's implement a control mechanism later. For now, it returns 404 (no action) unless toggled.
77
+ let terminationTime = null;
78
+ router.get("/latest/meta-data/spot/instance-action", (req, res) => {
79
+ if (terminationTime) {
80
+ res.json({
81
+ action: "terminate",
82
+ time: terminationTime
83
+ });
84
+ }
85
+ else {
86
+ res.status(404).send();
87
+ }
88
+ });
89
+ // Admin Control for Simulation
90
+ router.post("/_imposter/aws/terminate", (req, res) => {
91
+ // Simulate a spot termination notice 2 minutes from now
92
+ const now = new Date();
93
+ now.setMinutes(now.getMinutes() + 2);
94
+ terminationTime = now.toISOString();
95
+ logger.info("Cloud Imposter: Scheduled Spot Termination");
96
+ res.json({ status: "scheduled", time: terminationTime });
97
+ });
98
+ router.post("/_imposter/aws/reset", (req, res) => {
99
+ terminationTime = null;
100
+ res.json({ status: "cleared" });
101
+ });
102
+ export const awsRouter = router;
103
+ //# sourceMappingURL=aws.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws.js","sourceRoot":"","sources":["../../../src/imposter/providers/aws.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { Router } from "express";
2
+ import { logger } from "../../logger.js";
3
+ const router = Router();
4
+ // GCP requires this header
5
+ const HEADER_CHECK = (req, res, next) => {
6
+ if (req.headers["metadata-flavor"] !== "Google") {
7
+ return res.status(403).send("Missing Metadata-Flavor: Google header");
8
+ }
9
+ next();
10
+ };
11
+ router.use("/computeMetadata/v1", HEADER_CHECK);
12
+ router.get("/computeMetadata/v1/project/project-id", (req, res) => res.send("imposter-project-dev"));
13
+ router.get("/computeMetadata/v1/instance/id", (req, res) => res.send("1234567890123456789"));
14
+ router.get("/computeMetadata/v1/instance/zone", (req, res) => res.send("projects/imposter-project-dev/zones/us-central1-a"));
15
+ router.get("/computeMetadata/v1/instance/hostname", (req, res) => res.send("imposter-host.c.imposter-project-dev.internal"));
16
+ // Service Account Token (The Honey)
17
+ router.get("/computeMetadata/v1/instance/service-accounts/default/token", (req, res) => {
18
+ logger.warn({ ip: req.ip }, "Cloud Imposter: Client requested GCP Service Account Token");
19
+ res.json({
20
+ access_token: "ya29.imposter.fake.token.v1." + Date.now(),
21
+ expires_in: 3600,
22
+ token_type: "Bearer"
23
+ });
24
+ });
25
+ export const gcpRouter = router;
26
+ //# sourceMappingURL=gcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcp.js","sourceRoot":"","sources":["../../../src/imposter/providers/gcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB,2BAA2B;AAC3B,MAAM,YAAY,GAAG,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;IACnD,IAAI,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,EAAE,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC;AAEhD,MAAM,CAAC,GAAG,CAAC,wCAAwC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;AACrG,MAAM,CAAC,GAAG,CAAC,iCAAiC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAC7F,MAAM,CAAC,GAAG,CAAC,mCAAmC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC,CAAC;AAC7H,MAAM,CAAC,GAAG,CAAC,uCAAuC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;AAE7H,oCAAoC;AACpC,MAAM,CAAC,GAAG,CAAC,6DAA6D,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACnF,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,4DAA4D,CAAC,CAAC;IAE1F,GAAG,CAAC,IAAI,CAAC;QACL,YAAY,EAAE,8BAA8B,GAAG,IAAI,CAAC,GAAG,EAAE;QACzD,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,QAAQ;KACvB,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ import { cfg } from "./config.js";
2
+ import { logger } from "./logger.js";
3
+ import { createHttp1Server } from "./server-http1.js";
4
+ import { createHttp2Server, createH2CServerIfEnabled } from "./server-http2.js";
5
+ import { setupWebSocket } from "./server-ws.js";
6
+ import { startL4Servers } from "./server-l4.js";
7
+ import { startGrpcServer } from "./server-grpc.js";
8
+ import { startBadSslServer } from "./server-bad-ssl.js";
9
+ import { startProtocolServers } from "./server-protocols.js";
10
+ import { startMqttServer } from "./server-mqtt.js";
11
+ import { startIcapServer } from "./server-icap.js";
12
+ import { startClusterNode } from "./cluster.js";
13
+ import { startRedisServer } from "./server-redis.js";
14
+ import { startSmtpServer } from "./server-smtp.js";
15
+ import { startSyslogServer } from "./server-syslog.js";
16
+ async function main() {
17
+ const app1 = createHttp1Server();
18
+ const server1 = app1.listen(cfg.portHttp1, cfg.host, () => logger.info({ port: cfg.portHttp1 }, "HTTP/1.1 server listening"));
19
+ // Attach WebSocket server to HTTP/1.1 server
20
+ setupWebSocket(server1);
21
+ logger.info({ path: "/ws" }, "WebSocket server attached");
22
+ const h2 = createHttp2Server();
23
+ h2.listen(cfg.portHttp2, cfg.host, () => logger.info({ port: cfg.portHttp2 }, "HTTP/2 TLS server listening"));
24
+ const h2c = createH2CServerIfEnabled();
25
+ if (h2c) {
26
+ const h2cPort = (cfg.portHttp1 || 8080) + 1;
27
+ h2c.listen(h2cPort, cfg.host, () => logger.info({ port: h2cPort }, "HTTP/2 cleartext (h2c) server listening"));
28
+ }
29
+ // Start additional protocols
30
+ startL4Servers();
31
+ startGrpcServer();
32
+ startBadSslServer();
33
+ startProtocolServers();
34
+ startMqttServer();
35
+ startIcapServer();
36
+ startClusterNode();
37
+ startRedisServer();
38
+ startSmtpServer();
39
+ startSyslogServer();
40
+ // Graceful shutdown
41
+ const shutdown = (signal) => {
42
+ logger.info({ signal }, "Shutdown signal received, cleaning up...");
43
+ // Allow some time for other processes to cleanup if they have listeners
44
+ setTimeout(() => process.exit(0), 500);
45
+ };
46
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
47
+ process.on("SIGINT", () => shutdown("SIGINT"));
48
+ }
49
+ main().catch((err) => {
50
+ console.error(err);
51
+ process.exit(1);
52
+ });
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import dns from "dns/promises";
2
+ import net from "net";
3
+ export async function dnsHandler(req, res) {
4
+ const target = req.query.target;
5
+ const type = (req.query.type || "A").toUpperCase();
6
+ if (!target) {
7
+ return res.status(400).json({ error: "Missing 'target' query parameter" });
8
+ }
9
+ try {
10
+ let result;
11
+ switch (type) {
12
+ case "A":
13
+ result = await dns.resolve4(target);
14
+ break;
15
+ case "AAAA":
16
+ result = await dns.resolve6(target);
17
+ break;
18
+ case "MX":
19
+ result = await dns.resolveMx(target);
20
+ break;
21
+ case "TXT":
22
+ result = await dns.resolveTxt(target);
23
+ break;
24
+ case "SRV":
25
+ result = await dns.resolveSrv(target);
26
+ break;
27
+ case "NS":
28
+ result = await dns.resolveNs(target);
29
+ break;
30
+ case "CNAME":
31
+ result = await dns.resolveCname(target);
32
+ break;
33
+ default:
34
+ return res.status(400).json({ error: `Unsupported record type: ${type}` });
35
+ }
36
+ res.json({ target, type, result });
37
+ }
38
+ catch (e) {
39
+ res.status(500).json({ error: e.message });
40
+ }
41
+ }
42
+ export function pingHandler(req, res) {
43
+ const target = req.query.target;
44
+ if (!target) {
45
+ return res.status(400).json({ error: "Missing 'target' query parameter (host:port)" });
46
+ }
47
+ const [host, portStr] = target.split(":");
48
+ const port = parseInt(portStr);
49
+ if (!host || isNaN(port)) {
50
+ return res.status(400).json({ error: "Invalid format. Use host:port" });
51
+ }
52
+ const start = Date.now();
53
+ const socket = new net.Socket();
54
+ socket.setTimeout(2000); // 2s timeout
55
+ socket.connect(port, host, () => {
56
+ const duration = Date.now() - start;
57
+ res.json({ status: "success", target, duration_ms: duration });
58
+ socket.destroy();
59
+ });
60
+ socket.on("error", (err) => {
61
+ res.status(500).json({ status: "failed", target, error: err.message });
62
+ });
63
+ socket.on("timeout", () => {
64
+ res.status(504).json({ status: "timeout", target });
65
+ socket.destroy();
66
+ });
67
+ }
68
+ //# sourceMappingURL=infra-debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infra-debug.js","sourceRoot":"","sources":["../src/infra-debug.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,272 @@
1
+ import jwt from "jsonwebtoken";
2
+ import * as jose from "jose";
3
+ import { getOidcSigningMaterial } from "./oidc.js";
4
+ const TOKEN_ISSUER = "urn:apparatus:token-forge";
5
+ const TOKEN_AUDIENCE = "urn:apparatus:client";
6
+ const WEAK_KEYS = ["secret", "password", "123456", "letmein", "apparatus"];
7
+ const MAX_TOKEN_LIFETIME_SECONDS = 24 * 60 * 60;
8
+ const EXPIRY_UNIT_SECONDS = {
9
+ s: 1,
10
+ m: 60,
11
+ h: 60 * 60,
12
+ d: 24 * 60 * 60,
13
+ };
14
+ const DEFAULT_FLAGS = {
15
+ allowNoneAlg: false,
16
+ allowWeakKey: false,
17
+ allowKeyConfusion: false,
18
+ };
19
+ function getBearerToken(authHeader) {
20
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
21
+ return undefined;
22
+ }
23
+ const token = authHeader.slice("Bearer ".length).trim();
24
+ return token || undefined;
25
+ }
26
+ function parseDecodedJwt(token) {
27
+ const decoded = jwt.decode(token, { complete: true });
28
+ if (!decoded || typeof decoded === "string") {
29
+ return null;
30
+ }
31
+ return decoded;
32
+ }
33
+ function isRecord(value) {
34
+ return typeof value === "object" && value !== null && !Array.isArray(value);
35
+ }
36
+ function sanitizeClaims(value) {
37
+ return isRecord(value) ? value : {};
38
+ }
39
+ function tokenFromRequest(req) {
40
+ const tokenFromBody = isRecord(req.body) && typeof req.body.token === "string"
41
+ ? req.body.token.trim()
42
+ : undefined;
43
+ return tokenFromBody || getBearerToken(req.headers.authorization);
44
+ }
45
+ /**
46
+ * Strips PEM armor to produce raw base64 key material used as an HMAC secret
47
+ * in the key-confusion simulation path.
48
+ */
49
+ function toPublicKeySecret(publicKeyPem) {
50
+ return publicKeyPem
51
+ .replace(/-----BEGIN PUBLIC KEY-----/g, "")
52
+ .replace(/-----END PUBLIC KEY-----/g, "")
53
+ .replace(/\s+/g, "")
54
+ .trim();
55
+ }
56
+ function normalizeExpiresIn(value) {
57
+ if (!value)
58
+ return "1h";
59
+ const match = /^(\d+)([smhd])$/i.exec(value.trim());
60
+ if (!match)
61
+ return "1h";
62
+ const amount = Number(match[1]);
63
+ const unit = match[2].toLowerCase();
64
+ if (!Number.isFinite(amount) || amount <= 0) {
65
+ return "1h";
66
+ }
67
+ const seconds = amount * EXPIRY_UNIT_SECONDS[unit];
68
+ if (seconds > MAX_TOKEN_LIFETIME_SECONDS) {
69
+ return "24h";
70
+ }
71
+ return `${amount}${unit}`;
72
+ }
73
+ export function jwtDebugHandler(req, res) {
74
+ const token = getBearerToken(req.headers.authorization);
75
+ if (!token) {
76
+ return res.status(400).json({ error: "Missing or invalid Authorization header (Bearer token required)" });
77
+ }
78
+ const decoded = parseDecodedJwt(token);
79
+ if (!decoded) {
80
+ return res.status(400).json({ error: "Invalid JWT token structure" });
81
+ }
82
+ return res.json({
83
+ token,
84
+ header: decoded.header,
85
+ payload: decoded.payload,
86
+ signature: decoded.signature,
87
+ });
88
+ }
89
+ export async function jwtDebugPostHandler(req, res) {
90
+ const token = tokenFromRequest(req);
91
+ if (!token) {
92
+ return res.status(400).json({
93
+ valid: false,
94
+ header: {},
95
+ payload: {},
96
+ error: "Missing token in body (token) or Authorization header",
97
+ });
98
+ }
99
+ const decoded = parseDecodedJwt(token);
100
+ if (!decoded) {
101
+ return res.status(400).json({
102
+ valid: false,
103
+ header: {},
104
+ payload: {},
105
+ error: "Invalid JWT token structure",
106
+ });
107
+ }
108
+ const { keyPair } = await getOidcSigningMaterial();
109
+ let valid = false;
110
+ let error;
111
+ try {
112
+ await jose.jwtVerify(token, keyPair.publicKey, { algorithms: ["RS256"] });
113
+ valid = true;
114
+ }
115
+ catch (verificationError) {
116
+ const message = verificationError instanceof Error ? verificationError.message : "Signature verification failed";
117
+ error = message;
118
+ }
119
+ return res.json({
120
+ valid,
121
+ header: decoded.header,
122
+ payload: decoded.payload,
123
+ error,
124
+ });
125
+ }
126
+ export async function authForgeHandler(req, res) {
127
+ try {
128
+ const body = isRecord(req.body) ? req.body : {};
129
+ const claims = sanitizeClaims(body.claims);
130
+ const sub = typeof body.sub === "string" ? body.sub : (typeof claims.sub === "string" ? claims.sub : "analyst@example.local");
131
+ const role = typeof body.role === "string" ? body.role : (typeof claims.role === "string" ? claims.role : "user");
132
+ const expiresIn = normalizeExpiresIn(typeof body.expiresIn === "string" ? body.expiresIn : undefined);
133
+ const jwtPayload = {
134
+ ...claims,
135
+ iss: TOKEN_ISSUER,
136
+ aud: TOKEN_AUDIENCE,
137
+ sub,
138
+ role,
139
+ };
140
+ const { keyPair } = await getOidcSigningMaterial();
141
+ const token = await new jose.SignJWT(jwtPayload)
142
+ .setProtectedHeader({ alg: "RS256", kid: "simulated-key-id-1", typ: "JWT" })
143
+ .setIssuedAt()
144
+ .setExpirationTime(expiresIn)
145
+ .sign(keyPair.privateKey);
146
+ const decoded = parseDecodedJwt(token);
147
+ const publicKeyPem = await jose.exportSPKI(keyPair.publicKey);
148
+ const publicKey = toPublicKeySecret(publicKeyPem);
149
+ return res.json({
150
+ token,
151
+ token_type: "Bearer",
152
+ header: decoded?.header ?? {},
153
+ payload: decoded?.payload ?? {},
154
+ hints: {
155
+ weakKeys: WEAK_KEYS,
156
+ publicKey,
157
+ },
158
+ });
159
+ }
160
+ catch (error) {
161
+ const message = error instanceof Error ? error.message : "Token forge failed";
162
+ return res.status(500).json({ error: "Token forge failed", details: message });
163
+ }
164
+ }
165
+ export async function authVerifyHandler(req, res) {
166
+ const body = isRecord(req.body) ? req.body : {};
167
+ const token = typeof body.token === "string" ? body.token.trim() : "";
168
+ if (!token) {
169
+ return res.status(400).json({
170
+ valid: false,
171
+ bypassed: false,
172
+ mode: "invalid",
173
+ message: "Missing token",
174
+ });
175
+ }
176
+ const decoded = parseDecodedJwt(token);
177
+ if (!decoded) {
178
+ return res.status(400).json({
179
+ valid: false,
180
+ bypassed: false,
181
+ mode: "invalid",
182
+ message: "Malformed JWT",
183
+ });
184
+ }
185
+ const flags = {
186
+ allowNoneAlg: body.vulnerabilities?.allowNoneAlg ?? DEFAULT_FLAGS.allowNoneAlg,
187
+ allowWeakKey: body.vulnerabilities?.allowWeakKey ?? DEFAULT_FLAGS.allowWeakKey,
188
+ allowKeyConfusion: body.vulnerabilities?.allowKeyConfusion ?? DEFAULT_FLAGS.allowKeyConfusion,
189
+ };
190
+ const headerAlg = typeof decoded.header.alg === "string" ? decoded.header.alg : "unknown";
191
+ if (headerAlg === "none") {
192
+ if (flags.allowNoneAlg) {
193
+ return res.json({
194
+ valid: true,
195
+ bypassed: true,
196
+ mode: "none_alg",
197
+ message: "Signature bypass accepted via alg=none (intentional vulnerable mode)",
198
+ header: decoded.header,
199
+ payload: decoded.payload,
200
+ });
201
+ }
202
+ return res.status(401).json({
203
+ valid: false,
204
+ bypassed: false,
205
+ mode: "invalid",
206
+ message: "alg=none rejected",
207
+ header: decoded.header,
208
+ payload: decoded.payload,
209
+ });
210
+ }
211
+ const { keyPair } = await getOidcSigningMaterial();
212
+ try {
213
+ const verified = await jose.jwtVerify(token, keyPair.publicKey, { algorithms: ["RS256"] });
214
+ return res.json({
215
+ valid: true,
216
+ bypassed: false,
217
+ mode: "secure",
218
+ message: "Token verified against RS256 public key",
219
+ header: decoded.header,
220
+ payload: verified.payload,
221
+ });
222
+ }
223
+ catch {
224
+ // continue into vulnerable verification paths
225
+ }
226
+ if (flags.allowWeakKey) {
227
+ for (const weakKey of WEAK_KEYS) {
228
+ try {
229
+ const weakPayload = jwt.verify(token, weakKey, { algorithms: ["HS256"] });
230
+ return res.json({
231
+ valid: true,
232
+ bypassed: true,
233
+ mode: "weak_key",
234
+ message: `Token accepted with weak HMAC key: ${weakKey}`,
235
+ matchedKey: weakKey,
236
+ header: decoded.header,
237
+ payload: weakPayload,
238
+ });
239
+ }
240
+ catch {
241
+ // continue trying dictionary entries
242
+ }
243
+ }
244
+ }
245
+ if (flags.allowKeyConfusion) {
246
+ const publicKeyPem = await jose.exportSPKI(keyPair.publicKey);
247
+ const publicKeySecret = toPublicKeySecret(publicKeyPem);
248
+ try {
249
+ const confusedPayload = jwt.verify(token, publicKeySecret, { algorithms: ["HS256"] });
250
+ return res.json({
251
+ valid: true,
252
+ bypassed: true,
253
+ mode: "key_confusion",
254
+ message: "Token accepted using public-key material as HMAC secret (algorithm confusion)",
255
+ header: decoded.header,
256
+ payload: confusedPayload,
257
+ });
258
+ }
259
+ catch {
260
+ // fall through to invalid response
261
+ }
262
+ }
263
+ return res.status(401).json({
264
+ valid: false,
265
+ bypassed: false,
266
+ mode: "invalid",
267
+ message: `Signature verification failed for alg=${headerAlg}`,
268
+ header: decoded.header,
269
+ payload: decoded.payload,
270
+ });
271
+ }
272
+ //# sourceMappingURL=jwt-debug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-debug.js","sourceRoot":"","sources":["../src/jwt-debug.ts"],"names":[],"mappings":"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"}
package/dist/kv.js ADDED
@@ -0,0 +1,22 @@
1
+ const store = new Map();
2
+ export function kvHandler(req, res) {
3
+ const key = req.params.key;
4
+ if (req.method === "GET") {
5
+ if (store.has(key)) {
6
+ return res.json({ key, value: store.get(key) });
7
+ }
8
+ else {
9
+ return res.status(404).json({ error: "Key not found" });
10
+ }
11
+ }
12
+ if (req.method === "POST" || req.method === "PUT") {
13
+ const value = req.body;
14
+ store.set(key, value);
15
+ return res.json({ message: "Set", key, value });
16
+ }
17
+ if (req.method === "DELETE") {
18
+ store.delete(key);
19
+ return res.sendStatus(204);
20
+ }
21
+ }
22
+ //# sourceMappingURL=kv.js.map
package/dist/kv.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kv.js","sourceRoot":"","sources":["../src/kv.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAG,IAAI,GAAG,EAAe,CAAC;AAErC,MAAM,UAAU,SAAS,CAAC,GAAY,EAAE,GAAa;IACjD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;IAE3B,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjB,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACJ,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;QAC5D,CAAC;IACL,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC;QACvB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClB,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;AACL,CAAC"}
@@ -0,0 +1,43 @@
1
+ // Mock generators for DLP testing
2
+ function generateLuhn(prefix, length) {
3
+ let payload = prefix;
4
+ while (payload.length < length - 1)
5
+ payload += Math.floor(Math.random() * 10);
6
+ const digits = payload.split("").map(Number);
7
+ let sum = 0;
8
+ let shouldDouble = true;
9
+ for (let i = digits.length - 1; i >= 0; i--) {
10
+ let digit = digits[i];
11
+ if (shouldDouble) {
12
+ digit *= 2;
13
+ if (digit > 9)
14
+ digit -= 9;
15
+ }
16
+ sum += digit;
17
+ shouldDouble = !shouldDouble;
18
+ }
19
+ const checkDigit = (10 - (sum % 10)) % 10;
20
+ return payload + checkDigit;
21
+ }
22
+ export const generators = {
23
+ cc: () => {
24
+ // 16-digit Visa-like (starts with 4) with valid Luhn checksum.
25
+ return generateLuhn("4", 16);
26
+ },
27
+ ssn: () => {
28
+ // Generate a valid-looking SSN
29
+ const area = Math.floor(Math.random() * 900) + 100;
30
+ const group = Math.floor(Math.random() * 90) + 10;
31
+ const serial = Math.floor(Math.random() * 9000) + 1000;
32
+ return `${area}-${group}-${serial}`;
33
+ },
34
+ email: () => {
35
+ // Generate a random email
36
+ const domains = ["example.com", "test.org", "corp.net"];
37
+ const users = ["alice", "bob", "charlie", "admin", "support"];
38
+ const user = users[Math.floor(Math.random() * users.length)];
39
+ const domain = domains[Math.floor(Math.random() * domains.length)];
40
+ return `${user}@${domain}`;
41
+ }
42
+ };
43
+ //# sourceMappingURL=generators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generators.js","sourceRoot":"","sources":["../../src/lib/generators.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,SAAS,YAAY,CAAC,MAAc,EAAE,MAAc;IAChD,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,OAAO,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAE9E,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,YAAY,GAAG,IAAI,CAAC;IACxB,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,IAAI,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,YAAY,EAAE,CAAC;YACf,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,KAAK,GAAG,CAAC;gBAAE,KAAK,IAAI,CAAC,CAAC;QAC9B,CAAC;QACD,GAAG,IAAI,KAAK,CAAC;QACb,YAAY,GAAG,CAAC,YAAY,CAAC;IACjC,CAAC;IACD,MAAM,UAAU,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;IAC1C,OAAO,OAAO,GAAG,UAAU,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,EAAE,EAAE,GAAG,EAAE;QACL,+DAA+D;QAC/D,OAAO,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,GAAG,EAAE,GAAG,EAAE;QACN,+BAA+B;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QACvD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;IACxC,CAAC;IACD,KAAK,EAAE,GAAG,EAAE;QACR,0BAA0B;QAC1B,MAAM,OAAO,GAAG,CAAC,aAAa,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,OAAO,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC;IAC/B,CAAC;CACJ,CAAC"}