modelfusion 0.82.0 → 0.84.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/README.md +13 -10
- package/core/schema/UncheckedSchema.cjs +5 -1
- package/core/schema/UncheckedSchema.d.ts +1 -0
- package/core/schema/UncheckedSchema.js +3 -0
- package/model-function/AbstractModel.d.ts +1 -1
- package/model-function/generate-text/prompt-format/InstructionPrompt.d.ts +1 -1
- package/model-provider/automatic1111/Automatic1111ImageGenerationModel.cjs +1 -1
- package/model-provider/automatic1111/Automatic1111ImageGenerationModel.d.ts +1 -1
- package/model-provider/automatic1111/Automatic1111ImageGenerationModel.js +1 -1
- package/model-provider/index.cjs +1 -0
- package/model-provider/index.d.ts +1 -0
- package/model-provider/index.js +1 -0
- package/model-provider/llamacpp/LlamaCppBakLLaVA1Format.d.ts +2 -2
- package/model-provider/openai/AzureOpenAIApiConfiguration.cjs +1 -1
- package/model-provider/openai/AzureOpenAIApiConfiguration.d.ts +1 -1
- package/model-provider/openai/AzureOpenAIApiConfiguration.js +1 -1
- package/model-provider/openai/chat/AbstractOpenAIChatModel.cjs +228 -0
- package/model-provider/openai/chat/AbstractOpenAIChatModel.d.ts +467 -0
- package/model-provider/openai/chat/AbstractOpenAIChatModel.js +224 -0
- package/model-provider/openai/chat/OpenAIChatFunctionCallStructureGenerationModel.cjs +3 -3
- package/model-provider/openai/chat/OpenAIChatFunctionCallStructureGenerationModel.d.ts +6 -6
- package/model-provider/openai/chat/OpenAIChatFunctionCallStructureGenerationModel.js +1 -1
- package/model-provider/openai/chat/OpenAIChatModel.cjs +5 -218
- package/model-provider/openai/chat/OpenAIChatModel.d.ts +11 -460
- package/model-provider/openai/chat/OpenAIChatModel.js +4 -217
- package/model-provider/openai/chat/OpenAIChatPromptFormat.d.ts +2 -2
- package/model-provider/openai/index.cjs +1 -0
- package/model-provider/openai/index.d.ts +1 -0
- package/model-provider/openai/index.js +1 -0
- package/model-provider/openai-compatible/FireworksAIApiConfiguration.cjs +29 -0
- package/model-provider/openai-compatible/FireworksAIApiConfiguration.d.ts +18 -0
- package/model-provider/openai-compatible/FireworksAIApiConfiguration.js +25 -0
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.cjs +100 -0
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.d.ts +45 -0
- package/model-provider/openai-compatible/OpenAICompatibleChatModel.js +96 -0
- package/model-provider/openai-compatible/OpenAICompatibleFacade.cjs +30 -0
- package/model-provider/openai-compatible/OpenAICompatibleFacade.d.ts +24 -0
- package/model-provider/openai-compatible/OpenAICompatibleFacade.js +26 -0
- package/model-provider/openai-compatible/index.cjs +32 -0
- package/model-provider/openai-compatible/index.d.ts +3 -0
- package/model-provider/openai-compatible/index.js +3 -0
- package/model-provider/stability/StabilityImageGenerationModel.cjs +1 -1
- package/model-provider/stability/StabilityImageGenerationModel.d.ts +1 -1
- package/model-provider/stability/StabilityImageGenerationModel.js +1 -1
- package/package.json +1 -1
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.OpenAIChatFunctionCallStructureGenerationModel = void 0;
|
7
7
|
const secure_json_parse_1 = __importDefault(require("secure-json-parse"));
|
8
8
|
const StructureParseError_js_1 = require("../../../model-function/generate-structure/StructureParseError.cjs");
|
9
|
-
const
|
9
|
+
const AbstractOpenAIChatModel_js_1 = require("./AbstractOpenAIChatModel.cjs");
|
10
10
|
const OpenAIChatPromptFormat_js_1 = require("./OpenAIChatPromptFormat.cjs");
|
11
11
|
class OpenAIChatFunctionCallStructureGenerationModel {
|
12
12
|
constructor({ model, fnName, fnDescription, promptFormat, }) {
|
@@ -101,7 +101,7 @@ class OpenAIChatFunctionCallStructureGenerationModel {
|
|
101
101
|
})
|
102
102
|
.callAPI(expandedPrompt, {
|
103
103
|
...options,
|
104
|
-
responseFormat:
|
104
|
+
responseFormat: AbstractOpenAIChatModel_js_1.OpenAIChatResponseFormat.json,
|
105
105
|
functionCall: { name: this.fnName },
|
106
106
|
functions: [
|
107
107
|
{
|
@@ -132,7 +132,7 @@ class OpenAIChatFunctionCallStructureGenerationModel {
|
|
132
132
|
const expandedPrompt = this.promptFormat.format(prompt);
|
133
133
|
return this.model.callAPI(expandedPrompt, {
|
134
134
|
...options,
|
135
|
-
responseFormat:
|
135
|
+
responseFormat: AbstractOpenAIChatModel_js_1.OpenAIChatResponseFormat.structureDeltaIterable,
|
136
136
|
functionCall: { name: this.fnName },
|
137
137
|
functions: [
|
138
138
|
{
|
@@ -3,9 +3,9 @@ import { JsonSchemaProducer } from "../../../core/schema/JsonSchemaProducer.js";
|
|
3
3
|
import { Schema } from "../../../core/schema/Schema.js";
|
4
4
|
import { StructureGenerationModel } from "../../../model-function/generate-structure/StructureGenerationModel.js";
|
5
5
|
import { TextGenerationPromptFormat } from "../../../model-function/generate-text/TextGenerationPromptFormat.js";
|
6
|
-
import {
|
6
|
+
import { OpenAIChatPrompt } from "./AbstractOpenAIChatModel.js";
|
7
7
|
import { OpenAIChatModel, OpenAIChatSettings } from "./OpenAIChatModel";
|
8
|
-
export declare class OpenAIChatFunctionCallStructureGenerationModel<PROMPT_FORMAT extends TextGenerationPromptFormat<unknown,
|
8
|
+
export declare class OpenAIChatFunctionCallStructureGenerationModel<PROMPT_FORMAT extends TextGenerationPromptFormat<unknown, OpenAIChatPrompt>> implements StructureGenerationModel<Parameters<PROMPT_FORMAT["format"]>[0], // first argument of the function
|
9
9
|
OpenAIChatSettings> {
|
10
10
|
readonly model: OpenAIChatModel;
|
11
11
|
readonly fnName: string;
|
@@ -23,16 +23,16 @@ OpenAIChatSettings> {
|
|
23
23
|
/**
|
24
24
|
* Returns this model with a text prompt format.
|
25
25
|
*/
|
26
|
-
withTextPrompt(): OpenAIChatFunctionCallStructureGenerationModel<TextGenerationPromptFormat<string, OpenAIChatMessage[]>>;
|
26
|
+
withTextPrompt(): OpenAIChatFunctionCallStructureGenerationModel<TextGenerationPromptFormat<string, import("./OpenAIChatMessage.js").OpenAIChatMessage[]>>;
|
27
27
|
/**
|
28
28
|
* Returns this model with an instruction prompt format.
|
29
29
|
*/
|
30
|
-
withInstructionPrompt(): OpenAIChatFunctionCallStructureGenerationModel<TextGenerationPromptFormat<import("../../../index.js").
|
30
|
+
withInstructionPrompt(): OpenAIChatFunctionCallStructureGenerationModel<TextGenerationPromptFormat<import("../../../index.js").MultiModalInstructionPrompt | import("../../../index.js").TextInstructionPrompt, import("./OpenAIChatMessage.js").OpenAIChatMessage[]>>;
|
31
31
|
/**
|
32
32
|
* Returns this model with a chat prompt format.
|
33
33
|
*/
|
34
|
-
withChatPrompt(): OpenAIChatFunctionCallStructureGenerationModel<TextGenerationPromptFormat<import("../../../index.js").ChatPrompt, OpenAIChatMessage[]>>;
|
35
|
-
withPromptFormat<TARGET_PROMPT_FORMAT extends TextGenerationPromptFormat<unknown,
|
34
|
+
withChatPrompt(): OpenAIChatFunctionCallStructureGenerationModel<TextGenerationPromptFormat<import("../../../index.js").ChatPrompt, import("./OpenAIChatMessage.js").OpenAIChatMessage[]>>;
|
35
|
+
withPromptFormat<TARGET_PROMPT_FORMAT extends TextGenerationPromptFormat<unknown, OpenAIChatPrompt>>(promptFormat: TARGET_PROMPT_FORMAT): OpenAIChatFunctionCallStructureGenerationModel<TARGET_PROMPT_FORMAT>;
|
36
36
|
withSettings(additionalSettings: Partial<OpenAIChatSettings>): this;
|
37
37
|
/**
|
38
38
|
* JSON generation uses the OpenAI GPT function calling API.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import SecureJSON from "secure-json-parse";
|
2
2
|
import { StructureParseError } from "../../../model-function/generate-structure/StructureParseError.js";
|
3
|
-
import { OpenAIChatResponseFormat, } from "./
|
3
|
+
import { OpenAIChatResponseFormat, } from "./AbstractOpenAIChatModel.js";
|
4
4
|
import { chat, instruction, text } from "./OpenAIChatPromptFormat.js";
|
5
5
|
export class OpenAIChatFunctionCallStructureGenerationModel {
|
6
6
|
constructor({ model, fnName, fnDescription, promptFormat, }) {
|
@@ -1,20 +1,12 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
4
|
-
const zod_1 = require("zod");
|
5
|
-
const callWithRetryAndThrottle_js_1 = require("../../../core/api/callWithRetryAndThrottle.cjs");
|
6
|
-
const postToApi_js_1 = require("../../../core/api/postToApi.cjs");
|
7
|
-
const parseJSON_js_1 = require("../../../core/schema/parseJSON.cjs");
|
8
|
-
const AbstractModel_js_1 = require("../../../model-function/AbstractModel.cjs");
|
3
|
+
exports.OpenAIChatModel = exports.calculateOpenAIChatCostInMillicents = exports.isOpenAIChatModel = exports.getOpenAIChatModelInformation = exports.OPENAI_CHAT_MODELS = void 0;
|
9
4
|
const StructureFromTextStreamingModel_js_1 = require("../../../model-function/generate-structure/StructureFromTextStreamingModel.cjs");
|
10
|
-
const parsePartialJson_js_1 = require("../../../model-function/generate-structure/parsePartialJson.cjs");
|
11
5
|
const PromptFormatTextStreamingModel_js_1 = require("../../../model-function/generate-text/PromptFormatTextStreamingModel.cjs");
|
12
|
-
const OpenAIApiConfiguration_js_1 = require("../OpenAIApiConfiguration.cjs");
|
13
|
-
const OpenAIError_js_1 = require("../OpenAIError.cjs");
|
14
6
|
const TikTokenTokenizer_js_1 = require("../TikTokenTokenizer.cjs");
|
7
|
+
const AbstractOpenAIChatModel_js_1 = require("./AbstractOpenAIChatModel.cjs");
|
15
8
|
const OpenAIChatFunctionCallStructureGenerationModel_js_1 = require("./OpenAIChatFunctionCallStructureGenerationModel.cjs");
|
16
9
|
const OpenAIChatPromptFormat_js_1 = require("./OpenAIChatPromptFormat.cjs");
|
17
|
-
const OpenAIChatStreamIterable_js_1 = require("./OpenAIChatStreamIterable.cjs");
|
18
10
|
const countOpenAIChatMessageTokens_js_1 = require("./countOpenAIChatMessageTokens.cjs");
|
19
11
|
/*
|
20
12
|
* Available OpenAI chat models, their token limits, and pricing.
|
@@ -144,7 +136,7 @@ const calculateOpenAIChatCostInMillicents = ({ model, response, }) => {
|
|
144
136
|
};
|
145
137
|
exports.calculateOpenAIChatCostInMillicents = calculateOpenAIChatCostInMillicents;
|
146
138
|
/**
|
147
|
-
* Create a text generation model that calls the OpenAI chat
|
139
|
+
* Create a text generation model that calls the OpenAI chat API.
|
148
140
|
*
|
149
141
|
* @see https://platform.openai.com/docs/api-reference/chat/create
|
150
142
|
*
|
@@ -162,9 +154,9 @@ exports.calculateOpenAIChatCostInMillicents = calculateOpenAIChatCostInMillicent
|
|
162
154
|
* ),
|
163
155
|
* ]);
|
164
156
|
*/
|
165
|
-
class OpenAIChatModel extends
|
157
|
+
class OpenAIChatModel extends AbstractOpenAIChatModel_js_1.AbstractOpenAIChatModel {
|
166
158
|
constructor(settings) {
|
167
|
-
super(
|
159
|
+
super(settings);
|
168
160
|
Object.defineProperty(this, "provider", {
|
169
161
|
enumerable: true,
|
170
162
|
configurable: true,
|
@@ -202,31 +194,6 @@ class OpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
202
194
|
model: this.modelName,
|
203
195
|
});
|
204
196
|
}
|
205
|
-
async callAPI(messages, options) {
|
206
|
-
return (0, callWithRetryAndThrottle_js_1.callWithRetryAndThrottle)({
|
207
|
-
retry: this.settings.api?.retry,
|
208
|
-
throttle: this.settings.api?.throttle,
|
209
|
-
call: async () => callOpenAIChatCompletionAPI({
|
210
|
-
...this.settings,
|
211
|
-
// function & tool calling:
|
212
|
-
functions: options.functions ?? this.settings.functions,
|
213
|
-
functionCall: options.functionCall ?? this.settings.functionCall,
|
214
|
-
tools: options.tools ?? this.settings.tools,
|
215
|
-
toolChoice: options.toolChoice ?? this.settings.toolChoice,
|
216
|
-
// map to OpenAI API names:
|
217
|
-
stop: this.settings.stopSequences,
|
218
|
-
maxTokens: this.settings.maxCompletionTokens,
|
219
|
-
openAIResponseFormat: this.settings.responseFormat,
|
220
|
-
// other settings:
|
221
|
-
user: this.settings.isUserIdForwardingEnabled
|
222
|
-
? options.run?.userId
|
223
|
-
: undefined,
|
224
|
-
abortSignal: options.run?.abortSignal,
|
225
|
-
responseFormat: options.responseFormat,
|
226
|
-
messages,
|
227
|
-
}),
|
228
|
-
});
|
229
|
-
}
|
230
197
|
get settingsForEvent() {
|
231
198
|
const eventSettingProperties = [
|
232
199
|
"stopSequences",
|
@@ -244,87 +211,6 @@ class OpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
244
211
|
];
|
245
212
|
return Object.fromEntries(Object.entries(this.settings).filter(([key]) => eventSettingProperties.includes(key)));
|
246
213
|
}
|
247
|
-
async doGenerateText(prompt, options) {
|
248
|
-
const response = await this.callAPI(prompt, {
|
249
|
-
...options,
|
250
|
-
responseFormat: exports.OpenAIChatResponseFormat.json,
|
251
|
-
});
|
252
|
-
return {
|
253
|
-
response,
|
254
|
-
text: response.choices[0].message.content,
|
255
|
-
usage: this.extractUsage(response),
|
256
|
-
};
|
257
|
-
}
|
258
|
-
doStreamText(prompt, options) {
|
259
|
-
return this.callAPI(prompt, {
|
260
|
-
...options,
|
261
|
-
responseFormat: exports.OpenAIChatResponseFormat.textDeltaIterable,
|
262
|
-
});
|
263
|
-
}
|
264
|
-
async doGenerateToolCall(tool, prompt, options) {
|
265
|
-
const response = await this.callAPI(prompt, {
|
266
|
-
...options,
|
267
|
-
responseFormat: exports.OpenAIChatResponseFormat.json,
|
268
|
-
toolChoice: {
|
269
|
-
type: "function",
|
270
|
-
function: { name: tool.name },
|
271
|
-
},
|
272
|
-
tools: [
|
273
|
-
{
|
274
|
-
type: "function",
|
275
|
-
function: {
|
276
|
-
name: tool.name,
|
277
|
-
description: tool.description,
|
278
|
-
parameters: tool.parameters.getJsonSchema(),
|
279
|
-
},
|
280
|
-
},
|
281
|
-
],
|
282
|
-
});
|
283
|
-
const toolCalls = response.choices[0]?.message.tool_calls;
|
284
|
-
return {
|
285
|
-
response,
|
286
|
-
toolCall: toolCalls == null || toolCalls.length === 0
|
287
|
-
? null
|
288
|
-
: {
|
289
|
-
id: toolCalls[0].id,
|
290
|
-
args: (0, parseJSON_js_1.parseJSON)({ text: toolCalls[0].function.arguments }),
|
291
|
-
},
|
292
|
-
usage: this.extractUsage(response),
|
293
|
-
};
|
294
|
-
}
|
295
|
-
async doGenerateToolCallsOrText(tools, prompt, options) {
|
296
|
-
const response = await this.callAPI(prompt, {
|
297
|
-
...options,
|
298
|
-
responseFormat: exports.OpenAIChatResponseFormat.json,
|
299
|
-
toolChoice: "auto",
|
300
|
-
tools: tools.map((tool) => ({
|
301
|
-
type: "function",
|
302
|
-
function: {
|
303
|
-
name: tool.name,
|
304
|
-
description: tool.description,
|
305
|
-
parameters: tool.parameters.getJsonSchema(),
|
306
|
-
},
|
307
|
-
})),
|
308
|
-
});
|
309
|
-
const message = response.choices[0]?.message;
|
310
|
-
return {
|
311
|
-
response,
|
312
|
-
text: message.content ?? null,
|
313
|
-
toolCalls: message.tool_calls?.map((toolCall) => ({
|
314
|
-
id: toolCall.id,
|
315
|
-
name: toolCall.function.name,
|
316
|
-
args: (0, parseJSON_js_1.parseJSON)({ text: toolCall.function.arguments }),
|
317
|
-
})) ?? null,
|
318
|
-
usage: this.extractUsage(response),
|
319
|
-
};
|
320
|
-
}
|
321
|
-
extractUsage(response) {
|
322
|
-
return {
|
323
|
-
promptTokens: response.usage.prompt_tokens,
|
324
|
-
completionTokens: response.usage.completion_tokens,
|
325
|
-
totalTokens: response.usage.total_tokens,
|
326
|
-
};
|
327
|
-
}
|
328
214
|
asFunctionCallStructureGenerationModel({ fnName, fnDescription, }) {
|
329
215
|
return new OpenAIChatFunctionCallStructureGenerationModel_js_1.OpenAIChatFunctionCallStructureGenerationModel({
|
330
216
|
model: this,
|
@@ -373,102 +259,3 @@ class OpenAIChatModel extends AbstractModel_js_1.AbstractModel {
|
|
373
259
|
}
|
374
260
|
}
|
375
261
|
exports.OpenAIChatModel = OpenAIChatModel;
|
376
|
-
const openAIChatResponseSchema = zod_1.z.object({
|
377
|
-
id: zod_1.z.string(),
|
378
|
-
choices: zod_1.z.array(zod_1.z.object({
|
379
|
-
message: zod_1.z.object({
|
380
|
-
role: zod_1.z.literal("assistant"),
|
381
|
-
content: zod_1.z.string().nullable(),
|
382
|
-
function_call: zod_1.z
|
383
|
-
.object({
|
384
|
-
name: zod_1.z.string(),
|
385
|
-
arguments: zod_1.z.string(),
|
386
|
-
})
|
387
|
-
.optional(),
|
388
|
-
tool_calls: zod_1.z
|
389
|
-
.array(zod_1.z.object({
|
390
|
-
id: zod_1.z.string(),
|
391
|
-
type: zod_1.z.literal("function"),
|
392
|
-
function: zod_1.z.object({
|
393
|
-
name: zod_1.z.string(),
|
394
|
-
arguments: zod_1.z.string(),
|
395
|
-
}),
|
396
|
-
}))
|
397
|
-
.optional(),
|
398
|
-
}),
|
399
|
-
index: zod_1.z.number(),
|
400
|
-
logprobs: zod_1.z.nullable(zod_1.z.any()),
|
401
|
-
finish_reason: zod_1.z
|
402
|
-
.enum([
|
403
|
-
"stop",
|
404
|
-
"length",
|
405
|
-
"tool_calls",
|
406
|
-
"content_filter",
|
407
|
-
"function_call",
|
408
|
-
])
|
409
|
-
.optional()
|
410
|
-
.nullable(),
|
411
|
-
})),
|
412
|
-
created: zod_1.z.number(),
|
413
|
-
model: zod_1.z.string(),
|
414
|
-
system_fingerprint: zod_1.z.string().optional(),
|
415
|
-
object: zod_1.z.literal("chat.completion"),
|
416
|
-
usage: zod_1.z.object({
|
417
|
-
prompt_tokens: zod_1.z.number(),
|
418
|
-
completion_tokens: zod_1.z.number(),
|
419
|
-
total_tokens: zod_1.z.number(),
|
420
|
-
}),
|
421
|
-
});
|
422
|
-
async function callOpenAIChatCompletionAPI({ api = new OpenAIApiConfiguration_js_1.OpenAIApiConfiguration(), abortSignal, responseFormat, model, messages, functions, functionCall, tools, toolChoice, temperature, topP, n, stop, maxTokens, presencePenalty, frequencyPenalty, logitBias, user, openAIResponseFormat, seed, }) {
|
423
|
-
// empty arrays are not allowed for stop:
|
424
|
-
if (stop != null && Array.isArray(stop) && stop.length === 0) {
|
425
|
-
stop = undefined;
|
426
|
-
}
|
427
|
-
return (0, postToApi_js_1.postJsonToApi)({
|
428
|
-
url: api.assembleUrl("/chat/completions"),
|
429
|
-
headers: api.headers,
|
430
|
-
body: {
|
431
|
-
stream: responseFormat.stream,
|
432
|
-
model,
|
433
|
-
messages,
|
434
|
-
functions,
|
435
|
-
function_call: functionCall,
|
436
|
-
tools,
|
437
|
-
tool_choice: toolChoice,
|
438
|
-
temperature,
|
439
|
-
top_p: topP,
|
440
|
-
n,
|
441
|
-
stop,
|
442
|
-
max_tokens: maxTokens,
|
443
|
-
presence_penalty: presencePenalty,
|
444
|
-
frequency_penalty: frequencyPenalty,
|
445
|
-
logit_bias: logitBias,
|
446
|
-
seed,
|
447
|
-
response_format: openAIResponseFormat,
|
448
|
-
user,
|
449
|
-
},
|
450
|
-
failedResponseHandler: OpenAIError_js_1.failedOpenAICallResponseHandler,
|
451
|
-
successfulResponseHandler: responseFormat.handler,
|
452
|
-
abortSignal,
|
453
|
-
});
|
454
|
-
}
|
455
|
-
exports.OpenAIChatResponseFormat = {
|
456
|
-
/**
|
457
|
-
* Returns the response as a JSON object.
|
458
|
-
*/
|
459
|
-
json: {
|
460
|
-
stream: false,
|
461
|
-
handler: (0, postToApi_js_1.createJsonResponseHandler)(openAIChatResponseSchema),
|
462
|
-
},
|
463
|
-
/**
|
464
|
-
* Returns an async iterable over the text deltas (only the tex different of the first choice).
|
465
|
-
*/
|
466
|
-
textDeltaIterable: {
|
467
|
-
stream: true,
|
468
|
-
handler: async ({ response }) => (0, OpenAIChatStreamIterable_js_1.createOpenAIChatDeltaIterableQueue)(response.body, (delta) => delta[0]?.delta.content ?? ""),
|
469
|
-
},
|
470
|
-
structureDeltaIterable: {
|
471
|
-
stream: true,
|
472
|
-
handler: async ({ response }) => (0, OpenAIChatStreamIterable_js_1.createOpenAIChatDeltaIterableQueue)(response.body, (delta) => (0, parsePartialJson_js_1.parsePartialJson)(delta[0]?.function_call?.arguments)),
|
473
|
-
},
|
474
|
-
};
|