@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.3
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.
- package/README.md +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +14 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,292 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Attachment Validator
|
|
3
|
-
* Validates file attachments for security and size constraints
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import { fileURLToPath } from 'url';
|
|
8
|
-
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = path.dirname(__filename);
|
|
11
|
-
|
|
12
|
-
// Constants
|
|
13
|
-
const SIZE_LIMITS = {
|
|
14
|
-
content: 1024 * 1024, // 1MB for content mode
|
|
15
|
-
reference: Number.MAX_VALUE // No limit for reference mode (just metadata)
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const SIZE_WARNING_THRESHOLD = {
|
|
19
|
-
yellow: 100 * 1024, // 100KB
|
|
20
|
-
red: 1024 * 1024 // 1MB
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const BLOCKED_EXTENSIONS = [
|
|
24
|
-
'.exe', '.dll', '.so', '.dylib',
|
|
25
|
-
'.sh', '.bat', '.cmd', '.ps1',
|
|
26
|
-
'.app', '.dmg', '.deb', '.rpm',
|
|
27
|
-
'.msi', '.pkg', '.apk', '.jar'
|
|
28
|
-
];
|
|
29
|
-
|
|
30
|
-
const SUPPORTED_TEXT_EXTENSIONS = [
|
|
31
|
-
'.txt', '.md', '.js', '.jsx', '.ts', '.tsx',
|
|
32
|
-
'.json', '.xml', '.html', '.css', '.scss',
|
|
33
|
-
'.py', '.java', '.cpp', '.c', '.h',
|
|
34
|
-
'.go', '.rs', '.rb', '.php', '.sh',
|
|
35
|
-
'.yml', '.yaml', '.toml', '.env',
|
|
36
|
-
'.log', '.sql', '.vue', '.svelte'
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
const SUPPORTED_IMAGE_EXTENSIONS = [
|
|
40
|
-
'.jpg', '.jpeg', '.png', '.gif',
|
|
41
|
-
'.webp', '.bmp', '.svg'
|
|
42
|
-
];
|
|
43
|
-
|
|
44
|
-
const SUPPORTED_PDF_EXTENSIONS = ['.pdf'];
|
|
45
|
-
|
|
46
|
-
class AttachmentValidator {
|
|
47
|
-
constructor(config = {}, logger = null) {
|
|
48
|
-
this.config = config;
|
|
49
|
-
this.logger = logger;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Validate file size
|
|
54
|
-
* @param {number} size - File size in bytes
|
|
55
|
-
* @param {string} mode - 'content' or 'reference'
|
|
56
|
-
* @returns {Object} { valid: boolean, error?: string, warning?: string, level?: string }
|
|
57
|
-
*/
|
|
58
|
-
validateSize(size, mode = 'content') {
|
|
59
|
-
const limit = SIZE_LIMITS[mode];
|
|
60
|
-
|
|
61
|
-
if (size > limit) {
|
|
62
|
-
return {
|
|
63
|
-
valid: false,
|
|
64
|
-
error: `File size (${this.formatBytes(size)}) exceeds ${mode} mode limit (${this.formatBytes(limit)})`
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Check warning thresholds
|
|
69
|
-
if (mode === 'content') {
|
|
70
|
-
if (size > SIZE_WARNING_THRESHOLD.red) {
|
|
71
|
-
return {
|
|
72
|
-
valid: true,
|
|
73
|
-
warning: `This file is large (${this.formatBytes(size)}) and will consume significant tokens`,
|
|
74
|
-
level: 'red'
|
|
75
|
-
};
|
|
76
|
-
} else if (size > SIZE_WARNING_THRESHOLD.yellow) {
|
|
77
|
-
return {
|
|
78
|
-
valid: true,
|
|
79
|
-
warning: `This file is moderately large (${this.formatBytes(size)})`,
|
|
80
|
-
level: 'yellow'
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return { valid: true, level: 'green' };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Validate file type (block executables)
|
|
90
|
-
* @param {string} fileName - File name
|
|
91
|
-
* @returns {Object} { valid: boolean, error?: string }
|
|
92
|
-
*/
|
|
93
|
-
validateFileType(fileName) {
|
|
94
|
-
const ext = path.extname(fileName).toLowerCase();
|
|
95
|
-
|
|
96
|
-
if (this.isExecutable(fileName)) {
|
|
97
|
-
return {
|
|
98
|
-
valid: false,
|
|
99
|
-
error: `Executable files (${ext}) are not allowed for security reasons`
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return { valid: true };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Check if file is executable
|
|
108
|
-
* @param {string} fileName - File name
|
|
109
|
-
* @returns {boolean}
|
|
110
|
-
*/
|
|
111
|
-
isExecutable(fileName) {
|
|
112
|
-
const ext = path.extname(fileName).toLowerCase();
|
|
113
|
-
return BLOCKED_EXTENSIONS.includes(ext);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Validate file path (for reference mode)
|
|
118
|
-
* @param {string} filePath - File path
|
|
119
|
-
* @returns {Object} { valid: boolean, error?: string }
|
|
120
|
-
*/
|
|
121
|
-
validatePath(filePath) {
|
|
122
|
-
// Check for directory traversal attempts
|
|
123
|
-
const normalizedPath = path.normalize(filePath);
|
|
124
|
-
|
|
125
|
-
if (normalizedPath.includes('..')) {
|
|
126
|
-
return {
|
|
127
|
-
valid: false,
|
|
128
|
-
error: 'Directory traversal is not allowed'
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Check for absolute paths to system directories (Unix)
|
|
133
|
-
const systemDirs = ['/etc', '/bin', '/sbin', '/usr/bin', '/usr/sbin', '/sys', '/proc'];
|
|
134
|
-
if (systemDirs.some(dir => normalizedPath.startsWith(dir))) {
|
|
135
|
-
return {
|
|
136
|
-
valid: false,
|
|
137
|
-
error: 'Access to system directories is not allowed'
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Check for Windows system directories
|
|
142
|
-
const winSystemDirs = ['C:\\Windows', 'C:\\Program Files', 'C:\\Program Files (x86)'];
|
|
143
|
-
if (winSystemDirs.some(dir => normalizedPath.startsWith(dir))) {
|
|
144
|
-
return {
|
|
145
|
-
valid: false,
|
|
146
|
-
error: 'Access to system directories is not allowed'
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return { valid: true };
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Get content type from file extension
|
|
155
|
-
* @param {string} fileName - File name
|
|
156
|
-
* @returns {string} - 'text' | 'image' | 'pdf' | 'binary'
|
|
157
|
-
*/
|
|
158
|
-
getContentType(fileName) {
|
|
159
|
-
const ext = path.extname(fileName).toLowerCase();
|
|
160
|
-
|
|
161
|
-
if (SUPPORTED_TEXT_EXTENSIONS.includes(ext)) {
|
|
162
|
-
return 'text';
|
|
163
|
-
}
|
|
164
|
-
if (SUPPORTED_IMAGE_EXTENSIONS.includes(ext)) {
|
|
165
|
-
return 'image';
|
|
166
|
-
}
|
|
167
|
-
if (SUPPORTED_PDF_EXTENSIONS.includes(ext)) {
|
|
168
|
-
return 'pdf';
|
|
169
|
-
}
|
|
170
|
-
return 'binary';
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Check if file type is supported
|
|
175
|
-
* @param {string} fileName - File name
|
|
176
|
-
* @returns {boolean}
|
|
177
|
-
*/
|
|
178
|
-
isSupported(fileName) {
|
|
179
|
-
const contentType = this.getContentType(fileName);
|
|
180
|
-
return contentType !== 'binary';
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Validate all aspects of an attachment
|
|
185
|
-
* @param {Object} options
|
|
186
|
-
* @param {string} options.fileName - File name
|
|
187
|
-
* @param {number} options.size - File size in bytes
|
|
188
|
-
* @param {string} options.mode - 'content' or 'reference'
|
|
189
|
-
* @param {string} options.path - File path (for reference mode)
|
|
190
|
-
* @returns {Object} { valid: boolean, errors: string[], warnings: string[], sizeLevel: string }
|
|
191
|
-
*/
|
|
192
|
-
validate({ fileName, size, mode = 'content', path: filePath = null }) {
|
|
193
|
-
const errors = [];
|
|
194
|
-
const warnings = [];
|
|
195
|
-
let sizeLevel = 'green';
|
|
196
|
-
|
|
197
|
-
// Validate file type
|
|
198
|
-
const typeValidation = this.validateFileType(fileName);
|
|
199
|
-
if (!typeValidation.valid) {
|
|
200
|
-
errors.push(typeValidation.error);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Validate size
|
|
204
|
-
const sizeValidation = this.validateSize(size, mode);
|
|
205
|
-
if (!sizeValidation.valid) {
|
|
206
|
-
errors.push(sizeValidation.error);
|
|
207
|
-
} else if (sizeValidation.warning) {
|
|
208
|
-
warnings.push(sizeValidation.warning);
|
|
209
|
-
sizeLevel = sizeValidation.level;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Validate path (reference mode only)
|
|
213
|
-
if (mode === 'reference' && filePath) {
|
|
214
|
-
const pathValidation = this.validatePath(filePath);
|
|
215
|
-
if (!pathValidation.valid) {
|
|
216
|
-
errors.push(pathValidation.error);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Check if file type is supported
|
|
221
|
-
if (!this.isSupported(fileName)) {
|
|
222
|
-
warnings.push(`File type may not be fully supported (${path.extname(fileName)})`);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return {
|
|
226
|
-
valid: errors.length === 0,
|
|
227
|
-
errors,
|
|
228
|
-
warnings,
|
|
229
|
-
sizeLevel
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Format bytes to human-readable string
|
|
235
|
-
* @param {number} bytes
|
|
236
|
-
* @returns {string}
|
|
237
|
-
*/
|
|
238
|
-
formatBytes(bytes) {
|
|
239
|
-
if (bytes === 0) return '0 Bytes';
|
|
240
|
-
const k = 1024;
|
|
241
|
-
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
242
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
243
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Get MIME type from file extension
|
|
248
|
-
* @param {string} fileName - File name
|
|
249
|
-
* @returns {string}
|
|
250
|
-
*/
|
|
251
|
-
getMimeType(fileName) {
|
|
252
|
-
const ext = path.extname(fileName).toLowerCase();
|
|
253
|
-
const mimeTypes = {
|
|
254
|
-
// Text
|
|
255
|
-
'.txt': 'text/plain',
|
|
256
|
-
'.md': 'text/markdown',
|
|
257
|
-
'.json': 'application/json',
|
|
258
|
-
'.xml': 'application/xml',
|
|
259
|
-
'.html': 'text/html',
|
|
260
|
-
'.css': 'text/css',
|
|
261
|
-
'.js': 'text/javascript',
|
|
262
|
-
'.jsx': 'text/javascript',
|
|
263
|
-
'.ts': 'text/typescript',
|
|
264
|
-
'.tsx': 'text/typescript',
|
|
265
|
-
'.py': 'text/x-python',
|
|
266
|
-
'.java': 'text/x-java',
|
|
267
|
-
'.cpp': 'text/x-c++',
|
|
268
|
-
'.c': 'text/x-c',
|
|
269
|
-
'.yml': 'text/yaml',
|
|
270
|
-
'.yaml': 'text/yaml',
|
|
271
|
-
|
|
272
|
-
// Images
|
|
273
|
-
'.jpg': 'image/jpeg',
|
|
274
|
-
'.jpeg': 'image/jpeg',
|
|
275
|
-
'.png': 'image/png',
|
|
276
|
-
'.gif': 'image/gif',
|
|
277
|
-
'.webp': 'image/webp',
|
|
278
|
-
'.bmp': 'image/bmp',
|
|
279
|
-
'.svg': 'image/svg+xml',
|
|
280
|
-
|
|
281
|
-
// PDF
|
|
282
|
-
'.pdf': 'application/pdf',
|
|
283
|
-
|
|
284
|
-
// Default
|
|
285
|
-
'default': 'application/octet-stream'
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
return mimeTypes[ext] || mimeTypes['default'];
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
export default AttachmentValidator;
|
|
1
|
+
const a0_0x4c86e0=a0_0x3518;(function(_0x59dfb8,_0x17fc46){const _0x1abf1c=a0_0x3518,_0x159956=_0x59dfb8();while(!![]){try{const _0x4f90bf=parseInt(_0x1abf1c(0x15d))/0x1+parseInt(_0x1abf1c(0x153))/0x2+-parseInt(_0x1abf1c(0x169))/0x3+-parseInt(_0x1abf1c(0x155))/0x4*(-parseInt(_0x1abf1c(0x177))/0x5)+parseInt(_0x1abf1c(0x164))/0x6*(parseInt(_0x1abf1c(0x14a))/0x7)+parseInt(_0x1abf1c(0x150))/0x8*(-parseInt(_0x1abf1c(0x138))/0x9)+-parseInt(_0x1abf1c(0x149))/0xa;if(_0x4f90bf===_0x17fc46)break;else _0x159956['push'](_0x159956['shift']());}catch(_0xf3de16){_0x159956['push'](_0x159956['shift']());}}}(a0_0x2399,0x4a0c7));import a0_0x4f969e from'path';import{fileURLToPath}from'url';function a0_0x3518(_0x3385ea,_0x64c0a0){_0x3385ea=_0x3385ea-0x138;const _0x23997f=a0_0x2399();let _0x3518a9=_0x23997f[_0x3385ea];if(a0_0x3518['IogZIn']===undefined){var _0x1d2c89=function(_0x5f08b2){const _0x453619='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4f969e='',_0x2c9986='';for(let _0x3bbe0b=0x0,_0x184a73,_0xfddd62,_0x3d36b1=0x0;_0xfddd62=_0x5f08b2['charAt'](_0x3d36b1++);~_0xfddd62&&(_0x184a73=_0x3bbe0b%0x4?_0x184a73*0x40+_0xfddd62:_0xfddd62,_0x3bbe0b++%0x4)?_0x4f969e+=String['fromCharCode'](0xff&_0x184a73>>(-0x2*_0x3bbe0b&0x6)):0x0){_0xfddd62=_0x453619['indexOf'](_0xfddd62);}for(let _0x20c35f=0x0,_0x3f4c63=_0x4f969e['length'];_0x20c35f<_0x3f4c63;_0x20c35f++){_0x2c9986+='%'+('00'+_0x4f969e['charCodeAt'](_0x20c35f)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x2c9986);};a0_0x3518['GcFtvp']=_0x1d2c89,a0_0x3518['nPVIjP']={},a0_0x3518['IogZIn']=!![];}const _0x429e0f=_0x23997f[0x0],_0x48b9a2=_0x3385ea+_0x429e0f,_0x1dc1db=a0_0x3518['nPVIjP'][_0x48b9a2];return!_0x1dc1db?(_0x3518a9=a0_0x3518['GcFtvp'](_0x3518a9),a0_0x3518['nPVIjP'][_0x48b9a2]=_0x3518a9):_0x3518a9=_0x1dc1db,_0x3518a9;}const __filename=fileURLToPath(import.meta.url),__dirname=a0_0x4f969e[a0_0x4c86e0(0x13a)](__filename),SIZE_LIMITS={'content':0x400*0x400,'reference':Number[a0_0x4c86e0(0x142)]},SIZE_WARNING_THRESHOLD={'yellow':0x64*0x400,'red':0x400*0x400},BLOCKED_EXTENSIONS=[a0_0x4c86e0(0x18a),a0_0x4c86e0(0x141),'.so',a0_0x4c86e0(0x157),a0_0x4c86e0(0x13f),'.bat','.cmd','.ps1',a0_0x4c86e0(0x186),'.dmg','.deb','.rpm','.msi',a0_0x4c86e0(0x17f),'.apk',a0_0x4c86e0(0x172)],SUPPORTED_TEXT_EXTENSIONS=[a0_0x4c86e0(0x161),a0_0x4c86e0(0x179),'.js','.jsx',a0_0x4c86e0(0x15a),'.tsx',a0_0x4c86e0(0x188),'.xml','.html','.css','.scss',a0_0x4c86e0(0x143),a0_0x4c86e0(0x182),a0_0x4c86e0(0x146),'.c','.h','.go',a0_0x4c86e0(0x185),a0_0x4c86e0(0x13e),'.php','.sh',a0_0x4c86e0(0x151),'.yaml','.toml',a0_0x4c86e0(0x159),'.log','.sql','.vue','.svelte'],SUPPORTED_IMAGE_EXTENSIONS=['.jpg',a0_0x4c86e0(0x13d),'.png',a0_0x4c86e0(0x175),'.webp','.bmp','.svg'],SUPPORTED_PDF_EXTENSIONS=['.pdf'];class AttachmentValidator{constructor(_0x2c9986={},_0x3bbe0b=null){const _0x3aca83=a0_0x4c86e0;this[_0x3aca83(0x184)]=_0x2c9986,this[_0x3aca83(0x13b)]=_0x3bbe0b;}['validateSize'](_0x184a73,_0xfddd62='content'){const _0x97cc32=a0_0x4c86e0,_0x3d36b1=SIZE_LIMITS[_0xfddd62];if(_0x184a73>_0x3d36b1)return{'valid':![],'error':_0x97cc32(0x14f)+this['formatBytes'](_0x184a73)+')\x20exceeds\x20'+_0xfddd62+'\x20mode\x20limit\x20('+this[_0x97cc32(0x152)](_0x3d36b1)+')'};if(_0xfddd62==='content'){if(_0x184a73>SIZE_WARNING_THRESHOLD[_0x97cc32(0x174)])return{'valid':!![],'warning':_0x97cc32(0x156)+this[_0x97cc32(0x152)](_0x184a73)+')\x20and\x20will\x20consume\x20significant\x20tokens','level':_0x97cc32(0x174)};else{if(_0x184a73>SIZE_WARNING_THRESHOLD[_0x97cc32(0x15f)])return{'valid':!![],'warning':_0x97cc32(0x17e)+this['formatBytes'](_0x184a73)+')','level':'yellow'};}}return{'valid':!![],'level':'green'};}['validateFileType'](_0x20c35f){const _0x324f3b=a0_0x4c86e0,_0x3f4c63=a0_0x4f969e['extname'](_0x20c35f)[_0x324f3b(0x17a)]();if(this[_0x324f3b(0x16e)](_0x20c35f))return{'valid':![],'error':_0x324f3b(0x14b)+_0x3f4c63+')\x20are\x20not\x20allowed\x20for\x20security\x20reasons'};return{'valid':!![]};}['isExecutable'](_0x8fab23){const _0x1a72fa=a0_0x4c86e0,_0x33f8d8=a0_0x4f969e[_0x1a72fa(0x168)](_0x8fab23)['toLowerCase']();return BLOCKED_EXTENSIONS[_0x1a72fa(0x180)](_0x33f8d8);}[a0_0x4c86e0(0x165)](_0x13ca81){const _0x2d6898=a0_0x4c86e0,_0x40bcf9=a0_0x4f969e['normalize'](_0x13ca81);if(_0x40bcf9['includes']('..'))return{'valid':![],'error':'Directory\x20traversal\x20is\x20not\x20allowed'};const _0x8f0eda=['/etc',_0x2d6898(0x173),_0x2d6898(0x14d),'/usr/bin','/usr/sbin',_0x2d6898(0x187),'/proc'];if(_0x8f0eda[_0x2d6898(0x148)](_0x1e0464=>_0x40bcf9['startsWith'](_0x1e0464)))return{'valid':![],'error':_0x2d6898(0x18b)};const _0x2dd867=['C:\x5cWindows','C:\x5cProgram\x20Files',_0x2d6898(0x140)];if(_0x2dd867['some'](_0x431024=>_0x40bcf9[_0x2d6898(0x16c)](_0x431024)))return{'valid':![],'error':'Access\x20to\x20system\x20directories\x20is\x20not\x20allowed'};return{'valid':!![]};}['getContentType'](_0x425ee8){const _0x207aa1=a0_0x4c86e0,_0x24e718=a0_0x4f969e[_0x207aa1(0x168)](_0x425ee8)[_0x207aa1(0x17a)]();if(SUPPORTED_TEXT_EXTENSIONS[_0x207aa1(0x180)](_0x24e718))return'text';if(SUPPORTED_IMAGE_EXTENSIONS['includes'](_0x24e718))return _0x207aa1(0x13c);if(SUPPORTED_PDF_EXTENSIONS[_0x207aa1(0x180)](_0x24e718))return'pdf';return'binary';}[a0_0x4c86e0(0x176)](_0x136785){const _0x4690f1=a0_0x4c86e0,_0x299118=this[_0x4690f1(0x154)](_0x136785);return _0x299118!==_0x4690f1(0x160);}[a0_0x4c86e0(0x178)]({fileName:_0x4e12ff,size:_0x2489ba,mode:mode=a0_0x4c86e0(0x16a),path:_0x4370ba=null}){const _0x59f03f=a0_0x4c86e0,_0x1fa3df=[],_0x2d910e=[];let _0x38722b=_0x59f03f(0x15c);const _0x466b5e=this[_0x59f03f(0x17b)](_0x4e12ff);!_0x466b5e['valid']&&_0x1fa3df[_0x59f03f(0x17d)](_0x466b5e[_0x59f03f(0x189)]);const _0x4aa335=this[_0x59f03f(0x171)](_0x2489ba,mode);if(!_0x4aa335['valid'])_0x1fa3df[_0x59f03f(0x17d)](_0x4aa335[_0x59f03f(0x189)]);else _0x4aa335['warning']&&(_0x2d910e[_0x59f03f(0x17d)](_0x4aa335['warning']),_0x38722b=_0x4aa335[_0x59f03f(0x16b)]);if(mode===_0x59f03f(0x162)&&_0x4370ba){const _0x3d84fc=this['validatePath'](_0x4370ba);!_0x3d84fc[_0x59f03f(0x158)]&&_0x1fa3df['push'](_0x3d84fc['error']);}return!this[_0x59f03f(0x176)](_0x4e12ff)&&_0x2d910e['push']('File\x20type\x20may\x20not\x20be\x20fully\x20supported\x20('+a0_0x4f969e[_0x59f03f(0x168)](_0x4e12ff)+')'),{'valid':_0x1fa3df['length']===0x0,'errors':_0x1fa3df,'warnings':_0x2d910e,'sizeLevel':_0x38722b};}[a0_0x4c86e0(0x152)](_0x1609c2){const _0x1de735=a0_0x4c86e0;if(_0x1609c2===0x0)return _0x1de735(0x15e);const _0x1289d8=0x400,_0x2c2a5d=[_0x1de735(0x14e),'KB','MB','GB'],_0x74bb67=Math[_0x1de735(0x16f)](Math['log'](_0x1609c2)/Math[_0x1de735(0x147)](_0x1289d8));return parseFloat((_0x1609c2/Math[_0x1de735(0x170)](_0x1289d8,_0x74bb67))['toFixed'](0x2))+'\x20'+_0x2c2a5d[_0x74bb67];}[a0_0x4c86e0(0x17c)](_0x386136){const _0xc8dd58=a0_0x4c86e0,_0x341c9c=a0_0x4f969e['extname'](_0x386136)['toLowerCase'](),_0x3aaf2b={'.txt':'text/plain','.md':'text/markdown','.json':_0xc8dd58(0x167),'.xml':_0xc8dd58(0x144),'.html':_0xc8dd58(0x181),'.css':'text/css','.js':_0xc8dd58(0x183),'.jsx':'text/javascript','.ts':'text/typescript','.tsx':'text/typescript','.py':_0xc8dd58(0x145),'.java':'text/x-java','.cpp':_0xc8dd58(0x166),'.c':'text/x-c','.yml':'text/yaml','.yaml':'text/yaml','.jpg':_0xc8dd58(0x16d),'.jpeg':_0xc8dd58(0x16d),'.png':_0xc8dd58(0x163),'.gif':'image/gif','.webp':'image/webp','.bmp':'image/bmp','.svg':_0xc8dd58(0x139),'.pdf':_0xc8dd58(0x14c),'default':_0xc8dd58(0x15b)};return _0x3aaf2b[_0x341c9c]||_0x3aaf2b['default'];}}export default AttachmentValidator;function a0_0x2399(){const _0x55f7b6=['zgLYBMfTzq','Bg9Nz2vY','Aw1Hz2u','lMPWzwC','lNjI','lNnO','qZPCuhjVz3jHBsbgAwXLCYaOEdG2kq','lMrSBa','tufyx1zbtfvf','lNb5','yxbWBgLJyxrPB24VEg1S','Dgv4Dc94lxb5DgHVBG','lMnWCa','Bg9N','C29Tzq','mZaZodCWter5Aw9Z','n2TzyNvZsq','rxHLy3v0ywjSzsbMAwXLCYaO','yxbWBgLJyxrPB24VCgrM','l3nIAw4','qNL0zxm','rMLSzsbZAxPLicG','mZy1mdu2quH6vez4','lNLTBa','zM9YBwf0qNL0zxm','mtaWntiWmMP6uxrrsa','z2v0q29UDgvUDfr5Cgu','mtC2B2T6wKTm','vgHPCYbMAwXLigLZigXHCMDLicG','lMr5BgLI','DMfSAwq','lMvUDG','lNrZ','yxbWBgLJyxrPB24VB2n0zxqTC3rYzwfT','z3jLzw4','mZeZmdC1wMjltKrm','mcbcExrLCW','EwvSBg93','yMLUyxj5','lNr4Da','CMvMzxjLBMnL','Aw1Hz2uVCg5N','mtGYnte1ohzwrffiuq','DMfSAwrHDgvqyxrO','Dgv4Dc94lwmRkW','yxbWBgLJyxrPB24VANnVBG','zxH0BMfTzq','mtq5mtCXn3z0wK1wtG','y29UDgvUDa','Bgv2zwW','C3rHCNrZv2L0Aa','Aw1Hz2uVANbLzW','AxnfEgvJDxrHyMXL','zMXVB3i','Cg93','DMfSAwrHDgvtAxPL','lMPHCG','l2jPBG','CMvK','lMDPzG','AxntDxbWB3j0zwq','mtm4mZvgAe9Jy2u','DMfSAwrHDgu','lM1K','Dg9mB3DLCKnHC2u','DMfSAwrHDgvgAwXLvhLWzq','z2v0twLTzvr5Cgu','ChvZAa','vgHPCYbMAwXLigLZig1VzgvYyxrLBhKGBgfYz2uGka','lNbRzW','Aw5JBhvKzxm','Dgv4Dc9ODg1S','lMPHDMe','Dgv4Dc9QyxzHC2nYAxb0','y29UzMLN','lNjZ','lMfWCa','l3n5CW','lMPZB24','zxjYB3i','lMv4zq','qwnJzxnZihrVihn5C3rLBsbKAxjLy3rVCMLLCYbPCYbUB3qGywXSB3DLza','odfUvej0zg8','Aw1Hz2uVC3zNk3HTBa'];a0_0x2399=function(){return _0x55f7b6;};return a0_0x2399();}
|