@modelprofile.com/authswitch 7.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/authority-contract.d.ts +1 -3
- package/dist_ts/authority-contract.js +1 -1
- package/dist_ts/classes.authoritybroker.js +1 -5
- package/dist_ts/classes.authoritycli.js +2 -2
- package/dist_ts/classes.authoritydaemon.js +4 -9
- package/dist_ts/classes.authoritydatabase.d.ts +5 -26
- package/dist_ts/classes.authoritydatabase.js +49 -129
- package/dist_ts/classes.authoritymodels.d.ts +27 -43
- package/dist_ts/classes.authoritymodels.js +193 -243
- package/dist_ts/classes.authoritypreuse.js +1 -2
- package/dist_ts/classes.authorityregistry.d.ts +2 -17
- package/dist_ts/classes.authorityregistry.js +18 -74
- package/dist_ts/classes.authoritysecrets.d.ts +1 -1
- package/dist_ts/classes.authoritysecrets.js +2 -2
- package/dist_ts/classes.authorityusage.d.ts +3 -3
- package/dist_ts/classes.claudeauthority.js +3 -7
- package/dist_ts/classes.claudenative.d.ts +1 -8
- package/dist_ts/classes.claudenative.js +2 -25
- package/dist_ts/classes.codexmanaged.d.ts +1 -1
- package/dist_ts/plugins.d.ts +7 -7
- package/dist_ts/plugins.js +8 -8
- package/dist_ts/ts_migration/0001_authority_meta.d.ts +13 -3
- package/dist_ts/ts_migration/0001_authority_meta.js +29 -17
- package/dist_ts/ts_migration/0002_remove_backup_records.d.ts +17 -0
- package/dist_ts/ts_migration/0002_remove_backup_records.js +48 -0
- package/dist_ts/ts_migration/index.d.ts +6 -3
- package/dist_ts/ts_migration/index.js +10 -4
- package/package.json +2 -5
- package/readme.md +22 -26
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/authority-contract.ts +1 -3
- package/ts/classes.authoritybroker.ts +0 -4
- package/ts/classes.authoritycli.ts +1 -1
- package/ts/classes.authoritydaemon.ts +3 -8
- package/ts/classes.authoritydatabase.ts +50 -141
- package/ts/classes.authoritymodels.ts +232 -269
- package/ts/classes.authoritypreuse.ts +0 -1
- package/ts/classes.authorityregistry.ts +20 -91
- package/ts/classes.authoritysecrets.ts +1 -1
- package/ts/classes.authorityusage.ts +3 -3
- package/ts/classes.claudeauthority.ts +2 -6
- package/ts/classes.claudenative.ts +1 -32
- package/ts/classes.codexmanaged.ts +1 -1
- package/ts/plugins.ts +7 -7
- package/ts/ts_migration/0001_authority_meta.ts +29 -17
- package/ts/ts_migration/0002_remove_backup_records.ts +49 -0
- package/ts/ts_migration/index.ts +10 -5
- package/dist_ts/authorityrehearsal.child.d.ts +0 -1
- package/dist_ts/authorityrehearsal.child.js +0 -395
- package/dist_ts/classes.authoritybackup.d.ts +0 -134
- package/dist_ts/classes.authoritybackup.js +0 -769
- package/dist_ts/classes.authorityrehearsal.d.ts +0 -127
- package/dist_ts/classes.authorityrehearsal.js +0 -632
- package/ts/authorityrehearsal.child.ts +0 -330
- package/ts/classes.authoritybackup.ts +0 -780
- package/ts/classes.authorityrehearsal.ts +0 -625
|
@@ -1,769 +0,0 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
|
-
import { assertStoredAuthorityBinding, assertStoredAuthorityClaudeHandoff, assertStoredAuthorityClaudeHome, assertStoredAuthorityCodexHome, assertStoredAuthorityEnrollment, assertStoredAuthorityGrant, assertStoredAuthorityHandoff, assertStoredAuthorityMeta, assertStoredAuthorityMigrationLedger, assertStoredAuthorityOperation, restoreStoredAuthorityOperation, } from './classes.authoritymodels.js';
|
|
3
|
-
import { assertAuthorityStoredRecord } from './classes.authorityregistry.js';
|
|
4
|
-
const maxPlainChunkBytes = 8 * 1024 * 1024;
|
|
5
|
-
const maxEncryptedObjectBytes = 12 * 1024 * 1024;
|
|
6
|
-
// The manifest is still one object. A paged authenticated index is required for unlimited inventory.
|
|
7
|
-
const maxRecordBytes = 1024 * 1024;
|
|
8
|
-
const maxSourceBytes = 4 * 1024 * 1024;
|
|
9
|
-
const hash = (bytes) => plugins.crypto.createHash('sha256').update(bytes).digest('hex');
|
|
10
|
-
const uuid = () => plugins.crypto.randomUUID();
|
|
11
|
-
const isHash = (value) => typeof value === 'string' && /^[a-f0-9]{64}$/.test(value);
|
|
12
|
-
const isName = (value) => typeof value === 'string' && /^[a-zA-Z0-9_.:-]{1,256}$/.test(value);
|
|
13
|
-
const isDigestField = (value) => value === 'sourceDigest' || value === 'before.credentialDigest' || value === 'before.configDigest';
|
|
14
|
-
function fail(message) { throw new Error(message); }
|
|
15
|
-
const recordKey = (model, id) => `${model}\u0000${id}`;
|
|
16
|
-
const context = (...parts) => Buffer.from(JSON.stringify(['authswitch-backup-v1', ...parts]));
|
|
17
|
-
const object = (value) => value !== null
|
|
18
|
-
&& typeof value === 'object' && !Array.isArray(value)
|
|
19
|
-
&& [Object.prototype, null].includes(Object.getPrototypeOf(value));
|
|
20
|
-
const exactKeys = (value, keys) => Object.keys(value).length === keys.length && keys.every(key => Object.hasOwn(value, key));
|
|
21
|
-
const assertSnapshotRecord = assertAuthorityStoredRecord;
|
|
22
|
-
/** This ID preserves Codex's complete three-column enrollment key, without email matching. */
|
|
23
|
-
export const authorityEnrollmentId = (row) => hash(JSON.stringify(['authswitch-enrollment-v1', row.websocketUrl, row.accountId, row.appServerClientName]));
|
|
24
|
-
const parseEnrollment = (bytes, id) => {
|
|
25
|
-
const value = JSON.parse(Buffer.from(bytes).toString('utf8'));
|
|
26
|
-
if (!object(value) || !exactKeys(value, ['websocketUrl', 'accountId', 'appServerClientName',
|
|
27
|
-
'serverId', 'environmentId', 'serverName', 'updatedAt', 'remoteControlEnabled'])
|
|
28
|
-
|| !['websocketUrl', 'accountId', 'appServerClientName', 'serverId', 'environmentId', 'serverName']
|
|
29
|
-
.every(key => typeof value[key] === 'string')
|
|
30
|
-
|| !Number.isSafeInteger(value.updatedAt) || Number(value.updatedAt) < 0
|
|
31
|
-
|| ![null, 0, 1].includes(value.remoteControlEnabled)) {
|
|
32
|
-
throw new Error('Backup enrollment has an invalid or incomplete Codex row.');
|
|
33
|
-
}
|
|
34
|
-
const row = value;
|
|
35
|
-
if (!row.websocketUrl || !row.accountId
|
|
36
|
-
|| authorityEnrollmentId(row) !== id)
|
|
37
|
-
throw new Error('Backup enrollment composite identity changed.');
|
|
38
|
-
return row;
|
|
39
|
-
};
|
|
40
|
-
const assertJson = (value, depth = 0) => {
|
|
41
|
-
if (depth > 24)
|
|
42
|
-
fail('Backup record exceeds the JSON depth limit.');
|
|
43
|
-
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
44
|
-
return;
|
|
45
|
-
if (typeof value === 'number' && Number.isFinite(value))
|
|
46
|
-
return;
|
|
47
|
-
if (Array.isArray(value)) {
|
|
48
|
-
for (const item of value)
|
|
49
|
-
assertJson(item, depth + 1);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
if (object(value)) {
|
|
53
|
-
for (const item of Object.values(value))
|
|
54
|
-
assertJson(item, depth + 1);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
fail('Backup record contains a non-JSON value.');
|
|
58
|
-
};
|
|
59
|
-
/** SmartData readback may reorder object fields; arrays and native source bytes remain exact. */
|
|
60
|
-
const canonicalJson = (value) => {
|
|
61
|
-
if (Array.isArray(value))
|
|
62
|
-
return `[${value.map(canonicalJson).join(',')}]`;
|
|
63
|
-
if (object(value))
|
|
64
|
-
return `{${Object.keys(value).sort().map(key => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(',')}}`;
|
|
65
|
-
assertJson(value);
|
|
66
|
-
return JSON.stringify(value);
|
|
67
|
-
};
|
|
68
|
-
/** Thin adapter over SmartBucket's provider-probed, create-only exact upload API. */
|
|
69
|
-
export class AuthoritySmartBucketStore {
|
|
70
|
-
bucket;
|
|
71
|
-
capability;
|
|
72
|
-
constructor(bucket) {
|
|
73
|
-
this.bucket = bucket;
|
|
74
|
-
}
|
|
75
|
-
async prepare(signal) {
|
|
76
|
-
const result = await this.bucket.probeExactUploadCapability({ signal });
|
|
77
|
-
if (!result.supported)
|
|
78
|
-
throw new Error(`Exact backup uploads unavailable: ${result.reason}`);
|
|
79
|
-
this.capability = result.capability;
|
|
80
|
-
}
|
|
81
|
-
async putExact(path, bytes, signal) {
|
|
82
|
-
if (!this.capability)
|
|
83
|
-
throw new Error('Exact upload capability has not been probed.');
|
|
84
|
-
const source = plugins.stream.Readable.from((function* () {
|
|
85
|
-
for (let offset = 0; offset < bytes.byteLength; offset += 1024 * 1024) {
|
|
86
|
-
yield Buffer.from(bytes.subarray(offset, offset + 1024 * 1024));
|
|
87
|
-
}
|
|
88
|
-
})());
|
|
89
|
-
try {
|
|
90
|
-
await this.bucket.fastPutStreamExact({ capability: this.capability, path, readableStream: source,
|
|
91
|
-
contentLength: bytes.byteLength, nativeObjectProperties: { contentType: 'application/json' }, signal });
|
|
92
|
-
}
|
|
93
|
-
finally {
|
|
94
|
-
source.destroy();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
async get(path, maxBytes, signal) {
|
|
98
|
-
const source = await this.bucket.fastGetStream({ path, signal });
|
|
99
|
-
const chunks = [];
|
|
100
|
-
let length = 0;
|
|
101
|
-
try {
|
|
102
|
-
for await (const chunk of source) {
|
|
103
|
-
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
104
|
-
length += bytes.byteLength;
|
|
105
|
-
if (length > maxBytes)
|
|
106
|
-
throw new Error('Backup object exceeds its bounded read limit.');
|
|
107
|
-
chunks.push(bytes);
|
|
108
|
-
}
|
|
109
|
-
return Buffer.concat(chunks, length);
|
|
110
|
-
}
|
|
111
|
-
finally {
|
|
112
|
-
source.destroy();
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
function assertManifest(value, backupId, prefix) {
|
|
117
|
-
if (!object(value) || !exactKeys(value, ['schemaVersion', 'backupId', 'epoch', 'revision',
|
|
118
|
-
'recipientKeyId', 'chunks', 'recordCount', 'sources', 'snapshotDigest'])
|
|
119
|
-
|| value.schemaVersion !== 1 || value.backupId !== backupId
|
|
120
|
-
|| typeof value.epoch !== 'string' || !/^[a-f0-9-]{36}$/.test(value.epoch)
|
|
121
|
-
|| !Number.isSafeInteger(value.revision) || Number(value.revision) < 0
|
|
122
|
-
|| !isName(value.recipientKeyId) || !Number.isSafeInteger(value.recordCount)
|
|
123
|
-
|| Number(value.recordCount) < 1 || !isHash(value.snapshotDigest)
|
|
124
|
-
|| !Array.isArray(value.chunks) || !Array.isArray(value.sources)) {
|
|
125
|
-
fail('Invalid authenticated backup manifest.');
|
|
126
|
-
}
|
|
127
|
-
for (let index = 0; index < value.chunks.length; index++) {
|
|
128
|
-
const item = value.chunks[index];
|
|
129
|
-
if (!object(item) || !exactKeys(item, ['sequence', 'path', 'encryptedDigest',
|
|
130
|
-
'plaintextDigest', 'length', 'entries']) || item.sequence !== index
|
|
131
|
-
|| item.path !== `${prefix}/${backupId}/chunk-${String(index).padStart(5, '0')}.json`
|
|
132
|
-
|| !isHash(item.encryptedDigest) || !isHash(item.plaintextDigest)
|
|
133
|
-
|| !Number.isSafeInteger(item.length) || Number(item.length) < 1
|
|
134
|
-
|| Number(item.length) > maxEncryptedObjectBytes
|
|
135
|
-
|| !Number.isSafeInteger(item.entries) || Number(item.entries) < 1) {
|
|
136
|
-
fail('Invalid authenticated backup chunk index.');
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
const sourceIds = new Set();
|
|
140
|
-
for (const item of value.sources) {
|
|
141
|
-
if (!object(item) || !exactKeys(item, ['kind', 'id', 'linkedModel', 'linkedId', 'linkedDigestField', 'digest'])
|
|
142
|
-
|| !isName(item.kind) || !isName(item.id) || !isName(item.linkedModel)
|
|
143
|
-
|| !isName(item.linkedId) || !isDigestField(item.linkedDigestField) || !isHash(item.digest)) {
|
|
144
|
-
fail('Invalid authenticated backup source index.');
|
|
145
|
-
}
|
|
146
|
-
const sourceKey = recordKey(item.kind, item.id);
|
|
147
|
-
if (sourceIds.has(sourceKey))
|
|
148
|
-
fail('Duplicate authenticated backup source proof.');
|
|
149
|
-
sourceIds.add(sourceKey);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
export class AuthorityBackupPublicationUnknownError extends Error {
|
|
153
|
-
path;
|
|
154
|
-
constructor(path, cause) {
|
|
155
|
-
super('Backup exact upload outcome could not be reconciled by readback.', { cause });
|
|
156
|
-
this.path = path;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
/** Portable backup codec; the daemon's SmartData repository supplies the snapshot and persists the verified receipt. */
|
|
160
|
-
export class AuthSwitchAuthorityBackup {
|
|
161
|
-
options;
|
|
162
|
-
constructor(options) {
|
|
163
|
-
this.options = options;
|
|
164
|
-
}
|
|
165
|
-
publisher() {
|
|
166
|
-
if (!('source' in this.options))
|
|
167
|
-
fail('Backup publisher requires a committed snapshot source.');
|
|
168
|
-
return this.options;
|
|
169
|
-
}
|
|
170
|
-
verifier() {
|
|
171
|
-
if (!('rehearsal' in this.options))
|
|
172
|
-
fail('Backup verifier requires an isolated restore target.');
|
|
173
|
-
return this.options;
|
|
174
|
-
}
|
|
175
|
-
async secretFor(record) {
|
|
176
|
-
const value = record.value;
|
|
177
|
-
let id = null;
|
|
178
|
-
let sealed = null;
|
|
179
|
-
if (record.model === 'authswitch_authority_grants') {
|
|
180
|
-
assertStoredAuthorityGrant(value);
|
|
181
|
-
id = value.id;
|
|
182
|
-
sealed = value.ciphertext;
|
|
183
|
-
}
|
|
184
|
-
else if (record.model === 'authswitch_authority_enrollments') {
|
|
185
|
-
assertStoredAuthorityEnrollment(value);
|
|
186
|
-
id = value.id;
|
|
187
|
-
sealed = value.ciphertext;
|
|
188
|
-
}
|
|
189
|
-
else if (record.model === 'authswitch_authority_claude_handoffs' && object(value)
|
|
190
|
-
&& typeof value.outgoingGrantId === 'string' && typeof value.sealedOutgoing === 'string') {
|
|
191
|
-
id = value.outgoingGrantId;
|
|
192
|
-
sealed = value.sealedOutgoing;
|
|
193
|
-
}
|
|
194
|
-
if (!id || !sealed)
|
|
195
|
-
return null;
|
|
196
|
-
const bytes = await this.options.secrets.unseal(id, sealed);
|
|
197
|
-
try {
|
|
198
|
-
if (record.model === 'authswitch_authority_enrollments')
|
|
199
|
-
parseEnrollment(bytes, record.id);
|
|
200
|
-
return Buffer.from(bytes).toString('base64url');
|
|
201
|
-
}
|
|
202
|
-
finally {
|
|
203
|
-
bytes.fill(0);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
sourceDigestInRecord(record, field) {
|
|
207
|
-
if (!object(record.value))
|
|
208
|
-
return null;
|
|
209
|
-
if (field === 'sourceDigest')
|
|
210
|
-
return isHash(record.value.sourceDigest) ? record.value.sourceDigest : null;
|
|
211
|
-
if (object(record.value.before)) {
|
|
212
|
-
const digest = field === 'before.credentialDigest'
|
|
213
|
-
? record.value.before.credentialDigest : record.value.before.configDigest;
|
|
214
|
-
return isHash(digest) ? digest : null;
|
|
215
|
-
}
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
assertPreparedClaudeSourceCoverage(record, sources) {
|
|
219
|
-
if (record.model !== 'authswitch_authority_claude_handoffs')
|
|
220
|
-
return;
|
|
221
|
-
assertStoredAuthorityClaudeHandoff(record.value);
|
|
222
|
-
if (record.value.phase !== 'prepared')
|
|
223
|
-
return;
|
|
224
|
-
for (const field of ['before.credentialDigest', 'before.configDigest']) {
|
|
225
|
-
const digest = this.sourceDigestInRecord(record, field);
|
|
226
|
-
if (digest !== null && !sources.some(source => source.linkedDigestField === field && source.digest === digest)) {
|
|
227
|
-
fail('Prepared Claude native source bytes are missing from the backup.');
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
async stage(backupId, attempt) {
|
|
232
|
-
const publisher = this.publisher();
|
|
233
|
-
if (typeof attempt.epoch !== 'string' || !/^[a-f0-9-]{36}$/.test(attempt.epoch)
|
|
234
|
-
|| !Number.isSafeInteger(attempt.revision) || attempt.revision < 0)
|
|
235
|
-
fail('Invalid backup snapshot identity.');
|
|
236
|
-
const dir = await plugins.fs.promises.mkdtemp(plugins.path.join(plugins.os.tmpdir(), 'authswitch-backup-'));
|
|
237
|
-
await plugins.fs.promises.chmod(dir, 0o700);
|
|
238
|
-
const sources = [];
|
|
239
|
-
const sourceIds = new Set();
|
|
240
|
-
const sourceLinks = new Map();
|
|
241
|
-
const lines = [];
|
|
242
|
-
const chunks = [];
|
|
243
|
-
const snapshotHash = plugins.crypto.createHash('sha256');
|
|
244
|
-
let chunkBytes = 0;
|
|
245
|
-
let recordCount = 0;
|
|
246
|
-
let metaCount = 0;
|
|
247
|
-
let lastRecordKey = '';
|
|
248
|
-
const append = async (line) => {
|
|
249
|
-
const encoded = `${JSON.stringify(line)}\n`;
|
|
250
|
-
const length = Buffer.byteLength(encoded);
|
|
251
|
-
if (length > maxPlainChunkBytes)
|
|
252
|
-
fail('Backup entry exceeds the encrypted chunk limit.');
|
|
253
|
-
if (chunkBytes + length > maxPlainChunkBytes)
|
|
254
|
-
await flush();
|
|
255
|
-
lines.push(encoded);
|
|
256
|
-
chunkBytes += length;
|
|
257
|
-
snapshotHash.update(encoded);
|
|
258
|
-
};
|
|
259
|
-
const flush = async () => {
|
|
260
|
-
if (lines.length === 0)
|
|
261
|
-
return;
|
|
262
|
-
const sequence = chunks.length;
|
|
263
|
-
const plaintext = Buffer.from(lines.join(''));
|
|
264
|
-
const plaintextDigest = hash(plaintext);
|
|
265
|
-
try {
|
|
266
|
-
const envelope = await plugins.smartcrypto.sealX25519Envelope({ plaintext,
|
|
267
|
-
recipientPublicKey: publisher.recipientPublicKey, recipientKeyId: this.options.recipientKeyId,
|
|
268
|
-
context: context('chunk', backupId, attempt.epoch, attempt.revision, sequence, plaintextDigest) });
|
|
269
|
-
const encrypted = Buffer.from(JSON.stringify(envelope));
|
|
270
|
-
if (encrypted.byteLength > maxEncryptedObjectBytes)
|
|
271
|
-
fail('Encrypted backup chunk exceeds its object bound.');
|
|
272
|
-
const path = `${this.options.prefix}/${backupId}/chunk-${String(sequence).padStart(5, '0')}.json`;
|
|
273
|
-
await plugins.fs.promises.writeFile(plugins.path.join(dir, `${sequence}.enc`), encrypted, { flag: 'wx', mode: 0o600 });
|
|
274
|
-
chunks.push({ sequence, path, encryptedDigest: hash(encrypted), plaintextDigest,
|
|
275
|
-
length: encrypted.byteLength, entries: lines.length });
|
|
276
|
-
lines.length = 0;
|
|
277
|
-
chunkBytes = 0;
|
|
278
|
-
}
|
|
279
|
-
finally {
|
|
280
|
-
plaintext.fill(0);
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
try {
|
|
284
|
-
for await (const source of attempt.sources) {
|
|
285
|
-
this.options.signal?.throwIfAborted();
|
|
286
|
-
if (!isName(source.kind) || !isName(source.id)
|
|
287
|
-
|| !isName(source.linkedModel) || !isName(source.linkedId)
|
|
288
|
-
|| !isDigestField(source.linkedDigestField)
|
|
289
|
-
|| !(source.bytes instanceof Uint8Array) || source.bytes.byteLength === 0
|
|
290
|
-
|| source.bytes.byteLength > maxSourceBytes)
|
|
291
|
-
fail('Invalid or oversized exact-source capsule.');
|
|
292
|
-
const sourceKey = recordKey(source.kind, source.id);
|
|
293
|
-
if (sourceIds.has(sourceKey))
|
|
294
|
-
fail('Duplicate exact-source capsule.');
|
|
295
|
-
const bytes = Uint8Array.from(source.bytes);
|
|
296
|
-
try {
|
|
297
|
-
const proof = { kind: source.kind, id: source.id, linkedModel: source.linkedModel,
|
|
298
|
-
linkedId: source.linkedId, linkedDigestField: source.linkedDigestField,
|
|
299
|
-
digest: hash(bytes), seen: false };
|
|
300
|
-
await append({ kind: 'source', sourceKind: proof.kind, sourceId: proof.id,
|
|
301
|
-
linkedModel: proof.linkedModel, linkedId: proof.linkedId,
|
|
302
|
-
linkedDigestField: proof.linkedDigestField,
|
|
303
|
-
sourceDigest: proof.digest, payload: Buffer.from(bytes).toString('base64url') });
|
|
304
|
-
sources.push(proof);
|
|
305
|
-
sourceIds.add(sourceKey);
|
|
306
|
-
const linkKey = recordKey(proof.linkedModel, proof.linkedId);
|
|
307
|
-
const linked = sourceLinks.get(linkKey) ?? [];
|
|
308
|
-
linked.push(proof);
|
|
309
|
-
sourceLinks.set(linkKey, linked);
|
|
310
|
-
}
|
|
311
|
-
finally {
|
|
312
|
-
bytes.fill(0);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
for await (const record of attempt.records) {
|
|
316
|
-
this.options.signal?.throwIfAborted();
|
|
317
|
-
if (!isName(record.model) || !isName(record.id) || !object(record.value)
|
|
318
|
-
|| record.value.id !== record.id)
|
|
319
|
-
fail('Invalid backup record identity.');
|
|
320
|
-
const key = recordKey(record.model, record.id);
|
|
321
|
-
if (key <= lastRecordKey)
|
|
322
|
-
fail('Backup records must be sorted by model and stable ID.');
|
|
323
|
-
lastRecordKey = key;
|
|
324
|
-
assertJson(record.value);
|
|
325
|
-
if (Buffer.byteLength(JSON.stringify(record.value)) > maxRecordBytes)
|
|
326
|
-
fail('Backup record exceeds its size bound.');
|
|
327
|
-
assertSnapshotRecord(record);
|
|
328
|
-
if (record.model === 'authswitch_authority_meta') {
|
|
329
|
-
assertStoredAuthorityMeta(record.value);
|
|
330
|
-
if (record.value.epoch !== attempt.epoch || record.value.revision !== attempt.revision) {
|
|
331
|
-
fail('Backup metadata does not match the pinned snapshot.');
|
|
332
|
-
}
|
|
333
|
-
metaCount++;
|
|
334
|
-
}
|
|
335
|
-
for (const source of sourceLinks.get(key) ?? []) {
|
|
336
|
-
if (this.sourceDigestInRecord(record, source.linkedDigestField) !== source.digest) {
|
|
337
|
-
fail('Exact-source bytes differ from their linked persisted record.');
|
|
338
|
-
}
|
|
339
|
-
source.seen = true;
|
|
340
|
-
}
|
|
341
|
-
this.assertPreparedClaudeSourceCoverage(record, sourceLinks.get(key) ?? []);
|
|
342
|
-
await append({ kind: 'record', model: record.model, id: record.id,
|
|
343
|
-
value: record.value, secret: await this.secretFor(record) });
|
|
344
|
-
recordCount++;
|
|
345
|
-
}
|
|
346
|
-
if (metaCount !== 1 || sources.some(source => !source.seen)) {
|
|
347
|
-
fail('Backup is missing metadata or an exact-source linkage.');
|
|
348
|
-
}
|
|
349
|
-
await flush();
|
|
350
|
-
return { dir, manifest: { schemaVersion: 1, backupId, epoch: attempt.epoch,
|
|
351
|
-
revision: attempt.revision, recipientKeyId: this.options.recipientKeyId, chunks,
|
|
352
|
-
recordCount, sources: sources.map(source => ({ kind: source.kind, id: source.id,
|
|
353
|
-
linkedModel: source.linkedModel, linkedId: source.linkedId,
|
|
354
|
-
linkedDigestField: source.linkedDigestField, digest: source.digest })),
|
|
355
|
-
snapshotDigest: snapshotHash.digest('hex') } };
|
|
356
|
-
}
|
|
357
|
-
catch (error) {
|
|
358
|
-
await plugins.fs.promises.rm(dir, { recursive: true, force: true });
|
|
359
|
-
throw error;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
async publish(path, bytes) {
|
|
363
|
-
try {
|
|
364
|
-
await this.options.store.putExact(path, bytes, this.options.signal);
|
|
365
|
-
}
|
|
366
|
-
catch (error) {
|
|
367
|
-
if (!(error instanceof plugins.smartbucket.ExactUploadError)
|
|
368
|
-
|| error.state.destinationPublication !== 'ambiguous')
|
|
369
|
-
throw error;
|
|
370
|
-
let found;
|
|
371
|
-
try {
|
|
372
|
-
found = await this.options.store.get(path, bytes.byteLength, AbortSignal.timeout(30_000));
|
|
373
|
-
}
|
|
374
|
-
catch (readError) {
|
|
375
|
-
throw new AuthorityBackupPublicationUnknownError(path, readError);
|
|
376
|
-
}
|
|
377
|
-
if (hash(found) !== hash(bytes) || found.byteLength !== bytes.byteLength) {
|
|
378
|
-
throw new AuthorityBackupPublicationUnknownError(path, error);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
const readback = await this.options.store.get(path, bytes.byteLength, this.options.signal);
|
|
382
|
-
if (readback.byteLength !== bytes.byteLength || hash(readback) !== hash(bytes)) {
|
|
383
|
-
fail('Exact backup object readback differs from the published bytes.');
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
async publishSnapshot() {
|
|
387
|
-
const { source, recipientPublicKey } = this.publisher();
|
|
388
|
-
const { store, prefix, recipientKeyId } = this.options;
|
|
389
|
-
if (!/^[a-zA-Z0-9/_-]{1,256}$/.test(prefix) || prefix.startsWith('/') || prefix.endsWith('/')
|
|
390
|
-
|| prefix.includes('//') || !isName(recipientKeyId)
|
|
391
|
-
|| recipientPublicKey.byteLength !== 32) {
|
|
392
|
-
fail('Invalid backup destination or recovery-key reference.');
|
|
393
|
-
}
|
|
394
|
-
const backupId = uuid();
|
|
395
|
-
const stageHolder = { current: null };
|
|
396
|
-
try {
|
|
397
|
-
await source.capture(async (attempt) => {
|
|
398
|
-
if (stageHolder.current)
|
|
399
|
-
await plugins.fs.promises.rm(stageHolder.current.dir, { recursive: true, force: true });
|
|
400
|
-
stageHolder.current = null;
|
|
401
|
-
stageHolder.current = await this.stage(backupId, attempt);
|
|
402
|
-
});
|
|
403
|
-
const completed = stageHolder.current;
|
|
404
|
-
if (!completed)
|
|
405
|
-
fail('Snapshot source committed without a backup attempt.');
|
|
406
|
-
const manifestBytes = Buffer.from(JSON.stringify(completed.manifest));
|
|
407
|
-
if (manifestBytes.byteLength > maxRecordBytes)
|
|
408
|
-
fail('Backup manifest exceeds its size bound.');
|
|
409
|
-
const manifestEnvelope = await plugins.smartcrypto.sealX25519Envelope({
|
|
410
|
-
plaintext: manifestBytes, recipientPublicKey, recipientKeyId, context: context('manifest', backupId),
|
|
411
|
-
});
|
|
412
|
-
manifestBytes.fill(0);
|
|
413
|
-
const encryptedManifest = Buffer.from(JSON.stringify(manifestEnvelope));
|
|
414
|
-
const manifestPath = `${prefix}/${backupId}/manifest.json`;
|
|
415
|
-
await store.prepare(this.options.signal);
|
|
416
|
-
for (const chunk of completed.manifest.chunks) {
|
|
417
|
-
this.options.signal?.throwIfAborted();
|
|
418
|
-
const bytes = await plugins.fs.promises.readFile(plugins.path.join(completed.dir, `${chunk.sequence}.enc`));
|
|
419
|
-
if (bytes.byteLength !== chunk.length || hash(bytes) !== chunk.encryptedDigest) {
|
|
420
|
-
fail('Disposable encrypted backup staging changed before publication.');
|
|
421
|
-
}
|
|
422
|
-
await this.publish(chunk.path, bytes);
|
|
423
|
-
}
|
|
424
|
-
await this.publish(manifestPath, encryptedManifest);
|
|
425
|
-
return { backupId, manifestPath, manifestDigest: hash(encryptedManifest),
|
|
426
|
-
sourceEpoch: completed.manifest.epoch, sourceRevision: completed.manifest.revision,
|
|
427
|
-
snapshotDigest: completed.manifest.snapshotDigest };
|
|
428
|
-
}
|
|
429
|
-
finally {
|
|
430
|
-
if (stageHolder.current)
|
|
431
|
-
await plugins.fs.promises.rm(stageHolder.current.dir, { recursive: true, force: true });
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
/** Rehearse a previously published object set; no caller-supplied success flag is accepted. */
|
|
435
|
-
async rehearsePublished(input) {
|
|
436
|
-
if (!/^[a-f0-9-]{36}$/.test(input.backupId) || !isHash(input.manifestDigest)
|
|
437
|
-
|| !/^[a-f0-9-]{36}$/.test(input.sourceEpoch)
|
|
438
|
-
|| !Number.isSafeInteger(input.sourceRevision) || input.sourceRevision < 0
|
|
439
|
-
|| !isHash(input.snapshotDigest)
|
|
440
|
-
|| input.manifestPath !== `${this.options.prefix}/${input.backupId}/manifest.json`) {
|
|
441
|
-
fail('Invalid published backup reference.');
|
|
442
|
-
}
|
|
443
|
-
return this.verifyPublished(input);
|
|
444
|
-
}
|
|
445
|
-
async verifyPublished(input) {
|
|
446
|
-
const verifier = this.verifier();
|
|
447
|
-
const encrypted = await this.options.store.get(input.manifestPath, maxEncryptedObjectBytes, this.options.signal);
|
|
448
|
-
if (hash(encrypted) !== input.manifestDigest)
|
|
449
|
-
fail('Backup manifest readback digest changed.');
|
|
450
|
-
const opened = await plugins.smartcrypto.openX25519Envelope({
|
|
451
|
-
envelope: JSON.parse(Buffer.from(encrypted).toString('utf8')),
|
|
452
|
-
recipientPrivateKey: verifier.recipientPrivateKey,
|
|
453
|
-
expectedRecipientKeyId: this.options.recipientKeyId,
|
|
454
|
-
context: context('manifest', input.backupId),
|
|
455
|
-
});
|
|
456
|
-
let manifestValue;
|
|
457
|
-
try {
|
|
458
|
-
if (opened.byteLength > maxRecordBytes)
|
|
459
|
-
fail('Authenticated backup manifest exceeds its size bound.');
|
|
460
|
-
manifestValue = JSON.parse(Buffer.from(opened).toString('utf8'));
|
|
461
|
-
}
|
|
462
|
-
finally {
|
|
463
|
-
opened.fill(0);
|
|
464
|
-
}
|
|
465
|
-
assertManifest(manifestValue, input.backupId, this.options.prefix);
|
|
466
|
-
const manifest = manifestValue;
|
|
467
|
-
if (manifest.recipientKeyId !== this.options.recipientKeyId
|
|
468
|
-
|| manifest.epoch !== input.sourceEpoch || manifest.revision !== input.sourceRevision
|
|
469
|
-
|| manifest.snapshotDigest !== input.snapshotDigest) {
|
|
470
|
-
fail('Authenticated backup manifest does not match the committed snapshot.');
|
|
471
|
-
}
|
|
472
|
-
const sourceLinks = new Map();
|
|
473
|
-
manifest.sources.forEach((proof, index) => {
|
|
474
|
-
const key = recordKey(proof.linkedModel, proof.linkedId);
|
|
475
|
-
const linked = sourceLinks.get(key) ?? [];
|
|
476
|
-
linked.push({ proof, index });
|
|
477
|
-
sourceLinks.set(key, linked);
|
|
478
|
-
});
|
|
479
|
-
const linkedSourceIndexes = new Set();
|
|
480
|
-
const restoredEpoch = uuid();
|
|
481
|
-
const snapshotHash = plugins.crypto.createHash('sha256');
|
|
482
|
-
const expectedRecordHash = plugins.crypto.createHash('sha256');
|
|
483
|
-
const expectedSourceHash = plugins.crypto.createHash('sha256');
|
|
484
|
-
let recordCount = 0;
|
|
485
|
-
let sourceCount = 0;
|
|
486
|
-
let expectedCount = 0;
|
|
487
|
-
let expectedSourceCount = 0;
|
|
488
|
-
let lastKey = '';
|
|
489
|
-
let recordsStarted = false;
|
|
490
|
-
let fullyConsumed = false;
|
|
491
|
-
const self = this;
|
|
492
|
-
const entries = async function* () {
|
|
493
|
-
for (const chunk of manifest.chunks) {
|
|
494
|
-
self.options.signal?.throwIfAborted();
|
|
495
|
-
const encryptedChunk = await self.options.store.get(chunk.path, maxEncryptedObjectBytes, self.options.signal);
|
|
496
|
-
if (encryptedChunk.byteLength !== chunk.length || hash(encryptedChunk) !== chunk.encryptedDigest) {
|
|
497
|
-
fail('Published backup chunk differs from its authenticated manifest.');
|
|
498
|
-
}
|
|
499
|
-
const plaintext = await plugins.smartcrypto.openX25519Envelope({
|
|
500
|
-
envelope: JSON.parse(Buffer.from(encryptedChunk).toString('utf8')),
|
|
501
|
-
recipientPrivateKey: verifier.recipientPrivateKey,
|
|
502
|
-
expectedRecipientKeyId: manifest.recipientKeyId,
|
|
503
|
-
context: context('chunk', manifest.backupId, manifest.epoch, manifest.revision, chunk.sequence, chunk.plaintextDigest),
|
|
504
|
-
});
|
|
505
|
-
try {
|
|
506
|
-
if (plaintext.byteLength > maxPlainChunkBytes || hash(plaintext) !== chunk.plaintextDigest) {
|
|
507
|
-
fail('Published backup chunk plaintext digest changed.');
|
|
508
|
-
}
|
|
509
|
-
const serialized = Buffer.from(plaintext).toString('utf8');
|
|
510
|
-
if (!serialized.endsWith('\n'))
|
|
511
|
-
fail('Backup chunk ended with a truncated entry.');
|
|
512
|
-
const lines = serialized.slice(0, -1).split('\n');
|
|
513
|
-
if (lines.length !== chunk.entries)
|
|
514
|
-
fail('Backup chunk entry count changed.');
|
|
515
|
-
snapshotHash.update(serialized);
|
|
516
|
-
for (const line of lines) {
|
|
517
|
-
const entry = JSON.parse(line);
|
|
518
|
-
if (!object(entry))
|
|
519
|
-
fail('Invalid backup entry.');
|
|
520
|
-
if (entry.kind === 'source') {
|
|
521
|
-
if (recordsStarted)
|
|
522
|
-
fail('Exact-source capsules must precede backup records.');
|
|
523
|
-
if (!isName(entry.sourceKind) || !isName(entry.sourceId)
|
|
524
|
-
|| !isName(entry.linkedModel) || !isName(entry.linkedId)
|
|
525
|
-
|| !isDigestField(entry.linkedDigestField)
|
|
526
|
-
|| !isHash(entry.sourceDigest) || typeof entry.payload !== 'string') {
|
|
527
|
-
fail('Invalid exact-source backup capsule.');
|
|
528
|
-
}
|
|
529
|
-
const bytes = Buffer.from(entry.payload, 'base64url');
|
|
530
|
-
if (bytes.byteLength > maxSourceBytes || hash(bytes) !== entry.sourceDigest) {
|
|
531
|
-
fail('Exact-source capsule digest changed.');
|
|
532
|
-
}
|
|
533
|
-
const proof = manifest.sources[sourceCount];
|
|
534
|
-
if (!proof || proof.kind !== entry.sourceKind || proof.id !== entry.sourceId
|
|
535
|
-
|| proof.linkedModel !== entry.linkedModel || proof.linkedId !== entry.linkedId
|
|
536
|
-
|| proof.linkedDigestField !== entry.linkedDigestField
|
|
537
|
-
|| proof.digest !== entry.sourceDigest)
|
|
538
|
-
fail('Exact-source capsule order or coverage changed.');
|
|
539
|
-
sourceCount++;
|
|
540
|
-
const restored = { kind: 'source', sourceKind: entry.sourceKind,
|
|
541
|
-
sourceId: entry.sourceId, linkedModel: entry.linkedModel, linkedId: entry.linkedId,
|
|
542
|
-
linkedDigestField: entry.linkedDigestField, sourceDigest: entry.sourceDigest, bytes };
|
|
543
|
-
expectedSourceHash.update(canonicalJson({ ...restored,
|
|
544
|
-
bytes: Buffer.from(bytes).toString('base64url') }) + '\n');
|
|
545
|
-
expectedSourceCount++;
|
|
546
|
-
yield restored;
|
|
547
|
-
}
|
|
548
|
-
else if (entry.kind === 'record') {
|
|
549
|
-
recordsStarted = true;
|
|
550
|
-
if (!isName(entry.model) || !isName(entry.id) || !object(entry.value)
|
|
551
|
-
|| entry.value.id !== entry.id || (entry.secret !== null && typeof entry.secret !== 'string')) {
|
|
552
|
-
fail('Invalid backup record entry.');
|
|
553
|
-
}
|
|
554
|
-
const key = recordKey(entry.model, entry.id);
|
|
555
|
-
if (key <= lastKey)
|
|
556
|
-
fail('Backup record order changed.');
|
|
557
|
-
lastKey = key;
|
|
558
|
-
recordCount++;
|
|
559
|
-
const originalRecord = { model: entry.model, id: entry.id, value: entry.value };
|
|
560
|
-
assertSnapshotRecord(originalRecord);
|
|
561
|
-
const linked = sourceLinks.get(key) ?? [];
|
|
562
|
-
for (const { proof, index } of linked) {
|
|
563
|
-
if (self.sourceDigestInRecord(originalRecord, proof.linkedDigestField) !== proof.digest) {
|
|
564
|
-
fail('Authenticated source proof is not linked to its exact record digest.');
|
|
565
|
-
}
|
|
566
|
-
linkedSourceIndexes.add(index);
|
|
567
|
-
}
|
|
568
|
-
self.assertPreparedClaudeSourceCoverage(originalRecord, linked.map(item => item.proof));
|
|
569
|
-
const restored = await self.restoreRecord({ model: entry.model, id: entry.id,
|
|
570
|
-
value: entry.value }, entry.secret, restoredEpoch);
|
|
571
|
-
if (restored) {
|
|
572
|
-
expectedRecordHash.update(canonicalJson(restored) + '\n');
|
|
573
|
-
expectedCount++;
|
|
574
|
-
yield restored;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
else
|
|
578
|
-
fail('Unknown backup entry kind.');
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
finally {
|
|
582
|
-
plaintext.fill(0);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
if (linkedSourceIndexes.size !== manifest.sources.length) {
|
|
586
|
-
fail('Authenticated source proof lacks a linked persisted record.');
|
|
587
|
-
}
|
|
588
|
-
if (recordCount !== manifest.recordCount || sourceCount !== manifest.sources.length
|
|
589
|
-
|| snapshotHash.digest('hex') !== manifest.snapshotDigest) {
|
|
590
|
-
fail('Published backup snapshot is incomplete.');
|
|
591
|
-
}
|
|
592
|
-
fullyConsumed = true;
|
|
593
|
-
};
|
|
594
|
-
const readback = await verifier.rehearsal.restoreClosed(entries());
|
|
595
|
-
let rehearsalDigest;
|
|
596
|
-
let verificationFailure;
|
|
597
|
-
try {
|
|
598
|
-
if (!fullyConsumed)
|
|
599
|
-
fail('Restore rehearsal did not consume the complete backup.');
|
|
600
|
-
const actualRecordHash = plugins.crypto.createHash('sha256');
|
|
601
|
-
const actualSourceHash = plugins.crypto.createHash('sha256');
|
|
602
|
-
let actualCount = 0;
|
|
603
|
-
let actualSourceCount = 0;
|
|
604
|
-
let actualLastKey = '';
|
|
605
|
-
for await (const record of readback.records) {
|
|
606
|
-
if (!isName(record.model) || !isName(record.id) || !object(record.value)
|
|
607
|
-
|| record.value.id !== record.id)
|
|
608
|
-
fail('Rehearsal readback returned an invalid record.');
|
|
609
|
-
const key = recordKey(record.model, record.id);
|
|
610
|
-
if (key <= actualLastKey)
|
|
611
|
-
fail('Rehearsal readback order changed.');
|
|
612
|
-
actualLastKey = key;
|
|
613
|
-
actualRecordHash.update(canonicalJson(record) + '\n');
|
|
614
|
-
actualCount++;
|
|
615
|
-
}
|
|
616
|
-
for await (const source of readback.sources) {
|
|
617
|
-
if (source.kind !== 'source' || !isHash(source.sourceDigest)
|
|
618
|
-
|| hash(source.bytes) !== source.sourceDigest)
|
|
619
|
-
fail('Rehearsal source readback changed.');
|
|
620
|
-
actualSourceHash.update(canonicalJson({ ...source,
|
|
621
|
-
bytes: Buffer.from(source.bytes).toString('base64url') }) + '\n');
|
|
622
|
-
actualSourceCount++;
|
|
623
|
-
}
|
|
624
|
-
const expectedRecordDigest = expectedRecordHash.digest('hex');
|
|
625
|
-
const expectedSourceDigest = expectedSourceHash.digest('hex');
|
|
626
|
-
if (actualCount !== expectedCount || actualSourceCount !== expectedSourceCount
|
|
627
|
-
|| actualRecordHash.digest('hex') !== expectedRecordDigest
|
|
628
|
-
|| actualSourceHash.digest('hex') !== expectedSourceDigest) {
|
|
629
|
-
fail('Isolated restore readback differs from expected safe state.');
|
|
630
|
-
}
|
|
631
|
-
rehearsalDigest = hash(JSON.stringify([expectedRecordDigest, expectedSourceDigest]));
|
|
632
|
-
}
|
|
633
|
-
catch (error) {
|
|
634
|
-
verificationFailure = error;
|
|
635
|
-
}
|
|
636
|
-
let closeFailure;
|
|
637
|
-
// A matching postimage is not a receipt while the isolated owner still has a live database or child.
|
|
638
|
-
try {
|
|
639
|
-
await readback.close();
|
|
640
|
-
}
|
|
641
|
-
catch (error) {
|
|
642
|
-
closeFailure = error;
|
|
643
|
-
}
|
|
644
|
-
if (verificationFailure && closeFailure) {
|
|
645
|
-
throw new AggregateError([verificationFailure, closeFailure], 'Restore rehearsal verification and cleanup both failed.');
|
|
646
|
-
}
|
|
647
|
-
if (verificationFailure)
|
|
648
|
-
throw verificationFailure;
|
|
649
|
-
if (closeFailure)
|
|
650
|
-
throw closeFailure;
|
|
651
|
-
if (!rehearsalDigest)
|
|
652
|
-
fail('Restore rehearsal did not produce an exact postimage digest.');
|
|
653
|
-
return { backupId: manifest.backupId, manifestPath: input.manifestPath,
|
|
654
|
-
manifestDigest: input.manifestDigest, snapshotDigest: manifest.snapshotDigest, sourceEpoch: manifest.epoch,
|
|
655
|
-
sourceRevision: manifest.revision, restoredEpoch, recordCount: manifest.recordCount,
|
|
656
|
-
sources: manifest.sources, rehearsalDigest, verifiedAt: new Date().toISOString(),
|
|
657
|
-
restoreAdmission: 'closed_pending_codex_and_native_reconciliation' };
|
|
658
|
-
}
|
|
659
|
-
async restoreRecord(record, secret, restoredEpoch) {
|
|
660
|
-
const value = record.value;
|
|
661
|
-
if (!object(value))
|
|
662
|
-
fail('Invalid stored backup record.');
|
|
663
|
-
assertSnapshotRecord(record);
|
|
664
|
-
if (record.model === 'authswitch_authority_events')
|
|
665
|
-
return null;
|
|
666
|
-
if (record.model === 'authswitch_authority_usage')
|
|
667
|
-
return null;
|
|
668
|
-
if (record.model === 'authswitch_authority_meta') {
|
|
669
|
-
assertStoredAuthorityMeta(value);
|
|
670
|
-
const restored = { ...value, admission: 'closed_restored',
|
|
671
|
-
epoch: restoredEpoch, revision: 0, updateId: uuid() };
|
|
672
|
-
return { ...record, value: restored };
|
|
673
|
-
}
|
|
674
|
-
if (record.model === 'authswitch_authority_grants') {
|
|
675
|
-
assertStoredAuthorityGrant(value);
|
|
676
|
-
if ((value.ciphertext !== null) !== (secret !== null))
|
|
677
|
-
fail('Grant recovery payload is incomplete.');
|
|
678
|
-
if (value.state === 'removed')
|
|
679
|
-
return record;
|
|
680
|
-
const native = ['claude_host_native', 'opencode_native'].includes(value.purpose);
|
|
681
|
-
const restored = { ...value,
|
|
682
|
-
state: native ? 'legacy_native_pending' : 'needs_reauth',
|
|
683
|
-
owner: native ? 'legacy_native' : 'daemon', ciphertext: null, accessExpiresAt: null,
|
|
684
|
-
attemptId: null, retryAt: null, retryCount: 0,
|
|
685
|
-
problem: native ? 'native_owner' : 'exchange_uncertain',
|
|
686
|
-
grantGeneration: value.grantGeneration + 1,
|
|
687
|
-
authorizationGeneration: value.authorizationGeneration + 1,
|
|
688
|
-
revision: value.revision + 1, statusObservedAt: new Date().toISOString(), updateId: uuid() };
|
|
689
|
-
assertStoredAuthorityGrant(restored);
|
|
690
|
-
return { ...record, value: restored };
|
|
691
|
-
}
|
|
692
|
-
if (record.model === 'authswitch_authority_bindings') {
|
|
693
|
-
assertStoredAuthorityBinding(value);
|
|
694
|
-
const restored = { ...value,
|
|
695
|
-
capabilityHash: hash(plugins.crypto.randomBytes(32)), revision: value.revision + 1,
|
|
696
|
-
updateId: uuid() };
|
|
697
|
-
return { ...record, value: restored };
|
|
698
|
-
}
|
|
699
|
-
if (record.model === 'authswitch_authority_enrollments') {
|
|
700
|
-
assertStoredAuthorityEnrollment(value);
|
|
701
|
-
if (secret === null)
|
|
702
|
-
fail('Enrollment recovery payload is missing.');
|
|
703
|
-
const plaintext = Buffer.from(secret, 'base64url');
|
|
704
|
-
try {
|
|
705
|
-
const row = parseEnrollment(plaintext, value.id);
|
|
706
|
-
const sealed = await this.options.secrets.seal(value.id, plaintext);
|
|
707
|
-
const opened = await this.options.secrets.unseal(value.id, sealed);
|
|
708
|
-
try {
|
|
709
|
-
if (Buffer.compare(Buffer.from(opened), plaintext) !== 0)
|
|
710
|
-
fail('Destination enrollment reseal did not verify.');
|
|
711
|
-
}
|
|
712
|
-
finally {
|
|
713
|
-
opened.fill(0);
|
|
714
|
-
}
|
|
715
|
-
const restored = { ...value, ciphertext: sealed,
|
|
716
|
-
revision: value.revision + 1, updateId: uuid() };
|
|
717
|
-
assertStoredAuthorityEnrollment(restored);
|
|
718
|
-
if (authorityEnrollmentId(row) !== restored.id)
|
|
719
|
-
fail('Enrollment changed during destination reseal.');
|
|
720
|
-
return { ...record, value: restored };
|
|
721
|
-
}
|
|
722
|
-
finally {
|
|
723
|
-
plaintext.fill(0);
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
if (record.model === 'authswitch_authority_codex_homes') {
|
|
727
|
-
assertStoredAuthorityCodexHome(value);
|
|
728
|
-
const restored = { ...value, activeRun: null, updateId: uuid() };
|
|
729
|
-
return { ...record, value: restored };
|
|
730
|
-
}
|
|
731
|
-
if (record.model === 'authswitch_authority_claude_homes') {
|
|
732
|
-
const restored = { ...value, status: 'quarantined', pendingOperationId: uuid(),
|
|
733
|
-
revision: Number(value.revision) + 1, updateId: uuid() };
|
|
734
|
-
assertStoredAuthorityClaudeHome(restored);
|
|
735
|
-
return { ...record, value: restored };
|
|
736
|
-
}
|
|
737
|
-
if (record.model === 'authswitch_authority_claude_handoffs') {
|
|
738
|
-
const restored = { ...value, phase: 'quarantined',
|
|
739
|
-
problem: 'native_uncertain', sealedOutgoing: null,
|
|
740
|
-
revision: Number(value.revision) + 1, updateId: uuid() };
|
|
741
|
-
assertStoredAuthorityClaudeHandoff(restored);
|
|
742
|
-
return { ...record, value: restored };
|
|
743
|
-
}
|
|
744
|
-
if (record.model === 'authswitch_authority_handoffs') {
|
|
745
|
-
const restored = { ...value, phase: 'needs_reauth',
|
|
746
|
-
backupDigest: null, verifiedSourceDigest: null,
|
|
747
|
-
revision: Number(value.revision) + 1, updateId: uuid() };
|
|
748
|
-
assertStoredAuthorityHandoff(restored);
|
|
749
|
-
return { ...record, value: restored };
|
|
750
|
-
}
|
|
751
|
-
if (record.model === 'authswitch_authority_migration_ledger') {
|
|
752
|
-
const restored = { ...value, status: 'prepared', backupDigest: null,
|
|
753
|
-
revision: Number(value.revision) + 1, updateId: uuid() };
|
|
754
|
-
assertStoredAuthorityMigrationLedger(restored);
|
|
755
|
-
return { ...record, value: restored };
|
|
756
|
-
}
|
|
757
|
-
if (record.model === 'authswitch_authority_operations') {
|
|
758
|
-
if (secret !== null)
|
|
759
|
-
fail('Unexpected executable secret in backup operation.');
|
|
760
|
-
assertStoredAuthorityOperation(value);
|
|
761
|
-
const restored = restoreStoredAuthorityOperation(value, { restoredAt: new Date().toISOString(), updateId: uuid() });
|
|
762
|
-
return restored === value ? record : { ...record, value: restored };
|
|
763
|
-
}
|
|
764
|
-
if (secret !== null)
|
|
765
|
-
fail('Unexpected executable secret in backup record.');
|
|
766
|
-
return record;
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRob3JpdHliYWNrdXAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmF1dGhvcml0eWJhY2t1cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsNEJBQTRCLEVBQUUsa0NBQWtDLEVBQ2hFLCtCQUErQixFQUFFLDhCQUE4QixFQUFFLCtCQUErQixFQUNoRywwQkFBMEIsRUFBRSw0QkFBNEIsRUFDeEQseUJBQXlCLEVBQUUsb0NBQW9DLEVBQUUsOEJBQThCLEVBQy9GLCtCQUErQixHQUdoQyxNQUFNLDhCQUE4QixDQUFDO0FBQ3RDLE9BQU8sRUFBRSwyQkFBMkIsRUFBK0IsTUFBTSxnQ0FBZ0MsQ0FBQztBQUkxRyxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQzNDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDakQscUdBQXFHO0FBQ3JHLE1BQU0sY0FBYyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbkMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDdkMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxLQUEwQixFQUFVLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3JILE1BQU0sSUFBSSxHQUFHLEdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7QUFDdkQsTUFBTSxNQUFNLEdBQUcsQ0FBQyxLQUFjLEVBQW1CLEVBQUUsQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzlHLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBYyxFQUFtQixFQUFFLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLDBCQUEwQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN4SCxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQWMsRUFBK0QsRUFBRSxDQUNwRyxLQUFLLEtBQUssY0FBYyxJQUFJLEtBQUssS0FBSyx5QkFBeUIsSUFBSSxLQUFLLEtBQUsscUJBQXFCLENBQUM7QUFDckcsU0FBUyxJQUFJLENBQUMsT0FBZSxJQUFXLE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25FLE1BQU0sU0FBUyxHQUFHLENBQUMsS0FBYSxFQUFFLEVBQVUsRUFBVSxFQUFFLENBQUMsR0FBRyxLQUFLLFNBQVMsRUFBRSxFQUFFLENBQUM7QUFDL0UsTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFHLEtBQTZCLEVBQWMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLHNCQUFzQixFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xJLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBYyxFQUFvQyxFQUFFLENBQUMsS0FBSyxLQUFLLElBQUk7T0FDOUUsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7T0FDbEQsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDckUsTUFBTSxTQUFTLEdBQUcsQ0FBQyxLQUE4QixFQUFFLElBQXVCLEVBQVcsRUFBRSxDQUNyRixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBRTVGLE1BQU0sb0JBQW9CLEdBQUcsMkJBQTJCLENBQUM7QUFFekQsOEZBQThGO0FBQzlGLE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLENBQUMsR0FBNkIsRUFBVSxFQUFFLENBQzdFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUUvRyxNQUFNLGVBQWUsR0FBRyxDQUFDLEtBQWlCLEVBQUUsRUFBVSxFQUE0QixFQUFFO0lBQ2xGLE1BQU0sS0FBSyxHQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN2RSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDLGNBQWMsRUFBRSxXQUFXLEVBQUUscUJBQXFCO1FBQ3pGLFVBQVUsRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1dBQzdFLENBQUMsQ0FBQyxjQUFjLEVBQUUsV0FBVyxFQUFFLHFCQUFxQixFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsWUFBWSxDQUFDO2FBQ2hHLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsQ0FBQztXQUM1QyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQztXQUNyRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLG9CQUFxQyxDQUFDLEVBQUUsQ0FBQztRQUN6RSxNQUFNLElBQUksS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUNELE1BQU0sR0FBRyxHQUFHLEtBQTRDLENBQUM7SUFDekQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUztXQUNsQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO0lBQ3pHLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQyxDQUFDO0FBRUYsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFjLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBUSxFQUFFO0lBQ3JELElBQUksS0FBSyxHQUFHLEVBQUU7UUFBRSxJQUFJLENBQUMsNkNBQTZDLENBQUMsQ0FBQztJQUNwRSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE9BQU8sS0FBSyxLQUFLLFNBQVM7UUFBRSxPQUFPO0lBQ3RGLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTztJQUNoRSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUFDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSztZQUFFLFVBQVUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQUMsT0FBTztJQUFDLENBQUM7SUFDNUYsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUFDLEtBQUssTUFBTSxJQUFJLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFBRSxVQUFVLENBQUMsSUFBSSxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUFDLE9BQU87SUFBQyxDQUFDO0lBQ3BHLElBQUksQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0FBQ25ELENBQUMsQ0FBQztBQUVGLGlHQUFpRztBQUNqRyxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQWMsRUFBVSxFQUFFO0lBQy9DLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztJQUMzRSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FDaEUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLGFBQWEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7SUFDdEUsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2xCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMvQixDQUFDLENBQUM7QUE0QkYscUZBQXFGO0FBQ3JGLE1BQU0sT0FBTyx5QkFBeUI7SUFFUDtJQURyQixVQUFVLENBQThDO0lBQ2hFLFlBQTZCLE1BQWtDO1FBQWxDLFdBQU0sR0FBTixNQUFNLENBQTRCO0lBQUcsQ0FBQztJQUU1RCxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQW9CO1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDeEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDN0YsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDO0lBQ3RDLENBQUM7SUFFTSxLQUFLLENBQUMsUUFBUSxDQUFDLElBQVksRUFBRSxLQUFpQixFQUFFLE1BQW9CO1FBQ3pFLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUN0RixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUM7WUFDcEQsS0FBSyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUUsTUFBTSxHQUFHLEtBQUssQ0FBQyxVQUFVLEVBQUUsTUFBTSxJQUFJLElBQUksR0FBRyxJQUFJLEVBQUUsQ0FBQztnQkFDdEUsTUFBTSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNsRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ04sSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxNQUFNO2dCQUM5RixhQUFhLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxzQkFBc0IsRUFBRSxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDNUcsQ0FBQztnQkFBUyxDQUFDO1lBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFZLEVBQUUsUUFBZ0IsRUFBRSxNQUFvQjtRQUNuRSxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDakUsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO1FBQzVCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQztZQUNILElBQUksS0FBSyxFQUFFLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUNqQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBbUIsQ0FBQyxDQUFDO2dCQUNoRixNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQztnQkFDM0IsSUFBSSxNQUFNLEdBQUcsUUFBUTtvQkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUM7Z0JBQ3hGLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckIsQ0FBQztZQUNELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdkMsQ0FBQztnQkFBUyxDQUFDO1lBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQUMsQ0FBQztJQUNqQyxDQUFDO0NBQ0Y7QUE2QkQsU0FBUyxjQUFjLENBQUMsS0FBYyxFQUFFLFFBQWdCLEVBQUUsTUFBYztJQUN0RSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDLGVBQWUsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFVBQVU7UUFDdkYsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztXQUNyRSxLQUFLLENBQUMsYUFBYSxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxLQUFLLFFBQVE7V0FDeEQsT0FBTyxLQUFLLENBQUMsS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO1dBQ3ZFLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO1dBQ25FLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQztXQUN6RSxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO1dBQzlELENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ25FLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFDRCxLQUFLLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUN6RCxNQUFNLElBQUksR0FBWSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxpQkFBaUI7WUFDMUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxLQUFLO2VBQ2hFLElBQUksQ0FBQyxJQUFJLEtBQUssR0FBRyxNQUFNLElBQUksUUFBUSxVQUFVLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxPQUFPO2VBQ2xGLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO2VBQzlELENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO2VBQzdELE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsdUJBQXVCO2VBQzdDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyRSxJQUFJLENBQUMsMkNBQTJDLENBQUMsQ0FBQztRQUNwRCxDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDcEMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxDQUFDLENBQUM7ZUFDMUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO2VBQ25FLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUM5RixJQUFJLENBQUMsNENBQTRDLENBQUMsQ0FBQztRQUNyRCxDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7WUFBRSxJQUFJLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUNuRixTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzNCLENBQUM7QUFDSCxDQUFDO0FBMkJELE1BQU0sT0FBTyxzQ0FBdUMsU0FBUSxLQUFLO0lBQ25DO0lBQTVCLFlBQTRCLElBQVksRUFBRSxLQUFjO1FBQ3RELEtBQUssQ0FBQyxrRUFBa0UsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFEM0QsU0FBSSxHQUFKLElBQUksQ0FBUTtJQUV4QyxDQUFDO0NBQ0Y7QUFtQkQsd0hBQXdIO0FBQ3hILE1BQU0sT0FBTyx5QkFBeUI7SUFDUDtJQUE3QixZQUE2QixPQUFnQztRQUFoQyxZQUFPLEdBQVAsT0FBTyxDQUF5QjtJQUFHLENBQUM7SUFFekQsU0FBUztRQUNmLElBQUksQ0FBQyxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQUUsSUFBSSxDQUFDLHdEQUF3RCxDQUFDLENBQUM7UUFDaEcsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7SUFFTyxRQUFRO1FBQ2QsSUFBSSxDQUFDLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUM7WUFBRSxJQUFJLENBQUMsc0RBQXNELENBQUMsQ0FBQztRQUNqRyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVPLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBOEI7UUFDcEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUMzQixJQUFJLEVBQUUsR0FBa0IsSUFBSSxDQUFDO1FBQzdCLElBQUksTUFBTSxHQUFrQixJQUFJLENBQUM7UUFDakMsSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLDZCQUE2QixFQUFFLENBQUM7WUFDbkQsMEJBQTBCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbEMsRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUMzQyxDQUFDO2FBQU0sSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLGtDQUFrQyxFQUFFLENBQUM7WUFDL0QsK0JBQStCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkMsRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUMzQyxDQUFDO2FBQU0sSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLHNDQUFzQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUM7ZUFDOUUsT0FBTyxLQUFLLENBQUMsZUFBZSxLQUFLLFFBQVEsSUFBSSxPQUFPLEtBQUssQ0FBQyxjQUFjLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDM0YsRUFBRSxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUM7WUFBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQztRQUM1RCxDQUFDO1FBQ0QsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPLElBQUksQ0FBQztRQUNoQyxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDO1lBQ0gsSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLGtDQUFrQztnQkFBRSxlQUFlLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMzRixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2xELENBQUM7Z0JBQVMsQ0FBQztZQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFBQyxDQUFDO0lBQzlCLENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxNQUE4QixFQUN6RCxLQUF5RDtRQUN6RCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUN2QyxJQUFJLEtBQUssS0FBSyxjQUFjO1lBQUUsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUMxRyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDaEMsTUFBTSxNQUFNLEdBQUcsS0FBSyxLQUFLLHlCQUF5QjtnQkFDaEQsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUM7WUFDNUUsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3hDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxrQ0FBa0MsQ0FBQyxNQUE4QixFQUN2RSxPQUErQztRQUMvQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssc0NBQXNDO1lBQUUsT0FBTztRQUNwRSxrQ0FBa0MsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakQsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxVQUFVO1lBQUUsT0FBTztRQUM5QyxLQUFLLE1BQU0sS0FBSyxJQUFJLENBQUMseUJBQXlCLEVBQUUscUJBQXFCLENBQVUsRUFBRSxDQUFDO1lBQ2hGLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDeEQsSUFBSSxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUM1QyxNQUFNLENBQUMsaUJBQWlCLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLEVBQUUsQ0FBQztnQkFDbEUsSUFBSSxDQUFDLGtFQUFrRSxDQUFDLENBQUM7WUFDM0UsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFnQixFQUFFLE9BQXdDO1FBQzVFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNuQyxJQUFJLE9BQU8sT0FBTyxDQUFDLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztlQUMxRSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQztZQUFFLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQ2hILE1BQU0sR0FBRyxHQUFHLE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO1FBQzVHLE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1QyxNQUFNLE9BQU8sR0FBMkQsRUFBRSxDQUFDO1FBQzNFLE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDcEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQWtFLENBQUM7UUFDOUYsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO1FBQzNCLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUM1QixNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6RCxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7UUFDbkIsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNsQixJQUFJLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDdkIsTUFBTSxNQUFNLEdBQUcsS0FBSyxFQUFFLElBQVcsRUFBaUIsRUFBRTtZQUNsRCxNQUFNLE9BQU8sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUM1QyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzFDLElBQUksTUFBTSxHQUFHLGtCQUFrQjtnQkFBRSxJQUFJLENBQUMsaURBQWlELENBQUMsQ0FBQztZQUN6RixJQUFJLFVBQVUsR0FBRyxNQUFNLEdBQUcsa0JBQWtCO2dCQUFFLE1BQU0sS0FBSyxFQUFFLENBQUM7WUFDNUQsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUFDLFVBQVUsSUFBSSxNQUFNLENBQUM7WUFBQyxZQUFZLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFFLENBQUMsQ0FBQztRQUNGLE1BQU0sS0FBSyxHQUFHLEtBQUssSUFBbUIsRUFBRTtZQUN0QyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFBRSxPQUFPO1lBQy9CLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7WUFDL0IsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUMsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQztnQkFDSCxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsRUFBRSxTQUFTO29CQUN2RSxrQkFBa0IsRUFBRSxTQUFTLENBQUMsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYztvQkFDN0YsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNyRyxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDeEQsSUFBSSxTQUFTLENBQUMsVUFBVSxHQUFHLHVCQUF1QjtvQkFBRSxJQUFJLENBQUMsa0RBQWtELENBQUMsQ0FBQztnQkFDN0csTUFBTSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxRQUFRLFVBQVUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQztnQkFDbEcsTUFBTSxPQUFPLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsUUFBUSxNQUFNLENBQUMsRUFBRSxTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUN2SCxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLGVBQWU7b0JBQzdFLE1BQU0sRUFBRSxTQUFTLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztnQkFDekQsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztZQUNuQyxDQUFDO29CQUFTLENBQUM7Z0JBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDO1lBQ0gsSUFBSSxLQUFLLEVBQUUsTUFBTSxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUMzQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQzt1QkFDekMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7dUJBQ3ZELENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQzt1QkFDeEMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLFlBQVksVUFBVSxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLEtBQUssQ0FBQzt1QkFDdEUsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsY0FBYztvQkFBRSxJQUFJLENBQUMsNENBQTRDLENBQUMsQ0FBQztnQkFDbEcsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNwRCxJQUFJLFNBQVMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDO29CQUFFLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO2dCQUN0RSxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDNUMsSUFBSSxDQUFDO29CQUNILE1BQU0sS0FBSyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXO3dCQUMvRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLENBQUMsaUJBQWlCO3dCQUN0RSxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztvQkFDckMsTUFBTSxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRTt3QkFDdkUsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO3dCQUN4RCxpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO3dCQUMxQyxZQUFZLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUNuRixPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNwQixTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUN6QixNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQzdELE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUM5QyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNuQixXQUFXLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDbkMsQ0FBQzt3QkFBUyxDQUFDO29CQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQUMsQ0FBQztZQUM5QixDQUFDO1lBQ0QsSUFBSSxLQUFLLEVBQUUsTUFBTSxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUMzQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7dUJBQ25FLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLE1BQU0sQ0FBQyxFQUFFO29CQUFFLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO2dCQUM1RSxNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQy9DLElBQUksR0FBRyxJQUFJLGFBQWE7b0JBQUUsSUFBSSxDQUFDLHVEQUF1RCxDQUFDLENBQUM7Z0JBQ3hGLGFBQWEsR0FBRyxHQUFHLENBQUM7Z0JBQ3BCLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3pCLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLGNBQWM7b0JBQUUsSUFBSSxDQUFDLHVDQUF1QyxDQUFDLENBQUM7Z0JBQ3BILG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUM3QixJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssMkJBQTJCLEVBQUUsQ0FBQztvQkFDakQseUJBQXlCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUN4QyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLE9BQU8sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLEtBQUssT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUN2RixJQUFJLENBQUMscURBQXFELENBQUMsQ0FBQztvQkFDOUQsQ0FBQztvQkFDRCxTQUFTLEVBQUUsQ0FBQztnQkFDZCxDQUFDO2dCQUNELEtBQUssTUFBTSxNQUFNLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztvQkFDaEQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQzt3QkFDbEYsSUFBSSxDQUFDLCtEQUErRCxDQUFDLENBQUM7b0JBQ3hFLENBQUM7b0JBQ0QsTUFBTSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7Z0JBQ3JCLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLGtDQUFrQyxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUM1RSxNQUFNLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO29CQUMvRCxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDL0QsV0FBVyxFQUFFLENBQUM7WUFDaEIsQ0FBQztZQUNELElBQUksU0FBUyxLQUFLLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDNUQsSUFBSSxDQUFDLHdEQUF3RCxDQUFDLENBQUM7WUFDakUsQ0FBQztZQUNELE1BQU0sS0FBSyxFQUFFLENBQUM7WUFDZCxPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLGFBQWEsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztvQkFDeEUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLE1BQU07b0JBQy9FLFdBQVcsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUU7d0JBQzdFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTt3QkFDMUQsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztvQkFDeEUsY0FBYyxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ25ELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxPQUFPLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNwRSxNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFZLEVBQUUsS0FBaUI7UUFDbkQsSUFBSSxDQUFDO1lBQUMsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQUMsQ0FBQztRQUM1RSxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLENBQUMsS0FBSyxZQUFZLE9BQU8sQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUM7bUJBQ3ZELEtBQUssQ0FBQyxLQUFLLENBQUMsc0JBQXNCLEtBQUssV0FBVztnQkFBRSxNQUFNLEtBQUssQ0FBQztZQUNyRSxJQUFJLEtBQWlCLENBQUM7WUFDdEIsSUFBSSxDQUFDO2dCQUFDLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFBQyxDQUFDO1lBQ2xHLE9BQU8sU0FBUyxFQUFFLENBQUM7Z0JBQUMsTUFBTSxJQUFJLHNDQUFzQyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztZQUFDLENBQUM7WUFDeEYsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxVQUFVLEtBQUssS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUN6RSxNQUFNLElBQUksc0NBQXNDLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2hFLENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzRixJQUFJLFFBQVEsQ0FBQyxVQUFVLEtBQUssS0FBSyxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDL0UsSUFBSSxDQUFDLGdFQUFnRSxDQUFDLENBQUM7UUFDekUsQ0FBQztJQUNILENBQUM7SUFFTSxLQUFLLENBQUMsZUFBZTtRQUMxQixNQUFNLEVBQUUsTUFBTSxFQUFFLGtCQUFrQixFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ3hELE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDdkQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO2VBQ3hGLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDO2VBQ2hELGtCQUFrQixDQUFDLFVBQVUsS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDeEIsTUFBTSxXQUFXLEdBQXVDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO1FBQzFFLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUMsT0FBTyxFQUFDLEVBQUU7Z0JBQ25DLElBQUksV0FBVyxDQUFDLE9BQU87b0JBQUUsTUFBTSxPQUFPLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUNqSCxXQUFXLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztnQkFDM0IsV0FBVyxDQUFDLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzVELENBQUMsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQztZQUN0QyxJQUFJLENBQUMsU0FBUztnQkFBRSxJQUFJLENBQUMscURBQXFELENBQUMsQ0FBQztZQUM1RSxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDdEUsSUFBSSxhQUFhLENBQUMsVUFBVSxHQUFHLGNBQWM7Z0JBQUUsSUFBSSxDQUFDLHlDQUF5QyxDQUFDLENBQUM7WUFDL0YsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLE9BQU8sQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUM7Z0JBQ3BFLFNBQVMsRUFBRSxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQzthQUNyRyxDQUFDLENBQUM7WUFDSCxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztZQUN4RSxNQUFNLFlBQVksR0FBRyxHQUFHLE1BQU0sSUFBSSxRQUFRLGdCQUFnQixDQUFDO1lBQzNELE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pDLEtBQUssTUFBTSxLQUFLLElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDOUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLENBQUM7Z0JBQ3RDLE1BQU0sS0FBSyxHQUFHLE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsUUFBUSxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUM1RyxJQUFJLEtBQUssQ0FBQyxVQUFVLEtBQUssS0FBSyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO29CQUMvRSxJQUFJLENBQUMsaUVBQWlFLENBQUMsQ0FBQztnQkFDMUUsQ0FBQztnQkFDRCxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN4QyxDQUFDO1lBQ0QsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3BELE9BQU8sRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUM7Z0JBQ3RFLFdBQVcsRUFBRSxTQUFTLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxRQUFRO2dCQUNsRixjQUFjLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4RCxDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLFdBQVcsQ0FBQyxPQUFPO2dCQUFFLE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNuSCxDQUFDO0lBQ0gsQ0FBQztJQUVELCtGQUErRjtJQUN4RixLQUFLLENBQUMsaUJBQWlCLENBQUMsS0FBa0M7UUFDL0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztlQUN2RSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO2VBQzFDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksS0FBSyxDQUFDLGNBQWMsR0FBRyxDQUFDO2VBQ3ZFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7ZUFDN0IsS0FBSyxDQUFDLFlBQVksS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxRQUFRLGdCQUFnQixFQUFFLENBQUM7WUFDckYsSUFBSSxDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRU8sS0FBSyxDQUFDLGVBQWUsQ0FBQyxLQUFrQztRQUM5RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDakMsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSx1QkFBdUIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pILElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxjQUFjO1lBQUUsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7UUFDL0YsTUFBTSxNQUFNLEdBQUcsTUFBTSxPQUFPLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDO1lBQzFELFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzdELG1CQUFtQixFQUFFLFFBQVEsQ0FBQyxtQkFBbUI7WUFDakQsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjO1lBQ25ELE9BQU8sRUFBRSxPQUFPLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUM7U0FDN0MsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxhQUFzQixDQUFDO1FBQzNCLElBQUksQ0FBQztZQUNILElBQUksTUFBTSxDQUFDLFVBQVUsR0FBRyxjQUFjO2dCQUFFLElBQUksQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1lBQ3RHLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDbkUsQ0FBQztnQkFDTyxDQUFDO1lBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUFDLENBQUM7UUFDM0IsY0FBYyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkUsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDO1FBQy9CLElBQUksUUFBUSxDQUFDLGNBQWMsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWM7ZUFDdEQsUUFBUSxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsV0FBVyxJQUFJLFFBQVEsQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLGNBQWM7ZUFDbEYsUUFBUSxDQUFDLGNBQWMsS0FBSyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdEQsSUFBSSxDQUFDLHNFQUFzRSxDQUFDLENBQUM7UUFDL0UsQ0FBQztRQUNELE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUF3RSxDQUFDO1FBQ3BHLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3hDLE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN6RCxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMxQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDOUIsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDL0IsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDOUMsTUFBTSxhQUFhLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDN0IsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDekQsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvRCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9ELElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNwQixJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFDcEIsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLElBQUksbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNqQixJQUFJLGNBQWMsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBSSxhQUFhLEdBQUcsS0FBSyxDQUFDO1FBQzFCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQztRQUNsQixNQUFNLE9BQU8sR0FBRyxLQUFLLFNBQVMsQ0FBQztZQUM3QixLQUFLLE1BQU0sS0FBSyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLENBQUM7Z0JBQ3RDLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDOUcsSUFBSSxjQUFjLENBQUMsVUFBVSxLQUFLLEtBQUssQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDakcsSUFBSSxDQUFDLGlFQUFpRSxDQUFDLENBQUM7Z0JBQzFFLENBQUM7Z0JBQ0QsTUFBTSxTQUFTLEdBQUcsTUFBTSxPQUFPLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDO29CQUM3RCxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDbEUsbUJBQW1CLEVBQUUsUUFBUSxDQUFDLG1CQUFtQjtvQkFDakQsc0JBQXNCLEVBQUUsUUFBUSxDQUFDLGNBQWM7b0JBQy9DLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsUUFBUSxFQUM1RSxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxlQUFlLENBQUM7aUJBQ3pDLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUM7b0JBQ0gsSUFBSSxTQUFTLENBQUMsVUFBVSxHQUFHLGtCQUFrQixJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7d0JBQzNGLElBQUksQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO29CQUMzRCxDQUFDO29CQUNELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7d0JBQUUsSUFBSSxDQUFDLDRDQUE0QyxDQUFDLENBQUM7b0JBQ25GLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNsRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLE9BQU87d0JBQUUsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7b0JBQzlFLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ2hDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7d0JBQ3pCLE1BQU0sS0FBSyxHQUFZLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDOzRCQUFFLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO3dCQUNsRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7NEJBQzVCLElBQUksY0FBYztnQ0FBRSxJQUFJLENBQUMsb0RBQW9ELENBQUMsQ0FBQzs0QkFDL0UsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQzttQ0FDbkQsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7bUNBQ3JELENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQzttQ0FDdkMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLE9BQU8sS0FBSyxDQUFDLE9BQU8sS0FBSyxRQUFRLEVBQUUsQ0FBQztnQ0FDdEUsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7NEJBQy9DLENBQUM7NEJBQ0QsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDOzRCQUN0RCxJQUFJLEtBQUssQ0FBQyxVQUFVLEdBQUcsY0FBYyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLENBQUMsWUFBWSxFQUFFLENBQUM7Z0NBQzVFLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDOzRCQUMvQyxDQUFDOzRCQUNELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7NEJBQzVDLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsVUFBVSxJQUFJLEtBQUssQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLFFBQVE7bUNBQ3ZFLEtBQUssQ0FBQyxXQUFXLEtBQUssS0FBSyxDQUFDLFdBQVcsSUFBSSxLQUFLLENBQUMsUUFBUSxLQUFLLEtBQUssQ0FBQyxRQUFRO21DQUM1RSxLQUFLLENBQUMsaUJBQWlCLEtBQUssS0FBSyxDQUFDLGlCQUFpQjttQ0FDbkQsS0FBSyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsWUFBWTtnQ0FBRSxJQUFJLENBQUMsaURBQWlELENBQUMsQ0FBQzs0QkFDbEcsV0FBVyxFQUFFLENBQUM7NEJBQ2QsTUFBTSxRQUFRLEdBQTZCLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7Z0NBQ3ZGLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtnQ0FDbEYsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQixFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWSxFQUFFLEtBQUssRUFBRSxDQUFDOzRCQUN4RixrQkFBa0IsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRyxRQUFRO2dDQUNuRCxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDOzRCQUM3RCxtQkFBbUIsRUFBRSxDQUFDOzRCQUN0QixNQUFNLFFBQVEsQ0FBQzt3QkFDakIsQ0FBQzs2QkFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7NEJBQ25DLGNBQWMsR0FBRyxJQUFJLENBQUM7NEJBQ3RCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO21DQUNoRSxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0NBQ2hHLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDOzRCQUN2QyxDQUFDOzRCQUNELE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQzs0QkFDN0MsSUFBSSxHQUFHLElBQUksT0FBTztnQ0FBRSxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQzs0QkFDekQsT0FBTyxHQUFHLEdBQUcsQ0FBQzs0QkFBQyxXQUFXLEVBQUUsQ0FBQzs0QkFDN0IsTUFBTSxjQUFjLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDOzRCQUNoRixvQkFBb0IsQ0FBQyxjQUFjLENBQUMsQ0FBQzs0QkFDckMsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7NEJBQzFDLEtBQUssTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQ0FDdEMsSUFBSSxJQUFJLENBQUMsb0JBQW9CLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQ0FDeEYsSUFBSSxDQUFDLHNFQUFzRSxDQUFDLENBQUM7Z0NBQy9FLENBQUM7Z0NBQ0QsbUJBQW1CLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDOzRCQUNqQyxDQUFDOzRCQUNELElBQUksQ0FBQyxrQ0FBa0MsQ0FBQyxjQUFjLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDOzRCQUN4RixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUU7Z0NBQzFFLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsQ0FBQzs0QkFDckQsSUFBSSxRQUFRLEVBQUUsQ0FBQztnQ0FDYixrQkFBa0IsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO2dDQUFDLGFBQWEsRUFBRSxDQUFDO2dDQUMzRSxNQUFNLFFBQVEsQ0FBQzs0QkFDakIsQ0FBQzt3QkFDSCxDQUFDOzs0QkFBTSxJQUFJLENBQUMsNEJBQTRCLENBQUMsQ0FBQztvQkFDNUMsQ0FBQztnQkFDSCxDQUFDO3dCQUFTLENBQUM7b0JBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFBQyxDQUFDO1lBQ2xDLENBQUM7WUFDRCxJQUFJLG1CQUFtQixDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN6RCxJQUFJLENBQUMsNkRBQTZELENBQUMsQ0FBQztZQUN0RSxDQUFDO1lBQ0QsSUFBSSxXQUFXLEtBQUssUUFBUSxDQUFDLFdBQVcsSUFBSSxXQUFXLEtBQUssUUFBUSxDQUFDLE9BQU8sQ0FBQyxNQUFNO21CQUM5RSxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDNUQsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7WUFDbkQsQ0FBQztZQUNELGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDdkIsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxRQUFRLEdBQUcsTUFBTSxRQUFRLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ25FLElBQUksZUFBbUMsQ0FBQztRQUN4QyxJQUFJLG1CQUE0QixDQUFDO1FBQ2pDLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxhQUFhO2dCQUFFLElBQUksQ0FBQyx3REFBd0QsQ0FBQyxDQUFDO1lBQ25GLE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0QsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM3RCxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7WUFDcEIsSUFBSSxpQkFBaUIsR0FBRyxDQUFDLENBQUM7WUFDMUIsSUFBSSxhQUFhLEdBQUcsRUFBRSxDQUFDO1lBQ3ZCLElBQUksS0FBSyxFQUFFLE1BQU0sTUFBTSxJQUFJLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7dUJBQ25FLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLE1BQU0sQ0FBQyxFQUFFO29CQUFFLElBQUksQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO2dCQUMzRixNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQy9DLElBQUksR0FBRyxJQUFJLGFBQWE7b0JBQUUsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7Z0JBQ3BFLGFBQWEsR0FBRyxHQUFHLENBQUM7Z0JBQ3BCLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7Z0JBQUMsV0FBVyxFQUFFLENBQUM7WUFDdkUsQ0FBQztZQUNELElBQUksS0FBSyxFQUFFLE1BQU0sTUFBTSxJQUFJLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDNUMsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDO3VCQUN2RCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLE1BQU0sQ0FBQyxZQUFZO29CQUFFLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO2dCQUM1RixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRyxNQUFNO29CQUMvQyxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztnQkFDcEUsaUJBQWlCLEVBQUUsQ0FBQztZQUN0QixDQUFDO1lBQ0QsTUFBTSxvQkFBb0IsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDOUQsTUFBTSxvQkFBb0IsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDOUQsSUFBSSxXQUFXLEtBQUssYUFBYSxJQUFJLGlCQUFpQixLQUFLLG1CQUFtQjttQkFDekUsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLG9CQUFvQjttQkFDdkQsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLG9CQUFvQixFQUFFLENBQUM7Z0JBQzdELElBQUksQ0FBQyw2REFBNkQsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7WUFDRCxlQUFlLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxvQkFBb0IsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLG1CQUFtQixHQUFHLEtBQUssQ0FBQztRQUM5QixDQUFDO1FBQ0QsSUFBSSxZQUFxQixDQUFDO1FBQzFCLHFHQUFxRztRQUNyRyxJQUFJLENBQUM7WUFBQyxNQUFNLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUFDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUFDLENBQUM7UUFDdkUsSUFBSSxtQkFBbUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUN4QyxNQUFNLElBQUksY0FBYyxDQUFDLENBQUMsbUJBQW1CLEVBQUUsWUFBWSxDQUFDLEVBQzFELHlEQUF5RCxDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUNELElBQUksbUJBQW1CO1lBQUUsTUFBTSxtQkFBbUIsQ0FBQztRQUNuRCxJQUFJLFlBQVk7WUFBRSxNQUFNLFlBQVksQ0FBQztRQUNyQyxJQUFJLENBQUMsZUFBZTtZQUFFLElBQUksQ0FBQyw4REFBOEQsQ0FBQyxDQUFDO1FBQzNGLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLFlBQVk7WUFDcEUsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjLEVBQUUsY0FBYyxFQUFFLFFBQVEsQ0FBQyxjQUFjLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxLQUFLO1lBQzFHLGNBQWMsRUFBRSxRQUFRLENBQUMsUUFBUSxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsUUFBUSxDQUFDLFdBQVc7WUFDbkYsT0FBTyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtZQUNoRixnQkFBZ0IsRUFBRSxnREFBZ0QsRUFBRSxDQUFDO0lBQ3pFLENBQUM7SUFFTyxLQUFLLENBQUMsYUFBYSxDQUFDLE1BQThCLEVBQUUsTUFBcUIsRUFDL0UsYUFBcUI7UUFDckIsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztZQUFFLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQzFELG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdCLElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyw2QkFBNkI7WUFBRSxPQUFPLElBQUksQ0FBQztRQUNoRSxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssNEJBQTRCO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDL0QsSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLDJCQUEyQixFQUFFLENBQUM7WUFDakQseUJBQXlCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakMsTUFBTSxRQUFRLEdBQXlCLEVBQUUsR0FBRyxLQUFLLEVBQUUsU0FBUyxFQUFFLGlCQUFpQjtnQkFDN0UsS0FBSyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ3hELE9BQU8sRUFBRSxHQUFHLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUM7UUFDeEMsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyw2QkFBNkIsRUFBRSxDQUFDO1lBQ25ELDBCQUEwQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQztnQkFBRSxJQUFJLENBQUMsdUNBQXVDLENBQUMsQ0FBQztZQUNyRyxJQUFJLEtBQUssQ0FBQyxLQUFLLEtBQUssU0FBUztnQkFBRSxPQUFPLE1BQU0sQ0FBQztZQUM3QyxNQUFNLE1BQU0sR0FBRyxDQUFDLG9CQUFvQixFQUFFLGlCQUFpQixDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNqRixNQUFNLFFBQVEsR0FBMEIsRUFBRSxHQUFHLEtBQUs7Z0JBQ2hELEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxjQUFjO2dCQUN4RCxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxJQUFJO2dCQUNuRixTQUFTLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLENBQUM7Z0JBQzdDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CO2dCQUN2RCxlQUFlLEVBQUUsS0FBSyxDQUFDLGVBQWUsR0FBRyxDQUFDO2dCQUMxQyx1QkFBdUIsRUFBRSxLQUFLLENBQUMsdUJBQXVCLEdBQUcsQ0FBQztnQkFDMUQsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUM7WUFDL0YsMEJBQTBCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckMsT0FBTyxFQUFFLEdBQUcsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQztRQUN4QyxDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLCtCQUErQixFQUFFLENBQUM7WUFDckQsNEJBQTRCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEMsTUFBTSxRQUFRLEdBQTRCLEVBQUUsR0FBRyxLQUFLO2dCQUNsRCxjQUFjLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQztnQkFDbEYsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUM7WUFDckIsT0FBTyxFQUFFLEdBQUcsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQztRQUN4QyxDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLGtDQUFrQyxFQUFFLENBQUM7WUFDeEQsK0JBQStCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkMsSUFBSSxNQUFNLEtBQUssSUFBSTtnQkFBRSxJQUFJLENBQUMseUNBQXlDLENBQUMsQ0FBQztZQUNyRSxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztZQUNuRCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxHQUFHLEdBQUcsZUFBZSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2pELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ3BFLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ25FLElBQUksQ0FBQztvQkFDSCxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDO3dCQUFFLElBQUksQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO2dCQUNsSCxDQUFDO3dCQUFTLENBQUM7b0JBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFBQyxDQUFDO2dCQUM3QixNQUFNLFFBQVEsR0FBK0IsRUFBRSxHQUFHLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTTtvQkFDekUsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUNuRCwrQkFBK0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDMUMsSUFBSSxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxRQUFRLENBQUMsRUFBRTtvQkFBRSxJQUFJLENBQUMsK0NBQStDLENBQUMsQ0FBQztnQkFDdEcsT0FBTyxFQUFFLEdBQUcsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQztZQUN4QyxDQUFDO29CQUFTLENBQUM7Z0JBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUFDLENBQUM7UUFDbEMsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyxrQ0FBa0MsRUFBRSxDQUFDO1lBQ3hELDhCQUE4QixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3RDLE1BQU0sUUFBUSxHQUE4QixFQUFFLEdBQUcsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUM7WUFDNUYsT0FBTyxFQUFFLEdBQUcsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQztRQUN4QyxDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFLLG1DQUFtQyxFQUFFLENBQUM7WUFDekQsTUFBTSxRQUFRLEdBQUcsRUFBRSxHQUFHLEtBQUssRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLGtCQUFrQixFQUFFLElBQUksRUFBRTtnQkFDNUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQzNELCtCQUErQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzFDLE9BQU8sRUFBRSxHQUFHLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUM7UUFDeEMsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyxzQ0FBc0MsRUFBRSxDQUFDO1lBQzVELE1BQU0sUUFBUSxHQUFHLEVBQUUsR0FBRyxLQUFLLEVBQUUsS0FBSyxFQUFFLGFBQWE7Z0JBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsSUFBSTtnQkFDakQsUUFBUSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQzNELGtDQUFrQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzdDLE9BQU8sRUFBRSxHQUFHLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUM7UUFDeEMsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLEtBQUssS0FBSywrQkFBK0IsRUFBRSxDQUFDO1lBQ3JELE1BQU0sUUFBUSxHQUFHLEVBQUUsR0FBRyxLQUFLLEVBQUUsS0FBSyxFQUFFLGNBQWM7Z0JBQ2hELFlBQVksRUFBRSxJQUFJLEVBQUUsb0JBQW9CLEVBQUUsSUFBSTtnQkFDOUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQzNELDRCQUE0QixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZDLE9BQU8sRUFBRSxHQUFHLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUM7UUFDeEMsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyx1Q0FBdUMsRUFBRSxDQUFDO1lBQzdELE1BQU0sUUFBUSxHQUFHLEVBQUUsR0FBRyxLQUFLLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsSUFBSTtnQkFDakUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQzNELG9DQUFvQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQy9DLE9BQU8sRUFBRSxHQUFHLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUM7UUFDeEMsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyxpQ0FBaUMsRUFBRSxDQUFDO1lBQ3ZELElBQUksTUFBTSxLQUFLLElBQUk7Z0JBQUUsSUFBSSxDQUFDLG1EQUFtRCxDQUFDLENBQUM7WUFDL0UsOEJBQThCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEMsTUFBTSxRQUFRLEdBQUcsK0JBQStCLENBQUMsS0FBSyxFQUNwRCxFQUFFLFVBQVUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDOUQsT0FBTyxRQUFRLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDO1FBQ3RFLENBQUM7UUFDRCxJQUFJLE1BQU0sS0FBSyxJQUFJO1lBQUUsSUFBSSxDQUFDLGdEQUFnRCxDQUFDLENBQUM7UUFDNUUsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztDQUNGIn0=
|