@semiont/inference 0.5.4 → 0.5.5
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.d.ts +94 -6
- package/package.json +5 -3
- package/dist/factory.d.ts +0 -12
- package/dist/factory.d.ts.map +0 -1
- package/dist/implementations/anthropic.d.ts +0 -12
- package/dist/implementations/anthropic.d.ts.map +0 -1
- package/dist/implementations/mock.d.ts +0 -20
- package/dist/implementations/mock.d.ts.map +0 -1
- package/dist/implementations/ollama.d.ts +0 -12
- package/dist/implementations/ollama.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/interface.d.ts +0 -41
- package/dist/interface.d.ts.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { Logger } from '@semiont/core';
|
|
2
|
+
|
|
3
|
+
interface InferenceResponse {
|
|
4
|
+
text: string;
|
|
5
|
+
stopReason: 'end_turn' | 'max_tokens' | 'stop_sequence' | string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Per-call options. Drift here when output discipline matters more than
|
|
9
|
+
* raw model behavior — e.g. forcing valid JSON for entity extraction
|
|
10
|
+
* where a parse failure in the consumer is silent and useless.
|
|
11
|
+
*/
|
|
12
|
+
interface InferenceOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Constrain output to a parseable JSON array. Every implementation
|
|
15
|
+
* MUST satisfy this contract using whatever mechanism its provider
|
|
16
|
+
* supports — Ollama uses grammar-constrained sampling
|
|
17
|
+
* (`format: "json"`); Anthropic uses assistant-turn prefill (`[`)
|
|
18
|
+
* and re-attaches the prefix on return. Callers can rely on the
|
|
19
|
+
* returned `text` being a top-level JSON array regardless of
|
|
20
|
+
* provider.
|
|
21
|
+
*
|
|
22
|
+
* Current callers all expect arrays (entity extraction, motivation
|
|
23
|
+
* detection). If an object-emitting caller appears, this option
|
|
24
|
+
* grows a `root: 'array' | 'object'` field; do not silently drop
|
|
25
|
+
* the constraint.
|
|
26
|
+
*/
|
|
27
|
+
format?: 'json';
|
|
28
|
+
}
|
|
29
|
+
interface InferenceClient {
|
|
30
|
+
/** Provider type identifier (e.g. 'anthropic', 'ollama') */
|
|
31
|
+
readonly type: string;
|
|
32
|
+
/** Model identifier used for generation (e.g. 'claude-opus-4-6', 'llama3') */
|
|
33
|
+
readonly modelId: string;
|
|
34
|
+
/**
|
|
35
|
+
* Generate text from a prompt (simple interface)
|
|
36
|
+
*/
|
|
37
|
+
generateText(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Generate text with detailed response information
|
|
40
|
+
*/
|
|
41
|
+
generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<InferenceResponse>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type InferenceClientType = 'anthropic' | 'ollama';
|
|
45
|
+
interface InferenceClientConfig {
|
|
46
|
+
type: InferenceClientType;
|
|
47
|
+
apiKey?: string;
|
|
48
|
+
model: string;
|
|
49
|
+
endpoint?: string;
|
|
50
|
+
baseURL?: string;
|
|
51
|
+
}
|
|
52
|
+
declare function createInferenceClient(config: InferenceClientConfig, logger?: Logger): InferenceClient;
|
|
53
|
+
|
|
54
|
+
declare class AnthropicInferenceClient implements InferenceClient {
|
|
55
|
+
readonly type: "anthropic";
|
|
56
|
+
readonly modelId: string;
|
|
57
|
+
private client;
|
|
58
|
+
private logger?;
|
|
59
|
+
constructor(apiKey: string, model: string, baseURL?: string, logger?: Logger);
|
|
60
|
+
generateText(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<string>;
|
|
61
|
+
generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<InferenceResponse>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare class OllamaInferenceClient implements InferenceClient {
|
|
65
|
+
readonly type: "ollama";
|
|
66
|
+
readonly modelId: string;
|
|
67
|
+
private baseURL;
|
|
68
|
+
private logger?;
|
|
69
|
+
constructor(model: string, baseURL?: string, logger?: Logger);
|
|
70
|
+
generateText(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<string>;
|
|
71
|
+
generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<InferenceResponse>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
declare class MockInferenceClient implements InferenceClient {
|
|
75
|
+
readonly type: "mock";
|
|
76
|
+
readonly modelId: "mock-model";
|
|
77
|
+
private responses;
|
|
78
|
+
private responseIndex;
|
|
79
|
+
private stopReasons;
|
|
80
|
+
calls: Array<{
|
|
81
|
+
prompt: string;
|
|
82
|
+
maxTokens: number;
|
|
83
|
+
temperature: number;
|
|
84
|
+
options?: InferenceOptions;
|
|
85
|
+
}>;
|
|
86
|
+
constructor(responses?: string[], stopReasons?: string[]);
|
|
87
|
+
generateText(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<string>;
|
|
88
|
+
generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<InferenceResponse>;
|
|
89
|
+
reset(): void;
|
|
90
|
+
setResponses(responses: string[], stopReasons?: string[]): void;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { AnthropicInferenceClient, MockInferenceClient, OllamaInferenceClient, createInferenceClient };
|
|
94
|
+
export type { InferenceClient, InferenceClientConfig, InferenceClientType, InferenceOptions, InferenceResponse };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semiont/inference",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI inference capabilities for entity extraction, text generation, and resource creation",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"README.md"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "npm run typecheck && tsup && tsc -p tsconfig.build.json",
|
|
19
|
+
"build": "npm run typecheck && tsup && tsc -p tsconfig.build.json && rollup -c rollup.dts.config.mjs && rm -rf dist-types",
|
|
20
20
|
"typecheck": "tsc --noEmit",
|
|
21
|
-
"clean": "rm -rf dist",
|
|
21
|
+
"clean": "rm -rf dist dist-types",
|
|
22
22
|
"test": "vitest run",
|
|
23
23
|
"test:watch": "vitest",
|
|
24
24
|
"test:coverage": "vitest run --coverage"
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@vitest/coverage-v8": "^4.1.0",
|
|
34
|
+
"rollup": "^4.60.3",
|
|
35
|
+
"rollup-plugin-dts": "^6.4.1",
|
|
34
36
|
"tsup": "^8.0.1",
|
|
35
37
|
"typescript": "^6.0.2"
|
|
36
38
|
},
|
package/dist/factory.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Logger } from '@semiont/core';
|
|
2
|
-
import { InferenceClient } from './interface.js';
|
|
3
|
-
export type InferenceClientType = 'anthropic' | 'ollama';
|
|
4
|
-
export interface InferenceClientConfig {
|
|
5
|
-
type: InferenceClientType;
|
|
6
|
-
apiKey?: string;
|
|
7
|
-
model: string;
|
|
8
|
-
endpoint?: string;
|
|
9
|
-
baseURL?: string;
|
|
10
|
-
}
|
|
11
|
-
export declare function createInferenceClient(config: InferenceClientConfig, logger?: Logger): InferenceClient;
|
|
12
|
-
//# sourceMappingURL=factory.d.ts.map
|
package/dist/factory.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIjD,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEzD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,eAAe,CAyBrG"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Logger } from '@semiont/core';
|
|
2
|
-
import { InferenceClient, InferenceOptions, InferenceResponse } from '../interface.js';
|
|
3
|
-
export declare class AnthropicInferenceClient implements InferenceClient {
|
|
4
|
-
readonly type: "anthropic";
|
|
5
|
-
readonly modelId: string;
|
|
6
|
-
private client;
|
|
7
|
-
private logger?;
|
|
8
|
-
constructor(apiKey: string, model: string, baseURL?: string, logger?: Logger);
|
|
9
|
-
generateText(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<string>;
|
|
10
|
-
generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<InferenceResponse>;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/implementations/anthropic.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEvF,qBAAa,wBAAyB,YAAW,eAAe;IAC9D,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAU;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAStE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjH,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAqG/I"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { InferenceClient, InferenceOptions, InferenceResponse } from '../interface.js';
|
|
2
|
-
export declare class MockInferenceClient implements InferenceClient {
|
|
3
|
-
readonly type: "mock";
|
|
4
|
-
readonly modelId: "mock-model";
|
|
5
|
-
private responses;
|
|
6
|
-
private responseIndex;
|
|
7
|
-
private stopReasons;
|
|
8
|
-
calls: Array<{
|
|
9
|
-
prompt: string;
|
|
10
|
-
maxTokens: number;
|
|
11
|
-
temperature: number;
|
|
12
|
-
options?: InferenceOptions;
|
|
13
|
-
}>;
|
|
14
|
-
constructor(responses?: string[], stopReasons?: string[]);
|
|
15
|
-
generateText(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<string>;
|
|
16
|
-
generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<InferenceResponse>;
|
|
17
|
-
reset(): void;
|
|
18
|
-
setResponses(responses: string[], stopReasons?: string[]): void;
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=mock.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/implementations/mock.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEvF,qBAAa,mBAAoB,YAAW,eAAe;IACzD,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAU;IAChC,QAAQ,CAAC,OAAO,EAAG,YAAY,CAAU;IACzC,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,WAAW,CAAgB;IAC5B,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAM;gBAErG,SAAS,GAAE,MAAM,EAAsB,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE;IAKrE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjH,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAc9I,KAAK,IAAI,IAAI;IAKb,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;CAKhE"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Logger } from '@semiont/core';
|
|
2
|
-
import { InferenceClient, InferenceOptions, InferenceResponse } from '../interface.js';
|
|
3
|
-
export declare class OllamaInferenceClient implements InferenceClient {
|
|
4
|
-
readonly type: "ollama";
|
|
5
|
-
readonly modelId: string;
|
|
6
|
-
private baseURL;
|
|
7
|
-
private logger?;
|
|
8
|
-
constructor(model: string, baseURL?: string, logger?: Logger);
|
|
9
|
-
generateText(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<string>;
|
|
10
|
-
generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<InferenceResponse>;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=ollama.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/implementations/ollama.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAYvF,qBAAa,qBAAsB,YAAW,eAAe;IAC3D,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAMtD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjH,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA0G/I"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACzB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAClG,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/interface.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export interface InferenceResponse {
|
|
2
|
-
text: string;
|
|
3
|
-
stopReason: 'end_turn' | 'max_tokens' | 'stop_sequence' | string;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Per-call options. Drift here when output discipline matters more than
|
|
7
|
-
* raw model behavior — e.g. forcing valid JSON for entity extraction
|
|
8
|
-
* where a parse failure in the consumer is silent and useless.
|
|
9
|
-
*/
|
|
10
|
-
export interface InferenceOptions {
|
|
11
|
-
/**
|
|
12
|
-
* Constrain output to a parseable JSON array. Every implementation
|
|
13
|
-
* MUST satisfy this contract using whatever mechanism its provider
|
|
14
|
-
* supports — Ollama uses grammar-constrained sampling
|
|
15
|
-
* (`format: "json"`); Anthropic uses assistant-turn prefill (`[`)
|
|
16
|
-
* and re-attaches the prefix on return. Callers can rely on the
|
|
17
|
-
* returned `text` being a top-level JSON array regardless of
|
|
18
|
-
* provider.
|
|
19
|
-
*
|
|
20
|
-
* Current callers all expect arrays (entity extraction, motivation
|
|
21
|
-
* detection). If an object-emitting caller appears, this option
|
|
22
|
-
* grows a `root: 'array' | 'object'` field; do not silently drop
|
|
23
|
-
* the constraint.
|
|
24
|
-
*/
|
|
25
|
-
format?: 'json';
|
|
26
|
-
}
|
|
27
|
-
export interface InferenceClient {
|
|
28
|
-
/** Provider type identifier (e.g. 'anthropic', 'ollama') */
|
|
29
|
-
readonly type: string;
|
|
30
|
-
/** Model identifier used for generation (e.g. 'claude-opus-4-6', 'llama3') */
|
|
31
|
-
readonly modelId: string;
|
|
32
|
-
/**
|
|
33
|
-
* Generate text from a prompt (simple interface)
|
|
34
|
-
*/
|
|
35
|
-
generateText(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<string>;
|
|
36
|
-
/**
|
|
37
|
-
* Generate text with detailed response information
|
|
38
|
-
*/
|
|
39
|
-
generateTextWithMetadata(prompt: string, maxTokens: number, temperature: number, options?: InferenceOptions): Promise<InferenceResponse>;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=interface.d.ts.map
|
package/dist/interface.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src/interface.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,UAAU,GAAG,YAAY,GAAG,eAAe,GAAG,MAAM,CAAC;CAClE;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElH;;OAEG;IACH,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC1I"}
|