@modelprofile.com/authswitch 8.0.0 → 8.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.
Files changed (43) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/authority-import-contract.d.ts +207 -0
  3. package/dist_ts/authority-import-contract.js +18 -0
  4. package/dist_ts/classes.authoritycli.d.ts +4 -0
  5. package/dist_ts/classes.authoritycli.js +148 -11
  6. package/dist_ts/classes.authorityclient.d.ts +7 -0
  7. package/dist_ts/classes.authorityclient.js +13 -1
  8. package/dist_ts/classes.authoritydaemon.d.ts +4 -0
  9. package/dist_ts/classes.authoritydaemon.js +72 -1
  10. package/dist_ts/classes.authoritydatabase.d.ts +5 -0
  11. package/dist_ts/classes.authoritydatabase.js +20 -5
  12. package/dist_ts/classes.authorityimport.d.ts +161 -0
  13. package/dist_ts/classes.authorityimport.js +638 -0
  14. package/dist_ts/classes.authoritymodels.d.ts +12 -0
  15. package/dist_ts/classes.authoritymodels.js +17 -1
  16. package/dist_ts/index.d.ts +1 -0
  17. package/dist_ts/index.js +6 -3
  18. package/dist_ts/ts_migration/legacysources/authswitchstores.d.ts +2 -0
  19. package/dist_ts/ts_migration/legacysources/authswitchstores.js +244 -0
  20. package/dist_ts/ts_migration/legacysources/index.d.ts +18 -0
  21. package/dist_ts/ts_migration/legacysources/index.js +24 -0
  22. package/dist_ts/ts_migration/legacysources/material.d.ts +37 -0
  23. package/dist_ts/ts_migration/legacysources/material.js +120 -0
  24. package/dist_ts/ts_migration/legacysources/nativestores.d.ts +2 -0
  25. package/dist_ts/ts_migration/legacysources/nativestores.js +207 -0
  26. package/dist_ts/ts_migration/legacysources/shared.d.ts +124 -0
  27. package/dist_ts/ts_migration/legacysources/shared.js +142 -0
  28. package/package.json +5 -1
  29. package/readme.md +46 -0
  30. package/ts/00_commitinfo_data.ts +1 -1
  31. package/ts/authority-import-contract.ts +216 -0
  32. package/ts/classes.authoritycli.ts +164 -10
  33. package/ts/classes.authorityclient.ts +22 -0
  34. package/ts/classes.authoritydaemon.ts +72 -0
  35. package/ts/classes.authoritydatabase.ts +20 -4
  36. package/ts/classes.authorityimport.ts +718 -0
  37. package/ts/classes.authoritymodels.ts +21 -0
  38. package/ts/index.ts +5 -2
  39. package/ts/ts_migration/legacysources/authswitchstores.ts +211 -0
  40. package/ts/ts_migration/legacysources/index.ts +35 -0
  41. package/ts/ts_migration/legacysources/material.ts +134 -0
  42. package/ts/ts_migration/legacysources/nativestores.ts +204 -0
  43. package/ts/ts_migration/legacysources/shared.ts +220 -0
