@arizeai/phoenix-client 2.1.0 → 2.2.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.
- package/dist/esm/__generated__/api/v1.d.ts +687 -16
- package/dist/esm/__generated__/api/v1.d.ts.map +1 -1
- package/dist/esm/prompts/constants.d.ts.map +1 -1
- package/dist/esm/prompts/constants.js +4 -0
- package/dist/esm/prompts/constants.js.map +1 -1
- package/dist/esm/prompts/createPrompt.d.ts +15 -3
- package/dist/esm/prompts/createPrompt.d.ts.map +1 -1
- package/dist/esm/prompts/createPrompt.js +48 -0
- package/dist/esm/prompts/createPrompt.js.map +1 -1
- package/dist/esm/spans/getSpanAnnotations.d.ts +78 -0
- package/dist/esm/spans/getSpanAnnotations.d.ts.map +1 -0
- package/dist/esm/spans/getSpanAnnotations.js +83 -0
- package/dist/esm/spans/getSpanAnnotations.js.map +1 -0
- package/dist/esm/spans/getSpans.d.ts +78 -0
- package/dist/esm/spans/getSpans.d.ts.map +1 -0
- package/dist/esm/spans/getSpans.js +85 -0
- package/dist/esm/spans/getSpans.js.map +1 -0
- package/dist/esm/spans/index.d.ts +2 -0
- package/dist/esm/spans/index.d.ts.map +1 -1
- package/dist/esm/spans/index.js +2 -0
- package/dist/esm/spans/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types/projects.d.ts +10 -0
- package/dist/esm/types/projects.d.ts.map +1 -0
- package/dist/esm/types/projects.js +2 -0
- package/dist/esm/types/projects.js.map +1 -0
- package/dist/esm/types/prompts.d.ts +17 -1
- package/dist/esm/types/prompts.d.ts.map +1 -1
- package/dist/esm/utils/formatPromptMessages.d.ts.map +1 -1
- package/dist/esm/utils/getPromptBySelector.d.ts +1 -1
- package/dist/esm/utils/getPromptBySelector.d.ts.map +1 -1
- package/dist/src/__generated__/api/v1.d.ts +687 -16
- package/dist/src/__generated__/api/v1.d.ts.map +1 -1
- package/dist/src/prompts/constants.d.ts.map +1 -1
- package/dist/src/prompts/constants.js +4 -0
- package/dist/src/prompts/constants.js.map +1 -1
- package/dist/src/prompts/createPrompt.d.ts +15 -3
- package/dist/src/prompts/createPrompt.d.ts.map +1 -1
- package/dist/src/prompts/createPrompt.js +48 -0
- package/dist/src/prompts/createPrompt.js.map +1 -1
- package/dist/src/spans/getSpanAnnotations.d.ts +78 -0
- package/dist/src/spans/getSpanAnnotations.d.ts.map +1 -0
- package/dist/src/spans/getSpanAnnotations.js +98 -0
- package/dist/src/spans/getSpanAnnotations.js.map +1 -0
- package/dist/src/spans/getSpans.d.ts +78 -0
- package/dist/src/spans/getSpans.d.ts.map +1 -0
- package/dist/src/spans/getSpans.js +100 -0
- package/dist/src/spans/getSpans.js.map +1 -0
- package/dist/src/spans/index.d.ts +2 -0
- package/dist/src/spans/index.d.ts.map +1 -1
- package/dist/src/spans/index.js +2 -0
- package/dist/src/spans/index.js.map +1 -1
- package/dist/src/types/projects.d.ts +10 -0
- package/dist/src/types/projects.d.ts.map +1 -0
- package/dist/src/types/projects.js +3 -0
- package/dist/src/types/projects.js.map +1 -0
- package/dist/src/types/prompts.d.ts +17 -1
- package/dist/src/types/prompts.d.ts.map +1 -1
- package/dist/src/utils/formatPromptMessages.d.ts.map +1 -1
- package/dist/src/utils/getPromptBySelector.d.ts +1 -1
- package/dist/src/utils/getPromptBySelector.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/__generated__/api/v1.ts +687 -16
- package/src/prompts/constants.ts +4 -0
- package/src/prompts/createPrompt.ts +72 -2
- package/src/spans/getSpanAnnotations.ts +131 -0
- package/src/spans/getSpans.ts +127 -0
- package/src/spans/index.ts +2 -0
- package/src/types/projects.ts +5 -0
- package/src/types/prompts.ts +29 -1
package/src/prompts/constants.ts
CHANGED
|
@@ -8,6 +8,10 @@ import {
|
|
|
8
8
|
AzureOpenAIInvocationParameters,
|
|
9
9
|
AnthropicInvocationParameters,
|
|
10
10
|
GoogleInvocationParameters,
|
|
11
|
+
DeepSeekInvocationParameters,
|
|
12
|
+
XAIInvocationParameters,
|
|
13
|
+
OllamaInvocationParameters,
|
|
14
|
+
AwsInvocationParameters,
|
|
11
15
|
PromptChatMessage,
|
|
12
16
|
} from "../types/prompts";
|
|
13
17
|
import { assertUnreachable } from "../utils/assertUnreachable";
|
|
@@ -104,7 +108,22 @@ interface GooglePromptVersionInput extends PromptVersionInputBase {
|
|
|
104
108
|
|
|
105
109
|
interface DeepSeekPromptVersionInput extends PromptVersionInputBase {
|
|
106
110
|
modelProvider: "DEEPSEEK";
|
|
107
|
-
invocationParameters?:
|
|
111
|
+
invocationParameters?: DeepSeekInvocationParameters;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface XAIPromptVersionInput extends PromptVersionInputBase {
|
|
115
|
+
modelProvider: "XAI";
|
|
116
|
+
invocationParameters?: XAIInvocationParameters;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
interface OllamaPromptVersionInput extends PromptVersionInputBase {
|
|
120
|
+
modelProvider: "OLLAMA";
|
|
121
|
+
invocationParameters?: OllamaInvocationParameters;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
interface AwsPromptVersionInput extends PromptVersionInputBase {
|
|
125
|
+
modelProvider: "AWS";
|
|
126
|
+
invocationParameters?: AwsInvocationParameters;
|
|
108
127
|
}
|
|
109
128
|
|
|
110
129
|
type PromptVersionInput =
|
|
@@ -112,7 +131,10 @@ type PromptVersionInput =
|
|
|
112
131
|
| AzureOpenAIPromptVersionInput
|
|
113
132
|
| AnthropicPromptVersionInput
|
|
114
133
|
| GooglePromptVersionInput
|
|
115
|
-
| DeepSeekPromptVersionInput
|
|
134
|
+
| DeepSeekPromptVersionInput
|
|
135
|
+
| XAIPromptVersionInput
|
|
136
|
+
| OllamaPromptVersionInput
|
|
137
|
+
| AwsPromptVersionInput;
|
|
116
138
|
|
|
117
139
|
/**
|
|
118
140
|
* A helper function to construct a prompt version declaratively.
|
|
@@ -212,6 +234,54 @@ export function promptVersion(params: PromptVersionInput): PromptVersionData {
|
|
|
212
234
|
deepseek: invocation_parameters ?? {},
|
|
213
235
|
},
|
|
214
236
|
};
|
|
237
|
+
case "XAI":
|
|
238
|
+
return {
|
|
239
|
+
description,
|
|
240
|
+
model_provider,
|
|
241
|
+
model_name,
|
|
242
|
+
template_type: "CHAT",
|
|
243
|
+
template_format,
|
|
244
|
+
template: {
|
|
245
|
+
type: "chat",
|
|
246
|
+
messages: templateMessages,
|
|
247
|
+
},
|
|
248
|
+
invocation_parameters: {
|
|
249
|
+
type: "xai",
|
|
250
|
+
xai: invocation_parameters ?? {},
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
case "OLLAMA":
|
|
254
|
+
return {
|
|
255
|
+
description,
|
|
256
|
+
model_provider,
|
|
257
|
+
model_name,
|
|
258
|
+
template_type: "CHAT",
|
|
259
|
+
template_format,
|
|
260
|
+
template: {
|
|
261
|
+
type: "chat",
|
|
262
|
+
messages: templateMessages,
|
|
263
|
+
},
|
|
264
|
+
invocation_parameters: {
|
|
265
|
+
type: "ollama",
|
|
266
|
+
ollama: invocation_parameters ?? {},
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
case "AWS":
|
|
270
|
+
return {
|
|
271
|
+
description,
|
|
272
|
+
model_provider,
|
|
273
|
+
model_name,
|
|
274
|
+
template_type: "CHAT",
|
|
275
|
+
template_format,
|
|
276
|
+
template: {
|
|
277
|
+
type: "chat",
|
|
278
|
+
messages: templateMessages,
|
|
279
|
+
},
|
|
280
|
+
invocation_parameters: {
|
|
281
|
+
type: "aws",
|
|
282
|
+
aws: invocation_parameters ?? {},
|
|
283
|
+
},
|
|
284
|
+
};
|
|
215
285
|
default:
|
|
216
286
|
assertUnreachable(model_provider);
|
|
217
287
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createClient } from "../client";
|
|
2
|
+
import { ClientFn } from "../types/core";
|
|
3
|
+
import { operations } from "../__generated__/api/v1";
|
|
4
|
+
import { ProjectSelector } from "../types/projects";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Parameters to get span annotations from a project using auto-generated types
|
|
8
|
+
*/
|
|
9
|
+
interface GetSpanAnnotationsParams extends ClientFn {
|
|
10
|
+
/** The project to get span annotations from */
|
|
11
|
+
project: ProjectSelector;
|
|
12
|
+
/** One or more span IDs to fetch annotations for */
|
|
13
|
+
spanIds: string[];
|
|
14
|
+
/** Optional list of annotation names to include. If provided, only annotations with these names will be returned. 'note' annotations are excluded by default unless explicitly included in this list. */
|
|
15
|
+
includeAnnotationNames?: string[];
|
|
16
|
+
/** Optional list of annotation names to exclude from results. */
|
|
17
|
+
excludeAnnotationNames?: string[];
|
|
18
|
+
/** Pagination cursor */
|
|
19
|
+
cursor?: string | null;
|
|
20
|
+
/** Maximum number of annotations to return */
|
|
21
|
+
limit?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type GetSpanAnnotationsResponse =
|
|
25
|
+
operations["listSpanAnnotationsBySpanIds"]["responses"]["200"];
|
|
26
|
+
|
|
27
|
+
export type GetSpanAnnotationsResult = {
|
|
28
|
+
annotations: GetSpanAnnotationsResponse["content"]["application/json"]["data"];
|
|
29
|
+
nextCursor: GetSpanAnnotationsResponse["content"]["application/json"]["next_cursor"];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get span annotations for a list of span IDs.
|
|
34
|
+
*
|
|
35
|
+
* This method allows you to retrieve annotations for specific spans within a project.
|
|
36
|
+
* You can filter annotations by name and support cursor-based pagination.
|
|
37
|
+
*
|
|
38
|
+
* @experimental this function is experimental and may change in the future
|
|
39
|
+
*
|
|
40
|
+
* @param params - The parameters to get span annotations
|
|
41
|
+
* @returns A paginated response containing annotations and optional next cursor
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* // Get annotations for specific spans
|
|
46
|
+
* const result = await getSpanAnnotations({
|
|
47
|
+
* client,
|
|
48
|
+
* project: { projectName: "my-project" },
|
|
49
|
+
* spanIds: ["span1", "span2", "span3"],
|
|
50
|
+
* limit: 50
|
|
51
|
+
* });
|
|
52
|
+
*
|
|
53
|
+
* // Get specific annotation types
|
|
54
|
+
* const result = await getSpanAnnotations({
|
|
55
|
+
* client,
|
|
56
|
+
* project: { projectName: "my-project" },
|
|
57
|
+
* spanIds: ["span1"],
|
|
58
|
+
* includeAnnotationNames: ["quality_score", "sentiment"],
|
|
59
|
+
* limit: 100
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* // Paginate through results
|
|
63
|
+
* let cursor: string | undefined;
|
|
64
|
+
* do {
|
|
65
|
+
* const result = await getSpanAnnotations({
|
|
66
|
+
* client,
|
|
67
|
+
* project: { projectName: "my-project" },
|
|
68
|
+
* spanIds: ["span1"],
|
|
69
|
+
* cursor,
|
|
70
|
+
* limit: 100
|
|
71
|
+
* });
|
|
72
|
+
*
|
|
73
|
+
* // Process annotations
|
|
74
|
+
* result.annotations.forEach(annotation => {
|
|
75
|
+
* console.log(`Annotation: ${annotation.name}, Label: ${annotation.result.label}`);
|
|
76
|
+
* });
|
|
77
|
+
*
|
|
78
|
+
* cursor = result.nextCursor || undefined;
|
|
79
|
+
* } while (cursor);
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export async function getSpanAnnotations({
|
|
83
|
+
client: _client,
|
|
84
|
+
project,
|
|
85
|
+
spanIds,
|
|
86
|
+
includeAnnotationNames,
|
|
87
|
+
excludeAnnotationNames,
|
|
88
|
+
cursor,
|
|
89
|
+
limit = 100,
|
|
90
|
+
}: GetSpanAnnotationsParams): Promise<GetSpanAnnotationsResult> {
|
|
91
|
+
const client = _client ?? createClient();
|
|
92
|
+
const projectIdentifier =
|
|
93
|
+
"projectId" in project ? project.projectId : project.projectName;
|
|
94
|
+
|
|
95
|
+
const params: NonNullable<
|
|
96
|
+
operations["listSpanAnnotationsBySpanIds"]["parameters"]["query"]
|
|
97
|
+
> = {
|
|
98
|
+
span_ids: spanIds,
|
|
99
|
+
limit,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
if (cursor) {
|
|
103
|
+
params.cursor = cursor;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (includeAnnotationNames !== undefined) {
|
|
107
|
+
params.include_annotation_names = includeAnnotationNames;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (excludeAnnotationNames !== undefined) {
|
|
111
|
+
params.exclude_annotation_names = excludeAnnotationNames;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const { data, error } = await client.GET(
|
|
115
|
+
"/v1/projects/{project_identifier}/span_annotations",
|
|
116
|
+
{
|
|
117
|
+
params: {
|
|
118
|
+
path: {
|
|
119
|
+
project_identifier: projectIdentifier,
|
|
120
|
+
},
|
|
121
|
+
query: params,
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
if (error) throw error;
|
|
127
|
+
return {
|
|
128
|
+
annotations: data?.data ?? [],
|
|
129
|
+
nextCursor: data?.next_cursor ?? null,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createClient } from "../client";
|
|
2
|
+
import { ClientFn } from "../types/core";
|
|
3
|
+
import { operations } from "../__generated__/api/v1";
|
|
4
|
+
import { ProjectSelector } from "../types/projects";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Parameters to get spans from a project using auto-generated types
|
|
8
|
+
*/
|
|
9
|
+
interface GetSpansParams extends ClientFn {
|
|
10
|
+
/** The project to get spans from */
|
|
11
|
+
project: ProjectSelector;
|
|
12
|
+
/** Inclusive lower bound time. Must be a valid ISO 8601 string or Date object. */
|
|
13
|
+
startTime?: Date | string | null;
|
|
14
|
+
/** Exclusive upper bound time. Must be a valid ISO 8601 string or Date object. */
|
|
15
|
+
endTime?: Date | string | null;
|
|
16
|
+
/** Pagination cursor (Span Global ID) */
|
|
17
|
+
cursor?: string | null;
|
|
18
|
+
/** Maximum number of spans to return */
|
|
19
|
+
limit?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type GetSpansResponse = operations["getSpans"]["responses"]["200"];
|
|
23
|
+
|
|
24
|
+
export type GetSpansResult = {
|
|
25
|
+
spans: GetSpansResponse["content"]["application/json"]["data"];
|
|
26
|
+
nextCursor: GetSpansResponse["content"]["application/json"]["next_cursor"];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get spans from a project with filtering criteria.
|
|
31
|
+
*
|
|
32
|
+
* This method allows you to search for spans within a project using various filters
|
|
33
|
+
* such as time range and supports cursor-based pagination.
|
|
34
|
+
* The spans are returned in Phoenix's standard format with human-readable timestamps
|
|
35
|
+
* and simplified attribute structures.
|
|
36
|
+
*
|
|
37
|
+
* @experimental this function is experimental and may change in the future
|
|
38
|
+
*
|
|
39
|
+
* @param params - The parameters to search for spans
|
|
40
|
+
* @returns A paginated response containing spans and optional next cursor
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* // Get recent spans from a project
|
|
45
|
+
* const result = await getSpans({
|
|
46
|
+
* client,
|
|
47
|
+
* project: { projectName: "my-project" },
|
|
48
|
+
* limit: 50
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* // Get spans in a time range
|
|
52
|
+
|
|
53
|
+
* const result = await getSpans({
|
|
54
|
+
* client,
|
|
55
|
+
* project: { projectName: "my-project" },
|
|
56
|
+
* startTime: new Date("2024-01-01"),
|
|
57
|
+
* endTime: new Date("2024-01-02"),
|
|
58
|
+
* limit: 100
|
|
59
|
+
* });
|
|
60
|
+
|
|
61
|
+
*
|
|
62
|
+
* // Paginate through results
|
|
63
|
+
* let cursor: string | undefined;
|
|
64
|
+
* do {
|
|
65
|
+
* const result = await getSpans({
|
|
66
|
+
* client,
|
|
67
|
+
* project: { projectName: "my-project" },
|
|
68
|
+
* cursor,
|
|
69
|
+
* limit: 100
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* // Process spans
|
|
73
|
+
* result.spans.forEach(span => {
|
|
74
|
+
* console.log(`Span: ${span.name}, Trace: ${span.context.trace_id}`);
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* cursor = result.nextCursor || undefined;
|
|
78
|
+
* } while (cursor);
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export async function getSpans({
|
|
82
|
+
client: _client,
|
|
83
|
+
project,
|
|
84
|
+
cursor,
|
|
85
|
+
limit = 100,
|
|
86
|
+
startTime,
|
|
87
|
+
endTime,
|
|
88
|
+
}: GetSpansParams): Promise<GetSpansResult> {
|
|
89
|
+
const client = _client ?? createClient();
|
|
90
|
+
const projectIdentifier =
|
|
91
|
+
"projectId" in project ? project.projectId : project.projectName;
|
|
92
|
+
|
|
93
|
+
const params: NonNullable<operations["getSpans"]["parameters"]["query"]> = {
|
|
94
|
+
limit,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
if (cursor) {
|
|
98
|
+
params.cursor = cursor;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (startTime) {
|
|
102
|
+
params.start_time =
|
|
103
|
+
startTime instanceof Date ? startTime.toISOString() : startTime;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (endTime) {
|
|
107
|
+
params.end_time = endTime instanceof Date ? endTime.toISOString() : endTime;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const { data, error } = await client.GET(
|
|
111
|
+
"/v1/projects/{project_identifier}/spans",
|
|
112
|
+
{
|
|
113
|
+
params: {
|
|
114
|
+
path: {
|
|
115
|
+
project_identifier: projectIdentifier,
|
|
116
|
+
},
|
|
117
|
+
query: params,
|
|
118
|
+
},
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (error) throw error;
|
|
123
|
+
return {
|
|
124
|
+
spans: data?.data ?? [],
|
|
125
|
+
nextCursor: data?.next_cursor ?? null,
|
|
126
|
+
};
|
|
127
|
+
}
|
package/src/spans/index.ts
CHANGED
package/src/types/prompts.ts
CHANGED
|
@@ -7,7 +7,11 @@ export type PromptModelProvider =
|
|
|
7
7
|
| "OPENAI"
|
|
8
8
|
| "AZURE_OPENAI"
|
|
9
9
|
| "ANTHROPIC"
|
|
10
|
-
| "GOOGLE"
|
|
10
|
+
| "GOOGLE"
|
|
11
|
+
| "DEEPSEEK"
|
|
12
|
+
| "XAI"
|
|
13
|
+
| "OLLAMA"
|
|
14
|
+
| "AWS";
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
17
|
* Supported prompt provider SDKs
|
|
@@ -107,6 +111,30 @@ export type AnthropicInvocationParameters =
|
|
|
107
111
|
export type GoogleInvocationParameters =
|
|
108
112
|
components["schemas"]["PromptGoogleInvocationParametersContent"];
|
|
109
113
|
|
|
114
|
+
/**
|
|
115
|
+
* The invocation parameters for a prompt version for DeepSeek.
|
|
116
|
+
*/
|
|
117
|
+
export type DeepSeekInvocationParameters =
|
|
118
|
+
components["schemas"]["PromptDeepSeekInvocationParametersContent"];
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The invocation parameters for a prompt version for xAI.
|
|
122
|
+
*/
|
|
123
|
+
export type XAIInvocationParameters =
|
|
124
|
+
components["schemas"]["PromptXAIInvocationParametersContent"];
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The invocation parameters for a prompt version for Ollama.
|
|
128
|
+
*/
|
|
129
|
+
export type OllamaInvocationParameters =
|
|
130
|
+
components["schemas"]["PromptOllamaInvocationParametersContent"];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The invocation parameters for a prompt version for AWS.
|
|
134
|
+
*/
|
|
135
|
+
export type AwsInvocationParameters =
|
|
136
|
+
components["schemas"]["PromptAwsInvocationParametersContent"];
|
|
137
|
+
|
|
110
138
|
/**
|
|
111
139
|
* The format of the prompt template message(s).
|
|
112
140
|
*/
|