@trailofbits/vsix-audit 0.1.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 (197) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +281 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +703 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +4 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/scanner/batch.d.ts +12 -0
  12. package/dist/scanner/batch.d.ts.map +1 -0
  13. package/dist/scanner/batch.js +104 -0
  14. package/dist/scanner/batch.js.map +1 -0
  15. package/dist/scanner/bundler.d.ts +35 -0
  16. package/dist/scanner/bundler.d.ts.map +1 -0
  17. package/dist/scanner/bundler.js +120 -0
  18. package/dist/scanner/bundler.js.map +1 -0
  19. package/dist/scanner/cache.d.ts +45 -0
  20. package/dist/scanner/cache.d.ts.map +1 -0
  21. package/dist/scanner/cache.js +153 -0
  22. package/dist/scanner/cache.js.map +1 -0
  23. package/dist/scanner/cache.test.d.ts +2 -0
  24. package/dist/scanner/cache.test.d.ts.map +1 -0
  25. package/dist/scanner/cache.test.js +149 -0
  26. package/dist/scanner/cache.test.js.map +1 -0
  27. package/dist/scanner/capabilities.d.ts +29 -0
  28. package/dist/scanner/capabilities.d.ts.map +1 -0
  29. package/dist/scanner/capabilities.js +217 -0
  30. package/dist/scanner/capabilities.js.map +1 -0
  31. package/dist/scanner/checks/ast.d.ts +3 -0
  32. package/dist/scanner/checks/ast.d.ts.map +1 -0
  33. package/dist/scanner/checks/ast.js +469 -0
  34. package/dist/scanner/checks/ast.js.map +1 -0
  35. package/dist/scanner/checks/ast.test.d.ts +2 -0
  36. package/dist/scanner/checks/ast.test.d.ts.map +1 -0
  37. package/dist/scanner/checks/ast.test.js +389 -0
  38. package/dist/scanner/checks/ast.test.js.map +1 -0
  39. package/dist/scanner/checks/behavioral.d.ts +3 -0
  40. package/dist/scanner/checks/behavioral.d.ts.map +1 -0
  41. package/dist/scanner/checks/behavioral.js +367 -0
  42. package/dist/scanner/checks/behavioral.js.map +1 -0
  43. package/dist/scanner/checks/blocklist.d.ts +3 -0
  44. package/dist/scanner/checks/blocklist.d.ts.map +1 -0
  45. package/dist/scanner/checks/blocklist.js +32 -0
  46. package/dist/scanner/checks/blocklist.js.map +1 -0
  47. package/dist/scanner/checks/blocklist.test.d.ts +2 -0
  48. package/dist/scanner/checks/blocklist.test.d.ts.map +1 -0
  49. package/dist/scanner/checks/blocklist.test.js +74 -0
  50. package/dist/scanner/checks/blocklist.test.js.map +1 -0
  51. package/dist/scanner/checks/chains.d.ts +35 -0
  52. package/dist/scanner/checks/chains.d.ts.map +1 -0
  53. package/dist/scanner/checks/chains.js +505 -0
  54. package/dist/scanner/checks/chains.js.map +1 -0
  55. package/dist/scanner/checks/chains.test.d.ts +2 -0
  56. package/dist/scanner/checks/chains.test.d.ts.map +1 -0
  57. package/dist/scanner/checks/chains.test.js +250 -0
  58. package/dist/scanner/checks/chains.test.js.map +1 -0
  59. package/dist/scanner/checks/dataflow.d.ts +3 -0
  60. package/dist/scanner/checks/dataflow.d.ts.map +1 -0
  61. package/dist/scanner/checks/dataflow.js +316 -0
  62. package/dist/scanner/checks/dataflow.js.map +1 -0
  63. package/dist/scanner/checks/dependencies.d.ts +13 -0
  64. package/dist/scanner/checks/dependencies.d.ts.map +1 -0
  65. package/dist/scanner/checks/dependencies.js +225 -0
  66. package/dist/scanner/checks/dependencies.js.map +1 -0
  67. package/dist/scanner/checks/dependencies.test.d.ts +2 -0
  68. package/dist/scanner/checks/dependencies.test.d.ts.map +1 -0
  69. package/dist/scanner/checks/dependencies.test.js +248 -0
  70. package/dist/scanner/checks/dependencies.test.js.map +1 -0
  71. package/dist/scanner/checks/finding-quality.test.d.ts +8 -0
  72. package/dist/scanner/checks/finding-quality.test.d.ts.map +1 -0
  73. package/dist/scanner/checks/finding-quality.test.js +164 -0
  74. package/dist/scanner/checks/finding-quality.test.js.map +1 -0
  75. package/dist/scanner/checks/ioc.d.ts +20 -0
  76. package/dist/scanner/checks/ioc.d.ts.map +1 -0
  77. package/dist/scanner/checks/ioc.js +234 -0
  78. package/dist/scanner/checks/ioc.js.map +1 -0
  79. package/dist/scanner/checks/ioc.test.d.ts +2 -0
  80. package/dist/scanner/checks/ioc.test.d.ts.map +1 -0
  81. package/dist/scanner/checks/ioc.test.js +298 -0
  82. package/dist/scanner/checks/ioc.test.js.map +1 -0
  83. package/dist/scanner/checks/manifest.d.ts +6 -0
  84. package/dist/scanner/checks/manifest.d.ts.map +1 -0
  85. package/dist/scanner/checks/manifest.js +123 -0
  86. package/dist/scanner/checks/manifest.js.map +1 -0
  87. package/dist/scanner/checks/manifest.test.d.ts +2 -0
  88. package/dist/scanner/checks/manifest.test.d.ts.map +1 -0
  89. package/dist/scanner/checks/manifest.test.js +108 -0
  90. package/dist/scanner/checks/manifest.test.js.map +1 -0
  91. package/dist/scanner/checks/obfuscation.d.ts +3 -0
  92. package/dist/scanner/checks/obfuscation.d.ts.map +1 -0
  93. package/dist/scanner/checks/obfuscation.js +432 -0
  94. package/dist/scanner/checks/obfuscation.js.map +1 -0
  95. package/dist/scanner/checks/obfuscation.test.d.ts +2 -0
  96. package/dist/scanner/checks/obfuscation.test.d.ts.map +1 -0
  97. package/dist/scanner/checks/obfuscation.test.js +399 -0
  98. package/dist/scanner/checks/obfuscation.test.js.map +1 -0
  99. package/dist/scanner/checks/package.d.ts +17 -0
  100. package/dist/scanner/checks/package.d.ts.map +1 -0
  101. package/dist/scanner/checks/package.js +422 -0
  102. package/dist/scanner/checks/package.js.map +1 -0
  103. package/dist/scanner/checks/package.test.d.ts +2 -0
  104. package/dist/scanner/checks/package.test.d.ts.map +1 -0
  105. package/dist/scanner/checks/package.test.js +518 -0
  106. package/dist/scanner/checks/package.test.js.map +1 -0
  107. package/dist/scanner/checks/patterns.d.ts +5 -0
  108. package/dist/scanner/checks/patterns.d.ts.map +1 -0
  109. package/dist/scanner/checks/patterns.js +251 -0
  110. package/dist/scanner/checks/patterns.js.map +1 -0
  111. package/dist/scanner/checks/patterns.test.d.ts +2 -0
  112. package/dist/scanner/checks/patterns.test.d.ts.map +1 -0
  113. package/dist/scanner/checks/patterns.test.js +147 -0
  114. package/dist/scanner/checks/patterns.test.js.map +1 -0
  115. package/dist/scanner/checks/unicode.d.ts +3 -0
  116. package/dist/scanner/checks/unicode.d.ts.map +1 -0
  117. package/dist/scanner/checks/unicode.js +247 -0
  118. package/dist/scanner/checks/unicode.js.map +1 -0
  119. package/dist/scanner/checks/unicode.test.d.ts +2 -0
  120. package/dist/scanner/checks/unicode.test.d.ts.map +1 -0
  121. package/dist/scanner/checks/unicode.test.js +202 -0
  122. package/dist/scanner/checks/unicode.test.js.map +1 -0
  123. package/dist/scanner/checks/yara.d.ts +23 -0
  124. package/dist/scanner/checks/yara.d.ts.map +1 -0
  125. package/dist/scanner/checks/yara.js +349 -0
  126. package/dist/scanner/checks/yara.js.map +1 -0
  127. package/dist/scanner/checks/yara.test.d.ts +2 -0
  128. package/dist/scanner/checks/yara.test.d.ts.map +1 -0
  129. package/dist/scanner/checks/yara.test.js +126 -0
  130. package/dist/scanner/checks/yara.test.js.map +1 -0
  131. package/dist/scanner/constants.d.ts +18 -0
  132. package/dist/scanner/constants.d.ts.map +1 -0
  133. package/dist/scanner/constants.js +37 -0
  134. package/dist/scanner/constants.js.map +1 -0
  135. package/dist/scanner/detection-coverage.test.d.ts +2 -0
  136. package/dist/scanner/detection-coverage.test.d.ts.map +1 -0
  137. package/dist/scanner/detection-coverage.test.js +216 -0
  138. package/dist/scanner/detection-coverage.test.js.map +1 -0
  139. package/dist/scanner/download.d.ts +76 -0
  140. package/dist/scanner/download.d.ts.map +1 -0
  141. package/dist/scanner/download.js +339 -0
  142. package/dist/scanner/download.js.map +1 -0
  143. package/dist/scanner/download.test.d.ts +2 -0
  144. package/dist/scanner/download.test.d.ts.map +1 -0
  145. package/dist/scanner/download.test.js +149 -0
  146. package/dist/scanner/download.test.js.map +1 -0
  147. package/dist/scanner/index.d.ts +8 -0
  148. package/dist/scanner/index.d.ts.map +1 -0
  149. package/dist/scanner/index.js +167 -0
  150. package/dist/scanner/index.js.map +1 -0
  151. package/dist/scanner/index.test.d.ts +2 -0
  152. package/dist/scanner/index.test.d.ts.map +1 -0
  153. package/dist/scanner/index.test.js +71 -0
  154. package/dist/scanner/index.test.js.map +1 -0
  155. package/dist/scanner/loaders/zoo.d.ts +3 -0
  156. package/dist/scanner/loaders/zoo.d.ts.map +1 -0
  157. package/dist/scanner/loaders/zoo.js +112 -0
  158. package/dist/scanner/loaders/zoo.js.map +1 -0
  159. package/dist/scanner/types.d.ts +118 -0
  160. package/dist/scanner/types.d.ts.map +1 -0
  161. package/dist/scanner/types.js +2 -0
  162. package/dist/scanner/types.js.map +1 -0
  163. package/dist/scanner/utils.d.ts +14 -0
  164. package/dist/scanner/utils.d.ts.map +1 -0
  165. package/dist/scanner/utils.js +25 -0
  166. package/dist/scanner/utils.js.map +1 -0
  167. package/dist/scanner/vsix.d.ts +6 -0
  168. package/dist/scanner/vsix.d.ts.map +1 -0
  169. package/dist/scanner/vsix.js +213 -0
  170. package/dist/scanner/vsix.js.map +1 -0
  171. package/dist/scanner/vsix.test.d.ts +2 -0
  172. package/dist/scanner/vsix.test.d.ts.map +1 -0
  173. package/dist/scanner/vsix.test.js +355 -0
  174. package/dist/scanner/vsix.test.js.map +1 -0
  175. package/package.json +60 -0
  176. package/zoo/blocklist/extensions.json +201 -0
  177. package/zoo/iocs/blockchain-extensions.txt +21 -0
  178. package/zoo/iocs/c2-domains.txt +50 -0
  179. package/zoo/iocs/c2-ips.txt +24 -0
  180. package/zoo/iocs/hashes.txt +47 -0
  181. package/zoo/iocs/malicious-npm.txt +85 -0
  182. package/zoo/iocs/wallets.txt +18 -0
  183. package/zoo/signatures/yara/README.md +46 -0
  184. package/zoo/signatures/yara/blockchain_c2.yar +48 -0
  185. package/zoo/signatures/yara/code_execution.yar +165 -0
  186. package/zoo/signatures/yara/credential_harvesting.yar +116 -0
  187. package/zoo/signatures/yara/crypto_wallet_targeting.yar +92 -0
  188. package/zoo/signatures/yara/data_exfiltration.yar +207 -0
  189. package/zoo/signatures/yara/google_calendar_c2.yar +187 -0
  190. package/zoo/signatures/yara/messaging_c2.yar +103 -0
  191. package/zoo/signatures/yara/multi_stage_attacks.yar +331 -0
  192. package/zoo/signatures/yara/obfuscation_patterns.yar +208 -0
  193. package/zoo/signatures/yara/powershell_attacks.yar +116 -0
  194. package/zoo/signatures/yara/rat_capabilities.yar +243 -0
  195. package/zoo/signatures/yara/self_propagation.yar +239 -0
  196. package/zoo/signatures/yara/unicode_stealth.yar +48 -0
  197. package/zoo/signatures/yara/websocket_c2.yar +83 -0
