@objectstack/core 0.8.2 → 0.9.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.
Files changed (73) hide show
  1. package/API_REGISTRY.md +392 -0
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +36 -0
  4. package/dist/api-registry-plugin.d.ts +54 -0
  5. package/dist/api-registry-plugin.d.ts.map +1 -0
  6. package/dist/api-registry-plugin.js +53 -0
  7. package/dist/api-registry-plugin.test.d.ts +2 -0
  8. package/dist/api-registry-plugin.test.d.ts.map +1 -0
  9. package/dist/api-registry-plugin.test.js +332 -0
  10. package/dist/api-registry.d.ts +259 -0
  11. package/dist/api-registry.d.ts.map +1 -0
  12. package/dist/api-registry.js +599 -0
  13. package/dist/api-registry.test.d.ts +2 -0
  14. package/dist/api-registry.test.d.ts.map +1 -0
  15. package/dist/api-registry.test.js +957 -0
  16. package/dist/index.d.ts +4 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +5 -0
  19. package/dist/logger.d.ts +1 -0
  20. package/dist/logger.d.ts.map +1 -1
  21. package/dist/logger.js +35 -11
  22. package/dist/plugin-loader.d.ts +3 -2
  23. package/dist/plugin-loader.d.ts.map +1 -1
  24. package/dist/plugin-loader.js +13 -11
  25. package/dist/qa/adapter.d.ts +14 -0
  26. package/dist/qa/adapter.d.ts.map +1 -0
  27. package/dist/qa/adapter.js +1 -0
  28. package/dist/qa/http-adapter.d.ts +16 -0
  29. package/dist/qa/http-adapter.d.ts.map +1 -0
  30. package/dist/qa/http-adapter.js +107 -0
  31. package/dist/qa/index.d.ts +4 -0
  32. package/dist/qa/index.d.ts.map +1 -0
  33. package/dist/qa/index.js +3 -0
  34. package/dist/qa/runner.d.ts +27 -0
  35. package/dist/qa/runner.d.ts.map +1 -0
  36. package/dist/qa/runner.js +157 -0
  37. package/dist/security/index.d.ts +14 -0
  38. package/dist/security/index.d.ts.map +1 -0
  39. package/dist/security/index.js +13 -0
  40. package/dist/security/plugin-config-validator.d.ts +79 -0
  41. package/dist/security/plugin-config-validator.d.ts.map +1 -0
  42. package/dist/security/plugin-config-validator.js +166 -0
  43. package/dist/security/plugin-config-validator.test.d.ts +2 -0
  44. package/dist/security/plugin-config-validator.test.d.ts.map +1 -0
  45. package/dist/security/plugin-config-validator.test.js +223 -0
  46. package/dist/security/plugin-permission-enforcer.d.ts +154 -0
  47. package/dist/security/plugin-permission-enforcer.d.ts.map +1 -0
  48. package/dist/security/plugin-permission-enforcer.js +323 -0
  49. package/dist/security/plugin-permission-enforcer.test.d.ts +2 -0
  50. package/dist/security/plugin-permission-enforcer.test.d.ts.map +1 -0
  51. package/dist/security/plugin-permission-enforcer.test.js +205 -0
  52. package/dist/security/plugin-signature-verifier.d.ts +96 -0
  53. package/dist/security/plugin-signature-verifier.d.ts.map +1 -0
  54. package/dist/security/plugin-signature-verifier.js +250 -0
  55. package/examples/api-registry-example.ts +557 -0
  56. package/package.json +2 -2
  57. package/src/api-registry-plugin.test.ts +391 -0
  58. package/src/api-registry-plugin.ts +86 -0
  59. package/src/api-registry.test.ts +1089 -0
  60. package/src/api-registry.ts +736 -0
  61. package/src/index.ts +6 -0
  62. package/src/logger.ts +36 -11
  63. package/src/plugin-loader.ts +17 -13
  64. package/src/qa/adapter.ts +14 -0
  65. package/src/qa/http-adapter.ts +114 -0
  66. package/src/qa/index.ts +3 -0
  67. package/src/qa/runner.ts +179 -0
  68. package/src/security/index.ts +29 -0
  69. package/src/security/plugin-config-validator.test.ts +276 -0
  70. package/src/security/plugin-config-validator.ts +191 -0
  71. package/src/security/plugin-permission-enforcer.test.ts +251 -0
  72. package/src/security/plugin-permission-enforcer.ts +408 -0
  73. package/src/security/plugin-signature-verifier.ts +359 -0
