@forestadmin/agent-bff 1.33.0 → 1.34.1
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
CHANGED
|
@@ -59,8 +59,6 @@ docker run -d \
|
|
|
59
59
|
--add-host host.docker.internal:host-gateway \
|
|
60
60
|
-e FOREST_AUTH_SECRET="..." \
|
|
61
61
|
-e FOREST_ENV_SECRET="..." \
|
|
62
|
-
-e FOREST_SERVER_URL="https://api.forestadmin.com" \
|
|
63
|
-
-e FOREST_APP_URL="https://app.forestadmin.com" \
|
|
64
62
|
-e AGENT_URL="http://host.docker.internal:3351" \
|
|
65
63
|
-e BFF_TOKEN_ENCRYPTION_KEY="$(openssl rand -base64 32)" \
|
|
66
64
|
ghcr.io/forestadmin/agent-bff:latest
|
|
@@ -127,8 +125,6 @@ docker run -d \
|
|
|
127
125
|
--add-host host.docker.internal:host-gateway \
|
|
128
126
|
-e FOREST_AUTH_SECRET="..." \
|
|
129
127
|
-e FOREST_ENV_SECRET="..." \
|
|
130
|
-
-e FOREST_SERVER_URL="https://api.forestadmin.com" \
|
|
131
|
-
-e FOREST_APP_URL="https://app.forestadmin.com" \
|
|
132
128
|
-e AGENT_URL="http://host.docker.internal:3351" \
|
|
133
129
|
-e BFF_TOKEN_ENCRYPTION_KEY="$(openssl rand -base64 32)" \
|
|
134
130
|
-e OTEL_EXPORTER_OTLP_ENDPOINT="http://collector:4318" \
|
|
@@ -163,7 +159,7 @@ without it a client generated from the export has no base URL at all.
|
|
|
163
159
|
|
|
164
160
|
The document comes in two forms, and the command picks one from the environment:
|
|
165
161
|
|
|
166
|
-
- **Unfolded** when `
|
|
162
|
+
- **Unfolded** when `FOREST_ENV_SECRET`, `FOREST_AUTH_SECRET` and `AGENT_URL`
|
|
167
163
|
are all set: one path per exposed collection, per to-many relation and per action, each carrying
|
|
168
164
|
the collection's real field set. This is the form to generate a client from. The command reads the
|
|
169
165
|
Forest schema and asks the agent for each collection's capabilities, signing its own short-lived
|
|
@@ -201,8 +197,8 @@ yarn start:dev # node --env-file=.env dist/cli.js
|
|
|
201
197
|
| ----------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
202
198
|
| `FOREST_AUTH_SECRET` | yes | Agent JWT signing secret (never logged or echoed). |
|
|
203
199
|
| `FOREST_ENV_SECRET` | yes | Forest SaaS environment secret (`forest-secret-key`), server-to-server. |
|
|
204
|
-
| `FOREST_SERVER_URL` |
|
|
205
|
-
| `FOREST_APP_URL` |
|
|
200
|
+
| `FOREST_SERVER_URL` | no | Forest SaaS API base URL. Defaults to `https://api.forestadmin.com`. |
|
|
201
|
+
| `FOREST_APP_URL` | no | Forest front base URL, used to build the OAuth front-channel redirect (`src/oauth/oauth-routes.ts`). Defaults to `https://app.forestadmin.com`. |
|
|
206
202
|
| `AGENT_URL` | yes | The customer agent base URL the BFF calls via agent-client. |
|
|
207
203
|
| `BFF_TOKEN_ENCRYPTION_KEY` | for OAuth | Base64-encoded 32-byte AES-256 key encrypting stored refresh tokens. Until it is set, the `/oauth/*` token-issuance routes are disabled and `/health` reports `configured.oauth: false` — but it stays `ok`, since the key gates OAuth and not boot; already-issued `bff_access` tokens still authenticate on `/agent/*` whenever `FOREST_AUTH_SECRET` is present. |
|
|
208
204
|
| `HTTP_PORT` | no | Server port, integer 0–65535. Defaults to `3450`. `0` binds an OS-assigned ephemeral port — useful for a local run, unusable in the Docker image, where nothing outside the process learns which port it got: it can be neither published nor probed, and the image's healthcheck would report the container unhealthy forever. |
|
|
@@ -380,7 +376,7 @@ answers. They form a chain, not four independent switches:
|
|
|
380
376
|
|
|
381
377
|
| Surface | Switched on by |
|
|
382
378
|
| --- | --- |
|
|
383
|
-
| `oauth` | `BFF_TOKEN_ENCRYPTION_KEY` **and** `FOREST_SERVER_URL`, `FOREST_ENV_SECRET`, `FOREST_APP_URL`, `FOREST_AUTH_SECRET` — the routes need a Forest server to talk to as much as a key. Embedded, only `tokenEncryptionKey` is yours to set: the other four are inherited |
|
|
379
|
+
| `oauth` | `BFF_TOKEN_ENCRYPTION_KEY` **and** `FOREST_SERVER_URL`, `FOREST_ENV_SECRET`, `FOREST_APP_URL`, `FOREST_AUTH_SECRET` — the routes need a Forest server to talk to as much as a key. The two urls default to production, so standalone only the two secrets and the key are yours to set. Embedded, only `tokenEncryptionKey` is yours to set: the other four are inherited |
|
|
384
380
|
| `ai` | `oauth` — the relay needs a session, and only the OAuth flow creates one |
|
|
385
381
|
| `cors` | a non-empty `BFF_ALLOWED_ORIGINS` (`allowedOrigins`) |
|
|
386
382
|
| `openapi` | `BFF_OPENAPI_ENABLED` (`openapiEnabled`), and a mounted agent edge |
|
|
@@ -52,6 +52,7 @@ const ALLOWED_STYLE_PROPERTIES = [
|
|
|
52
52
|
const OPTIONS = {
|
|
53
53
|
allowedAttributes: { ...sanitize_html_1.default.defaults.allowedAttributes, '*': ['style'] },
|
|
54
54
|
allowedClasses: { '*': ['c-*', 'l-*'] },
|
|
55
|
+
nonTextTags: ['script', 'style', 'xmp'],
|
|
55
56
|
allowedStyles: {
|
|
56
57
|
'*': Object.fromEntries(ALLOWED_STYLE_PROPERTIES.map(name => [name, [SAFE_STYLE_VALUE]])),
|
|
57
58
|
},
|
|
@@ -111,4 +112,4 @@ function sanitizeActionLayout(layout, logger, depth = 0, budget = { remaining: M
|
|
|
111
112
|
return element;
|
|
112
113
|
});
|
|
113
114
|
}
|
|
114
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
115
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FuaXRpemUtYWN0aW9uLWh0bWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWN0aW9uL3Nhbml0aXplLWFjdGlvbi1odG1sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBcUZBLHFDQUVDO0FBRUQsb0RBa0RDO0FBeElELGtFQUF5QztBQUV6QyxNQUFNLG1CQUFtQixHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFFdkMsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7QUFFNUIsTUFBTSxnQkFBZ0IsR0FDcEIsaUZBQWlGLENBQUM7QUFFcEYsTUFBTSx3QkFBd0IsR0FBRztJQUMvQixZQUFZO0lBQ1osa0JBQWtCO0lBQ2xCLFFBQVE7SUFDUixlQUFlO0lBQ2YsaUJBQWlCO0lBQ2pCLGFBQWE7SUFDYixlQUFlO0lBQ2YsY0FBYztJQUNkLFlBQVk7SUFDWixPQUFPO0lBQ1AsU0FBUztJQUNULGFBQWE7SUFDYixXQUFXO0lBQ1gsWUFBWTtJQUNaLGFBQWE7SUFDYixRQUFRO0lBQ1IsZ0JBQWdCO0lBQ2hCLGFBQWE7SUFDYixRQUFRO0lBQ1IsZUFBZTtJQUNmLGFBQWE7SUFDYixjQUFjO0lBQ2QsWUFBWTtJQUNaLFdBQVc7SUFDWCxXQUFXO0lBQ1gsU0FBUztJQUNULFVBQVU7SUFDVixTQUFTO0lBQ1QsZ0JBQWdCO0lBQ2hCLGNBQWM7SUFDZCxlQUFlO0lBQ2YsYUFBYTtJQUNiLFlBQVk7SUFDWixpQkFBaUI7SUFDakIsZ0JBQWdCO0lBQ2hCLGdCQUFnQjtJQUNoQixhQUFhO0lBQ2IsT0FBTztDQUNSLENBQUM7QUFFRixNQUFNLE9BQU8sR0FBMEI7SUFDckMsaUJBQWlCLEVBQUUsRUFBRSxHQUFHLHVCQUFZLENBQUMsUUFBUSxDQUFDLGlCQUFpQixFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFO0lBQ2pGLGNBQWMsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsRUFB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
|
package/dist/cli-dispatch.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type BFFHttpServer from './http/bff-http-server';
|
|
2
2
|
import type { Logger } from './ports/logger-port';
|
|
3
3
|
export declare const DEFAULT_OUTPUT_FILE = "openapi.json";
|
|
4
|
-
export declare const USAGE = "Usage: forest-bff [command]\n\nCommands:\n (none) Start the BFF server, configured from the environment.\n openapi Write the OpenAPI document to stdout. Needs no configuration, but\n a deployment configured to reach its Forest schema and its agent\n (
|
|
4
|
+
export declare const USAGE = "Usage: forest-bff [command]\n\nCommands:\n (none) Start the BFF server, configured from the environment.\n openapi Write the OpenAPI document to stdout. Needs no configuration, but\n a deployment configured to reach its Forest schema and its agent\n (FOREST_ENV_SECRET, FOREST_AUTH_SECRET, AGENT_URL) unfolds one\n path per collection, relation and action instead of the generic\n ones.\n --output [file] Write to a file instead of stdout, defaulting\n to openapi.json in the current directory.\n\nOptions:\n -h, --help Show this help and exit.\n -v, --version Show the package version and exit.";
|
|
5
5
|
export declare const HINT = "Run 'forest-bff --help' for usage.";
|
|
6
6
|
export interface DispatchOutcome {
|
|
7
7
|
exitCode: number;
|
package/dist/cli-dispatch.js
CHANGED
|
@@ -59,9 +59,9 @@ Commands:
|
|
|
59
59
|
(none) Start the BFF server, configured from the environment.
|
|
60
60
|
openapi Write the OpenAPI document to stdout. Needs no configuration, but
|
|
61
61
|
a deployment configured to reach its Forest schema and its agent
|
|
62
|
-
(
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
(FOREST_ENV_SECRET, FOREST_AUTH_SECRET, AGENT_URL) unfolds one
|
|
63
|
+
path per collection, relation and action instead of the generic
|
|
64
|
+
ones.
|
|
65
65
|
--output [file] Write to a file instead of stdout, defaulting
|
|
66
66
|
to ${exports.DEFAULT_OUTPUT_FILE} in the current directory.
|
|
67
67
|
|
|
@@ -71,12 +71,7 @@ Options:
|
|
|
71
71
|
exports.HINT = "Run 'forest-bff --help' for usage.";
|
|
72
72
|
const HELP_FLAGS = new Set(['-h', '--help']);
|
|
73
73
|
const VERSION_FLAGS = new Set(['-v', '--version']);
|
|
74
|
-
const UNFOLD_VARS = [
|
|
75
|
-
'FOREST_SERVER_URL',
|
|
76
|
-
'FOREST_ENV_SECRET',
|
|
77
|
-
'FOREST_AUTH_SECRET',
|
|
78
|
-
'AGENT_URL',
|
|
79
|
-
];
|
|
74
|
+
const UNFOLD_VARS = ['FOREST_ENV_SECRET', 'FOREST_AUTH_SECRET', 'AGENT_URL'];
|
|
80
75
|
const NOTHING_TO_UNFOLD = `${UNFOLD_VARS.join(', ')} must all be set to unfold it`;
|
|
81
76
|
function wantsUnfolding(env) {
|
|
82
77
|
return UNFOLD_VARS.every(name => (env[name] ?? '').trim() !== '');
|
|
@@ -102,7 +97,7 @@ async function renderOpenApi(env, logger) {
|
|
|
102
97
|
// `parseConfig` validates the WHOLE server configuration, including settings the export has nothing
|
|
103
98
|
// to do with (HTTP_PORT, the OAuth keys, the default timezone). A deployment that never asked for an
|
|
104
99
|
// unfolded document must not see its export die on one of those, so the config is parsed only once
|
|
105
|
-
// the
|
|
100
|
+
// the variables unfolding needs are all present — and from there a bad value is a real failure.
|
|
106
101
|
const unfoldable = authSecret && wantsUnfolding(env)
|
|
107
102
|
? { source: (0, build_bff_1.resolveUnfoldSource)((0, env_config_1.parseConfig)(env), logger), authSecret }
|
|
108
103
|
: undefined;
|
|
@@ -183,4 +178,4 @@ async function dispatchCli(argv, env, logger) {
|
|
|
183
178
|
process.stdout.write(document);
|
|
184
179
|
return { exitCode: 0 };
|
|
185
180
|
}
|
|
186
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
181
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLWRpc3BhdGNoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NsaS1kaXNwYXRjaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE0RUEsc0NBNENDO0FBZ0RELDhCQWdEQztBQXJORCwyQkFBOEM7QUFDOUMsZ0RBQXdCO0FBRXhCLCtFQUE0RDtBQUM1RCxvRUFBMkQ7QUFDM0QsMkNBQXNFO0FBQ3RFLDBEQUFnQztBQUNoQyxvREFBa0U7QUFDbEUscUNBQStDO0FBQy9DLGlFQUF1RjtBQUN2RixpRkFBNEY7QUFDNUYsbURBQXNEO0FBQ3RELHdEQUFnQztBQUVuQixRQUFBLG1CQUFtQixHQUFHLGNBQWMsQ0FBQztBQUVsRCxNQUFNLFdBQVcsR0FBRyxVQUFVLENBQUM7QUFFbEIsUUFBQSxLQUFLLEdBQUc7Ozs7Ozs7Ozs7b0NBVWUsMkJBQW1COzs7O29EQUlILENBQUM7QUFFeEMsUUFBQSxJQUFJLEdBQUcsb0NBQW9DLENBQUM7QUFFekQsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUM3QyxNQUFNLGFBQWEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO0FBT25ELE1BQU0sV0FBVyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsb0JBQW9CLEVBQUUsV0FBVyxDQUFVLENBQUM7QUFFdEYsTUFBTSxpQkFBaUIsR0FBRyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLCtCQUErQixDQUFDO0FBRW5GLFNBQVMsY0FBYyxDQUFDLEdBQXNCO0lBQzVDLE9BQU8sV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxL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
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const REQUIRED_KEYS: readonly ["FOREST_AUTH_SECRET", "FOREST_ENV_SECRET", "FOREST_SERVER_URL", "FOREST_APP_URL", "AGENT_URL"];
|
|
2
2
|
export type RequiredKey = (typeof REQUIRED_KEYS)[number];
|
|
3
|
+
export declare const DEFAULTS: Partial<Record<RequiredKey, string>>;
|
|
3
4
|
export type PresenceMap = Record<RequiredKey, boolean>;
|
|
4
5
|
export interface BFFConfig {
|
|
5
6
|
forestAuthSecret?: string;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MIN_RATE_LIMIT_WINDOW_MS = exports.MAX_RATE_LIMIT_REQUESTS = exports.DEFAULT_RATE_LIMIT_WINDOW_MS = exports.DEFAULT_RATE_LIMIT_MAX_REQUESTS = exports.MAX_TIMEOUT_MS = exports.DEFAULT_AI_TIMEOUT_MS = exports.DEFAULT_AGENT_TIMEOUT_MS = exports.REQUIRED_KEYS = void 0;
|
|
6
|
+
exports.MIN_RATE_LIMIT_WINDOW_MS = exports.MAX_RATE_LIMIT_REQUESTS = exports.DEFAULT_RATE_LIMIT_WINDOW_MS = exports.DEFAULT_RATE_LIMIT_MAX_REQUESTS = exports.MAX_TIMEOUT_MS = exports.DEFAULT_AI_TIMEOUT_MS = exports.DEFAULT_AGENT_TIMEOUT_MS = exports.DEFAULTS = exports.REQUIRED_KEYS = void 0;
|
|
7
7
|
exports.parsePublicUrl = parsePublicUrl;
|
|
8
8
|
exports.parseConfig = parseConfig;
|
|
9
9
|
const zod_1 = require("zod");
|
|
@@ -18,6 +18,10 @@ exports.REQUIRED_KEYS = [
|
|
|
18
18
|
'FOREST_APP_URL',
|
|
19
19
|
'AGENT_URL',
|
|
20
20
|
];
|
|
21
|
+
exports.DEFAULTS = {
|
|
22
|
+
FOREST_SERVER_URL: 'https://api.forestadmin.com',
|
|
23
|
+
FOREST_APP_URL: 'https://app.forestadmin.com',
|
|
24
|
+
};
|
|
21
25
|
const URL_KEYS = ['FOREST_SERVER_URL', 'FOREST_APP_URL', 'AGENT_URL'];
|
|
22
26
|
const DECIMAL_INTEGER = /^\d+$/;
|
|
23
27
|
exports.DEFAULT_AGENT_TIMEOUT_MS = 10000;
|
|
@@ -99,7 +103,7 @@ function parseOpenApiEnabled(raw) {
|
|
|
99
103
|
throw new errors_1.ConfigurationError('Invalid configuration: BFF_OPENAPI_ENABLED must be a boolean (true/false).');
|
|
100
104
|
}
|
|
101
105
|
function parseConfig(env) {
|
|
102
|
-
const normalized = Object.fromEntries(exports.REQUIRED_KEYS.map(key => [key, normalize(env[key])]));
|
|
106
|
+
const normalized = Object.fromEntries(exports.REQUIRED_KEYS.map(key => [key, normalize(env[key]) ?? exports.DEFAULTS[key]]));
|
|
103
107
|
for (const key of URL_KEYS) {
|
|
104
108
|
const value = normalized[key];
|
|
105
109
|
if (value !== undefined && !isHttpUrl(value)) {
|
|
@@ -143,4 +147,4 @@ function parseConfig(env) {
|
|
|
143
147
|
hasAllRequired: exports.REQUIRED_KEYS.every(key => presence[key]),
|
|
144
148
|
};
|
|
145
149
|
}
|
|
146
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
150
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW52LWNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvZW52LWNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUErRkEsd0NBMEJDO0FBNENELGtDQW1FQztBQXhPRCw2QkFBd0I7QUFFeEIsMkNBQXFEO0FBQ3JELDJEQUEyQztBQUMzQyxzQ0FBK0M7QUFDL0MsbURBQXVEO0FBRTFDLFFBQUEsYUFBYSxHQUFHO0lBQzNCLG9CQUFvQjtJQUNwQixtQkFBbUI7SUFDbkIsbUJBQW1CO0lBQ25CLGdCQUFnQjtJQUNoQixXQUFXO0NBQ0gsQ0FBQztBQUlFLFFBQUEsUUFBUSxHQUF5QztJQUM1RCxpQkFBaUIsRUFBRSw2QkFBNkI7SUFDaEQsY0FBYyxFQUFFLDZCQUE2QjtDQUM5QyxDQUFDO0FBRUYsTUFBTSxRQUFRLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLENBQVUsQ0FBQztBQXlCL0UsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ25CLFFBQUEsd0JBQXdCLEdBQUcsS0FBTSxDQUFDO0FBQ2xDLFFBQUEscUJBQXFCLEdBQUcsTUFBTyxDQUFDO0FBQ2hDLFFBQUEsY0FBYyxHQUFHLFVBQWEsQ0FBQztBQUMvQixRQUFBLCtCQUErQixHQUFHLEdBQUcsQ0FBQztBQUN0QyxRQUFBLDRCQUE0QixHQUFHLEtBQU0sQ0FBQztBQUN0QyxRQUFBLHVCQUF1QixHQUFHLEtBQU0sQ0FBQztBQUNqQyxRQUFBLHdCQUF3QixHQUFHLElBQUssQ0FBQztBQUM5QyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUM7QUFDdkIsTUFBTSxvQkFBb0IsR0FBRyxFQUFFLENBQUM7QUFDaEMsTUFBTSxjQUFjLEdBQUcsd0JBQXdCLENBQUM7QUFDaEQsTUFBTSxlQUFlLEdBQUcsT0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0FBRXhELFNBQVMs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
|