xcomponent-ai 0.1.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 (49) hide show
  1. package/CONTRIBUTING.md +195 -0
  2. package/LICENSE +45 -0
  3. package/PERSISTENCE.md +774 -0
  4. package/README.md +594 -0
  5. package/dist/agents.d.ts +81 -0
  6. package/dist/agents.d.ts.map +1 -0
  7. package/dist/agents.js +405 -0
  8. package/dist/agents.js.map +1 -0
  9. package/dist/api.d.ts +36 -0
  10. package/dist/api.d.ts.map +1 -0
  11. package/dist/api.js +404 -0
  12. package/dist/api.js.map +1 -0
  13. package/dist/cli.d.ts +7 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +437 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/component-registry.d.ts +190 -0
  18. package/dist/component-registry.d.ts.map +1 -0
  19. package/dist/component-registry.js +382 -0
  20. package/dist/component-registry.js.map +1 -0
  21. package/dist/fsm-runtime.d.ts +263 -0
  22. package/dist/fsm-runtime.d.ts.map +1 -0
  23. package/dist/fsm-runtime.js +1122 -0
  24. package/dist/fsm-runtime.js.map +1 -0
  25. package/dist/index.d.ts +23 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +56 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/monitoring.d.ts +68 -0
  30. package/dist/monitoring.d.ts.map +1 -0
  31. package/dist/monitoring.js +176 -0
  32. package/dist/monitoring.js.map +1 -0
  33. package/dist/persistence.d.ts +100 -0
  34. package/dist/persistence.d.ts.map +1 -0
  35. package/dist/persistence.js +270 -0
  36. package/dist/persistence.js.map +1 -0
  37. package/dist/timer-wheel.d.ts +85 -0
  38. package/dist/timer-wheel.d.ts.map +1 -0
  39. package/dist/timer-wheel.js +181 -0
  40. package/dist/timer-wheel.js.map +1 -0
  41. package/dist/types.d.ts +404 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +40 -0
  44. package/dist/types.js.map +1 -0
  45. package/dist/websockets.d.ts +32 -0
  46. package/dist/websockets.d.ts.map +1 -0
  47. package/dist/websockets.js +117 -0
  48. package/dist/websockets.js.map +1 -0
  49. package/package.json +103 -0
