@mneme-ai/core 0.8.4 → 0.10.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 (272) hide show
  1. package/dist/entities/go-parser.d.ts +47 -0
  2. package/dist/entities/go-parser.d.ts.map +1 -0
  3. package/dist/entities/go-parser.js +315 -0
  4. package/dist/entities/go-parser.js.map +1 -0
  5. package/dist/entities/go-parser.test.d.ts +2 -0
  6. package/dist/entities/go-parser.test.d.ts.map +1 -0
  7. package/dist/entities/go-parser.test.js +147 -0
  8. package/dist/entities/go-parser.test.js.map +1 -0
  9. package/dist/entities/index.d.ts +1 -0
  10. package/dist/entities/index.d.ts.map +1 -1
  11. package/dist/entities/index.js +1 -0
  12. package/dist/entities/index.js.map +1 -1
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/indexer/indexer.d.ts +12 -0
  18. package/dist/indexer/indexer.d.ts.map +1 -1
  19. package/dist/indexer/indexer.js +28 -1
  20. package/dist/indexer/indexer.js.map +1 -1
  21. package/dist/insights/bus-factor.d.ts +58 -0
  22. package/dist/insights/bus-factor.d.ts.map +1 -0
  23. package/dist/insights/bus-factor.js +117 -0
  24. package/dist/insights/bus-factor.js.map +1 -0
  25. package/dist/insights/bus-factor.test.d.ts +2 -0
  26. package/dist/insights/bus-factor.test.d.ts.map +1 -0
  27. package/dist/insights/bus-factor.test.js +149 -0
  28. package/dist/insights/bus-factor.test.js.map +1 -0
  29. package/dist/insights/commit-coach.d.ts +80 -0
  30. package/dist/insights/commit-coach.d.ts.map +1 -0
  31. package/dist/insights/commit-coach.js +230 -0
  32. package/dist/insights/commit-coach.js.map +1 -0
  33. package/dist/insights/commit-coach.test.d.ts +2 -0
  34. package/dist/insights/commit-coach.test.d.ts.map +1 -0
  35. package/dist/insights/commit-coach.test.js +163 -0
  36. package/dist/insights/commit-coach.test.js.map +1 -0
  37. package/dist/insights/crystal-ball.d.ts +76 -0
  38. package/dist/insights/crystal-ball.d.ts.map +1 -0
  39. package/dist/insights/crystal-ball.js +219 -0
  40. package/dist/insights/crystal-ball.js.map +1 -0
  41. package/dist/insights/crystal-ball.test.d.ts +2 -0
  42. package/dist/insights/crystal-ball.test.d.ts.map +1 -0
  43. package/dist/insights/crystal-ball.test.js +157 -0
  44. package/dist/insights/crystal-ball.test.js.map +1 -0
  45. package/dist/insights/decisions.d.ts +38 -0
  46. package/dist/insights/decisions.d.ts.map +1 -0
  47. package/dist/insights/decisions.js +125 -0
  48. package/dist/insights/decisions.js.map +1 -0
  49. package/dist/insights/decisions.test.d.ts +2 -0
  50. package/dist/insights/decisions.test.d.ts.map +1 -0
  51. package/dist/insights/decisions.test.js +141 -0
  52. package/dist/insights/decisions.test.js.map +1 -0
  53. package/dist/insights/dream.d.ts +71 -0
  54. package/dist/insights/dream.d.ts.map +1 -0
  55. package/dist/insights/dream.js +235 -0
  56. package/dist/insights/dream.js.map +1 -0
  57. package/dist/insights/dream.test.d.ts +2 -0
  58. package/dist/insights/dream.test.d.ts.map +1 -0
  59. package/dist/insights/dream.test.js +127 -0
  60. package/dist/insights/dream.test.js.map +1 -0
  61. package/dist/insights/index.d.ts +21 -0
  62. package/dist/insights/index.d.ts.map +1 -0
  63. package/dist/insights/index.js +21 -0
  64. package/dist/insights/index.js.map +1 -0
  65. package/dist/insights/obsidian.d.ts +42 -0
  66. package/dist/insights/obsidian.d.ts.map +1 -0
  67. package/dist/insights/obsidian.js +263 -0
  68. package/dist/insights/obsidian.js.map +1 -0
  69. package/dist/insights/obsidian.test.d.ts +2 -0
  70. package/dist/insights/obsidian.test.d.ts.map +1 -0
  71. package/dist/insights/obsidian.test.js +241 -0
  72. package/dist/insights/obsidian.test.js.map +1 -0
  73. package/dist/insights/paradox.d.ts +36 -0
  74. package/dist/insights/paradox.d.ts.map +1 -0
  75. package/dist/insights/paradox.js +201 -0
  76. package/dist/insights/paradox.js.map +1 -0
  77. package/dist/insights/paradox.test.d.ts +2 -0
  78. package/dist/insights/paradox.test.d.ts.map +1 -0
  79. package/dist/insights/paradox.test.js +88 -0
  80. package/dist/insights/paradox.test.js.map +1 -0
  81. package/dist/insights/regret.d.ts +57 -0
  82. package/dist/insights/regret.d.ts.map +1 -0
  83. package/dist/insights/regret.js +137 -0
  84. package/dist/insights/regret.js.map +1 -0
  85. package/dist/insights/regret.test.d.ts +2 -0
  86. package/dist/insights/regret.test.d.ts.map +1 -0
  87. package/dist/insights/regret.test.js +153 -0
  88. package/dist/insights/regret.test.js.map +1 -0
  89. package/dist/insights/stack-trace.d.ts +40 -0
  90. package/dist/insights/stack-trace.d.ts.map +1 -0
  91. package/dist/insights/stack-trace.js +127 -0
  92. package/dist/insights/stack-trace.js.map +1 -0
  93. package/dist/insights/stack-trace.test.d.ts +2 -0
  94. package/dist/insights/stack-trace.test.d.ts.map +1 -0
  95. package/dist/insights/stack-trace.test.js +103 -0
  96. package/dist/insights/stack-trace.test.js.map +1 -0
  97. package/dist/insights/story.d.ts +34 -0
  98. package/dist/insights/story.d.ts.map +1 -0
  99. package/dist/insights/story.js +100 -0
  100. package/dist/insights/story.js.map +1 -0
  101. package/dist/insights/story.test.d.ts +2 -0
  102. package/dist/insights/story.test.d.ts.map +1 -0
  103. package/dist/insights/story.test.js +99 -0
  104. package/dist/insights/story.test.js.map +1 -0
  105. package/dist/insights/suggest.d.ts +29 -0
  106. package/dist/insights/suggest.d.ts.map +1 -0
  107. package/dist/insights/suggest.js +93 -0
  108. package/dist/insights/suggest.js.map +1 -0
  109. package/dist/insights/suggest.test.d.ts +2 -0
  110. package/dist/insights/suggest.test.d.ts.map +1 -0
  111. package/dist/insights/suggest.test.js +71 -0
  112. package/dist/insights/suggest.test.js.map +1 -0
  113. package/dist/insights/who-knows.d.ts +66 -0
  114. package/dist/insights/who-knows.d.ts.map +1 -0
  115. package/dist/insights/who-knows.js +125 -0
  116. package/dist/insights/who-knows.js.map +1 -0
  117. package/dist/insights/who-knows.test.d.ts +2 -0
  118. package/dist/insights/who-knows.test.d.ts.map +1 -0
  119. package/dist/insights/who-knows.test.js +109 -0
  120. package/dist/insights/who-knows.test.js.map +1 -0
  121. package/dist/quant/alpha.d.ts +87 -0
  122. package/dist/quant/alpha.d.ts.map +1 -0
  123. package/dist/quant/alpha.js +103 -0
  124. package/dist/quant/alpha.js.map +1 -0
  125. package/dist/quant/alpha.test.d.ts +2 -0
  126. package/dist/quant/alpha.test.d.ts.map +1 -0
  127. package/dist/quant/alpha.test.js +147 -0
  128. package/dist/quant/alpha.test.js.map +1 -0
  129. package/dist/quant/backtest.d.ts +57 -0
  130. package/dist/quant/backtest.d.ts.map +1 -0
  131. package/dist/quant/backtest.js +90 -0
  132. package/dist/quant/backtest.js.map +1 -0
  133. package/dist/quant/backtest.test.d.ts +2 -0
  134. package/dist/quant/backtest.test.d.ts.map +1 -0
  135. package/dist/quant/backtest.test.js +133 -0
  136. package/dist/quant/backtest.test.js.map +1 -0
  137. package/dist/quant/black-swan.d.ts +45 -0
  138. package/dist/quant/black-swan.d.ts.map +1 -0
  139. package/dist/quant/black-swan.js +112 -0
  140. package/dist/quant/black-swan.js.map +1 -0
  141. package/dist/quant/black-swan.test.d.ts +2 -0
  142. package/dist/quant/black-swan.test.d.ts.map +1 -0
  143. package/dist/quant/black-swan.test.js +131 -0
  144. package/dist/quant/black-swan.test.js.map +1 -0
  145. package/dist/quant/correlation-matrix.d.ts +54 -0
  146. package/dist/quant/correlation-matrix.d.ts.map +1 -0
  147. package/dist/quant/correlation-matrix.js +103 -0
  148. package/dist/quant/correlation-matrix.js.map +1 -0
  149. package/dist/quant/correlation-matrix.test.d.ts +2 -0
  150. package/dist/quant/correlation-matrix.test.d.ts.map +1 -0
  151. package/dist/quant/correlation-matrix.test.js +118 -0
  152. package/dist/quant/correlation-matrix.test.js.map +1 -0
  153. package/dist/quant/drawdown.d.ts +51 -0
  154. package/dist/quant/drawdown.d.ts.map +1 -0
  155. package/dist/quant/drawdown.js +96 -0
  156. package/dist/quant/drawdown.js.map +1 -0
  157. package/dist/quant/drawdown.test.d.ts +2 -0
  158. package/dist/quant/drawdown.test.d.ts.map +1 -0
  159. package/dist/quant/drawdown.test.js +166 -0
  160. package/dist/quant/drawdown.test.js.map +1 -0
  161. package/dist/quant/greek.d.ts +55 -0
  162. package/dist/quant/greek.d.ts.map +1 -0
  163. package/dist/quant/greek.js +157 -0
  164. package/dist/quant/greek.js.map +1 -0
  165. package/dist/quant/greek.test.d.ts +2 -0
  166. package/dist/quant/greek.test.d.ts.map +1 -0
  167. package/dist/quant/greek.test.js +138 -0
  168. package/dist/quant/greek.test.js.map +1 -0
  169. package/dist/quant/implied-volatility.d.ts +65 -0
  170. package/dist/quant/implied-volatility.d.ts.map +1 -0
  171. package/dist/quant/implied-volatility.js +149 -0
  172. package/dist/quant/implied-volatility.js.map +1 -0
  173. package/dist/quant/implied-volatility.test.d.ts +2 -0
  174. package/dist/quant/implied-volatility.test.d.ts.map +1 -0
  175. package/dist/quant/implied-volatility.test.js +127 -0
  176. package/dist/quant/implied-volatility.test.js.map +1 -0
  177. package/dist/quant/index.d.ts +28 -0
  178. package/dist/quant/index.d.ts.map +1 -0
  179. package/dist/quant/index.js +28 -0
  180. package/dist/quant/index.js.map +1 -0
  181. package/dist/quant/insider-trading.d.ts +56 -0
  182. package/dist/quant/insider-trading.d.ts.map +1 -0
  183. package/dist/quant/insider-trading.js +129 -0
  184. package/dist/quant/insider-trading.js.map +1 -0
  185. package/dist/quant/insider-trading.test.d.ts +2 -0
  186. package/dist/quant/insider-trading.test.d.ts.map +1 -0
  187. package/dist/quant/insider-trading.test.js +130 -0
  188. package/dist/quant/insider-trading.test.js.map +1 -0
  189. package/dist/quant/moneyball.d.ts +48 -0
  190. package/dist/quant/moneyball.d.ts.map +1 -0
  191. package/dist/quant/moneyball.js +110 -0
  192. package/dist/quant/moneyball.js.map +1 -0
  193. package/dist/quant/moneyball.test.d.ts +2 -0
  194. package/dist/quant/moneyball.test.d.ts.map +1 -0
  195. package/dist/quant/moneyball.test.js +137 -0
  196. package/dist/quant/moneyball.test.js.map +1 -0
  197. package/dist/quant/tax-loss-harvest.d.ts +59 -0
  198. package/dist/quant/tax-loss-harvest.d.ts.map +1 -0
  199. package/dist/quant/tax-loss-harvest.js +126 -0
  200. package/dist/quant/tax-loss-harvest.js.map +1 -0
  201. package/dist/quant/tax-loss-harvest.test.d.ts +2 -0
  202. package/dist/quant/tax-loss-harvest.test.d.ts.map +1 -0
  203. package/dist/quant/tax-loss-harvest.test.js +126 -0
  204. package/dist/quant/tax-loss-harvest.test.js.map +1 -0
  205. package/dist/retrieve/index.d.ts +2 -0
  206. package/dist/retrieve/index.d.ts.map +1 -1
  207. package/dist/retrieve/index.js +2 -0
  208. package/dist/retrieve/index.js.map +1 -1
  209. package/dist/retrieve/intent.d.ts +32 -0
  210. package/dist/retrieve/intent.d.ts.map +1 -0
  211. package/dist/retrieve/intent.js +104 -0
  212. package/dist/retrieve/intent.js.map +1 -0
  213. package/dist/retrieve/intent.test.d.ts +2 -0
  214. package/dist/retrieve/intent.test.d.ts.map +1 -0
  215. package/dist/retrieve/intent.test.js +106 -0
  216. package/dist/retrieve/intent.test.js.map +1 -0
  217. package/dist/retrieve/search.d.ts +30 -0
  218. package/dist/retrieve/search.d.ts.map +1 -1
  219. package/dist/retrieve/search.js +48 -0
  220. package/dist/retrieve/search.js.map +1 -1
  221. package/dist/retrieve/search.test.js +84 -1
  222. package/dist/retrieve/search.test.js.map +1 -1
  223. package/dist/retrieve/synthesize.d.ts +57 -0
  224. package/dist/retrieve/synthesize.d.ts.map +1 -0
  225. package/dist/retrieve/synthesize.js +191 -0
  226. package/dist/retrieve/synthesize.js.map +1 -0
  227. package/dist/retrieve/synthesize.test.d.ts +2 -0
  228. package/dist/retrieve/synthesize.test.d.ts.map +1 -0
  229. package/dist/retrieve/synthesize.test.js +127 -0
  230. package/dist/retrieve/synthesize.test.js.map +1 -0
  231. package/dist/store/schema.d.ts +2 -2
  232. package/dist/store/schema.d.ts.map +1 -1
  233. package/dist/store/schema.js +60 -2
  234. package/dist/store/schema.js.map +1 -1
  235. package/dist/store/sqlite.d.ts +2 -0
  236. package/dist/store/sqlite.d.ts.map +1 -1
  237. package/dist/store/sqlite.js +24 -0
  238. package/dist/store/sqlite.js.map +1 -1
  239. package/dist/store/sqlite.test.js +1 -1
  240. package/dist/util/index.d.ts +2 -0
  241. package/dist/util/index.d.ts.map +1 -1
  242. package/dist/util/index.js +2 -1
  243. package/dist/util/index.js.map +1 -1
  244. package/dist/util/redact.d.ts +58 -0
  245. package/dist/util/redact.d.ts.map +1 -0
  246. package/dist/util/redact.js +129 -0
  247. package/dist/util/redact.js.map +1 -0
  248. package/dist/util/redact.test.d.ts +2 -0
  249. package/dist/util/redact.test.d.ts.map +1 -0
  250. package/dist/util/redact.test.js +148 -0
  251. package/dist/util/redact.test.js.map +1 -0
  252. package/dist/wisdom/calibrator.d.ts +43 -0
  253. package/dist/wisdom/calibrator.d.ts.map +1 -0
  254. package/dist/wisdom/calibrator.js +120 -0
  255. package/dist/wisdom/calibrator.js.map +1 -0
  256. package/dist/wisdom/feedback.d.ts +45 -0
  257. package/dist/wisdom/feedback.d.ts.map +1 -0
  258. package/dist/wisdom/feedback.js +116 -0
  259. package/dist/wisdom/feedback.js.map +1 -0
  260. package/dist/wisdom/index.d.ts +15 -0
  261. package/dist/wisdom/index.d.ts.map +1 -0
  262. package/dist/wisdom/index.js +15 -0
  263. package/dist/wisdom/index.js.map +1 -0
  264. package/dist/wisdom/types.d.ts +67 -0
  265. package/dist/wisdom/types.d.ts.map +1 -0
  266. package/dist/wisdom/types.js +20 -0
  267. package/dist/wisdom/types.js.map +1 -0
  268. package/dist/wisdom/wisdom.test.d.ts +2 -0
  269. package/dist/wisdom/wisdom.test.d.ts.map +1 -0
  270. package/dist/wisdom/wisdom.test.js +144 -0
  271. package/dist/wisdom/wisdom.test.js.map +1 -0
  272. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"correlation-matrix.js","sourceRoot":"","sources":["../../src/quant/correlation-matrix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=correlation-matrix.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"correlation-matrix.test.d.ts","sourceRoot":"","sources":["../../src/quant/correlation-matrix.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,118 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { correlationMatrix, classifyCouplingTier } from "./correlation-matrix.js";
3
+ const cmt = (hash, date, files) => ({
4
+ hash,
5
+ shortHash: hash.slice(0, 7),
6
+ authorName: "alice",
7
+ authorEmail: "a@x",
8
+ authorDate: `${date}T00:00:00Z`,
9
+ committerDate: `${date}T00:00:00Z`,
10
+ subject: "x",
11
+ body: "",
12
+ parents: [],
13
+ files,
14
+ });
15
+ describe("classifyCouplingTier", () => {
16
+ it("'tight' when both jaccard ≥ 0.6 + lift ≥ 5", () => {
17
+ expect(classifyCouplingTier(0.7, 6)).toBe("tight");
18
+ });
19
+ it("'strong' when one of jaccard ≥ 0.4 or lift ≥ 3", () => {
20
+ expect(classifyCouplingTier(0.5, 1)).toBe("strong");
21
+ expect(classifyCouplingTier(0.1, 4)).toBe("strong");
22
+ });
23
+ it("'moderate' for middling values", () => {
24
+ expect(classifyCouplingTier(0.25, 2)).toBe("moderate");
25
+ });
26
+ it("'weak' otherwise", () => {
27
+ expect(classifyCouplingTier(0.05, 1.2)).toBe("weak");
28
+ });
29
+ });
30
+ describe("correlationMatrix — basic detection", () => {
31
+ it("returns empty when there are no co-occurring file pairs", () => {
32
+ const commits = [
33
+ cmt("a1", "2024-01-01", ["src/a.ts"]),
34
+ cmt("a2", "2024-01-02", ["src/b.ts"]),
35
+ cmt("a3", "2024-01-03", ["src/c.ts"]),
36
+ ];
37
+ expect(correlationMatrix(commits)).toEqual([]);
38
+ });
39
+ it("detects a tightly-coupled pair when both files always change together", () => {
40
+ // 10 co-touched commits + 20 background commits on unrelated files.
41
+ // Background commits lower the baseline rate of x and y so that
42
+ // co-occurrence has lift > 1.5 (otherwise lift = 1 and is filtered out).
43
+ const co = Array.from({ length: 10 }, (_, i) => cmt(`c${i}`.padEnd(7, "x"), `2024-01-${String(i + 1).padStart(2, "0")}`, ["src/x.ts", "src/y.ts"]));
44
+ const bg = Array.from({ length: 20 }, (_, i) => cmt(`bg${i}`.padEnd(7, "x"), `2024-02-${String((i % 28) + 1).padStart(2, "0")}`, [`src/other${i}.ts`]));
45
+ const pairs = correlationMatrix([...co, ...bg], { minFileTouches: 3, minCoOccurrences: 2 });
46
+ const xy = pairs.find((p) => (p.fileA === "src/x.ts" && p.fileB === "src/y.ts") ||
47
+ (p.fileA === "src/y.ts" && p.fileB === "src/x.ts"));
48
+ expect(xy).toBeDefined();
49
+ expect(xy.jaccard).toBeCloseTo(1, 3);
50
+ expect(xy.tier).toBe("tight");
51
+ });
52
+ it("respects minFileTouches threshold", () => {
53
+ const commits = [
54
+ cmt("a1", "2024-01-01", ["src/x.ts", "src/y.ts"]),
55
+ cmt("a2", "2024-01-02", ["src/x.ts", "src/y.ts"]),
56
+ ];
57
+ expect(correlationMatrix(commits, { minFileTouches: 5 })).toEqual([]);
58
+ expect(correlationMatrix(commits, { minFileTouches: 1, minCoOccurrences: 1, minLift: 0 })).toHaveLength(1);
59
+ });
60
+ it("respects minCoOccurrences threshold", () => {
61
+ const commits = [
62
+ cmt("a1", "2024-01-01", ["src/x.ts", "src/y.ts"]),
63
+ cmt("a2", "2024-01-02", ["src/x.ts"]),
64
+ cmt("a3", "2024-01-03", ["src/y.ts"]),
65
+ cmt("a4", "2024-01-04", ["src/x.ts"]),
66
+ ];
67
+ expect(correlationMatrix(commits, { minFileTouches: 1, minCoOccurrences: 3 })).toEqual([]);
68
+ });
69
+ it("respects minLift threshold (filters weak pairs)", () => {
70
+ // Build a noisy history where x and y co-occur but at random level
71
+ const commits = [];
72
+ for (let i = 0; i < 20; i++)
73
+ commits.push(cmt(`x${i}`.padEnd(7, "y"), `2024-01-${String(i + 1).padStart(2, "0")}`, ["src/x.ts"]));
74
+ for (let i = 0; i < 20; i++)
75
+ commits.push(cmt(`y${i}`.padEnd(7, "x"), `2024-02-${String(i + 1).padStart(2, "0")}`, ["src/y.ts"]));
76
+ commits.push(cmt("co1", "2024-03-01", ["src/x.ts", "src/y.ts"]));
77
+ commits.push(cmt("co2", "2024-03-02", ["src/x.ts", "src/y.ts"]));
78
+ // 2 co-occurrences but x has 22 total, y has 22 total, so jaccard tiny + lift low
79
+ expect(correlationMatrix(commits, { minLift: 5 })).toEqual([]);
80
+ });
81
+ });
82
+ describe("correlationMatrix — sort + tiers", () => {
83
+ it("sorts by lift desc", () => {
84
+ const commits = [
85
+ // Pair 1: TIGHT (5 co-occurrences, files appear in nothing else).
86
+ cmt("a1", "2024-01-01", ["src/tight-a.ts", "src/tight-b.ts"]),
87
+ cmt("a2", "2024-01-02", ["src/tight-a.ts", "src/tight-b.ts"]),
88
+ cmt("a3", "2024-01-03", ["src/tight-a.ts", "src/tight-b.ts"]),
89
+ cmt("a4", "2024-01-04", ["src/tight-a.ts", "src/tight-b.ts"]),
90
+ cmt("a5", "2024-01-05", ["src/tight-a.ts", "src/tight-b.ts"]),
91
+ // Pair 2: LOOSER (3 co, but both files also touched alone — diluted lift).
92
+ cmt("b1", "2024-02-01", ["src/loose-a.ts", "src/loose-b.ts"]),
93
+ cmt("b2", "2024-02-02", ["src/loose-a.ts", "src/loose-b.ts"]),
94
+ cmt("b3", "2024-02-03", ["src/loose-a.ts", "src/loose-b.ts"]),
95
+ cmt("b4", "2024-02-04", ["src/loose-a.ts"]),
96
+ cmt("b5", "2024-02-05", ["src/loose-a.ts"]),
97
+ cmt("b6", "2024-02-06", ["src/loose-b.ts"]),
98
+ cmt("b7", "2024-02-07", ["src/loose-b.ts"]),
99
+ // Background — 15 commits on unrelated files lower the global baseline,
100
+ // so even the tight pair has lift > 1.5 (otherwise lift = 1 and filtered).
101
+ ...Array.from({ length: 15 }, (_, i) => cmt(`bg${i}`.padEnd(7, "x"), `2024-03-${String(i + 1).padStart(2, "0")}`, [`src/other${i}.ts`])),
102
+ ];
103
+ const pairs = correlationMatrix(commits, { minFileTouches: 3, minCoOccurrences: 2 });
104
+ expect(pairs[0].fileA).toMatch(/tight-/);
105
+ expect(pairs[0].lift).toBeGreaterThan(pairs[pairs.length - 1].lift);
106
+ });
107
+ it("respects topN", () => {
108
+ const commits = [];
109
+ // 10 file pairs, each with 4 co-occurrences
110
+ for (let p = 0; p < 10; p++) {
111
+ for (let i = 0; i < 4; i++) {
112
+ commits.push(cmt(`p${p}c${i}`.padEnd(7, "x"), `2024-${String(p + 1).padStart(2, "0")}-0${i + 1}`, [`src/p${p}-a.ts`, `src/p${p}-b.ts`]));
113
+ }
114
+ }
115
+ expect(correlationMatrix(commits, { minFileTouches: 1, minCoOccurrences: 2, topN: 5, minLift: 0 }).length).toBeLessThanOrEqual(5);
116
+ });
117
+ });
118
+ //# sourceMappingURL=correlation-matrix.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"correlation-matrix.test.js","sourceRoot":"","sources":["../../src/quant/correlation-matrix.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `mneme drawdown` — find the worst "losing streaks" in repo history.
3
+ *
4
+ * In finance, a drawdown is a peak-to-trough decline. In a codebase, it's
5
+ * a stretch of bug-fix-only commits with no feature progress — pure
6
+ * firefighting. Surfacing these is gold for retrospectives:
7
+ *
8
+ * "We spent 3 weeks last September shipping nothing but fixes."
9
+ *
10
+ * Pure data analysis. No LLM. Tested via TDD against synthetic histories.
11
+ */
12
+ import type { Commit } from "../types.js";
13
+ export interface Drawdown {
14
+ /** Start commit (peak — last feat before the drawdown). */
15
+ startHash: string;
16
+ startDate: string;
17
+ /** End commit (trough — last fix in the streak). */
18
+ endHash: string;
19
+ endDate: string;
20
+ /** Number of consecutive non-feat commits in the streak. */
21
+ length: number;
22
+ /** Days between start and end. */
23
+ durationDays: number;
24
+ /** Sample fix subjects from inside the streak (up to 3). */
25
+ sampleFixes: string[];
26
+ /** Severity tier from length × duration. */
27
+ tier: "minor" | "moderate" | "severe" | "critical";
28
+ }
29
+ /** Decide whether a commit subject is a "fix" (counts toward drawdown). */
30
+ export declare function isFixCommit(c: Commit): boolean;
31
+ /** Decide whether a commit subject is a "feature" (resets the streak). */
32
+ export declare function isFeatCommit(c: Commit): boolean;
33
+ /**
34
+ * Detect drawdowns — runs of ≥ minLength consecutive non-feat commits
35
+ * where ≥ fixRatio of those commits are explicit fixes.
36
+ */
37
+ export declare function detectDrawdowns(commits: Commit[], opts?: {
38
+ minLength?: number;
39
+ fixRatio?: number;
40
+ topN?: number;
41
+ }): Drawdown[];
42
+ export declare function classifyDrawdown(length: number, durationDays: number): Drawdown["tier"];
43
+ export interface DrawdownSummary {
44
+ total: number;
45
+ longestStreak: number;
46
+ totalFixingDays: number;
47
+ /** Fraction of the repo's lifespan spent in drawdown. */
48
+ drawdownFraction: number;
49
+ }
50
+ export declare function summarizeDrawdowns(commits: Commit[], drawdowns: Drawdown[]): DrawdownSummary;
51
+ //# sourceMappingURL=drawdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawdown.d.ts","sourceRoot":"","sources":["../../src/quant/drawdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,QAAQ;IACvB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,4CAA4C;IAC5C,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;CACpD;AAKD,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAClE,QAAQ,EAAE,CA4CZ;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAKvF;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,eAAe,CAiB5F"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * `mneme drawdown` — find the worst "losing streaks" in repo history.
3
+ *
4
+ * In finance, a drawdown is a peak-to-trough decline. In a codebase, it's
5
+ * a stretch of bug-fix-only commits with no feature progress — pure
6
+ * firefighting. Surfacing these is gold for retrospectives:
7
+ *
8
+ * "We spent 3 weeks last September shipping nothing but fixes."
9
+ *
10
+ * Pure data analysis. No LLM. Tested via TDD against synthetic histories.
11
+ */
12
+ const FEAT_RE = /^feat[(:]/i;
13
+ const FIX_RE = /^(fix|hotfix|bug|revert|patch)[(:]/i;
14
+ /** Decide whether a commit subject is a "fix" (counts toward drawdown). */
15
+ export function isFixCommit(c) {
16
+ return FIX_RE.test(c.subject);
17
+ }
18
+ /** Decide whether a commit subject is a "feature" (resets the streak). */
19
+ export function isFeatCommit(c) {
20
+ return FEAT_RE.test(c.subject);
21
+ }
22
+ /**
23
+ * Detect drawdowns — runs of ≥ minLength consecutive non-feat commits
24
+ * where ≥ fixRatio of those commits are explicit fixes.
25
+ */
26
+ export function detectDrawdowns(commits, opts = {}) {
27
+ const minLength = opts.minLength ?? 3;
28
+ const fixRatio = opts.fixRatio ?? 0.5;
29
+ const topN = opts.topN ?? 10;
30
+ const sorted = [...commits].sort((a, b) => a.authorDate.localeCompare(b.authorDate));
31
+ const out = [];
32
+ let i = 0;
33
+ while (i < sorted.length) {
34
+ if (isFeatCommit(sorted[i])) {
35
+ i += 1;
36
+ continue;
37
+ }
38
+ // Walk forward while non-feat.
39
+ let j = i;
40
+ let fixCount = 0;
41
+ while (j < sorted.length && !isFeatCommit(sorted[j])) {
42
+ if (isFixCommit(sorted[j]))
43
+ fixCount += 1;
44
+ j += 1;
45
+ }
46
+ const length = j - i;
47
+ const ratio = length === 0 ? 0 : fixCount / length;
48
+ if (length >= minLength && ratio >= fixRatio) {
49
+ const start = sorted[i];
50
+ const end = sorted[j - 1];
51
+ const dur = (new Date(end.authorDate).getTime() - new Date(start.authorDate).getTime()) / 86_400_000;
52
+ const samples = sorted.slice(i, j).filter(isFixCommit).slice(0, 3).map((c) => c.subject);
53
+ out.push({
54
+ startHash: start.shortHash || start.hash.slice(0, 7),
55
+ startDate: start.authorDate.slice(0, 10),
56
+ endHash: end.shortHash || end.hash.slice(0, 7),
57
+ endDate: end.authorDate.slice(0, 10),
58
+ length,
59
+ durationDays: Math.round(dur * 10) / 10,
60
+ sampleFixes: samples,
61
+ tier: classifyDrawdown(length, dur),
62
+ });
63
+ }
64
+ i = j === i ? i + 1 : j;
65
+ }
66
+ // Sort by severity (length × duration), desc.
67
+ out.sort((a, b) => b.length * Math.max(b.durationDays, 1) - a.length * Math.max(a.durationDays, 1));
68
+ return out.slice(0, topN);
69
+ }
70
+ export function classifyDrawdown(length, durationDays) {
71
+ if (length >= 15 || durationDays >= 30)
72
+ return "critical";
73
+ if (length >= 8 || durationDays >= 14)
74
+ return "severe";
75
+ if (length >= 5 || durationDays >= 7)
76
+ return "moderate";
77
+ return "minor";
78
+ }
79
+ export function summarizeDrawdowns(commits, drawdowns) {
80
+ if (commits.length === 0) {
81
+ return { total: 0, longestStreak: 0, totalFixingDays: 0, drawdownFraction: 0 };
82
+ }
83
+ const sorted = [...commits].sort((a, b) => a.authorDate.localeCompare(b.authorDate));
84
+ const repoSpan = (new Date(sorted[sorted.length - 1].authorDate).getTime() -
85
+ new Date(sorted[0].authorDate).getTime()) /
86
+ 86_400_000;
87
+ const totalFixingDays = drawdowns.reduce((s, d) => s + d.durationDays, 0);
88
+ const longest = drawdowns.reduce((m, d) => Math.max(m, d.length), 0);
89
+ return {
90
+ total: drawdowns.length,
91
+ longestStreak: longest,
92
+ totalFixingDays: Math.round(totalFixingDays * 10) / 10,
93
+ drawdownFraction: repoSpan === 0 ? 0 : totalFixingDays / repoSpan,
94
+ };
95
+ }
96
+ //# sourceMappingURL=drawdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawdown.js","sourceRoot":"","sources":["../../src/quant/drawdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=drawdown.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawdown.test.d.ts","sourceRoot":"","sources":["../../src/quant/drawdown.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,166 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { detectDrawdowns, summarizeDrawdowns, isFeatCommit, isFixCommit, classifyDrawdown, } from "./drawdown.js";
3
+ const cmt = (hash, date, subject) => ({
4
+ hash,
5
+ shortHash: hash.slice(0, 7),
6
+ authorName: "alice",
7
+ authorEmail: "alice@x",
8
+ authorDate: `${date}T00:00:00Z`,
9
+ committerDate: `${date}T00:00:00Z`,
10
+ subject,
11
+ body: "",
12
+ parents: [],
13
+ files: [],
14
+ });
15
+ describe("isFeatCommit / isFixCommit — Conventional-Commit subject classifiers", () => {
16
+ it("matches feat( and feat:", () => {
17
+ expect(isFeatCommit(cmt("a", "2024-01-01", "feat: thing"))).toBe(true);
18
+ expect(isFeatCommit(cmt("a", "2024-01-01", "feat(auth): thing"))).toBe(true);
19
+ expect(isFeatCommit(cmt("a", "2024-01-01", "feat scoped without colon"))).toBe(false);
20
+ });
21
+ it("matches fix/hotfix/bug/revert/patch", () => {
22
+ expect(isFixCommit(cmt("a", "2024-01-01", "fix: x"))).toBe(true);
23
+ expect(isFixCommit(cmt("a", "2024-01-01", "hotfix: x"))).toBe(true);
24
+ expect(isFixCommit(cmt("a", "2024-01-01", "bug: x"))).toBe(true);
25
+ expect(isFixCommit(cmt("a", "2024-01-01", "revert: x"))).toBe(true);
26
+ expect(isFixCommit(cmt("a", "2024-01-01", "feat: x"))).toBe(false);
27
+ });
28
+ });
29
+ describe("classifyDrawdown — tier from length × duration", () => {
30
+ it("critical at 15+ commits or 30+ days", () => {
31
+ expect(classifyDrawdown(15, 5)).toBe("critical");
32
+ expect(classifyDrawdown(5, 30)).toBe("critical");
33
+ });
34
+ it("severe at 8+ or 14+", () => {
35
+ expect(classifyDrawdown(8, 5)).toBe("severe");
36
+ expect(classifyDrawdown(5, 14)).toBe("severe");
37
+ });
38
+ it("moderate at 5+ or 7+", () => {
39
+ expect(classifyDrawdown(5, 1)).toBe("moderate");
40
+ expect(classifyDrawdown(3, 7)).toBe("moderate");
41
+ });
42
+ it("minor for short streaks", () => {
43
+ expect(classifyDrawdown(3, 2)).toBe("minor");
44
+ });
45
+ });
46
+ describe("detectDrawdowns — simple cases", () => {
47
+ it("returns empty when no fix commits", () => {
48
+ const commits = [
49
+ cmt("a1", "2024-01-01", "feat: A"),
50
+ cmt("a2", "2024-01-02", "feat: B"),
51
+ cmt("a3", "2024-01-03", "feat: C"),
52
+ ];
53
+ expect(detectDrawdowns(commits)).toEqual([]);
54
+ });
55
+ it("returns empty when streak shorter than minLength", () => {
56
+ const commits = [
57
+ cmt("a1", "2024-01-01", "feat: A"),
58
+ cmt("a2", "2024-01-02", "fix: x"),
59
+ cmt("a3", "2024-01-03", "fix: y"),
60
+ cmt("a4", "2024-01-04", "feat: B"),
61
+ ];
62
+ expect(detectDrawdowns(commits, { minLength: 3 })).toEqual([]);
63
+ });
64
+ it("detects a single drawdown of 5 fixes between two feats", () => {
65
+ const commits = [
66
+ cmt("a1", "2024-01-01", "feat: A"),
67
+ cmt("a2", "2024-01-02", "fix: 1"),
68
+ cmt("a3", "2024-01-03", "fix: 2"),
69
+ cmt("a4", "2024-01-04", "fix: 3"),
70
+ cmt("a5", "2024-01-05", "fix: 4"),
71
+ cmt("a6", "2024-01-06", "fix: 5"),
72
+ cmt("a7", "2024-01-07", "feat: B"),
73
+ ];
74
+ const drawdowns = detectDrawdowns(commits, { minLength: 3 });
75
+ expect(drawdowns).toHaveLength(1);
76
+ expect(drawdowns[0].length).toBe(5);
77
+ expect(drawdowns[0].tier).toBe("moderate");
78
+ expect(drawdowns[0].sampleFixes).toHaveLength(3);
79
+ });
80
+ it("detects multiple separate drawdowns", () => {
81
+ const commits = [
82
+ cmt("a1", "2024-01-01", "feat: A"),
83
+ cmt("a2", "2024-01-02", "fix: 1"),
84
+ cmt("a3", "2024-01-03", "fix: 2"),
85
+ cmt("a4", "2024-01-04", "fix: 3"),
86
+ cmt("a5", "2024-01-05", "feat: B"),
87
+ cmt("a6", "2024-01-06", "fix: 4"),
88
+ cmt("a7", "2024-01-07", "fix: 5"),
89
+ cmt("a8", "2024-01-08", "fix: 6"),
90
+ cmt("a9", "2024-01-09", "fix: 7"),
91
+ cmt("a10", "2024-01-10", "feat: C"),
92
+ ];
93
+ const drawdowns = detectDrawdowns(commits, { minLength: 3 });
94
+ expect(drawdowns).toHaveLength(2);
95
+ });
96
+ it("respects fixRatio threshold (mixed chore/fix streaks)", () => {
97
+ const commits = [
98
+ cmt("a1", "2024-01-01", "feat: A"),
99
+ cmt("a2", "2024-01-02", "fix: 1"),
100
+ cmt("a3", "2024-01-03", "chore: bump deps"),
101
+ cmt("a4", "2024-01-04", "chore: lint config"),
102
+ cmt("a5", "2024-01-05", "feat: B"),
103
+ ];
104
+ // 1/3 fix ratio — below default 0.5
105
+ expect(detectDrawdowns(commits, { minLength: 3, fixRatio: 0.5 })).toEqual([]);
106
+ expect(detectDrawdowns(commits, { minLength: 3, fixRatio: 0.3 })).toHaveLength(1);
107
+ });
108
+ it("sorts drawdowns by severity descending", () => {
109
+ const commits = [
110
+ // Drawdown 1: 4 fixes
111
+ cmt("a1", "2024-01-01", "feat: A"),
112
+ cmt("a2", "2024-01-02", "fix: 1"),
113
+ cmt("a3", "2024-01-03", "fix: 2"),
114
+ cmt("a4", "2024-01-04", "fix: 3"),
115
+ cmt("a5", "2024-01-05", "fix: 4"),
116
+ cmt("a6", "2024-01-06", "feat: B"),
117
+ // Drawdown 2: 8 fixes (more severe)
118
+ cmt("b1", "2024-02-01", "fix: 1"),
119
+ cmt("b2", "2024-02-02", "fix: 2"),
120
+ cmt("b3", "2024-02-03", "fix: 3"),
121
+ cmt("b4", "2024-02-04", "fix: 4"),
122
+ cmt("b5", "2024-02-05", "fix: 5"),
123
+ cmt("b6", "2024-02-06", "fix: 6"),
124
+ cmt("b7", "2024-02-07", "fix: 7"),
125
+ cmt("b8", "2024-02-08", "fix: 8"),
126
+ cmt("b9", "2024-02-09", "feat: C"),
127
+ ];
128
+ const drawdowns = detectDrawdowns(commits, { minLength: 3 });
129
+ expect(drawdowns[0].length).toBe(8);
130
+ expect(drawdowns[1].length).toBe(4);
131
+ });
132
+ it("respects topN cap", () => {
133
+ const commits = [];
134
+ for (let i = 0; i < 30; i++) {
135
+ const day = String(i + 1).padStart(2, "0");
136
+ commits.push(cmt(`f${i}`, `2024-01-${day}`, "feat: x"));
137
+ commits.push(cmt(`x${i}`, `2024-01-${day}`, "fix: 1"));
138
+ commits.push(cmt(`y${i}`, `2024-01-${day}`, "fix: 2"));
139
+ commits.push(cmt(`z${i}`, `2024-01-${day}`, "fix: 3"));
140
+ }
141
+ expect(detectDrawdowns(commits, { minLength: 3, topN: 5 }).length).toBeLessThanOrEqual(5);
142
+ });
143
+ });
144
+ describe("summarizeDrawdowns — repo-level metrics", () => {
145
+ it("computes drawdown fraction over repo lifespan", () => {
146
+ const commits = [
147
+ cmt("a1", "2024-01-01", "feat: A"),
148
+ cmt("a2", "2024-01-08", "fix: 1"), // 7 days into lifespan
149
+ cmt("a3", "2024-01-15", "fix: 2"),
150
+ cmt("a4", "2024-01-22", "fix: 3"),
151
+ cmt("a5", "2024-02-01", "feat: B"), // 31 days total
152
+ ];
153
+ const drawdowns = detectDrawdowns(commits, { minLength: 3 });
154
+ const summary = summarizeDrawdowns(commits, drawdowns);
155
+ expect(summary.total).toBe(1);
156
+ expect(summary.longestStreak).toBe(3);
157
+ expect(summary.drawdownFraction).toBeGreaterThan(0);
158
+ expect(summary.drawdownFraction).toBeLessThan(1);
159
+ });
160
+ it("returns zero metrics for empty commits", () => {
161
+ const summary = summarizeDrawdowns([], []);
162
+ expect(summary.total).toBe(0);
163
+ expect(summary.drawdownFraction).toBe(0);
164
+ });
165
+ });
166
+ //# sourceMappingURL=drawdown.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawdown.test.js","sourceRoot":"","sources":["../../src/quant/drawdown.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * `mneme greek` — sensitivity analysis (Δ Γ Θ ν) for a codebase.
3
+ *
4
+ * Δ DELTA — sensitivity to the top contributor (% knowledge lost if X quits)
5
+ * Γ GAMMA — acceleration of risk (super-linear scaling of bug rate vs PR rate)
6
+ * Θ THETA — time decay (untouched files lose coverage over time)
7
+ * ν VEGA — sensitivity to dependency volatility (placeholder for now)
8
+ *
9
+ * Pure analysis. Delta + Gamma are required and computed from store data.
10
+ * Theta is best-effort (depends on coverage indexed). Vega returns null
11
+ * unless dependency manifest data is available — honestly.
12
+ */
13
+ import type { MnemeStore } from "../store/sqlite.js";
14
+ export interface DeltaResult {
15
+ /** The author name. */
16
+ name: string;
17
+ /** Email. */
18
+ email: string;
19
+ /** Files where this author owns ≥ 75% of touches. */
20
+ ownedFiles: string[];
21
+ /** Approximate % of knowledge that walks out the door if they quit. */
22
+ knowledgeLossPct: number;
23
+ }
24
+ export declare function computeDelta(store: MnemeStore, opts?: {
25
+ topN?: number;
26
+ }): DeltaResult[];
27
+ export interface GammaResult {
28
+ /** Slope of (commits per week) → (fix-commits per week). */
29
+ riskAcceleration: number;
30
+ /** Sample size — number of weekly buckets used. */
31
+ weeks: number;
32
+ /** Plain-English interpretation. */
33
+ interpretation: string;
34
+ }
35
+ export declare function computeGamma(store: MnemeStore): GammaResult;
36
+ export interface ThetaResult {
37
+ /** Files untouched for > 6 months. */
38
+ staleFiles: number;
39
+ /** Average days since last touch across stale set. */
40
+ avgStaleDays: number;
41
+ /** Plain-English interpretation. */
42
+ interpretation: string;
43
+ }
44
+ export declare function computeTheta(store: MnemeStore, opts?: {
45
+ now?: Date;
46
+ }): ThetaResult;
47
+ export interface GreekReport {
48
+ delta: DeltaResult[];
49
+ gamma: GammaResult;
50
+ theta: ThetaResult;
51
+ }
52
+ export declare function computeGreeks(store: MnemeStore, opts?: {
53
+ now?: Date;
54
+ }): GreekReport;
55
+ //# sourceMappingURL=greek.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"greek.d.ts","sourceRoot":"","sources":["../../src/quant/greek.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,WAAW,EAAE,CAwD3F;AAID,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAC;CACxB;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CA0C3D;AA4BD,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAAG,WAAW,CA6BtF;AAID,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAAG,WAAW,CAMvF"}