@@ -0,0 +1,399 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { checkObfuscation } from "./obfuscation.js";
3
+ function makeContents(files) {
4
+ const manifest = {
5
+ name: "test-extension",
6
+ publisher: "test",
7
+ version: "1.0.0",
8
+ };
9
+ const fileMap = new Map();
10
+ for (const [name, content] of Object.entries(files)) {
11
+ fileMap.set(name, Buffer.from(content, "utf8"));
12
+ }
13
+ return { manifest, files: fileMap, basePath: "/test" };
14
+ }
15
+ describe("checkObfuscation", () => {
16
+ // ============================================================================
17
+ // ENTROPY DETECTION
18
+ // ============================================================================
19
+ describe("entropy detection", () => {
20
+ it("detects high entropy regions", () => {
21
+ // Generate high-entropy string using full alphanumeric charset (62 chars)
22
+ // Each char used ~equally = entropy near log2(62) ≈ 5.95 bits/char
23
+ // Threshold is 5.5, so this will trigger detection
24
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
25
+ let highEntropy = "";
26
+ for (let i = 0; i < 300; i++) {
27
+ highEntropy += chars[i % chars.length];
28
+ }
29
+ const content = `const data = "${highEntropy}";`;
30
+ const contents = makeContents({ "extension.js": content });
31
+ const findings = checkObfuscation(contents);
32
+ expect(findings.some((f) => f.id === "OBFUSCATION_HIGH_ENTROPY")).toBe(true);
33
+ });
34
+ it("ignores normal code with low entropy", () => {
35
+ const content = `
36
+ function hello() {
37
+ console.log("Hello, World!");
38
+ return true;
39
+ }
40
+ `;
41
+ const contents = makeContents({ "extension.js": content });
42
+ const findings = checkObfuscation(contents);
43
+ expect(findings.some((f) => f.id === "OBFUSCATION_HIGH_ENTROPY")).toBe(false);
44
+ });
45
+ });
46
+ // ============================================================================
47
+ // UNICODE HIDING DETECTION
48
+ // ============================================================================
49
+ describe("Unicode - zero-width characters", () => {
50
+ it("detects zero-width space characters (U+200B)", () => {
51
+ // 3+ occurrences needed
52
+ const content = "const x\u200B = 'a\u200Bb\u200Bc';";
53
+ const contents = makeContents({ "extension.js": content });
54
+ const findings = checkObfuscation(contents);
55
+ expect(findings).toHaveLength(1);
56
+ expect(findings.some((f) => f.id === "ZERO_WIDTH_CHARS")).toBe(true);
57
+ expect(findings.some((f) => f.severity === "high")).toBe(true);
58
+ });
59
+ it("detects zero-width joiner (U+200D)", () => {
60
+ const content = "const x\u200D = 'a\u200Db\u200Dc';";
61
+ const contents = makeContents({ "extension.js": content });
62
+ const findings = checkObfuscation(contents);
63
+ expect(findings).toHaveLength(1);
64
+ expect(findings.some((f) => f.id === "ZERO_WIDTH_CHARS")).toBe(true);
65
+ });
66
+ it("ignores files with only 1-2 zero-width chars", () => {
67
+ const content = "const x\u200B = 'a\u200Bb';";
68
+ const contents = makeContents({ "extension.js": content });
69
+ const findings = checkObfuscation(contents);
70
+ const zeroWidthFinding = findings.find((f) => f.id === "ZERO_WIDTH_CHARS");
71
+ expect(zeroWidthFinding).toBeUndefined();
72
+ });
73
+ });
74
+ describe("Unicode - variation selectors (GlassWorm technique)", () => {
75
+ it("detects variation selectors (U+FE00-FE0F) when >= 50 present", () => {
76
+ // Implementation requires 50+ variation selectors (GlassWorm uses hundreds)
77
+ // Normal emoji use has far fewer variation selectors
78
+ const variations = Array(55).fill("\uFE0F").join("x");
79
+ const content = `const payload = "${variations}";`;
80
+ const contents = makeContents({ "extension.js": content });
81
+ const findings = checkObfuscation(contents);
82
+ expect(findings).toHaveLength(1);
83
+ expect(findings.some((f) => f.id === "VARIATION_SELECTOR")).toBe(true);
84
+ expect(findings.some((f) => f.severity === "critical")).toBe(true);
85
+ });
86
+ it("ignores few variation selectors (normal for emoji)", () => {
87
+ // Less than 50 variation selectors should be ignored (normal emoji use)
88
+ const content = "a\uFE00b\uFE01c\uFE02d\uFE0F";
89
+ const contents = makeContents({ "extension.js": content });
90
+ const findings = checkObfuscation(contents);
91
+ expect(findings.find((f) => f.id === "VARIATION_SELECTOR")).toBeUndefined();
92
+ });
93
+ });
94
+ describe("Unicode - bidirectional overrides (Trojan Source)", () => {
95
+ it("detects left-to-right override (U+202D)", () => {
96
+ const content = "const admin\u202D = true;";
97
+ const contents = makeContents({ "extension.js": content });
98
+ const findings = checkObfuscation(contents);
99
+ expect(findings).toHaveLength(1);
100
+ expect(findings.some((f) => f.id === "BIDI_OVERRIDE")).toBe(true);
101
+ expect(findings.some((f) => f.severity === "critical")).toBe(true);
102
+ });
103
+ it("detects right-to-left override (U+202E)", () => {
104
+ const content = "const admin\u202E = true;";
105
+ const contents = makeContents({ "extension.js": content });
106
+ const findings = checkObfuscation(contents);
107
+ expect(findings).toHaveLength(1);
108
+ expect(findings.some((f) => f.id === "BIDI_OVERRIDE")).toBe(true);
109
+ });
110
+ });
111
+ describe("Unicode - ASCII escapes", () => {
112
+ it("detects excessive Unicode escapes for ASCII", () => {
113
+ // Using \\u00XX for normal printable ASCII is suspicious
114
+ const content = "const x = '\\u0068\\u0065\\u006c\\u006c\\u006f\\u0077';"; // "hellow"
115
+ const contents = makeContents({ "extension.js": content });
116
+ const findings = checkObfuscation(contents);
117
+ expect(findings).toHaveLength(1);
118
+ expect(findings.some((f) => f.id === "UNICODE_ASCII_ESCAPE")).toBe(true);
119
+ expect(findings.some((f) => f.severity === "medium")).toBe(true);
120
+ });
121
+ it("ignores files with few Unicode escapes", () => {
122
+ const content = "const x = '\\u0068\\u0065';"; // Only 2 escapes
123
+ const contents = makeContents({ "extension.js": content });
124
+ const findings = checkObfuscation(contents);
125
+ const escapeFinding = findings.find((f) => f.id === "UNICODE_ASCII_ESCAPE");
126
+ expect(escapeFinding).toBeUndefined();
127
+ });
128
+ });
129
+ describe("Unicode - Cyrillic homoglyphs", () => {
130
+ it("detects Cyrillic 'а' (U+0430) that looks like Latin 'a'", () => {
131
+ const content = "const \u0430dmin = true;"; // Cyrillic а
132
+ const contents = makeContents({ "extension.js": content });
133
+ const findings = checkObfuscation(contents);
134
+ expect(findings).toHaveLength(1);
135
+ expect(findings.some((f) => f.id === "CYRILLIC_HOMOGLYPH")).toBe(true);
136
+ expect(findings.some((f) => f.severity === "high")).toBe(true);
137
+ });
138
+ it("detects Cyrillic 'е' (U+0435) that looks like Latin 'e'", () => {
139
+ const content = "const s\u0435cret = 'password';"; // Cyrillic е
140
+ const contents = makeContents({ "extension.js": content });
141
+ const findings = checkObfuscation(contents);
142
+ expect(findings).toHaveLength(1);
143
+ expect(findings.some((f) => f.id === "CYRILLIC_HOMOGLYPH")).toBe(true);
144
+ });
145
+ it("ignores Cyrillic in markdown files", () => {
146
+ const content = "# Hello \u0430nd welcome"; // Cyrillic а in markdown
147
+ const contents = makeContents({ "README.md": content });
148
+ const findings = checkObfuscation(contents);
149
+ const cyrillicFinding = findings.find((f) => f.id === "CYRILLIC_HOMOGLYPH");
150
+ expect(cyrillicFinding).toBeUndefined();
151
+ });
152
+ });
153
+ describe("Unicode - invisible characters near code execution", () => {
154
+ it("flags many invisible chars in file with eval()", () => {
155
+ // Implementation requires 5+ invisible chars near execution patterns
156
+ const content = "const payload\uFE01\uFE02\uFE03\uFE04\uFE05 = 'data';\neval(payload);";
157
+ const contents = makeContents({ "extension.js": content });
158
+ const findings = checkObfuscation(contents);
159
+ expect(findings.some((f) => f.id === "INVISIBLE_CODE_EXECUTION")).toBe(true);
160
+ });
161
+ it("flags many invisible chars in file with Function()", () => {
162
+ const content = "const x\uFE01\uFE02\uFE03\uFE04\uFE05 = 1;\nnew Function('return x')();";
163
+ const contents = makeContents({ "extension.js": content });
164
+ const findings = checkObfuscation(contents);
165
+ expect(findings.some((f) => f.id === "INVISIBLE_CODE_EXECUTION")).toBe(true);
166
+ });
167
+ it("flags many invisible chars in file with child_process", () => {
168
+ const content = "require('child_process').exec('ls');\nconst hidden\uFE01\uFE02\uFE03\uFE04\uFE05 = 1;";
169
+ const contents = makeContents({ "extension.js": content });
170
+ const findings = checkObfuscation(contents);
171
+ expect(findings.some((f) => f.id === "INVISIBLE_CODE_EXECUTION")).toBe(true);
172
+ });
173
+ it("does NOT flag few invisible chars even with execution context", () => {
174
+ // Single invisible char isn't enough - needs 5+
175
+ const content = "const x\uFE01 = 1;\neval(x);";
176
+ const contents = makeContents({ "extension.js": content });
177
+ const findings = checkObfuscation(contents);
178
+ expect(findings.some((f) => f.id === "INVISIBLE_CODE_EXECUTION")).toBe(false);
179
+ });
180
+ });
181
+ describe("file filtering", () => {
182
+ it("scans JavaScript files", () => {
183
+ // Use bidi override which triggers with just 1 occurrence
184
+ const content = "const admin\u202E = true;";
185
+ const contents = makeContents({ "test.js": content });
186
+ const findings = checkObfuscation(contents);
187
+ expect(findings.length).toBeGreaterThan(0);
188
+ });
189
+ it("scans TypeScript files", () => {
190
+ const content = "const admin\u202E: boolean = true;";
191
+ const contents = makeContents({ "test.ts": content });
192
+ const findings = checkObfuscation(contents);
193
+ expect(findings.length).toBeGreaterThan(0);
194
+ });
195
+ it("scans JSON files for unicode issues", () => {
196
+ const content = '{"key\u202E": "value"}';
197
+ const contents = makeContents({ "test.json": content });
198
+ const findings = checkObfuscation(contents);
199
+ expect(findings.length).toBeGreaterThan(0);
200
+ });
201
+ it("ignores binary files", () => {
202
+ // Even critical patterns should be ignored in binary files
203
+ const content = "\u202E\u202D\u202C";
204
+ const contents = makeContents({ "test.png": content });
205
+ const findings = checkObfuscation(contents);
206
+ expect(findings).toHaveLength(0);
207
+ });
208
+ });
209
+ describe("metadata", () => {
210
+ it("includes match count in metadata for unicode findings", () => {
211
+ // Use BIDI_OVERRIDE which triggers with 1+ occurrences
212
+ const content = "a\u202Db\u202Ec\u202D";
213
+ const contents = makeContents({ "test.js": content });
214
+ const findings = checkObfuscation(contents);
215
+ const finding = findings.find((f) => f.id === "BIDI_OVERRIDE");
216
+ expect(finding?.metadata?.["matchCount"]).toBe(3);
217
+ });
218
+ it("includes code points in metadata for unicode findings", () => {
219
+ const content = "const admin\u202E = true;";
220
+ const contents = makeContents({ "test.js": content });
221
+ const findings = checkObfuscation(contents);
222
+ const finding = findings.find((f) => f.id === "BIDI_OVERRIDE");
223
+ const codePoints = finding?.metadata?.["codePoints"];
224
+ expect(codePoints).toBeDefined();
225
+ expect(codePoints?.some((cp) => cp.includes("202E"))).toBe(true);
226
+ });
227
+ it("includes line number in location", () => {
228
+ const content = "line1\nline2\nconst admin\u202E = true;";
229
+ const contents = makeContents({ "test.js": content });
230
+ const findings = checkObfuscation(contents);
231
+ const finding = findings.find((f) => f.id === "BIDI_OVERRIDE");
232
+ expect(finding?.location?.line).toBe(3);
233
+ });
234
+ it("includes obfuscation score for entropy findings", () => {
235
+ // Use full alphanumeric charset for high entropy (log2(62) ≈ 5.95 bits/char)
236
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
237
+ let highEntropy = "";
238
+ for (let i = 0; i < 300; i++) {
239
+ highEntropy += chars[i % chars.length];
240
+ }
241
+ const content = `const data = "${highEntropy}";`;
242
+ const contents = makeContents({ "test.js": content });
243
+ const findings = checkObfuscation(contents);
244
+ const finding = findings.find((f) => f.id === "OBFUSCATION_HIGH_ENTROPY");
245
+ expect(finding?.metadata?.["obfuscationScore"]).toBeGreaterThan(0);
246
+ });
247
+ });
248
+ // ============================================================================
249
+ // FALSE POSITIVE EXCLUSIONS
250
+ // ============================================================================
251
+ describe("false positive exclusions", () => {
252
+ describe("node_modules exclusions", () => {
253
+ it("skips high entropy detection in node_modules", () => {
254
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
255
+ let highEntropy = "";
256
+ for (let i = 0; i < 300; i++) {
257
+ highEntropy += chars[i % chars.length];
258
+ }
259
+ const content = `const data = "${highEntropy}";`;
260
+ const contents = makeContents({
261
+ "node_modules/iconv-lite/encodings/tables/cp437.js": content,
262
+ });
263
+ const findings = checkObfuscation(contents);
264
+ expect(findings.some((f) => f.id === "OBFUSCATION_HIGH_ENTROPY")).toBe(false);
265
+ });
266
+ it("skips zero-width chars in node_modules", () => {
267
+ const content = "const x\u200B = 'a\u200Bb\u200Bc';"; // 3 zero-width spaces
268
+ const contents = makeContents({ "node_modules/moment/locale/ku.js": content });
269
+ const findings = checkObfuscation(contents);
270
+ expect(findings.some((f) => f.id === "ZERO_WIDTH_CHARS")).toBe(false);
271
+ });
272
+ it("skips Cyrillic homoglyphs in node_modules", () => {
273
+ const content = "const \u0430dmin = true;"; // Cyrillic а
274
+ const contents = makeContents({ "node_modules/iconv-lite/lib/extend-node.js": content });
275
+ const findings = checkObfuscation(contents);
276
+ expect(findings.some((f) => f.id === "CYRILLIC_HOMOGLYPH")).toBe(false);
277
+ });
278
+ it("still detects BIDI_OVERRIDE in node_modules (critical)", () => {
279
+ const content = "const admin\u202E = true;";
280
+ const contents = makeContents({ "node_modules/suspicious-package/index.js": content });
281
+ const findings = checkObfuscation(contents);
282
+ expect(findings.some((f) => f.id === "BIDI_OVERRIDE")).toBe(true);
283
+ });
284
+ });
285
+ describe("emoji and entity file exclusions", () => {
286
+ it("skips variation selectors in emoji.json", () => {
287
+ // 50+ variation selectors would normally trigger
288
+ const variations = "\uFE0F".repeat(60);
289
+ const content = `{"emoji": "👍${variations}"}`;
290
+ const contents = makeContents({ "extension/out/emoji.json": content });
291
+ const findings = checkObfuscation(contents);
292
+ expect(findings.some((f) => f.id === "VARIATION_SELECTOR")).toBe(false);
293
+ });
294
+ it("skips variation selectors in entities.json", () => {
295
+ const variations = "\uFE0F".repeat(60);
296
+ const content = `{"entity": "test${variations}"}`;
297
+ const contents = makeContents({ "extension/out/entities.json": content });
298
+ const findings = checkObfuscation(contents);
299
+ expect(findings.some((f) => f.id === "VARIATION_SELECTOR")).toBe(false);
300
+ });
301
+ it("skips variation selectors in README.md", () => {
302
+ const variations = "\uFE0F".repeat(60);
303
+ const content = `# README\nEmoji test: ${variations}`;
304
+ const contents = makeContents({ "extension/README.md": content });
305
+ const findings = checkObfuscation(contents);
306
+ expect(findings.some((f) => f.id === "VARIATION_SELECTOR")).toBe(false);
307
+ });
308
+ it("still detects variation selectors in suspicious JS files", () => {
309
+ // 50+ variation selectors in a non-emoji file
310
+ const variations = Array(55).fill("\uFE00").join("x");
311
+ const content = `const payload = "${variations}"; eval(payload);`;
312
+ const contents = makeContents({ "extension.js": content });
313
+ const findings = checkObfuscation(contents);
314
+ expect(findings.some((f) => f.id === "VARIATION_SELECTOR")).toBe(true);
315
+ });
316
+ });
317
+ describe("RTL file exclusions", () => {
318
+ it("skips BIDI_OVERRIDE in katex files", () => {
319
+ const content = "const rtl\u202E = true;";
320
+ const contents = makeContents({ "node_modules/katex/dist/katex.js": content });
321
+ const findings = checkObfuscation(contents);
322
+ expect(findings.some((f) => f.id === "BIDI_OVERRIDE")).toBe(false);
323
+ });
324
+ it("skips BIDI_OVERRIDE in mermaid files", () => {
325
+ const content = "const rtl\u202E = true;";
326
+ const contents = makeContents({ "node_modules/mermaid/dist/mermaid.js": content });
327
+ const findings = checkObfuscation(contents);
328
+ expect(findings.some((f) => f.id === "BIDI_OVERRIDE")).toBe(false);
329
+ });
330
+ it("skips BIDI_OVERRIDE in Hebrew language files", () => {
331
+ const content = "Hebrew text\u202Ehere";
332
+ const contents = makeContents({ "extension/resources/dia_he.txt": content });
333
+ const findings = checkObfuscation(contents);
334
+ expect(findings.some((f) => f.id === "BIDI_OVERRIDE")).toBe(false);
335
+ });
336
+ it("still detects BIDI_OVERRIDE in regular JS files", () => {
337
+ const content = "const admin\u202E = true;";
338
+ const contents = makeContents({ "extension/src/index.js": content });
339
+ const findings = checkObfuscation(contents);
340
+ expect(findings.some((f) => f.id === "BIDI_OVERRIDE")).toBe(true);
341
+ });
342
+ });
343
+ describe("i18n file exclusions", () => {
344
+ it("skips Cyrillic in moment locale files", () => {
345
+ const content = "const \u0430dmin = '\u0435xample';"; // Cyrillic а and е
346
+ const contents = makeContents({ "moment/locale/ru.js": content });
347
+ const findings = checkObfuscation(contents);
348
+ expect(findings.some((f) => f.id === "CYRILLIC_HOMOGLYPH")).toBe(false);
349
+ });
350
+ it("skips Cyrillic in encoding table files", () => {
351
+ const content = "module.exports = { '\u0430': 0x00 };"; // Cyrillic а
352
+ const contents = makeContents({ "encodings/tables/cp866.js": content });
353
+ const findings = checkObfuscation(contents);
354
+ expect(findings.some((f) => f.id === "CYRILLIC_HOMOGLYPH")).toBe(false);
355
+ });
356
+ });
357
+ describe("variation selector threshold", () => {
358
+ it("ignores fewer than 50 variation selectors (normal emoji use)", () => {
359
+ // 30 variation selectors - below threshold
360
+ const variations = Array(30).fill("\uFE0F").join("x");
361
+ const content = `const emoji = "${variations}";`;
362
+ const contents = makeContents({ "extension.js": content });
363
+ const findings = checkObfuscation(contents);
364
+ expect(findings.some((f) => f.id === "VARIATION_SELECTOR")).toBe(false);
365
+ });
366
+ it("detects 50+ variation selectors (GlassWorm technique)", () => {
367
+ // 55 variation selectors - above threshold
368
+ const variations = Array(55).fill("\uFE0F").join("x");
369
+ const content = `const payload = "${variations}";`;
370
+ const contents = makeContents({ "extension.js": content });
371
+ const findings = checkObfuscation(contents);
372
+ expect(findings.some((f) => f.id === "VARIATION_SELECTOR")).toBe(true);
373
+ });
374
+ });
375
+ });
376
+ describe("category assignment", () => {
377
+ it("assigns obfuscation category to entropy findings", () => {
378
+ // Use full alphanumeric charset for high entropy (log2(62) ≈ 5.95 bits/char)
379
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
380
+ let highEntropy = "";
381
+ for (let i = 0; i < 300; i++) {
382
+ highEntropy += chars[i % chars.length];
383
+ }
384
+ const content = `const data = "${highEntropy}";`;
385
+ const contents = makeContents({ "test.js": content });
386
+ const findings = checkObfuscation(contents);
387
+ const finding = findings.find((f) => f.id === "OBFUSCATION_HIGH_ENTROPY");
388
+ expect(finding?.category).toBe("obfuscation");
389
+ });
390
+ it("assigns obfuscation category to unicode findings", () => {
391
+ const content = "const admin\u202E = true;";
392
+ const contents = makeContents({ "test.js": content });
393
+ const findings = checkObfuscation(contents);
394
+ const finding = findings.find((f) => f.id === "BIDI_OVERRIDE");
395
+ expect(finding?.category).toBe("obfuscation");
396
+ });
397
+ });
398
+ });
399
+ //# sourceMappingURL=obfuscation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obfuscation.test.js","sourceRoot":"","sources":["../../../src/scanner/checks/obfuscation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,SAAS,YAAY,CAAC,KAA6B;IACjD,MAAM,QAAQ,GAAiB;QAC7B,IAAI,EAAE,gBAAgB;QACtB,SAAS,EAAE,MAAM;QACjB,OAAO,EAAE,OAAO;KACjB,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AACzD,CAAC;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,+EAA+E;IAC/E,oBAAoB;IACpB,+EAA+E;IAE/E,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,0EAA0E;YAC1E,mEAAmE;YACnE,mDAAmD;YACnD,MAAM,KAAK,GAAG,gEAAgE,CAAC;YAC/E,IAAI,WAAW,GAAG,EAAE,CAAC;YACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,WAAW,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YACzC,CAAC;YACD,MAAM,OAAO,GAAG,iBAAiB,WAAW,IAAI,CAAC;YACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,OAAO,GAAG;;;;;OAKf,CAAC;YACF,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,2BAA2B;IAC3B,+EAA+E;IAE/E,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;QAC/C,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,wBAAwB;YACxB,MAAM,OAAO,GAAG,oCAAoC,CAAC;YACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,OAAO,GAAG,oCAAoC,CAAC;YACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,OAAO,GAAG,6BAA6B,CAAC;YAC9C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,kBAAkB,CAAC,CAAC;YAE3E,MAAM,CAAC,gBAAgB,CAAC,CAAC,aAAa,EAAE,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qDAAqD,EAAE,GAAG,EAAE;QACnE,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;YACtE,4EAA4E;YAC5E,qDAAqD;YACrD,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,oBAAoB,UAAU,IAAI,CAAC;YACnD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,wEAAwE;YACxE,MAAM,OAAO,GAAG,8BAA8B,CAAC;YAC/C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC9E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE;QACjE,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,OAAO,GAAG,2BAA2B,CAAC;YAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,OAAO,GAAG,2BAA2B,CAAC;YAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,yDAAyD;YACzD,MAAM,OAAO,GAAG,yDAAyD,CAAC,CAAC,WAAW;YACtF,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,OAAO,GAAG,6BAA6B,CAAC,CAAC,iBAAiB;YAChE,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,sBAAsB,CAAC,CAAC;YAE5E,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC7C,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;YACjE,MAAM,OAAO,GAAG,0BAA0B,CAAC,CAAC,aAAa;YACzD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;YACjE,MAAM,OAAO,GAAG,iCAAiC,CAAC,CAAC,aAAa;YAChE,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,OAAO,GAAG,0BAA0B,CAAC,CAAC,yBAAyB;YACrE,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;YAExD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC;YAE5E,MAAM,CAAC,eAAe,CAAC,CAAC,aAAa,EAAE,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAClE,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,qEAAqE;YACrE,MAAM,OAAO,GAAG,uEAAuE,CAAC;YACxF,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;YAC5D,MAAM,OAAO,GAAG,yEAAyE,CAAC;YAC1F,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC/D,MAAM,OAAO,GACX,uFAAuF,CAAC;YAC1F,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,gDAAgD;YAChD,MAAM,OAAO,GAAG,8BAA8B,CAAC;YAC/C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;YAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,0DAA0D;YAC1D,MAAM,OAAO,GAAG,2BAA2B,CAAC;YAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,MAAM,OAAO,GAAG,oCAAoC,CAAC;YACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,OAAO,GAAG,wBAAwB,CAAC;YACzC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;YAExD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;YAC9B,2DAA2D;YAC3D,MAAM,OAAO,GAAG,oBAAoB,CAAC;YACrC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;YAEvD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC/D,uDAAuD;YACvD,MAAM,OAAO,GAAG,uBAAuB,CAAC;YACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC;YAE/D,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC/D,MAAM,OAAO,GAAG,2BAA2B,CAAC;YAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC;YAC/D,MAAM,UAAU,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAyB,CAAC;YAE7E,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,OAAO,GAAG,yCAAyC,CAAC;YAC1D,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC;YAE/D,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,6EAA6E;YAC7E,MAAM,KAAK,GAAG,gEAAgE,CAAC;YAC/E,IAAI,WAAW,GAAG,EAAE,CAAC;YACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,WAAW,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YACzC,CAAC;YACD,MAAM,OAAO,GAAG,iBAAiB,WAAW,IAAI,CAAC;YACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC;YAE1E,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,4BAA4B;IAC5B,+EAA+E;IAE/E,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;YACvC,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;gBACtD,MAAM,KAAK,GAAG,gEAAgE,CAAC;gBAC/E,IAAI,WAAW,GAAG,EAAE,CAAC;gBACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7B,WAAW,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;gBACzC,CAAC;gBACD,MAAM,OAAO,GAAG,iBAAiB,WAAW,IAAI,CAAC;gBACjD,MAAM,QAAQ,GAAG,YAAY,CAAC;oBAC5B,mDAAmD,EAAE,OAAO;iBAC7D,CAAC,CAAC;gBAEH,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChF,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;gBAChD,MAAM,OAAO,GAAG,oCAAoC,CAAC,CAAC,sBAAsB;gBAC5E,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,kCAAkC,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE/E,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;gBACnD,MAAM,OAAO,GAAG,0BAA0B,CAAC,CAAC,aAAa;gBACzD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,4CAA4C,EAAE,OAAO,EAAE,CAAC,CAAC;gBAEzF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;gBAChE,MAAM,OAAO,GAAG,2BAA2B,CAAC;gBAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,0CAA0C,EAAE,OAAO,EAAE,CAAC,CAAC;gBAEvF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAChD,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;gBACjD,iDAAiD;gBACjD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACvC,MAAM,OAAO,GAAG,gBAAgB,UAAU,IAAI,CAAC;gBAC/C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,0BAA0B,EAAE,OAAO,EAAE,CAAC,CAAC;gBAEvE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;gBACpD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACvC,MAAM,OAAO,GAAG,mBAAmB,UAAU,IAAI,CAAC;gBAClD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,6BAA6B,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE1E,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;gBAChD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACvC,MAAM,OAAO,GAAG,yBAAyB,UAAU,EAAE,CAAC;gBACtD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,CAAC;gBAElE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;gBAClE,8CAA8C;gBAC9C,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtD,MAAM,OAAO,GAAG,oBAAoB,UAAU,mBAAmB,CAAC;gBAClE,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;YACnC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;gBAC5C,MAAM,OAAO,GAAG,yBAAyB,CAAC;gBAC1C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,kCAAkC,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE/E,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;gBAC9C,MAAM,OAAO,GAAG,yBAAyB,CAAC;gBAC1C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,sCAAsC,EAAE,OAAO,EAAE,CAAC,CAAC;gBAEnF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;gBACtD,MAAM,OAAO,GAAG,uBAAuB,CAAC;gBACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,gCAAgC,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE7E,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;gBACzD,MAAM,OAAO,GAAG,2BAA2B,CAAC;gBAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,wBAAwB,EAAE,OAAO,EAAE,CAAC,CAAC;gBAErE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;YACpC,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;gBAC/C,MAAM,OAAO,GAAG,oCAAoC,CAAC,CAAC,mBAAmB;gBACzE,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,CAAC;gBAElE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;gBAChD,MAAM,OAAO,GAAG,sCAAsC,CAAC,CAAC,aAAa;gBACrE,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,2BAA2B,EAAE,OAAO,EAAE,CAAC,CAAC;gBAExE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;YAC5C,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;gBACtE,2CAA2C;gBAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtD,MAAM,OAAO,GAAG,kBAAkB,UAAU,IAAI,CAAC;gBACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1E,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;gBAC/D,2CAA2C;gBAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtD,MAAM,OAAO,GAAG,oBAAoB,UAAU,IAAI,CAAC;gBACnD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,6EAA6E;YAC7E,MAAM,KAAK,GAAG,gEAAgE,CAAC;YAC/E,IAAI,WAAW,GAAG,EAAE,CAAC;YACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7B,WAAW,IAAI,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YACzC,CAAC;YACD,MAAM,OAAO,GAAG,iBAAiB,WAAW,IAAI,CAAC;YACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,0BAA0B,CAAC,CAAC;YAE1E,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,OAAO,GAAG,2BAA2B,CAAC;YAC5C,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAAC;YAE/D,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { BlocklistEntry, Finding, VsixContents, VsixManifest, ZooData } from "../types.js";
2
+ interface PackageJson {
3
+ name?: string;
4
+ dependencies?: Record<string, string>;
5
+ devDependencies?: Record<string, string>;
6
+ scripts?: Record<string, string>;
7
+ }
8
+ export declare function checkBlocklist(manifest: VsixManifest, blocklist: BlocklistEntry[]): Finding[];
9
+ export declare function checkActivationEvents(manifest: VsixManifest): Finding[];
10
+ export declare function checkThemeAbuse(manifest: VsixManifest): Finding[];
11
+ export declare function checkSuspiciousPermissions(manifest: VsixManifest): Finding[];
12
+ export declare function checkMaliciousPackages(packageJson: PackageJson, maliciousPackages: Set<string>): Finding[];
13
+ export declare function checkTyposquattingPackages(packageJson: PackageJson): Finding[];
14
+ export declare function checkLifecycleScripts(packageJson: PackageJson): Finding[];
15
+ export declare function checkPackage(contents: VsixContents, zooData: ZooData): Finding[];
16
+ export {};
17
+ //# sourceMappingURL=package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../../src/scanner/checks/package.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEhG,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAmLD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,EAAE,CAyB7F;AAID,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,EAAE,CAmDvE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,EAAE,CAsCjE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,EAAE,CAkC5E;AAID,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC7B,OAAO,EAAE,CAyBX;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,EAAE,CA6B9E;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,EAAE,CAuDzE;AAID,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CA4BhF"}