@@ -0,0 +1,382 @@
1
+ "use strict";
2
+ /**
3
+ * Component Registry for Cross-Component Communication
4
+ *
5
+ * Manages multiple FSMRuntimes (components) and enables communication
6
+ * between them, reproducing XComponent's cross-component messaging pattern.
7
+ *
8
+ * Features:
9
+ * - Register/unregister components
10
+ * - Route events between components
11
+ * - Broadcast across components
12
+ * - Property-based routing across component boundaries
13
+ * - Instance lookup across all components
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.ComponentRegistry = void 0;
17
+ const events_1 = require("events");
18
+ /**
19
+ * ComponentRegistry manages multiple components and enables cross-component communication
20
+ */
21
+ class ComponentRegistry extends events_1.EventEmitter {
22
+ runtimes;
23
+ components;
24
+ constructor() {
25
+ super();
26
+ this.runtimes = new Map();
27
+ this.components = new Map();
28
+ }
29
+ /**
30
+ * Register a component with its runtime
31
+ *
32
+ * @param component Component definition
33
+ * @param runtime FSM runtime instance
34
+ */
35
+ registerComponent(component, runtime) {
36
+ if (this.runtimes.has(component.name)) {
37
+ throw new Error(`Component ${component.name} is already registered`);
38
+ }
39
+ this.runtimes.set(component.name, runtime);
40
+ this.components.set(component.name, component);
41
+ // Forward runtime events
42
+ this.forwardRuntimeEvents(component.name, runtime);
43
+ this.emit('component_registered', {
44
+ componentName: component.name,
45
+ version: component.version,
46
+ machineCount: component.stateMachines.length,
47
+ });
48
+ }
49
+ /**
50
+ * Unregister a component
51
+ *
52
+ * @param componentName Component name
53
+ */
54
+ unregisterComponent(componentName) {
55
+ const runtime = this.runtimes.get(componentName);
56
+ if (!runtime) {
57
+ throw new Error(`Component ${componentName} not found`);
58
+ }
59
+ // Cleanup runtime
60
+ runtime.dispose();
61
+ this.runtimes.delete(componentName);
62
+ this.components.delete(componentName);
63
+ this.emit('component_unregistered', { componentName });
64
+ }
65
+ /**
66
+ * Get runtime for a component
67
+ *
68
+ * @param componentName Component name
69
+ * @returns FSMRuntime or undefined
70
+ */
71
+ getRuntime(componentName) {
72
+ return this.runtimes.get(componentName);
73
+ }
74
+ /**
75
+ * Get component definition
76
+ *
77
+ * @param componentName Component name
78
+ * @returns Component or undefined
79
+ */
80
+ getComponent(componentName) {
81
+ return this.components.get(componentName);
82
+ }
83
+ /**
84
+ * Check if component is registered
85
+ *
86
+ * @param componentName Component name
87
+ * @returns true if registered
88
+ */
89
+ hasComponent(componentName) {
90
+ return this.runtimes.has(componentName);
91
+ }
92
+ /**
93
+ * Get all registered component names
94
+ *
95
+ * @returns Array of component names
96
+ */
97
+ getComponentNames() {
98
+ return Array.from(this.runtimes.keys());
99
+ }
100
+ /**
101
+ * Get component information
102
+ *
103
+ * @param componentName Component name
104
+ * @returns Component info or undefined
105
+ */
106
+ getComponentInfo(componentName) {
107
+ const runtime = this.runtimes.get(componentName);
108
+ const component = this.components.get(componentName);
109
+ if (!runtime || !component) {
110
+ return undefined;
111
+ }
112
+ return {
113
+ name: component.name,
114
+ runtime,
115
+ version: component.version,
116
+ machineCount: component.stateMachines.length,
117
+ instanceCount: runtime.getAllInstances().length,
118
+ };
119
+ }
120
+ /**
121
+ * Get all component information
122
+ *
123
+ * @returns Array of component info
124
+ */
125
+ getAllComponentInfo() {
126
+ return this.getComponentNames()
127
+ .map(name => this.getComponentInfo(name))
128
+ .filter((info) => info !== undefined);
129
+ }
130
+ /**
131
+ * Send event to instance in any component
132
+ *
133
+ * @param componentName Target component name
134
+ * @param instanceId Instance ID
135
+ * @param event Event to send
136
+ */
137
+ async sendEventToComponent(componentName, instanceId, event) {
138
+ const runtime = this.runtimes.get(componentName);
139
+ if (!runtime) {
140
+ throw new Error(`Component ${componentName} not found`);
141
+ }
142
+ await runtime.sendEvent(instanceId, event);
143
+ }
144
+ /**
145
+ * Broadcast event to instances in a specific component
146
+ *
147
+ * @param componentName Target component name
148
+ * @param machineName Target machine name
149
+ * @param currentState Current state filter
150
+ * @param event Event to broadcast
151
+ * @returns Number of instances processed
152
+ */
153
+ async broadcastToComponent(componentName, machineName, currentState, event) {
154
+ const runtime = this.runtimes.get(componentName);
155
+ if (!runtime) {
156
+ throw new Error(`Component ${componentName} not found`);
157
+ }
158
+ return await runtime.broadcastEvent(machineName, currentState, event);
159
+ }
160
+ /**
161
+ * Broadcast event to all components
162
+ *
163
+ * Useful for system-wide notifications (e.g., shutdown, maintenance mode)
164
+ *
165
+ * @param machineName Target machine name
166
+ * @param currentState Current state filter
167
+ * @param event Event to broadcast
168
+ * @returns Total number of instances processed across all components
169
+ */
170
+ async broadcastToAll(machineName, currentState, event) {
171
+ let total = 0;
172
+ for (const [componentName, runtime] of this.runtimes) {
173
+ try {
174
+ const count = await runtime.broadcastEvent(machineName, currentState, event);
175
+ total += count;
176
+ }
177
+ catch (error) {
178
+ this.emit('broadcast_error', {
179
+ componentName,
180
+ machineName,
181
+ currentState,
182
+ error: error instanceof Error ? error.message : String(error),
183
+ });
184
+ }
185
+ }
186
+ return total;
187
+ }
188
+ /**
189
+ * Create instance in a specific component
190
+ *
191
+ * @param componentName Target component name
192
+ * @param machineName Machine name
193
+ * @param initialContext Initial context
194
+ * @returns Instance ID
195
+ */
196
+ createInstanceInComponent(componentName, machineName, initialContext) {
197
+ const runtime = this.runtimes.get(componentName);
198
+ if (!runtime) {
199
+ throw new Error(`Component ${componentName} not found`);
200
+ }
201
+ return runtime.createInstance(machineName, initialContext);
202
+ }
203
+ /**
204
+ * Find instance by ID across all components
205
+ *
206
+ * @param instanceId Instance ID
207
+ * @returns Instance and component name, or undefined
208
+ */
209
+ findInstance(instanceId) {
210
+ for (const [componentName, runtime] of this.runtimes) {
211
+ const instance = runtime.getInstance(instanceId);
212
+ if (instance) {
213
+ return { instance, componentName };
214
+ }
215
+ }
216
+ return undefined;
217
+ }
218
+ /**
219
+ * Get all instances across all components
220
+ *
221
+ * @returns Array of instances with component name
222
+ */
223
+ getAllInstances() {
224
+ const result = [];
225
+ for (const [componentName, runtime] of this.runtimes) {
226
+ const instances = runtime.getAllInstances();
227
+ instances.forEach(instance => {
228
+ result.push({ instance, componentName });
229
+ });
230
+ }
231
+ return result;
232
+ }
233
+ /**
234
+ * Get statistics across all components
235
+ *
236
+ * @returns Registry statistics
237
+ */
238
+ getStats() {
239
+ const components = this.getAllComponentInfo();
240
+ return {
241
+ componentCount: components.length,
242
+ totalInstances: components.reduce((sum, c) => sum + c.instanceCount, 0),
243
+ totalMachines: components.reduce((sum, c) => sum + c.machineCount, 0),
244
+ components: components.map(c => ({
245
+ name: c.name,
246
+ instances: c.instanceCount,
247
+ machines: c.machineCount,
248
+ })),
249
+ };
250
+ }
251
+ /**
252
+ * Trace event causality across all components
253
+ *
254
+ * Follows event chains across component boundaries to show
255
+ * complete system-wide workflows
256
+ *
257
+ * @param eventId Starting event ID
258
+ * @returns Array of persisted events showing full causality chain
259
+ */
260
+ async traceEventAcrossComponents(eventId) {
261
+ const allEvents = [];
262
+ const eventMap = new Map();
263
+ // Collect all events from all components
264
+ for (const [, runtime] of this.runtimes) {
265
+ try {
266
+ const events = await runtime.getAllPersistedEvents();
267
+ events.forEach(event => {
268
+ eventMap.set(event.id, event);
269
+ allEvents.push(event);
270
+ });
271
+ }
272
+ catch {
273
+ // Component may not have persistence enabled, skip
274
+ continue;
275
+ }
276
+ }
277
+ // Build causality chain
278
+ const result = [];
279
+ const visited = new Set();
280
+ const trace = (id) => {
281
+ if (visited.has(id))
282
+ return;
283
+ visited.add(id);
284
+ const event = eventMap.get(id);
285
+ if (!event)
286
+ return;
287
+ result.push(event);
288
+ // Trace caused events recursively
289
+ if (event.caused && event.caused.length > 0) {
290
+ for (const causedId of event.caused) {
291
+ trace(causedId);
292
+ }
293
+ }
294
+ };
295
+ trace(eventId);
296
+ return result;
297
+ }
298
+ /**
299
+ * Get all persisted events across all components
300
+ *
301
+ * Useful for system-wide analysis, debugging, and monitoring
302
+ *
303
+ * @returns Array of all persisted events from all components
304
+ */
305
+ async getAllPersistedEvents() {
306
+ const eventMap = new Map();
307
+ for (const [, runtime] of this.runtimes) {
308
+ try {
309
+ const events = await runtime.getAllPersistedEvents();
310
+ // Deduplicate by event ID (in case components share event store)
311
+ events.forEach(event => eventMap.set(event.id, event));
312
+ }
313
+ catch {
314
+ // Component may not have persistence enabled, skip
315
+ continue;
316
+ }
317
+ }
318
+ // Convert to array and sort by timestamp
319
+ return Array.from(eventMap.values()).sort((a, b) => a.persistedAt - b.persistedAt);
320
+ }
321
+ /**
322
+ * Get persisted events for a specific instance across components
323
+ *
324
+ * @param instanceId Instance ID to query
325
+ * @returns Array of persisted events for the instance
326
+ */
327
+ async getInstanceHistory(instanceId) {
328
+ for (const [, runtime] of this.runtimes) {
329
+ try {
330
+ const instance = runtime.getInstance(instanceId);
331
+ if (instance) {
332
+ return await runtime.getInstanceHistory(instanceId);
333
+ }
334
+ }
335
+ catch {
336
+ continue;
337
+ }
338
+ }
339
+ return [];
340
+ }
341
+ /**
342
+ * Forward runtime events to registry
343
+ */
344
+ forwardRuntimeEvents(componentName, runtime) {
345
+ // Forward all runtime events with component context
346
+ const eventsToForward = [
347
+ 'state_change',
348
+ 'instance_created',
349
+ 'instance_disposed',
350
+ 'instance_error',
351
+ 'guard_failed',
352
+ 'cascade_completed',
353
+ 'cascade_error',
354
+ ];
355
+ eventsToForward.forEach(eventName => {
356
+ runtime.on(eventName, (data) => {
357
+ this.emit(eventName, {
358
+ ...data,
359
+ componentName,
360
+ });
361
+ });
362
+ });
363
+ }
364
+ /**
365
+ * Dispose all components and cleanup
366
+ */
367
+ dispose() {
368
+ for (const [componentName, runtime] of this.runtimes) {
369
+ try {
370
+ runtime.dispose();
371
+ }
372
+ catch (error) {
373
+ console.error(`Error disposing component ${componentName}:`, error);
374
+ }
375
+ }
376
+ this.runtimes.clear();
377
+ this.components.clear();
378
+ this.removeAllListeners();
379
+ }
380
+ }
381
+ exports.ComponentRegistry = ComponentRegistry;
382
+ //# sourceMappingURL=component-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-registry.js","sourceRoot":"","sources":["../src/component-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * FSM Runtime Engine
3
+ * Implements XComponent-inspired state machine execution with multi-instance support
4
+ */
5
+ import { EventEmitter } from 'events';
6
+ import { Component, Transition, FSMEvent, FSMInstance, PersistenceConfig } from './types';
7
+ import { PersistenceManager } from './persistence';
8
+ import type { ComponentRegistry } from './component-registry';
9
+ /**
10
+ * FSM Runtime Engine
11
+ * Manages multiple FSM instances with event-driven execution
12
+ */
13
+ export declare class FSMRuntime extends EventEmitter {
14
+ private instances;
15
+ private machines;
16
+ private timerWheel;
17
+ private timeoutTasks;
18
+ private persistence;
19
+ private componentDef;
20
+ private registry?;
21
+ private machineIndex;
22
+ private stateIndex;
23
+ private propertyIndex;
24
+ constructor(component: Component, persistenceConfig?: PersistenceConfig);
25
+ /**
26
+ * Create a new FSM instance
27
+ *
28
+ * If the state machine defines a publicMemberType (XComponent pattern),
29
+ * the instance will have separate publicMember and internalMember.
30
+ * Otherwise, it uses the simple context pattern.
31
+ *
32
+ * @param machineName State machine name
33
+ * @param initialContext Initial context or public member data
34
+ * @returns Instance ID
35
+ */
36
+ createInstance(machineName: string, initialContext?: Record<string, any>): string;
37
+ /**
38
+ * Send event to an instance
39
+ */
40
+ sendEvent(instanceId: string, event: FSMEvent): Promise<void>;
41
+ /**
42
+ * Broadcast event to all matching instances (XComponent-style property matching)
43
+ *
44
+ * This method implements XComponent's property-based instance routing:
45
+ * - Finds all instances of the target machine in the specified state
46
+ * - Evaluates matching rules (property equality checks)
47
+ * - Routes event to ALL instances where matching rules pass
48
+ *
49
+ * Example:
50
+ * // 100 Order instances exist
51
+ * // Event: ExecutionInput { OrderId: 42, Quantity: 500 }
52
+ * // Matching rule: ExecutionInput.OrderId = Order.Id
53
+ * // → Automatically routes to Order instance with Id=42
54
+ *
55
+ * @param machineName Target state machine name
56
+ * @param currentState Current state filter (only instances in this state)
57
+ * @param event Event to broadcast
58
+ * @returns Number of instances that received the event
59
+ */
60
+ broadcastEvent(machineName: string, currentState: string, event: FSMEvent): Promise<number>;
61
+ /**
62
+ * Find instances that match the property matching rules
63
+ *
64
+ * @param machineName Target machine name
65
+ * @param currentState Current state filter
66
+ * @param event Event to match against
67
+ * @param matchingRules Property matching rules
68
+ * @returns Array of matching instances
69
+ */
70
+ private findMatchingInstances;
71
+ /**
72
+ * Evaluate matching rules for an instance
73
+ *
74
+ * @param instance FSM instance to check
75
+ * @param event Event to match against
76
+ * @param matchingRules Matching rules to evaluate
77
+ * @returns true if all matching rules pass
78
+ */
79
+ private evaluateMatchingRules;
80
+ /**
81
+ * Get nested property value from object using dot notation
82
+ *
83
+ * Example: getNestedProperty({ customer: { id: 42 } }, "customer.id") → 42
84
+ *
85
+ * @param obj Object to get property from
86
+ * @param path Property path (dot notation)
87
+ * @returns Property value or undefined
88
+ */
89
+ private getNestedProperty;
90
+ /**
91
+ * Find applicable transition with support for specific triggering rules
92
+ *
93
+ * When multiple transitions exist from the same state with the same event,
94
+ * specific triggering rules differentiate them (XComponent pattern).
95
+ *
96
+ * @param machine State machine
97
+ * @param currentState Current state name
98
+ * @param event Event to match
99
+ * @param instanceContext Instance context for specific triggering rule evaluation
100
+ * @returns Matching transition or null
101
+ */
102
+ private findTransition;
103
+ /**
104
+ * Evaluate guards
105
+ */
106
+ private evaluateGuards;
107
+ /**
108
+ * Execute transition
109
+ *
110
+ * Creates a Sender instance and passes it to triggered methods,
111
+ * enabling cross-instance communication (XComponent pattern)
112
+ */
113
+ private executeTransition;
114
+ /**
115
+ * Setup timeout transitions
116
+ */
117
+ /**
118
+ * Setup timeout transitions using timer wheel (performance optimized)
119
+ *
120
+ * Instead of creating one setTimeout per instance (O(n) timers),
121
+ * use a single timer wheel that manages all timeouts (O(1) timer).
122
+ */
123
+ private setupTimeouts;
124
+ /**
125
+ * Setup auto-transitions (XComponent-style automatic transitions)
126
+ *
127
+ * Auto-transitions are triggered automatically when entering a state,
128
+ * typically with timeoutMs: 0 for immediate execution.
129
+ *
130
+ * Example:
131
+ * - from: Validated
132
+ * to: Processing
133
+ * event: AUTO_PROCESS
134
+ * type: auto
135
+ * timeoutMs: 0
136
+ */
137
+ private setupAutoTransitions;
138
+ /**
139
+ * Setup cascading rules engine (XComponent pattern)
140
+ *
141
+ * Listens to state_change events and automatically triggers cross-machine updates
142
+ * based on cascading rules defined in state definitions.
143
+ */
144
+ private setupCascadingEngine;
145
+ /**
146
+ * Add instance to indexes (for O(1) lookup)
147
+ * Performance optimization: XComponent hash-based matching
148
+ */
149
+ private addToIndex;
150
+ /**
151
+ * Remove instance from indexes
152
+ */
153
+ private removeFromIndex;
154
+ /**
155
+ * Update state index when state changes
156
+ */
157
+ private updateIndexOnStateChange;
158
+ /**
159
+ * Process a single cascading rule
160
+ *
161
+ * Applies payload templating and broadcasts event to target instances
162
+ * If matchingRules exist, uses property-based routing
163
+ * Otherwise, sends to ALL instances in the target state
164
+ */
165
+ private processCascadingRule;
166
+ /**
167
+ * Apply payload template with {{property}} syntax
168
+ *
169
+ * Replaces {{property}} with actual values from source context
170
+ *
171
+ * Example:
172
+ * payload: { orderId: "{{Id}}", total: "{{Total}}" }
173
+ * context: { Id: 42, Total: 99.99 }
174
+ * result: { orderId: 42, total: 99.99 }
175
+ */
176
+ private applyPayloadTemplate;
177
+ /**
178
+ * Clear timeouts for instance (using timer wheel)
179
+ */
180
+ private clearTimeouts;
181
+ /**
182
+ * Get instance
183
+ */
184
+ getInstance(instanceId: string): FSMInstance | undefined;
185
+ /**
186
+ * Get all instances
187
+ */
188
+ getAllInstances(): FSMInstance[];
189
+ /**
190
+ * Get instances by machine
191
+ */
192
+ getInstancesByMachine(machineName: string): FSMInstance[];
193
+ /**
194
+ * Simulate FSM path
195
+ */
196
+ simulatePath(machineName: string, events: FSMEvent[]): {
197
+ success: boolean;
198
+ path: string[];
199
+ error?: string;
200
+ };
201
+ /**
202
+ * Restore all instances from snapshots (for long-running workflows)
203
+ *
204
+ * Called after restart to restore system state from persistence
205
+ *
206
+ * Example:
207
+ * const runtime = new FSMRuntime(component, { snapshots: true });
208
+ * await runtime.restore();
209
+ * // System is now in same state as before restart
210
+ */
211
+ restore(): Promise<{
212
+ restored: number;
213
+ failed: number;
214
+ }>;
215
+ /**
216
+ * Resynchronize timeouts after restart
217
+ *
218
+ * Recalculates timeout transitions based on current state and elapsed time
219
+ * Handles expired timeouts by triggering them immediately
220
+ */
221
+ resynchronizeTimeouts(): Promise<{
222
+ synced: number;
223
+ expired: number;
224
+ }>;
225
+ /**
226
+ * Get persistence manager (for testing/inspection)
227
+ */
228
+ getPersistenceManager(): PersistenceManager | null;
229
+ /**
230
+ * Get instance event history (for audit/debug)
231
+ */
232
+ getInstanceHistory(instanceId: string): Promise<import('./types').PersistedEvent[]>;
233
+ /**
234
+ * Get all persisted events for this component
235
+ */
236
+ getAllPersistedEvents(): Promise<import('./types').PersistedEvent[]>;
237
+ /**
238
+ * Trace event causality chain (for debugging cascades/sender)
239
+ */
240
+ traceEventCausality(eventId: string): Promise<import('./types').PersistedEvent[]>;
241
+ /**
242
+ * Get component definition
243
+ */
244
+ getComponent(): Component;
245
+ /**
246
+ * Set component registry for cross-component communication
247
+ */
248
+ setRegistry(registry: ComponentRegistry): void;
249
+ /**
250
+ * Get available transitions from current state of an instance
251
+ */
252
+ getAvailableTransitions(instanceId: string): Transition[];
253
+ /**
254
+ * Stop the runtime and cleanup resources
255
+ * Important: Call this when done to prevent memory leaks from timer wheel
256
+ */
257
+ dispose(): void;
258
+ }
259
+ /**
260
+ * Load component from object
261
+ */
262
+ export declare function loadComponent(data: any): Component;
263
+ //# sourceMappingURL=fsm-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsm-runtime.d.ts","sourceRoot":"","sources":["../src/fsm-runtime.ts"],"names":[],"mappings":"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"}