@cydm/pie 1.0.18 → 1.0.20
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/dist/builtin/extensions/ask-user/index.js +3 -3
- package/dist/builtin/extensions/plan-mode/index.js +3 -3
- package/dist/builtin/extensions/subagent/index.js +4 -4
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/chunks/{chunk-VE2HDCNB.js → chunk-L5BJNCNG.js} +1 -1
- package/dist/chunks/{chunk-G4GV2CRT.js → chunk-NHR6EBM2.js} +775 -181
- package/dist/chunks/{chunk-5DA2D3K2.js → chunk-VESPMEDG.js} +317 -0
- package/dist/chunks/{chunk-MHFUWY7I.js → chunk-ZYOTRKU7.js} +3 -2
- package/dist/chunks/{src-6WPNVGT2.js → src-2FHZO63Y.js} +2 -2
- package/dist/chunks/{test-stream-ZSKNLUEJ.js → test-stream-UW74PA6T.js} +1 -1
- package/dist/cli.js +749 -232
- package/package.json +4 -3
|
@@ -3107,6 +3107,27 @@ function calculateCost(model, usage) {
|
|
|
3107
3107
|
};
|
|
3108
3108
|
}
|
|
3109
3109
|
|
|
3110
|
+
// ../../packages/platform/src/text-hash.ts
|
|
3111
|
+
function createTextHasher() {
|
|
3112
|
+
let hash = 2166136261;
|
|
3113
|
+
return {
|
|
3114
|
+
update(text) {
|
|
3115
|
+
for (let index = 0; index < text.length; index++) {
|
|
3116
|
+
hash ^= text.charCodeAt(index);
|
|
3117
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
3118
|
+
}
|
|
3119
|
+
},
|
|
3120
|
+
digest() {
|
|
3121
|
+
return hash.toString(16).padStart(8, "0");
|
|
3122
|
+
}
|
|
3123
|
+
};
|
|
3124
|
+
}
|
|
3125
|
+
function hashText(text) {
|
|
3126
|
+
const hasher = createTextHasher();
|
|
3127
|
+
hasher.update(text);
|
|
3128
|
+
return hasher.digest();
|
|
3129
|
+
}
|
|
3130
|
+
|
|
3110
3131
|
// ../../packages/platform/src/detector.ts
|
|
3111
3132
|
function isPuerTS() {
|
|
3112
3133
|
try {
|
|
@@ -3252,6 +3273,17 @@ function convertStats(stats) {
|
|
|
3252
3273
|
mtime: stats.mtime
|
|
3253
3274
|
};
|
|
3254
3275
|
}
|
|
3276
|
+
function byteLength(text) {
|
|
3277
|
+
return Buffer.byteLength(text, "utf-8");
|
|
3278
|
+
}
|
|
3279
|
+
function normalizeRangeOptions(options) {
|
|
3280
|
+
return {
|
|
3281
|
+
offsetLine: Math.max(0, Math.floor(options?.offsetLine ?? 0)),
|
|
3282
|
+
limitLines: options?.limitLines === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, Math.floor(options.limitLines)),
|
|
3283
|
+
maxOutputLines: Math.max(0, Math.floor(options?.maxOutputLines ?? Number.POSITIVE_INFINITY)),
|
|
3284
|
+
maxOutputBytes: Math.max(0, Math.floor(options?.maxOutputBytes ?? Number.POSITIVE_INFINITY))
|
|
3285
|
+
};
|
|
3286
|
+
}
|
|
3255
3287
|
var NodeFileSystem = class {
|
|
3256
3288
|
platform = "node";
|
|
3257
3289
|
sep;
|
|
@@ -3266,6 +3298,142 @@ var NodeFileSystem = class {
|
|
|
3266
3298
|
readFileSync(path, encoding = "utf-8") {
|
|
3267
3299
|
return getNodeFs().readFileSync(path, encoding);
|
|
3268
3300
|
}
|
|
3301
|
+
async readTextRange(path, options, signal) {
|
|
3302
|
+
const fs = getNodeFs();
|
|
3303
|
+
const range = normalizeRangeOptions(options);
|
|
3304
|
+
const stat = await fs.promises.stat(path);
|
|
3305
|
+
const fullHasher = createTextHasher();
|
|
3306
|
+
const selectedHasher = createTextHasher();
|
|
3307
|
+
const outputLines = [];
|
|
3308
|
+
let lineStarted = false;
|
|
3309
|
+
let currentLineSelected = false;
|
|
3310
|
+
let currentLineBytes = 0;
|
|
3311
|
+
let currentOutputLine = "";
|
|
3312
|
+
let currentOutputLineBytes = 0;
|
|
3313
|
+
let currentOutputPrefixBytes = 0;
|
|
3314
|
+
let currentLineCanOutput = false;
|
|
3315
|
+
let lineIndex = 0;
|
|
3316
|
+
let selectedLines = 0;
|
|
3317
|
+
let selectedBytes = 0;
|
|
3318
|
+
let firstLineBytes = 0;
|
|
3319
|
+
let outputBytes = 0;
|
|
3320
|
+
let truncated = false;
|
|
3321
|
+
let truncatedBy = null;
|
|
3322
|
+
let firstLineExceedsLimit = false;
|
|
3323
|
+
const selectedEndLine = Number.isFinite(range.limitLines) ? range.offsetLine + range.limitLines : Number.POSITIVE_INFINITY;
|
|
3324
|
+
const startLine = () => {
|
|
3325
|
+
if (lineStarted) return;
|
|
3326
|
+
currentLineSelected = lineIndex >= range.offsetLine && lineIndex < selectedEndLine;
|
|
3327
|
+
currentLineBytes = 0;
|
|
3328
|
+
currentOutputLine = "";
|
|
3329
|
+
currentOutputLineBytes = 0;
|
|
3330
|
+
currentOutputPrefixBytes = outputLines.length > 0 ? 1 : 0;
|
|
3331
|
+
currentLineCanOutput = false;
|
|
3332
|
+
lineStarted = true;
|
|
3333
|
+
if (!currentLineSelected) return;
|
|
3334
|
+
if (selectedLines > 0) {
|
|
3335
|
+
selectedHasher.update("\n");
|
|
3336
|
+
selectedBytes += 1;
|
|
3337
|
+
}
|
|
3338
|
+
if (!truncated && !firstLineExceedsLimit) {
|
|
3339
|
+
if (outputLines.length >= range.maxOutputLines) {
|
|
3340
|
+
truncated = true;
|
|
3341
|
+
truncatedBy = "lines";
|
|
3342
|
+
} else {
|
|
3343
|
+
currentLineCanOutput = true;
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
};
|
|
3347
|
+
const scanLineChar = (char) => {
|
|
3348
|
+
startLine();
|
|
3349
|
+
if (!currentLineSelected) return;
|
|
3350
|
+
selectedHasher.update(char);
|
|
3351
|
+
const charBytes = byteLength(char);
|
|
3352
|
+
currentLineBytes += charBytes;
|
|
3353
|
+
selectedBytes += charBytes;
|
|
3354
|
+
if (selectedLines === 0 && currentLineBytes > range.maxOutputBytes) {
|
|
3355
|
+
firstLineExceedsLimit = true;
|
|
3356
|
+
truncated = true;
|
|
3357
|
+
truncatedBy = "bytes";
|
|
3358
|
+
currentLineCanOutput = false;
|
|
3359
|
+
currentOutputLine = "";
|
|
3360
|
+
currentOutputLineBytes = 0;
|
|
3361
|
+
return;
|
|
3362
|
+
}
|
|
3363
|
+
if (!currentLineCanOutput) return;
|
|
3364
|
+
const candidateOutputBytes = outputBytes + currentOutputPrefixBytes + currentOutputLineBytes + charBytes;
|
|
3365
|
+
if (candidateOutputBytes > range.maxOutputBytes) {
|
|
3366
|
+
truncated = true;
|
|
3367
|
+
truncatedBy = "bytes";
|
|
3368
|
+
currentLineCanOutput = false;
|
|
3369
|
+
currentOutputLine = "";
|
|
3370
|
+
currentOutputLineBytes = 0;
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3373
|
+
currentOutputLine += char;
|
|
3374
|
+
currentOutputLineBytes += charBytes;
|
|
3375
|
+
};
|
|
3376
|
+
const finishLine = () => {
|
|
3377
|
+
startLine();
|
|
3378
|
+
if (currentLineSelected) {
|
|
3379
|
+
if (selectedLines === 0) {
|
|
3380
|
+
firstLineBytes = currentLineBytes;
|
|
3381
|
+
}
|
|
3382
|
+
if (currentLineCanOutput) {
|
|
3383
|
+
const candidateOutputBytes = outputBytes + currentOutputPrefixBytes + currentOutputLineBytes;
|
|
3384
|
+
if (candidateOutputBytes > range.maxOutputBytes) {
|
|
3385
|
+
truncated = true;
|
|
3386
|
+
truncatedBy = "bytes";
|
|
3387
|
+
currentLineCanOutput = false;
|
|
3388
|
+
} else {
|
|
3389
|
+
outputLines.push(currentOutputLine);
|
|
3390
|
+
outputBytes = candidateOutputBytes;
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
selectedLines++;
|
|
3394
|
+
}
|
|
3395
|
+
lineStarted = false;
|
|
3396
|
+
lineIndex++;
|
|
3397
|
+
};
|
|
3398
|
+
const stream = fs.createReadStream(path, { encoding: "utf-8" });
|
|
3399
|
+
try {
|
|
3400
|
+
for await (const chunk of stream) {
|
|
3401
|
+
if (signal?.aborted) {
|
|
3402
|
+
stream.destroy();
|
|
3403
|
+
throw new Error("Operation aborted");
|
|
3404
|
+
}
|
|
3405
|
+
const text = String(chunk);
|
|
3406
|
+
fullHasher.update(text);
|
|
3407
|
+
for (const char of text) {
|
|
3408
|
+
if (char === "\n") {
|
|
3409
|
+
finishLine();
|
|
3410
|
+
} else {
|
|
3411
|
+
scanLineChar(char);
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
finishLine();
|
|
3416
|
+
} finally {
|
|
3417
|
+
stream.destroy();
|
|
3418
|
+
}
|
|
3419
|
+
return {
|
|
3420
|
+
content: outputLines.join("\n"),
|
|
3421
|
+
contentHash: fullHasher.digest(),
|
|
3422
|
+
selectedContentHash: selectedHasher.digest(),
|
|
3423
|
+
totalLines: lineIndex,
|
|
3424
|
+
totalBytes: stat.size,
|
|
3425
|
+
selectedLines,
|
|
3426
|
+
selectedBytes,
|
|
3427
|
+
firstLineBytes,
|
|
3428
|
+
outputLines: outputLines.length,
|
|
3429
|
+
outputBytes,
|
|
3430
|
+
truncated,
|
|
3431
|
+
truncatedBy,
|
|
3432
|
+
firstLineExceedsLimit,
|
|
3433
|
+
mtimeMs: stat.mtime.getTime(),
|
|
3434
|
+
size: stat.size
|
|
3435
|
+
};
|
|
3436
|
+
}
|
|
3269
3437
|
async writeFile(path, data, encoding = "utf-8") {
|
|
3270
3438
|
return getNodeFs().promises.writeFile(path, data, encoding);
|
|
3271
3439
|
}
|
|
@@ -3392,6 +3560,87 @@ function convertBridgeStatResult(result) {
|
|
|
3392
3560
|
mtime: new Date((Number(result?.LastWriteTicksUtc || 0) - 621355968e9) / 1e4)
|
|
3393
3561
|
};
|
|
3394
3562
|
}
|
|
3563
|
+
function normalizeOptionalNumber(value, fallback) {
|
|
3564
|
+
if (value === void 0 || !Number.isFinite(value)) {
|
|
3565
|
+
return fallback;
|
|
3566
|
+
}
|
|
3567
|
+
return Math.max(0, Math.floor(value));
|
|
3568
|
+
}
|
|
3569
|
+
function convertTextRangeResult(result) {
|
|
3570
|
+
return {
|
|
3571
|
+
content: String(result?.Content ?? ""),
|
|
3572
|
+
contentHash: String(result?.ContentHash ?? ""),
|
|
3573
|
+
selectedContentHash: String(result?.SelectedContentHash ?? ""),
|
|
3574
|
+
totalLines: Number(result?.TotalLines ?? 0),
|
|
3575
|
+
totalBytes: Number(result?.TotalBytes ?? 0),
|
|
3576
|
+
selectedLines: Number(result?.SelectedLines ?? 0),
|
|
3577
|
+
selectedBytes: Number(result?.SelectedBytes ?? 0),
|
|
3578
|
+
firstLineBytes: Number(result?.FirstLineBytes ?? 0),
|
|
3579
|
+
outputLines: Number(result?.OutputLines ?? 0),
|
|
3580
|
+
outputBytes: Number(result?.OutputBytes ?? 0),
|
|
3581
|
+
truncated: !!result?.Truncated,
|
|
3582
|
+
truncatedBy: result?.TruncatedBy ? String(result.TruncatedBy) : null,
|
|
3583
|
+
firstLineExceedsLimit: !!result?.FirstLineExceedsLimit,
|
|
3584
|
+
mtimeMs: (Number(result?.LastWriteTicksUtc || 0) - 621355968e9) / 1e4,
|
|
3585
|
+
size: Number(result?.Size ?? 0)
|
|
3586
|
+
};
|
|
3587
|
+
}
|
|
3588
|
+
function byteLength2(text) {
|
|
3589
|
+
if (typeof Buffer !== "undefined") {
|
|
3590
|
+
return Buffer.byteLength(text, "utf-8");
|
|
3591
|
+
}
|
|
3592
|
+
return unescape(encodeURIComponent(text)).length;
|
|
3593
|
+
}
|
|
3594
|
+
function buildTextRangeFallback(content, stat, offsetLine, limitLines, maxOutputLines, maxOutputBytes) {
|
|
3595
|
+
const lines = content.split("\n");
|
|
3596
|
+
const endLine = Number.isFinite(limitLines) ? Math.min(lines.length, offsetLine + limitLines) : lines.length;
|
|
3597
|
+
const selectedLinesArray = offsetLine >= lines.length ? [] : lines.slice(offsetLine, endLine);
|
|
3598
|
+
const selectedContent = selectedLinesArray.join("\n");
|
|
3599
|
+
const outputLines = [];
|
|
3600
|
+
let outputBytes = 0;
|
|
3601
|
+
let truncated = false;
|
|
3602
|
+
let truncatedBy = null;
|
|
3603
|
+
let firstLineExceedsLimit = false;
|
|
3604
|
+
for (const line of selectedLinesArray) {
|
|
3605
|
+
const lineBytes = byteLength2(line);
|
|
3606
|
+
if (outputLines.length === 0 && lineBytes > maxOutputBytes) {
|
|
3607
|
+
firstLineExceedsLimit = true;
|
|
3608
|
+
truncated = true;
|
|
3609
|
+
truncatedBy = "bytes";
|
|
3610
|
+
break;
|
|
3611
|
+
}
|
|
3612
|
+
if (outputLines.length >= maxOutputLines) {
|
|
3613
|
+
truncated = true;
|
|
3614
|
+
truncatedBy = "lines";
|
|
3615
|
+
break;
|
|
3616
|
+
}
|
|
3617
|
+
const candidateBytes = lineBytes + (outputLines.length > 0 ? 1 : 0);
|
|
3618
|
+
if (outputBytes + candidateBytes > maxOutputBytes) {
|
|
3619
|
+
truncated = true;
|
|
3620
|
+
truncatedBy = "bytes";
|
|
3621
|
+
break;
|
|
3622
|
+
}
|
|
3623
|
+
outputLines.push(line);
|
|
3624
|
+
outputBytes += candidateBytes;
|
|
3625
|
+
}
|
|
3626
|
+
return {
|
|
3627
|
+
content: outputLines.join("\n"),
|
|
3628
|
+
contentHash: hashText(content),
|
|
3629
|
+
selectedContentHash: hashText(selectedContent),
|
|
3630
|
+
totalLines: lines.length,
|
|
3631
|
+
totalBytes: stat.size,
|
|
3632
|
+
selectedLines: selectedLinesArray.length,
|
|
3633
|
+
selectedBytes: byteLength2(selectedContent),
|
|
3634
|
+
firstLineBytes: selectedLinesArray.length > 0 ? byteLength2(selectedLinesArray[0]) : 0,
|
|
3635
|
+
outputLines: outputLines.length,
|
|
3636
|
+
outputBytes,
|
|
3637
|
+
truncated,
|
|
3638
|
+
truncatedBy,
|
|
3639
|
+
firstLineExceedsLimit,
|
|
3640
|
+
mtimeMs: stat.mtime.getTime(),
|
|
3641
|
+
size: stat.size
|
|
3642
|
+
};
|
|
3643
|
+
}
|
|
3395
3644
|
function convertDateTime(dateTime) {
|
|
3396
3645
|
if (!dateTime) return /* @__PURE__ */ new Date(0);
|
|
3397
3646
|
const ticks = dateTime.get_Ticks?.() || 0;
|
|
@@ -3457,6 +3706,33 @@ var PuerTSFileSystem = class {
|
|
|
3457
3706
|
}
|
|
3458
3707
|
return IO.File.ReadAllText(normalizedPath);
|
|
3459
3708
|
}
|
|
3709
|
+
async readTextRange(path, options, signal) {
|
|
3710
|
+
if (signal?.aborted) {
|
|
3711
|
+
throw new Error("Operation aborted");
|
|
3712
|
+
}
|
|
3713
|
+
const bridge = getPieFileBridge();
|
|
3714
|
+
const normalizedPath = this.normalizePath(path);
|
|
3715
|
+
if (typeof bridge.ReadTextRangeAsync !== "function") {
|
|
3716
|
+
const content = await this.readFile(path, "utf-8");
|
|
3717
|
+
const stat = await this.stat(path);
|
|
3718
|
+
const offsetLine = normalizeOptionalNumber(options?.offsetLine, 0);
|
|
3719
|
+
const limitLines = options?.limitLines === void 0 ? Number.POSITIVE_INFINITY : normalizeOptionalNumber(options.limitLines, 0);
|
|
3720
|
+
const maxOutputLines = normalizeOptionalNumber(options?.maxOutputLines, Number.POSITIVE_INFINITY);
|
|
3721
|
+
const maxOutputBytes = normalizeOptionalNumber(options?.maxOutputBytes, Number.POSITIVE_INFINITY);
|
|
3722
|
+
return buildTextRangeFallback(content, stat, offsetLine, limitLines, maxOutputLines, maxOutputBytes);
|
|
3723
|
+
}
|
|
3724
|
+
const payload = await taskToPromise(bridge.ReadTextRangeAsync(
|
|
3725
|
+
normalizedPath,
|
|
3726
|
+
normalizeOptionalNumber(options?.offsetLine, 0),
|
|
3727
|
+
options?.limitLines === void 0 ? -1 : normalizeOptionalNumber(options.limitLines, 0),
|
|
3728
|
+
normalizeOptionalNumber(options?.maxOutputLines, -1),
|
|
3729
|
+
normalizeOptionalNumber(options?.maxOutputBytes, -1)
|
|
3730
|
+
));
|
|
3731
|
+
if (signal?.aborted) {
|
|
3732
|
+
throw new Error("Operation aborted");
|
|
3733
|
+
}
|
|
3734
|
+
return convertTextRangeResult(JSON.parse(String(payload ?? "{}")));
|
|
3735
|
+
}
|
|
3460
3736
|
async writeFile(path, data, encoding = "utf-8") {
|
|
3461
3737
|
const bridge = getPieFileBridge();
|
|
3462
3738
|
const normalizedPath = this.normalizePath(path);
|
|
@@ -4381,6 +4657,31 @@ var FileSystemGateway = class {
|
|
|
4381
4657
|
const fs = nodeRequire("fs");
|
|
4382
4658
|
return fs.readFileSync(path, encoding);
|
|
4383
4659
|
}
|
|
4660
|
+
/**
|
|
4661
|
+
* Read at most the first maxBytes of a file.
|
|
4662
|
+
*/
|
|
4663
|
+
readFileHead(path, maxBytes, encoding = "utf-8") {
|
|
4664
|
+
this.validatePath(path, "read");
|
|
4665
|
+
const byteLimit = Math.max(0, Math.floor(maxBytes));
|
|
4666
|
+
if (byteLimit === 0) return "";
|
|
4667
|
+
const platform = detectPlatform();
|
|
4668
|
+
if (platform === "puerts" && typeof CS !== "undefined") {
|
|
4669
|
+
if (!CS.System.IO.File.Exists(path)) {
|
|
4670
|
+
throw new Error(`File not found: ${path}`);
|
|
4671
|
+
}
|
|
4672
|
+
return CS.System.IO.File.ReadAllText(path).slice(0, byteLimit);
|
|
4673
|
+
}
|
|
4674
|
+
const fs = nodeRequire("fs");
|
|
4675
|
+
const fileSize = fs.existsSync(path) ? fs.statSync(path).size : 0;
|
|
4676
|
+
const buffer = Buffer.alloc(Math.min(byteLimit, fileSize));
|
|
4677
|
+
const fd = fs.openSync(path, "r");
|
|
4678
|
+
try {
|
|
4679
|
+
const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, 0);
|
|
4680
|
+
return buffer.subarray(0, bytesRead).toString(encoding);
|
|
4681
|
+
} finally {
|
|
4682
|
+
fs.closeSync(fd);
|
|
4683
|
+
}
|
|
4684
|
+
}
|
|
4384
4685
|
/**
|
|
4385
4686
|
* Write file content
|
|
4386
4687
|
*/
|
|
@@ -4549,6 +4850,21 @@ var FileSystemGateway = class {
|
|
|
4549
4850
|
if (!fs.existsSync(path)) return 0;
|
|
4550
4851
|
return fs.statSync(path).size;
|
|
4551
4852
|
}
|
|
4853
|
+
/**
|
|
4854
|
+
* Get file modified time in milliseconds since epoch.
|
|
4855
|
+
*/
|
|
4856
|
+
getModifiedTime(path) {
|
|
4857
|
+
this.validatePath(path, "getModifiedTime");
|
|
4858
|
+
const platform = detectPlatform();
|
|
4859
|
+
if (platform === "puerts" && typeof CS !== "undefined") {
|
|
4860
|
+
if (!CS.System.IO.File.Exists(path)) return 0;
|
|
4861
|
+
const ticks = Number(CS.System.IO.File.GetLastWriteTimeUtc(path).Ticks);
|
|
4862
|
+
return Number.isFinite(ticks) ? ticks / 1e4 - 621355968e5 : 0;
|
|
4863
|
+
}
|
|
4864
|
+
const fs = nodeRequire("fs");
|
|
4865
|
+
if (!fs.existsSync(path)) return 0;
|
|
4866
|
+
return fs.statSync(path).mtimeMs;
|
|
4867
|
+
}
|
|
4552
4868
|
/**
|
|
4553
4869
|
* Get config
|
|
4554
4870
|
*/
|
|
@@ -9121,6 +9437,7 @@ registerApiProvider({
|
|
|
9121
9437
|
});
|
|
9122
9438
|
|
|
9123
9439
|
export {
|
|
9440
|
+
hashText,
|
|
9124
9441
|
detectPlatform,
|
|
9125
9442
|
createLogger,
|
|
9126
9443
|
setLogger,
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
createSharedWebSearchTool,
|
|
9
9
|
interpretShellExit,
|
|
10
10
|
requestInteraction
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-NHR6EBM2.js";
|
|
12
12
|
import {
|
|
13
13
|
Type
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-VESPMEDG.js";
|
|
15
15
|
|
|
16
16
|
// src/config.ts
|
|
17
17
|
import { existsSync, mkdirSync, readFileSync, renameSync } from "fs";
|
|
@@ -978,6 +978,7 @@ export {
|
|
|
978
978
|
getPackageDir,
|
|
979
979
|
getThemesDir,
|
|
980
980
|
getBuiltinDir,
|
|
981
|
+
VERSION,
|
|
981
982
|
getConfigDir,
|
|
982
983
|
getAgentDir,
|
|
983
984
|
getCustomThemesDir,
|