@@ -0,0 +1,166 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Plugin Configuration Validator
4
+ *
5
+ * Validates plugin configurations against Zod schemas to ensure:
6
+ * 1. Type safety - all config values have correct types
7
+ * 2. Business rules - values meet constraints (min/max, regex, etc.)
8
+ * 3. Required fields - all mandatory configuration is provided
9
+ * 4. Default values - missing optional fields get defaults
10
+ *
11
+ * Architecture:
12
+ * - Uses Zod for runtime validation
13
+ * - Provides detailed error messages with field paths
14
+ * - Supports nested configuration objects
15
+ * - Allows partial validation for incremental updates
16
+ *
17
+ * Usage:
18
+ * ```typescript
19
+ * const validator = new PluginConfigValidator(logger);
20
+ * const validConfig = validator.validatePluginConfig(plugin, userConfig);
21
+ * ```
22
+ */
23
+ export class PluginConfigValidator {
24
+ constructor(logger) {
25
+ this.logger = logger;
26
+ }
27
+ /**
28
+ * Validate plugin configuration against its Zod schema
29
+ *
30
+ * @param plugin - Plugin metadata with configSchema
31
+ * @param config - User-provided configuration
32
+ * @returns Validated and typed configuration
33
+ * @throws Error with detailed validation errors
34
+ */
35
+ validatePluginConfig(plugin, config) {
36
+ if (!plugin.configSchema) {
37
+ this.logger.debug(`Plugin ${plugin.name} has no config schema - skipping validation`);
38
+ return config;
39
+ }
40
+ try {
41
+ // Use Zod to parse and validate
42
+ const validatedConfig = plugin.configSchema.parse(config);
43
+ this.logger.debug(`✅ Plugin config validated: ${plugin.name}`, {
44
+ plugin: plugin.name,
45
+ configKeys: Object.keys(config || {}).length,
46
+ });
47
+ return validatedConfig;
48
+ }
49
+ catch (error) {
50
+ if (error instanceof z.ZodError) {
51
+ const formattedErrors = this.formatZodErrors(error);
52
+ const errorMessage = [
53
+ `Plugin ${plugin.name} configuration validation failed:`,
54
+ ...formattedErrors.map(e => ` - ${e.path}: ${e.message}`),
55
+ ].join('\n');
56
+ this.logger.error(errorMessage, undefined, {
57
+ plugin: plugin.name,
58
+ errors: formattedErrors,
59
+ });
60
+ throw new Error(errorMessage);
61
+ }
62
+ // Re-throw other errors
63
+ throw error;
64
+ }
65
+ }
66
+ /**
67
+ * Validate partial configuration (for incremental updates)
68
+ *
69
+ * @param plugin - Plugin metadata
70
+ * @param partialConfig - Partial configuration to validate
71
+ * @returns Validated partial configuration
72
+ */
73
+ validatePartialConfig(plugin, partialConfig) {
74
+ if (!plugin.configSchema) {
75
+ return partialConfig;
76
+ }
77
+ try {
78
+ // Use Zod's partial() method for partial validation
79
+ // Cast to ZodObject to access partial() method
80
+ const partialSchema = plugin.configSchema.partial();
81
+ const validatedConfig = partialSchema.parse(partialConfig);
82
+ this.logger.debug(`✅ Partial config validated: ${plugin.name}`);
83
+ return validatedConfig;
84
+ }
85
+ catch (error) {
86
+ if (error instanceof z.ZodError) {
87
+ const formattedErrors = this.formatZodErrors(error);
88
+ const errorMessage = [
89
+ `Plugin ${plugin.name} partial configuration validation failed:`,
90
+ ...formattedErrors.map(e => ` - ${e.path}: ${e.message}`),
91
+ ].join('\n');
92
+ throw new Error(errorMessage);
93
+ }
94
+ throw error;
95
+ }
96
+ }
97
+ /**
98
+ * Get default configuration from schema
99
+ *
100
+ * @param plugin - Plugin metadata
101
+ * @returns Default configuration object
102
+ */
103
+ getDefaultConfig(plugin) {
104
+ if (!plugin.configSchema) {
105
+ return undefined;
106
+ }
107
+ try {
108
+ // Parse empty object to get defaults
109
+ const defaults = plugin.configSchema.parse({});
110
+ this.logger.debug(`Default config extracted: ${plugin.name}`);
111
+ return defaults;
112
+ }
113
+ catch (error) {
114
+ // Schema may require some fields - return undefined
115
+ this.logger.debug(`No default config available: ${plugin.name}`);
116
+ return undefined;
117
+ }
118
+ }
119
+ /**
120
+ * Check if configuration is valid without throwing
121
+ *
122
+ * @param plugin - Plugin metadata
123
+ * @param config - Configuration to check
124
+ * @returns True if valid, false otherwise
125
+ */
126
+ isConfigValid(plugin, config) {
127
+ if (!plugin.configSchema) {
128
+ return true;
129
+ }
130
+ const result = plugin.configSchema.safeParse(config);
131
+ return result.success;
132
+ }
133
+ /**
134
+ * Get configuration errors without throwing
135
+ *
136
+ * @param plugin - Plugin metadata
137
+ * @param config - Configuration to check
138
+ * @returns Array of validation errors, or empty array if valid
139
+ */
140
+ getConfigErrors(plugin, config) {
141
+ if (!plugin.configSchema) {
142
+ return [];
143
+ }
144
+ const result = plugin.configSchema.safeParse(config);
145
+ if (result.success) {
146
+ return [];
147
+ }
148
+ return this.formatZodErrors(result.error);
149
+ }
150
+ // Private methods
151
+ formatZodErrors(error) {
152
+ return error.issues.map((e) => ({
153
+ path: e.path.join('.') || 'root',
154
+ message: e.message,
155
+ }));
156
+ }
157
+ }
158
+ /**
159
+ * Create a plugin config validator
160
+ *
161
+ * @param logger - Logger instance
162
+ * @returns Plugin config validator
163
+ */
164
+ export function createPluginConfigValidator(logger) {
165
+ return new PluginConfigValidator(logger);
166
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin-config-validator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-config-validator.test.d.ts","sourceRoot":"","sources":["../../src/security/plugin-config-validator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,223 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { z } from 'zod';
3
+ import { PluginConfigValidator } from './plugin-config-validator.js';
4
+ import { createLogger } from '../logger.js';
5
+ describe('PluginConfigValidator', () => {
6
+ let validator;
7
+ let logger;
8
+ beforeEach(() => {
9
+ logger = createLogger({ level: 'error' });
10
+ validator = new PluginConfigValidator(logger);
11
+ });
12
+ describe('validatePluginConfig', () => {
13
+ it('should validate valid configuration', () => {
14
+ const configSchema = z.object({
15
+ port: z.number().min(1000).max(65535),
16
+ host: z.string(),
17
+ debug: z.boolean().default(false),
18
+ });
19
+ const plugin = {
20
+ name: 'com.test.plugin',
21
+ version: '1.0.0',
22
+ configSchema,
23
+ init: async () => { },
24
+ };
25
+ const config = {
26
+ port: 3000,
27
+ host: 'localhost',
28
+ debug: true,
29
+ };
30
+ const validatedConfig = validator.validatePluginConfig(plugin, config);
31
+ expect(validatedConfig).toEqual(config);
32
+ });
33
+ it('should apply defaults for missing optional fields', () => {
34
+ const configSchema = z.object({
35
+ port: z.number().default(3000),
36
+ host: z.string().default('localhost'),
37
+ debug: z.boolean().default(false),
38
+ });
39
+ const plugin = {
40
+ name: 'com.test.plugin',
41
+ version: '1.0.0',
42
+ configSchema,
43
+ init: async () => { },
44
+ };
45
+ const config = {
46
+ port: 8080,
47
+ };
48
+ const validatedConfig = validator.validatePluginConfig(plugin, config);
49
+ expect(validatedConfig).toEqual({
50
+ port: 8080,
51
+ host: 'localhost',
52
+ debug: false,
53
+ });
54
+ });
55
+ it('should throw error for invalid configuration', () => {
56
+ const configSchema = z.object({
57
+ port: z.number().min(1000).max(65535),
58
+ host: z.string(),
59
+ });
60
+ const plugin = {
61
+ name: 'com.test.plugin',
62
+ version: '1.0.0',
63
+ configSchema,
64
+ init: async () => { },
65
+ };
66
+ const config = {
67
+ port: 100, // Invalid: < 1000
68
+ host: 'localhost',
69
+ };
70
+ expect(() => validator.validatePluginConfig(plugin, config)).toThrow();
71
+ });
72
+ it('should provide detailed error messages', () => {
73
+ const configSchema = z.object({
74
+ port: z.number().min(1000),
75
+ host: z.string().min(1),
76
+ });
77
+ const plugin = {
78
+ name: 'com.test.plugin',
79
+ version: '1.0.0',
80
+ configSchema,
81
+ init: async () => { },
82
+ };
83
+ const config = {
84
+ port: 100,
85
+ host: '',
86
+ };
87
+ try {
88
+ validator.validatePluginConfig(plugin, config);
89
+ expect.fail('Should have thrown validation error');
90
+ }
91
+ catch (error) {
92
+ const errorMessage = error.message;
93
+ expect(errorMessage).toContain('com.test.plugin');
94
+ expect(errorMessage).toContain('port');
95
+ expect(errorMessage).toContain('host');
96
+ }
97
+ });
98
+ it('should skip validation when no schema is provided', () => {
99
+ const plugin = {
100
+ name: 'com.test.plugin',
101
+ version: '1.0.0',
102
+ init: async () => { },
103
+ };
104
+ const config = { anything: 'goes' };
105
+ const validatedConfig = validator.validatePluginConfig(plugin, config);
106
+ expect(validatedConfig).toEqual(config);
107
+ });
108
+ });
109
+ describe('validatePartialConfig', () => {
110
+ it('should validate partial configuration', () => {
111
+ const configSchema = z.object({
112
+ port: z.number().min(1000),
113
+ host: z.string(),
114
+ debug: z.boolean(),
115
+ });
116
+ const plugin = {
117
+ name: 'com.test.plugin',
118
+ version: '1.0.0',
119
+ configSchema,
120
+ init: async () => { },
121
+ };
122
+ const partialConfig = {
123
+ port: 8080,
124
+ };
125
+ const validatedConfig = validator.validatePartialConfig(plugin, partialConfig);
126
+ expect(validatedConfig).toEqual({ port: 8080 });
127
+ });
128
+ });
129
+ describe('getDefaultConfig', () => {
130
+ it('should extract default configuration', () => {
131
+ const configSchema = z.object({
132
+ port: z.number().default(3000),
133
+ host: z.string().default('localhost'),
134
+ debug: z.boolean().default(false),
135
+ });
136
+ const plugin = {
137
+ name: 'com.test.plugin',
138
+ version: '1.0.0',
139
+ configSchema,
140
+ init: async () => { },
141
+ };
142
+ const defaults = validator.getDefaultConfig(plugin);
143
+ expect(defaults).toEqual({
144
+ port: 3000,
145
+ host: 'localhost',
146
+ debug: false,
147
+ });
148
+ });
149
+ it('should return undefined when schema requires fields', () => {
150
+ const configSchema = z.object({
151
+ port: z.number(),
152
+ host: z.string(),
153
+ });
154
+ const plugin = {
155
+ name: 'com.test.plugin',
156
+ version: '1.0.0',
157
+ configSchema,
158
+ init: async () => { },
159
+ };
160
+ const defaults = validator.getDefaultConfig(plugin);
161
+ expect(defaults).toBeUndefined();
162
+ });
163
+ });
164
+ describe('isConfigValid', () => {
165
+ it('should return true for valid config', () => {
166
+ const configSchema = z.object({
167
+ port: z.number(),
168
+ });
169
+ const plugin = {
170
+ name: 'com.test.plugin',
171
+ version: '1.0.0',
172
+ configSchema,
173
+ init: async () => { },
174
+ };
175
+ const isValid = validator.isConfigValid(plugin, { port: 3000 });
176
+ expect(isValid).toBe(true);
177
+ });
178
+ it('should return false for invalid config', () => {
179
+ const configSchema = z.object({
180
+ port: z.number(),
181
+ });
182
+ const plugin = {
183
+ name: 'com.test.plugin',
184
+ version: '1.0.0',
185
+ configSchema,
186
+ init: async () => { },
187
+ };
188
+ const isValid = validator.isConfigValid(plugin, { port: 'invalid' });
189
+ expect(isValid).toBe(false);
190
+ });
191
+ });
192
+ describe('getConfigErrors', () => {
193
+ it('should return errors for invalid config', () => {
194
+ const configSchema = z.object({
195
+ port: z.number().min(1000),
196
+ host: z.string().min(1),
197
+ });
198
+ const plugin = {
199
+ name: 'com.test.plugin',
200
+ version: '1.0.0',
201
+ configSchema,
202
+ init: async () => { },
203
+ };
204
+ const errors = validator.getConfigErrors(plugin, { port: 100, host: '' });
205
+ expect(errors).toHaveLength(2);
206
+ expect(errors[0].path).toBe('port');
207
+ expect(errors[1].path).toBe('host');
208
+ });
209
+ it('should return empty array for valid config', () => {
210
+ const configSchema = z.object({
211
+ port: z.number(),
212
+ });
213
+ const plugin = {
214
+ name: 'com.test.plugin',
215
+ version: '1.0.0',
216
+ configSchema,
217
+ init: async () => { },
218
+ };
219
+ const errors = validator.getConfigErrors(plugin, { port: 3000 });
220
+ expect(errors).toEqual([]);
221
+ });
222
+ });
223
+ });
@@ -0,0 +1,154 @@
1
+ import type { Logger } from '@objectstack/spec/contracts';
2
+ import type { PluginCapability } from '@objectstack/spec/system';
3
+ import type { PluginContext } from '../types.js';
4
+ /**
5
+ * Plugin Permissions
6
+ * Defines what actions a plugin is allowed to perform
7
+ */
8
+ export interface PluginPermissions {
9
+ canAccessService(serviceName: string): boolean;
10
+ canTriggerHook(hookName: string): boolean;
11
+ canReadFile(path: string): boolean;
12
+ canWriteFile(path: string): boolean;
13
+ canNetworkRequest(url: string): boolean;
14
+ }
15
+ /**
16
+ * Permission Check Result
17
+ */
18
+ export interface PermissionCheckResult {
19
+ allowed: boolean;
20
+ reason?: string;
21
+ capability?: string;
22
+ }
23
+ /**
24
+ * Plugin Permission Enforcer
25
+ *
26
+ * Implements capability-based security model to enforce:
27
+ * 1. Service access control - which services a plugin can use
28
+ * 2. Hook restrictions - which hooks a plugin can trigger
29
+ * 3. File system permissions - what files a plugin can read/write
30
+ * 4. Network permissions - what URLs a plugin can access
31
+ *
32
+ * Architecture:
33
+ * - Uses capability declarations from plugin manifest
34
+ * - Checks permissions before allowing operations
35
+ * - Logs all permission denials for security audit
36
+ * - Supports allowlist and denylist patterns
37
+ *
38
+ * Security Model:
39
+ * - Principle of least privilege - plugins get minimal permissions
40
+ * - Explicit declaration - all capabilities must be declared
41
+ * - Runtime enforcement - checks happen at operation time
42
+ * - Audit trail - all denials are logged
43
+ *
44
+ * Usage:
45
+ * ```typescript
46
+ * const enforcer = new PluginPermissionEnforcer(logger);
47
+ * enforcer.registerPluginPermissions(pluginName, capabilities);
48
+ * enforcer.enforceServiceAccess(pluginName, 'database');
49
+ * ```
50
+ */
51
+ export declare class PluginPermissionEnforcer {
52
+ private logger;
53
+ private permissionRegistry;
54
+ private capabilityRegistry;
55
+ constructor(logger: Logger);
56
+ /**
57
+ * Register plugin capabilities and build permission set
58
+ *
59
+ * @param pluginName - Plugin identifier
60
+ * @param capabilities - Array of capability declarations
61
+ */
62
+ registerPluginPermissions(pluginName: string, capabilities: PluginCapability[]): void;
63
+ /**
64
+ * Enforce service access permission
65
+ *
66
+ * @param pluginName - Plugin requesting access
67
+ * @param serviceName - Service to access
68
+ * @throws Error if permission denied
69
+ */
70
+ enforceServiceAccess(pluginName: string, serviceName: string): void;
71
+ /**
72
+ * Enforce hook trigger permission
73
+ *
74
+ * @param pluginName - Plugin requesting access
75
+ * @param hookName - Hook to trigger
76
+ * @throws Error if permission denied
77
+ */
78
+ enforceHookTrigger(pluginName: string, hookName: string): void;
79
+ /**
80
+ * Enforce file read permission
81
+ *
82
+ * @param pluginName - Plugin requesting access
83
+ * @param path - File path to read
84
+ * @throws Error if permission denied
85
+ */
86
+ enforceFileRead(pluginName: string, path: string): void;
87
+ /**
88
+ * Enforce file write permission
89
+ *
90
+ * @param pluginName - Plugin requesting access
91
+ * @param path - File path to write
92
+ * @throws Error if permission denied
93
+ */
94
+ enforceFileWrite(pluginName: string, path: string): void;
95
+ /**
96
+ * Enforce network request permission
97
+ *
98
+ * @param pluginName - Plugin requesting access
99
+ * @param url - URL to access
100
+ * @throws Error if permission denied
101
+ */
102
+ enforceNetworkRequest(pluginName: string, url: string): void;
103
+ /**
104
+ * Get plugin capabilities
105
+ *
106
+ * @param pluginName - Plugin identifier
107
+ * @returns Array of capabilities or undefined
108
+ */
109
+ getPluginCapabilities(pluginName: string): PluginCapability[] | undefined;
110
+ /**
111
+ * Get plugin permissions
112
+ *
113
+ * @param pluginName - Plugin identifier
114
+ * @returns Permissions object or undefined
115
+ */
116
+ getPluginPermissions(pluginName: string): PluginPermissions | undefined;
117
+ /**
118
+ * Revoke all permissions for a plugin
119
+ *
120
+ * @param pluginName - Plugin identifier
121
+ */
122
+ revokePermissions(pluginName: string): void;
123
+ private checkPermission;
124
+ private checkServiceAccess;
125
+ private checkHookAccess;
126
+ private checkFileRead;
127
+ private checkFileWrite;
128
+ private checkNetworkAccess;
129
+ }
130
+ /**
131
+ * Secure Plugin Context
132
+ * Wraps PluginContext with permission checks
133
+ */
134
+ export declare class SecurePluginContext implements PluginContext {
135
+ private pluginName;
136
+ private permissionEnforcer;
137
+ private baseContext;
138
+ constructor(pluginName: string, permissionEnforcer: PluginPermissionEnforcer, baseContext: PluginContext);
139
+ registerService(name: string, service: any): void;
140
+ getService<T>(name: string): T;
141
+ getServices(): Map<string, any>;
142
+ hook(name: string, handler: (...args: any[]) => void | Promise<void>): void;
143
+ trigger(name: string, ...args: any[]): Promise<void>;
144
+ get logger(): Logger;
145
+ getKernel(): import("../kernel.js").ObjectKernel;
146
+ }
147
+ /**
148
+ * Create a plugin permission enforcer
149
+ *
150
+ * @param logger - Logger instance
151
+ * @returns Plugin permission enforcer
152
+ */
153
+ export declare function createPluginPermissionEnforcer(logger: Logger): PluginPermissionEnforcer;
154
+ //# sourceMappingURL=plugin-permission-enforcer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-permission-enforcer.d.ts","sourceRoot":"","sources":["../../src/security/plugin-permission-enforcer.ts"],"names":[],"mappings":"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"}