@@ -0,0 +1,638 @@
1
+ import * as plugins from './plugins.js';
2
+ import { authSwitchEnvironmentId } from './classes.operations.js';
3
+ import { AuthSwitchTpmSecretCodec } from './classes.authoritysecrets.js';
4
+ import { ClaudeAccountStatus } from './classes.claudestatus.js';
5
+ import { ClaudeTokenRefresh } from './classes.claudetokenrefresh.js';
6
+ import { CodexDaemon } from './classes.codexdaemon.js';
7
+ import { CodexHome } from './classes.codexhome.js';
8
+ import { HarnessProcesses } from './classes.harnessprocesses.js';
9
+ import { LegacySourceChangedError, readLegacySourceEnrollments, readLegacySourceMaterial, readLegacySources, resolveLegacySourceLocations } from './ts_migration/legacysources/index.js';
10
+ /**
11
+ * What the owner must know before importing anything.
12
+ *
13
+ * The run-order line is not advice: after an account is imported, its legacy record holds a refresh token
14
+ * the provider has already rotated away, and the everyday legacy commands would restore or exercise exactly
15
+ * that record. The import is therefore only safe once those commands run on the authority.
16
+ */
17
+ const INVENTORY_NOTICE = [
18
+ 'This inventory only reads. It changes no authority record, no legacy store and no credential.',
19
+ 'Importing transfers ownership; it does not copy. Verifying a saved authswitch record refreshes its token, '
20
+ + 'and the legacy copy is unusable from that moment. The fallback is one device sign-in for that account.',
21
+ 'A native Codex, Claude or OpenCode store is projected, not imported: the native tool stays the only '
22
+ + 'refresher, and its record is verified by a provider read that rotates nothing.',
23
+ 'Do not import until the everyday commands run on the authority and the native projections exist. Until '
24
+ + 'then a legacy command could restore or exercise a record whose token an import has already replaced.',
25
+ 'No file under the legacy stores is deleted by an import. Retiring those files is a separate later step.',
26
+ 'The authority store is deliberately not backed up. Losing it later loses the remote-control enrollments '
27
+ + 'and every runtime binding as well as the logins: each account then needs a device sign-in, and each '
28
+ + 'enrollment has to be paired again.',
29
+ ];
30
+ /** Reads the host: the watch lock file, the process table and Codex's own daemon status. */
31
+ export class AuthSwitchImportHostQuiescence {
32
+ authSwitchHome;
33
+ codexHome;
34
+ constructor(authSwitchHome, codexHome) {
35
+ this.authSwitchHome = authSwitchHome;
36
+ this.codexHome = codexHome;
37
+ }
38
+ watchHolderPid() {
39
+ // The lock is read, never acquired: an inventory or an import must not become the watch.
40
+ let raw;
41
+ try {
42
+ raw = plugins.fs.readFileSync(plugins.path.join(this.authSwitchHome, 'watch.lock'), 'utf8');
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ let pid;
48
+ try {
49
+ pid = JSON.parse(raw).pid;
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ if (typeof pid !== 'number' || !Number.isSafeInteger(pid) || pid <= 0)
55
+ return null;
56
+ try {
57
+ process.kill(pid, 0);
58
+ return pid;
59
+ }
60
+ catch (error) {
61
+ return error.code === 'EPERM' ? pid : null;
62
+ }
63
+ }
64
+ runningHarnessPids(binary) {
65
+ return new HarnessProcesses(binary).list().map(item => item.pid);
66
+ }
67
+ codexAppServerRunning() {
68
+ const status = new CodexDaemon(new CodexHome(this.codexHome)).status();
69
+ return status === null ? null : status.running;
70
+ }
71
+ }
72
+ const idHash = (...values) => plugins.crypto.createHash('sha256').update(JSON.stringify(values)).digest('hex');
73
+ const grantPlan = (record) => {
74
+ if (record.sourceKind === 'claude_native') {
75
+ return { providerId: 'anthropic', purpose: 'claude_host_native', audience: 'claude-code-host',
76
+ settledOwner: 'claude_native' };
77
+ }
78
+ if (record.sourceKind === 'opencode_native') {
79
+ return { providerId: 'openai', purpose: 'opencode_native', audience: 'chatgpt',
80
+ settledOwner: 'legacy_native' };
81
+ }
82
+ if (record.sourceKind === 'codex_native') {
83
+ return { providerId: 'openai', purpose: 'openai_managed', audience: 'chatgpt',
84
+ settledOwner: 'legacy_native' };
85
+ }
86
+ return record.providerId === 'anthropic'
87
+ ? { providerId: 'anthropic', purpose: 'claude_host_native', audience: 'claude-code-host',
88
+ settledOwner: 'daemon' }
89
+ : { providerId: 'openai', purpose: 'openai_managed', audience: 'chatgpt', settledOwner: 'daemon' };
90
+ };
91
+ /** One grant per account, purpose and audience -- the same rule the device login uses. */
92
+ const importGrantId = (accountId, plan) => idHash('authswitch-grant-v1', accountId, plan.purpose, plan.audience);
93
+ const importHandoffId = (sourceId) => idHash('authswitch-import-handoff-v1', sourceId);
94
+ /** The handoff phases past the pre-send marker: the exchange may already have consumed the refresh token. */
95
+ const spentHandoffPhases = ['source_stopped', 'needs_reauth', 'aborted'];
96
+ /**
97
+ * What a ledger status asks of the owner.
98
+ *
99
+ * An unsettled row is resumed by submitting the same source again -- unless its handoff got past the marker
100
+ * that says the sign-in exchange may have been sent, because a rotating refresh token is never sent twice.
101
+ * Reading the handoff here is what keeps this answer truthful: without it a source whose only remaining
102
+ * repair is a device sign-in would invite a submission that can only end in a quarantine.
103
+ */
104
+ const importAction = (status, handoff) => {
105
+ if (status === 'complete')
106
+ return 'none';
107
+ if (status === 'quarantined')
108
+ return 'device_login';
109
+ return handoff !== null && spentHandoffPhases.includes(handoff.phase) ? 'device_login' : 'resume';
110
+ };
111
+ /** A refusal the owner can act on. It never leaves a half-written import behind. */
112
+ export class AuthSwitchImportRefusal extends Error {
113
+ }
114
+ // The annotation on the binding, not only on the arrow, is what lets a refusal narrow the code after it.
115
+ const refuse = reason => { throw new AuthSwitchImportRefusal(reason); };
116
+ const RUN_ORDER_REFUSAL = 'Importing needs the run-order acknowledgement: an imported source\'s legacy copy '
117
+ + 'holds a refresh token the provider has rotated away, and the everyday legacy commands would restore or '
118
+ + 'exercise exactly that copy. Import only once those commands run on the authority and the native '
119
+ + 'projections exist.';
120
+ /** Strips the source location: a ledger row stores its hash, and no response may carry the path. */
121
+ const publicSource = (record, ledgerStatus) => ({
122
+ id: record.id,
123
+ sourceKind: record.sourceKind,
124
+ sourcePathHash: record.sourcePathHash,
125
+ sourceDigest: record.sourceDigest,
126
+ treatment: record.treatment,
127
+ proof: record.proof,
128
+ accountId: record.accountId,
129
+ providerId: record.providerId,
130
+ email: record.email,
131
+ plan: record.plan,
132
+ label: record.label,
133
+ accessExpiresAt: record.accessExpiresAt,
134
+ enrollmentCount: record.enrollmentCount,
135
+ ledgerStatus,
136
+ problems: [...record.problems],
137
+ });
138
+ /**
139
+ * The one-time account import.
140
+ *
141
+ * It reads the legacy stores through the isolated migration readers and reports them against the authority's
142
+ * migration ledger. Nothing here is a runtime fallback: no ordinary authority operation reaches this class,
143
+ * and it never writes to a legacy store.
144
+ */
145
+ export class AuthSwitchAuthorityImport {
146
+ database;
147
+ env;
148
+ homeDirectory;
149
+ now;
150
+ openAi;
151
+ claudeStatus;
152
+ claudeTokens;
153
+ secrets;
154
+ quiescence;
155
+ constructor(database, options = {}) {
156
+ this.database = database;
157
+ this.env = options.env ?? process.env;
158
+ this.homeDirectory = options.homeDirectory ?? plugins.os.homedir();
159
+ this.now = options.now ?? Date.now;
160
+ this.openAi = options.openAi ?? new plugins.flexAccounts.OpenAiProviderAdapter();
161
+ this.claudeStatus = options.claudeStatus ?? new ClaudeAccountStatus();
162
+ this.claudeTokens = options.claudeTokens ?? new ClaudeTokenRefresh();
163
+ this.secrets = options.secrets ?? new AuthSwitchTpmSecretCodec();
164
+ const locations = resolveLegacySourceLocations(this.env, this.homeDirectory);
165
+ this.quiescence = options.quiescence
166
+ ?? new AuthSwitchImportHostQuiescence(locations.authSwitchHome, locations.codexHome);
167
+ }
168
+ /** The credential-free report. Reads the legacy stores and the ledger; writes nothing. */
169
+ async inventory() {
170
+ const now = this.now();
171
+ const report = readLegacySources({ env: this.env, homeDirectory: this.homeDirectory, now });
172
+ const sources = [];
173
+ for (const record of report.sources) {
174
+ const ledger = await this.database.readMigrationLedger(record.id);
175
+ const source = publicSource(record, ledger?.status ?? null);
176
+ if (ledger !== null && ledger.sourceDigest !== record.sourceDigest) {
177
+ // The source changed after its row was written. A later import must not treat the approved bytes and
178
+ // the current bytes as the same source; the ledger deliberately refuses to move that row.
179
+ source.problems.push('the source changed after its migration ledger row was written');
180
+ }
181
+ if (ledger?.status === 'complete') {
182
+ source.problems.push('this source is already imported; its legacy copy is retired');
183
+ }
184
+ sources.push(source);
185
+ }
186
+ return {
187
+ generatedAt: new Date(now).toISOString(),
188
+ environmentId: authSwitchEnvironmentId(this.env),
189
+ notice: [...INVENTORY_NOTICE],
190
+ sources,
191
+ problems: [...report.problems],
192
+ };
193
+ }
194
+ /**
195
+ * Where every source the authority knows about stands.
196
+ *
197
+ * Read from the migration ledger, the grants and the handoffs only: it opens no legacy store, so it stays
198
+ * truthful about what the authority decided even if a source has since been moved or deleted on the host.
199
+ * A source that was never submitted has no ledger row and belongs to the inventory, not here.
200
+ */
201
+ async status(request = {}) {
202
+ const page = await this.database.migrationLedgerPage(request.after ?? null, request.limit ?? 128);
203
+ const entries = [];
204
+ for (const row of page.rows) {
205
+ const grant = row.grantId === null ? null : await this.database.readGrant(row.grantId);
206
+ const handoff = await this.database.readHandoff(importHandoffId(row.id));
207
+ entries.push({
208
+ sourceId: row.id, sourceKind: row.sourceKind, status: row.status,
209
+ accountId: row.accountId, loginId: row.grantId, owner: grant?.owner ?? null,
210
+ action: importAction(row.status, handoff), statusObservedAt: row.statusObservedAt,
211
+ });
212
+ }
213
+ return { generatedAt: this.stamp(), entries, nextCursor: page.nextCursor };
214
+ }
215
+ /**
216
+ * Imports one source.
217
+ *
218
+ * A source whose grant the authority takes over is verified by one real refresh, which rotates its token
219
+ * and is the point of no return; a source a native tool keeps refreshing is verified by a provider read
220
+ * that rotates nothing. Every step before the refresh is durable, and the marker that says "the exchange
221
+ * may have been sent" is the handoff's own `source_stopped` phase: a restart that finds it never replays
222
+ * the grant, it asks for a device sign-in instead.
223
+ */
224
+ async submit(request) {
225
+ if (request.acknowledgeRunOrder !== true)
226
+ refuse(RUN_ORDER_REFUSAL);
227
+ if (request.callerQuiescent !== true) {
228
+ refuse('Importing needs the caller\'s assertion that nothing it owns will use this source meanwhile: '
229
+ + 'a host that drives the legacy library inside its own process cannot be observed from here.');
230
+ }
231
+ const record = this.resolveSource(request.submission);
232
+ const plan = grantPlan(record);
233
+ this.assertQuiescent(record);
234
+ const ledger = await this.database.readMigrationLedger(record.id);
235
+ if (ledger !== null) {
236
+ if (ledger.sourceDigest !== record.sourceDigest) {
237
+ refuse('The source changed after its migration ledger row was written; it is a different source now.');
238
+ }
239
+ if (ledger.status === 'complete')
240
+ refuse('This source is already imported.');
241
+ if (ledger.status === 'quarantined') {
242
+ refuse('This source is quarantined: its outcome could not be established, so it needs a device '
243
+ + 'sign-in for that account rather than another import.');
244
+ }
245
+ }
246
+ const accountId = record.accountId;
247
+ const subject = record.subject;
248
+ const workspaceId = record.workspaceId;
249
+ if (accountId === null || subject === null || workspaceId === null) {
250
+ refuse('The source carries no provider identity the authority can bind an account to.');
251
+ }
252
+ const grantId = importGrantId(accountId, plan);
253
+ if (ledger === null)
254
+ await this.beginLedger(record);
255
+ const material = this.material(record, request.submission);
256
+ return record.treatment === 'project'
257
+ ? this.project(record, plan, { accountId, subject, workspaceId, grantId }, material)
258
+ : this.adopt(record, plan, { accountId, subject, workspaceId, grantId }, material);
259
+ }
260
+ /** The source a submission names, proven to be the one that was inventoried. */
261
+ resolveSource(submission) {
262
+ if (submission.kind === 'external') {
263
+ const identity = this.externalIdentity(submission.credential.idToken);
264
+ return {
265
+ id: idHash('authswitch-migration-v1', 'agl_flex', submission.sourcePathHash),
266
+ sourceKind: 'agl_flex', path: '', sourcePathHash: submission.sourcePathHash,
267
+ sourceDigest: submission.sourceDigest, treatment: 'import', proof: 'rotating_refresh',
268
+ accountId: identity.accountId, subject: identity.subject, workspaceId: identity.workspaceId,
269
+ providerId: 'openai', email: identity.email, plan: identity.plan, label: identity.email,
270
+ accessExpiresAt: null, enrollmentCount: null, problems: [],
271
+ };
272
+ }
273
+ const report = readLegacySources({ env: this.env, homeDirectory: this.homeDirectory, now: this.now() });
274
+ const record = report.sources.find(source => source.id === submission.sourceId);
275
+ if (!record)
276
+ refuse('That source no longer exists on this host.');
277
+ if (record.sourceDigest !== submission.sourceDigest) {
278
+ refuse('The source changed after it was inventoried; review the inventory again before importing.');
279
+ }
280
+ if (record.problems.length)
281
+ refuse(`The source cannot be imported: ${record.problems.join('; ')}.`);
282
+ if (record.treatment === 'refuse')
283
+ refuse('This source is not a login the authority can hold.');
284
+ return record;
285
+ }
286
+ externalIdentity(idToken) {
287
+ let info;
288
+ try {
289
+ info = plugins.flexAuth.parseOpenAiChatGptTokenInfo(idToken);
290
+ }
291
+ catch {
292
+ return refuse('The submitted login carries no readable ChatGPT identity.');
293
+ }
294
+ if (!info.chatgptUserId || !info.chatgptAccountId) {
295
+ refuse('The submitted login omits a stable ChatGPT user or account identity.');
296
+ }
297
+ return {
298
+ accountId: idHash('authswitch-account-v1', 'openai', info.chatgptUserId, info.chatgptAccountId),
299
+ subject: info.chatgptUserId, workspaceId: info.chatgptAccountId,
300
+ email: info.email?.toLowerCase() ?? null, plan: info.chatgptPlanType ?? null,
301
+ };
302
+ }
303
+ /** Reads the credential the daemon will seal. Only an external submission brings its own. */
304
+ material(record, submission) {
305
+ if (submission.kind === 'external') {
306
+ return { providerId: 'openai', credential: { kind: 'chatgptOAuth', providerId: 'openai',
307
+ accessToken: submission.credential.accessToken, refreshToken: submission.credential.refreshToken,
308
+ idToken: submission.credential.idToken } };
309
+ }
310
+ try {
311
+ return readLegacySourceMaterial(record);
312
+ }
313
+ catch (error) {
314
+ if (error instanceof LegacySourceChangedError)
315
+ refuse(error.message);
316
+ throw error;
317
+ }
318
+ }
319
+ /**
320
+ * Refuses while anything that could refresh this source is running.
321
+ *
322
+ * Unknown counts as running: an import that guessed idle could rotate a token another owner is using.
323
+ */
324
+ assertQuiescent(record) {
325
+ const watch = this.quiescence.watchHolderPid();
326
+ if (watch !== null) {
327
+ refuse(`An authswitch watch is running (pid ${watch}); it switches logins. Stop it and import again.`);
328
+ }
329
+ const binary = record.providerId === 'anthropic' ? 'claude'
330
+ : record.sourceKind === 'opencode_native' ? 'opencode' : null;
331
+ if (binary !== null) {
332
+ const pids = this.quiescence.runningHarnessPids(binary);
333
+ if (pids.length) {
334
+ refuse(`${binary} is running (pid ${pids.join(', ')}) and owns this login. Close it and import again.`);
335
+ }
336
+ }
337
+ if (record.sourceKind === 'codex_native'
338
+ || (record.sourceKind === 'authswitch_stash' && record.providerId === 'openai')) {
339
+ const running = this.quiescence.codexAppServerRunning();
340
+ if (running !== false) {
341
+ refuse(running === null
342
+ ? 'Codex could not be asked whether its app-server is running, and an unknown app-server counts '
343
+ + 'as running. Make Codex answerable and import again.'
344
+ : 'The Codex app-server is running and refreshes this login on its own schedule. '
345
+ + 'Stop it with `codex app-server daemon stop` and import again.');
346
+ }
347
+ }
348
+ }
349
+ async beginLedger(record) {
350
+ const updateId = plugins.crypto.randomUUID();
351
+ // Written before any provider call, so a crash always leaves the source named in the authority.
352
+ await this.database.changeMigrationLedger(updateId, record.id, () => ({
353
+ id: record.id, version: 1, sourceKind: record.sourceKind, sourcePathHash: record.sourcePathHash,
354
+ sourceDigest: record.sourceDigest, status: 'prepared', accountId: null, grantId: null,
355
+ revision: 1, statusObservedAt: this.stamp(), updateId,
356
+ }));
357
+ }
358
+ async moveLedger(ledgerId, status, accountId, grantId) {
359
+ const updateId = plugins.crypto.randomUUID();
360
+ return this.database.changeMigrationLedger(updateId, ledgerId, current => {
361
+ if (!current)
362
+ throw new Error('The migration ledger row disappeared during the import.');
363
+ return { ...current, status, accountId, grantId, revision: current.revision + 1,
364
+ statusObservedAt: this.stamp(), updateId };
365
+ });
366
+ }
367
+ stamp() { return new Date(this.now()).toISOString(); }
368
+ account(record, identity, plan, existing, grantId, updateId) {
369
+ const label = record.label ?? record.email ?? `${plan.providerId} ${identity.workspaceId}`;
370
+ return existing
371
+ ? { ...existing, label: existing.label || label, email: record.email, plan: record.plan,
372
+ removed: false, revision: existing.revision + 1, statusObservedAt: this.stamp(), updateId }
373
+ : { id: identity.accountId, providerId: plan.providerId, issuer: plan.providerId,
374
+ subject: identity.subject, workspaceId: identity.workspaceId, label, email: record.email,
375
+ plan: record.plan, primaryGrantId: grantId, removed: false, revision: 1,
376
+ statusObservedAt: this.stamp(), updateId };
377
+ }
378
+ /** Writes the account and its grant, choosing the primary or the secondary transaction by identity. */
379
+ async putGrant(identity, record, plan, grantId, make) {
380
+ const existingAccount = await this.database.readAccount(identity.accountId);
381
+ const updateId = plugins.crypto.randomUUID();
382
+ if (existingAccount && existingAccount.primaryGrantId !== grantId) {
383
+ await this.database.changeSecondaryGrant(updateId, identity.accountId, grantId, grant => make(grant, updateId));
384
+ return;
385
+ }
386
+ await this.database.changeAccountAndGrant(updateId, identity.accountId, grantId, (account, grant) => ({
387
+ account: this.account(record, identity, plan, account, grantId, updateId),
388
+ grant: make(grant, updateId),
389
+ }));
390
+ }
391
+ baseGrant(identity, plan, grantId, existing, updateId, overrides) {
392
+ return {
393
+ id: grantId, accountId: identity.accountId, providerId: plan.providerId, purpose: plan.purpose,
394
+ audience: plan.audience, state: 'legacy_native_pending', owner: 'legacy_native',
395
+ grantGeneration: existing ? existing.grantGeneration : 1,
396
+ authorizationGeneration: existing ? existing.authorizationGeneration : 1,
397
+ revision: existing ? existing.revision + 1 : 1, ciphertext: null, accessExpiresAt: null,
398
+ attemptId: null, retryAt: null, retryCount: 0, problem: 'native_owner',
399
+ statusObservedAt: this.stamp(), updateId, ...overrides,
400
+ };
401
+ }
402
+ /** Refuses a source whose grant another owner already holds, in either direction. */
403
+ assertOwnable(existing, plan) {
404
+ if (!existing)
405
+ return;
406
+ if (existing.owner === plan.settledOwner || existing.owner === 'none')
407
+ return;
408
+ refuse(existing.owner === 'daemon'
409
+ ? 'The authority already owns this login; a native store cannot take it over without a handoff.'
410
+ : 'A native store already owns this login. Its account is registered from that source; select it '
411
+ + 'there rather than importing a second copy.');
412
+ }
413
+ /**
414
+ * A projected source: the account is registered, the grant stays with its native owner, and the proof is a
415
+ * provider read that rotates nothing. No refresh is ever sent here.
416
+ */
417
+ async project(record, plan, identity, material) {
418
+ this.assertOwnable(await this.database.readGrant(identity.grantId), plan);
419
+ await this.putGrant(identity, record, plan, identity.grantId, (existing, updateId) => this.baseGrant(identity, plan, identity.grantId, existing, updateId, { state: 'native', owner: plan.settledOwner }));
420
+ try {
421
+ await this.proveWithoutRotation(record, identity, material);
422
+ }
423
+ catch (error) {
424
+ // Not a quarantine: no rotating token was sent here, so nothing was consumed and nothing is lost. The
425
+ // account stays registered with its native owner, unproven, and the same source is submitted again
426
+ // once that native tool has refreshed its own store -- which is exactly what the refusal asks for.
427
+ await this.moveLedger(record.id, 'pending_native_owner', identity.accountId, identity.grantId);
428
+ throw error;
429
+ }
430
+ await this.moveLedger(record.id, 'verified', identity.accountId, identity.grantId);
431
+ await this.moveLedger(record.id, 'complete', identity.accountId, identity.grantId);
432
+ return this.result(record, 'complete', identity, []);
433
+ }
434
+ /** The non-rotating proof: the stored access token is asked about itself and must name this account. */
435
+ async proveWithoutRotation(record, identity, material) {
436
+ if (material.providerId === 'openai') {
437
+ const result = await this.openAi.getAccountRateLimits({ kind: 'chatgptAccess',
438
+ providerId: 'openai', accessToken: material.credential.accessToken,
439
+ accountId: identity.workspaceId, isFedrampAccount: false });
440
+ if (!result.success) {
441
+ refuse(`The stored access token could not be proven live (${result.errorCode}); let the native tool `
442
+ + 'refresh its own store, then import again.');
443
+ }
444
+ // The claims of the very token that answered must still name this account.
445
+ const claims = plugins.flexAuth.parseOpenAiChatGptTokenInfo(material.credential.accessToken);
446
+ if (claims.chatgptAccountId !== identity.workspaceId) {
447
+ refuse('The stored access token belongs to another ChatGPT account.');
448
+ }
449
+ return;
450
+ }
451
+ const oauth = material.login.claudeAiOauth;
452
+ const accessToken = typeof oauth.accessToken === 'string' ? oauth.accessToken : '';
453
+ const scopes = Array.isArray(oauth.scopes)
454
+ ? oauth.scopes.filter((scope) => typeof scope === 'string') : [];
455
+ const read = await this.claudeStatus.readDetailed({ accessToken, scopes,
456
+ identity: { accountUuid: identity.subject, organizationUuid: identity.workspaceId },
457
+ ...(record.plan === null ? {} : { plan: record.plan }) });
458
+ if (read.profile === 'mismatch')
459
+ refuse('The native Claude login belongs to another account.');
460
+ if (read.profile !== 'verified') {
461
+ refuse(`The native Claude login could not be proven live (profile ${read.profile}); let Claude Code `
462
+ + 'refresh its own store, then import again.');
463
+ }
464
+ }
465
+ /**
466
+ * A source the authority takes over.
467
+ *
468
+ * The handoff row is the durable record of how far this went. `source_stopped` is written before the
469
+ * refresh is sent, so a lost answer is always visible afterwards and is never retried.
470
+ */
471
+ async adopt(record, plan, identity, material) {
472
+ const handoffId = importHandoffId(record.id);
473
+ let handoff = await this.database.readHandoff(handoffId);
474
+ if (handoff === null) {
475
+ this.assertOwnable(await this.database.readGrant(identity.grantId), plan);
476
+ const ciphertext = await this.seal(identity.grantId, material);
477
+ await this.putGrant(identity, record, plan, identity.grantId, (existing, updateId) => this.baseGrant(identity, plan, identity.grantId, existing, updateId, { ciphertext }));
478
+ handoff = await this.moveHandoff(handoffId, record, identity, 'prepared', grant => ({ ...grant, state: 'legacy_native_pending' }));
479
+ }
480
+ if (handoff.phase === 'needs_reauth' || handoff.phase === 'aborted') {
481
+ await this.quarantine(record, identity);
482
+ refuse('A previous import of this source did not settle; sign in to that account again instead.');
483
+ }
484
+ if (handoff.phase === 'prepared') {
485
+ // The durable marker. Everything after it may have reached the provider.
486
+ handoff = await this.moveHandoff(handoffId, record, identity, 'source_stopped', grant => ({ ...grant, state: 'legacy_native_pending' }));
487
+ const rotated = await this.rotate(material);
488
+ if (rotated === null) {
489
+ await this.failHandoff(handoffId, record, identity);
490
+ await this.quarantine(record, identity);
491
+ refuse('The sign-in service did not give a usable answer, and a rotating refresh token is never '
492
+ + 'sent twice. Sign in to that account again to finish this import.');
493
+ }
494
+ const ciphertext = await this.seal(identity.grantId, rotated.material);
495
+ handoff = await this.moveHandoff(handoffId, record, identity, 'target_written', grant => ({
496
+ ...grant, ciphertext, accessExpiresAt: rotated.accessExpiresAt,
497
+ grantGeneration: grant.grantGeneration + 1, state: 'legacy_native_pending',
498
+ }));
499
+ }
500
+ if (handoff.phase === 'source_stopped') {
501
+ // Reached only by a restart: the exchange may have been sent, so the grant is never replayed.
502
+ await this.failHandoff(handoffId, record, identity);
503
+ await this.quarantine(record, identity);
504
+ refuse('This import was interrupted while its sign-in was in flight. A rotating refresh token is '
505
+ + 'never sent twice; sign in to that account again.');
506
+ }
507
+ if (handoff.phase === 'target_written') {
508
+ handoff = await this.moveHandoff(handoffId, record, identity, 'verified', grant => ({ ...grant, state: 'legacy_native_pending' }));
509
+ }
510
+ if (handoff.phase === 'verified') {
511
+ await this.moveHandoff(handoffId, record, identity, 'committed', grant => ({
512
+ ...grant, state: 'ready', owner: 'daemon', problem: 'none',
513
+ authorizationGeneration: grant.authorizationGeneration + 1,
514
+ }));
515
+ }
516
+ const ledger = await this.database.readMigrationLedger(record.id);
517
+ if (ledger?.status !== 'verified' && ledger?.status !== 'complete') {
518
+ await this.moveLedger(record.id, 'verified', identity.accountId, identity.grantId);
519
+ }
520
+ await this.storeEnrollments(record, identity);
521
+ if ((await this.database.readMigrationLedger(record.id))?.status !== 'complete') {
522
+ await this.moveLedger(record.id, 'complete', identity.accountId, identity.grantId);
523
+ }
524
+ return this.result(record, 'complete', identity, []);
525
+ }
526
+ async moveHandoff(handoffId, record, identity, phase, grantChange) {
527
+ const updateId = plugins.crypto.randomUUID();
528
+ const result = await this.database.changeHandoffAndGrant(updateId, handoffId, identity.grantId, (current, grant) => ({
529
+ handoff: {
530
+ id: handoffId, accountId: identity.accountId, grantId: identity.grantId,
531
+ nativeHomeId: record.sourcePathHash, direction: 'to_daemon', phase,
532
+ operationId: current?.operationId ?? plugins.crypto.randomUUID(),
533
+ sourceDigest: record.sourceDigest,
534
+ verifiedSourceDigest: ['verified', 'committed'].includes(phase) ? record.sourceDigest
535
+ : current?.verifiedSourceDigest ?? null,
536
+ revision: current ? current.revision + 1 : 1, statusObservedAt: this.stamp(), updateId,
537
+ },
538
+ grant: { ...grantChange(grant), revision: grant.revision + 1,
539
+ statusObservedAt: this.stamp(), updateId },
540
+ }));
541
+ return result.handoff;
542
+ }
543
+ async failHandoff(handoffId, record, identity) {
544
+ await this.moveHandoff(handoffId, record, identity, 'needs_reauth', grant => ({
545
+ ...grant, state: 'needs_reauth', owner: 'none', ciphertext: null, accessExpiresAt: null,
546
+ problem: 'exchange_uncertain',
547
+ }));
548
+ }
549
+ /**
550
+ * Marks a source whose sign-in exchange may already have been consumed. That is its only meaning, so the
551
+ * refusal a later submission gets needs no further reason: the repair is always a device sign-in.
552
+ */
553
+ async quarantine(record, identity) {
554
+ const ledger = await this.database.readMigrationLedger(record.id);
555
+ if (!ledger || ledger.status === 'complete' || ledger.status === 'quarantined')
556
+ return;
557
+ // A quarantined row keeps the account and grant it names, so the owner knows which account to sign in to.
558
+ await this.moveLedger(record.id, 'quarantined', identity.accountId, identity.grantId);
559
+ }
560
+ /**
561
+ * The one rotating refresh. `null` means the outcome is unknown and the grant must never be replayed.
562
+ *
563
+ * A thrown error is the same answer as a failed one: once the request left this process, whether the
564
+ * provider consumed the token is unknowable, so both end in a device sign-in rather than a retry.
565
+ */
566
+ async rotate(material) {
567
+ try {
568
+ return await this.rotateOnce(material);
569
+ }
570
+ catch {
571
+ return null;
572
+ }
573
+ }
574
+ async rotateOnce(material) {
575
+ if (material.providerId === 'openai') {
576
+ const result = await this.openAi.refreshCredential(material.credential);
577
+ if (!result.success)
578
+ return null;
579
+ let accessExpiresAt = null;
580
+ try {
581
+ accessExpiresAt = plugins.flexAuth.parseOpenAiChatGptTokenInfo(result.credential.accessToken).expiresAt ?? null;
582
+ }
583
+ catch {
584
+ accessExpiresAt = null;
585
+ }
586
+ return { material: { providerId: 'openai', credential: { kind: 'chatgptOAuth', providerId: 'openai',
587
+ accessToken: result.credential.accessToken, refreshToken: result.credential.refreshToken,
588
+ idToken: result.credential.idToken } }, accessExpiresAt };
589
+ }
590
+ const outcome = await this.claudeTokens.refreshForAuthority(material.login.claudeAiOauth);
591
+ if (!outcome.success)
592
+ return null;
593
+ return {
594
+ material: { providerId: 'anthropic', login: { ...material.login,
595
+ claudeAiOauth: { ...material.login.claudeAiOauth, accessToken: outcome.tokens.accessToken,
596
+ refreshToken: outcome.tokens.refreshToken, expiresAt: outcome.tokens.expiresAt,
597
+ scopes: outcome.tokens.scopes } } },
598
+ accessExpiresAt: new Date(outcome.tokens.expiresAt).toISOString(),
599
+ };
600
+ }
601
+ async seal(grantId, material) {
602
+ const payload = material.providerId === 'openai' ? material.credential : material.login;
603
+ const bytes = Buffer.from(JSON.stringify(payload), 'utf8');
604
+ try {
605
+ return await this.secrets.seal(grantId, bytes);
606
+ }
607
+ finally {
608
+ bytes.fill(0);
609
+ }
610
+ }
611
+ /** Codex remote-control enrollments travel with the credential; losing them is losing a pairing. */
612
+ async storeEnrollments(record, identity) {
613
+ if (record.sourceKind !== 'authswitch_stash' || !record.enrollmentCount)
614
+ return;
615
+ const rows = readLegacySourceEnrollments(record);
616
+ if (!rows.length)
617
+ return;
618
+ const enrollmentId = idHash('authswitch-enrollment-v1', identity.accountId);
619
+ const updateId = plugins.crypto.randomUUID();
620
+ const bytes = Buffer.from(JSON.stringify(rows), 'utf8');
621
+ let ciphertext;
622
+ try {
623
+ ciphertext = await this.secrets.seal(identity.accountId, bytes);
624
+ }
625
+ finally {
626
+ bytes.fill(0);
627
+ }
628
+ await this.database.changeEnrollment(updateId, enrollmentId, identity.accountId, current => ({
629
+ id: enrollmentId, accountId: identity.accountId, ciphertext,
630
+ revision: current ? current.revision + 1 : 1, updateId,
631
+ }));
632
+ }
633
+ result(record, status, identity, problems) {
634
+ return { sourceId: record.id, sourceKind: record.sourceKind, treatment: record.treatment, status,
635
+ accountId: identity.accountId, loginId: identity.grantId, problems };
636
+ }
637
+ }
638
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRob3JpdHlpbXBvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmF1dGhvcml0eWltcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsd0JBQXdCLEVBQStCLE1BQU0sK0JBQStCLENBQUM7QUFDdEcsT0FBTyxFQUFFLG1CQUFtQixFQUE2QyxNQUFNLDJCQUEyQixDQUFDO0FBQzNHLE9BQU8sRUFBRSxrQkFBa0IsRUFBc0MsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6RyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBdUIsTUFBTSwrQkFBK0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsMkJBQTJCLEVBQUUsd0JBQXdCLEVBQ3RGLGlCQUFpQixFQUFFLDRCQUE0QixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFRakc7Ozs7OztHQU1HO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBc0I7SUFDMUMsK0ZBQStGO0lBQy9GLDRHQUE0RztVQUMxRyx3R0FBd0c7SUFDMUcsc0dBQXNHO1VBQ3BHLGdGQUFnRjtJQUNsRix5R0FBeUc7VUFDdkcsc0dBQXNHO0lBQ3hHLHlHQUF5RztJQUN6RywwR0FBMEc7VUFDeEcsc0dBQXNHO1VBQ3RHLG9DQUFvQztDQUN2QyxDQUFDO0FBb0RGLDRGQUE0RjtBQUM1RixNQUFNLE9BQU8sOEJBQThCO0lBQ1o7SUFBeUM7SUFBdEUsWUFBNkIsY0FBc0IsRUFBbUIsU0FBaUI7UUFBMUQsbUJBQWMsR0FBZCxjQUFjLENBQVE7UUFBbUIsY0FBUyxHQUFULFNBQVMsQ0FBUTtJQUFHLENBQUM7SUFFcEYsY0FBYztRQUNuQix5RkFBeUY7UUFDekYsSUFBSSxHQUFXLENBQUM7UUFDaEIsSUFBSSxDQUFDO1lBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsWUFBWSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFBQyxDQUFDO1FBQ3BHLE1BQU0sQ0FBQztZQUFDLE9BQU8sSUFBSSxDQUFDO1FBQUMsQ0FBQztRQUN0QixJQUFJLEdBQVksQ0FBQztRQUNqQixJQUFJLENBQUM7WUFBQyxHQUFHLEdBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQTZCLENBQUMsR0FBRyxDQUFDO1FBQUMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUFDLE9BQU8sSUFBSSxDQUFDO1FBQUMsQ0FBQztRQUN0RixJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUNuRixJQUFJLENBQUM7WUFBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUFDLE9BQU8sR0FBRyxDQUFDO1FBQUMsQ0FBQztRQUN6QyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQUMsT0FBUSxLQUErQixDQUFDLElBQUksS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQUMsQ0FBQztJQUMxRixDQUFDO0lBRU0sa0JBQWtCLENBQUMsTUFBc0I7UUFDOUMsT0FBTyxJQUFJLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRU0scUJBQXFCO1FBQzFCLE1BQU0sTUFBTSxHQUFHLElBQUksV0FBVyxDQUFDLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3ZFLE9BQU8sTUFBTSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO0lBQ2pELENBQUM7Q0FDRjtBQVdELE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxNQUFnQixFQUFVLEVBQUUsQ0FDN0MsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFFbkYsTUFBTSxTQUFTLEdBQUcsQ0FBQyxNQUE4RCxFQUFvQixFQUFFO0lBQ3JHLElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxlQUFlLEVBQUUsQ0FBQztRQUMxQyxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsUUFBUSxFQUFFLGtCQUFrQjtZQUMzRixZQUFZLEVBQUUsZUFBZSxFQUFFLENBQUM7SUFDcEMsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxpQkFBaUIsRUFBRSxDQUFDO1FBQzVDLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsU0FBUztZQUM1RSxZQUFZLEVBQUUsZUFBZSxFQUFFLENBQUM7SUFDcEMsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxjQUFjLEVBQUUsQ0FBQztRQUN6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLFNBQVM7WUFDM0UsWUFBWSxFQUFFLGVBQWUsRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxVQUFVLEtBQUssV0FBVztRQUN0QyxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxRQUFRLEVBQUUsa0JBQWtCO1lBQ3RGLFlBQVksRUFBRSxRQUFRLEVBQUU7UUFDMUIsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFDdkcsQ0FBQyxDQUFDO0FBRUYsMEZBQTBGO0FBQzFGLE1BQU0sYUFBYSxHQUFHLENBQUMsU0FBaUIsRUFBRSxJQUFzQixFQUFVLEVBQUUsQ0FDMUUsTUFBTSxDQUFDLHFCQUFxQixFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN4RSxNQUFNLGVBQWUsR0FBRyxDQUFDLFFBQWdCLEVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQyw4QkFBOEIsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUV2Ryw2R0FBNkc7QUFDN0csTUFBTSxrQkFBa0IsR0FDdEIsQ0FBQyxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFFaEQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sWUFBWSxHQUFHLENBQUMsTUFBcUMsRUFDekQsT0FBdUMsRUFBMkIsRUFBRTtJQUNwRSxJQUFJLE1BQU0sS0FBSyxVQUFVO1FBQUUsT0FBTyxNQUFNLENBQUM7SUFDekMsSUFBSSxNQUFNLEtBQUssYUFBYTtRQUFFLE9BQU8sY0FBYyxDQUFDO0lBQ3BELE9BQU8sT0FBTyxLQUFLLElBQUksSUFBSSxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztBQUNwRyxDQUFDLENBQUM7QUFFRixvRkFBb0Y7QUFDcEYsTUFBTSxPQUFPLHVCQUF3QixTQUFRLEtBQUs7Q0FBRztBQUVyRCx5R0FBeUc7QUFDekcsTUFBTSxNQUFNLEdBQThCLE1BQU0sQ0FBQyxFQUFFLEdBQUcsTUFBTSxJQUFJLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRW5HLE1BQU0saUJBQWlCLEdBQUcsbUZBQW1GO01BQ3pHLHlHQUF5RztNQUN6RyxrR0FBa0c7TUFDbEcsb0JBQW9CLENBQUM7QUFFekIsb0dBQW9HO0FBQ3BHLE1BQU0sWUFBWSxHQUFHLENBQUMsTUFBMkIsRUFDL0MsWUFBcUQsRUFBMkIsRUFBRSxDQUFDLENBQUM7SUFDcEYsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO0lBQ2IsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO0lBQzdCLGNBQWMsRUFBRSxNQUFNLENBQUMsY0FBYztJQUNyQyxZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVk7SUFDakMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTO0lBQzNCLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztJQUNuQixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7SUFDM0IsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO0lBQzdCLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztJQUNuQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7SUFDakIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO0lBQ25CLGVBQWUsRUFBRSxNQUFNLENBQUMsZUFBZTtJQUN2QyxlQUFlLEVBQUUsTUFBTSxDQUFDLGVBQWU7SUFDdkMsWUFBWTtJQUNaLFFBQVEsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztDQUMvQixDQUFDLENBQUM7QUFFSDs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8seUJBQXlCO0lBVVA7SUFUWixHQUFHLENBQW9CO0lBQ3ZCLGFBQWEsQ0FBUztJQUN0QixHQUFHLENBQWU7SUFDbEIsTUFBTSxDQUFvQztJQUMxQyxZQUFZLENBQWdDO0lBQzVDLFlBQVksQ0FBZ0M7SUFDNUMsT0FBTyxDQUF5QjtJQUNoQyxVQUFVLENBQThCO0lBRXpELFlBQTZCLFFBQXFDLEVBQ2hFLFVBQTZDLEVBQUU7UUFEcEIsYUFBUSxHQUFSLFFBQVEsQ0FBNkI7UUFFaEUsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsYUFBYSxJQUFJLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkUsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDbkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ2pGLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksSUFBSSxJQUFJLG1CQUFtQixFQUFFLENBQUM7UUFDdEUsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxJQUFJLElBQUksa0JBQWtCLEVBQUUsQ0FBQztRQUNyRSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksSUFBSSx3QkFBd0IsRUFBRSxDQUFDO1FBQ2pFLE1BQU0sU0FBUyxHQUFHLDRCQUE0QixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzdFLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVU7ZUFDL0IsSUFBSSw4QkFBOEIsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6RixDQUFDO0lBRUQsMEZBQTBGO0lBQ25GLEtBQUssQ0FBQyxTQUFTO1FBQ3BCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDNUYsTUFBTSxPQUFPLEdBQThCLEVBQUUsQ0FBQztRQUM5QyxLQUFLLE1BQU0sTUFBTSxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2xFLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQztZQUM1RCxJQUFJLE1BQU0sS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLFlBQVksS0FBSyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ25FLHFHQUFxRztnQkFDckcsMEZBQTBGO2dCQUMxRixNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQywrREFBK0QsQ0FBQyxDQUFDO1lBQ3hGLENBQUM7WUFDRCxJQUFJLE1BQU0sRUFBRSxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLDZEQUE2RCxDQUFDLENBQUM7WUFDdEYsQ0FBQztZQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkIsQ0FBQztRQUNELE9BQU87WUFDTCxXQUFXLEVBQUUsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsV0FBVyxFQUFFO1lBQ3hDLGFBQWEsRUFBRSx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQ2hELE1BQU0sRUFBRSxDQUFDLEdBQUcsZ0JBQWdCLENBQUM7WUFDN0IsT0FBTztZQUNQLFFBQVEsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztTQUMvQixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBOEMsRUFBRTtRQUNsRSxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxJQUFJLEVBQUUsT0FBTyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsQ0FBQztRQUNsRyxNQUFNLE9BQU8sR0FBbUMsRUFBRSxDQUFDO1FBQ25ELEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzVCLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZGLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pFLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQ1gsUUFBUSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNO2dCQUNoRSxTQUFTLEVBQUUsR0FBRyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssSUFBSSxJQUFJO2dCQUMzRSxNQUFNLEVBQUUsWUFBWSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLGdCQUFnQjthQUNsRixDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDN0UsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUNTO1FBQzNCLElBQUksT0FBTyxDQUFDLG1CQUFtQixLQUFLLElBQUk7WUFBRSxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNwRSxJQUFJLE9BQU8sQ0FBQyxlQUFlLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDckMsTUFBTSxDQUFDLCtGQUErRjtrQkFDbEcsNEZBQTRGLENBQUMsQ0FBQztRQUNwRyxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEQsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNsRSxJQUFJLE1BQU0sS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNwQixJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNoRCxNQUFNLENBQUMsOEZBQThGLENBQUMsQ0FBQztZQUN6RyxDQUFDO1lBQ0QsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLFVBQVU7Z0JBQUUsTUFBTSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7WUFDN0UsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLGFBQWEsRUFBRSxDQUFDO2dCQUNwQyxNQUFNLENBQUMseUZBQXlGO3NCQUM1RixzREFBc0QsQ0FBQyxDQUFDO1lBQzlELENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUNuQyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQy9CLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUM7UUFDdkMsSUFBSSxTQUFTLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxJQUFJLElBQUksV0FBVyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ25FLE1BQU0sQ0FBQywrRUFBK0UsQ0FBQyxDQUFDO1FBQzFGLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9DLElBQUksTUFBTSxLQUFLLElBQUk7WUFBRSxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzNELE9BQU8sTUFBTSxDQUFDLFNBQVMsS0FBSyxTQUFTO1lBQ25DLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsRUFBRSxRQUFRLENBQUM7WUFDcEYsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFFRCxnRkFBZ0Y7SUFDeEUsYUFBYSxDQUFDLFVBQXVDO1FBQzNELElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNuQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN0RSxPQUFPO2dCQUNMLEVBQUUsRUFBRSxNQUFNLENBQUMseUJBQXlCLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxjQUFjLENBQUM7Z0JBQzVFLFVBQVUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsVUFBVSxDQUFDLGNBQWM7Z0JBQzNFLFlBQVksRUFBRSxVQUFVLENBQUMsWUFBWSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLGtCQUFrQjtnQkFDckYsU0FBUyxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxXQUFXO2dCQUMzRixVQUFVLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSztnQkFDdkYsZUFBZSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFFO2FBQzNELENBQUM7UUFDSixDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsaUJBQWlCLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN4RyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEtBQUssVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hGLElBQUksQ0FBQyxNQUFNO1lBQUUsTUFBTSxDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDbEUsSUFBSSxNQUFNLENBQUMsWUFBWSxLQUFLLFVBQVUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwRCxNQUFNLENBQUMsMkZBQTJGLENBQUMsQ0FBQztRQUN0RyxDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU07WUFBRSxNQUFNLENBQUMsa0NBQWtDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwRyxJQUFJLE1BQU0sQ0FBQyxTQUFTLEtBQUssUUFBUTtZQUFFLE1BQU0sQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ2hHLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxPQUFlO1FBRXRDLElBQUksSUFBcUUsQ0FBQztRQUMxRSxJQUFJLENBQUM7WUFBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUFDLENBQUM7UUFDckUsTUFBTSxDQUFDO1lBQUMsT0FBTyxNQUFNLENBQUMsMkRBQTJELENBQUMsQ0FBQztRQUFDLENBQUM7UUFDckYsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNsRCxNQUFNLENBQUMsc0VBQXNFLENBQUMsQ0FBQztRQUNqRixDQUFDO1FBQ0QsT0FBTztZQUNMLFNBQVMsRUFBRSxNQUFNLENBQUMsdUJBQXVCLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1lBQy9GLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO1lBQy9ELEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJO1NBQzdFLENBQUM7SUFDSixDQUFDO0lBRUQsNkZBQTZGO0lBQ3JGLFFBQVEsQ0FBQyxNQUEyQixFQUMxQyxVQUF1QztRQUN2QyxJQUFJLFVBQVUsQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDbkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsUUFBUTtvQkFDckYsV0FBVyxFQUFFLFVBQVUsQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLFlBQVksRUFBRSxVQUFVLENBQUMsVUFBVSxDQUFDLFlBQVk7b0JBQ2hHLE9BQU8sRUFBRSxVQUFVLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7UUFDL0MsQ0FBQztRQUNELElBQUksQ0FBQztZQUFDLE9BQU8sd0JBQXdCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFBQyxDQUFDO1FBQ2hELE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDYixJQUFJLEtBQUssWUFBWSx3QkFBd0I7Z0JBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyRSxNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGVBQWUsQ0FBQyxNQUEyQjtRQUNqRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQy9DLElBQUksS0FBSyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ25CLE1BQU0sQ0FBQyx1Q0FBdUMsS0FBSyxrREFBa0QsQ0FBQyxDQUFDO1FBQ3pHLENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBMEIsTUFBTSxDQUFDLFVBQVUsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLFFBQVE7WUFDaEYsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEtBQUssaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ2hFLElBQUksTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEQsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ2hCLE1BQU0sQ0FBQyxHQUFHLE1BQU0sb0JBQW9CLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1EQUFtRCxDQUFDLENBQUM7WUFDMUcsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssY0FBYztlQUNuQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEtBQUssa0JBQWtCLElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQ2xGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUN4RCxJQUFJLE9BQU8sS0FBSyxLQUFLLEVBQUUsQ0FBQztnQkFDdEIsTUFBTSxDQUFDLE9BQU8sS0FBSyxJQUFJO29CQUNyQixDQUFDLENBQUMsK0ZBQStGOzBCQUM3RixxREFBcUQ7b0JBQ3pELENBQUMsQ0FBQyxnRkFBZ0Y7MEJBQzlFLCtEQUErRCxDQUFDLENBQUM7WUFDekUsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUEyQjtRQUNuRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzdDLGdHQUFnRztRQUNoRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNwRSxFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFLGNBQWMsRUFBRSxNQUFNLENBQUMsY0FBYztZQUMvRixZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUk7WUFDckYsUUFBUSxFQUFFLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsUUFBUTtTQUN0RCxDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFFTyxLQUFLLENBQUMsVUFBVSxDQUFDLFFBQWdCLEVBQUUsTUFBaUQsRUFDMUYsU0FBd0IsRUFBRSxPQUFzQjtRQUNoRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzdDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxFQUFFO1lBQ3ZFLElBQUksQ0FBQyxPQUFPO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQztZQUN6RixPQUFPLEVBQUUsR0FBRyxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQztnQkFDN0UsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLEtBQUssS0FBYSxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUU5RCxPQUFPLENBQUMsTUFBMkIsRUFBRSxRQUN0QixFQUFFLElBQXNCLEVBQUUsUUFBd0MsRUFDekYsT0FBZSxFQUFFLFFBQWdCO1FBQy9CLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzNGLE9BQU8sUUFBUTtZQUNiLENBQUMsQ0FBQyxFQUFFLEdBQUcsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxJQUFJLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7Z0JBQ3JGLE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUU7WUFDN0YsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVO2dCQUM5RSxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsUUFBUSxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO2dCQUN4RixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUM7Z0JBQ3ZFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsQ0FBQztJQUNqRCxDQUFDO0lBRUQsdUdBQXVHO0lBQy9GLEtBQUssQ0FBQyxRQUFRLENBQUMsUUFBcUUsRUFDMUYsTUFBMkIsRUFBRSxJQUFzQixFQUFFLE9BQWUsRUFDcEUsSUFBeUY7UUFDekYsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDNUUsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM3QyxJQUFJLGVBQWUsSUFBSSxlQUFlLENBQUMsY0FBYyxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ2xFLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQzVFLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDcEcsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUM7WUFDekUsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDO1NBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ04sQ0FBQztJQUVPLFNBQVMsQ0FBQyxRQUErQixFQUFFLElBQXNCLEVBQUUsT0FBZSxFQUN4RixRQUFzQyxFQUFFLFFBQWdCLEVBQ3hELFNBQXlDO1FBQ3pDLE9BQU87WUFDTCxFQUFFLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUM5RixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsS0FBSyxFQUFFLGVBQWU7WUFDL0UsZUFBZSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4RCx1QkFBdUIsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4RSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLElBQUk7WUFDdkYsU0FBUyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLGNBQWM7WUFDdEUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLFFBQVEsRUFBRSxHQUFHLFNBQVM7U0FDdkQsQ0FBQztJQUNKLENBQUM7SUFFRCxxRkFBcUY7SUFDN0UsYUFBYSxDQUFDLFFBQXNDLEVBQUUsSUFBc0I7UUFDbEYsSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBQ3RCLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsWUFBWSxJQUFJLFFBQVEsQ0FBQyxLQUFLLEtBQUssTUFBTTtZQUFFLE9BQU87UUFDOUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEtBQUssUUFBUTtZQUNoQyxDQUFDLENBQUMsOEZBQThGO1lBQ2hHLENBQUMsQ0FBQyxnR0FBZ0c7a0JBQzlGLDRDQUE0QyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVEOzs7T0FHRztJQUNLLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBMkIsRUFBRSxJQUFzQixFQUN2RSxRQUFzRixFQUN0RixRQUErQjtRQUMvQixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFFLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQ25GLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQ2pFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUM7WUFBQyxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQUMsQ0FBQztRQUNwRSxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2Isc0dBQXNHO1lBQ3RHLG1HQUFtRztZQUNuRyxtR0FBbUc7WUFDbkcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsc0JBQXNCLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDL0YsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25GLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuRixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVELHdHQUF3RztJQUNoRyxLQUFLLENBQUMsb0JBQW9CLENBQUMsTUFBMkIsRUFDNUQsUUFBcUUsRUFDckUsUUFBK0I7UUFDL0IsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLElBQUksRUFBRSxlQUFlO2dCQUMzRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUMsVUFBVSxDQUFDLFdBQVc7Z0JBQ2xFLFNBQVMsRUFBRSxRQUFRLENBQUMsV0FBVyxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDOUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxDQUFDLHFEQUFxRCxNQUFNLENBQUMsU0FBUyx5QkFBeUI7c0JBQ2pHLDJDQUEyQyxDQUFDLENBQUM7WUFDbkQsQ0FBQztZQUNELDJFQUEyRTtZQUMzRSxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLDJCQUEyQixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDN0YsSUFBSSxNQUFNLENBQUMsZ0JBQWdCLEtBQUssUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyRCxNQUFNLENBQUMsNkRBQTZELENBQUMsQ0FBQztZQUN4RSxDQUFDO1lBQ0QsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQztRQUMzQyxNQUFNLFdBQVcsR0FBRyxPQUFPLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDbkYsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQ3hDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBbUIsRUFBRSxDQUFDLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDcEYsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxFQUFFLFdBQVcsRUFBRSxNQUFNO1lBQ3JFLFFBQVEsRUFBRSxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxXQUFXLEVBQUU7WUFDbkYsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM1RCxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssVUFBVTtZQUFFLE1BQU0sQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO1FBQy9GLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNoQyxNQUFNLENBQUMsNkRBQTZELElBQUksQ0FBQyxPQUFPLHFCQUFxQjtrQkFDakcsMkNBQTJDLENBQUMsQ0FBQztRQUNuRCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUEyQixFQUFFLElBQXNCLEVBQ3JFLFFBQXNGLEVBQ3RGLFFBQStCO1FBQy9CLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0MsSUFBSSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN6RCxJQUFJLE9BQU8sS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzFFLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQy9ELE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQ25GLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDeEYsT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQ3RFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsS0FBSyxLQUFLLGNBQWMsSUFBSSxPQUFPLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3BFLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDeEMsTUFBTSxDQUFDLHlGQUF5RixDQUFDLENBQUM7UUFDcEcsQ0FBQztRQUNELElBQUksT0FBTyxDQUFDLEtBQUssS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNqQyx5RUFBeUU7WUFDekUsT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFDNUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsS0FBSyxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM1QyxJQUFJLE9BQU8sS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDckIsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3BELE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3hDLE1BQU0sQ0FBQywwRkFBMEY7c0JBQzdGLGtFQUFrRSxDQUFDLENBQUM7WUFDMUUsQ0FBQztZQUNELE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2RSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDeEYsR0FBRyxLQUFLLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBRSxPQUFPLENBQUMsZUFBZTtnQkFDOUQsZUFBZSxFQUFFLEtBQUssQ0FBQyxlQUFlLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSx1QkFBdUI7YUFDM0UsQ0FBQyxDQUFDLENBQUM7UUFDTixDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsS0FBSyxLQUFLLGdCQUFnQixFQUFFLENBQUM7WUFDdkMsOEZBQThGO1lBQzlGLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3BELE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDeEMsTUFBTSxDQUFDLDJGQUEyRjtrQkFDOUYsa0RBQWtELENBQUMsQ0FBQztRQUMxRCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsS0FBSyxLQUFLLGdCQUFnQixFQUFFLENBQUM7WUFDdkMsT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQ3RFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsS0FBSyxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN6RSxHQUFHLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU07Z0JBQzFELHVCQUF1QixFQUFFLEtBQUssQ0FBQyx1QkFBdUIsR0FBRyxDQUFDO2FBQzNELENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbEUsSUFBSSxNQUFNLEVBQUUsTUFBTSxLQUFLLFVBQVUsSUFBSSxNQUFNLEVBQUUsTUFBTSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQ25FLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyRixDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQ2hGLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyRixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFTyxLQUFLLENBQUMsV0FBVyxDQUFDLFNBQWlCLEVBQUUsTUFBMkIsRUFDdEUsUUFBZ0QsRUFBRSxLQUF1QyxFQUN6RixXQUFvRTtRQUNwRSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzdDLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQzVGLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNuQixPQUFPLEVBQUU7Z0JBQ1AsRUFBRSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87Z0JBQ3ZFLFlBQVksRUFBRSxNQUFNLENBQUMsY0FBYyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsS0FBSztnQkFDbEUsV0FBVyxFQUFFLE9BQU8sRUFBRSxXQUFXLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUU7Z0JBQ2hFLFlBQVksRUFBRSxNQUFNLENBQUMsWUFBWTtnQkFDakMsb0JBQW9CLEVBQUUsQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWTtvQkFDbkYsQ0FBQyxDQUFDLE9BQU8sRUFBRSxvQkFBb0IsSUFBSSxJQUFJO2dCQUN6QyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxRQUFRO2FBQ3ZGO1lBQ0QsS0FBSyxFQUFFLEVBQUUsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQztnQkFDMUQsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLFFBQVEsRUFBRTtTQUM3QyxDQUFDLENBQUMsQ0FBQztRQUNOLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUN4QixDQUFDO0lBRU8sS0FBSyxDQUFDLFdBQVcsQ0FBQyxTQUFpQixFQUFFLE1BQTJCLEVBQ3RFLFFBQWdEO1FBQ2hELE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzVFLEdBQUcsS0FBSyxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxJQUFJO1lBQ3ZGLE9BQU8sRUFBRSxvQkFBb0I7U0FDOUIsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUEyQixFQUNsRCxRQUFnRDtRQUNoRCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxVQUFVLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxhQUFhO1lBQUUsT0FBTztRQUN2RiwwR0FBMEc7UUFDMUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBK0I7UUFFbEQsSUFBSSxDQUFDO1lBQUMsT0FBTyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7UUFBQyxDQUFDO1FBQy9DLE1BQU0sQ0FBQztZQUFDLE9BQU8sSUFBSSxDQUFDO1FBQUMsQ0FBQztJQUN4QixDQUFDO0lBRU8sS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUErQjtRQUV0RCxJQUFJLFFBQVEsQ0FBQyxVQUFVLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDckMsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN4RSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFDakMsSUFBSSxlQUFlLEdBQWtCLElBQUksQ0FBQztZQUMxQyxJQUFJLENBQUM7Z0JBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsMkJBQTJCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDO1lBQUMsQ0FBQztZQUN4SCxNQUFNLENBQUM7Z0JBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztZQUFDLENBQUM7WUFDakMsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsUUFBUTt3QkFDakcsV0FBVyxFQUFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVk7d0JBQ3hGLE9BQU8sRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLENBQUM7UUFDOUQsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzFGLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ2xDLE9BQU87WUFDTCxRQUFRLEVBQUUsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxFQUFFLEdBQUcsUUFBUSxDQUFDLEtBQUs7b0JBQzdELGFBQWEsRUFBRSxFQUFFLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVzt3QkFDdkYsWUFBWSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVM7d0JBQzlFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUU7WUFDdkMsZUFBZSxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsV0FBVyxFQUFFO1NBQ2xFLENBQUM7SUFDSixDQUFDO0lBRU8sS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFlLEVBQUUsUUFBK0I7UUFDakUsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDeEYsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQztZQUFDLE9BQU8sTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFBQyxDQUFDO2dCQUMvQyxDQUFDO1lBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELG9HQUFvRztJQUM1RixLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBMkIsRUFDeEQsUUFBK0I7UUFDL0IsSUFBSSxNQUFNLENBQUMsVUFBVSxLQUFLLGtCQUFrQixJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWU7WUFBRSxPQUFPO1FBQ2hGLE1BQU0sSUFBSSxHQUFHLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFDekIsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLDBCQUEwQixFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM1RSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzdDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN4RCxJQUFJLFVBQWtCLENBQUM7UUFDdkIsSUFBSSxDQUFDO1lBQUMsVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUFDLENBQUM7Z0JBQ2hFLENBQUM7WUFBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQUMsQ0FBQztRQUMxQixNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMzRixFQUFFLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLFVBQVU7WUFDM0QsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRO1NBQ3ZELENBQUMsQ0FBQyxDQUFDO0lBQ04sQ0FBQztJQUVPLE1BQU0sQ0FBQyxNQUEyQixFQUFFLE1BQXlDLEVBQ25GLFFBQWdELEVBQUUsUUFBa0I7UUFDcEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLE1BQU07WUFDOUYsU0FBUyxFQUFFLFFBQVEsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFDekUsQ0FBQztDQUNGIn0=