@scenetest/scenes 0.1.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/LICENSE +21 -0
- package/dist/__tests__/devices.test.d.ts +2 -0
- package/dist/__tests__/devices.test.d.ts.map +1 -0
- package/dist/__tests__/devices.test.js +117 -0
- package/dist/__tests__/devices.test.js.map +1 -0
- package/dist/__tests__/dsl.test.d.ts +2 -0
- package/dist/__tests__/dsl.test.d.ts.map +1 -0
- package/dist/__tests__/dsl.test.js +385 -0
- package/dist/__tests__/dsl.test.js.map +1 -0
- package/dist/__tests__/markdown-scene.test.d.ts +2 -0
- package/dist/__tests__/markdown-scene.test.d.ts.map +1 -0
- package/dist/__tests__/markdown-scene.test.js +508 -0
- package/dist/__tests__/markdown-scene.test.js.map +1 -0
- package/dist/__tests__/reactive.test.d.ts +2 -0
- package/dist/__tests__/reactive.test.d.ts.map +1 -0
- package/dist/__tests__/reactive.test.js +383 -0
- package/dist/__tests__/reactive.test.js.map +1 -0
- package/dist/__tests__/swarm.test.d.ts +2 -0
- package/dist/__tests__/swarm.test.d.ts.map +1 -0
- package/dist/__tests__/swarm.test.js +214 -0
- package/dist/__tests__/swarm.test.js.map +1 -0
- package/dist/actor.d.ts +104 -0
- package/dist/actor.d.ts.map +1 -0
- package/dist/actor.js +527 -0
- package/dist/actor.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +273 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +120 -0
- package/dist/config.js.map +1 -0
- package/dist/devices.d.ts +55 -0
- package/dist/devices.d.ts.map +1 -0
- package/dist/devices.js +167 -0
- package/dist/devices.js.map +1 -0
- package/dist/dsl.d.ts +99 -0
- package/dist/dsl.d.ts.map +1 -0
- package/dist/dsl.js +247 -0
- package/dist/dsl.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +9 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +27 -0
- package/dist/init.js.map +1 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +10 -0
- package/dist/loader.js.map +1 -0
- package/dist/markdown-scene.d.ts +120 -0
- package/dist/markdown-scene.d.ts.map +1 -0
- package/dist/markdown-scene.js +452 -0
- package/dist/markdown-scene.js.map +1 -0
- package/dist/message-bus.d.ts +31 -0
- package/dist/message-bus.d.ts.map +1 -0
- package/dist/message-bus.js +74 -0
- package/dist/message-bus.js.map +1 -0
- package/dist/reactive.d.ts +267 -0
- package/dist/reactive.d.ts.map +1 -0
- package/dist/reactive.js +779 -0
- package/dist/reactive.js.map +1 -0
- package/dist/runner.d.ts +51 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +306 -0
- package/dist/runner.js.map +1 -0
- package/dist/scene.d.ts +40 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +110 -0
- package/dist/scene.js.map +1 -0
- package/dist/selectors.d.ts +57 -0
- package/dist/selectors.d.ts.map +1 -0
- package/dist/selectors.js +193 -0
- package/dist/selectors.js.map +1 -0
- package/dist/swarm.d.ts +64 -0
- package/dist/swarm.d.ts.map +1 -0
- package/dist/swarm.js +306 -0
- package/dist/swarm.js.map +1 -0
- package/dist/team-manager.d.ts +120 -0
- package/dist/team-manager.d.ts.map +1 -0
- package/dist/team-manager.js +267 -0
- package/dist/team-manager.js.map +1 -0
- package/dist/types.d.ts +653 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { Browser, Page } from 'playwright';
|
|
2
|
+
import type { TeamConfig, ActorConfig, AssertionResult, TimelineEntry, ScriptWarning } from './types.js';
|
|
3
|
+
import type { DeviceProfile } from './devices.js';
|
|
4
|
+
import { DeviceRotation } from './devices.js';
|
|
5
|
+
import { SequentialActorHandleImpl } from './actor.js';
|
|
6
|
+
import { MessageBus } from './message-bus.js';
|
|
7
|
+
/**
|
|
8
|
+
* Manages team assignment and lifecycle.
|
|
9
|
+
*
|
|
10
|
+
* Each scene gets exclusive use of one team.
|
|
11
|
+
* The team manager tracks which teams are in use.
|
|
12
|
+
*/
|
|
13
|
+
export declare class TeamManager {
|
|
14
|
+
private teams;
|
|
15
|
+
private inUse;
|
|
16
|
+
private browser;
|
|
17
|
+
private deviceRotation;
|
|
18
|
+
constructor(teams: TeamConfig[]);
|
|
19
|
+
/**
|
|
20
|
+
* Set the browser instance to use for creating contexts
|
|
21
|
+
*/
|
|
22
|
+
setBrowser(browser: Browser): void;
|
|
23
|
+
/**
|
|
24
|
+
* Enable device rotation with the given profiles (or built-in defaults).
|
|
25
|
+
*/
|
|
26
|
+
setDeviceRotation(rotation: DeviceRotation): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get the current device rotation instance, if any.
|
|
29
|
+
*/
|
|
30
|
+
getDeviceRotation(): DeviceRotation | null;
|
|
31
|
+
/**
|
|
32
|
+
* Get the number of available teams
|
|
33
|
+
*/
|
|
34
|
+
get availableCount(): number;
|
|
35
|
+
/**
|
|
36
|
+
* Get the total number of teams
|
|
37
|
+
*/
|
|
38
|
+
get totalCount(): number;
|
|
39
|
+
/**
|
|
40
|
+
* Acquire an available team for exclusive use.
|
|
41
|
+
* Returns the team index, or null if none available.
|
|
42
|
+
*/
|
|
43
|
+
acquire(): number | null;
|
|
44
|
+
/**
|
|
45
|
+
* Wait for a team to become available.
|
|
46
|
+
*/
|
|
47
|
+
acquireWait(timeout?: number): Promise<number>;
|
|
48
|
+
/**
|
|
49
|
+
* Release a team back to the pool
|
|
50
|
+
*/
|
|
51
|
+
release(teamIndex: number): void;
|
|
52
|
+
/**
|
|
53
|
+
* Get the team config for a given index
|
|
54
|
+
*/
|
|
55
|
+
getTeam(teamIndex: number): TeamConfig;
|
|
56
|
+
/**
|
|
57
|
+
* Get actor config for a role in a team
|
|
58
|
+
*/
|
|
59
|
+
getActorConfig(teamIndex: number, role: string): ActorConfig;
|
|
60
|
+
/**
|
|
61
|
+
* Create a scene session with a team
|
|
62
|
+
*/
|
|
63
|
+
createSession(teamIndex: number, actionTimeout: number, warnAfter: number, baseUrl?: string): Promise<TeamSession>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A session for a scene with an assigned team.
|
|
67
|
+
* Manages browser contexts and actors for the scene.
|
|
68
|
+
*/
|
|
69
|
+
export declare class TeamSession {
|
|
70
|
+
private browser;
|
|
71
|
+
private team;
|
|
72
|
+
readonly teamIndex: number;
|
|
73
|
+
readonly actionTimeout: number;
|
|
74
|
+
readonly warnAfter: number;
|
|
75
|
+
private baseUrl?;
|
|
76
|
+
private deviceRotation?;
|
|
77
|
+
private contexts;
|
|
78
|
+
private actors;
|
|
79
|
+
private actorDevices;
|
|
80
|
+
private bus;
|
|
81
|
+
readonly timeline: TimelineEntry[];
|
|
82
|
+
readonly assertions: AssertionResult[];
|
|
83
|
+
readonly warnings: ScriptWarning[];
|
|
84
|
+
constructor(browser: Browser, team: TeamConfig, teamIndex: number, actionTimeout: number, warnAfter: number, baseUrl?: string | undefined, deviceRotation?: (DeviceRotation | null) | undefined);
|
|
85
|
+
/**
|
|
86
|
+
* Get the actor config for a role (sync — no browser setup).
|
|
87
|
+
* Used by flow() to create reactive handles before browser init.
|
|
88
|
+
*/
|
|
89
|
+
getActorConfig(role: string): ActorConfig;
|
|
90
|
+
/**
|
|
91
|
+
* Create a browser context + page for a role and wire up assertion collection.
|
|
92
|
+
* Returns the Page. Used by flow() to initialize actors after declaration.
|
|
93
|
+
*/
|
|
94
|
+
createPage(role: string): Promise<Page>;
|
|
95
|
+
/**
|
|
96
|
+
* Get or create an actor for a role
|
|
97
|
+
*/
|
|
98
|
+
getActor(role: string): Promise<SequentialActorHandleImpl>;
|
|
99
|
+
/**
|
|
100
|
+
* Get the device assigned to an actor role
|
|
101
|
+
*/
|
|
102
|
+
getActorDevice(role: string): DeviceProfile | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Get all actor-device assignments
|
|
105
|
+
*/
|
|
106
|
+
getActorDevices(): Map<string, DeviceProfile>;
|
|
107
|
+
/**
|
|
108
|
+
* Get the message bus for this session
|
|
109
|
+
*/
|
|
110
|
+
getMessageBus(): MessageBus;
|
|
111
|
+
/**
|
|
112
|
+
* Get all actors created in this session
|
|
113
|
+
*/
|
|
114
|
+
getActors(): Map<string, SequentialActorHandleImpl>;
|
|
115
|
+
/**
|
|
116
|
+
* Close all browser contexts
|
|
117
|
+
*/
|
|
118
|
+
close(): Promise<void>;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=team-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-manager.d.ts","sourceRoot":"","sources":["../src/team-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { SequentialActorHandleImpl } from './actor.js';
|
|
2
|
+
import { MessageBus } from './message-bus.js';
|
|
3
|
+
/**
|
|
4
|
+
* Manages team assignment and lifecycle.
|
|
5
|
+
*
|
|
6
|
+
* Each scene gets exclusive use of one team.
|
|
7
|
+
* The team manager tracks which teams are in use.
|
|
8
|
+
*/
|
|
9
|
+
export class TeamManager {
|
|
10
|
+
teams;
|
|
11
|
+
inUse = new Set();
|
|
12
|
+
browser = null;
|
|
13
|
+
deviceRotation = null;
|
|
14
|
+
constructor(teams) {
|
|
15
|
+
this.teams = teams;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Set the browser instance to use for creating contexts
|
|
19
|
+
*/
|
|
20
|
+
setBrowser(browser) {
|
|
21
|
+
this.browser = browser;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Enable device rotation with the given profiles (or built-in defaults).
|
|
25
|
+
*/
|
|
26
|
+
setDeviceRotation(rotation) {
|
|
27
|
+
this.deviceRotation = rotation;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the current device rotation instance, if any.
|
|
31
|
+
*/
|
|
32
|
+
getDeviceRotation() {
|
|
33
|
+
return this.deviceRotation;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the number of available teams
|
|
37
|
+
*/
|
|
38
|
+
get availableCount() {
|
|
39
|
+
return this.teams.length - this.inUse.size;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get the total number of teams
|
|
43
|
+
*/
|
|
44
|
+
get totalCount() {
|
|
45
|
+
return this.teams.length;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Acquire an available team for exclusive use.
|
|
49
|
+
* Returns the team index, or null if none available.
|
|
50
|
+
*/
|
|
51
|
+
acquire() {
|
|
52
|
+
for (let i = 0; i < this.teams.length; i++) {
|
|
53
|
+
if (!this.inUse.has(i)) {
|
|
54
|
+
this.inUse.add(i);
|
|
55
|
+
return i;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Wait for a team to become available.
|
|
62
|
+
*/
|
|
63
|
+
async acquireWait(timeout = 60000) {
|
|
64
|
+
const start = Date.now();
|
|
65
|
+
while (true) {
|
|
66
|
+
const index = this.acquire();
|
|
67
|
+
if (index !== null) {
|
|
68
|
+
return index;
|
|
69
|
+
}
|
|
70
|
+
if (Date.now() - start > timeout) {
|
|
71
|
+
throw new Error(`Timeout waiting for available team (${timeout}ms)`);
|
|
72
|
+
}
|
|
73
|
+
// Wait a bit before trying again
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Release a team back to the pool
|
|
79
|
+
*/
|
|
80
|
+
release(teamIndex) {
|
|
81
|
+
this.inUse.delete(teamIndex);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get the team config for a given index
|
|
85
|
+
*/
|
|
86
|
+
getTeam(teamIndex) {
|
|
87
|
+
if (teamIndex < 0 || teamIndex >= this.teams.length) {
|
|
88
|
+
throw new Error(`Invalid team index: ${teamIndex}`);
|
|
89
|
+
}
|
|
90
|
+
return this.teams[teamIndex];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get actor config for a role in a team
|
|
94
|
+
*/
|
|
95
|
+
getActorConfig(teamIndex, role) {
|
|
96
|
+
const team = this.getTeam(teamIndex);
|
|
97
|
+
const actor = team[role];
|
|
98
|
+
if (!actor) {
|
|
99
|
+
throw new Error(`Role "${role}" not found in team ${teamIndex}. Available roles: ${Object.keys(team).join(', ')}`);
|
|
100
|
+
}
|
|
101
|
+
return actor;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create a scene session with a team
|
|
105
|
+
*/
|
|
106
|
+
async createSession(teamIndex, actionTimeout, warnAfter, baseUrl) {
|
|
107
|
+
if (!this.browser) {
|
|
108
|
+
throw new Error('Browser not set. Call setBrowser() first.');
|
|
109
|
+
}
|
|
110
|
+
return new TeamSession(this.browser, this.getTeam(teamIndex), teamIndex, actionTimeout, warnAfter, baseUrl, this.deviceRotation);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A session for a scene with an assigned team.
|
|
115
|
+
* Manages browser contexts and actors for the scene.
|
|
116
|
+
*/
|
|
117
|
+
export class TeamSession {
|
|
118
|
+
browser;
|
|
119
|
+
team;
|
|
120
|
+
teamIndex;
|
|
121
|
+
actionTimeout;
|
|
122
|
+
warnAfter;
|
|
123
|
+
baseUrl;
|
|
124
|
+
deviceRotation;
|
|
125
|
+
contexts = new Map();
|
|
126
|
+
actors = new Map();
|
|
127
|
+
actorDevices = new Map();
|
|
128
|
+
bus = new MessageBus();
|
|
129
|
+
timeline = [];
|
|
130
|
+
assertions = [];
|
|
131
|
+
warnings = [];
|
|
132
|
+
constructor(browser, team, teamIndex, actionTimeout, warnAfter, baseUrl, deviceRotation) {
|
|
133
|
+
this.browser = browser;
|
|
134
|
+
this.team = team;
|
|
135
|
+
this.teamIndex = teamIndex;
|
|
136
|
+
this.actionTimeout = actionTimeout;
|
|
137
|
+
this.warnAfter = warnAfter;
|
|
138
|
+
this.baseUrl = baseUrl;
|
|
139
|
+
this.deviceRotation = deviceRotation;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get the actor config for a role (sync — no browser setup).
|
|
143
|
+
* Used by flow() to create reactive handles before browser init.
|
|
144
|
+
*/
|
|
145
|
+
getActorConfig(role) {
|
|
146
|
+
const config = this.team[role];
|
|
147
|
+
if (!config) {
|
|
148
|
+
throw new Error(`Role "${role}" not found in team. Available roles: ${Object.keys(this.team).join(', ')}`);
|
|
149
|
+
}
|
|
150
|
+
return config;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create a browser context + page for a role and wire up assertion collection.
|
|
154
|
+
* Returns the Page. Used by flow() to initialize actors after declaration.
|
|
155
|
+
*/
|
|
156
|
+
async createPage(role) {
|
|
157
|
+
const config = this.team[role];
|
|
158
|
+
if (!config) {
|
|
159
|
+
throw new Error(`Role "${role}" not found in team. Available roles: ${Object.keys(this.team).join(', ')}`);
|
|
160
|
+
}
|
|
161
|
+
// Determine device for this actor (if rotation is enabled)
|
|
162
|
+
const device = this.deviceRotation?.next() ?? null;
|
|
163
|
+
if (device) {
|
|
164
|
+
this.actorDevices.set(role, device);
|
|
165
|
+
}
|
|
166
|
+
// Create context with device emulation if assigned
|
|
167
|
+
const contextOptions = {
|
|
168
|
+
...(this.baseUrl ? { baseURL: this.baseUrl } : {}),
|
|
169
|
+
...(device ? device.contextOptions : {}),
|
|
170
|
+
};
|
|
171
|
+
const context = await this.browser.newContext(contextOptions);
|
|
172
|
+
const page = await context.newPage();
|
|
173
|
+
// Track device name for assertions
|
|
174
|
+
const deviceName = device?.name;
|
|
175
|
+
await page.exposeFunction('__scenetest_report', (result) => {
|
|
176
|
+
const enriched = { ...result, actor: role, ...(deviceName ? { device: deviceName } : {}) };
|
|
177
|
+
this.assertions.push(enriched);
|
|
178
|
+
});
|
|
179
|
+
this.contexts.set(role, context);
|
|
180
|
+
// Log device assignment
|
|
181
|
+
if (device) {
|
|
182
|
+
console.log(` [${role}] assigned device: ${device.name} (${device.category})`);
|
|
183
|
+
}
|
|
184
|
+
return page;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get or create an actor for a role
|
|
188
|
+
*/
|
|
189
|
+
async getActor(role) {
|
|
190
|
+
// Return existing actor if already created
|
|
191
|
+
const existing = this.actors.get(role);
|
|
192
|
+
if (existing) {
|
|
193
|
+
return existing;
|
|
194
|
+
}
|
|
195
|
+
// Get actor config
|
|
196
|
+
const config = this.team[role];
|
|
197
|
+
if (!config) {
|
|
198
|
+
throw new Error(`Role "${role}" not found in team. Available roles: ${Object.keys(this.team).join(', ')}`);
|
|
199
|
+
}
|
|
200
|
+
// Determine device for this actor (if rotation is enabled)
|
|
201
|
+
const device = this.deviceRotation?.next() ?? null;
|
|
202
|
+
if (device) {
|
|
203
|
+
this.actorDevices.set(role, device);
|
|
204
|
+
}
|
|
205
|
+
// Create new browser context for this actor, with device emulation if assigned
|
|
206
|
+
const contextOptions = {
|
|
207
|
+
...(this.baseUrl ? { baseURL: this.baseUrl } : {}),
|
|
208
|
+
...(device ? device.contextOptions : {}),
|
|
209
|
+
};
|
|
210
|
+
const context = await this.browser.newContext(contextOptions);
|
|
211
|
+
const page = await context.newPage();
|
|
212
|
+
// Track device name for assertions
|
|
213
|
+
const deviceName = device?.name;
|
|
214
|
+
// Set up assertion collection
|
|
215
|
+
await page.exposeFunction('__scenetest_report', (result) => {
|
|
216
|
+
// Add actor and device info to assertion
|
|
217
|
+
const enriched = { ...result, actor: role, ...(deviceName ? { device: deviceName } : {}) };
|
|
218
|
+
this.assertions.push(enriched);
|
|
219
|
+
});
|
|
220
|
+
// Create actor handle
|
|
221
|
+
const actor = new SequentialActorHandleImpl(role, config, page, context, this.bus, this.timeline, this.warnings, this.actionTimeout, this.warnAfter);
|
|
222
|
+
this.contexts.set(role, context);
|
|
223
|
+
this.actors.set(role, actor);
|
|
224
|
+
// Log device assignment
|
|
225
|
+
if (device) {
|
|
226
|
+
console.log(` [${role}] assigned device: ${device.name} (${device.category})`);
|
|
227
|
+
}
|
|
228
|
+
return actor;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Get the device assigned to an actor role
|
|
232
|
+
*/
|
|
233
|
+
getActorDevice(role) {
|
|
234
|
+
return this.actorDevices.get(role);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Get all actor-device assignments
|
|
238
|
+
*/
|
|
239
|
+
getActorDevices() {
|
|
240
|
+
return this.actorDevices;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Get the message bus for this session
|
|
244
|
+
*/
|
|
245
|
+
getMessageBus() {
|
|
246
|
+
return this.bus;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get all actors created in this session
|
|
250
|
+
*/
|
|
251
|
+
getActors() {
|
|
252
|
+
return this.actors;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Close all browser contexts
|
|
256
|
+
*/
|
|
257
|
+
async close() {
|
|
258
|
+
for (const context of this.contexts.values()) {
|
|
259
|
+
await context.close();
|
|
260
|
+
}
|
|
261
|
+
this.contexts.clear();
|
|
262
|
+
this.actors.clear();
|
|
263
|
+
this.actorDevices.clear();
|
|
264
|
+
this.bus.clear();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=team-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-manager.js","sourceRoot":"","sources":["../src/team-manager.ts"],"names":[],"mappings":"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"}
|