@syke1/mcp-server 1.5.6 → 1.6.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.
@@ -1,250 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.invalidateCouplingCache = invalidateCouplingCache;
4
- exports.mineGitHistory = mineGitHistory;
5
- exports.getCoupledFiles = getCoupledFiles;
6
- const child_process_1 = require("child_process");
7
- // ── Defaults ──
8
- const DEFAULT_MAX_COMMITS = 500;
9
- const DEFAULT_MIN_SUPPORT = 3;
10
- const DEFAULT_MIN_CONFIDENCE = 0.3;
11
- const DEFAULT_MAX_FILES_PER_COMMIT = 20;
12
- const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
13
- // ── Cache ──
14
- let cachedResult = null;
15
- let cachedProjectRoot = null;
16
- /**
17
- * Invalidate the coupling cache. Call this when the graph is refreshed
18
- * or when git history may have changed.
19
- */
20
- function invalidateCouplingCache() {
21
- cachedResult = null;
22
- cachedProjectRoot = null;
23
- }
24
- // ── Git History Mining ──
25
- /**
26
- * Check whether the given directory is inside a git repository.
27
- */
28
- function isGitRepo(projectRoot) {
29
- try {
30
- (0, child_process_1.execSync)("git rev-parse --is-inside-work-tree", {
31
- cwd: projectRoot,
32
- encoding: "utf-8",
33
- stdio: ["pipe", "pipe", "pipe"],
34
- });
35
- return true;
36
- }
37
- catch {
38
- return false;
39
- }
40
- }
41
- /**
42
- * Parse git log output into a list of commits, each containing
43
- * the list of files changed in that commit.
44
- */
45
- function parseGitLog(raw) {
46
- const commits = [];
47
- const segments = raw.split("COMMIT:");
48
- for (const segment of segments) {
49
- const trimmed = segment.trim();
50
- if (!trimmed)
51
- continue;
52
- // First line is the commit hash, remaining lines are file paths
53
- const lines = trimmed.split("\n");
54
- const files = [];
55
- for (let i = 1; i < lines.length; i++) {
56
- const fileLine = lines[i].trim();
57
- if (fileLine) {
58
- files.push(fileLine);
59
- }
60
- }
61
- if (files.length > 0) {
62
- commits.push(files);
63
- }
64
- }
65
- return commits;
66
- }
67
- /**
68
- * Normalize a git-output path (forward slashes) to be consistent
69
- * with how the dependency graph stores paths.
70
- */
71
- function normalizePath(filePath) {
72
- // Git always outputs forward slashes; normalize for consistency
73
- return filePath.replace(/\\/g, "/");
74
- }
75
- /**
76
- * Check if a file path looks like a source file (not binary, not config noise).
77
- * We keep this broad — the dependency graph comparison will handle the real filtering.
78
- */
79
- function isSourceFile(filePath) {
80
- // Skip obviously non-source files
81
- const skipPatterns = [
82
- /\.lock$/,
83
- /package-lock\.json$/,
84
- /yarn\.lock$/,
85
- /\.min\.(js|css)$/,
86
- /\.map$/,
87
- /\.d\.ts$/,
88
- /\.png$/,
89
- /\.jpg$/,
90
- /\.jpeg$/,
91
- /\.gif$/,
92
- /\.svg$/,
93
- /\.ico$/,
94
- /\.woff2?$/,
95
- /\.ttf$/,
96
- /\.eot$/,
97
- /\.pdf$/,
98
- /\.zip$/,
99
- /\.tar$/,
100
- /\.gz$/,
101
- ];
102
- const normalized = filePath.toLowerCase();
103
- return !skipPatterns.some((p) => p.test(normalized));
104
- }
105
- /**
106
- * Create a canonical pair key for two files (order-independent).
107
- */
108
- function pairKey(a, b) {
109
- return a < b ? `${a}\0${b}` : `${b}\0${a}`;
110
- }
111
- /**
112
- * Mine git history to find files that frequently co-change.
113
- *
114
- * Runs `git log --name-only` and analyzes pairwise file combinations
115
- * within each commit to identify hidden logical dependencies.
116
- */
117
- async function mineGitHistory(projectRoot, options) {
118
- // Return cached result if still valid
119
- if (cachedResult &&
120
- cachedProjectRoot === projectRoot &&
121
- Date.now() - cachedResult.analyzedAt < CACHE_TTL_MS) {
122
- return cachedResult;
123
- }
124
- const maxCommits = options?.maxCommits ?? DEFAULT_MAX_COMMITS;
125
- const minSupport = options?.minSupport ?? DEFAULT_MIN_SUPPORT;
126
- const minConfidence = options?.minConfidence ?? DEFAULT_MIN_CONFIDENCE;
127
- const maxFilesPerCommit = options?.maxFilesPerCommit ?? DEFAULT_MAX_FILES_PER_COMMIT;
128
- // Empty result for non-git projects
129
- const emptyResult = {
130
- couplings: [],
131
- fileCouplings: new Map(),
132
- totalCommitsAnalyzed: 0,
133
- analyzedAt: Date.now(),
134
- };
135
- if (!isGitRepo(projectRoot)) {
136
- cachedResult = emptyResult;
137
- cachedProjectRoot = projectRoot;
138
- return emptyResult;
139
- }
140
- // Run git log
141
- let raw;
142
- try {
143
- raw = (0, child_process_1.execSync)(`git log --name-only --format="COMMIT:%H" --max-count=${maxCommits}`, {
144
- cwd: projectRoot,
145
- encoding: "utf-8",
146
- maxBuffer: 10 * 1024 * 1024,
147
- stdio: ["pipe", "pipe", "pipe"],
148
- });
149
- }
150
- catch {
151
- cachedResult = emptyResult;
152
- cachedProjectRoot = projectRoot;
153
- return emptyResult;
154
- }
155
- const commits = parseGitLog(raw);
156
- // Track per-file change counts and per-pair co-change counts
157
- const fileChangeCount = new Map();
158
- const pairCoChangeCount = new Map();
159
- let totalCommitsAnalyzed = 0;
160
- for (const commitFiles of commits) {
161
- // Filter to source files and normalize paths
162
- const filtered = commitFiles
163
- .map(normalizePath)
164
- .filter(isSourceFile);
165
- // Skip mega-commits (merge commits, large refactors)
166
- if (filtered.length > maxFilesPerCommit || filtered.length < 2) {
167
- if (filtered.length === 1) {
168
- // Still count single-file commits for per-file totals
169
- const file = filtered[0];
170
- fileChangeCount.set(file, (fileChangeCount.get(file) || 0) + 1);
171
- }
172
- totalCommitsAnalyzed++;
173
- continue;
174
- }
175
- totalCommitsAnalyzed++;
176
- // Count per-file changes
177
- for (const file of filtered) {
178
- fileChangeCount.set(file, (fileChangeCount.get(file) || 0) + 1);
179
- }
180
- // Count pairwise co-changes
181
- for (let i = 0; i < filtered.length; i++) {
182
- for (let j = i + 1; j < filtered.length; j++) {
183
- const key = pairKey(filtered[i], filtered[j]);
184
- pairCoChangeCount.set(key, (pairCoChangeCount.get(key) || 0) + 1);
185
- }
186
- }
187
- }
188
- // Build coupling results, filtering by thresholds
189
- const couplings = [];
190
- for (const [key, coCount] of pairCoChangeCount) {
191
- if (coCount < minSupport)
192
- continue;
193
- const [file1, file2] = key.split("\0");
194
- const file1Changes = fileChangeCount.get(file1) || 0;
195
- const file2Changes = fileChangeCount.get(file2) || 0;
196
- const maxChanges = Math.max(file1Changes, file2Changes);
197
- const confidence = maxChanges > 0 ? coCount / maxChanges : 0;
198
- if (confidence < minConfidence)
199
- continue;
200
- couplings.push({
201
- file1,
202
- file2,
203
- coChangeCount: coCount,
204
- file1Changes,
205
- file2Changes,
206
- confidence,
207
- support: coCount,
208
- });
209
- }
210
- // Sort by confidence descending
211
- couplings.sort((a, b) => b.confidence - a.confidence);
212
- // Build the per-file lookup map
213
- const fileCouplings = new Map();
214
- for (const coupling of couplings) {
215
- // Add to file1's list
216
- if (!fileCouplings.has(coupling.file1)) {
217
- fileCouplings.set(coupling.file1, []);
218
- }
219
- fileCouplings.get(coupling.file1).push(coupling);
220
- // Add to file2's list
221
- if (!fileCouplings.has(coupling.file2)) {
222
- fileCouplings.set(coupling.file2, []);
223
- }
224
- fileCouplings.get(coupling.file2).push(coupling);
225
- }
226
- // Sort each file's couplings by confidence descending
227
- for (const [, list] of fileCouplings) {
228
- list.sort((a, b) => b.confidence - a.confidence);
229
- }
230
- const result = {
231
- couplings,
232
- fileCouplings,
233
- totalCommitsAnalyzed,
234
- analyzedAt: Date.now(),
235
- };
236
- cachedResult = result;
237
- cachedProjectRoot = projectRoot;
238
- return result;
239
- }
240
- /**
241
- * Get all significant couplings for a given file path.
242
- * Returns an empty array if no couplings are found.
243
- *
244
- * The filePath should be a relative path matching git log output format
245
- * (forward slashes, relative to project root).
246
- */
247
- function getCoupledFiles(filePath, result) {
248
- const normalized = normalizePath(filePath);
249
- return result.fileCouplings.get(normalized) || [];
250
- }
1
+ 'use strict';const _0x49eb89=_0x3098;(function(_0x5d274e,_0x421570){const _0x1562e9={_0x19be3d:0x194,_0x373a27:0x178},_0x411906=_0x3098,_0x35518c=_0x5d274e();while(!![]){try{const _0x2415bb=parseInt(_0x411906(0x195))/0x1+-parseInt(_0x411906(_0x1562e9._0x19be3d))/0x2+-parseInt(_0x411906(0x189))/0x3+-parseInt(_0x411906(_0x1562e9._0x373a27))/0x4*(-parseInt(_0x411906(0x180))/0x5)+parseInt(_0x411906(0x18a))/0x6+-parseInt(_0x411906(0x175))/0x7*(-parseInt(_0x411906(0x196))/0x8)+-parseInt(_0x411906(0x193))/0x9;if(_0x2415bb===_0x421570)break;else _0x35518c['push'](_0x35518c['shift']());}catch(_0x1d76f3){_0x35518c['push'](_0x35518c['shift']());}}}(_0x4274,0x89833));function _0x4274(){const _0x2d3ee3=['rwL4BuO','C3bSAxq','BM93','wevAzxG','C3rKAw8','zMLSzte','BwLUu3vWCg9YDa','AgfZ','mta1ntqYmZDoyKHVvw0','mZK0nJm2zM5qrvfi','mJu4ntu3EKTsse5Q','mtaWnJe2tu9HyNHY','zMLSDgvY','BgvUz3rO','CgLWzq','wwjYuNC','zw5JB2rPBMC','wevTD24','uuHAEMm','C29YDa','zMLSzti','mJq1swLmyNjU','BeLIEha','z2v0q291CgXLzezPBgvZ','nerrCLz0CG','CMvWBgfJzq','Bw51reu','z2v0','DxrMltG','ChvZAa','zxHLy1n5BMm','DhjPBq','ndi4nZC0mhHVzMPoqG','BwLUq29UzMLKzw5Jzq','ru5mqM0','vefTB2y','C29Tzq','y29UzMLKzw5Jzq','DMfSDwu','rufcD1u','v0L0uhy','mtKWotG1n0LbA2PuyG','nJa4mtq4nMnmrhjntG'];_0x4274=function(){return _0x2d3ee3;};return _0x4274();}const _0x4fc17e={};_0x4fc17e[_0x49eb89(0x186)]=!![],Object['defineProperty'](exports,'__esModule',_0x4fc17e),exports['invalidateCouplingCache']=invalidateCouplingCache,exports['mineGitHistory']=mineGitHistory,exports[_0x49eb89(0x177)]=getCoupledFiles;const child_process_1=require('child_process'),DEFAULT_MAX_COMMITS=0x1f4,DEFAULT_MIN_SUPPORT=0x3,DEFAULT_MIN_CONFIDENCE=0.3,DEFAULT_MAX_FILES_PER_COMMIT=0x14,CACHE_TTL_MS=0x5*0x3c*0x3e8;let cachedResult=null,cachedProjectRoot=null;function invalidateCouplingCache(){cachedResult=null,cachedProjectRoot=null;}function _0x3098(_0x42b2a1,_0x471aeb){_0x42b2a1=_0x42b2a1-0x16f;const _0x4274c9=_0x4274();let _0x30980e=_0x4274c9[_0x42b2a1];if(_0x3098['VudMIc']===undefined){var _0x1f884e=function(_0xb948e){const _0x382959='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3d3424='',_0x3783b9='';for(let _0x45b38e=0x0,_0x5f51df,_0x238e41,_0x19c246=0x0;_0x238e41=_0xb948e['charAt'](_0x19c246++);~_0x238e41&&(_0x5f51df=_0x45b38e%0x4?_0x5f51df*0x40+_0x238e41:_0x238e41,_0x45b38e++%0x4)?_0x3d3424+=String['fromCharCode'](0xff&_0x5f51df>>(-0x2*_0x45b38e&0x6)):0x0){_0x238e41=_0x382959['indexOf'](_0x238e41);}for(let _0x1ca4d6=0x0,_0x3dae57=_0x3d3424['length'];_0x1ca4d6<_0x3dae57;_0x1ca4d6++){_0x3783b9+='%'+('00'+_0x3d3424['charCodeAt'](_0x1ca4d6)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3783b9);};_0x3098['QYwItW']=_0x1f884e,_0x3098['fRpsOS']={},_0x3098['VudMIc']=!![];}const _0x236a60=_0x4274c9[0x0],_0x1e4a92=_0x42b2a1+_0x236a60,_0x532722=_0x3098['fRpsOS'][_0x1e4a92];return!_0x532722?(_0x30980e=_0x3098['QYwItW'](_0x30980e),_0x3098['fRpsOS'][_0x1e4a92]=_0x30980e):_0x30980e=_0x532722,_0x30980e;}function isGitRepo(_0x398f1f){const _0x116a5e={_0x28d3ae:0x16f,_0x263020:0x199,_0x7c29b4:0x170},_0x33e29d=_0x49eb89,_0x17294d={};_0x17294d[_0x33e29d(_0x116a5e._0x28d3ae)]=_0x33e29d(_0x116a5e._0x263020);const _0x58e9c2=_0x17294d;try{const _0x1ac877={};return _0x1ac877['cwd']=_0x398f1f,_0x1ac877[_0x33e29d(_0x116a5e._0x7c29b4)]=_0x33e29d(0x17c),_0x1ac877[_0x33e29d(0x18f)]=[_0x33e29d(0x199),_0x58e9c2['YbrRw'],_0x33e29d(0x199)],(0x0,child_process_1[_0x33e29d(0x17e)])('git\x20rev-parse\x20--is-inside-work-tree',_0x1ac877),!![];}catch{return![];}}function parseGitLog(_0x4dd684){const _0x223422={_0x3efbd9:0x18b,_0x586cc2:0x17d},_0x146d6f=_0x49eb89,_0x5dc557={};_0x5dc557['EixmJ']='COMMIT:',_0x5dc557['lUbAX']=function(_0x3c77cd,_0x5d8949){return _0x3c77cd>_0x5d8949;};const _0x2130cd=_0x5dc557,_0x168fe5=[],_0x4486b1=_0x4dd684[_0x146d6f(0x18c)](_0x2130cd[_0x146d6f(_0x223422._0x3efbd9)]);for(const _0x2e4667 of _0x4486b1){const _0x1b2f43=_0x2e4667['trim']();if(!_0x1b2f43)continue;const _0xab5803=_0x1b2f43['split']('\x0a'),_0x12a949=[];for(let _0xb7cc1e=0x1;_0xb7cc1e<_0xab5803['length'];_0xb7cc1e++){const _0x2e4a8f=_0xab5803[_0xb7cc1e][_0x146d6f(0x17f)]();_0x2e4a8f&&_0x12a949[_0x146d6f(_0x223422._0x586cc2)](_0x2e4a8f);}_0x2130cd['lUbAX'](_0x12a949['length'],0x0)&&_0x168fe5[_0x146d6f(0x17d)](_0x12a949);}return _0x168fe5;}function normalizePath(_0xc1cdc6){const _0x17dc3e={_0x1c817e:0x179},_0x1762b0=_0x49eb89;return _0xc1cdc6[_0x1762b0(_0x17dc3e._0x1c817e)](/\\/g,'/');}function isSourceFile(_0x14d42e){const _0x4ea0c7={_0x3ed3f8:0x184},_0x456a6a=_0x49eb89,_0x46fe51=[/\.lock$/,/package-lock\.json$/,/yarn\.lock$/,/\.min\.(js|css)$/,/\.map$/,/\.d\.ts$/,/\.png$/,/\.jpg$/,/\.jpeg$/,/\.gif$/,/\.svg$/,/\.ico$/,/\.woff2?$/,/\.ttf$/,/\.eot$/,/\.pdf$/,/\.zip$/,/\.tar$/,/\.gz$/],_0x7bdc0d=_0x14d42e['toLowerCase']();return!_0x46fe51[_0x456a6a(_0x4ea0c7._0x3ed3f8)](_0x26a1d3=>_0x26a1d3['test'](_0x7bdc0d));}function pairKey(_0x1a4b1f,_0x2fe143){const _0x1fb450=_0x49eb89,_0x43361d={};_0x43361d[_0x1fb450(0x183)]=function(_0x23cc74,_0x56f669){return _0x23cc74<_0x56f669;};const _0x4dd857=_0x43361d;return _0x4dd857['TAmof'](_0x1a4b1f,_0x2fe143)?_0x1a4b1f+'\x00'+_0x2fe143:_0x2fe143+'\x00'+_0x1a4b1f;}async function mineGitHistory(_0x161e0d,_0x46f8de){const _0x5c1a04={_0x1db9ba:0x17c,_0x2eed80:0x17a,_0x44afa1:0x191,_0x1f7467:0x181,_0x46519b:0x18d,_0x220655:0x187,_0x501aee:0x17e,_0x497add:0x198,_0x5d72cf:0x182,_0x5c9479:0x18e,_0x48413b:0x17b,_0x4d77a2:0x172,_0x3257f5:0x190,_0x2c8935:0x192,_0xd296bd:0x174},_0x3e922d=_0x49eb89,_0x5397e3={'lIbxp':function(_0x5c65c2,_0x5cfce7){return _0x5c65c2===_0x5cfce7;},'mnuDE':function(_0x48833b,_0x585e6a){return _0x48833b<_0x585e6a;},'EABwU':function(_0x1ba2c1,_0x488297){return _0x1ba2c1(_0x488297);},'RsYEL':_0x3e922d(_0x5c1a04._0x1db9ba),'yuHyf':function(_0x11e3ea,_0xf6814d){return _0x11e3ea*_0xf6814d;},'WItPv':'pipe','ENLBm':function(_0x4e68e9,_0x5696f1){return _0x4e68e9+_0x5696f1;},'XEZex':function(_0x362a95,_0x2f11f2){return _0x362a95<_0x2f11f2;},'JftDY':function(_0x3d0d26,_0x84c42c,_0x3a0bb1){return _0x3d0d26(_0x84c42c,_0x3a0bb1);},'QHZzc':function(_0x2f8b6d,_0x4a3c14){return _0x2f8b6d>_0x4a3c14;},'gNLTF':function(_0x28df40,_0x5dd78f){return _0x28df40<_0x5dd78f;}};if(cachedResult&&_0x5397e3[_0x3e922d(0x176)](cachedProjectRoot,_0x161e0d)&&_0x5397e3[_0x3e922d(_0x5c1a04._0x2eed80)](Date['now']()-cachedResult['analyzedAt'],CACHE_TTL_MS))return cachedResult;const _0x586fdf=_0x46f8de?.['maxCommits']??DEFAULT_MAX_COMMITS,_0x40eb09=_0x46f8de?.[_0x3e922d(_0x5c1a04._0x44afa1)]??DEFAULT_MIN_SUPPORT,_0x1262ed=_0x46f8de?.[_0x3e922d(_0x5c1a04._0x1f7467)]??DEFAULT_MIN_CONFIDENCE,_0x42b9ca=_0x46f8de?.['maxFilesPerCommit']??DEFAULT_MAX_FILES_PER_COMMIT,_0x150644={'couplings':[],'fileCouplings':new Map(),'totalCommitsAnalyzed':0x0,'analyzedAt':Date[_0x3e922d(_0x5c1a04._0x46519b)]()};if(!_0x5397e3[_0x3e922d(_0x5c1a04._0x220655)](isGitRepo,_0x161e0d))return cachedResult=_0x150644,cachedProjectRoot=_0x161e0d,_0x150644;let _0x404464;try{_0x404464=(0x0,child_process_1[_0x3e922d(_0x5c1a04._0x501aee)])('git\x20log\x20--name-only\x20--format=\x22COMMIT:%H\x22\x20--max-count='+_0x586fdf,{'cwd':_0x161e0d,'encoding':_0x5397e3['RsYEL'],'maxBuffer':_0x5397e3['yuHyf'](0xa*0x400,0x400),'stdio':[_0x5397e3[_0x3e922d(0x188)],_0x5397e3['WItPv'],_0x3e922d(0x199)]});}catch{return cachedResult=_0x150644,cachedProjectRoot=_0x161e0d,_0x150644;}const _0x167bd4=parseGitLog(_0x404464),_0x5ca1ca=new Map(),_0x21a9d5=new Map();let _0x4b88aa=0x0;for(const _0xa0d058 of _0x167bd4){const _0x9307fd=_0xa0d058['map'](normalizePath)[_0x3e922d(0x197)](isSourceFile);if(_0x9307fd[_0x3e922d(_0x5c1a04._0x497add)]>_0x42b9ca||_0x9307fd['length']<0x2){if(_0x9307fd['length']===0x1){const _0x460bd9=_0x9307fd[0x0];_0x5ca1ca['set'](_0x460bd9,_0x5397e3['ENLBm'](_0x5ca1ca['get'](_0x460bd9)||0x0,0x1));}_0x4b88aa++;continue;}_0x4b88aa++;for(const _0x283507 of _0x9307fd){_0x5ca1ca['set'](_0x283507,_0x5397e3[_0x3e922d(_0x5c1a04._0x5d72cf)](_0x5ca1ca[_0x3e922d(0x17b)](_0x283507)||0x0,0x1));}for(let _0x907df1=0x0;_0x5397e3[_0x3e922d(_0x5c1a04._0x5c9479)](_0x907df1,_0x9307fd[_0x3e922d(0x198)]);_0x907df1++){for(let _0x106cda=_0x907df1+0x1;_0x106cda<_0x9307fd['length'];_0x106cda++){const _0x331c1a=_0x5397e3['JftDY'](pairKey,_0x9307fd[_0x907df1],_0x9307fd[_0x106cda]);_0x21a9d5['set'](_0x331c1a,(_0x21a9d5['get'](_0x331c1a)||0x0)+0x1);}}}const _0x322746=[];for(const [_0x10b5a2,_0x45d5bf]of _0x21a9d5){if(_0x5397e3['XEZex'](_0x45d5bf,_0x40eb09))continue;const [_0xa645d,_0x2f67a3]=_0x10b5a2[_0x3e922d(0x18c)]('\x00'),_0xbde73b=_0x5ca1ca['get'](_0xa645d)||0x0,_0xe5f094=_0x5ca1ca[_0x3e922d(_0x5c1a04._0x48413b)](_0x2f67a3)||0x0,_0x1f1b81=Math['max'](_0xbde73b,_0xe5f094),_0x2275a2=_0x5397e3[_0x3e922d(_0x5c1a04._0x4d77a2)](_0x1f1b81,0x0)?_0x45d5bf/_0x1f1b81:0x0;if(_0x5397e3['gNLTF'](_0x2275a2,_0x1262ed))continue;const _0x37d954={};_0x37d954[_0x3e922d(0x190)]=_0xa645d,_0x37d954['file2']=_0x2f67a3,_0x37d954['coChangeCount']=_0x45d5bf,_0x37d954['file1Changes']=_0xbde73b,_0x37d954['file2Changes']=_0xe5f094,_0x37d954['confidence']=_0x2275a2,_0x37d954['support']=_0x45d5bf,_0x322746[_0x3e922d(0x17d)](_0x37d954);}_0x322746['sort']((_0x4fdbec,_0xfe34d0)=>_0xfe34d0[_0x3e922d(0x185)]-_0x4fdbec['confidence']);const _0x20998f=new Map();for(const _0x31468c of _0x322746){!_0x20998f['has'](_0x31468c[_0x3e922d(_0x5c1a04._0x3257f5)])&&_0x20998f['set'](_0x31468c['file1'],[]),_0x20998f['get'](_0x31468c[_0x3e922d(_0x5c1a04._0x3257f5)])['push'](_0x31468c),!_0x20998f[_0x3e922d(_0x5c1a04._0x2c8935)](_0x31468c[_0x3e922d(_0x5c1a04._0xd296bd)])&&_0x20998f['set'](_0x31468c['file2'],[]),_0x20998f['get'](_0x31468c[_0x3e922d(0x174)])[_0x3e922d(0x17d)](_0x31468c);}for(const [,_0x149dd6]of _0x20998f){_0x149dd6[_0x3e922d(0x173)]((_0x3e898e,_0x242229)=>_0x242229[_0x3e922d(0x185)]-_0x3e898e['confidence']);}const _0x317ab6={'couplings':_0x322746,'fileCouplings':_0x20998f,'totalCommitsAnalyzed':_0x4b88aa,'analyzedAt':Date[_0x3e922d(0x18d)]()};return cachedResult=_0x317ab6,cachedProjectRoot=_0x161e0d,_0x317ab6;}function getCoupledFiles(_0x121a23,_0x1e2a0b){const _0x2ddc06=_0x49eb89,_0x86ea3a={'XEmwn':function(_0x151ba0,_0x2a98bd){return _0x151ba0(_0x2a98bd);}},_0x3253a5=_0x86ea3a[_0x2ddc06(0x171)](normalizePath,_0x121a23);return _0x1e2a0b['fileCouplings']['get'](_0x3253a5)||[];}
@@ -1,319 +1 @@
1
- "use strict";
2
- /**
3
- * Incremental Graph Updates for SYKE.
4
- *
5
- * Instead of rebuilding the entire dependency graph when a single file changes,
6
- * this module re-parses only the changed file's imports and updates the
7
- * forward/reverse maps in place. SCC and PageRank are recomputed fully
8
- * (both are O(V+E) and fast enough) only when edges actually change.
9
- *
10
- * This brings update latency from O(N * parse) down to O(1 * parse + V+E)
11
- * for large codebases (10K+ files).
12
- */
13
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- var desc = Object.getOwnPropertyDescriptor(m, k);
16
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
- desc = { enumerable: true, get: function() { return m[k]; } };
18
- }
19
- Object.defineProperty(o, k2, desc);
20
- }) : (function(o, m, k, k2) {
21
- if (k2 === undefined) k2 = k;
22
- o[k2] = m[k];
23
- }));
24
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
- Object.defineProperty(o, "default", { enumerable: true, value: v });
26
- }) : function(o, v) {
27
- o["default"] = v;
28
- });
29
- var __importStar = (this && this.__importStar) || (function () {
30
- var ownKeys = function(o) {
31
- ownKeys = Object.getOwnPropertyNames || function (o) {
32
- var ar = [];
33
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
- return ar;
35
- };
36
- return ownKeys(o);
37
- };
38
- return function (mod) {
39
- if (mod && mod.__esModule) return mod;
40
- var result = {};
41
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
- __setModuleDefault(result, mod);
43
- return result;
44
- };
45
- })();
46
- Object.defineProperty(exports, "__esModule", { value: true });
47
- exports.updateGraphForFile = updateGraphForFile;
48
- exports.addFileToGraph = addFileToGraph;
49
- exports.removeFileFromGraph = removeFileFromGraph;
50
- const path = __importStar(require("path"));
51
- const plugin_1 = require("../languages/plugin");
52
- const scc_1 = require("./scc");
53
- const pagerank_1 = require("../scoring/pagerank");
54
- const risk_scorer_1 = require("../scoring/risk-scorer");
55
- // ── Core Functions ──
56
- /**
57
- * Update the graph for a single changed file.
58
- * Re-parses only that file's imports and updates forward/reverse maps.
59
- * Returns info about what changed for cache invalidation.
60
- */
61
- function updateGraphForFile(graph, filePath, projectRoot) {
62
- const normalized = path.normalize(filePath);
63
- // If file is not in the graph, treat as a new file addition
64
- if (!graph.files.has(normalized)) {
65
- return addFileToGraph(graph, filePath, projectRoot);
66
- }
67
- // 1. Get old forward edges for this file
68
- const oldDeps = graph.forward.get(normalized) || [];
69
- const oldDepsSet = new Set(oldDeps);
70
- // 2. Determine which language plugin handles this file
71
- const plugin = (0, plugin_1.getPluginForFile)(normalized);
72
- if (!plugin) {
73
- // No plugin can handle this file extension - nothing to update
74
- return {
75
- updatedFile: normalized,
76
- addedEdges: [],
77
- removedEdges: [],
78
- edgesChanged: false,
79
- affectedFiles: [],
80
- };
81
- }
82
- // 3. Find the appropriate source directory for this file
83
- const sourceDir = findSourceDirForFile(normalized, graph);
84
- // 4. Re-parse imports for this file
85
- const rawImports = plugin.parseImports(normalized, projectRoot, sourceDir);
86
- // 5. Filter to only include files that exist in the graph (internal deps)
87
- const newDeps = rawImports.filter(imp => graph.files.has(imp));
88
- const newDepsSet = new Set(newDeps);
89
- // 6. Compute diff
90
- const addedEdges = [];
91
- const removedEdges = [];
92
- for (const dep of newDeps) {
93
- if (!oldDepsSet.has(dep)) {
94
- addedEdges.push([normalized, dep]);
95
- }
96
- }
97
- for (const dep of oldDeps) {
98
- if (!newDepsSet.has(dep)) {
99
- removedEdges.push([normalized, dep]);
100
- }
101
- }
102
- const edgesChanged = addedEdges.length > 0 || removedEdges.length > 0;
103
- // 7. Update forward map
104
- graph.forward.set(normalized, newDeps);
105
- // 8. Update reverse map for removed edges
106
- for (const [, dep] of removedEdges) {
107
- const revList = graph.reverse.get(dep);
108
- if (revList) {
109
- const idx = revList.indexOf(normalized);
110
- if (idx !== -1) {
111
- revList.splice(idx, 1);
112
- }
113
- }
114
- }
115
- // 9. Update reverse map for added edges
116
- for (const [, dep] of addedEdges) {
117
- const revList = graph.reverse.get(dep);
118
- if (revList) {
119
- if (!revList.includes(normalized)) {
120
- revList.push(normalized);
121
- }
122
- }
123
- else {
124
- graph.reverse.set(dep, [normalized]);
125
- }
126
- }
127
- // 10. Compute affected files (reverse transitive closure of the changed file)
128
- const affectedFiles = computeAffectedFiles(normalized, graph);
129
- // 11. If edges changed, recompute SCC and PageRank
130
- if (edgesChanged) {
131
- recomputeGraphMetrics(graph);
132
- }
133
- return {
134
- updatedFile: normalized,
135
- addedEdges,
136
- removedEdges,
137
- edgesChanged,
138
- affectedFiles,
139
- };
140
- }
141
- /**
142
- * Add a new file to the graph.
143
- * Initializes forward/reverse entries, parses imports, and adds edges.
144
- */
145
- function addFileToGraph(graph, filePath, projectRoot) {
146
- const normalized = path.normalize(filePath);
147
- // Already in graph? Treat as an update instead
148
- if (graph.files.has(normalized)) {
149
- return updateGraphForFile(graph, filePath, projectRoot);
150
- }
151
- // 1. Add to the files set
152
- graph.files.add(normalized);
153
- // 2. Initialize forward entry
154
- graph.forward.set(normalized, []);
155
- // 3. Initialize reverse entry if not exists
156
- if (!graph.reverse.has(normalized)) {
157
- graph.reverse.set(normalized, []);
158
- }
159
- // 4. Determine which plugin handles this file
160
- const plugin = (0, plugin_1.getPluginForFile)(normalized);
161
- if (!plugin) {
162
- return {
163
- updatedFile: normalized,
164
- addedEdges: [],
165
- removedEdges: [],
166
- edgesChanged: false,
167
- affectedFiles: [],
168
- };
169
- }
170
- // 5. Find source directory
171
- const sourceDir = findSourceDirForFile(normalized, graph);
172
- // 6. Parse imports
173
- const rawImports = plugin.parseImports(normalized, projectRoot, sourceDir);
174
- const newDeps = rawImports.filter(imp => graph.files.has(imp));
175
- const addedEdges = [];
176
- // 7. Set forward edges
177
- graph.forward.set(normalized, newDeps);
178
- // 8. Update reverse maps for new edges
179
- for (const dep of newDeps) {
180
- addedEdges.push([normalized, dep]);
181
- const revList = graph.reverse.get(dep);
182
- if (revList) {
183
- if (!revList.includes(normalized)) {
184
- revList.push(normalized);
185
- }
186
- }
187
- else {
188
- graph.reverse.set(dep, [normalized]);
189
- }
190
- }
191
- // 9. Check if any existing file imports this new file
192
- // (their forward edges might now resolve to this file)
193
- // This is hard to detect without re-parsing all files,
194
- // so we skip it — the next full refresh will catch it.
195
- // The conservative approach is to just note that edges changed.
196
- const edgesChanged = addedEdges.length > 0;
197
- const affectedFiles = computeAffectedFiles(normalized, graph);
198
- if (edgesChanged) {
199
- recomputeGraphMetrics(graph);
200
- }
201
- return {
202
- updatedFile: normalized,
203
- addedEdges,
204
- removedEdges: [],
205
- edgesChanged,
206
- affectedFiles,
207
- };
208
- }
209
- /**
210
- * Remove a file from the graph.
211
- * Cleans up all forward edges, reverse edges, and the files set.
212
- */
213
- function removeFileFromGraph(graph, filePath) {
214
- const normalized = path.normalize(filePath);
215
- if (!graph.files.has(normalized)) {
216
- // File wasn't in graph, nothing to do
217
- return {
218
- updatedFile: normalized,
219
- addedEdges: [],
220
- removedEdges: [],
221
- edgesChanged: false,
222
- affectedFiles: [],
223
- };
224
- }
225
- // Compute affected files BEFORE removing (need the reverse graph intact)
226
- const affectedFiles = computeAffectedFiles(normalized, graph);
227
- const removedEdges = [];
228
- // 1. Remove all forward edges (this file imports X)
229
- const forwardDeps = graph.forward.get(normalized) || [];
230
- for (const dep of forwardDeps) {
231
- removedEdges.push([normalized, dep]);
232
- // Remove this file from dep's reverse list
233
- const revList = graph.reverse.get(dep);
234
- if (revList) {
235
- const idx = revList.indexOf(normalized);
236
- if (idx !== -1) {
237
- revList.splice(idx, 1);
238
- }
239
- }
240
- }
241
- // 2. Remove all reverse edges (X imports this file)
242
- const reverseDeps = graph.reverse.get(normalized) || [];
243
- for (const src of reverseDeps) {
244
- removedEdges.push([src, normalized]);
245
- // Remove this file from src's forward list
246
- const fwdList = graph.forward.get(src);
247
- if (fwdList) {
248
- const idx = fwdList.indexOf(normalized);
249
- if (idx !== -1) {
250
- fwdList.splice(idx, 1);
251
- }
252
- }
253
- }
254
- // 3. Clean up maps
255
- graph.forward.delete(normalized);
256
- graph.reverse.delete(normalized);
257
- graph.files.delete(normalized);
258
- const edgesChanged = removedEdges.length > 0;
259
- if (edgesChanged) {
260
- recomputeGraphMetrics(graph);
261
- }
262
- return {
263
- updatedFile: normalized,
264
- addedEdges: [],
265
- removedEdges,
266
- edgesChanged,
267
- affectedFiles,
268
- };
269
- }
270
- // ── Internal Helpers ──
271
- /**
272
- * Find the source directory that contains the given file.
273
- * Falls back to graph.sourceDir if no match found.
274
- */
275
- function findSourceDirForFile(filePath, graph) {
276
- for (const dir of graph.sourceDirs) {
277
- if (filePath.startsWith(dir)) {
278
- return dir;
279
- }
280
- }
281
- return graph.sourceDir;
282
- }
283
- /**
284
- * Compute the set of files whose cached BFS/impact results might be stale.
285
- * This is the reverse transitive closure: all files that transitively depend
286
- * on the changed file (including the changed file itself).
287
- */
288
- function computeAffectedFiles(filePath, graph) {
289
- const affected = new Set();
290
- affected.add(filePath);
291
- const queue = [filePath];
292
- while (queue.length > 0) {
293
- const current = queue.shift();
294
- const dependents = graph.reverse.get(current) || [];
295
- for (const dep of dependents) {
296
- if (!affected.has(dep)) {
297
- affected.add(dep);
298
- queue.push(dep);
299
- }
300
- }
301
- }
302
- return [...affected];
303
- }
304
- /**
305
- * Recompute SCC and PageRank after edge changes.
306
- * Both are O(V+E) and fast (<100ms for 10K files).
307
- */
308
- function recomputeGraphMetrics(graph) {
309
- // Recompute SCC
310
- graph.scc = (0, scc_1.computeSCC)(graph);
311
- // Recompute PageRank
312
- (0, pagerank_1.invalidatePageRank)();
313
- graph.pageRank = (0, pagerank_1.computePageRank)(graph);
314
- // Invalidate project metrics (will be recomputed lazily)
315
- (0, risk_scorer_1.invalidateProjectMetrics)();
316
- const cyclicCount = graph.scc.condensed.nodes.filter(n => n.isCyclic).length;
317
- console.error(`[syke:incremental] Graph metrics recomputed: ${graph.files.size} files, ` +
318
- `${graph.scc.components.length} SCCs (${cyclicCount} cyclic)`);
319
- }
1
+ 'use strict';const _0x45314f=_0x4cea;(function(_0xa12997,_0x4ed295){const _0x16cdf7={_0x3f7e1f:0x185,_0x295879:0x155,_0x4f9c14:0x154,_0x2724d5:0x14f,_0x14ce86:0x161},_0x52e6b8=_0x4cea,_0x126fbb=_0xa12997();while(!![]){try{const _0x2a968a=-parseInt(_0x52e6b8(_0x16cdf7._0x3f7e1f))/0x1*(parseInt(_0x52e6b8(_0x16cdf7._0x295879))/0x2)+parseInt(_0x52e6b8(0x183))/0x3+-parseInt(_0x52e6b8(0x17c))/0x4*(-parseInt(_0x52e6b8(_0x16cdf7._0x4f9c14))/0x5)+-parseInt(_0x52e6b8(0x16b))/0x6*(-parseInt(_0x52e6b8(_0x16cdf7._0x2724d5))/0x7)+-parseInt(_0x52e6b8(0x14e))/0x8*(parseInt(_0x52e6b8(0x14b))/0x9)+-parseInt(_0x52e6b8(0x15b))/0xa+parseInt(_0x52e6b8(_0x16cdf7._0x14ce86))/0xb*(parseInt(_0x52e6b8(0x149))/0xc);if(_0x2a968a===_0x4ed295)break;else _0x126fbb['push'](_0x126fbb['shift']());}catch(_0x3152a1){_0x126fbb['push'](_0x126fbb['shift']());}}}(_0x3cb3,0x3bf27));var __createBinding=this&&this[_0x45314f(0x169)]||(Object[_0x45314f(0x152)]?function(_0x4a028c,_0x55cb71,_0x307f81,_0x1ebffb){const _0x1dea65={_0x15bf7f:0x14c,_0x24f5fa:0x177,_0x258dba:0x150},_0x155f08=_0x45314f,_0x3379bd={};_0x3379bd['XBpmL']=function(_0x1aa1dd,_0x38f099){return _0x1aa1dd===_0x38f099;},_0x3379bd[_0x155f08(0x177)]=function(_0x2926da,_0x54159b){return _0x2926da in _0x54159b;};const _0x46f6f3=_0x3379bd;if(_0x46f6f3[_0x155f08(_0x1dea65._0x15bf7f)](_0x1ebffb,undefined))_0x1ebffb=_0x307f81;var _0x3cbcf6=Object[_0x155f08(0x176)](_0x55cb71,_0x307f81);if(!_0x3cbcf6||(_0x46f6f3[_0x155f08(_0x1dea65._0x24f5fa)]('get',_0x3cbcf6)?!_0x55cb71['__esModule']:_0x3cbcf6[_0x155f08(_0x1dea65._0x258dba)]||_0x3cbcf6['configurable'])){const _0x1d0920={};_0x1d0920['enumerable']=!![],_0x1d0920['get']=function(){return _0x55cb71[_0x307f81];},_0x3cbcf6=_0x1d0920;}Object[_0x155f08(0x164)](_0x4a028c,_0x1ebffb,_0x3cbcf6);}:function(_0x4e6025,_0x2740ec,_0x57a083,_0x2b0f53){const _0x3ed5e4={};_0x3ed5e4['tLVuY']=function(_0x4ede21,_0x759fdf){return _0x4ede21===_0x759fdf;};const _0x2ea3f9=_0x3ed5e4;if(_0x2ea3f9['tLVuY'](_0x2b0f53,undefined))_0x2b0f53=_0x57a083;_0x4e6025[_0x2b0f53]=_0x2740ec[_0x57a083];}),__setModuleDefault=this&&this[_0x45314f(0x15d)]||(Object[_0x45314f(0x152)]?function(_0x45f190,_0x214fce){const _0x257598=_0x45314f,_0x3cf8d2={};_0x3cf8d2[_0x257598(0x162)]='default';const _0x1e6d38=_0x3cf8d2,_0x368750={};_0x368750['enumerable']=!![],_0x368750['value']=_0x214fce,Object['defineProperty'](_0x45f190,_0x1e6d38['cNbrz'],_0x368750);}:function(_0xc1128f,_0x3f8232){const _0x345421=_0x45314f,_0x4736ef={};_0x4736ef['iqEJr']=_0x345421(0x167);const _0x19517c=_0x4736ef;_0xc1128f[_0x19517c['iqEJr']]=_0x3f8232;}),__importStar=this&&this['__importStar']||(function(){const _0x208f17={_0x7c0165:0x143,_0x30ba13:0x16f,_0x40e2d6:0x145},_0x568d25={_0x217a5a:0x173},_0xcc9c78={'YaTDm':function(_0x20fea1,_0x18f32c){return _0x20fea1(_0x18f32c);},'KQSaQ':function(_0x3e5908,_0x395ce0){return _0x3e5908<_0x395ce0;},'YQKqu':function(_0x2757da,_0x400aed,_0x45a390){return _0x2757da(_0x400aed,_0x45a390);}};var _0x1ef8fa=function(_0x3af9f3){const _0x49fc91=_0x4cea;return _0x1ef8fa=Object['getOwnPropertyNames']||function(_0x5bb89f){const _0x19a8c7=_0x4cea;var _0x1a9c56=[];for(var _0x5e5e88 in _0x5bb89f)if(Object[_0x19a8c7(0x174)]['hasOwnProperty']['call'](_0x5bb89f,_0x5e5e88))_0x1a9c56[_0x1a9c56[_0x19a8c7(0x166)]]=_0x5e5e88;return _0x1a9c56;},_0xcc9c78[_0x49fc91(_0x568d25._0x217a5a)](_0x1ef8fa,_0x3af9f3);};return function(_0x327c9f){const _0x2d7835=_0x4cea,_0x43a4d4='3|4|0|2|1'[_0x2d7835(_0x208f17._0x7c0165)]('|');let _0x4bee4b=0x0;while(!![]){switch(_0x43a4d4[_0x4bee4b++]){case'0':if(_0x327c9f!=null){for(var _0x47906b=_0xcc9c78['YaTDm'](_0x1ef8fa,_0x327c9f),_0x3985de=0x0;_0xcc9c78['KQSaQ'](_0x3985de,_0x47906b['length']);_0x3985de++)if(_0x47906b[_0x3985de]!==_0x2d7835(0x167))__createBinding(_0x1dc2db,_0x327c9f,_0x47906b[_0x3985de]);}continue;case'1':return _0x1dc2db;case'2':_0xcc9c78[_0x2d7835(_0x208f17._0x30ba13)](__setModuleDefault,_0x1dc2db,_0x327c9f);continue;case'3':if(_0x327c9f&&_0x327c9f[_0x2d7835(_0x208f17._0x40e2d6)])return _0x327c9f;continue;case'4':var _0x1dc2db={};continue;}break;}};}());const _0x51b6f7={};function _0x3cb3(){const _0x462e47=['nZG1nJrTvgTlAMu','y29TCg9Uzw50CW','y29UzgvUC2vK','zMLSzxm','ywrK','BwLHwLq','CMv2zxjZzq','mZqYndK1r2fnDKrf','CMvTB3zLrMLSzuzYB21hCMfWAa','otiZvwnjrg5o','C2HPzNq','CgfYC2vjBxbVCNrZ','ww13Afu','z2v0ugX1z2LUrM9YrMLSzq','C3bSAxq','C2nJ','x19LC01VzhvSzq','BM9YBwfSAxPL','CgfNzvjHBMS','Aw52ywXPzgf0zvbHz2vsyw5R','mtC1nJy2ogXgww94vG','C3bSAwnL','mZi0nZj5D0fXCNa','wejWBuW','y29TChv0zvbHz2vsyw5R','mtm2q0HsteLc','mtyYmteZsLHoD1DI','D3jPDgfIBgu','ywrKrMLSzvrVr3jHCgG','y3jLyxrL','C291CMnLrgLY','ntvfrgTOuNC','nZu4AKvtAu15','ywrKzwrfzgDLCW','DxbKyxrLzezPBgu','igzPBgvZlca','q2nlEvO','z2v0','mZa1mZK0mhvUz0LMwq','DxbKyxrLr3jHCgHgB3jgAwXL','x19ZzxrnB2r1BgvezwzHDwX0','ChvZAa','CMvTB3zLzevKz2vZ','lI4VBgfUz3vHz2vZl3bSDwDPBG','ndrWCKXqvhy','y05ICNO','lI4VC2nVCMLUzY9YAxnRlxnJB3jLCG','zgvMAw5LuhjVCgvYDhK','yw93zKy','BgvUz3rO','zgvMyxvSDa','C2v0','x19JCMvHDgvcAw5KAw5N','Aw5KzxHpzG','mtjZsND4AMe','zM9YD2fYza','zgvSzxrL','zwrNzxndAgfUz2vK','wvflCxu','C291CMnLrgLYCW','AgfZ','ywzMzwn0zwrgAwXLCW','wwfurg0','ChjVDg90ExbL','y29TChv0zvndqW','z2v0t3DUuhjVCgvYDhLezxnJCMLWDg9Y','A2LQAu4','rMTbAhO','CgHcBg8','lI9Zy2m','Cgf0Aa'];_0x3cb3=function(){return _0x462e47;};return _0x3cb3();}_0x51b6f7['value']=!![],Object['defineProperty'](exports,_0x45314f(0x145),_0x51b6f7),exports[_0x45314f(0x15c)]=updateGraphForFile,exports[_0x45314f(0x151)]=addFileToGraph,exports[_0x45314f(0x184)]=removeFileFromGraph;const path=__importStar(require(_0x45314f(0x17b))),plugin_1=require(_0x45314f(0x160)),scc_1=require(_0x45314f(0x17a)),pagerank_1=require('../scoring/pagerank'),risk_scorer_1=require(_0x45314f(0x163));function updateGraphForFile(_0x1f448e,_0x28610a,_0x1c87bd){const _0x866eed={_0x3e7159:0x146,_0x1f3984:0x157,_0x43f8be:0x15f,_0xba6305:0x15e,_0x55ea88:0x166,_0x501663:0x182,_0x5f4fde:0x16a,_0x462e43:0x14a,_0x521acc:0x168,_0x379a6b:0x157,_0x5a5931:0x156,_0x1af142:0x15f},_0x587480=_0x45314f,_0x4987eb={'YmwhU':function(_0x54e19a,_0x1e41db,_0x12d26c,_0x62f1d){return _0x54e19a(_0x1e41db,_0x12d26c,_0x62f1d);},'EgnXL':function(_0x29930d,_0x34978a,_0x2e324f){return _0x29930d(_0x34978a,_0x2e324f);},'PfZLM':function(_0x2f3130,_0x5292d0){return _0x2f3130>_0x5292d0;},'IZBIM':function(_0x67e19c,_0x1048b3){return _0x67e19c(_0x1048b3);}},_0x14e1d0=path[_0x587480(_0x866eed._0x3e7159)](_0x28610a);if(!_0x1f448e[_0x587480(0x17f)]['has'](_0x14e1d0))return _0x4987eb[_0x587480(0x141)](addFileToGraph,_0x1f448e,_0x28610a,_0x1c87bd);const _0x530f1b=_0x1f448e['forward']['get'](_0x14e1d0)||[],_0x4a92c8=new Set(_0x530f1b),_0x1cc0b8=(0x0,plugin_1['getPluginForFile'])(_0x14e1d0);if(!_0x1cc0b8){const _0x283f7c={};return _0x283f7c[_0x587480(_0x866eed._0x1f3984)]=_0x14e1d0,_0x283f7c['addedEdges']=[],_0x283f7c[_0x587480(_0x866eed._0x43f8be)]=[],_0x283f7c['edgesChanged']=![],_0x283f7c['affectedFiles']=[],_0x283f7c;}const _0x56b5aa=_0x4987eb['EgnXL'](findSourceDirForFile,_0x14e1d0,_0x1f448e),_0xa99afd=_0x1cc0b8[_0x587480(0x187)](_0x14e1d0,_0x1c87bd,_0x56b5aa),_0x5a340d=_0xa99afd['filter'](_0x43ef2f=>_0x1f448e[_0x587480(0x17f)][_0x587480(0x171)](_0x43ef2f)),_0x5eae11=new Set(_0x5a340d),_0x1a0c27=[],_0x4ac43e=[];for(const _0x13675b of _0x5a340d){!_0x4a92c8['has'](_0x13675b)&&_0x1a0c27[_0x587480(_0x866eed._0xba6305)]([_0x14e1d0,_0x13675b]);}for(const _0x5a0972 of _0x530f1b){!_0x5eae11['has'](_0x5a0972)&&_0x4ac43e['push']([_0x14e1d0,_0x5a0972]);}const _0xb5e886=_0x4987eb['PfZLM'](_0x1a0c27[_0x587480(_0x866eed._0x55ea88)],0x0)||_0x4ac43e[_0x587480(_0x866eed._0x55ea88)]>0x0;_0x1f448e['forward']['set'](_0x14e1d0,_0x5a340d);for(const [,_0x83d9e9]of _0x4ac43e){const _0x23e469=_0x1f448e[_0x587480(_0x866eed._0x501663)]['get'](_0x83d9e9);if(_0x23e469){const _0x3baeb3=_0x23e469[_0x587480(_0x866eed._0x5f4fde)](_0x14e1d0);_0x3baeb3!==-0x1&&_0x23e469[_0x587480(_0x866eed._0x462e43)](_0x3baeb3,0x1);}}for(const [,_0x18d24f]of _0x1a0c27){const _0x27d33f=_0x1f448e['reverse']['get'](_0x18d24f);_0x27d33f?!_0x27d33f['includes'](_0x14e1d0)&&_0x27d33f['push'](_0x14e1d0):_0x1f448e[_0x587480(0x182)][_0x587480(_0x866eed._0x521acc)](_0x18d24f,[_0x14e1d0]);}const _0x17671f=computeAffectedFiles(_0x14e1d0,_0x1f448e);_0xb5e886&&_0x4987eb['IZBIM'](recomputeGraphMetrics,_0x1f448e);const _0x5507d7={};return _0x5507d7[_0x587480(_0x866eed._0x379a6b)]=_0x14e1d0,_0x5507d7[_0x587480(_0x866eed._0x5a5931)]=_0x1a0c27,_0x5507d7[_0x587480(_0x866eed._0x1af142)]=_0x4ac43e,_0x5507d7['edgesChanged']=_0xb5e886,_0x5507d7[_0x587480(0x172)]=_0x17671f,_0x5507d7;}function addFileToGraph(_0x5e88db,_0x497d36,_0x209fe3){const _0x5f4136={_0x27d483:0x180,_0x455269:0x168,_0x196a80:0x142,_0x25b9a2:0x157,_0x3e71d9:0x172,_0x3b4a09:0x165,_0x15ceae:0x15e,_0x4e57af:0x182,_0x3dcd23:0x168,_0x4f2158:0x156,_0x241fe8:0x172},_0x2000b3=_0x45314f,_0x17f78a={'CcKyZ':function(_0x41b9cb,_0x4c1386,_0x47941f,_0x239377){return _0x41b9cb(_0x4c1386,_0x47941f,_0x239377);},'aowfF':function(_0x1cfe59,_0x222453,_0x4e86b6){return _0x1cfe59(_0x222453,_0x4e86b6);},'FkAhz':function(_0x12a958,_0x2d0135){return _0x12a958>_0x2d0135;},'phBlo':function(_0x1970db,_0x5514f6){return _0x1970db(_0x5514f6);}},_0x5aa574=path['normalize'](_0x497d36);if(_0x5e88db['files']['has'](_0x5aa574))return _0x17f78a[_0x2000b3(0x159)](updateGraphForFile,_0x5e88db,_0x497d36,_0x209fe3);_0x5e88db['files'][_0x2000b3(_0x5f4136._0x27d483)](_0x5aa574),_0x5e88db['forward']['set'](_0x5aa574,[]);!_0x5e88db[_0x2000b3(0x182)]['has'](_0x5aa574)&&_0x5e88db['reverse'][_0x2000b3(_0x5f4136._0x455269)](_0x5aa574,[]);const _0x23cd91=(0x0,plugin_1[_0x2000b3(_0x5f4136._0x196a80)])(_0x5aa574);if(!_0x23cd91){const _0x3454f3={};return _0x3454f3[_0x2000b3(_0x5f4136._0x25b9a2)]=_0x5aa574,_0x3454f3['addedEdges']=[],_0x3454f3['removedEdges']=[],_0x3454f3[_0x2000b3(0x16e)]=![],_0x3454f3[_0x2000b3(_0x5f4136._0x3e71d9)]=[],_0x3454f3;}const _0x37086c=_0x17f78a[_0x2000b3(_0x5f4136._0x3b4a09)](findSourceDirForFile,_0x5aa574,_0x5e88db),_0x57684a=_0x23cd91[_0x2000b3(0x187)](_0x5aa574,_0x209fe3,_0x37086c),_0x3dcd0d=_0x57684a['filter'](_0x45fb78=>_0x5e88db['files']['has'](_0x45fb78)),_0x42ec98=[];_0x5e88db[_0x2000b3(0x16c)]['set'](_0x5aa574,_0x3dcd0d);for(const _0x36fdf4 of _0x3dcd0d){_0x42ec98[_0x2000b3(_0x5f4136._0x15ceae)]([_0x5aa574,_0x36fdf4]);const _0x298c99=_0x5e88db[_0x2000b3(_0x5f4136._0x4e57af)]['get'](_0x36fdf4);_0x298c99?!_0x298c99['includes'](_0x5aa574)&&_0x298c99['push'](_0x5aa574):_0x5e88db[_0x2000b3(0x182)][_0x2000b3(_0x5f4136._0x3dcd23)](_0x36fdf4,[_0x5aa574]);}const _0x34dbf5=_0x17f78a[_0x2000b3(0x178)](_0x42ec98[_0x2000b3(0x166)],0x0),_0x317d45=computeAffectedFiles(_0x5aa574,_0x5e88db);_0x34dbf5&&_0x17f78a[_0x2000b3(0x179)](recomputeGraphMetrics,_0x5e88db);const _0x28564d={};return _0x28564d[_0x2000b3(0x157)]=_0x5aa574,_0x28564d[_0x2000b3(_0x5f4136._0x4f2158)]=_0x42ec98,_0x28564d['removedEdges']=[],_0x28564d[_0x2000b3(0x16e)]=_0x34dbf5,_0x28564d[_0x2000b3(_0x5f4136._0x241fe8)]=_0x317d45,_0x28564d;}function removeFileFromGraph(_0x1b8bcc,_0x5ecc16){const _0x4aa84d={_0x47b676:0x146,_0x193dba:0x16e,_0x437648:0x181,_0xb63b9a:0x166,_0x24e180:0x156,_0xec2ab4:0x16e,_0x3fbf52:0x172},_0xa21bc8=_0x45314f,_0x974c08={'miaZT':function(_0x592693,_0x584a6c){return _0x592693!==_0x584a6c;},'Sonon':function(_0x37b2e7,_0xdd11ae){return _0x37b2e7(_0xdd11ae);}},_0x4a256c=path[_0xa21bc8(_0x4aa84d._0x47b676)](_0x5ecc16);if(!_0x1b8bcc[_0xa21bc8(0x17f)]['has'](_0x4a256c)){const _0xc2214c={};return _0xc2214c['updatedFile']=_0x4a256c,_0xc2214c['addedEdges']=[],_0xc2214c['removedEdges']=[],_0xc2214c[_0xa21bc8(_0x4aa84d._0x193dba)]=![],_0xc2214c['affectedFiles']=[],_0xc2214c;}const _0x301bea=computeAffectedFiles(_0x4a256c,_0x1b8bcc),_0xc14e5d=[],_0x23e831=_0x1b8bcc[_0xa21bc8(0x16c)][_0xa21bc8(0x15a)](_0x4a256c)||[];for(const _0x5b56d3 of _0x23e831){_0xc14e5d['push']([_0x4a256c,_0x5b56d3]);const _0x3f9e4b=_0x1b8bcc[_0xa21bc8(0x182)]['get'](_0x5b56d3);if(_0x3f9e4b){const _0x3c22cf=_0x3f9e4b[_0xa21bc8(0x16a)](_0x4a256c);_0x974c08[_0xa21bc8(_0x4aa84d._0x437648)](_0x3c22cf,-0x1)&&_0x3f9e4b[_0xa21bc8(0x14a)](_0x3c22cf,0x1);}}const _0x2c08ce=_0x1b8bcc[_0xa21bc8(0x182)][_0xa21bc8(0x15a)](_0x4a256c)||[];for(const _0x353b5b of _0x2c08ce){_0xc14e5d[_0xa21bc8(0x15e)]([_0x353b5b,_0x4a256c]);const _0x126f2c=_0x1b8bcc[_0xa21bc8(0x16c)]['get'](_0x353b5b);if(_0x126f2c){const _0x4f7d49=_0x126f2c['indexOf'](_0x4a256c);_0x4f7d49!==-0x1&&_0x126f2c[_0xa21bc8(0x14a)](_0x4f7d49,0x1);}}_0x1b8bcc[_0xa21bc8(0x16c)]['delete'](_0x4a256c),_0x1b8bcc['reverse'][_0xa21bc8(0x16d)](_0x4a256c),_0x1b8bcc[_0xa21bc8(0x17f)]['delete'](_0x4a256c);const _0x4c47da=_0xc14e5d[_0xa21bc8(_0x4aa84d._0xb63b9a)]>0x0;_0x4c47da&&_0x974c08['Sonon'](recomputeGraphMetrics,_0x1b8bcc);const _0x219a60={};return _0x219a60['updatedFile']=_0x4a256c,_0x219a60[_0xa21bc8(_0x4aa84d._0x24e180)]=[],_0x219a60['removedEdges']=_0xc14e5d,_0x219a60[_0xa21bc8(_0x4aa84d._0xec2ab4)]=_0x4c47da,_0x219a60[_0xa21bc8(_0x4aa84d._0x3fbf52)]=_0x301bea,_0x219a60;}function _0x4cea(_0x3775ff,_0x23be71){_0x3775ff=_0x3775ff-0x141;const _0x3cb359=_0x3cb3();let _0x4cea31=_0x3cb359[_0x3775ff];if(_0x4cea['doKJJp']===undefined){var _0x1118c6=function(_0x1c9bdc){const _0x1b3e67='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x54aca0='',_0x43d123='';for(let _0x41ca16=0x0,_0x333a41,_0x2edd4e,_0x456d08=0x0;_0x2edd4e=_0x1c9bdc['charAt'](_0x456d08++);~_0x2edd4e&&(_0x333a41=_0x41ca16%0x4?_0x333a41*0x40+_0x2edd4e:_0x2edd4e,_0x41ca16++%0x4)?_0x54aca0+=String['fromCharCode'](0xff&_0x333a41>>(-0x2*_0x41ca16&0x6)):0x0){_0x2edd4e=_0x1b3e67['indexOf'](_0x2edd4e);}for(let _0x3f2b82=0x0,_0x177231=_0x54aca0['length'];_0x3f2b82<_0x177231;_0x3f2b82++){_0x43d123+='%'+('00'+_0x54aca0['charCodeAt'](_0x3f2b82)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x43d123);};_0x4cea['KryPYu']=_0x1118c6,_0x4cea['tbbJzu']={},_0x4cea['doKJJp']=!![];}const _0x3015a4=_0x3cb359[0x0],_0x5644ee=_0x3775ff+_0x3015a4,_0x236690=_0x4cea['tbbJzu'][_0x5644ee];return!_0x236690?(_0x4cea31=_0x4cea['KryPYu'](_0x4cea31),_0x4cea['tbbJzu'][_0x5644ee]=_0x4cea31):_0x4cea31=_0x236690,_0x4cea31;}function findSourceDirForFile(_0x268ba9,_0x2dad9e){const _0x4f574a={_0x42376e:0x153},_0x47efac=_0x45314f;for(const _0x4eabad of _0x2dad9e[_0x47efac(0x170)]){if(_0x268ba9['startsWith'](_0x4eabad))return _0x4eabad;}return _0x2dad9e[_0x47efac(_0x4f574a._0x42376e)];}function computeAffectedFiles(_0x52fba8,_0x4e6c66){const _0x30ab14=_0x45314f,_0x38443e=new Set();_0x38443e['add'](_0x52fba8);const _0x217ee6=[_0x52fba8];while(_0x217ee6[_0x30ab14(0x166)]>0x0){const _0x24eb65=_0x217ee6[_0x30ab14(0x186)](),_0xc11cd6=_0x4e6c66['reverse']['get'](_0x24eb65)||[];for(const _0x5cf3e6 of _0xc11cd6){!_0x38443e['has'](_0x5cf3e6)&&(_0x38443e[_0x30ab14(0x180)](_0x5cf3e6),_0x217ee6[_0x30ab14(0x15e)](_0x5cf3e6));}}return[..._0x38443e];}function recomputeGraphMetrics(_0x3d0198){const _0x56be26={_0x1c77d9:0x14d,_0x29bc67:0x144,_0x36e180:0x166,_0x7e197b:0x17f,_0x23c56d:0x158,_0x2b3fc8:0x17d},_0x24eab2=_0x45314f;_0x3d0198[_0x24eab2(0x144)]=(0x0,scc_1[_0x24eab2(0x175)])(_0x3d0198),(0x0,pagerank_1[_0x24eab2(0x148)])(),_0x3d0198[_0x24eab2(0x147)]=(0x0,pagerank_1[_0x24eab2(_0x56be26._0x1c77d9)])(_0x3d0198),(0x0,risk_scorer_1['invalidateProjectMetrics'])();const _0x468694=_0x3d0198[_0x24eab2(_0x56be26._0x29bc67)][_0x24eab2(0x17e)]['nodes']['filter'](_0x10f184=>_0x10f184['isCyclic'])[_0x24eab2(_0x56be26._0x36e180)];console['error']('[syke:incremental]\x20Graph\x20metrics\x20recomputed:\x20'+_0x3d0198[_0x24eab2(_0x56be26._0x7e197b)]['size']+_0x24eab2(_0x56be26._0x23c56d)+(_0x3d0198['scc'][_0x24eab2(_0x56be26._0x2b3fc8)][_0x24eab2(0x166)]+'\x20SCCs\x20('+_0x468694+'\x20cyclic)'));}