@cleocode/adapters 2026.5.29 → 2026.5.33
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/index.js +58 -73
- package/dist/index.js.map +4 -4
- package/dist/providers/claude-code/install.d.ts +2 -7
- package/dist/providers/claude-code/install.d.ts.map +1 -1
- package/dist/providers/cursor/install.d.ts +6 -1
- package/dist/providers/cursor/install.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/claude-code-adapter.test.ts +10 -10
- package/src/providers/claude-code/__tests__/adapter.test.ts +11 -0
- package/src/providers/claude-code/install.ts +8 -52
- package/src/providers/cursor/__tests__/adapter.test.ts +17 -0
- package/src/providers/cursor/install.ts +26 -16
package/dist/index.js
CHANGED
|
@@ -27887,14 +27887,6 @@ var init_hook_template_installer = __esm({
|
|
|
27887
27887
|
}
|
|
27888
27888
|
});
|
|
27889
27889
|
|
|
27890
|
-
// packages/adapters/src/providers/shared/paths.ts
|
|
27891
|
-
import { getCleoTemplatesTildePath } from "@cleocode/paths";
|
|
27892
|
-
var init_paths2 = __esm({
|
|
27893
|
-
"packages/adapters/src/providers/shared/paths.ts"() {
|
|
27894
|
-
"use strict";
|
|
27895
|
-
}
|
|
27896
|
-
});
|
|
27897
|
-
|
|
27898
27890
|
// packages/adapters/src/providers/claude-code/install.ts
|
|
27899
27891
|
import {
|
|
27900
27892
|
copyFileSync as copyFileSync2,
|
|
@@ -27907,20 +27899,16 @@ import {
|
|
|
27907
27899
|
import { homedir as homedir6 } from "node:os";
|
|
27908
27900
|
import { dirname as dirname3, join as join7 } from "node:path";
|
|
27909
27901
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
27902
|
+
import { ensureProviderInstructionFile } from "@cleocode/caamp";
|
|
27910
27903
|
function getAdapterCommandsDir() {
|
|
27911
27904
|
const thisDir = dirname3(fileURLToPath2(import.meta.url));
|
|
27912
27905
|
return join7(thisDir, "commands");
|
|
27913
27906
|
}
|
|
27914
|
-
var
|
|
27907
|
+
var ClaudeCodeInstallProvider;
|
|
27915
27908
|
var init_install = __esm({
|
|
27916
27909
|
"packages/adapters/src/providers/claude-code/install.ts"() {
|
|
27917
27910
|
"use strict";
|
|
27918
27911
|
init_hook_template_installer();
|
|
27919
|
-
init_paths2();
|
|
27920
|
-
INSTRUCTION_REFERENCES = [
|
|
27921
|
-
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
27922
|
-
"@.cleo/memory-bridge.md"
|
|
27923
|
-
];
|
|
27924
27912
|
ClaudeCodeInstallProvider = class {
|
|
27925
27913
|
/**
|
|
27926
27914
|
* Install CLEO into a Claude Code project.
|
|
@@ -27933,9 +27921,10 @@ var init_install = __esm({
|
|
|
27933
27921
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
27934
27922
|
let instructionFileUpdated = false;
|
|
27935
27923
|
const details = {};
|
|
27936
|
-
|
|
27924
|
+
const instructionResult = await ensureProviderInstructionFile("claude-code", projectDir, {});
|
|
27925
|
+
instructionFileUpdated = instructionResult.action !== "intact";
|
|
27937
27926
|
if (instructionFileUpdated) {
|
|
27938
|
-
details.instructionFile =
|
|
27927
|
+
details.instructionFile = instructionResult.filePath;
|
|
27939
27928
|
}
|
|
27940
27929
|
const commandsInstalled = this.installCommands(projectDir);
|
|
27941
27930
|
if (commandsInstalled.length > 0) {
|
|
@@ -27985,39 +27974,13 @@ var init_install = __esm({
|
|
|
27985
27974
|
/**
|
|
27986
27975
|
* Ensure CLAUDE.md contains @-references to CLEO instruction files.
|
|
27987
27976
|
*
|
|
27988
|
-
*
|
|
27977
|
+
* Delegates to CAAMP's canonical API which reads the instruction file name
|
|
27978
|
+
* and default references from the provider registry (T1919).
|
|
27989
27979
|
*
|
|
27990
27980
|
* @param projectDir - Project root directory
|
|
27991
27981
|
*/
|
|
27992
27982
|
async ensureInstructionReferences(projectDir) {
|
|
27993
|
-
|
|
27994
|
-
}
|
|
27995
|
-
/**
|
|
27996
|
-
* Update CLAUDE.md with CLEO @-references.
|
|
27997
|
-
*
|
|
27998
|
-
* @returns true if the file was created or modified
|
|
27999
|
-
*/
|
|
28000
|
-
updateInstructionFile(projectDir) {
|
|
28001
|
-
const claudeMdPath = join7(projectDir, "CLAUDE.md");
|
|
28002
|
-
let content = "";
|
|
28003
|
-
let existed = false;
|
|
28004
|
-
if (existsSync6(claudeMdPath)) {
|
|
28005
|
-
content = readFileSync5(claudeMdPath, "utf-8");
|
|
28006
|
-
existed = true;
|
|
28007
|
-
}
|
|
28008
|
-
const missingRefs = INSTRUCTION_REFERENCES.filter((ref) => !content.includes(ref));
|
|
28009
|
-
if (missingRefs.length === 0) {
|
|
28010
|
-
return false;
|
|
28011
|
-
}
|
|
28012
|
-
const refsBlock = missingRefs.join("\n");
|
|
28013
|
-
if (existed) {
|
|
28014
|
-
const separator = content.endsWith("\n") ? "" : "\n";
|
|
28015
|
-
content = content + separator + refsBlock + "\n";
|
|
28016
|
-
} else {
|
|
28017
|
-
content = refsBlock + "\n";
|
|
28018
|
-
}
|
|
28019
|
-
writeFileSync3(claudeMdPath, content, "utf-8");
|
|
28020
|
-
return true;
|
|
27983
|
+
await ensureProviderInstructionFile("claude-code", projectDir, {});
|
|
28021
27984
|
}
|
|
28022
27985
|
/**
|
|
28023
27986
|
* Install Claude Code-specific commands to .claude/commands/ in the project.
|
|
@@ -28708,6 +28671,14 @@ var init_claude_code = __esm({
|
|
|
28708
28671
|
}
|
|
28709
28672
|
});
|
|
28710
28673
|
|
|
28674
|
+
// packages/adapters/src/providers/shared/paths.ts
|
|
28675
|
+
import { getCleoTemplatesTildePath } from "@cleocode/paths";
|
|
28676
|
+
var init_paths2 = __esm({
|
|
28677
|
+
"packages/adapters/src/providers/shared/paths.ts"() {
|
|
28678
|
+
"use strict";
|
|
28679
|
+
}
|
|
28680
|
+
});
|
|
28681
|
+
|
|
28711
28682
|
// packages/adapters/src/providers/cursor/hooks.ts
|
|
28712
28683
|
var PROVIDER_ID2, CURSOR_EVENT_MAP, CursorHookProvider;
|
|
28713
28684
|
var init_hooks2 = __esm({
|
|
@@ -28864,16 +28835,13 @@ var init_hooks2 = __esm({
|
|
|
28864
28835
|
// packages/adapters/src/providers/cursor/install.ts
|
|
28865
28836
|
import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "node:fs";
|
|
28866
28837
|
import { join as join16 } from "node:path";
|
|
28867
|
-
|
|
28838
|
+
import { ensureProviderInstructionFile as ensureProviderInstructionFile2 } from "@cleocode/caamp";
|
|
28839
|
+
var CursorInstallProvider;
|
|
28868
28840
|
var init_install2 = __esm({
|
|
28869
28841
|
"packages/adapters/src/providers/cursor/install.ts"() {
|
|
28870
28842
|
"use strict";
|
|
28871
28843
|
init_hook_template_installer();
|
|
28872
28844
|
init_paths2();
|
|
28873
|
-
INSTRUCTION_REFERENCES3 = [
|
|
28874
|
-
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
28875
|
-
"@.cleo/memory-bridge.md"
|
|
28876
|
-
];
|
|
28877
28845
|
CursorInstallProvider = class {
|
|
28878
28846
|
/**
|
|
28879
28847
|
* Install CLEO into a Cursor project.
|
|
@@ -28886,7 +28854,9 @@ var init_install2 = __esm({
|
|
|
28886
28854
|
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
28887
28855
|
let instructionFileUpdated = false;
|
|
28888
28856
|
const details = {};
|
|
28889
|
-
|
|
28857
|
+
const instructionResult = await ensureProviderInstructionFile2("cursor", projectDir, {});
|
|
28858
|
+
const cursorFilesUpdated = this.updateInstructionFiles(projectDir);
|
|
28859
|
+
instructionFileUpdated = instructionResult.action !== "intact" || cursorFilesUpdated;
|
|
28890
28860
|
if (instructionFileUpdated) {
|
|
28891
28861
|
details.instructionFiles = this.getUpdatedFileList(projectDir);
|
|
28892
28862
|
}
|
|
@@ -28922,7 +28892,8 @@ var init_install2 = __esm({
|
|
|
28922
28892
|
if (existsSync12(rulesPath)) {
|
|
28923
28893
|
try {
|
|
28924
28894
|
const content = readFileSync8(rulesPath, "utf-8");
|
|
28925
|
-
|
|
28895
|
+
const injectionRef = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`;
|
|
28896
|
+
if (content.includes(injectionRef) || content.includes("@.cleo/memory-bridge.md")) {
|
|
28926
28897
|
return true;
|
|
28927
28898
|
}
|
|
28928
28899
|
} catch {
|
|
@@ -28933,11 +28904,13 @@ var init_install2 = __esm({
|
|
|
28933
28904
|
/**
|
|
28934
28905
|
* Ensure instruction files contain @-references to CLEO.
|
|
28935
28906
|
*
|
|
28936
|
-
*
|
|
28907
|
+
* Delegates the primary AGENTS.md write to CAAMP's canonical API (T1919) and
|
|
28908
|
+
* also updates cursor-specific MDC + legacy .cursorrules formats.
|
|
28937
28909
|
*
|
|
28938
28910
|
* @param projectDir - Project root directory
|
|
28939
28911
|
*/
|
|
28940
28912
|
async ensureInstructionReferences(projectDir) {
|
|
28913
|
+
await ensureProviderInstructionFile2("cursor", projectDir, {});
|
|
28941
28914
|
this.updateInstructionFiles(projectDir);
|
|
28942
28915
|
}
|
|
28943
28916
|
/**
|
|
@@ -28959,6 +28932,9 @@ var init_install2 = __esm({
|
|
|
28959
28932
|
}
|
|
28960
28933
|
/**
|
|
28961
28934
|
* Update legacy .cursorrules file with @-references.
|
|
28935
|
+
*
|
|
28936
|
+
* References are sourced from the CAAMP provider registry (T1919) rather than
|
|
28937
|
+
* a local constant, keeping this adapter in sync with the single source of truth.
|
|
28962
28938
|
* Only modifies the file if it already exists (does not create it).
|
|
28963
28939
|
*
|
|
28964
28940
|
* @returns true if the file was modified
|
|
@@ -28969,7 +28945,11 @@ var init_install2 = __esm({
|
|
|
28969
28945
|
return false;
|
|
28970
28946
|
}
|
|
28971
28947
|
let content = readFileSync8(rulesPath, "utf-8");
|
|
28972
|
-
const
|
|
28948
|
+
const cursorRefs = [
|
|
28949
|
+
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
28950
|
+
"@.cleo/memory-bridge.md"
|
|
28951
|
+
];
|
|
28952
|
+
const missingRefs = cursorRefs.filter((ref) => !content.includes(ref));
|
|
28973
28953
|
if (missingRefs.length === 0) {
|
|
28974
28954
|
return false;
|
|
28975
28955
|
}
|
|
@@ -28983,12 +28963,17 @@ var init_install2 = __esm({
|
|
|
28983
28963
|
*
|
|
28984
28964
|
* MDC (Markdown Component) format is Cursor's modern rule file format.
|
|
28985
28965
|
* Each .mdc file in .cursor/rules/ is loaded as a rule set.
|
|
28966
|
+
* References are sourced from the CAAMP provider registry (T1919).
|
|
28986
28967
|
*
|
|
28987
28968
|
* @returns true if the file was created or modified
|
|
28988
28969
|
*/
|
|
28989
28970
|
updateModernRules(projectDir) {
|
|
28990
28971
|
const rulesDir = join16(projectDir, ".cursor", "rules");
|
|
28991
28972
|
const mdcPath = join16(rulesDir, "cleo.mdc");
|
|
28973
|
+
const cursorRefs = [
|
|
28974
|
+
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
28975
|
+
"@.cleo/memory-bridge.md"
|
|
28976
|
+
];
|
|
28992
28977
|
const expectedContent = [
|
|
28993
28978
|
"---",
|
|
28994
28979
|
"description: CLEO task management protocol references",
|
|
@@ -28996,7 +28981,7 @@ var init_install2 = __esm({
|
|
|
28996
28981
|
"alwaysApply: true",
|
|
28997
28982
|
"---",
|
|
28998
28983
|
"",
|
|
28999
|
-
...
|
|
28984
|
+
...cursorRefs,
|
|
29000
28985
|
""
|
|
29001
28986
|
].join("\n");
|
|
29002
28987
|
if (existsSync12(mdcPath)) {
|
|
@@ -29412,13 +29397,13 @@ var init_hooks3 = __esm({
|
|
|
29412
29397
|
// packages/adapters/src/providers/opencode/install.ts
|
|
29413
29398
|
import { existsSync as existsSync18, mkdirSync as mkdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "node:fs";
|
|
29414
29399
|
import { join as join23 } from "node:path";
|
|
29415
|
-
var
|
|
29400
|
+
var INSTRUCTION_REFERENCES4, OpenCodeInstallProvider;
|
|
29416
29401
|
var init_install3 = __esm({
|
|
29417
29402
|
"packages/adapters/src/providers/opencode/install.ts"() {
|
|
29418
29403
|
"use strict";
|
|
29419
29404
|
init_hook_template_installer();
|
|
29420
29405
|
init_paths2();
|
|
29421
|
-
|
|
29406
|
+
INSTRUCTION_REFERENCES4 = [
|
|
29422
29407
|
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
29423
29408
|
"@.cleo/memory-bridge.md"
|
|
29424
29409
|
];
|
|
@@ -29466,7 +29451,7 @@ var init_install3 = __esm({
|
|
|
29466
29451
|
if (existsSync18(agentsMdPath)) {
|
|
29467
29452
|
try {
|
|
29468
29453
|
const content = readFileSync11(agentsMdPath, "utf-8");
|
|
29469
|
-
if (
|
|
29454
|
+
if (INSTRUCTION_REFERENCES4.some((ref) => content.includes(ref))) {
|
|
29470
29455
|
return true;
|
|
29471
29456
|
}
|
|
29472
29457
|
} catch {
|
|
@@ -29497,7 +29482,7 @@ var init_install3 = __esm({
|
|
|
29497
29482
|
content = readFileSync11(agentsMdPath, "utf-8");
|
|
29498
29483
|
existed = true;
|
|
29499
29484
|
}
|
|
29500
|
-
const missingRefs =
|
|
29485
|
+
const missingRefs = INSTRUCTION_REFERENCES4.filter((ref) => !content.includes(ref));
|
|
29501
29486
|
if (missingRefs.length === 0) {
|
|
29502
29487
|
return false;
|
|
29503
29488
|
}
|
|
@@ -30144,12 +30129,12 @@ function getPiAgentDir() {
|
|
|
30144
30129
|
}
|
|
30145
30130
|
return join26(homedir14(), ".pi", "agent");
|
|
30146
30131
|
}
|
|
30147
|
-
var
|
|
30132
|
+
var INSTRUCTION_REFERENCES5, PiInstallProvider;
|
|
30148
30133
|
var init_install4 = __esm({
|
|
30149
30134
|
"packages/adapters/src/providers/pi/install.ts"() {
|
|
30150
30135
|
"use strict";
|
|
30151
30136
|
init_paths2();
|
|
30152
|
-
|
|
30137
|
+
INSTRUCTION_REFERENCES5 = [
|
|
30153
30138
|
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
30154
30139
|
"@.cleo/memory-bridge.md"
|
|
30155
30140
|
];
|
|
@@ -30202,7 +30187,7 @@ var init_install4 = __esm({
|
|
|
30202
30187
|
if (existsSync20(agentsMdPath)) {
|
|
30203
30188
|
try {
|
|
30204
30189
|
const content = readFileSync12(agentsMdPath, "utf-8");
|
|
30205
|
-
if (
|
|
30190
|
+
if (INSTRUCTION_REFERENCES5.some((ref) => content.includes(ref))) {
|
|
30206
30191
|
return true;
|
|
30207
30192
|
}
|
|
30208
30193
|
} catch {
|
|
@@ -30212,7 +30197,7 @@ var init_install4 = __esm({
|
|
|
30212
30197
|
const globalPath = join26(getPiAgentDir(), "AGENTS.md");
|
|
30213
30198
|
if (existsSync20(globalPath)) {
|
|
30214
30199
|
const content = readFileSync12(globalPath, "utf-8");
|
|
30215
|
-
if (
|
|
30200
|
+
if (INSTRUCTION_REFERENCES5.some((ref) => content.includes(ref))) {
|
|
30216
30201
|
return true;
|
|
30217
30202
|
}
|
|
30218
30203
|
}
|
|
@@ -30245,7 +30230,7 @@ var init_install4 = __esm({
|
|
|
30245
30230
|
content = readFileSync12(filePath, "utf-8");
|
|
30246
30231
|
existed = true;
|
|
30247
30232
|
}
|
|
30248
|
-
const missingRefs =
|
|
30233
|
+
const missingRefs = INSTRUCTION_REFERENCES5.filter((ref) => !content.includes(ref));
|
|
30249
30234
|
if (missingRefs.length === 0) {
|
|
30250
30235
|
return false;
|
|
30251
30236
|
}
|
|
@@ -30901,7 +30886,7 @@ var CodexHookProvider = class {
|
|
|
30901
30886
|
init_paths2();
|
|
30902
30887
|
import { existsSync as existsSync10, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "node:fs";
|
|
30903
30888
|
import { join as join14 } from "node:path";
|
|
30904
|
-
var
|
|
30889
|
+
var INSTRUCTION_REFERENCES = [
|
|
30905
30890
|
`@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`,
|
|
30906
30891
|
"@.cleo/memory-bridge.md"
|
|
30907
30892
|
];
|
|
@@ -30948,7 +30933,7 @@ var CodexInstallProvider = class {
|
|
|
30948
30933
|
if (existsSync10(agentsMdPath)) {
|
|
30949
30934
|
try {
|
|
30950
30935
|
const content = readFileSync7(agentsMdPath, "utf-8");
|
|
30951
|
-
if (
|
|
30936
|
+
if (INSTRUCTION_REFERENCES.some((ref) => content.includes(ref))) {
|
|
30952
30937
|
return true;
|
|
30953
30938
|
}
|
|
30954
30939
|
} catch {
|
|
@@ -30981,7 +30966,7 @@ var CodexInstallProvider = class {
|
|
|
30981
30966
|
content = readFileSync7(agentsMdPath, "utf-8");
|
|
30982
30967
|
existed = true;
|
|
30983
30968
|
}
|
|
30984
|
-
const missingRefs =
|
|
30969
|
+
const missingRefs = INSTRUCTION_REFERENCES.filter((ref) => !content.includes(ref));
|
|
30985
30970
|
if (missingRefs.length === 0) {
|
|
30986
30971
|
return false;
|
|
30987
30972
|
}
|
|
@@ -31217,7 +31202,7 @@ var GeminiCliHookProvider = class {
|
|
|
31217
31202
|
// packages/adapters/src/providers/gemini-cli/install.ts
|
|
31218
31203
|
import { existsSync as existsSync14, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
31219
31204
|
import { join as join19 } from "node:path";
|
|
31220
|
-
var
|
|
31205
|
+
var INSTRUCTION_REFERENCES2 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
|
|
31221
31206
|
var GeminiCliInstallProvider = class {
|
|
31222
31207
|
/**
|
|
31223
31208
|
* Install CLEO into a Gemini CLI environment.
|
|
@@ -31261,7 +31246,7 @@ var GeminiCliInstallProvider = class {
|
|
|
31261
31246
|
if (existsSync14(agentsMdPath)) {
|
|
31262
31247
|
try {
|
|
31263
31248
|
const content = readFileSync9(agentsMdPath, "utf-8");
|
|
31264
|
-
if (
|
|
31249
|
+
if (INSTRUCTION_REFERENCES2.some((ref) => content.includes(ref))) {
|
|
31265
31250
|
return true;
|
|
31266
31251
|
}
|
|
31267
31252
|
} catch {
|
|
@@ -31294,7 +31279,7 @@ var GeminiCliInstallProvider = class {
|
|
|
31294
31279
|
content = readFileSync9(agentsMdPath, "utf-8");
|
|
31295
31280
|
existed = true;
|
|
31296
31281
|
}
|
|
31297
|
-
const missingRefs =
|
|
31282
|
+
const missingRefs = INSTRUCTION_REFERENCES2.filter((ref) => !content.includes(ref));
|
|
31298
31283
|
if (missingRefs.length === 0) {
|
|
31299
31284
|
return false;
|
|
31300
31285
|
}
|
|
@@ -31509,7 +31494,7 @@ var KimiHookProvider = class {
|
|
|
31509
31494
|
// packages/adapters/src/providers/kimi/install.ts
|
|
31510
31495
|
import { existsSync as existsSync16, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "node:fs";
|
|
31511
31496
|
import { join as join21 } from "node:path";
|
|
31512
|
-
var
|
|
31497
|
+
var INSTRUCTION_REFERENCES3 = ["@~/.cleo/templates/CLEO-INJECTION.md", "@.cleo/memory-bridge.md"];
|
|
31513
31498
|
var KimiInstallProvider = class {
|
|
31514
31499
|
/**
|
|
31515
31500
|
* Install CLEO into a Kimi environment.
|
|
@@ -31553,7 +31538,7 @@ var KimiInstallProvider = class {
|
|
|
31553
31538
|
if (existsSync16(agentsMdPath)) {
|
|
31554
31539
|
try {
|
|
31555
31540
|
const content = readFileSync10(agentsMdPath, "utf-8");
|
|
31556
|
-
if (
|
|
31541
|
+
if (INSTRUCTION_REFERENCES3.some((ref) => content.includes(ref))) {
|
|
31557
31542
|
return true;
|
|
31558
31543
|
}
|
|
31559
31544
|
} catch {
|
|
@@ -31586,7 +31571,7 @@ var KimiInstallProvider = class {
|
|
|
31586
31571
|
content = readFileSync10(agentsMdPath, "utf-8");
|
|
31587
31572
|
existed = true;
|
|
31588
31573
|
}
|
|
31589
|
-
const missingRefs =
|
|
31574
|
+
const missingRefs = INSTRUCTION_REFERENCES3.filter((ref) => !content.includes(ref));
|
|
31590
31575
|
if (missingRefs.length === 0) {
|
|
31591
31576
|
return false;
|
|
31592
31577
|
}
|