@modelprofile.com/flexharness 10.24.0 → 10.24.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.flexharness.admission.d.ts +17 -0
- package/dist_ts/classes.flexharness.admission.js +263 -0
- package/dist_ts/classes.flexharness.callbacks.d.ts +38 -0
- package/dist_ts/classes.flexharness.callbacks.js +313 -0
- package/dist_ts/classes.flexharness.compaction.d.ts +25 -0
- package/dist_ts/classes.flexharness.compaction.js +87 -0
- package/dist_ts/classes.flexharness.configurations.d.ts +11 -0
- package/dist_ts/classes.flexharness.configurations.js +137 -0
- package/dist_ts/classes.flexharness.core.d.ts +143 -0
- package/dist_ts/classes.flexharness.core.js +1538 -0
- package/dist_ts/classes.flexharness.d.ts +2 -437
- package/dist_ts/classes.flexharness.deletion.d.ts +31 -0
- package/dist_ts/classes.flexharness.deletion.js +396 -0
- package/dist_ts/classes.flexharness.imports.d.ts +24 -0
- package/dist_ts/classes.flexharness.imports.js +345 -0
- package/dist_ts/classes.flexharness.js +119 -9776
- package/dist_ts/classes.flexharness.lifecycle.d.ts +47 -0
- package/dist_ts/classes.flexharness.lifecycle.js +625 -0
- package/dist_ts/classes.flexharness.permissions.d.ts +19 -0
- package/dist_ts/classes.flexharness.permissions.js +450 -0
- package/dist_ts/classes.flexharness.projects.d.ts +55 -0
- package/dist_ts/classes.flexharness.projects.js +575 -0
- package/dist_ts/classes.flexharness.prompts.d.ts +44 -0
- package/dist_ts/classes.flexharness.prompts.js +659 -0
- package/dist_ts/classes.flexharness.providers.d.ts +18 -0
- package/dist_ts/classes.flexharness.providers.js +267 -0
- package/dist_ts/classes.flexharness.results.d.ts +26 -0
- package/dist_ts/classes.flexharness.results.js +89 -0
- package/dist_ts/classes.flexharness.reversions.d.ts +52 -0
- package/dist_ts/classes.flexharness.reversions.js +1306 -0
- package/dist_ts/classes.flexharness.runs.d.ts +63 -0
- package/dist_ts/classes.flexharness.runs.js +1058 -0
- package/dist_ts/classes.flexharness.sessions.d.ts +20 -0
- package/dist_ts/classes.flexharness.sessions.js +381 -0
- package/dist_ts/classes.flexharness.slashcommands.d.ts +40 -0
- package/dist_ts/classes.flexharness.slashcommands.js +458 -0
- package/dist_ts/classes.flexharness.subagents.d.ts +31 -0
- package/dist_ts/classes.flexharness.subagents.js +690 -0
- package/dist_ts/classes.flexharness.tooldispatch.d.ts +53 -0
- package/dist_ts/classes.flexharness.tooldispatch.js +418 -0
- package/dist_ts/interfaces.flexharness.d.ts +455 -0
- package/dist_ts/interfaces.flexharness.js +2 -0
- package/dist_ts/utils.flexharness.d.ts +19 -0
- package/dist_ts/utils.flexharness.js +83 -0
- package/package.json +3 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.flexharness.admission.ts +331 -0
- package/ts/classes.flexharness.callbacks.ts +352 -0
- package/ts/classes.flexharness.compaction.ts +167 -0
- package/ts/classes.flexharness.configurations.ts +167 -0
- package/ts/classes.flexharness.core.ts +1830 -0
- package/ts/classes.flexharness.deletion.ts +616 -0
- package/ts/classes.flexharness.imports.ts +414 -0
- package/ts/classes.flexharness.lifecycle.ts +786 -0
- package/ts/classes.flexharness.permissions.ts +535 -0
- package/ts/classes.flexharness.projects.ts +1006 -0
- package/ts/classes.flexharness.prompts.ts +857 -0
- package/ts/classes.flexharness.providers.ts +322 -0
- package/ts/classes.flexharness.results.ts +98 -0
- package/ts/classes.flexharness.reversions.ts +1684 -0
- package/ts/classes.flexharness.runs.ts +1204 -0
- package/ts/classes.flexharness.sessions.ts +483 -0
- package/ts/classes.flexharness.slashcommands.ts +705 -0
- package/ts/classes.flexharness.subagents.ts +860 -0
- package/ts/classes.flexharness.tooldispatch.ts +475 -0
- package/ts/classes.flexharness.ts +147 -12567
- package/ts/interfaces.flexharness.ts +517 -0
- package/ts/utils.flexharness.ts +121 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { FlexHarnessAbortError, FlexHarnessNotFoundError, FlexHarnessQueueFullError, FlexHarnessSessionBusyError, FlexHarnessSlashCommandReentryError, FlexHarnessSteerRejectedError, FlexHarnessStoreCommitUncertainError, FlexHarnessValidationError, errorToInfo, } from './errors.js';
|
|
3
|
+
import { cloneSerializable } from './utils.json.js';
|
|
4
|
+
import { normalizeFlexPrompt } from './utils.prompt.js';
|
|
5
|
+
import { jsonBytes, publicSnapshot, requireTransferIdentifier } from './utils.transfer.js';
|
|
6
|
+
import { validateIdentifier, validatePromptOptions } from './utils.validation.js';
|
|
7
|
+
import { createSessionMetricsOperation } from './utils.sessionmetrics.js';
|
|
8
|
+
import { combineErrors, isAbortError } from './utils.flexharness.js';
|
|
9
|
+
const maxScheduleDebounceMs = 24 * 60 * 60 * 1000;
|
|
10
|
+
function containsStoreCommitUncertainty(error, seen = new Set()) {
|
|
11
|
+
if (error instanceof FlexHarnessStoreCommitUncertainError)
|
|
12
|
+
return true;
|
|
13
|
+
if (!(error instanceof Error) || seen.has(error))
|
|
14
|
+
return false;
|
|
15
|
+
seen.add(error);
|
|
16
|
+
try {
|
|
17
|
+
if (error instanceof AggregateError) {
|
|
18
|
+
for (const nested of error.errors) {
|
|
19
|
+
if (containsStoreCommitUncertainty(nested, seen))
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return containsStoreCommitUncertainty(error.cause, seen);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** The prompt queue: admission, scheduling, promotion and cancellation of prompts and steers. */
|
|
30
|
+
export class FlexHarnessPromptQueue {
|
|
31
|
+
core;
|
|
32
|
+
pendingPromptAdmissionOwners = new Set();
|
|
33
|
+
promptQueueSequence = 0;
|
|
34
|
+
pendingPromptAdmissions = 0;
|
|
35
|
+
pendingPromptAdmissionBytes = 0;
|
|
36
|
+
constructor(core) {
|
|
37
|
+
this.core = core;
|
|
38
|
+
}
|
|
39
|
+
promptAdmissionByteSize(prompt, options, scheduleKey, debounceMs) {
|
|
40
|
+
return jsonBytes({
|
|
41
|
+
prompt: normalizeFlexPrompt(prompt),
|
|
42
|
+
options: cloneSerializable(options),
|
|
43
|
+
scheduleKey,
|
|
44
|
+
debounceMs,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
isSessionRuntimeIdle(state, stored) {
|
|
48
|
+
return stored.session.status === 'idle'
|
|
49
|
+
&& !state.activeRuns.has(stored.session.sessionId)
|
|
50
|
+
&& stored.outstandingPromptsById.size === 0;
|
|
51
|
+
}
|
|
52
|
+
async prompt(scopeId, sessionId, prompt, options = {}) {
|
|
53
|
+
const admission = await this.startPrompt(scopeId, sessionId, prompt, options);
|
|
54
|
+
return admission.completion;
|
|
55
|
+
}
|
|
56
|
+
async startPrompt(scopeId, sessionId, prompt, options = {}) {
|
|
57
|
+
validatePromptOptions(options, false);
|
|
58
|
+
const queued = await this.enqueuePromptInternal(scopeId, sessionId, prompt, options);
|
|
59
|
+
return queued.started;
|
|
60
|
+
}
|
|
61
|
+
async enqueuePrompt(scopeId, sessionId, prompt, options = {}) {
|
|
62
|
+
validatePromptOptions(options, false);
|
|
63
|
+
const queued = await this.enqueuePromptInternal(scopeId, sessionId, prompt, options);
|
|
64
|
+
return queued.admission;
|
|
65
|
+
}
|
|
66
|
+
async schedulePrompt(scopeId, sessionId, scheduleKey, prompt, options = {}) {
|
|
67
|
+
validateIdentifier(scheduleKey, 'scheduleKey');
|
|
68
|
+
requireTransferIdentifier(scheduleKey, 'scheduleKey');
|
|
69
|
+
validatePromptOptions(options, true);
|
|
70
|
+
const debounceMs = options.debounceMs ?? 50;
|
|
71
|
+
if (!Number.isSafeInteger(debounceMs) || debounceMs < 0 || debounceMs > maxScheduleDebounceMs) {
|
|
72
|
+
throw new FlexHarnessValidationError(`debounceMs must be an integer from 0 through ${maxScheduleDebounceMs}.`);
|
|
73
|
+
}
|
|
74
|
+
const queued = await this.enqueuePromptInternal(scopeId, sessionId, prompt, options, scheduleKey, debounceMs);
|
|
75
|
+
const admission = await queued.started;
|
|
76
|
+
return Object.freeze({ ...admission, scheduleKey });
|
|
77
|
+
}
|
|
78
|
+
async getPromptQueueEntry(scopeId, sessionId, queueId) {
|
|
79
|
+
validateIdentifier(queueId, 'queueId');
|
|
80
|
+
requireTransferIdentifier(queueId, 'queueId');
|
|
81
|
+
const { state } = await this.core.resolveState(scopeId);
|
|
82
|
+
this.core.assertStateAcceptingWork(state);
|
|
83
|
+
const stored = this.core.requireSession(state, sessionId);
|
|
84
|
+
const entry = this.promptQueueEntry(stored, queueId);
|
|
85
|
+
if (!entry)
|
|
86
|
+
throw new FlexHarnessNotFoundError('Prompt queue entry', queueId);
|
|
87
|
+
return publicSnapshot(entry);
|
|
88
|
+
}
|
|
89
|
+
async listPromptQueueEntries(scopeId, sessionId) {
|
|
90
|
+
const { state } = await this.core.resolveState(scopeId);
|
|
91
|
+
this.core.assertStateAcceptingWork(state);
|
|
92
|
+
const stored = this.core.requireSession(state, sessionId);
|
|
93
|
+
return publicSnapshot([
|
|
94
|
+
...[...stored.outstandingPromptsById.values()].map((entry) => this.projectPromptQueueEntry(entry)),
|
|
95
|
+
...stored.terminalPromptQueueEntries.values(),
|
|
96
|
+
].sort((left, right) => left.queueSequence - right.queueSequence));
|
|
97
|
+
}
|
|
98
|
+
async cancelPrompt(scopeId, sessionId, queueId) {
|
|
99
|
+
validateIdentifier(queueId, 'queueId');
|
|
100
|
+
requireTransferIdentifier(queueId, 'queueId');
|
|
101
|
+
const { scope, state } = await this.core.resolveState(scopeId);
|
|
102
|
+
const stored = this.core.requireSession(state, sessionId);
|
|
103
|
+
const queued = stored.outstandingPromptsById.get(queueId);
|
|
104
|
+
if (!queued) {
|
|
105
|
+
if (stored.terminalPromptQueueEntries.has(queueId))
|
|
106
|
+
return false;
|
|
107
|
+
throw new FlexHarnessNotFoundError('Prompt queue entry', queueId);
|
|
108
|
+
}
|
|
109
|
+
return this.cancelQueuedPrompt(queued, this.core.trustInternalError(new FlexHarnessAbortError('The queued prompt was cancelled.')), this.core.compaction.createCompactorContext(scopeId, scope.scope, state.storageKey, sessionId));
|
|
110
|
+
}
|
|
111
|
+
async cancelScheduledPrompt(scopeId, sessionId, scheduleKey) {
|
|
112
|
+
validateIdentifier(scheduleKey, 'scheduleKey');
|
|
113
|
+
const { scope, state } = await this.core.resolveState(scopeId);
|
|
114
|
+
const stored = this.core.requireSession(state, sessionId);
|
|
115
|
+
const queued = [...stored.outstandingPromptsById.values()]
|
|
116
|
+
.find((entry) => entry.scheduleKey === scheduleKey);
|
|
117
|
+
if (!queued)
|
|
118
|
+
return false;
|
|
119
|
+
const cancellation = this.core.trustInternalError(new FlexHarnessAbortError('The scheduled run was cancelled.'));
|
|
120
|
+
return this.cancelQueuedPrompt(queued, cancellation, this.core.compaction.createCompactorContext(scopeId, scope.scope, state.storageKey, sessionId));
|
|
121
|
+
}
|
|
122
|
+
async steerPrompt(scopeId, sessionId, queueId, steer) {
|
|
123
|
+
validateIdentifier(queueId, 'queueId');
|
|
124
|
+
requireTransferIdentifier(queueId, 'queueId');
|
|
125
|
+
validateIdentifier(steer.steerId, 'steerId');
|
|
126
|
+
requireTransferIdentifier(steer.steerId, 'steerId');
|
|
127
|
+
this.core.assertOpen();
|
|
128
|
+
const prompt = normalizeFlexPrompt(steer.prompt);
|
|
129
|
+
const byteSize = this.promptAdmissionByteSize(steer.prompt, {});
|
|
130
|
+
const { state } = await this.core.resolveState(scopeId);
|
|
131
|
+
this.core.assertStateAcceptingWork(state);
|
|
132
|
+
const stored = this.core.requireSession(state, sessionId);
|
|
133
|
+
this.core.assertSessionWritable(stored);
|
|
134
|
+
if (stored.session.agent !== undefined) {
|
|
135
|
+
throw new FlexHarnessValidationError('Subagent sessions can only be prompted through the foreground delegate tool.');
|
|
136
|
+
}
|
|
137
|
+
const run = state.activeRuns.get(sessionId);
|
|
138
|
+
if (!run || run.queueId !== queueId) {
|
|
139
|
+
if (stored.outstandingPromptsById.has(queueId) || stored.terminalPromptQueueEntries.has(queueId)) {
|
|
140
|
+
throw new FlexHarnessSteerRejectedError('not-running', steer.steerId);
|
|
141
|
+
}
|
|
142
|
+
throw new FlexHarnessNotFoundError('Prompt queue entry', queueId);
|
|
143
|
+
}
|
|
144
|
+
return this.admitRunSteer(run, steer, prompt, byteSize);
|
|
145
|
+
}
|
|
146
|
+
/** The shared synchronous admission point; neither entrypoint starts or resumes a run. */
|
|
147
|
+
admitRunSteer(run, steer, prompt, byteSize) {
|
|
148
|
+
if (run.phase === 'closing'
|
|
149
|
+
|| run.phase === 'finalizing'
|
|
150
|
+
|| run.phase === 'promoting'
|
|
151
|
+
|| run.callbacksClosed
|
|
152
|
+
|| run.controller.signal.aborted
|
|
153
|
+
|| run.stop.signal.aborted
|
|
154
|
+
|| run.state.activeRuns.get(run.sessionId) !== run)
|
|
155
|
+
throw new FlexHarnessSteerRejectedError('not-running', steer.steerId);
|
|
156
|
+
const steering = run.steering;
|
|
157
|
+
if (!steering.input.closed && !steering.accepted.has(steer.steerId)) {
|
|
158
|
+
if (steering.accepted.size - steering.applied.size
|
|
159
|
+
>= this.core.promptQueueLimits.maxOutstandingPromptsPerSession) {
|
|
160
|
+
throw new FlexHarnessQueueFullError(`Session "${run.sessionId}" has reached its pending steer limit.`);
|
|
161
|
+
}
|
|
162
|
+
// Pending steers hold outstanding prompt bytes of the session until they are taken in.
|
|
163
|
+
if (steering.stored.outstandingPromptBytes + byteSize
|
|
164
|
+
> this.core.promptQueueLimits.maxOutstandingBytesPerSession) {
|
|
165
|
+
throw new FlexHarnessQueueFullError(`Session "${run.sessionId}" has reached its outstanding prompt byte limit.`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
steering.input.add({
|
|
170
|
+
inputId: steer.steerId,
|
|
171
|
+
content: cloneSerializable(prompt.modelMessage.content),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
if (error instanceof plugins.AgentPendingInputRejectedError) {
|
|
176
|
+
throw new FlexHarnessSteerRejectedError(error.reason === 'duplicate' ? 'duplicate' : 'not-running', steer.steerId);
|
|
177
|
+
}
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
steering.accepted.set(steer.steerId, { prompt, byteSize });
|
|
181
|
+
steering.stored.outstandingPromptBytes += byteSize;
|
|
182
|
+
this.core.emitEvent(run.scopeId, run.stored.session, {
|
|
183
|
+
type: 'prompt.steer.accepted',
|
|
184
|
+
queueId: run.queueId,
|
|
185
|
+
runId: run.runId,
|
|
186
|
+
steerId: steer.steerId,
|
|
187
|
+
});
|
|
188
|
+
return { steerId: steer.steerId, queueId: run.queueId, runId: run.runId };
|
|
189
|
+
}
|
|
190
|
+
async enqueuePromptInternal(scopeId, sessionId, prompt, options, scheduleKey, debounceMs, delegationSeed, admissionSignal, slashCommandAdmission = false) {
|
|
191
|
+
this.core.assertOpen();
|
|
192
|
+
const normalizedPrompt = normalizeFlexPrompt(prompt);
|
|
193
|
+
const normalizedOptions = cloneSerializable(options);
|
|
194
|
+
const byteSize = this.promptAdmissionByteSize(prompt, options, scheduleKey, debounceMs);
|
|
195
|
+
const releasePendingAdmission = this.reservePendingPromptAdmission(byteSize);
|
|
196
|
+
let resolveSettled;
|
|
197
|
+
const pendingOwner = {
|
|
198
|
+
controller: new AbortController(),
|
|
199
|
+
settled: new Promise((resolve) => {
|
|
200
|
+
resolveSettled = resolve;
|
|
201
|
+
}),
|
|
202
|
+
resolveSettled: () => resolveSettled(),
|
|
203
|
+
};
|
|
204
|
+
this.pendingPromptAdmissionOwners.add(pendingOwner);
|
|
205
|
+
const admissionSignals = [
|
|
206
|
+
pendingOwner.controller.signal,
|
|
207
|
+
...(admissionSignal === undefined ? [] : [admissionSignal]),
|
|
208
|
+
];
|
|
209
|
+
let abortAdmission;
|
|
210
|
+
const abortPromise = new Promise((_resolve, reject) => {
|
|
211
|
+
abortAdmission = () => {
|
|
212
|
+
const aborted = admissionSignals.find((signal) => signal.aborted);
|
|
213
|
+
reject(aborted?.reason ?? new FlexHarnessAbortError());
|
|
214
|
+
};
|
|
215
|
+
for (const signal of admissionSignals) {
|
|
216
|
+
signal.addEventListener('abort', abortAdmission, { once: true });
|
|
217
|
+
}
|
|
218
|
+
if (admissionSignals.some((signal) => signal.aborted))
|
|
219
|
+
abortAdmission();
|
|
220
|
+
});
|
|
221
|
+
try {
|
|
222
|
+
const resolved = await Promise.race([this.core.resolveState(scopeId), abortPromise]);
|
|
223
|
+
const state = resolved.state;
|
|
224
|
+
await Promise.race([state.scopeQueue, abortPromise]);
|
|
225
|
+
if (admissionSignal?.aborted) {
|
|
226
|
+
throw admissionSignal.reason ?? new FlexHarnessAbortError();
|
|
227
|
+
}
|
|
228
|
+
this.core.assertStateAcceptingWork(state);
|
|
229
|
+
const stored = this.core.requireSession(state, sessionId);
|
|
230
|
+
this.core.assertSessionWritable(stored);
|
|
231
|
+
const sessionKey = this.core.commands.slashCommandSessionKey(state.storageKey, sessionId);
|
|
232
|
+
const invocationOwner = this.core.commands.slashCommandInvocationContext.getStore();
|
|
233
|
+
if (invocationOwner?.sessionKey === sessionKey) {
|
|
234
|
+
throw this.core.trustInternalError(new FlexHarnessSlashCommandReentryError(sessionId));
|
|
235
|
+
}
|
|
236
|
+
if (!slashCommandAdmission && this.core.commands.activeSlashCommandExecutions.has(sessionKey)) {
|
|
237
|
+
throw new FlexHarnessSessionBusyError(sessionId, 'already has an active slash command execution');
|
|
238
|
+
}
|
|
239
|
+
if (stored.pendingReversion) {
|
|
240
|
+
throw new FlexHarnessSessionBusyError(sessionId, 'has a pending reversion operation');
|
|
241
|
+
}
|
|
242
|
+
if (stored.session.agent !== undefined && delegationSeed === undefined) {
|
|
243
|
+
throw new FlexHarnessValidationError('Subagent sessions can only be prompted through the foreground delegate tool.');
|
|
244
|
+
}
|
|
245
|
+
if (delegationSeed !== undefined) {
|
|
246
|
+
this.core.admission.assertDelegatedRunAdmissionOwnership(delegationSeed, state, stored, scopeId);
|
|
247
|
+
}
|
|
248
|
+
if (stored.outstandingPromptsById.size >= this.core.promptQueueLimits.maxOutstandingPromptsPerSession) {
|
|
249
|
+
throw new FlexHarnessQueueFullError(`Session "${sessionId}" has reached its outstanding prompt limit.`);
|
|
250
|
+
}
|
|
251
|
+
if (stored.outstandingPromptBytes + byteSize
|
|
252
|
+
> this.core.promptQueueLimits.maxOutstandingBytesPerSession) {
|
|
253
|
+
throw new FlexHarnessQueueFullError(`Session "${sessionId}" has reached its outstanding prompt byte limit.`);
|
|
254
|
+
}
|
|
255
|
+
if (scheduleKey
|
|
256
|
+
&& [...stored.outstandingPromptsById.values()]
|
|
257
|
+
.some((entry) => entry.scheduleKey === scheduleKey)) {
|
|
258
|
+
throw new FlexHarnessSessionBusyError(sessionId, `already has scheduled key "${scheduleKey}"`);
|
|
259
|
+
}
|
|
260
|
+
let resolveCompletion;
|
|
261
|
+
let rejectCompletion;
|
|
262
|
+
const completion = new Promise((resolve, reject) => {
|
|
263
|
+
resolveCompletion = resolve;
|
|
264
|
+
rejectCompletion = reject;
|
|
265
|
+
});
|
|
266
|
+
void completion.catch(() => undefined);
|
|
267
|
+
let resolveStarted;
|
|
268
|
+
let rejectStarted;
|
|
269
|
+
const started = new Promise((resolve, reject) => {
|
|
270
|
+
resolveStarted = resolve;
|
|
271
|
+
rejectStarted = reject;
|
|
272
|
+
});
|
|
273
|
+
void started.catch(() => undefined);
|
|
274
|
+
const queued = {
|
|
275
|
+
state,
|
|
276
|
+
stored,
|
|
277
|
+
scopeId,
|
|
278
|
+
scope: delegationSeed === undefined ? resolved.scope.scope : delegationSeed.scope,
|
|
279
|
+
sessionId,
|
|
280
|
+
queueId: plugins.crypto.randomUUID(),
|
|
281
|
+
queueSequence: ++this.promptQueueSequence,
|
|
282
|
+
status: 'queued',
|
|
283
|
+
queuedAt: new Date().toISOString(),
|
|
284
|
+
...(scheduleKey === undefined ? {} : { scheduleKey, debounceMs }),
|
|
285
|
+
prompt: normalizedPrompt,
|
|
286
|
+
options: normalizedOptions,
|
|
287
|
+
...(delegationSeed === undefined ? {} : { delegationSeed }),
|
|
288
|
+
byteSize,
|
|
289
|
+
completion,
|
|
290
|
+
resolveCompletion,
|
|
291
|
+
rejectCompletion,
|
|
292
|
+
started,
|
|
293
|
+
resolveStarted,
|
|
294
|
+
rejectStarted,
|
|
295
|
+
};
|
|
296
|
+
stored.promptQueue.push(queued);
|
|
297
|
+
stored.outstandingPromptsById.set(queued.queueId, queued);
|
|
298
|
+
stored.outstandingPromptBytes += byteSize;
|
|
299
|
+
this.emitPromptQueueEvent(queued, 'prompt.queued');
|
|
300
|
+
this.schedulePromptQueueDrain(state, stored);
|
|
301
|
+
return {
|
|
302
|
+
admission: Object.freeze({ queueId: queued.queueId, completion }),
|
|
303
|
+
started,
|
|
304
|
+
queued,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
finally {
|
|
308
|
+
for (const signal of admissionSignals) {
|
|
309
|
+
signal.removeEventListener('abort', abortAdmission);
|
|
310
|
+
}
|
|
311
|
+
this.pendingPromptAdmissionOwners.delete(pendingOwner);
|
|
312
|
+
releasePendingAdmission();
|
|
313
|
+
pendingOwner.resolveSettled();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
reservePendingPromptAdmission(byteSize) {
|
|
317
|
+
if (this.pendingPromptAdmissions >= this.core.promptQueueLimits.maxPendingAdmissions) {
|
|
318
|
+
throw new FlexHarnessQueueFullError('FlexHarness has reached its pending prompt admission limit.');
|
|
319
|
+
}
|
|
320
|
+
if (this.pendingPromptAdmissionBytes + byteSize
|
|
321
|
+
> this.core.promptQueueLimits.maxPendingAdmissionBytes) {
|
|
322
|
+
throw new FlexHarnessQueueFullError('FlexHarness has reached its pending prompt admission byte limit.');
|
|
323
|
+
}
|
|
324
|
+
this.pendingPromptAdmissions++;
|
|
325
|
+
this.pendingPromptAdmissionBytes += byteSize;
|
|
326
|
+
let released = false;
|
|
327
|
+
return () => {
|
|
328
|
+
if (released)
|
|
329
|
+
return;
|
|
330
|
+
released = true;
|
|
331
|
+
this.pendingPromptAdmissions--;
|
|
332
|
+
this.pendingPromptAdmissionBytes -= byteSize;
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
schedulePromptQueueDrain(state, stored) {
|
|
336
|
+
if (stored.promptQueueDrain)
|
|
337
|
+
return;
|
|
338
|
+
let drain;
|
|
339
|
+
drain = Promise.resolve()
|
|
340
|
+
.then(() => this.drainPromptQueue(state, stored))
|
|
341
|
+
.finally(() => {
|
|
342
|
+
if (stored.promptQueueDrain === drain)
|
|
343
|
+
delete stored.promptQueueDrain;
|
|
344
|
+
if (stored.promptQueue.length > 0
|
|
345
|
+
&& !state.activeRuns.has(stored.session.sessionId)
|
|
346
|
+
&& state.lifecycle === 'active'
|
|
347
|
+
&& state.sessions.get(stored.session.sessionId) === stored)
|
|
348
|
+
this.schedulePromptQueueDrain(state, stored);
|
|
349
|
+
});
|
|
350
|
+
stored.promptQueueDrain = drain;
|
|
351
|
+
void drain.catch(() => undefined);
|
|
352
|
+
}
|
|
353
|
+
async drainPromptQueue(state, stored) {
|
|
354
|
+
while (state.lifecycle === 'active'
|
|
355
|
+
&& state.sessions.get(stored.session.sessionId) === stored
|
|
356
|
+
&& !state.activeRuns.has(stored.session.sessionId)) {
|
|
357
|
+
const queued = stored.promptQueue.shift();
|
|
358
|
+
if (!queued)
|
|
359
|
+
return;
|
|
360
|
+
if (stored.outstandingPromptsById.get(queued.queueId) !== queued)
|
|
361
|
+
continue;
|
|
362
|
+
queued.status = 'starting';
|
|
363
|
+
queued.runId = plugins.crypto.randomUUID();
|
|
364
|
+
queued.startedAt = new Date().toISOString();
|
|
365
|
+
const run = this.core.runs.createActiveRun(queued);
|
|
366
|
+
state.activeRuns.set(queued.sessionId, run);
|
|
367
|
+
try {
|
|
368
|
+
await this.promoteQueuedPrompt(queued, run);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
catch (error) {
|
|
372
|
+
if (state.activeRuns.get(queued.sessionId) === run)
|
|
373
|
+
state.activeRuns.delete(queued.sessionId);
|
|
374
|
+
const cancellation = isAbortError(error);
|
|
375
|
+
this.finishQueuedPrompt(queued, cancellation ? 'cancelled' : 'failed', error);
|
|
376
|
+
if (state.lifecycle !== 'active')
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
assertPromptPromotion(queued, run) {
|
|
382
|
+
if (run.controller.signal.aborted) {
|
|
383
|
+
throw run.controller.signal.reason ?? new FlexHarnessAbortError();
|
|
384
|
+
}
|
|
385
|
+
this.core.assertStateAcceptingWork(run.state);
|
|
386
|
+
if (run.state.sessions.get(run.sessionId) !== run.stored
|
|
387
|
+
|| run.stored.outstandingPromptsById.get(run.queueId) !== queued
|
|
388
|
+
|| run.state.activeRuns.get(run.sessionId) !== run)
|
|
389
|
+
throw this.core.trustInternalError(new FlexHarnessAbortError('The prompt was retired during admission.'));
|
|
390
|
+
if (queued.delegationSeed) {
|
|
391
|
+
this.core.admission.assertDelegatedRunAdmissionOwnership(queued.delegationSeed, run.state, run.stored, run.scopeId);
|
|
392
|
+
if (run.queueId !== queued.queueId
|
|
393
|
+
|| run.runId !== queued.runId
|
|
394
|
+
|| run.sessionId !== queued.delegationSeed.sessionId) {
|
|
395
|
+
throw this.core.trustInternalError(new FlexHarnessAbortError('The delegated prompt lost its exact child run ownership.'));
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
async promoteQueuedPrompt(queued, run) {
|
|
400
|
+
const prompt = queued.prompt;
|
|
401
|
+
const options = queued.options;
|
|
402
|
+
let projectionReserved = false;
|
|
403
|
+
// Open from the reservation until its messages are announced or rolled back.
|
|
404
|
+
let closeReservationPublication = () => undefined;
|
|
405
|
+
try {
|
|
406
|
+
try {
|
|
407
|
+
this.assertPromptPromotion(queued, run);
|
|
408
|
+
await this.core.admission.acquireDelegatedRunAdmission(queued, run);
|
|
409
|
+
this.assertPromptPromotion(queued, run);
|
|
410
|
+
await this.core.reversions.commitRevertedBranch(run.state, run.stored, run.scopeId, run.scope);
|
|
411
|
+
this.assertPromptPromotion(queued, run);
|
|
412
|
+
const generationPrompt = cloneSerializable(prompt.modelMessage.content);
|
|
413
|
+
this.assertPromptPromotion(queued, run);
|
|
414
|
+
run.transaction = await this.core.compaction.withRunCompactorContext(run, () => run.stored.agentSession.beginGeneration(generationPrompt, { generationId: run.runId }));
|
|
415
|
+
this.assertPromptPromotion(queued, run);
|
|
416
|
+
const reservation = this.core.runs.createReservation(run, prompt);
|
|
417
|
+
closeReservationPublication = this.core.openPublication(run.state, run.sessionId);
|
|
418
|
+
run.metricsOperation = createSessionMetricsOperation(run.runId, 'generation');
|
|
419
|
+
await this.core.mutateProjection(run.state, run.stored, () => {
|
|
420
|
+
if (run.stored.metrics.pendingGenerationId !== undefined) {
|
|
421
|
+
throw new Error('Session metrics already owns a generation.');
|
|
422
|
+
}
|
|
423
|
+
run.stored.metrics.pendingGenerationId = run.runId;
|
|
424
|
+
run.stored.messages.push(reservation.userMessage, reservation.assistantMessage);
|
|
425
|
+
if (run.stored.session.agent === undefined) {
|
|
426
|
+
this.core.reversions.pruneReversionState(run.stored, true);
|
|
427
|
+
const captureId = this.core.turnReversionProvider
|
|
428
|
+
? this.core.reversions.reversionId('capture', run.state.storageKey, run.sessionId, run.runId)
|
|
429
|
+
: undefined;
|
|
430
|
+
const protocolVersion = this.core.reversions.reversionProviderProtocolVersion() ?? 1;
|
|
431
|
+
run.stored.reversionSegments.push({
|
|
432
|
+
runId: run.runId,
|
|
433
|
+
userMessageId: reservation.userMessage.messageId,
|
|
434
|
+
status: 'capturing',
|
|
435
|
+
contextAvailable: true,
|
|
436
|
+
eventIds: [],
|
|
437
|
+
workspaceCaptured: captureId !== undefined,
|
|
438
|
+
protocolVersion,
|
|
439
|
+
provenance: captureId === undefined ? 'transcript' : 'workspace',
|
|
440
|
+
...(captureId === undefined ? {} : { disposition: 'pending' }),
|
|
441
|
+
...(captureId === undefined ? {} : { captureId }),
|
|
442
|
+
});
|
|
443
|
+
if (captureId) {
|
|
444
|
+
run.stored.pendingReversion = {
|
|
445
|
+
kind: 'capture',
|
|
446
|
+
runId: run.runId,
|
|
447
|
+
captureId,
|
|
448
|
+
state: 'preparing',
|
|
449
|
+
protocolVersion,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
projectionReserved = true;
|
|
455
|
+
run.reservedUserMessage = publicSnapshot(reservation.userMessage);
|
|
456
|
+
run.reservedAssistantMessage = publicSnapshot(reservation.assistantMessage);
|
|
457
|
+
this.assertPromptPromotion(queued, run);
|
|
458
|
+
await this.core.mutateScope(run.state, () => {
|
|
459
|
+
if (run.controller.signal.aborted) {
|
|
460
|
+
throw run.controller.signal.reason ?? new FlexHarnessAbortError();
|
|
461
|
+
}
|
|
462
|
+
if (run.state.tombstones.has(run.sessionId) || run.state.sessions.get(run.sessionId) !== run.stored) {
|
|
463
|
+
throw new FlexHarnessAbortError('The session was deleted during prompt admission.');
|
|
464
|
+
}
|
|
465
|
+
run.stored.session.status = run.scheduleKey ? 'scheduled' : 'running';
|
|
466
|
+
run.stored.session.activity = {
|
|
467
|
+
runId: run.runId,
|
|
468
|
+
status: run.scheduleKey ? 'scheduled' : 'running',
|
|
469
|
+
startedAt: reservation.userMessage.createdAt,
|
|
470
|
+
};
|
|
471
|
+
run.stored.session.updatedAt = reservation.userMessage.createdAt;
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
if (containsStoreCommitUncertainty(error))
|
|
476
|
+
run.state.lifecycle = 'fenced';
|
|
477
|
+
const safeError = this.core.projectExternalError(run, error, projectionReserved ? 'persistence' : 'agentSession');
|
|
478
|
+
let cleanupErrors = [];
|
|
479
|
+
let cleanupFailure;
|
|
480
|
+
try {
|
|
481
|
+
await this.core.admission.closeRunDelegatedRunAdmission(run, !run.delegatedRunAdmissionOwner?.acquisitionDetached);
|
|
482
|
+
}
|
|
483
|
+
catch (closeError) {
|
|
484
|
+
cleanupErrors.push(closeError);
|
|
485
|
+
}
|
|
486
|
+
try {
|
|
487
|
+
cleanupErrors.push(...await this.core.runs.rollbackAdmission(run, projectionReserved, safeError));
|
|
488
|
+
}
|
|
489
|
+
catch (rollbackError) {
|
|
490
|
+
cleanupFailure = rollbackError;
|
|
491
|
+
}
|
|
492
|
+
if (cleanupFailure !== undefined && cleanupErrors.length > 0) {
|
|
493
|
+
cleanupFailure = combineErrors([cleanupFailure, ...cleanupErrors]);
|
|
494
|
+
}
|
|
495
|
+
if (run.state.lifecycle === 'fenced' && cleanupFailure === undefined) {
|
|
496
|
+
const combined = combineErrors([safeError, ...cleanupErrors]);
|
|
497
|
+
try {
|
|
498
|
+
await this.core.lifecycle.fenceNamespace(run.state, run, combined);
|
|
499
|
+
}
|
|
500
|
+
catch (fenceError) {
|
|
501
|
+
cleanupFailure = fenceError;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
const rejection = cleanupFailure
|
|
505
|
+
?? (cleanupErrors.length > 0 ? combineErrors([safeError, ...cleanupErrors]) : safeError);
|
|
506
|
+
throw rejection;
|
|
507
|
+
}
|
|
508
|
+
const runType = run.scheduleKey ? 'run.scheduled' : 'run.started';
|
|
509
|
+
this.core.emitEvent(run.scopeId, run.stored.session, {
|
|
510
|
+
type: runType,
|
|
511
|
+
runId: run.runId,
|
|
512
|
+
messageId: run.userMessageId,
|
|
513
|
+
session: publicSnapshot(run.stored.session),
|
|
514
|
+
});
|
|
515
|
+
for (const message of [run.reservedUserMessage, run.reservedAssistantMessage]) {
|
|
516
|
+
this.core.emitEvent(run.scopeId, run.stored.session, {
|
|
517
|
+
type: 'message.created',
|
|
518
|
+
runId: run.runId,
|
|
519
|
+
messageId: message.messageId,
|
|
520
|
+
message,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
finally {
|
|
525
|
+
closeReservationPublication();
|
|
526
|
+
}
|
|
527
|
+
queued.status = run.scheduleKey ? 'scheduled' : 'starting';
|
|
528
|
+
this.emitPromptQueueEvent(queued, 'prompt.started');
|
|
529
|
+
queued.resolveStarted(Object.freeze({
|
|
530
|
+
queueId: queued.queueId,
|
|
531
|
+
runId: run.runId,
|
|
532
|
+
completion: queued.completion,
|
|
533
|
+
}));
|
|
534
|
+
run.phase = run.scheduleKey ? 'scheduled' : 'running';
|
|
535
|
+
const generateOptions = {
|
|
536
|
+
transaction: run.transaction,
|
|
537
|
+
abort: run.controller.signal,
|
|
538
|
+
stop: run.stop.signal,
|
|
539
|
+
prepare: (context) => this.core.runs.prepareGeneration(run, options, context.abortSignal),
|
|
540
|
+
pendingInput: run.steering.input,
|
|
541
|
+
activateOnBackgroundJobs: true,
|
|
542
|
+
onCacheDispatch: (dispatch) => { run.cacheDispatch = dispatch; },
|
|
543
|
+
onInputApplied: (input) => this.core.runs.applyRunSteer(run, input),
|
|
544
|
+
beforeFinish: (context) => this.core.subagentTasks.awaitNextBackgroundSubagent(run, context.abortSignal),
|
|
545
|
+
};
|
|
546
|
+
const generation = this.core.compaction.withRunCompactorContext(run, () => run.scheduleKey
|
|
547
|
+
? run.stored.agentSession.scheduleGenerate({
|
|
548
|
+
key: run.scheduleKey,
|
|
549
|
+
debounceMs: run.debounceMs,
|
|
550
|
+
...generateOptions,
|
|
551
|
+
})
|
|
552
|
+
: run.stored.agentSession.generate(generateOptions));
|
|
553
|
+
const execution = this.core.runs.executeRun(run, generation).then((result) => this.finishQueuedPrompt(queued, 'completed', undefined, result), (error) => this.finishQueuedPrompt(queued, isAbortError(error) ? 'cancelled' : 'failed', error)).finally(() => this.schedulePromptQueueDrain(run.state, run.stored));
|
|
554
|
+
void execution.catch(() => undefined);
|
|
555
|
+
}
|
|
556
|
+
projectPromptQueueEntry(queued) {
|
|
557
|
+
return {
|
|
558
|
+
queueId: queued.queueId,
|
|
559
|
+
queueSequence: queued.queueSequence,
|
|
560
|
+
scopeId: queued.scopeId,
|
|
561
|
+
sessionId: queued.sessionId,
|
|
562
|
+
status: queued.status,
|
|
563
|
+
queuedAt: queued.queuedAt,
|
|
564
|
+
...(queued.runId ? { runId: queued.runId } : {}),
|
|
565
|
+
...(queued.scheduleKey ? { scheduleKey: queued.scheduleKey } : {}),
|
|
566
|
+
...(queued.startedAt ? { startedAt: queued.startedAt } : {}),
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
promptQueueEntry(stored, queueId) {
|
|
570
|
+
const outstanding = stored.outstandingPromptsById.get(queueId);
|
|
571
|
+
return outstanding
|
|
572
|
+
? this.projectPromptQueueEntry(outstanding)
|
|
573
|
+
: stored.terminalPromptQueueEntries.get(queueId);
|
|
574
|
+
}
|
|
575
|
+
emitPromptQueueEvent(queued, type, entry = this.projectPromptQueueEntry(queued)) {
|
|
576
|
+
this.core.emitEvent(queued.scopeId, queued.stored.session, {
|
|
577
|
+
type,
|
|
578
|
+
queueId: queued.queueId,
|
|
579
|
+
...(entry.runId ? { runId: entry.runId } : {}),
|
|
580
|
+
entry: publicSnapshot(entry),
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
finishQueuedPrompt(queued, status, error, result) {
|
|
584
|
+
const stored = queued.stored;
|
|
585
|
+
if (stored.outstandingPromptsById.get(queued.queueId) !== queued)
|
|
586
|
+
return;
|
|
587
|
+
stored.promptQueue = stored.promptQueue.filter((entry) => entry !== queued);
|
|
588
|
+
stored.outstandingPromptsById.delete(queued.queueId);
|
|
589
|
+
stored.outstandingPromptBytes = Math.max(0, stored.outstandingPromptBytes - queued.byteSize);
|
|
590
|
+
delete queued.prompt;
|
|
591
|
+
delete queued.options;
|
|
592
|
+
delete queued.delegationSeed;
|
|
593
|
+
const steering = queued.steering === undefined ? undefined : this.core.runs.closeRunSteering(queued.steering);
|
|
594
|
+
const terminal = {
|
|
595
|
+
...this.projectPromptQueueEntry(queued),
|
|
596
|
+
status,
|
|
597
|
+
finishedAt: new Date().toISOString(),
|
|
598
|
+
...(error === undefined ? {} : { error: errorToInfo(error) }),
|
|
599
|
+
keptInContext: steering?.keptInContext ?? false,
|
|
600
|
+
...(steering === undefined || steering.unappliedSteerIds.length === 0
|
|
601
|
+
? {}
|
|
602
|
+
: { unappliedSteerIds: [...steering.unappliedSteerIds] }),
|
|
603
|
+
};
|
|
604
|
+
stored.terminalPromptQueueEntries.set(queued.queueId, terminal);
|
|
605
|
+
while (stored.terminalPromptQueueEntries.size
|
|
606
|
+
> this.core.promptQueueLimits.maxTerminalEntriesPerSession) {
|
|
607
|
+
const oldest = stored.terminalPromptQueueEntries.keys().next().value;
|
|
608
|
+
if (!oldest)
|
|
609
|
+
break;
|
|
610
|
+
stored.terminalPromptQueueEntries.delete(oldest);
|
|
611
|
+
}
|
|
612
|
+
this.emitPromptQueueEvent(queued, 'prompt.finished', terminal);
|
|
613
|
+
if (status === 'completed') {
|
|
614
|
+
if (!result)
|
|
615
|
+
throw new Error('A completed queued prompt requires a result.');
|
|
616
|
+
queued.resolveCompletion(result);
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
const rejection = error ?? this.core.trustInternalError(new FlexHarnessAbortError());
|
|
620
|
+
queued.rejectStarted(rejection);
|
|
621
|
+
queued.rejectCompletion(rejection);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
cancelQueuedPrompt(queued, reason, context) {
|
|
625
|
+
if (queued.stored.outstandingPromptsById.get(queued.queueId) !== queued)
|
|
626
|
+
return false;
|
|
627
|
+
if (queued.status === 'queued') {
|
|
628
|
+
this.finishQueuedPrompt(queued, 'cancelled', reason);
|
|
629
|
+
this.schedulePromptQueueDrain(queued.state, queued.stored);
|
|
630
|
+
return true;
|
|
631
|
+
}
|
|
632
|
+
const run = queued.state.activeRuns.get(queued.sessionId);
|
|
633
|
+
if (!run || run.queueId !== queued.queueId)
|
|
634
|
+
return false;
|
|
635
|
+
if (run.phase === 'finalizing' || run.phase === 'promoting')
|
|
636
|
+
return false;
|
|
637
|
+
this.core.runs.cancelRun(run, reason, context);
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
cancelStoredPromptQueue(stored, reason, excludedQueueId, context) {
|
|
641
|
+
for (const queued of [...stored.outstandingPromptsById.values()]) {
|
|
642
|
+
if (queued.queueId === excludedQueueId)
|
|
643
|
+
continue;
|
|
644
|
+
this.cancelQueuedPrompt(queued, reason, context);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
purgeStoredPromptQueue(stored) {
|
|
648
|
+
for (const queued of stored.outstandingPromptsById.values()) {
|
|
649
|
+
delete queued.prompt;
|
|
650
|
+
delete queued.options;
|
|
651
|
+
delete queued.delegationSeed;
|
|
652
|
+
}
|
|
653
|
+
stored.promptQueue.length = 0;
|
|
654
|
+
stored.outstandingPromptsById.clear();
|
|
655
|
+
stored.terminalPromptQueueEntries.clear();
|
|
656
|
+
stored.outstandingPromptBytes = 0;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4aGFybmVzcy5wcm9tcHRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5mbGV4aGFybmVzcy5wcm9tcHRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6QiwyQkFBMkIsRUFDM0IsbUNBQW1DLEVBQ25DLDZCQUE2QixFQUM3QixvQ0FBb0MsRUFDcEMsMEJBQTBCLEVBQzFCLFdBQVcsR0FDWixNQUFNLGFBQWEsQ0FBQztBQWNyQixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsbUJBQW1CLEVBQThCLE1BQU0sbUJBQW1CLENBQUM7QUFDcEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMzRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQVMxRSxPQUFPLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3JFLE1BQU0scUJBQXFCLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRWxELFNBQVMsOEJBQThCLENBQUMsS0FBYyxFQUFFLE9BQU8sSUFBSSxHQUFHLEVBQVc7SUFDL0UsSUFBSSxLQUFLLFlBQVksb0NBQW9DO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkUsSUFBSSxDQUFDLENBQUMsS0FBSyxZQUFZLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDL0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQixJQUFJLENBQUM7UUFDSCxJQUFJLEtBQUssWUFBWSxjQUFjLEVBQUUsQ0FBQztZQUNwQyxLQUFLLE1BQU0sTUFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDbEMsSUFBSSw4QkFBOEIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDO29CQUFFLE9BQU8sSUFBSSxDQUFDO1lBQ2hFLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyw4QkFBOEIsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDO0FBRUQsaUdBQWlHO0FBQ2pHLE1BQU0sT0FBTyxzQkFBc0I7SUFNSjtJQUxiLDRCQUE0QixHQUFHLElBQUksR0FBRyxFQUEyQixDQUFDO0lBQzFFLG1CQUFtQixHQUFHLENBQUMsQ0FBQztJQUN6Qix1QkFBdUIsR0FBRyxDQUFDLENBQUM7SUFDNUIsMkJBQTJCLEdBQUcsQ0FBQyxDQUFDO0lBRXZDLFlBQTZCLElBQTZCO1FBQTdCLFNBQUksR0FBSixJQUFJLENBQXlCO0lBQUcsQ0FBQztJQUV2RCx1QkFBdUIsQ0FDNUIsTUFBbUIsRUFDbkIsT0FBMkIsRUFDM0IsV0FBb0IsRUFDcEIsVUFBbUI7UUFFbkIsT0FBTyxTQUFTLENBQUM7WUFDZixNQUFNLEVBQUUsbUJBQW1CLENBQUMsTUFBTSxDQUFDO1lBQ25DLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxPQUFPLENBQUM7WUFDbkMsV0FBVztZQUNYLFVBQVU7U0FDWCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sb0JBQW9CLENBQUMsS0FBb0IsRUFBRSxNQUEyQjtRQUMzRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLE1BQU07ZUFDbEMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztlQUMvQyxNQUFNLENBQUMsc0JBQXNCLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRU0sS0FBSyxDQUFDLE1BQU0sQ0FDakIsT0FBZSxFQUNmLFNBQWlCLEVBQ2pCLE1BQW1CLEVBQ25CLFVBQThCLEVBQUU7UUFFaEMsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzlFLE9BQU8sU0FBUyxDQUFDLFVBQVUsQ0FBQztJQUM5QixDQUFDO0lBRU0sS0FBSyxDQUFDLFdBQVcsQ0FDdEIsT0FBZSxFQUNmLFNBQWlCLEVBQ2pCLE1BQW1CLEVBQ25CLFVBQThCLEVBQUU7UUFFaEMscUJBQXFCLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3JGLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUN4QixDQUFDO0lBRU0sS0FBSyxDQUFDLGFBQWEsQ0FDeEIsT0FBZSxFQUNmLFNBQWlCLEVBQ2pCLE1BQW1CLEVBQ25CLFVBQThCLEVBQUU7UUFFaEMscUJBQXFCLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3JGLE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQztJQUMxQixDQUFDO0lBRU0sS0FBSyxDQUFDLGNBQWMsQ0FDekIsT0FBZSxFQUNmLFNBQWlCLEVBQ2pCLFdBQW1CLEVBQ25CLE1BQW1CLEVBQ25CLFVBQXNDLEVBQUU7UUFFeEMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQy9DLHlCQUF5QixDQUFDLFdBQVcsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUN0RCxxQkFBcUIsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDckMsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksVUFBVSxHQUFHLENBQUMsSUFBSSxVQUFVLEdBQUcscUJBQXFCLEVBQUUsQ0FBQztZQUM5RixNQUFNLElBQUksMEJBQTBCLENBQ2xDLGdEQUFnRCxxQkFBcUIsR0FBRyxDQUN6RSxDQUFDO1FBQ0osQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUM3QyxPQUFPLEVBQ1AsU0FBUyxFQUNULE1BQU0sRUFDTixPQUFPLEVBQ1AsV0FBVyxFQUNYLFVBQVUsQ0FDWCxDQUFDO1FBQ0YsTUFBTSxTQUFTLEdBQUcsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQ3ZDLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsU0FBUyxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVNLEtBQUssQ0FBQyxtQkFBbUIsQ0FDOUIsT0FBZSxFQUNmLFNBQWlCLEVBQ2pCLE9BQWU7UUFFZixrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDdkMseUJBQXlCLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzFELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLEtBQUs7WUFBRSxNQUFNLElBQUksd0JBQXdCLENBQUMsb0JBQW9CLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDOUUsT0FBTyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVNLEtBQUssQ0FBQyxzQkFBc0IsQ0FDakMsT0FBZSxFQUNmLFNBQWlCO1FBRWpCLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzFELE9BQU8sY0FBYyxDQUFDO1lBQ3BCLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xHLEdBQUcsTUFBTSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sRUFBRTtTQUM5QyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVNLEtBQUssQ0FBQyxZQUFZLENBQ3ZCLE9BQWUsRUFDZixTQUFpQixFQUNqQixPQUFlO1FBRWYsa0JBQWtCLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZDLHlCQUF5QixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM5QyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzFELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ1osSUFBSSxNQUFNLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQztnQkFBRSxPQUFPLEtBQUssQ0FBQztZQUNqRSxNQUFNLElBQUksd0JBQXdCLENBQUMsb0JBQW9CLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDcEUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUM1QixNQUFNLEVBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLHFCQUFxQixDQUFDLGtDQUFrQyxDQUFDLENBQUMsRUFDM0YsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FDL0YsQ0FBQztJQUNKLENBQUM7SUFFTSxLQUFLLENBQUMscUJBQXFCLENBQ2hDLE9BQWUsRUFDZixTQUFpQixFQUNqQixXQUFtQjtRQUVuQixrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDL0MsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9ELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMxRCxNQUFNLE1BQU0sR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxDQUFDO2FBQ3ZELElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQzFCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxxQkFBcUIsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDLENBQUM7UUFDakgsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQzVCLE1BQU0sRUFDTixZQUFZLEVBQ1osSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FDL0YsQ0FBQztJQUNKLENBQUM7SUFFTSxLQUFLLENBQUMsV0FBVyxDQUN0QixPQUFlLEVBQ2YsU0FBaUIsRUFDakIsT0FBZSxFQUNmLEtBQXNCO1FBRXRCLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN2Qyx5QkFBeUIsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDOUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM3Qyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDdkIsTUFBTSxNQUFNLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QyxNQUFNLElBQUksMEJBQTBCLENBQ2xDLDhFQUE4RSxDQUMvRSxDQUFDO1FBQ0osQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNwQyxJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksTUFBTSxDQUFDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNqRyxNQUFNLElBQUksNkJBQTZCLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN4RSxDQUFDO1lBQ0QsTUFBTSxJQUFJLHdCQUF3QixDQUFDLG9CQUFvQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELDBGQUEwRjtJQUNuRixhQUFhLENBQ2xCLEdBQWUsRUFDZixLQUFzQixFQUN0QixNQUE2QixFQUM3QixRQUFnQjtRQUVoQixJQUNFLEdBQUcsQ0FBQyxLQUFLLEtBQUssU0FBUztlQUNwQixHQUFHLENBQUMsS0FBSyxLQUFLLFlBQVk7ZUFDMUIsR0FBRyxDQUFDLEtBQUssS0FBSyxXQUFXO2VBQ3pCLEdBQUcsQ0FBQyxlQUFlO2VBQ25CLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU87ZUFDN0IsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTztlQUN2QixHQUFHLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUc7WUFDbEQsTUFBTSxJQUFJLDZCQUE2QixDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEUsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQztRQUM5QixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNwRSxJQUNFLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSTttQkFDM0MsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQywrQkFBK0IsRUFDOUQsQ0FBQztnQkFDRCxNQUFNLElBQUkseUJBQXlCLENBQUMsWUFBWSxHQUFHLENBQUMsU0FBUyx3Q0FBd0MsQ0FBQyxDQUFDO1lBQ3pHLENBQUM7WUFDRCx1RkFBdUY7WUFDdkYsSUFDRSxRQUFRLENBQUMsTUFBTSxDQUFDLHNCQUFzQixHQUFHLFFBQVE7a0JBQy9DLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsNkJBQTZCLEVBQzNELENBQUM7Z0JBQ0QsTUFBTSxJQUFJLHlCQUF5QixDQUNqQyxZQUFZLEdBQUcsQ0FBQyxTQUFTLGtEQUFrRCxDQUM1RSxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUM7WUFDSCxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztnQkFDakIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO2dCQUN0QixPQUFPLEVBQUUsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBRWxEO2FBQ0wsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLEtBQUssWUFBWSxPQUFPLENBQUMsOEJBQThCLEVBQUUsQ0FBQztnQkFDNUQsTUFBTSxJQUFJLDZCQUE2QixDQUNyQyxLQUFLLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxhQUFhLEVBQzFELEtBQUssQ0FBQyxPQUFPLENBQ2QsQ0FBQztZQUNKLENBQUM7WUFDRCxNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7UUFDRCxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDM0QsUUFBUSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsSUFBSSxRQUFRLENBQUM7UUFDbkQsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtZQUNuRCxJQUFJLEVBQUUsdUJBQXVCO1lBQzdCLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztZQUNwQixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7WUFDaEIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1NBQ3ZCLENBQUMsQ0FBQztRQUNILE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzVFLENBQUM7SUFFTSxLQUFLLENBQUMscUJBQXFCLENBQ2hDLE9BQWUsRUFDZixTQUFpQixFQUNqQixNQUFtQixFQUNuQixPQUEyQixFQUMzQixXQUFvQixFQUNwQixVQUFtQixFQUNuQixjQUEyQyxFQUMzQyxlQUE2QixFQUM3QixxQkFBcUIsR0FBRyxLQUFLO1FBTTdCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDdkIsTUFBTSxnQkFBZ0IsR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNyRCxNQUFNLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUN4RixNQUFNLHVCQUF1QixHQUFHLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3RSxJQUFJLGNBQTJCLENBQUM7UUFDaEMsTUFBTSxZQUFZLEdBQTRCO1lBQzVDLFVBQVUsRUFBRSxJQUFJLGVBQWUsRUFBRTtZQUNqQyxPQUFPLEVBQUUsSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDckMsY0FBYyxHQUFHLE9BQU8sQ0FBQztZQUMzQixDQUFDLENBQUM7WUFDRixjQUFjLEVBQUUsR0FBRyxFQUFFLENBQUMsY0FBYyxFQUFFO1NBQ3ZDLENBQUM7UUFDRixJQUFJLENBQUMsNEJBQTRCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3BELE1BQU0sZ0JBQWdCLEdBQUc7WUFDdkIsWUFBWSxDQUFDLFVBQVUsQ0FBQyxNQUFNO1lBQzlCLEdBQUcsQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUM7U0FDNUQsQ0FBQztRQUNGLElBQUksY0FBMkIsQ0FBQztRQUNoQyxNQUFNLFlBQVksR0FBRyxJQUFJLE9BQU8sQ0FBUSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUMzRCxjQUFjLEdBQUcsR0FBRyxFQUFFO2dCQUNwQixNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDbEUsTUFBTSxDQUFDLE9BQU8sRUFBRSxNQUFNLElBQUksSUFBSSxxQkFBcUIsRUFBRSxDQUFDLENBQUM7WUFDekQsQ0FBQyxDQUFDO1lBQ0YsS0FBSyxNQUFNLE1BQU0sSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO2dCQUN0QyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLENBQUM7WUFDRCxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztnQkFBRSxjQUFjLEVBQUUsQ0FBQztRQUMxRSxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDckYsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUM3QixNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDckQsSUFBSSxlQUFlLEVBQUUsT0FBTyxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sZUFBZSxDQUFDLE1BQU0sSUFBSSxJQUFJLHFCQUFxQixFQUFFLENBQUM7WUFDOUQsQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQzFELElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUMxRixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyw2QkFBNkIsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNwRixJQUFJLGVBQWUsRUFBRSxVQUFVLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQy9DLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLG1DQUFtQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDekYsQ0FBQztZQUNELElBQUksQ0FBQyxxQkFBcUIsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyw0QkFBNEIsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztnQkFDOUYsTUFBTSxJQUFJLDJCQUEyQixDQUNuQyxTQUFTLEVBQ1QsK0NBQStDLENBQ2hELENBQUM7WUFDSixDQUFDO1lBQ0QsSUFBSSxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxJQUFJLDJCQUEyQixDQUFDLFNBQVMsRUFBRSxtQ0FBbUMsQ0FBQyxDQUFDO1lBQ3hGLENBQUM7WUFDRCxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxLQUFLLFNBQVMsSUFBSSxjQUFjLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZFLE1BQU0sSUFBSSwwQkFBMEIsQ0FDbEMsOEVBQThFLENBQy9FLENBQUM7WUFDSixDQUFDO1lBQ0QsSUFBSSxjQUFjLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLG9DQUFvQyxDQUFDLGNBQWMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ25HLENBQUM7WUFDRCxJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQywrQkFBK0IsRUFBRSxDQUFDO2dCQUN0RyxNQUFNLElBQUkseUJBQXlCLENBQ2pDLFlBQVksU0FBUyw2Q0FBNkMsQ0FDbkUsQ0FBQztZQUNKLENBQUM7WUFDRCxJQUNFLE1BQU0sQ0FBQyxzQkFBc0IsR0FBRyxRQUFRO2tCQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLDZCQUE2QixFQUMzRCxDQUFDO2dCQUNELE1BQU0sSUFBSSx5QkFBeUIsQ0FDakMsWUFBWSxTQUFTLGtEQUFrRCxDQUN4RSxDQUFDO1lBQ0osQ0FBQztZQUNELElBQ0UsV0FBVzttQkFDUixDQUFDLEdBQUcsTUFBTSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxDQUFDO3FCQUMzQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUssV0FBVyxDQUFDLEVBQ3JELENBQUM7Z0JBQ0QsTUFBTSxJQUFJLDJCQUEyQixDQUFDLFNBQVMsRUFBRSw4QkFBOEIsV0FBVyxHQUFHLENBQUMsQ0FBQztZQUNqRyxDQUFDO1lBQ0QsSUFBSSxpQkFBdUQsQ0FBQztZQUM1RCxJQUFJLGdCQUEyQyxDQUFDO1lBQ2hELE1BQU0sVUFBVSxHQUFHLElBQUksT0FBTyxDQUFvQixDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtnQkFDcEUsaUJBQWlCLEdBQUcsT0FBTyxDQUFDO2dCQUM1QixnQkFBZ0IsR0FBRyxNQUFNLENBQUM7WUFDNUIsQ0FBQyxDQUFDLENBQUM7WUFDSCxLQUFLLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdkMsSUFBSSxjQUEwRCxDQUFDO1lBQy9ELElBQUksYUFBd0MsQ0FBQztZQUM3QyxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBdUIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQ3BFLGNBQWMsR0FBRyxPQUFPLENBQUM7Z0JBQ3pCLGFBQWEsR0FBRyxNQUFNLENBQUM7WUFDekIsQ0FBQyxDQUFDLENBQUM7WUFDSCxLQUFLLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDcEMsTUFBTSxNQUFNLEdBQWtCO2dCQUM1QixLQUFLO2dCQUNMLE1BQU07Z0JBQ04sT0FBTztnQkFDUCxLQUFLLEVBQUUsY0FBYyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxLQUFLO2dCQUNqRixTQUFTO2dCQUNULE9BQU8sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRTtnQkFDcEMsYUFBYSxFQUFFLEVBQUUsSUFBSSxDQUFDLG1CQUFtQjtnQkFDekMsTUFBTSxFQUFFLFFBQVE7Z0JBQ2hCLFFBQVEsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtnQkFDbEMsR0FBRyxDQUFDLFdBQVcsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLENBQUM7Z0JBQ2pFLE1BQU0sRUFBRSxnQkFBZ0I7Z0JBQ3hCLE9BQU8sRUFBRSxpQkFBaUI7Z0JBQzFCLEdBQUcsQ0FBQyxjQUFjLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxFQUFFLENBQUM7Z0JBQzNELFFBQVE7Z0JBQ1IsVUFBVTtnQkFDVixpQkFBaUI7Z0JBQ2pCLGdCQUFnQjtnQkFDaEIsT0FBTztnQkFDUCxjQUFjO2dCQUNkLGFBQWE7YUFDZCxDQUFDO1lBQ0YsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDaEMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzFELE1BQU0sQ0FBQyxzQkFBc0IsSUFBSSxRQUFRLENBQUM7WUFDMUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQztZQUNuRCxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzdDLE9BQU87Z0JBQ0wsU0FBUyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQztnQkFDakUsT0FBTztnQkFDUCxNQUFNO2FBQ1AsQ0FBQztRQUNKLENBQUM7Z0JBQVMsQ0FBQztZQUNULEtBQUssTUFBTSxNQUFNLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztnQkFDdEMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxjQUFjLENBQUMsQ0FBQztZQUN0RCxDQUFDO1lBQ0QsSUFBSSxDQUFDLDRCQUE0QixDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN2RCx1QkFBdUIsRUFBRSxDQUFDO1lBQzFCLFlBQVksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLDZCQUE2QixDQUFDLFFBQWdCO1FBQ3BELElBQUksSUFBSSxDQUFDLHVCQUF1QixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUNyRixNQUFNLElBQUkseUJBQXlCLENBQUMsNkRBQTZELENBQUMsQ0FBQztRQUNyRyxDQUFDO1FBQ0QsSUFDRSxJQUFJLENBQUMsMkJBQTJCLEdBQUcsUUFBUTtjQUN6QyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLHdCQUF3QixFQUN0RCxDQUFDO1lBQ0QsTUFBTSxJQUFJLHlCQUF5QixDQUFDLGtFQUFrRSxDQUFDLENBQUM7UUFDMUcsQ0FBQztRQUNELElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQywyQkFBMkIsSUFBSSxRQUFRLENBQUM7UUFDN0MsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLE9BQU8sR0FBRyxFQUFFO1lBQ1YsSUFBSSxRQUFRO2dCQUFFLE9BQU87WUFDckIsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNoQixJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsMkJBQTJCLElBQUksUUFBUSxDQUFDO1FBQy9DLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFTyx3QkFBd0IsQ0FBQyxLQUFvQixFQUFFLE1BQTJCO1FBQ2hGLElBQUksTUFBTSxDQUFDLGdCQUFnQjtZQUFFLE9BQU87UUFDcEMsSUFBSSxLQUFxQixDQUFDO1FBQzFCLEtBQUssR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFO2FBQ3RCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2FBQ2hELE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDWixJQUFJLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxLQUFLO2dCQUFFLE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDO1lBQ3RFLElBQ0UsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQzttQkFDMUIsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQzttQkFDL0MsS0FBSyxDQUFDLFNBQVMsS0FBSyxRQUFRO21CQUM1QixLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLE1BQU07Z0JBQzFELElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7UUFDTCxNQUFNLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLEtBQUssS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRU8sS0FBSyxDQUFDLGdCQUFnQixDQUFDLEtBQW9CLEVBQUUsTUFBMkI7UUFDOUUsT0FDRSxLQUFLLENBQUMsU0FBUyxLQUFLLFFBQVE7ZUFDekIsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxNQUFNO2VBQ3ZELENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFDbEQsQ0FBQztZQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLE1BQU07Z0JBQUUsT0FBTztZQUNwQixJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLE1BQU07Z0JBQUUsU0FBUztZQUMzRSxNQUFNLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQztZQUMzQixNQUFNLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDM0MsTUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzVDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNuRCxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQztnQkFDSCxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzVDLE9BQU87WUFDVCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHO29CQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDOUYsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUN6QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQzlFLElBQUksS0FBSyxDQUFDLFNBQVMsS0FBSyxRQUFRO29CQUFFLE9BQU87WUFDM0MsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8scUJBQXFCLENBQUMsTUFBcUIsRUFBRSxHQUFlO1FBQ2xFLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbEMsTUFBTSxHQUFHLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksSUFBSSxxQkFBcUIsRUFBRSxDQUFDO1FBQ3BFLENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxJQUNFLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxDQUFDLE1BQU07ZUFDakQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLE1BQU07ZUFDN0QsR0FBRyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHO1lBQ2xELE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLHFCQUFxQixDQUFDLDBDQUEwQyxDQUFDLENBQUMsQ0FBQztRQUM1RyxJQUFJLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxvQ0FBb0MsQ0FDdEQsTUFBTSxDQUFDLGNBQWMsRUFDckIsR0FBRyxDQUFDLEtBQUssRUFDVCxHQUFHLENBQUMsTUFBTSxFQUNWLEdBQUcsQ0FBQyxPQUFPLENBQ1osQ0FBQztZQUNGLElBQ0UsR0FBRyxDQUFDLE9BQU8sS0FBSyxNQUFNLENBQUMsT0FBTzttQkFDM0IsR0FBRyxDQUFDLEtBQUssS0FBSyxNQUFNLENBQUMsS0FBSzttQkFDMUIsR0FBRyxDQUFDLFNBQVMsS0FBSyxNQUFNLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFDcEQsQ0FBQztnQkFDRCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQ2hDLElBQUkscUJBQXFCLENBQUMsMERBQTBELENBQUMsQ0FDdEYsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxNQUFxQixFQUFFLEdBQWU7UUFDdEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU8sQ0FBQztRQUM5QixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBUSxDQUFDO1FBQ2hDLElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1FBQy9CLDZFQUE2RTtRQUM3RSxJQUFJLDJCQUEyQixHQUFHLEdBQVMsRUFBRSxDQUFDLFNBQVMsQ0FBQztRQUN4RCxJQUFJLENBQUM7WUFDSCxJQUFJLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDeEMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyw0QkFBNEIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3BFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3hDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLEtBQWUsQ0FBQyxDQUFDO2dCQUN6RyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUN4QyxNQUFNLGdCQUFnQixHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUVsRSxDQUFDO2dCQUNMLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3hDLEdBQUcsQ0FBQyxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FDbEUsR0FBRyxFQUNILEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FDM0MsZ0JBQWdCLEVBQ2hCLEVBQUUsWUFBWSxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FDNUIsQ0FDRixDQUFDO2dCQUNGLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3hDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDbEUsMkJBQTJCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQ2xGLEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyw2QkFBNkIsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUM5RSxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRTtvQkFDM0QsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsS0FBSyxTQUFTLEVBQUUsQ0FBQzt3QkFDekQsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO29CQUNoRSxDQUFDO29CQUNELEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLG1CQUFtQixHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUM7b0JBQ25ELEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO29CQUNoRixJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQzt3QkFDM0MsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDM0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxxQkFBcUI7NEJBQy9DLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQzs0QkFDN0YsQ0FBQyxDQUFDLFNBQVMsQ0FBQzt3QkFDZCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQ0FBZ0MsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDckYsR0FBRyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUM7NEJBQ2hDLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSzs0QkFDaEIsYUFBYSxFQUFFLFdBQVcsQ0FBQyxXQUFXLENBQUMsU0FBUzs0QkFDaEQsTUFBTSxFQUFFLFdBQVc7NEJBQ25CLGdCQUFnQixFQUFFLElBQUk7NEJBQ3RCLFFBQVEsRUFBRSxFQUFFOzRCQUNaLGlCQUFpQixFQUFFLFNBQVMsS0FBSyxTQUFTOzRCQUMxQyxlQUFlOzRCQUNmLFVBQVUsRUFBRSxTQUFTLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFdBQVc7NEJBQ2hFLEdBQUcsQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxDQUFDOzRCQUM5RCxHQUFHLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDO3lCQUNsRCxDQUFDLENBQUM7d0JBQ0gsSUFBSSxTQUFTLEVBQUUsQ0FBQzs0QkFDZCxHQUFHLENBQUMsTUFBTSxDQUFDLGdCQUFnQixHQUFHO2dDQUM1QixJQUFJLEVBQUUsU0FBUztnQ0FDZixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7Z0NBQ2hCLFNBQVM7Z0NBQ1QsS0FBSyxFQUFFLFdBQVc7Z0NBQ2xCLGVBQWU7NkJBQ2hCLENBQUM7d0JBQ0osQ0FBQztvQkFDSCxDQUFDO2dCQUNILENBQUMsQ0FBQyxDQUFDO2dCQUNILGtCQUFrQixHQUFHLElBQUksQ0FBQztnQkFDMUIsR0FBRyxDQUFDLG1CQUFtQixHQUFHLGNBQWMsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ2xFLEdBQUcsQ0FBQyx3QkFBd0IsR0FBRyxjQUFjLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQzVFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3hDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7b0JBQzFDLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7d0JBQ2xDLE1BQU0sR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxJQUFJLElBQUkscUJBQXFCLEVBQUUsQ0FBQztvQkFDcEUsQ0FBQztvQkFDRCxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7d0JBQ3BHLE1BQU0sSUFBSSxxQkFBcUIsQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO29CQUN0RixDQUFDO29CQUNELEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztvQkFDdEUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxHQUFHO3dCQUM1QixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7d0JBQ2hCLE1BQU0sRUFBRSxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFNBQVM7d0JBQ2pELFNBQVMsRUFBRSxXQUFXLENBQUMsV0FBVyxDQUFDLFNBQVM7cUJBQzdDLENBQUM7b0JBQ0YsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDO2dCQUNuRSxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUksOEJBQThCLENBQUMsS0FBSyxDQUFDO29CQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQztnQkFDMUUsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUNsSCxJQUFJLGFBQWEsR0FBYyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksY0FBdUIsQ0FBQztnQkFDNUIsSUFBSSxDQUFDO29CQUNILE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsNkJBQTZCLENBQ3JELEdBQUcsRUFDSCxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsRUFBRSxtQkFBbUIsQ0FDckQsQ0FBQztnQkFDSixDQUFDO2dCQUFDLE9BQU8sVUFBVSxFQUFFLENBQUM7b0JBQ3BCLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ2pDLENBQUM7Z0JBQ0QsSUFBSSxDQUFDO29CQUNILGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxrQkFBa0IsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUNwRyxDQUFDO2dCQUFDLE9BQU8sYUFBYSxFQUFFLENBQUM7b0JBQ3ZCLGNBQWMsR0FBRyxhQUFhLENBQUM7Z0JBQ2pDLENBQUM7Z0JBQ0QsSUFBSSxjQUFjLEtBQUssU0FBUyxJQUFJLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQzdELGNBQWMsR0FBRyxhQUFhLENBQUMsQ0FBQyxjQUFjLEVBQUUsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDO2dCQUNyRSxDQUFDO2dCQUNELElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLEtBQUssUUFBUSxJQUFJLGNBQWMsS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDckUsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLENBQUMsU0FBUyxFQUFFLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQztvQkFDOUQsSUFBSSxDQUFDO3dCQUNILE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO29CQUNyRSxDQUFDO29CQUFDLE9BQU8sVUFBVSxFQUFFLENBQUM7d0JBQ3BCLGNBQWMsR0FBRyxVQUFVLENBQUM7b0JBQzlCLENBQUM7Z0JBQ0gsQ0FBQztnQkFDRCxNQUFNLFNBQVMsR0FBRyxjQUFjO3VCQUMzQixDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxTQUFTLEVBQUUsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDM0YsTUFBTSxTQUFTLENBQUM7WUFDbEIsQ0FBQztZQUVELE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO1lBQ2xFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7Z0JBQ25ELElBQUksRUFBRSxPQUFPO2dCQUNiLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSztnQkFDaEIsU0FBUyxFQUFFLEdBQUcsQ0FBQyxhQUFhO2dCQUM1QixPQUFPLEVBQUUsY0FBYyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO2FBQzVDLENBQUMsQ0FBQztZQUNILEtBQUssTUFBTSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsbUJBQW9CLEVBQUUsR0FBRyxDQUFDLHdCQUF5QixDQUFDLEVBQUUsQ0FBQztnQkFDaEYsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtvQkFDbkQsSUFBSSxFQUFFLGlCQUFpQjtvQkFDdkIsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLO29CQUNoQixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7b0JBQzVCLE9BQU87aUJBQ1IsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7Z0JBQVMsQ0FBQztZQUNULDJCQUEyQixFQUFFLENBQUM7UUFDaEMsQ0FBQztRQUVELE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7UUFDM0QsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUNsQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU87WUFDdkIsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLO1lBQ2hCLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtTQUM5QixDQUFDLENBQUMsQ0FBQztRQUNKLEdBQUcsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDdEQsTUFBTSxlQUFlLEdBQUc7WUFDdEIsV0FBVyxFQUFFLEdBQUcsQ0FBQyxXQUFXO1lBQzVCLEtBQUssRUFBRSxHQUFHLENBQUMsVUFBVSxDQUFDLE1BQU07WUFDNUIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTTtZQUNyQixPQUFPLEVBQUUsQ0FBQyxPQUEyRCxFQUFFLEVBQUUsQ0FDdkUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDO1lBQ3JFLFlBQVksRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUs7WUFDaEMsd0JBQXdCLEVBQUUsSUFBSTtZQUM5QixlQUFlLEVBQUUsQ0FBQyxRQUF1QyxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDL0YsY0FBYyxFQUFFLENBQUMsS0FBaUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUM7WUFDL0YsWUFBWSxFQUFFLENBQUMsT0FBcUMsRUFBRSxFQUFFLENBQ3RELElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLDJCQUEyQixDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDO1NBQ2hGLENBQUM7UUFDRixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLFdBQVc7WUFDeEYsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDO2dCQUN2QyxHQUFHLEVBQUUsR0FBRyxDQUFDLFdBQVc7Z0JBQ3BCLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVTtnQkFDMUIsR0FBRyxlQUFlO2FBQ25CLENBQUM7WUFDSixDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFDdkQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQy9ELENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQzNFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQ2hDLE1BQU0sRUFDTixZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUM1QyxLQUFLLENBQ04sQ0FDRixDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN0RSxLQUFLLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVPLHVCQUF1QixDQUFDLE1BQXFCO1FBQ25ELE9BQU87WUFDTCxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU87WUFDdkIsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhO1lBQ25DLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztZQUN2QixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7WUFDM0IsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO1lBQ3JCLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtZQUN6QixHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDaEQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2xFLEdBQUcsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUM3RCxDQUFDO0lBQ0osQ0FBQztJQUVPLGdCQUFnQixDQUN0QixNQUEyQixFQUMzQixPQUFlO1FBRWYsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvRCxPQUFPLFdBQVc7WUFDaEIsQ0FBQyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxXQUFXLENBQUM7WUFDM0MsQ0FBQyxDQUFDLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVNLG9CQUFvQixDQUN6QixNQUFxQixFQUNyQixJQUErRSxFQUMvRSxRQUErQixJQUFJLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDO1FBRW5FLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7WUFDekQsSUFBSTtZQUNKLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztZQUN2QixHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDOUMsS0FBSyxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUM7U0FDN0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLGtCQUFrQixDQUN4QixNQUFxQixFQUNyQixNQUE0QyxFQUM1QyxLQUFlLEVBQ2YsTUFBMEI7UUFFMUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUM3QixJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLE1BQU07WUFBRSxPQUFPO1FBQ3pFLE1BQU0sQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssS0FBSyxNQUFNLENBQUMsQ0FBQztRQUM1RSxNQUFNLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyRCxNQUFNLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3RixPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDckIsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQ3RCLE9BQU8sTUFBTSxDQUFDLGNBQWMsQ0FBQztRQUM3QixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUcsTUFBTSxRQUFRLEdBQTBCO1lBQ3RDLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQztZQUN2QyxNQUFNO1lBQ04sVUFBVSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO1lBQ3BDLEdBQUcsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzdELGFBQWEsRUFBRSxRQUFRLEVBQUUsYUFBYSxJQUFJLEtBQUs7WUFDL0MsR0FBRyxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksUUFBUSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sS0FBSyxDQUFDO2dCQUNuRSxDQUFDLENBQUMsRUFBRTtnQkFDSixDQUFDLENBQUMsRUFBRSxpQkFBaUIsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQztTQUM1RCxDQUFDO1FBQ0YsTUFBTSxDQUFDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2hFLE9BQ0UsTUFBTSxDQUFDLDBCQUEwQixDQUFDLElBQUk7Y0FDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyw0QkFBNEIsRUFDMUQsQ0FBQztZQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUEyQixDQUFDO1lBQzNGLElBQUksQ0FBQyxNQUFNO2dCQUFFLE1BQU07WUFDbkIsTUFBTSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMvRCxJQUFJLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsTUFBTTtnQkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7WUFDN0UsTUFBTSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25DLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxTQUFTLEdBQUcsS0FBSyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxxQkFBcUIsRUFBRSxDQUFDLENBQUM7WUFDckYsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsQ0FBQztJQUNILENBQUM7SUFFTSxrQkFBa0IsQ0FDdkIsTUFBcUIsRUFDckIsTUFBNkIsRUFDN0IsT0FBNkM7UUFFN0MsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssTUFBTTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3RGLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsd0JBQXdCLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLEtBQUssTUFBTSxDQUFDLE9BQU87WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN6RCxJQUFJLEdBQUcsQ0FBQyxLQUFLLEtBQUssWUFBWSxJQUFJLEdBQUcsQ0FBQyxLQUFLLEtBQUssV0FBVztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQzFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQy9DLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVNLHVCQUF1QixDQUM1QixNQUEyQixFQUMzQixNQUE2QixFQUM3QixlQUF3QixFQUN4QixPQUE4QztRQUU5QyxLQUFLLE1BQU0sTUFBTSxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2pFLElBQUksTUFBTSxDQUFDLE9BQU8sS0FBSyxlQUFlO2dCQUFFLFNBQVM7WUFDakQsSUFBSSxDQUFDLGtCQUFrQixDQUNyQixNQUFNLEVBQ04sTUFBTSxFQUNOLE9BQTBELENBQzNELENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVNLHNCQUFzQixDQUFDLE1BQTJCO1FBQ3ZELEtBQUssTUFBTSxNQUFNLElBQUksTUFBTSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDNUQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQ3JCLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQztZQUN0QixPQUFPLE1BQU0sQ0FBQyxjQUFjLENBQUM7UUFDL0IsQ0FBQztRQUNELE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUM5QixNQUFNLENBQUMsc0JBQXNCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEMsTUFBTSxDQUFDLDBCQUEwQixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxzQkFBc0IsR0FBRyxDQUFDLENBQUM7SUFDcEMsQ0FBQztDQUNGIn0=
|