@serve.zone/interfaces 32.12.0 → 32.14.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.
@@ -0,0 +1,1021 @@
1
+ import { snapshotClusterRuntimeReference } from './clusterruntime.js';
2
+ import { canonicalizeStrictJson, createCanonicalJsonSha256Hex, } from '../private/canonicaljson.js';
3
+ import { captureNetwork, networkCounter, networkDigest, networkId, networkList, networkNodeId, networkRecord, networkReference, networkSorted, requireNetwork, } from '../private/networkcontract.js';
4
+ export const fleetCutoverContract = Object.freeze({
5
+ maximumServices: 512,
6
+ maximumTasks: 4096,
7
+ maximumNodes: 1024,
8
+ maximumContainersPerNode: 512,
9
+ maximumMountsPerOwner: 32,
10
+ maximumClassifications: 512,
11
+ observationFreshnessMs: 300_000,
12
+ mountSourceIdentityDigestDomain: 'serve.zone/fleet-cutover-mount-source-identity',
13
+ mountTargetIdentityDigestDomain: 'serve.zone/fleet-cutover-mount-target-identity',
14
+ mountIdentityDigestDomain: 'serve.zone/fleet-cutover-mount-identity',
15
+ containerSetIdentityDigestDomain: 'serve.zone/fleet-cutover-container-set-identity',
16
+ localNodeSnapshotDigestDomain: 'serve.zone/fleet-cutover-local-node-snapshot',
17
+ managerSnapshotDigestDomain: 'serve.zone/fleet-cutover-manager-snapshot',
18
+ censusDigestDomain: 'serve.zone/fleet-cutover-census',
19
+ scopeDigestDomain: 'serve.zone/fleet-cutover-scope',
20
+ volumeHandoffDigestDomain: 'serve.zone/fleet-cutover-volume-handoff',
21
+ volumeFenceDigestDomain: 'serve.zone/fleet-cutover-volume-fence',
22
+ corestoreAdoptionDigestDomain: 'serve.zone/fleet-cutover-corestore-adoption',
23
+ coreflowRetirementDigestDomain: 'serve.zone/fleet-cutover-coreflow-retirement',
24
+ ingressDesignationDigestDomain: 'serve.zone/fleet-cutover-ingress-designation',
25
+ ingressAuthorityDigestDomain: 'serve.zone/fleet-cutover-ingress-authority',
26
+ legalPhaseTransitions: Object.freeze({
27
+ swarm: 'draining',
28
+ draining: 'switching',
29
+ switching: 'pallet',
30
+ pallet: null,
31
+ }),
32
+ });
33
+ const fail = () => { throw new Error('Fleet cutover contract rejected.'); };
34
+ const safe = (operationArg) => {
35
+ try {
36
+ return operationArg();
37
+ }
38
+ catch {
39
+ return fail();
40
+ }
41
+ };
42
+ const nonNegative = (valueArg) => {
43
+ requireNetwork(Number.isSafeInteger(valueArg) && valueArg >= 0);
44
+ return valueArg;
45
+ };
46
+ const literal = (valuesArg, valueArg) => {
47
+ requireNetwork(valuesArg.includes(valueArg));
48
+ return valueArg;
49
+ };
50
+ const sha256Hex = (valueArg) => {
51
+ requireNetwork(typeof valueArg === 'string' && /^[a-f0-9]{64}$/.test(valueArg));
52
+ return valueArg;
53
+ };
54
+ const releaseVersion = (valueArg) => {
55
+ requireNetwork(typeof valueArg === 'string'
56
+ && /^(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)$/.test(valueArg)
57
+ && valueArg.length <= 32);
58
+ return valueArg;
59
+ };
60
+ const reference = (valueArg) => networkReference(valueArg);
61
+ const targetSetReference = (valueArg) => {
62
+ const value = networkRecord(valueArg, ['cloudlyClusterId', 'generation', 'targetSetDigest']);
63
+ return {
64
+ cloudlyClusterId: networkId(value.cloudlyClusterId),
65
+ generation: networkCounter(value.generation),
66
+ targetSetDigest: networkDigest(value.targetSetDigest),
67
+ };
68
+ };
69
+ const runtimeReference = (valueArg) => snapshotClusterRuntimeReference(valueArg);
70
+ const assignmentReference = (valueArg) => {
71
+ const value = networkRecord(valueArg, ['assignmentId', 'generation', 'digest']);
72
+ return {
73
+ assignmentId: networkId(value.assignmentId),
74
+ generation: networkCounter(value.generation),
75
+ digest: networkDigest(value.digest),
76
+ };
77
+ };
78
+ const ingressCredentialReference = (valueArg) => {
79
+ const value = networkRecord(valueArg, ['credentialId', 'generation', 'secretVersion']);
80
+ const secretVersion = networkRecord(value.secretVersion, ['secretId', 'secretVersionId']);
81
+ return {
82
+ credentialId: networkId(value.credentialId),
83
+ generation: networkCounter(value.generation),
84
+ secretVersion: {
85
+ secretId: networkId(secretVersion.secretId),
86
+ secretVersionId: networkId(secretVersion.secretVersionId),
87
+ },
88
+ };
89
+ };
90
+ const mountTypeAndClassification = (typeArg, classificationArg) => {
91
+ const type = literal(['volume', 'bind', 'tmpfs', 'unknown'], typeArg);
92
+ const classification = literal([
93
+ 'docker-socket', 'cgroup', 'persistent-volume', 'bind', 'tmpfs', 'other', 'unknown',
94
+ ], classificationArg);
95
+ requireNetwork((type === 'volume' && ['persistent-volume', 'other', 'unknown'].includes(classification))
96
+ || (type === 'bind' && ['docker-socket', 'cgroup', 'bind', 'other', 'unknown'].includes(classification))
97
+ || (type === 'tmpfs' && ['tmpfs', 'other', 'unknown'].includes(classification))
98
+ || (type === 'unknown' && classification === 'unknown'));
99
+ return { type, classification };
100
+ };
101
+ const mountDescriptor = (valueArg) => {
102
+ const value = networkRecord(valueArg, [
103
+ 'type', 'classification', 'sourceIdentityDigest', 'targetIdentityDigest', 'readOnly',
104
+ 'mountIdentityDigest',
105
+ ]);
106
+ requireNetwork(typeof value.readOnly === 'boolean');
107
+ const shape = mountTypeAndClassification(value.type, value.classification);
108
+ return {
109
+ ...shape,
110
+ sourceIdentityDigest: networkDigest(value.sourceIdentityDigest),
111
+ targetIdentityDigest: networkDigest(value.targetIdentityDigest),
112
+ readOnly: value.readOnly,
113
+ mountIdentityDigest: networkDigest(value.mountIdentityDigest),
114
+ };
115
+ };
116
+ const sortedMountDescriptors = (valueArg) => networkSorted(networkList(valueArg, fleetCutoverContract.maximumMountsPerOwner, mountDescriptor), itemArg => itemArg.mountIdentityDigest);
117
+ const dockerMode = (valueArg) => {
118
+ requireNetwork(valueArg !== null && typeof valueArg === 'object');
119
+ const kind = valueArg.kind;
120
+ if (kind === 'global') {
121
+ networkRecord(valueArg, ['kind']);
122
+ return { kind };
123
+ }
124
+ const value = networkRecord(valueArg, ['kind', 'replicas']);
125
+ requireNetwork(kind === 'replicated');
126
+ return { kind, replicas: nonNegative(value.replicas) };
127
+ };
128
+ const ownershipLabels = (valueArg) => {
129
+ const value = networkRecord(valueArg, ['serviceId', 'platformOwner']);
130
+ const serviceId = value.serviceId === null ? null : networkId(value.serviceId);
131
+ const platformOwner = value.platformOwner === null ? null : literal([
132
+ 'coreflow', 'corestore', 'coretraffic',
133
+ ], value.platformOwner);
134
+ return { serviceId, platformOwner };
135
+ };
136
+ const dockerService = (valueArg) => {
137
+ const value = networkRecord(valueArg, [
138
+ 'dockerServiceId', 'dockerServiceName', 'specVersion', 'specDigest', 'imageDigest', 'mode',
139
+ 'desiredTaskCount', 'constraintCount', 'constraintSetDigest', 'mounts', 'ownershipLabels',
140
+ ]);
141
+ return {
142
+ dockerServiceId: networkId(value.dockerServiceId),
143
+ dockerServiceName: networkId(value.dockerServiceName),
144
+ specVersion: networkCounter(value.specVersion),
145
+ specDigest: networkDigest(value.specDigest),
146
+ imageDigest: networkDigest(value.imageDigest),
147
+ mode: dockerMode(value.mode),
148
+ desiredTaskCount: nonNegative(value.desiredTaskCount),
149
+ constraintCount: nonNegative(value.constraintCount),
150
+ constraintSetDigest: networkDigest(value.constraintSetDigest),
151
+ mounts: sortedMountDescriptors(value.mounts),
152
+ ownershipLabels: ownershipLabels(value.ownershipLabels),
153
+ };
154
+ };
155
+ const dockerTask = (valueArg) => {
156
+ const value = networkRecord(valueArg, [
157
+ 'dockerTaskId', 'dockerServiceId', 'swarmNodeId', 'nodeName', 'desiredState', 'state', 'container',
158
+ ]);
159
+ let container = null;
160
+ if (value.container !== null) {
161
+ const containerValue = networkRecord(value.container, ['dockerContainerId']);
162
+ container = {
163
+ dockerContainerId: networkId(containerValue.dockerContainerId),
164
+ };
165
+ }
166
+ const swarmNodeId = value.swarmNodeId === null ? null : networkId(value.swarmNodeId);
167
+ const nodeName = value.nodeName === null ? null : networkId(value.nodeName);
168
+ requireNetwork((swarmNodeId === null) === (nodeName === null));
169
+ const taskStates = [
170
+ 'new', 'allocated', 'pending', 'assigned', 'accepted', 'preparing', 'ready', 'starting',
171
+ 'running', 'complete', 'shutdown', 'failed', 'rejected', 'remove', 'orphaned',
172
+ ];
173
+ return {
174
+ dockerTaskId: networkId(value.dockerTaskId),
175
+ dockerServiceId: networkId(value.dockerServiceId),
176
+ swarmNodeId,
177
+ nodeName,
178
+ desiredState: literal(taskStates, value.desiredState),
179
+ state: literal(taskStates, value.state),
180
+ container,
181
+ };
182
+ };
183
+ const physicalContainer = (valueArg) => {
184
+ const value = networkRecord(valueArg, [
185
+ 'dockerContainerId', 'dockerServiceId', 'dockerTaskId', 'imageId', 'serviceIdLabel', 'mounts',
186
+ ]);
187
+ return {
188
+ dockerContainerId: networkId(value.dockerContainerId),
189
+ dockerServiceId: value.dockerServiceId === null ? null : networkId(value.dockerServiceId),
190
+ dockerTaskId: value.dockerTaskId === null ? null : networkId(value.dockerTaskId),
191
+ imageId: networkDigest(value.imageId),
192
+ serviceIdLabel: value.serviceIdLabel === null ? null : networkId(value.serviceIdLabel),
193
+ mounts: sortedMountDescriptors(value.mounts),
194
+ };
195
+ };
196
+ const inventory = (valueArg) => {
197
+ const value = networkRecord(valueArg, [
198
+ 'swarmClusterId', 'managerSwarmNodeId', 'services', 'tasks',
199
+ ]);
200
+ const services = networkSorted(networkList(value.services, fleetCutoverContract.maximumServices, dockerService), itemArg => itemArg.dockerServiceId);
201
+ const serviceIds = new Set(services.map(itemArg => itemArg.dockerServiceId));
202
+ const tasks = networkSorted(networkList(value.tasks, fleetCutoverContract.maximumTasks, dockerTask), itemArg => `${itemArg.dockerServiceId}\0${itemArg.dockerTaskId}`);
203
+ requireNetwork(tasks.every(itemArg => serviceIds.has(itemArg.dockerServiceId)));
204
+ return {
205
+ swarmClusterId: networkId(value.swarmClusterId),
206
+ managerSwarmNodeId: networkId(value.managerSwarmNodeId),
207
+ services,
208
+ tasks,
209
+ };
210
+ };
211
+ const observationReference = (valueArg) => {
212
+ const value = networkRecord(valueArg, [
213
+ 'observation', 'nodeId', 'swarmNodeId', 'credentialGeneration', 'reporterSessionId',
214
+ 'observationSequence', 'observedAt', 'acceptedAt', 'freshUntil', 'observationDigest',
215
+ 'snapshotDigest',
216
+ ]);
217
+ const result = {
218
+ observation: reference(value.observation),
219
+ nodeId: networkNodeId(value.nodeId),
220
+ swarmNodeId: networkId(value.swarmNodeId),
221
+ credentialGeneration: networkCounter(value.credentialGeneration),
222
+ reporterSessionId: networkId(value.reporterSessionId),
223
+ observationSequence: networkCounter(value.observationSequence),
224
+ observedAt: networkCounter(value.observedAt),
225
+ acceptedAt: networkCounter(value.acceptedAt),
226
+ freshUntil: networkCounter(value.freshUntil),
227
+ observationDigest: networkDigest(value.observationDigest),
228
+ snapshotDigest: networkDigest(value.snapshotDigest),
229
+ };
230
+ requireNetwork(result.acceptedAt >= result.observedAt
231
+ && result.acceptedAt <= result.freshUntil
232
+ && result.freshUntil === result.observedAt + fleetCutoverContract.observationFreshnessMs);
233
+ return result;
234
+ };
235
+ const managerCensusRead = (valueArg) => {
236
+ const value = networkRecord(valueArg, [
237
+ 'observation', 'nodeId', 'swarmNodeId', 'credentialGeneration', 'reporterSessionId',
238
+ 'observationSequence', 'observedAt', 'acceptedAt', 'freshUntil', 'observationDigest',
239
+ 'snapshotDigest', 'swarmSnapshotDigest', 'inventoryDigest',
240
+ ]);
241
+ return {
242
+ ...observationReference({
243
+ observation: value.observation,
244
+ nodeId: value.nodeId,
245
+ swarmNodeId: value.swarmNodeId,
246
+ credentialGeneration: value.credentialGeneration,
247
+ reporterSessionId: value.reporterSessionId,
248
+ observationSequence: value.observationSequence,
249
+ observedAt: value.observedAt,
250
+ acceptedAt: value.acceptedAt,
251
+ freshUntil: value.freshUntil,
252
+ observationDigest: value.observationDigest,
253
+ snapshotDigest: value.snapshotDigest,
254
+ }),
255
+ swarmSnapshotDigest: networkDigest(value.swarmSnapshotDigest),
256
+ inventoryDigest: networkDigest(value.inventoryDigest),
257
+ };
258
+ };
259
+ const canonicalDigest = async (domainArg, valueArg) => {
260
+ const { digest: _digest, ...payload } = valueArg;
261
+ return `sha256:${await createCanonicalJsonSha256Hex(canonicalizeStrictJson({
262
+ domain: domainArg,
263
+ payload,
264
+ }, fail), fail)}`;
265
+ };
266
+ const exactDockerText = (valueArg, allowEmptyArg) => {
267
+ requireNetwork(typeof valueArg === 'string'
268
+ && new TextEncoder().encode(valueArg).length <= 4096
269
+ && (allowEmptyArg || valueArg.length > 0));
270
+ return valueArg;
271
+ };
272
+ const computeExactIdentityDigest = async (domainArg, inputArg) => `sha256:${await createCanonicalJsonSha256Hex(canonicalizeStrictJson({
273
+ domain: domainArg,
274
+ input: inputArg,
275
+ }, fail), fail)}`;
276
+ export const computeFleetCutoverMountSourceIdentityDigest = async (valueArg) => safe(async () => {
277
+ const value = networkRecord(valueArg, ['type', 'source']);
278
+ return computeExactIdentityDigest(fleetCutoverContract.mountSourceIdentityDigestDomain, {
279
+ type: literal(['volume', 'bind', 'tmpfs', 'unknown'], value.type),
280
+ source: exactDockerText(value.source, true),
281
+ });
282
+ });
283
+ export const computeFleetCutoverMountTargetIdentityDigest = async (valueArg) => safe(async () => {
284
+ const value = networkRecord(valueArg, ['target']);
285
+ return computeExactIdentityDigest(fleetCutoverContract.mountTargetIdentityDigestDomain, {
286
+ target: exactDockerText(value.target, false),
287
+ });
288
+ });
289
+ export const computeFleetCutoverMountIdentityDigest = async (valueArg) => safe(async () => {
290
+ const value = networkRecord(valueArg, [
291
+ 'type', 'classification', 'sourceIdentityDigest', 'targetIdentityDigest', 'readOnly',
292
+ ]);
293
+ requireNetwork(typeof value.readOnly === 'boolean');
294
+ const shape = mountTypeAndClassification(value.type, value.classification);
295
+ return computeExactIdentityDigest(fleetCutoverContract.mountIdentityDigestDomain, {
296
+ ...shape,
297
+ sourceIdentityDigest: networkDigest(value.sourceIdentityDigest),
298
+ targetIdentityDigest: networkDigest(value.targetIdentityDigest),
299
+ readOnly: value.readOnly,
300
+ });
301
+ });
302
+ const validateMountDescriptors = async (mountsArg) => {
303
+ for (const mount of mountsArg) {
304
+ const { mountIdentityDigest, ...input } = mount;
305
+ requireNetwork(mountIdentityDigest === await computeFleetCutoverMountIdentityDigest(input));
306
+ }
307
+ };
308
+ export const computeFleetCutoverContainerSetIdentityDigest = async (containerIdsArg) => safe(async () => {
309
+ const containerIds = networkSorted(networkList(containerIdsArg, fleetCutoverContract.maximumContainersPerNode, networkId), itemArg => itemArg);
310
+ return computeExactIdentityDigest(fleetCutoverContract.containerSetIdentityDigestDomain, {
311
+ containerIds,
312
+ });
313
+ });
314
+ const containerSetIdentity = (valueArg) => {
315
+ const value = networkRecord(valueArg, ['containerCount', 'containerIdsDigest']);
316
+ return {
317
+ containerCount: nonNegative(value.containerCount),
318
+ containerIdsDigest: networkDigest(value.containerIdsDigest),
319
+ };
320
+ };
321
+ export const snapshotFleetCutoverLocalNodeSnapshot = (valueArg) => safe(() => {
322
+ const value = networkRecord(captureNetwork(valueArg), [
323
+ 'swarmNodeId', 'before', 'containers', 'after', 'snapshotDigest',
324
+ ]);
325
+ const containers = networkSorted(networkList(value.containers, fleetCutoverContract.maximumContainersPerNode, physicalContainer), itemArg => itemArg.dockerContainerId);
326
+ const before = containerSetIdentity(value.before);
327
+ const after = containerSetIdentity(value.after);
328
+ requireNetwork(before.containerCount === containers.length
329
+ && after.containerCount === containers.length
330
+ && before.containerIdsDigest === after.containerIdsDigest);
331
+ return {
332
+ swarmNodeId: networkId(value.swarmNodeId),
333
+ before,
334
+ containers,
335
+ after,
336
+ snapshotDigest: networkDigest(value.snapshotDigest),
337
+ };
338
+ });
339
+ export const computeFleetCutoverLocalNodeSnapshotDigest = async (valueArg) => safe(async () => {
340
+ const value = snapshotFleetCutoverLocalNodeSnapshot(valueArg);
341
+ const { snapshotDigest: _omitted, ...input } = value;
342
+ return computeExactIdentityDigest(fleetCutoverContract.localNodeSnapshotDigestDomain, input);
343
+ });
344
+ export const validateFleetCutoverLocalNodeSnapshot = async (valueArg) => {
345
+ try {
346
+ const value = snapshotFleetCutoverLocalNodeSnapshot(valueArg);
347
+ const containerIdsDigest = await computeFleetCutoverContainerSetIdentityDigest(value.containers.map(itemArg => itemArg.dockerContainerId));
348
+ requireNetwork(value.before.containerIdsDigest === containerIdsDigest
349
+ && value.after.containerIdsDigest === containerIdsDigest);
350
+ for (const container of value.containers)
351
+ await validateMountDescriptors(container.mounts);
352
+ return value.snapshotDigest === await computeFleetCutoverLocalNodeSnapshotDigest(value)
353
+ ? [] : ['fleet cutover local node snapshot digest does not match'];
354
+ }
355
+ catch {
356
+ return ['fleet cutover local node snapshot must use its exact canonical schema'];
357
+ }
358
+ };
359
+ export const computeFleetCutoverInventoryDigest = async (valueArg) => safe(async () => {
360
+ const hex = await createCanonicalJsonSha256Hex(canonicalizeStrictJson({
361
+ domain: 'serve.zone/fleet-cutover-inventory',
362
+ inventory: inventory(captureNetwork(valueArg)),
363
+ }, fail), fail);
364
+ return `sha256:${hex}`;
365
+ });
366
+ export const snapshotFleetCutoverManagerSnapshot = async (valueArg) => safe(async () => {
367
+ const value = networkRecord(captureNetwork(valueArg), ['inventory', 'inventoryDigest']);
368
+ const inventoryValue = inventory(value.inventory);
369
+ const inventoryDigest = networkDigest(value.inventoryDigest);
370
+ requireNetwork(inventoryDigest === await computeFleetCutoverInventoryDigest(inventoryValue));
371
+ for (const service of inventoryValue.services)
372
+ await validateMountDescriptors(service.mounts);
373
+ return { inventory: inventoryValue, inventoryDigest };
374
+ });
375
+ export const computeFleetCutoverManagerSnapshotDigest = async (valueArg) => computeExactIdentityDigest(fleetCutoverContract.managerSnapshotDigestDomain, await snapshotFleetCutoverManagerSnapshot(valueArg));
376
+ export const validateFleetCutoverManagerSnapshot = async (valueArg) => {
377
+ try {
378
+ await snapshotFleetCutoverManagerSnapshot(valueArg);
379
+ return [];
380
+ }
381
+ catch {
382
+ return ['fleet cutover manager snapshot must use its exact canonical schema'];
383
+ }
384
+ };
385
+ export const snapshotFleetCutoverCensusCandidate = async (valueArg) => safe(async () => {
386
+ const value = networkRecord(captureNetwork(valueArg), [
387
+ 'clusterId', 'runtime', 'targetSet', 'inventory', 'managerReads', 'nodeObservations',
388
+ 'freshUntil',
389
+ ]);
390
+ const clusterId = networkId(value.clusterId);
391
+ const runtime = runtimeReference(value.runtime);
392
+ const targetSet = targetSetReference(value.targetSet);
393
+ const inventoryValue = inventory(value.inventory);
394
+ for (const service of inventoryValue.services)
395
+ await validateMountDescriptors(service.mounts);
396
+ const managerReads = networkList(value.managerReads, 2, managerCensusRead);
397
+ const nodeObservations = networkSorted(networkList(value.nodeObservations, fleetCutoverContract.maximumNodes, observationReference), itemArg => `${itemArg.nodeId}\0${itemArg.swarmNodeId}`);
398
+ requireNetwork(managerReads.length === 2
399
+ && managerReads[1].nodeId === managerReads[0].nodeId
400
+ && managerReads[1].swarmNodeId === managerReads[0].swarmNodeId
401
+ && managerReads[1].credentialGeneration === managerReads[0].credentialGeneration
402
+ && managerReads[1].reporterSessionId === managerReads[0].reporterSessionId
403
+ && managerReads[1].observationSequence === managerReads[0].observationSequence + 1
404
+ && managerReads[1].observedAt > managerReads[0].observedAt
405
+ && managerReads[1].swarmSnapshotDigest === managerReads[0].swarmSnapshotDigest
406
+ && managerReads.every(itemArg => itemArg.swarmNodeId === inventoryValue.managerSwarmNodeId)
407
+ && nodeObservations.length > 0
408
+ && new Set(nodeObservations.map(itemArg => itemArg.nodeId)).size === nodeObservations.length
409
+ && new Set(nodeObservations.map(itemArg => itemArg.swarmNodeId)).size === nodeObservations.length
410
+ && runtime.id === clusterId
411
+ && targetSet.cloudlyClusterId === clusterId);
412
+ const inventoryDigest = await computeFleetCutoverInventoryDigest(inventoryValue);
413
+ const managerSnapshotDigest = await computeFleetCutoverManagerSnapshotDigest({
414
+ inventory: inventoryValue,
415
+ inventoryDigest,
416
+ });
417
+ requireNetwork(managerReads.every(itemArg => itemArg.inventoryDigest === inventoryDigest
418
+ && itemArg.snapshotDigest === managerSnapshotDigest));
419
+ const freshUntil = networkCounter(value.freshUntil);
420
+ requireNetwork(freshUntil === Math.min(...managerReads.map(itemArg => itemArg.freshUntil), ...nodeObservations.map(itemArg => itemArg.freshUntil)));
421
+ return {
422
+ clusterId,
423
+ runtime,
424
+ targetSet,
425
+ inventory: inventoryValue,
426
+ managerReads: managerReads,
427
+ nodeObservations,
428
+ freshUntil,
429
+ };
430
+ });
431
+ export const snapshotFleetCutoverCensus = async (valueArg) => safe(async () => {
432
+ const value = networkRecord(captureNetwork(valueArg), [
433
+ 'id', 'generation', 'acceptedAt', 'digest', 'clusterId', 'runtime', 'targetSet',
434
+ 'inventory', 'managerReads', 'nodeObservations', 'freshUntil',
435
+ ]);
436
+ const candidate = await snapshotFleetCutoverCensusCandidate({
437
+ clusterId: value.clusterId,
438
+ runtime: value.runtime,
439
+ targetSet: value.targetSet,
440
+ inventory: value.inventory,
441
+ managerReads: value.managerReads,
442
+ nodeObservations: value.nodeObservations,
443
+ freshUntil: value.freshUntil,
444
+ });
445
+ const acceptedAt = networkCounter(value.acceptedAt);
446
+ requireNetwork(acceptedAt <= candidate.freshUntil
447
+ && candidate.managerReads.every(itemArg => acceptedAt >= itemArg.acceptedAt)
448
+ && candidate.nodeObservations.every(itemArg => acceptedAt >= itemArg.acceptedAt));
449
+ return {
450
+ id: networkId(value.id),
451
+ generation: networkCounter(value.generation),
452
+ acceptedAt,
453
+ digest: networkDigest(value.digest),
454
+ ...candidate,
455
+ };
456
+ });
457
+ export const computeFleetCutoverCensusDigest = async (valueArg) => canonicalDigest(fleetCutoverContract.censusDigestDomain, await snapshotFleetCutoverCensus(valueArg));
458
+ export const validateFleetCutoverCensus = async (valueArg) => {
459
+ try {
460
+ const value = await snapshotFleetCutoverCensus(valueArg);
461
+ return value.digest === await computeFleetCutoverCensusDigest(value)
462
+ ? [] : ['fleet cutover census digest does not match'];
463
+ }
464
+ catch {
465
+ return ['fleet cutover census must use its exact canonical schema'];
466
+ }
467
+ };
468
+ export const fleetCutoverEvidenceReferenceOf = (valueArg) => reference({
469
+ id: valueArg.id,
470
+ generation: valueArg.generation,
471
+ digest: valueArg.digest,
472
+ });
473
+ export const snapshotFleetCutoverAcceptedEvidenceReference = (valueArg) => safe(() => reference(captureNetwork(valueArg)));
474
+ const scopeEntry = (valueArg) => {
475
+ const value = networkRecord(valueArg, [
476
+ 'dockerServiceId', 'serviceId', 'owner', 'serviceAuthority', 'classificationAuthority',
477
+ ]);
478
+ const owner = literal([
479
+ 'application', 'coreflow', 'corestore', 'coretraffic', 'unknown',
480
+ ], value.owner);
481
+ const serviceId = value.serviceId === null ? null : networkId(value.serviceId);
482
+ const serviceAuthority = value.serviceAuthority === null ? null : reference(value.serviceAuthority);
483
+ const classificationAuthority = value.classificationAuthority === null
484
+ ? null : reference(value.classificationAuthority);
485
+ requireNetwork(owner === 'unknown'
486
+ ? serviceId === null && serviceAuthority === null && classificationAuthority === null
487
+ : serviceId !== null && serviceAuthority !== null && classificationAuthority !== null);
488
+ return {
489
+ dockerServiceId: networkId(value.dockerServiceId),
490
+ serviceId,
491
+ owner,
492
+ serviceAuthority,
493
+ classificationAuthority,
494
+ };
495
+ };
496
+ export const snapshotFleetCutoverScope = (valueArg) => safe(() => {
497
+ const value = networkRecord(captureNetwork(valueArg), [
498
+ 'id', 'generation', 'previous', 'state', 'clusterId', 'census', 'runtime', 'targetSet', 'entries',
499
+ 'actorId', 'acceptedAt', 'digest',
500
+ ]);
501
+ const state = literal(['incomplete', 'complete'], value.state);
502
+ const id = networkId(value.id);
503
+ const generation = networkCounter(value.generation);
504
+ const previous = value.previous === null ? null : reference(value.previous);
505
+ const clusterId = networkId(value.clusterId);
506
+ const runtime = runtimeReference(value.runtime);
507
+ const targetSet = targetSetReference(value.targetSet);
508
+ const entries = networkSorted(networkList(value.entries, fleetCutoverContract.maximumServices, scopeEntry), itemArg => itemArg.dockerServiceId);
509
+ requireNetwork(runtime.id === clusterId
510
+ && targetSet.cloudlyClusterId === clusterId
511
+ && (generation === 1
512
+ ? previous === null && state === 'incomplete'
513
+ : previous?.id === id && previous.generation === generation - 1)
514
+ && (state === 'incomplete' || entries.every(itemArg => itemArg.owner !== 'unknown')));
515
+ return {
516
+ id,
517
+ generation,
518
+ previous,
519
+ state,
520
+ clusterId,
521
+ census: reference(value.census),
522
+ runtime,
523
+ targetSet,
524
+ entries,
525
+ actorId: networkId(value.actorId),
526
+ acceptedAt: networkCounter(value.acceptedAt),
527
+ digest: networkDigest(value.digest),
528
+ };
529
+ });
530
+ export const computeFleetCutoverScopeDigest = async (valueArg) => canonicalDigest(fleetCutoverContract.scopeDigestDomain, snapshotFleetCutoverScope(valueArg));
531
+ export const validateFleetCutoverScope = async (valueArg) => {
532
+ try {
533
+ const value = snapshotFleetCutoverScope(valueArg);
534
+ return value.digest === await computeFleetCutoverScopeDigest(value)
535
+ ? [] : ['fleet cutover scope digest does not match'];
536
+ }
537
+ catch {
538
+ return ['fleet cutover scope must use its exact canonical schema'];
539
+ }
540
+ };
541
+ export const snapshotFleetCutoverScopeClassificationRequest = (valueArg) => safe(() => {
542
+ const value = networkRecord(captureNetwork(valueArg), [
543
+ 'mutationId', 'clusterId', 'expectedScopeGeneration', 'census', 'classifications',
544
+ ]);
545
+ const classifications = networkSorted(networkList(value.classifications, fleetCutoverContract.maximumClassifications, itemArg => {
546
+ const item = networkRecord(itemArg, ['dockerServiceId', 'serviceId', 'owner']);
547
+ return {
548
+ dockerServiceId: networkId(item.dockerServiceId),
549
+ serviceId: networkId(item.serviceId),
550
+ owner: literal(['application', 'coreflow', 'corestore', 'coretraffic'], item.owner),
551
+ };
552
+ }), itemArg => itemArg.dockerServiceId);
553
+ return {
554
+ mutationId: networkId(value.mutationId),
555
+ clusterId: networkId(value.clusterId),
556
+ expectedScopeGeneration: networkCounter(value.expectedScopeGeneration),
557
+ census: reference(value.census),
558
+ classifications,
559
+ };
560
+ });
561
+ export const snapshotFleetCutoverTargetSetReference = (valueArg) => safe(() => targetSetReference(captureNetwork(valueArg)));
562
+ const volumeHandoff = (valueArg) => {
563
+ const value = networkRecord(valueArg, [
564
+ 'id', 'generation', 'clusterId', 'nodeId', 'serviceId', 'volumeId',
565
+ 'mountIdentityDigest', 'sourceLineageDigest', 'storageRequestDigest', 'runtime', 'scope',
566
+ 'targetSet', 'legacyStorageEvidence', 'sourceNodeObservation', 'acceptedAt', 'digest',
567
+ ]);
568
+ const clusterId = networkId(value.clusterId);
569
+ const runtime = runtimeReference(value.runtime);
570
+ const targetSet = targetSetReference(value.targetSet);
571
+ requireNetwork(runtime.id === clusterId && runtime.phase === 'draining'
572
+ && targetSet.cloudlyClusterId === clusterId);
573
+ return {
574
+ id: networkId(value.id),
575
+ generation: networkCounter(value.generation),
576
+ clusterId,
577
+ nodeId: networkNodeId(value.nodeId),
578
+ serviceId: networkId(value.serviceId),
579
+ volumeId: networkId(value.volumeId),
580
+ mountIdentityDigest: networkDigest(value.mountIdentityDigest),
581
+ sourceLineageDigest: networkDigest(value.sourceLineageDigest),
582
+ storageRequestDigest: networkDigest(value.storageRequestDigest),
583
+ runtime: runtime,
584
+ scope: reference(value.scope),
585
+ targetSet,
586
+ legacyStorageEvidence: reference(value.legacyStorageEvidence),
587
+ sourceNodeObservation: reference(value.sourceNodeObservation),
588
+ acceptedAt: networkCounter(value.acceptedAt),
589
+ digest: networkDigest(value.digest),
590
+ };
591
+ };
592
+ export const snapshotFleetCutoverVolumeHandoffIntent = (valueArg) => safe(() => volumeHandoff(captureNetwork(valueArg)));
593
+ export const computeFleetCutoverVolumeHandoffDigest = async (valueArg) => canonicalDigest(fleetCutoverContract.volumeHandoffDigestDomain, snapshotFleetCutoverVolumeHandoffIntent(valueArg));
594
+ const volumeFence = (valueArg) => {
595
+ requireNetwork(valueArg !== null && typeof valueArg === 'object');
596
+ const state = valueArg.state;
597
+ const consumedKeys = state === 'consumed'
598
+ ? ['consumedRuntime', 'adoptionReceipt', 'claim', 'consumedAt'] : [];
599
+ const value = networkRecord(valueArg, [
600
+ 'id', 'generation', 'previous', 'clusterId', 'nodeId', 'serviceId', 'volumeId',
601
+ 'mountIdentityDigest', 'handoffIntent', 'heldRuntime', 'heldAt', 'state', ...consumedKeys,
602
+ 'digest',
603
+ ]);
604
+ requireNetwork(state === 'held' || state === 'consumed');
605
+ const id = networkId(value.id);
606
+ const generation = networkCounter(value.generation);
607
+ const previous = value.previous === null ? null : reference(value.previous);
608
+ requireNetwork(generation === 1
609
+ ? previous === null
610
+ : previous?.id === id && previous.generation === generation - 1);
611
+ const heldRuntime = runtimeReference(value.heldRuntime);
612
+ requireNetwork(heldRuntime.phase === 'draining');
613
+ const base = {
614
+ id,
615
+ generation,
616
+ previous,
617
+ clusterId: networkId(value.clusterId),
618
+ nodeId: networkNodeId(value.nodeId),
619
+ serviceId: networkId(value.serviceId),
620
+ volumeId: networkId(value.volumeId),
621
+ mountIdentityDigest: networkDigest(value.mountIdentityDigest),
622
+ handoffIntent: reference(value.handoffIntent),
623
+ heldRuntime: heldRuntime,
624
+ heldAt: networkCounter(value.heldAt),
625
+ digest: networkDigest(value.digest),
626
+ };
627
+ if (state === 'held')
628
+ return { ...base, state };
629
+ const consumedRuntime = runtimeReference(value.consumedRuntime);
630
+ requireNetwork(consumedRuntime.phase === 'pallet');
631
+ return {
632
+ ...base,
633
+ state,
634
+ consumedRuntime: consumedRuntime,
635
+ adoptionReceipt: reference(value.adoptionReceipt),
636
+ claim: reference(value.claim),
637
+ consumedAt: networkCounter(value.consumedAt),
638
+ };
639
+ };
640
+ export const snapshotFleetCutoverVolumeFence = (valueArg) => safe(() => volumeFence(captureNetwork(valueArg)));
641
+ export const computeFleetCutoverVolumeFenceDigest = async (valueArg) => canonicalDigest(fleetCutoverContract.volumeFenceDigestDomain, snapshotFleetCutoverVolumeFence(valueArg));
642
+ const corestoreAdoption = (valueArg) => {
643
+ const value = networkRecord(valueArg, [
644
+ 'id', 'generation', 'clusterId', 'nodeId', 'serviceId', 'volumeId',
645
+ 'mountIdentityDigest', 'handoffIntent', 'palletFence', 'sourceLineageDigest', 'claim',
646
+ 'accessMode', 'acceptedAt', 'digest',
647
+ ]);
648
+ requireNetwork(value.generation === 1 && value.accessMode === 'ReadWriteOnce');
649
+ return {
650
+ id: networkId(value.id),
651
+ generation: 1,
652
+ clusterId: networkId(value.clusterId),
653
+ nodeId: networkNodeId(value.nodeId),
654
+ serviceId: networkId(value.serviceId),
655
+ volumeId: networkId(value.volumeId),
656
+ mountIdentityDigest: networkDigest(value.mountIdentityDigest),
657
+ handoffIntent: reference(value.handoffIntent),
658
+ palletFence: reference(value.palletFence),
659
+ sourceLineageDigest: networkDigest(value.sourceLineageDigest),
660
+ claim: reference(value.claim),
661
+ accessMode: 'ReadWriteOnce',
662
+ acceptedAt: networkCounter(value.acceptedAt),
663
+ digest: networkDigest(value.digest),
664
+ };
665
+ };
666
+ export const snapshotFleetCutoverCorestoreAdoptionReceipt = (valueArg) => safe(() => corestoreAdoption(captureNetwork(valueArg)));
667
+ export const computeFleetCutoverCorestoreAdoptionDigest = async (valueArg) => canonicalDigest(fleetCutoverContract.corestoreAdoptionDigestDomain, snapshotFleetCutoverCorestoreAdoptionReceipt(valueArg));
668
+ /** Content join only. The Pallet owner must dereference both accepted records while holding its CAS. */
669
+ export const bindFleetCutoverAdoptionToVolumeFence = (adoptionArg, fenceArg) => safe(() => {
670
+ const adoption = snapshotFleetCutoverCorestoreAdoptionReceipt(adoptionArg);
671
+ const fence = snapshotFleetCutoverVolumeFence(fenceArg);
672
+ requireNetwork(fence.state === 'held'
673
+ && adoption.clusterId === fence.clusterId
674
+ && adoption.nodeId === fence.nodeId
675
+ && adoption.serviceId === fence.serviceId
676
+ && adoption.volumeId === fence.volumeId
677
+ && adoption.mountIdentityDigest === fence.mountIdentityDigest
678
+ && adoption.handoffIntent.id === fence.handoffIntent.id
679
+ && adoption.handoffIntent.generation === fence.handoffIntent.generation
680
+ && adoption.handoffIntent.digest === fence.handoffIntent.digest
681
+ && adoption.palletFence.id === fence.id
682
+ && adoption.palletFence.generation === fence.generation
683
+ && adoption.palletFence.digest === fence.digest);
684
+ return { adoption, fence };
685
+ });
686
+ export const validateFleetCutoverVolumeHandoffIntent = async (valueArg) => {
687
+ try {
688
+ const value = snapshotFleetCutoverVolumeHandoffIntent(valueArg);
689
+ return value.digest === await computeFleetCutoverVolumeHandoffDigest(value)
690
+ ? [] : ['fleet cutover volume handoff digest does not match'];
691
+ }
692
+ catch {
693
+ return ['fleet cutover volume handoff must use its exact canonical schema'];
694
+ }
695
+ };
696
+ export const validateFleetCutoverVolumeFence = async (valueArg) => {
697
+ try {
698
+ const value = snapshotFleetCutoverVolumeFence(valueArg);
699
+ return value.digest === await computeFleetCutoverVolumeFenceDigest(value)
700
+ ? [] : ['fleet cutover volume fence digest does not match'];
701
+ }
702
+ catch {
703
+ return ['fleet cutover volume fence must use its exact canonical schema'];
704
+ }
705
+ };
706
+ export const validateFleetCutoverCorestoreAdoptionReceipt = async (valueArg) => {
707
+ try {
708
+ const value = snapshotFleetCutoverCorestoreAdoptionReceipt(valueArg);
709
+ return value.digest === await computeFleetCutoverCorestoreAdoptionDigest(value)
710
+ ? [] : ['fleet cutover Corestore adoption digest does not match'];
711
+ }
712
+ catch {
713
+ return ['fleet cutover Corestore adoption receipt must use its exact canonical schema'];
714
+ }
715
+ };
716
+ const runtimeSession = (valueArg) => {
717
+ const value = networkRecord(valueArg, [
718
+ 'reporterSessionId', 'nodeId', 'clusterId', 'credentialGeneration', 'sessionEpoch',
719
+ 'controllerInstanceId', 'controller', 'runtimeNamespace',
720
+ ]);
721
+ const controller = networkRecord(value.controller, ['kind', 'id', 'epoch']);
722
+ requireNetwork(controller.kind === 'cloudly' || controller.kind === 'onebox');
723
+ return {
724
+ reporterSessionId: networkId(value.reporterSessionId),
725
+ nodeId: networkNodeId(value.nodeId),
726
+ clusterId: networkId(value.clusterId),
727
+ credentialGeneration: networkCounter(value.credentialGeneration),
728
+ sessionEpoch: networkCounter(value.sessionEpoch),
729
+ controllerInstanceId: networkId(value.controllerInstanceId),
730
+ controller: {
731
+ kind: controller.kind,
732
+ id: networkId(controller.id),
733
+ epoch: networkId(controller.epoch),
734
+ },
735
+ runtimeNamespace: networkId(value.runtimeNamespace),
736
+ };
737
+ };
738
+ export const snapshotFleetCutoverCoreflowRetirementEvidence = (valueArg) => safe(() => {
739
+ const value = networkRecord(captureNetwork(valueArg), [
740
+ 'id', 'generation', 'clusterId', 'scope', 'targetSet', 'runtime', 'relay', 'spark',
741
+ 'legacy', 'acceptedAt', 'digest',
742
+ ]);
743
+ const relay = networkRecord(value.relay, [
744
+ 'serviceId', 'nodeId', 'dockerServiceId', 'dockerContainerId', 'specVersion', 'specDigest',
745
+ 'imageDigest', 'managerObservation', 'nodeObservation', 'credential',
746
+ 'acceptedRegistration', 'version',
747
+ ]);
748
+ const spark = networkRecord(value.spark, [
749
+ 'nodeId', 'credentialGeneration', 'reporterSessionId', 'observationSequence',
750
+ 'observation', 'bundleVersion', 'bundleSourceCommit',
751
+ 'bundleManifestSha256', 'unitName', 'unitDigest',
752
+ ]);
753
+ const legacy = networkRecord(value.legacy, [
754
+ 'credential', 'invalidation', 'oldModeRefusal', 'configurationCas',
755
+ 'sourceOwnerGeneration', 'sourceSha256', 'sourceDisposition',
756
+ ]);
757
+ const clusterId = networkId(value.clusterId);
758
+ const runtime = runtimeReference(value.runtime);
759
+ const targetSet = targetSetReference(value.targetSet);
760
+ requireNetwork(runtime.id === clusterId && runtime.phase === 'swarm'
761
+ && targetSet.cloudlyClusterId === clusterId);
762
+ const relayNodeId = networkNodeId(relay.nodeId);
763
+ const sparkNodeId = networkNodeId(spark.nodeId);
764
+ requireNetwork(relayNodeId === sparkNodeId);
765
+ const relayNodeObservation = reference(relay.nodeObservation);
766
+ const sparkObservation = reference(spark.observation);
767
+ requireNetwork(relayNodeObservation.id === sparkObservation.id
768
+ && relayNodeObservation.generation === sparkObservation.generation
769
+ && relayNodeObservation.digest === sparkObservation.digest);
770
+ const relayVersion = releaseVersion(relay.version);
771
+ requireNetwork(relayVersion.startsWith('32.'));
772
+ return {
773
+ id: networkId(value.id),
774
+ generation: networkCounter(value.generation),
775
+ clusterId,
776
+ scope: reference(value.scope),
777
+ targetSet,
778
+ runtime,
779
+ relay: {
780
+ serviceId: networkId(relay.serviceId),
781
+ nodeId: relayNodeId,
782
+ dockerServiceId: networkId(relay.dockerServiceId),
783
+ dockerContainerId: networkId(relay.dockerContainerId),
784
+ specVersion: networkCounter(relay.specVersion),
785
+ specDigest: networkDigest(relay.specDigest),
786
+ imageDigest: networkDigest(relay.imageDigest),
787
+ managerObservation: reference(relay.managerObservation),
788
+ nodeObservation: relayNodeObservation,
789
+ credential: reference(relay.credential),
790
+ acceptedRegistration: reference(relay.acceptedRegistration),
791
+ version: relayVersion,
792
+ },
793
+ spark: {
794
+ nodeId: sparkNodeId,
795
+ credentialGeneration: networkCounter(spark.credentialGeneration),
796
+ reporterSessionId: networkId(spark.reporterSessionId),
797
+ observationSequence: networkCounter(spark.observationSequence),
798
+ observation: sparkObservation,
799
+ bundleVersion: releaseVersion(spark.bundleVersion),
800
+ bundleSourceCommit: (() => {
801
+ requireNetwork(typeof spark.bundleSourceCommit === 'string'
802
+ && /^[a-f0-9]{40}$/.test(spark.bundleSourceCommit));
803
+ return spark.bundleSourceCommit;
804
+ })(),
805
+ bundleManifestSha256: sha256Hex(spark.bundleManifestSha256),
806
+ unitName: networkId(spark.unitName),
807
+ unitDigest: networkDigest(spark.unitDigest),
808
+ },
809
+ legacy: {
810
+ credential: reference(legacy.credential),
811
+ invalidation: reference(legacy.invalidation),
812
+ oldModeRefusal: reference(legacy.oldModeRefusal),
813
+ configurationCas: reference(legacy.configurationCas),
814
+ sourceOwnerGeneration: networkCounter(legacy.sourceOwnerGeneration),
815
+ sourceSha256: sha256Hex(legacy.sourceSha256),
816
+ sourceDisposition: literal(['retained-inert', 'removed'], legacy.sourceDisposition),
817
+ },
818
+ acceptedAt: networkCounter(value.acceptedAt),
819
+ digest: networkDigest(value.digest),
820
+ };
821
+ });
822
+ export const computeFleetCutoverCoreflowRetirementDigest = async (valueArg) => canonicalDigest(fleetCutoverContract.coreflowRetirementDigestDomain, snapshotFleetCutoverCoreflowRetirementEvidence(valueArg));
823
+ export const validateFleetCutoverCoreflowRetirementEvidence = async (valueArg) => {
824
+ try {
825
+ const value = snapshotFleetCutoverCoreflowRetirementEvidence(valueArg);
826
+ return value.digest === await computeFleetCutoverCoreflowRetirementDigest(value)
827
+ ? [] : ['fleet cutover Coreflow retirement digest does not match'];
828
+ }
829
+ catch {
830
+ return ['fleet cutover Coreflow retirement evidence must use its exact canonical schema'];
831
+ }
832
+ };
833
+ export const snapshotFleetCutoverIngressPreparationRequest = (valueArg) => safe(() => {
834
+ const value = networkRecord(captureNetwork(valueArg), [
835
+ 'mutationId', 'clusterId', 'ingressServiceId', 'currentRuntime', 'scope', 'targetSet',
836
+ 'expectedSpecRevision', 'expectedDesignation',
837
+ ]);
838
+ const clusterId = networkId(value.clusterId);
839
+ const currentRuntime = runtimeReference(value.currentRuntime);
840
+ const targetSet = targetSetReference(value.targetSet);
841
+ requireNetwork(currentRuntime.id === clusterId && currentRuntime.phase === 'pallet'
842
+ && targetSet.cloudlyClusterId === clusterId);
843
+ return {
844
+ mutationId: networkId(value.mutationId),
845
+ clusterId,
846
+ ingressServiceId: networkId(value.ingressServiceId),
847
+ currentRuntime: currentRuntime,
848
+ scope: reference(value.scope),
849
+ targetSet,
850
+ expectedSpecRevision: networkCounter(value.expectedSpecRevision),
851
+ expectedDesignation: value.expectedDesignation === null
852
+ ? null : reference(value.expectedDesignation),
853
+ };
854
+ });
855
+ export const snapshotFleetCutoverIngressDesignation = (valueArg) => safe(() => {
856
+ const value = networkRecord(captureNetwork(valueArg), [
857
+ 'id', 'generation', 'previous', 'clusterId', 'runtime', 'scope', 'targetSet',
858
+ 'ingressServiceId', 'preparedSpecRevision', 'credential', 'actorId', 'acceptedAt', 'digest',
859
+ ]);
860
+ const id = networkId(value.id);
861
+ const generation = networkCounter(value.generation);
862
+ const previous = value.previous === null ? null : reference(value.previous);
863
+ const clusterId = networkId(value.clusterId);
864
+ const runtime = runtimeReference(value.runtime);
865
+ const targetSet = targetSetReference(value.targetSet);
866
+ requireNetwork(runtime.id === clusterId && runtime.phase === 'pallet'
867
+ && targetSet.cloudlyClusterId === clusterId
868
+ && (generation === 1
869
+ ? previous === null
870
+ : previous?.id === id && previous.generation === generation - 1));
871
+ return {
872
+ id,
873
+ generation,
874
+ previous,
875
+ clusterId,
876
+ runtime: runtime,
877
+ scope: reference(value.scope),
878
+ targetSet,
879
+ ingressServiceId: networkId(value.ingressServiceId),
880
+ preparedSpecRevision: networkCounter(value.preparedSpecRevision),
881
+ credential: ingressCredentialReference(value.credential),
882
+ actorId: networkId(value.actorId),
883
+ acceptedAt: networkCounter(value.acceptedAt),
884
+ digest: networkDigest(value.digest),
885
+ };
886
+ });
887
+ export const computeFleetCutoverIngressDesignationDigest = async (valueArg) => canonicalDigest(fleetCutoverContract.ingressDesignationDigestDomain, snapshotFleetCutoverIngressDesignation(valueArg));
888
+ export const validateFleetCutoverIngressDesignation = async (valueArg) => {
889
+ try {
890
+ const value = snapshotFleetCutoverIngressDesignation(valueArg);
891
+ return value.digest === await computeFleetCutoverIngressDesignationDigest(value)
892
+ ? [] : ['fleet cutover ingress designation digest does not match'];
893
+ }
894
+ catch {
895
+ return ['fleet cutover ingress designation must use its exact canonical schema'];
896
+ }
897
+ };
898
+ export const snapshotFleetCutoverIngressAuthority = (valueArg) => safe(() => {
899
+ const value = networkRecord(captureNetwork(valueArg), [
900
+ 'id', 'generation', 'clusterId', 'runtime', 'scope', 'targetSet', 'ingressServiceId',
901
+ 'assignment', 'session', 'ingressRegistration', 'registrationRouteRevision',
902
+ 'legacyIngressAbsence', 'sourcePublication', 'targetPublication', 'portTransfer',
903
+ 'routeTableRevision', 'routeTableReadback', 'acceptedAt', 'digest',
904
+ ]);
905
+ const clusterId = networkId(value.clusterId);
906
+ const runtime = runtimeReference(value.runtime);
907
+ const targetSet = targetSetReference(value.targetSet);
908
+ const session = runtimeSession(value.session);
909
+ requireNetwork(runtime.id === clusterId && runtime.phase === 'pallet'
910
+ && targetSet.cloudlyClusterId === clusterId && session.clusterId === clusterId);
911
+ return {
912
+ id: networkId(value.id),
913
+ generation: networkCounter(value.generation),
914
+ clusterId,
915
+ runtime: runtime,
916
+ scope: reference(value.scope),
917
+ targetSet,
918
+ ingressServiceId: networkId(value.ingressServiceId),
919
+ assignment: assignmentReference(value.assignment),
920
+ session,
921
+ ingressRegistration: reference(value.ingressRegistration),
922
+ registrationRouteRevision: value.registrationRouteRevision === null
923
+ ? null : nonNegative(value.registrationRouteRevision),
924
+ legacyIngressAbsence: reference(value.legacyIngressAbsence),
925
+ sourcePublication: reference(value.sourcePublication),
926
+ targetPublication: reference(value.targetPublication),
927
+ portTransfer: reference(value.portTransfer),
928
+ routeTableRevision: nonNegative(value.routeTableRevision),
929
+ routeTableReadback: reference(value.routeTableReadback),
930
+ acceptedAt: networkCounter(value.acceptedAt),
931
+ digest: networkDigest(value.digest),
932
+ };
933
+ });
934
+ export const computeFleetCutoverIngressAuthorityDigest = async (valueArg) => canonicalDigest(fleetCutoverContract.ingressAuthorityDigestDomain, snapshotFleetCutoverIngressAuthority(valueArg));
935
+ export const validateFleetCutoverIngressAuthority = async (valueArg) => {
936
+ try {
937
+ const value = snapshotFleetCutoverIngressAuthority(valueArg);
938
+ return value.digest === await computeFleetCutoverIngressAuthorityDigest(value)
939
+ ? [] : ['fleet cutover ingress authority digest does not match'];
940
+ }
941
+ catch {
942
+ return ['fleet cutover ingress authority must use its exact canonical schema'];
943
+ }
944
+ };
945
+ export const isLegalFleetCutoverPhaseTransition = (fromArg, toArg) => fleetCutoverContract.legalPhaseTransitions[fromArg] === toArg;
946
+ export const snapshotFleetCutoverPhaseAdvance = (valueArg) => safe(() => {
947
+ requireNetwork(valueArg !== null && typeof valueArg === 'object');
948
+ const candidate = valueArg;
949
+ const from = literal(['swarm', 'draining', 'switching'], candidate.from);
950
+ const expectedTo = fleetCutoverContract.legalPhaseTransitions[from];
951
+ requireNetwork(candidate.to === expectedTo);
952
+ const extraKeys = from === 'swarm'
953
+ ? ['coreflowRetirement']
954
+ : from === 'draining'
955
+ ? ['swarmQuiescence', 'heldRuntimeSpecs', 'heldVolumeFences']
956
+ : ['heldRuntimeSpecs', 'heldVolumeFences', 'palletPreparation'];
957
+ const value = networkRecord(captureNetwork(valueArg), [
958
+ 'mutationId', 'clusterId', 'currentRuntime', 'scope', 'targetSet', 'from', 'to', ...extraKeys,
959
+ ]);
960
+ const currentRuntime = runtimeReference(value.currentRuntime);
961
+ const clusterId = networkId(value.clusterId);
962
+ const targetSet = targetSetReference(value.targetSet);
963
+ requireNetwork(currentRuntime.id === clusterId && currentRuntime.phase === from
964
+ && targetSet.cloudlyClusterId === clusterId);
965
+ const base = {
966
+ mutationId: networkId(value.mutationId),
967
+ clusterId,
968
+ currentRuntime,
969
+ scope: reference(value.scope),
970
+ targetSet,
971
+ };
972
+ if (from === 'swarm')
973
+ return {
974
+ ...base,
975
+ from,
976
+ to: 'draining',
977
+ coreflowRetirement: reference(value.coreflowRetirement),
978
+ };
979
+ if (from === 'draining')
980
+ return {
981
+ ...base,
982
+ from,
983
+ to: 'switching',
984
+ swarmQuiescence: reference(value.swarmQuiescence),
985
+ heldRuntimeSpecs: reference(value.heldRuntimeSpecs),
986
+ heldVolumeFences: reference(value.heldVolumeFences),
987
+ };
988
+ return {
989
+ ...base,
990
+ from,
991
+ to: 'pallet',
992
+ heldRuntimeSpecs: reference(value.heldRuntimeSpecs),
993
+ heldVolumeFences: reference(value.heldVolumeFences),
994
+ palletPreparation: reference(value.palletPreparation),
995
+ };
996
+ });
997
+ export const snapshotFleetCutoverRuntimeSpecRelease = (valueArg) => safe(() => {
998
+ requireNetwork(valueArg !== null && typeof valueArg === 'object');
999
+ const kind = literal(['ingress', 'application'], valueArg.kind);
1000
+ const evidenceKey = kind === 'ingress' ? 'emptyPublishedPortsPolicy' : 'ingressAuthority';
1001
+ const value = networkRecord(captureNetwork(valueArg), [
1002
+ 'kind', 'mutationId', 'clusterId', 'serviceId', 'expectedSpecRevision', 'runtime', 'scope',
1003
+ evidenceKey,
1004
+ ]);
1005
+ const runtime = runtimeReference(value.runtime);
1006
+ const clusterId = networkId(value.clusterId);
1007
+ requireNetwork(runtime.id === clusterId && runtime.phase === 'pallet');
1008
+ const base = {
1009
+ kind,
1010
+ mutationId: networkId(value.mutationId),
1011
+ clusterId,
1012
+ serviceId: networkId(value.serviceId),
1013
+ expectedSpecRevision: networkCounter(value.expectedSpecRevision),
1014
+ runtime: runtime,
1015
+ scope: reference(value.scope),
1016
+ };
1017
+ return kind === 'ingress'
1018
+ ? { ...base, kind, emptyPublishedPortsPolicy: reference(value.emptyPublishedPortsPolicy) }
1019
+ : { ...base, kind, ingressAuthority: reference(value.ingressAuthority) };
1020
+ });
1021
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxlZXRjdXRvdmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvZGF0YS9mbGVldGN1dG92ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFPdEUsT0FBTyxFQUNMLHNCQUFzQixFQUN0Qiw0QkFBNEIsR0FDN0IsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQ0wsY0FBYyxFQUNkLGNBQWMsRUFDZCxhQUFhLEVBQ2IsU0FBUyxFQUNULFdBQVcsRUFDWCxhQUFhLEVBQ2IsYUFBYSxFQUNiLGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsY0FBYyxHQUNmLE1BQU0sK0JBQStCLENBQUM7QUFxZHZDLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDaEQsZUFBZSxFQUFFLEdBQUc7SUFDcEIsWUFBWSxFQUFFLElBQUk7SUFDbEIsWUFBWSxFQUFFLElBQUk7SUFDbEIsd0JBQXdCLEVBQUUsR0FBRztJQUM3QixxQkFBcUIsRUFBRSxFQUFFO0lBQ3pCLHNCQUFzQixFQUFFLEdBQUc7SUFDM0Isc0JBQXNCLEVBQUUsT0FBTztJQUMvQiwrQkFBK0IsRUFBRSxnREFBZ0Q7SUFDakYsK0JBQStCLEVBQUUsZ0RBQWdEO0lBQ2pGLHlCQUF5QixFQUFFLHlDQUF5QztJQUNwRSxnQ0FBZ0MsRUFBRSxpREFBaUQ7SUFDbkYsNkJBQTZCLEVBQUUsOENBQThDO0lBQzdFLDJCQUEyQixFQUFFLDJDQUEyQztJQUN4RSxrQkFBa0IsRUFBRSxpQ0FBaUM7SUFDckQsaUJBQWlCLEVBQUUsZ0NBQWdDO0lBQ25ELHlCQUF5QixFQUFFLHlDQUF5QztJQUNwRSx1QkFBdUIsRUFBRSx1Q0FBdUM7SUFDaEUsNkJBQTZCLEVBQUUsNkNBQTZDO0lBQzVFLDhCQUE4QixFQUFFLDhDQUE4QztJQUM5RSw4QkFBOEIsRUFBRSw4Q0FBOEM7SUFDOUUsNEJBQTRCLEVBQUUsNENBQTRDO0lBQzFFLHFCQUFxQixFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDbkMsS0FBSyxFQUFFLFVBQVU7UUFDakIsUUFBUSxFQUFFLFdBQVc7UUFDckIsU0FBUyxFQUFFLFFBQVE7UUFDbkIsTUFBTSxFQUFFLElBQUk7S0FDdUQsQ0FBQztDQUM5RCxDQUFDLENBQUM7QUFFWixNQUFNLElBQUksR0FBRyxHQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkYsTUFBTSxJQUFJLEdBQUcsQ0FBSSxZQUFxQixFQUFLLEVBQUU7SUFDM0MsSUFBSSxDQUFDO1FBQUMsT0FBTyxZQUFZLEVBQUUsQ0FBQztJQUFDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFBQyxPQUFPLElBQUksRUFBRSxDQUFDO0lBQUMsQ0FBQztBQUN6RCxDQUFDLENBQUM7QUFDRixNQUFNLFdBQVcsR0FBRyxDQUFDLFFBQWlCLEVBQVUsRUFBRTtJQUNoRCxjQUFjLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsSUFBSyxRQUFtQixJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzVFLE9BQU8sUUFBa0IsQ0FBQztBQUM1QixDQUFDLENBQUM7QUFDRixNQUFNLE9BQU8sR0FBRyxDQUFtQixTQUF1QixFQUFFLFFBQWlCLEVBQUssRUFBRTtJQUNsRixjQUFjLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxRQUFhLENBQUMsQ0FBQyxDQUFDO0lBQ2xELE9BQU8sUUFBYSxDQUFDO0FBQ3ZCLENBQUMsQ0FBQztBQUNGLE1BQU0sU0FBUyxHQUFHLENBQUMsUUFBaUIsRUFBVSxFQUFFO0lBQzlDLGNBQWMsQ0FBQyxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDaEYsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQyxDQUFDO0FBQ0YsTUFBTSxjQUFjLEdBQUcsQ0FBQyxRQUFpQixFQUFVLEVBQUU7SUFDbkQsY0FBYyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVE7V0FDdEMsMkRBQTJELENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztXQUMxRSxRQUFRLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVCLE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUNGLE1BQU0sU0FBUyxHQUFHLENBQUMsUUFBaUIsRUFBMEMsRUFBRSxDQUM5RSxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM3QixNQUFNLGtCQUFrQixHQUFHLENBQUMsUUFBaUIsRUFBbUMsRUFBRTtJQUNoRixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQztJQUM3RixPQUFPO1FBQ0wsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztRQUNuRCxVQUFVLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDNUMsZUFBZSxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO0tBQ3RELENBQUM7QUFDSixDQUFDLENBQUM7QUFDRixNQUFNLGdCQUFnQixHQUFHLENBQUMsUUFBaUIsRUFBNEIsRUFBRSxDQUN2RSwrQkFBK0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM1QyxNQUFNLG1CQUFtQixHQUFHLENBQUMsUUFBaUIsRUFBK0IsRUFBRTtJQUM3RSxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsY0FBYyxFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ2hGLE9BQU87UUFDTCxZQUFZLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7UUFDM0MsVUFBVSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQzVDLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztLQUNwQyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBQ0YsTUFBTSwwQkFBMEIsR0FBRyxDQUNqQyxRQUFpQixFQUN3QixFQUFFO0lBQzNDLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxjQUFjLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDdkYsTUFBTSxhQUFhLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQyxVQUFVLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO0lBQzFGLE9BQU87UUFDTCxZQUFZLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7UUFDM0MsVUFBVSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQzVDLGFBQWEsRUFBRTtZQUNiLFFBQVEsRUFBRSxTQUFTLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQztZQUMzQyxlQUFlLEVBQUUsU0FBUyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUM7U0FDMUQ7S0FDRixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBQ0YsTUFBTSwwQkFBMEIsR0FBRyxDQUNqQyxPQUFnQixFQUNoQixpQkFBMEIsRUFDcUMsRUFBRTtJQUNqRSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTLENBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMvRSxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUM7UUFDN0IsZUFBZSxFQUFFLFFBQVEsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTO0tBQzNFLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUMvQixjQUFjLENBQ1osQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztXQUN0RixDQUFDLElBQUksS0FBSyxNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1dBQ3JHLENBQUMsSUFBSSxLQUFLLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1dBQzVFLENBQUMsSUFBSSxLQUFLLFNBQVMsSUFBSSxjQUFjLEtBQUssU0FBUyxDQUFDLENBQ3hELENBQUM7SUFDRixPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxDQUFDO0FBQ2xDLENBQUMsQ0FBQztBQUNGLE1BQU0sZUFBZSxHQUFHLENBQUMsUUFBaUIsRUFBZ0MsRUFBRTtJQUMxRSxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFO1FBQ3BDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxzQkFBc0IsRUFBRSxzQkFBc0IsRUFBRSxVQUFVO1FBQ3BGLHFCQUFxQjtLQUN0QixDQUFDLENBQUM7SUFDSCxjQUFjLENBQUMsT0FBTyxLQUFLLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDO0lBQ3BELE1BQU0sS0FBSyxHQUFHLDBCQUEwQixDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzNFLE9BQU87UUFDTCxHQUFHLEtBQUs7UUFDUixvQkFBb0IsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDO1FBQy9ELG9CQUFvQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUM7UUFDL0QsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1FBQ3hCLG1CQUFtQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUM7S0FDOUQsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUNGLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxRQUFpQixFQUFrQyxFQUFFLENBQUMsYUFBYSxDQUNqRyxXQUFXLENBQUMsUUFBUSxFQUFFLG9CQUFvQixDQUFDLHFCQUFxQixFQUFFLGVBQWUsQ0FBQyxFQUNsRixPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FDdkMsQ0FBQztBQUNGLE1BQU0sVUFBVSxHQUFHLENBQUMsUUFBaUIsRUFBa0MsRUFBRTtJQUN2RSxjQUFjLENBQUMsUUFBUSxLQUFLLElBQUksSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQztJQUNsRSxNQUFNLElBQUksR0FBSSxRQUFvQyxDQUFDLElBQUksQ0FBQztJQUN4RCxJQUFJLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN0QixhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNsQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUNELE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUM1RCxjQUFjLENBQUMsSUFBSSxLQUFLLFlBQVksQ0FBQyxDQUFDO0lBQ3RDLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztBQUN6RCxDQUFDLENBQUM7QUFDRixNQUFNLGVBQWUsR0FBRyxDQUFDLFFBQWlCLEVBQXNDLEVBQUU7SUFDaEYsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDO0lBQ3RFLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDL0UsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1FBQ2xFLFVBQVUsRUFBRSxXQUFXLEVBQUUsYUFBYTtLQUM5QixFQUFFLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNqQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxDQUFDO0FBQ3RDLENBQUMsQ0FBQztBQUNGLE1BQU0sYUFBYSxHQUFHLENBQUMsUUFBaUIsRUFBOEIsRUFBRTtJQUN0RSxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFO1FBQ3BDLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE1BQU07UUFDMUYsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQUUscUJBQXFCLEVBQUUsUUFBUSxFQUFFLGlCQUFpQjtLQUMxRixDQUFDLENBQUM7SUFDSCxPQUFPO1FBQ0wsZUFBZSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO1FBQ2pELGlCQUFpQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUM7UUFDckQsV0FBVyxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO1FBQzlDLFVBQVUsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUMzQyxXQUFXLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUM7UUFDN0MsSUFBSSxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO1FBQzVCLGdCQUFnQixFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUM7UUFDckQsZUFBZSxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO1FBQ25ELG1CQUFtQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUM7UUFDN0QsTUFBTSxFQUFFLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDNUMsZUFBZSxFQUFFLGVBQWUsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO0tBQ3hELENBQUM7QUFDSixDQUFDLENBQUM7QUFDRixNQUFNLFVBQVUsR0FBRyxDQUFDLFFBQWlCLEVBQTJCLEVBQUU7SUFDaEUsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRTtRQUNwQyxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLFdBQVc7S0FDbkcsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxTQUFTLEdBQXlDLElBQUksQ0FBQztJQUMzRCxJQUFJLEtBQUssQ0FBQyxTQUFTLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDN0IsTUFBTSxjQUFjLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUM7UUFDN0UsU0FBUyxHQUFHO1lBQ1YsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQztTQUMvRCxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxXQUFXLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckYsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1RSxjQUFjLENBQUMsQ0FBQyxXQUFXLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztJQUMvRCxNQUFNLFVBQVUsR0FBRztRQUNqQixLQUFLLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsVUFBVTtRQUN2RixTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxVQUFVO0tBQ3JFLENBQUM7SUFDWCxPQUFPO1FBQ0wsWUFBWSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO1FBQzNDLGVBQWUsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztRQUNqRCxXQUFXO1FBQ1gsUUFBUTtRQUNSLFlBQVksRUFBRSxPQUFPLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxZQUFZLENBQUM7UUFDckQsS0FBSyxFQUFFLE9BQU8sQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUN2QyxTQUFTO0tBQ1YsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUNGLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxRQUFpQixFQUFrQyxFQUFFO0lBQzlFLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUU7UUFDcEMsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxRQUFRO0tBQzlGLENBQUMsQ0FBQztJQUNILE9BQU87UUFDTCxpQkFBaUIsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDO1FBQ3JELGVBQWUsRUFBRSxLQUFLLENBQUMsZUFBZSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztRQUN6RixZQUFZLEVBQUUsS0FBSyxDQUFDLFlBQVksS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7UUFDaEYsT0FBTyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQ3JDLGNBQWMsRUFBRSxLQUFLLENBQUMsY0FBYyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztRQUN0RixNQUFNLEVBQUUsc0JBQXNCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztLQUM3QyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBQ0YsTUFBTSxTQUFTLEdBQUcsQ0FBQyxRQUFpQixFQUFnQyxFQUFFO0lBQ3BFLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUU7UUFDcEMsZ0JBQWdCLEVBQUUsb0JBQW9CLEVBQUUsVUFBVSxFQUFFLE9BQU87S0FDNUQsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FDeEMsS0FBSyxDQUFDLFFBQVEsRUFDZCxvQkFBb0IsQ0FBQyxlQUFlLEVBQ3BDLGFBQWEsQ0FDZCxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUM3RSxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsV0FBVyxDQUNyQyxLQUFLLENBQUMsS0FBSyxFQUNYLG9CQUFvQixDQUFDLFlBQVksRUFDakMsVUFBVSxDQUNYLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxlQUFlLEtBQUssT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7SUFDckUsY0FBYyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEYsT0FBTztRQUNMLGNBQWMsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQztRQUMvQyxrQkFBa0IsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBQ3ZELFFBQVE7UUFDUixLQUFLO0tBQ04sQ0FBQztBQUNKLENBQUMsQ0FBQztBQUNGLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxRQUFpQixFQUEwQyxFQUFFO0lBQ3pGLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUU7UUFDcEMsYUFBYSxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsc0JBQXNCLEVBQUUsbUJBQW1CO1FBQ25GLHFCQUFxQixFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLG1CQUFtQjtRQUNwRixnQkFBZ0I7S0FDakIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxNQUFNLEdBQTJDO1FBQ3JELFdBQVcsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQztRQUN6QyxNQUFNLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDbkMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO1FBQ3pDLG9CQUFvQixFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUM7UUFDaEUsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztRQUNyRCxtQkFBbUIsRUFBRSxjQUFjLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDO1FBQzlELFVBQVUsRUFBRSxjQUFjLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUM1QyxVQUFVLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDNUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQzVDLGlCQUFpQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUM7UUFDekQsY0FBYyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO0tBQ3BELENBQUM7SUFDRixjQUFjLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsVUFBVTtXQUNoRCxNQUFNLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQyxVQUFVO1dBQ3RDLE1BQU0sQ0FBQyxVQUFVLEtBQUssTUFBTSxDQUFDLFVBQVUsR0FBRyxvQkFBb0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBQzVGLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMsQ0FBQztBQUNGLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxRQUFpQixFQUFrQyxFQUFFO0lBQzlFLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUU7UUFDcEMsYUFBYSxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsc0JBQXNCLEVBQUUsbUJBQW1CO1FBQ25GLHFCQUFxQixFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLG1CQUFtQjtRQUNwRixnQkFBZ0IsRUFBRSxxQkFBcUIsRUFBRSxpQkFBaUI7S0FDM0QsQ0FBQyxDQUFDO0lBQ0gsT0FBTztRQUNMLEdBQUcsb0JBQW9CLENBQUM7WUFDdEIsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO1lBQzlCLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNwQixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVc7WUFDOUIsb0JBQW9CLEVBQUUsS0FBSyxDQUFDLG9CQUFvQjtZQUNoRCxpQkFBaUIsRUFBRSxLQUFLLENBQUMsaUJBQWlCO1lBQzFDLG1CQUFtQixFQUFFLEtBQUssQ0FBQyxtQkFBbUI7WUFDOUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO1lBQzVCLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtZQUM1QixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7WUFDNUIsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLGlCQUFpQjtZQUMxQyxjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWM7U0FDckMsQ0FBQztRQUNGLG1CQUFtQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUM7UUFDN0QsZUFBZSxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO0tBQ3RELENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLGVBQWUsR0FBRyxLQUFLLEVBQUUsU0FBaUIsRUFBRSxRQUFnQixFQUEwQixFQUFFO0lBQzVGLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxFQUFFLEdBQUcsUUFBZ0MsQ0FBQztJQUN6RSxPQUFPLFVBQVUsTUFBTSw0QkFBNEIsQ0FBQyxzQkFBc0IsQ0FBQztRQUN6RSxNQUFNLEVBQUUsU0FBUztRQUNqQixPQUFPO0tBQ1IsRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO0FBQ3BCLENBQUMsQ0FBQztBQUVGLE1BQU0sZUFBZSxHQUFHLENBQUMsUUFBaUIsRUFBRSxhQUFzQixFQUFVLEVBQUU7SUFDNUUsY0FBYyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVE7V0FDdEMsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxJQUFJLElBQUk7V0FDakQsQ0FBQyxhQUFhLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdDLE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUVGLE1BQU0sMEJBQTBCLEdBQUcsS0FBSyxFQUN0QyxTQUFpQixFQUNqQixRQUFnQixFQUNRLEVBQUUsQ0FBQyxVQUFVLE1BQU0sNEJBQTRCLENBQUMsc0JBQXNCLENBQUM7SUFDL0YsTUFBTSxFQUFFLFNBQVM7SUFDakIsS0FBSyxFQUFFLFFBQVE7Q0FDaEIsRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO0FBRWxCLE1BQU0sQ0FBQyxNQUFNLDRDQUE0QyxHQUFHLEtBQUssRUFDL0QsUUFBK0MsRUFDdkIsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRTtJQUMzQyxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDMUQsT0FBTywwQkFBMEIsQ0FBQyxvQkFBb0IsQ0FBQywrQkFBK0IsRUFBRTtRQUN0RixJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFVLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQztRQUMxRSxNQUFNLEVBQUUsZUFBZSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDO0tBQzVDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sNENBQTRDLEdBQUcsS0FBSyxFQUMvRCxRQUErQyxFQUN2QixFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO0lBQzNDLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ2xELE9BQU8sMEJBQTBCLENBQUMsb0JBQW9CLENBQUMsK0JBQStCLEVBQUU7UUFDdEYsTUFBTSxFQUFFLGVBQWUsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQztLQUM3QyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sQ0FBQyxNQUFNLHNDQUFzQyxHQUFHLEtBQUssRUFDekQsUUFBbUUsRUFDM0MsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRTtJQUMzQyxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsUUFBUSxFQUFFO1FBQ3BDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxzQkFBc0IsRUFBRSxzQkFBc0IsRUFBRSxVQUFVO0tBQ3JGLENBQUMsQ0FBQztJQUNILGNBQWMsQ0FBQyxPQUFPLEtBQUssQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLENBQUM7SUFDcEQsTUFBTSxLQUFLLEdBQUcsMEJBQTBCLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDM0UsT0FBTywwQkFBMEIsQ0FBQyxvQkFBb0IsQ0FBQyx5QkFBeUIsRUFBRTtRQUNoRixHQUFHLEtBQUs7UUFDUixvQkFBb0IsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDO1FBQy9ELG9CQUFvQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUM7UUFDL0QsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO0tBQ3pCLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSx3QkFBd0IsR0FBRyxLQUFLLEVBQ3BDLFNBQXlDLEVBQzFCLEVBQUU7SUFDakIsS0FBSyxNQUFNLEtBQUssSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUM5QixNQUFNLEVBQUUsbUJBQW1CLEVBQUUsR0FBRyxLQUFLLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFDaEQsY0FBYyxDQUFDLG1CQUFtQixLQUFLLE1BQU0sc0NBQXNDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUM5RixDQUFDO0FBQ0gsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sNkNBQTZDLEdBQUcsS0FBSyxFQUNoRSxlQUF5QixFQUNELEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUU7SUFDM0MsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FDNUMsZUFBZSxFQUNmLG9CQUFvQixDQUFDLHdCQUF3QixFQUM3QyxTQUFTLENBQ1YsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZCLE9BQU8sMEJBQTBCLENBQUMsb0JBQW9CLENBQUMsZ0NBQWdDLEVBQUU7UUFDdkYsWUFBWTtLQUNiLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLFFBQWlCLEVBQXFDLEVBQUU7SUFDcEYsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDLGdCQUFnQixFQUFFLG9CQUFvQixDQUFDLENBQUMsQ0FBQztJQUNoRixPQUFPO1FBQ0wsY0FBYyxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDO1FBQ2pELGtCQUFrQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7S0FDNUQsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLHFDQUFxQyxHQUFHLENBQ25ELFFBQWlCLEVBQ2UsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDN0MsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUNwRCxhQUFhLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsZ0JBQWdCO0tBQ2pFLENBQUMsQ0FBQztJQUNILE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxXQUFXLENBQzFDLEtBQUssQ0FBQyxVQUFVLEVBQ2hCLG9CQUFvQixDQUFDLHdCQUF3QixFQUM3QyxpQkFBaUIsQ0FDbEIsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sTUFBTSxHQUFHLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsRCxNQUFNLEtBQUssR0FBRyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEQsY0FBYyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEtBQUssVUFBVSxDQUFDLE1BQU07V0FDckQsS0FBSyxDQUFDLGNBQWMsS0FBSyxVQUFVLENBQUMsTUFBTTtXQUMxQyxNQUFNLENBQUMsa0JBQWtCLEtBQUssS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDN0QsT0FBTztRQUNMLFdBQVcsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQztRQUN6QyxNQUFNO1FBQ04sVUFBVTtRQUNWLEtBQUs7UUFDTCxjQUFjLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7S0FDcEQsQ0FBQztBQUNKLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sMENBQTBDLEdBQUcsS0FBSyxFQUM3RCxRQUFpQixFQUNPLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUU7SUFDM0MsTUFBTSxLQUFLLEdBQUcscUNBQXFDLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUQsTUFBTSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsR0FBRyxLQUFLLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFDckQsT0FBTywwQkFBMEIsQ0FBQyxvQkFBb0IsQ0FBQyw2QkFBNkIsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUMvRixDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sQ0FBQyxNQUFNLHFDQUFxQyxHQUFHLEtBQUssRUFDeEQsUUFBaUIsRUFDRSxFQUFFO0lBQ3JCLElBQUksQ0FBQztRQUNILE1BQU0sS0FBSyxHQUFHLHFDQUFxQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzlELE1BQU0sa0JBQWtCLEdBQUcsTUFBTSw2Q0FBNkMsQ0FDNUUsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FDM0QsQ0FBQztRQUNGLGNBQWMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLGtCQUFrQixLQUFLLGtCQUFrQjtlQUNoRSxLQUFLLENBQUMsS0FBSyxDQUFDLGtCQUFrQixLQUFLLGtCQUFrQixDQUFDLENBQUM7UUFDNUQsS0FBSyxNQUFNLFNBQVMsSUFBSSxLQUFLLENBQUMsVUFBVTtZQUFFLE1BQU0sd0JBQXdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNGLE9BQU8sS0FBSyxDQUFDLGNBQWMsS0FBSyxNQUFNLDBDQUEwQyxDQUFDLEtBQUssQ0FBQztZQUNyRixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sQ0FBQyx1RUFBdUUsQ0FBQyxDQUFDO0lBQ25GLENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxLQUFLLEVBQ3JELFFBQWlCLEVBQ08sRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRTtJQUMzQyxNQUFNLEdBQUcsR0FBRyxNQUFNLDRCQUE0QixDQUM1QyxzQkFBc0IsQ0FBQztRQUNyQixNQUFNLEVBQUUsb0NBQW9DO1FBQzVDLFNBQVMsRUFBRSxTQUFTLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQy9DLEVBQUUsSUFBSSxDQUFDLEVBQ1IsSUFBSSxDQUNMLENBQUM7SUFDRixPQUFPLFVBQVUsR0FBRyxFQUFtQixDQUFDO0FBQzFDLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sbUNBQW1DLEdBQUcsS0FBSyxFQUN0RCxRQUFpQixFQUNzQixFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO0lBQzFELE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO0lBQ3hGLE1BQU0sY0FBYyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbEQsTUFBTSxlQUFlLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUM3RCxjQUFjLENBQUMsZUFBZSxLQUFLLE1BQU0sa0NBQWtDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztJQUM3RixLQUFLLE1BQU0sT0FBTyxJQUFJLGNBQWMsQ0FBQyxRQUFRO1FBQUUsTUFBTSx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUYsT0FBTyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLENBQUM7QUFDeEQsQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSx3Q0FBd0MsR0FBRyxLQUFLLEVBQzNELFFBQWlCLEVBQ08sRUFBRSxDQUFDLDBCQUEwQixDQUNyRCxvQkFBb0IsQ0FBQywyQkFBMkIsRUFDaEQsTUFBTSxtQ0FBbUMsQ0FBQyxRQUFRLENBQUMsQ0FDcEQsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1DQUFtQyxHQUFHLEtBQUssRUFDdEQsUUFBaUIsRUFDRSxFQUFFO0lBQ3JCLElBQUksQ0FBQztRQUNILE1BQU0sbUNBQW1DLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEQsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7SUFDaEYsQ0FBQztBQUNILENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1DQUFtQyxHQUFHLEtBQUssRUFDdEQsUUFBaUIsRUFDc0IsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRTtJQUMxRCxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ3BELFdBQVcsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsa0JBQWtCO1FBQ3BGLFlBQVk7S0FDYixDQUFDLENBQUM7SUFDSCxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoRCxNQUFNLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEQsTUFBTSxjQUFjLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNsRCxLQUFLLE1BQU0sT0FBTyxJQUFJLGNBQWMsQ0FBQyxRQUFRO1FBQUUsTUFBTSx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUYsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDM0UsTUFBTSxnQkFBZ0IsR0FBRyxhQUFhLENBQUMsV0FBVyxDQUNoRCxLQUFLLENBQUMsZ0JBQWdCLEVBQ3RCLG9CQUFvQixDQUFDLFlBQVksRUFDakMsb0JBQW9CLENBQ3JCLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDM0QsY0FBYyxDQUFDLFlBQVksQ0FBQyxNQUFNLEtBQUssQ0FBQztXQUNuQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNO1dBQ2pELFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVc7V0FDM0QsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxvQkFBb0I7V0FDN0UsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7V0FDdkUsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsR0FBRyxDQUFDO1dBQy9FLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVU7V0FDdkQsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUI7V0FDM0UsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEtBQUssY0FBYyxDQUFDLGtCQUFrQixDQUFDO1dBQ3hGLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDO1dBQzNCLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxNQUFNO1dBQ3pGLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxnQkFBZ0IsQ0FBQyxNQUFNO1dBQzlGLE9BQU8sQ0FBQyxFQUFFLEtBQUssU0FBUztXQUN4QixTQUFTLENBQUMsZ0JBQWdCLEtBQUssU0FBUyxDQUFDLENBQUM7SUFDL0MsTUFBTSxlQUFlLEdBQUcsTUFBTSxrQ0FBa0MsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNqRixNQUFNLHFCQUFxQixHQUFHLE1BQU0sd0NBQXdDLENBQUM7UUFDM0UsU0FBUyxFQUFFLGNBQWM7UUFDekIsZUFBZTtLQUNoQixDQUFDLENBQUM7SUFDSCxjQUFjLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssZUFBZTtXQUNuRixPQUFPLENBQUMsY0FBYyxLQUFLLHFCQUFxQixDQUFDLENBQUMsQ0FBQztJQUN4RCxNQUFNLFVBQVUsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3BELGNBQWMsQ0FBQyxVQUFVLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FDcEMsR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUNsRCxHQUFHLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FDdkQsQ0FBQyxDQUFDO0lBQ0gsT0FBTztRQUNMLFNBQVM7UUFDVCxPQUFPO1FBQ1AsU0FBUztRQUNULFNBQVMsRUFBRSxjQUFjO1FBQ3pCLFlBQVksRUFBRSxZQUFnRjtRQUM5RixnQkFBZ0I7UUFDaEIsVUFBVTtLQUNYLENBQUM7QUFDSixDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLEtBQUssRUFDN0MsUUFBaUIsRUFDYSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO0lBQ2pELE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDcEQsSUFBSSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsV0FBVztRQUMvRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixFQUFFLFlBQVk7S0FDOUQsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSxtQ0FBbUMsQ0FBQztRQUMxRCxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7UUFDMUIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1FBQ3RCLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztRQUMxQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7UUFDMUIsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZO1FBQ2hDLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7UUFDeEMsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO0tBQzdCLENBQUMsQ0FBQztJQUNILE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDcEQsY0FBYyxDQUFDLFVBQVUsSUFBSSxTQUFTLENBQUMsVUFBVTtXQUM1QyxTQUFTLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDO1dBQ3pFLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDcEYsT0FBTztRQUNMLEVBQUUsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN2QixVQUFVLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDNUMsVUFBVTtRQUNWLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUNuQyxHQUFHLFNBQVM7S0FDYixDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRyxLQUFLLEVBQ2xELFFBQWlCLEVBQ08sRUFBRSxDQUFDLGVBQWUsQ0FDMUMsb0JBQW9CLENBQUMsa0JBQWtCLEVBQ3ZDLE1BQU0sMEJBQTBCLENBQUMsUUFBUSxDQUFDLENBQzNDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxLQUFLLEVBQUUsUUFBaUIsRUFBcUIsRUFBRTtJQUN2RixJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssR0FBRyxNQUFNLDBCQUEwQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3pELE9BQU8sS0FBSyxDQUFDLE1BQU0sS0FBSyxNQUFNLCtCQUErQixDQUFDLEtBQUssQ0FBQztZQUNsRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLDRDQUE0QyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sQ0FBQywwREFBMEQsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRyxDQUM3QyxRQUFtRSxFQUMzQixFQUFFLENBQUMsU0FBUyxDQUFDO0lBQ3JELEVBQUUsRUFBRSxRQUFRLENBQUMsRUFBRTtJQUNmLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVTtJQUMvQixNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU07Q0FDeEIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sNkNBQTZDLEdBQUcsQ0FDM0QsUUFBaUIsRUFDdUIsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUU3RixNQUFNLFVBQVUsR0FBRyxDQUFDLFFBQWlCLEVBQTJCLEVBQUU7SUFDaEUsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRTtRQUNwQyxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLHlCQUF5QjtLQUN2RixDQUFDLENBQUM7SUFDSCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUM7UUFDcEIsYUFBYSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLFNBQVM7S0FDeEQsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekIsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvRSxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3BHLE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxDQUFDLHVCQUF1QixLQUFLLElBQUk7UUFDcEUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQ3BELGNBQWMsQ0FBQyxLQUFLLEtBQUssU0FBUztRQUNoQyxDQUFDLENBQUMsU0FBUyxLQUFLLElBQUksSUFBSSxnQkFBZ0IsS0FBSyxJQUFJLElBQUksdUJBQXVCLEtBQUssSUFBSTtRQUNyRixDQUFDLENBQUMsU0FBUyxLQUFLLElBQUksSUFBSSxnQkFBZ0IsS0FBSyxJQUFJLElBQUksdUJBQXVCLEtBQUssSUFBSSxDQUFDLENBQUM7SUFDekYsT0FBTztRQUNMLGVBQWUsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztRQUNqRCxTQUFTO1FBQ1QsS0FBSztRQUNMLGdCQUFnQjtRQUNoQix1QkFBdUI7S0FDeEIsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLENBQUMsUUFBaUIsRUFBc0IsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDNUYsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUNwRCxJQUFJLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFNBQVM7UUFDakcsU0FBUyxFQUFFLFlBQVksRUFBRSxRQUFRO0tBQ2xDLENBQUMsQ0FBQztJQUNILE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxDQUFDLFlBQVksRUFBRSxVQUFVLENBQVUsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEUsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMvQixNQUFNLFVBQVUsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3BELE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDNUUsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM3QyxNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEQsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxXQUFXLENBQ3ZDLEtBQUssQ0FBQyxPQUFPLEVBQ2Isb0JBQW9CLENBQUMsZUFBZSxFQUNwQyxVQUFVLENBQ1gsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN2QyxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxTQUFTO1dBQ2xDLFNBQVMsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTO1dBQ3hDLENBQUMsVUFBVSxLQUFLLENBQUM7WUFDbEIsQ0FBQyxDQUFDLFFBQVEsS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFlBQVk7WUFDN0MsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEtBQUssVUFBVSxHQUFHLENBQUMsQ0FBQztXQUMvRCxDQUFDLEtBQUssS0FBSyxZQUFZLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hGLE9BQU87UUFDTCxFQUFFO1FBQ0YsVUFBVTtRQUNWLFFBQVE7UUFDUixLQUFLO1FBQ0wsU0FBUztRQUNULE1BQU0sRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUMvQixPQUFPO1FBQ1AsU0FBUztRQUNULE9BQU87UUFDUCxPQUFPLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDakMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQzVDLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztLQUNwQyxDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRyxLQUFLLEVBQ2pELFFBQWlCLEVBQ08sRUFBRSxDQUFDLGVBQWUsQ0FDMUMsb0JBQW9CLENBQUMsaUJBQWlCLEVBQ3RDLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxDQUNwQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsS0FBSyxFQUFFLFFBQWlCLEVBQXFCLEVBQUU7SUFDdEYsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcseUJBQXlCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEQsT0FBTyxLQUFLLENBQUMsTUFBTSxLQUFLLE1BQU0sOEJBQThCLENBQUMsS0FBSyxDQUFDO1lBQ2pFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsMkNBQTJDLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7SUFDckUsQ0FBQztBQUNILENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDhDQUE4QyxHQUFHLENBQzVELFFBQWlCLEVBQ3dCLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO0lBQ3RELE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDcEQsWUFBWSxFQUFFLFdBQVcsRUFBRSx5QkFBeUIsRUFBRSxRQUFRLEVBQUUsaUJBQWlCO0tBQ2xGLENBQUMsQ0FBQztJQUNILE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQyxXQUFXLENBQy9DLEtBQUssQ0FBQyxlQUFlLEVBQ3JCLG9CQUFvQixDQUFDLHNCQUFzQixFQUMzQyxPQUFPLENBQUMsRUFBRTtRQUNSLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUMvRSxPQUFPO1lBQ0wsZUFBZSxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQ2hELFNBQVMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNwQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsYUFBYSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsYUFBYSxDQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQztTQUM3RixDQUFDO0lBQ0osQ0FBQyxDQUNGLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDdkMsT0FBTztRQUNMLFVBQVUsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUN2QyxTQUFTLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDckMsdUJBQXVCLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQztRQUN0RSxNQUFNLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDL0IsZUFBZTtLQUNoQixDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSxzQ0FBc0MsR0FBRyxDQUNwRCxRQUFpQixFQUNnQixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFL0YsTUFBTSxhQUFhLEdBQUcsQ0FBQyxRQUFpQixFQUFvQyxFQUFFO0lBQzVFLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUU7UUFDcEMsSUFBSSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxVQUFVO1FBQ2xFLHFCQUFxQixFQUFFLHFCQUFxQixFQUFFLHNCQUFzQixFQUFFLFNBQVMsRUFBRSxPQUFPO1FBQ3hGLFdBQVcsRUFBRSx1QkFBdUIsRUFBRSx1QkFBdUIsRUFBRSxZQUFZLEVBQUUsUUFBUTtLQUN0RixDQUFDLENBQUM7SUFDSCxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoRCxNQUFNLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEQsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEtBQUssVUFBVTtXQUNsRSxTQUFTLENBQUMsZ0JBQWdCLEtBQUssU0FBUyxDQUFDLENBQUM7SUFDL0MsT0FBTztRQUNMLEVBQUUsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN2QixVQUFVLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDNUMsU0FBUztRQUNULE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUNuQyxTQUFTLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDckMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQ25DLG1CQUFtQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUM7UUFDN0QsbUJBQW1CLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQztRQUM3RCxvQkFBb0IsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDO1FBQy9ELE9BQU8sRUFBRSxPQUFzRDtRQUMvRCxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDN0IsU0FBUztRQUNULHFCQUFxQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUM7UUFDN0QscUJBQXFCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQztRQUM3RCxVQUFVLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDNUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO0tBQ3BDLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSx1Q0FBdUMsR0FBRyxDQUNyRCxRQUFpQixFQUNpQixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRTNGLE1BQU0sQ0FBQyxNQUFNLHNDQUFzQyxHQUFHLEtBQUssRUFDekQsUUFBaUIsRUFDTyxFQUFFLENBQUMsZUFBZSxDQUMxQyxvQkFBb0IsQ0FBQyx5QkFBeUIsRUFDOUMsdUNBQXVDLENBQUMsUUFBUSxDQUFDLENBQ2xELENBQUM7QUFFRixNQUFNLFdBQVcsR0FBRyxDQUFDLFFBQWlCLEVBQTRCLEVBQUU7SUFDbEUsY0FBYyxDQUFDLFFBQVEsS0FBSyxJQUFJLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUM7SUFDbEUsTUFBTSxLQUFLLEdBQUksUUFBb0MsQ0FBQyxLQUFLLENBQUM7SUFDMUQsTUFBTSxZQUFZLEdBQUcsS0FBSyxLQUFLLFVBQVU7UUFDdkMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDdkUsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRTtRQUNwQyxJQUFJLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxVQUFVO1FBQzlFLHFCQUFxQixFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxHQUFHLFlBQVk7UUFDekYsUUFBUTtLQUNULENBQUMsQ0FBQztJQUNILGNBQWMsQ0FBQyxLQUFLLEtBQUssTUFBTSxJQUFJLEtBQUssS0FBSyxVQUFVLENBQUMsQ0FBQztJQUN6RCxNQUFNLEVBQUUsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQy9CLE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDcEQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1RSxjQUFjLENBQUMsVUFBVSxLQUFLLENBQUM7UUFDN0IsQ0FBQyxDQUFDLFFBQVEsS0FBSyxJQUFJO1FBQ25CLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNuRSxNQUFNLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDeEQsY0FBYyxDQUFDLFdBQVcsQ0FBQyxLQUFLLEtBQUssVUFBVSxDQUFDLENBQUM7SUFDakQsTUFBTSxJQUFJLEdBQWlDO1FBQ3pDLEVBQUU7UUFDRixVQUFVO1FBQ1YsUUFBUTtRQUNSLFNBQVMsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUNyQyxNQUFNLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDbkMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ3JDLFFBQVEsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztRQUNuQyxtQkFBbUIsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDO1FBQzdELGFBQWEsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQztRQUM3QyxXQUFXLEVBQUUsV0FBMEQ7UUFDdkUsTUFBTSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQ3BDLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztLQUNwQyxDQUFDO0lBQ0YsSUFBSSxLQUFLLEtBQUssTUFBTTtRQUFFLE9BQU8sRUFBRSxHQUFHLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUNoRCxNQUFNLGVBQWUsR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDaEUsY0FBYyxDQUFDLGVBQWUsQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUM7SUFDbkQsT0FBTztRQUNMLEdBQUcsSUFBSTtRQUNQLEtBQUs7UUFDTCxlQUFlLEVBQUUsZUFBOEY7UUFDL0csZUFBZSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO1FBQ2pELEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUM3QixVQUFVLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7S0FDN0MsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLENBQzdDLFFBQWlCLEVBQ1MsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVqRixNQUFNLENBQUMsTUFBTSxvQ0FBb0MsR0FBRyxLQUFLLEVBQ3ZELFFBQWlCLEVBQ08sRUFBRSxDQUFDLGVBQWUsQ0FDMUMsb0JBQW9CLENBQUMsdUJBQXVCLEVBQzVDLCtCQUErQixDQUFDLFFBQVEsQ0FBQyxDQUMxQyxDQUFDO0FBRUYsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLFFBQWlCLEVBQXlDLEVBQUU7SUFDckYsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRTtRQUNwQyxJQUFJLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFVBQVU7UUFDbEUscUJBQXFCLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxxQkFBcUIsRUFBRSxPQUFPO1FBQ3JGLFlBQVksRUFBRSxZQUFZLEVBQUUsUUFBUTtLQUNyQyxDQUFDLENBQUM7SUFDSCxjQUFjLENBQUMsS0FBSyxDQUFDLFVBQVUsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxlQUFlLENBQUMsQ0FBQztJQUMvRSxPQUFPO1FBQ0wsRUFBRSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLFVBQVUsRUFBRSxDQUFDO1FBQ2IsU0FBUyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ3JDLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUNuQyxTQUFTLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDckMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQ25DLG1CQUFtQixFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUM7UUFDN0QsYUFBYSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDO1FBQzdDLFdBQVcsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQztRQUN6QyxtQkFBbUIsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDO1FBQzdELEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUM3QixVQUFVLEVBQUUsZUFBZTtRQUMzQixVQUFVLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7UUFDNUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO0tBQ3BDLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw0Q0FBNEMsR0FBRyxDQUMxRCxRQUFpQixFQUNzQixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLGlCQUFpQixDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFcEcsTUFBTSxDQUFDLE1BQU0sMENBQTBDLEdBQUcsS0FBSyxFQUM3RCxRQUFpQixFQUNPLEVBQUUsQ0FBQyxlQUFlLENBQzFDLG9CQUFvQixDQUFDLDZCQUE2QixFQUNsRCw0Q0FBNEMsQ0FBQyxRQUFRLENBQUMsQ0FDdkQsQ0FBQztBQUVGLHdHQUF3RztBQUN4RyxNQUFNLENBQUMsTUFBTSxxQ0FBcUMsR0FBRyxDQUNuRCxXQUFvQixFQUNwQixRQUFpQixFQUNxRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUNuRyxNQUFNLFFBQVEsR0FBRyw0Q0FBNEMsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUMzRSxNQUFNLEtBQUssR0FBRywrQkFBK0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4RCxjQUFjLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxNQUFNO1dBQ2hDLFFBQVEsQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLFNBQVM7V0FDdEMsUUFBUSxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsTUFBTTtXQUNoQyxRQUFRLENBQUMsU0FBUyxLQUFLLEtBQUssQ0FBQyxTQUFTO1dBQ3RDLFFBQVEsQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLFFBQVE7V0FDcEMsUUFBUSxDQUFDLG1CQUFtQixLQUFLLEtBQUssQ0FBQyxtQkFBbUI7V0FDMUQsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLGFBQWEsQ0FBQyxFQUFFO1dBQ3BELFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxLQUFLLEtBQUssQ0FBQyxhQUFhLENBQUMsVUFBVTtXQUNwRSxRQUFRLENBQUMsYUFBYSxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsYUFBYSxDQUFDLE1BQU07V0FDNUQsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLEVBQUU7V0FDcEMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEtBQUssS0FBSyxDQUFDLFVBQVU7V0FDcEQsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDN0IsQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSx1Q0FBdUMsR0FBRyxLQUFLLEVBQUUsUUFBaUIsRUFBcUIsRUFBRTtJQUNwRyxJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssR0FBRyx1Q0FBdUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRSxPQUFPLEtBQUssQ0FBQyxNQUFNLEtBQUssTUFBTSxzQ0FBc0MsQ0FBQyxLQUFLLENBQUM7WUFDekUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFBQyxNQUFNLENBQUM7UUFBQyxPQUFPLENBQUMsa0VBQWtFLENBQUMsQ0FBQztJQUFDLENBQUM7QUFDMUYsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQUcsS0FBSyxFQUFFLFFBQWlCLEVBQXFCLEVBQUU7SUFDNUYsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsK0JBQStCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEQsT0FBTyxLQUFLLENBQUMsTUFBTSxLQUFLLE1BQU0sb0NBQW9DLENBQUMsS0FBSyxDQUFDO1lBQ3ZFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsa0RBQWtELENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQUMsT0FBTyxDQUFDLGdFQUFnRSxDQUFDLENBQUM7SUFBQyxDQUFDO0FBQ3hGLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDRDQUE0QyxHQUFHLEtBQUssRUFDL0QsUUFBaUIsRUFDRSxFQUFFO0lBQ3JCLElBQUksQ0FBQztRQUNILE1BQU0sS0FBSyxHQUFHLDRDQUE0QyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JFLE9BQU8sS0FBSyxDQUFDLE1BQU0sS0FBSyxNQUFNLDBDQUEwQyxDQUFDLEtBQUssQ0FBQztZQUM3RSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLHdEQUF3RCxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUFDLE9BQU8sQ0FBQyw4RUFBOEUsQ0FBQyxDQUFDO0lBQUMsQ0FBQztBQUN0RyxDQUFDLENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxDQUFDLFFBQWlCLEVBQTBCLEVBQUU7SUFDbkUsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLFFBQVEsRUFBRTtRQUNwQyxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLHNCQUFzQixFQUFFLGNBQWM7UUFDbEYsc0JBQXNCLEVBQUUsWUFBWSxFQUFFLGtCQUFrQjtLQUN6RCxDQUFDLENBQUM7SUFDSCxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUM1RSxjQUFjLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQztJQUM5RSxPQUFPO1FBQ0wsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztRQUNyRCxNQUFNLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDbkMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ3JDLG9CQUFvQixFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUM7UUFDaEUsWUFBWSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO1FBQ2hELG9CQUFvQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUM7UUFDM0QsVUFBVSxFQUFFO1lBQ1YsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO1lBQ3JCLEVBQUUsRUFBRSxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUM1QixLQUFLLEVBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7U0FDbkM7UUFDRCxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDO0tBQ3BELENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw4Q0FBOEMsR0FBRyxDQUM1RCxRQUFpQixFQUN3QixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUN0RCxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ3BELElBQUksRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxPQUFPO1FBQ2xGLFFBQVEsRUFBRSxZQUFZLEVBQUUsUUFBUTtLQUNqQyxDQUFDLENBQUM7SUFDSCxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRTtRQUN2QyxXQUFXLEVBQUUsUUFBUSxFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLGFBQWEsRUFBRSxZQUFZO1FBQzFGLGFBQWEsRUFBRSxvQkFBb0IsRUFBRSxpQkFBaUIsRUFBRSxZQUFZO1FBQ3BFLHNCQUFzQixFQUFFLFNBQVM7S0FDbEMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUU7UUFDdkMsUUFBUSxFQUFFLHNCQUFzQixFQUFFLG1CQUFtQixFQUFFLHFCQUFxQjtRQUM1RSxhQUFhLEVBQUUsZUFBZSxFQUFFLG9CQUFvQjtRQUNwRCxzQkFBc0IsRUFBRSxVQUFVLEVBQUUsWUFBWTtLQUNqRCxDQUFDLENBQUM7SUFDSCxNQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRTtRQUN6QyxZQUFZLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQjtRQUNsRSx1QkFBdUIsRUFBRSxjQUFjLEVBQUUsbUJBQW1CO0tBQzdELENBQUMsQ0FBQztJQUNILE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsTUFBTSxPQUFPLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hELE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0RCxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxTQUFTLElBQUksT0FBTyxDQUFDLEtBQUssS0FBSyxPQUFPO1dBQy9ELFNBQVMsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUMvQyxNQUFNLFdBQVcsR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2hELE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEQsY0FBYyxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUMsQ0FBQztJQUM1QyxNQUFNLG9CQUFvQixHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDOUQsTUFBTSxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3RELGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLEtBQUssZ0JBQWdCLENBQUMsRUFBRTtXQUN6RCxvQkFBb0IsQ0FBQyxVQUFVLEtBQUssZ0JBQWdCLENBQUMsVUFBVTtXQUMvRCxvQkFBb0IsQ0FBQyxNQUFNLEtBQUssZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUQsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxjQUFjLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQy9DLE9BQU87UUFDTCxFQUFFLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdkIsVUFBVSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQzVDLFNBQVM7UUFDVCxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDN0IsU0FBUztRQUNULE9BQU87UUFDUCxLQUFLLEVBQUU7WUFDTCxTQUFTLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7WUFDckMsTUFBTSxFQUFFLFdBQVc7WUFDbkIsZUFBZSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO1lBQ2pELGlCQUFpQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUM7WUFDckQsV0FBVyxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO1lBQzlDLFVBQVUsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztZQUMzQyxXQUFXLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUM7WUFDN0Msa0JBQWtCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztZQUN2RCxlQUFlLEVBQUUsb0JBQW9CO1lBQ3JDLFVBQVUsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztZQUN2QyxvQkFBb0IsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDO1lBQzNELE9BQU8sRUFBRSxZQUFZO1NBQ3RCO1FBQ0QsS0FBSyxFQUFFO1lBQ0wsTUFBTSxFQUFFLFdBQVc7WUFDbkIsb0JBQW9CLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQztZQUNoRSxpQkFBaUIsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDO1lBQ3JELG1CQUFtQixFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUM7WUFDOUQsV0FBVyxFQUFFLGdCQUFnQjtZQUM3QixhQUFhLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUM7WUFDbEQsa0JBQWtCLEVBQUUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3hCLGNBQWMsQ0FBQyxPQUFPLEtBQUssQ0FBQyxrQkFBa0IsS0FBSyxRQUFRO3VCQUN0RCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQztnQkFDdEQsT0FBTyxLQUFLLENBQUMsa0JBQWtCLENBQUM7WUFDbEMsQ0FBQyxDQUFDLEVBQUU7WUFDSixvQkFBb0IsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDO1lBQzNELFFBQVEsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztZQUNuQyxVQUFVLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7U0FDNUM7UUFDRCxNQUFNLEVBQUU7WUFDTixVQUFVLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDeEMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDO1lBQzVDLGNBQWMsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQztZQUNoRCxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1lBQ3BELHFCQUFxQixFQUFFLGNBQWMsQ0FBQyxNQUFNLENBQUMscUJBQXFCLENBQUM7WUFDbkUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDO1lBQzVDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxDQUFDLGdCQUFnQixFQUFFLFNBQVMsQ0FBVSxFQUFFLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztTQUM3RjtRQUNELFVBQVUsRUFBRSxjQUFjLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUM1QyxNQUFNLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7S0FDcEMsQ0FBQztBQUNKLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sMkNBQTJDLEdBQUcsS0FBSyxFQUM5RCxRQUFpQixFQUNPLEVBQUUsQ0FBQyxlQUFlLENBQzFDLG9CQUFvQixDQUFDLDhCQUE4QixFQUNuRCw4Q0FBOEMsQ0FBQyxRQUFRLENBQUMsQ0FDekQsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDhDQUE4QyxHQUFHLEtBQUssRUFDakUsUUFBaUIsRUFDRSxFQUFFO0lBQ3JCLElBQUksQ0FBQztRQUNILE1BQU0sS0FBSyxHQUFHLDhDQUE4QyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZFLE9BQU8sS0FBSyxDQUFDLE1BQU0sS0FBSyxNQUFNLDJDQUEyQyxDQUFDLEtBQUssQ0FBQztZQUM5RSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUFDLE9BQU8sQ0FBQyxnRkFBZ0YsQ0FBQyxDQUFDO0lBQUMsQ0FBQztBQUN4RyxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw2Q0FBNkMsR0FBRyxDQUMzRCxRQUFpQixFQUN1QixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUNyRCxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ3BELFlBQVksRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLFdBQVc7UUFDckYsc0JBQXNCLEVBQUUscUJBQXFCO0tBQzlDLENBQUMsQ0FBQztJQUNILE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsTUFBTSxjQUFjLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzlELE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0RCxjQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsS0FBSyxTQUFTLElBQUksY0FBYyxDQUFDLEtBQUssS0FBSyxRQUFRO1dBQzlFLFNBQVMsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUMvQyxPQUFPO1FBQ0wsVUFBVSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQ3ZDLFNBQVM7UUFDVCxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDO1FBQ25ELGNBQWMsRUFBRSxjQUEwRTtRQUMxRixLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDN0IsU0FBUztRQUNULG9CQUFvQixFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUM7UUFDaEUsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLG1CQUFtQixLQUFLLElBQUk7WUFDckQsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQztLQUNoRCxDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSxzQ0FBc0MsR0FBRyxDQUNwRCxRQUFpQixFQUNnQixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUM5QyxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ3BELElBQUksRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFdBQVc7UUFDNUUsa0JBQWtCLEVBQUUsc0JBQXNCLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsUUFBUTtLQUM1RixDQUFDLENBQUM7SUFDSCxNQUFNLEVBQUUsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQy9CLE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDcEQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1RSxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoRCxNQUFNLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEQsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEtBQUssUUFBUTtXQUNoRSxTQUFTLENBQUMsZ0JBQWdCLEtBQUssU0FBUztXQUN4QyxDQUFDLFVBQVUsS0FBSyxDQUFDO1lBQ2xCLENBQUMsQ0FBQyxRQUFRLEtBQUssSUFBSTtZQUNuQixDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksUUFBUSxDQUFDLFVBQVUsS0FBSyxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RSxPQUFPO1FBQ0wsRUFBRTtRQUNGLFVBQVU7UUFDVixRQUFRO1FBQ1IsU0FBUztRQUNULE9BQU8sRUFBRSxPQUFxRDtRQUM5RCxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDN0IsU0FBUztRQUNULGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUM7UUFDbkQsb0JBQW9CLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQztRQUNoRSxVQUFVLEVBQUUsMEJBQTBCLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUN4RCxPQUFPLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDakMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQzVDLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztLQUNwQyxDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSwyQ0FBMkMsR0FBRyxLQUFLLEVBQzlELFFBQWlCLEVBQ08sRUFBRSxDQUFDLGVBQWUsQ0FDMUMsb0JBQW9CLENBQUMsOEJBQThCLEVBQ25ELHNDQUFzQyxDQUFDLFFBQVEsQ0FBQyxDQUNqRCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sc0NBQXNDLEdBQUcsS0FBSyxFQUN6RCxRQUFpQixFQUNFLEVBQUU7SUFDckIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsc0NBQXNDLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0QsT0FBTyxLQUFLLENBQUMsTUFBTSxLQUFLLE1BQU0sMkNBQTJDLENBQUMsS0FBSyxDQUFDO1lBQzlFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMseURBQXlELENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQUMsT0FBTyxDQUFDLHVFQUF1RSxDQUFDLENBQUM7SUFBQyxDQUFDO0FBQy9GLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG9DQUFvQyxHQUFHLENBQ2xELFFBQWlCLEVBQ2MsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7SUFDNUMsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUNwRCxJQUFJLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxrQkFBa0I7UUFDcEYsWUFBWSxFQUFFLFNBQVMsRUFBRSxxQkFBcUIsRUFBRSwyQkFBMkI7UUFDM0Usc0JBQXNCLEVBQUUsbUJBQW1CLEVBQUUsbUJBQW1CLEVBQUUsY0FBYztRQUNoRixvQkFBb0IsRUFBRSxvQkFBb0IsRUFBRSxZQUFZLEVBQUUsUUFBUTtLQUNuRSxDQUFDLENBQUM7SUFDSCxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoRCxNQUFNLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEQsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5QyxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxTQUFTLElBQUksT0FBTyxDQUFDLEtBQUssS0FBSyxRQUFRO1dBQ2hFLFNBQVMsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLElBQUksT0FBTyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUNsRixPQUFPO1FBQ0wsRUFBRSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLFVBQVUsRUFBRSxjQUFjLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUM1QyxTQUFTO1FBQ1QsT0FBTyxFQUFFLE9BQW1EO1FBQzVELEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUM3QixTQUFTO1FBQ1QsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztRQUNuRCxVQUFVLEVBQUUsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUNqRCxPQUFPO1FBQ1AsbUJBQW1CLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQztRQUN6RCx5QkFBeUIsRUFBRSxLQUFLLENBQUMseUJBQXlCLEtBQUssSUFBSTtZQUNqRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLHlCQUF5QixDQUFDO1FBQ3ZELG9CQUFvQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUM7UUFDM0QsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztRQUNyRCxpQkFBaUIsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDO1FBQ3JELFlBQVksRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztRQUMzQyxrQkFBa0IsRUFBRSxXQUFXLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBQ3pELGtCQUFrQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7UUFDdkQsVUFBVSxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQzVDLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztLQUNwQyxDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUM7QUFFSCxNQUFNLENBQUMsTUFBTSx5Q0FBeUMsR0FBRyxLQUFLLEVBQzVELFFBQWlCLEVBQ08sRUFBRSxDQUFDLGVBQWUsQ0FDMUMsb0JBQW9CLENBQUMsNEJBQTRCLEVBQ2pELG9DQUFvQyxDQUFDLFFBQVEsQ0FBQyxDQUMvQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sb0NBQW9DLEdBQUcsS0FBSyxFQUFFLFFBQWlCLEVBQXFCLEVBQUU7SUFDakcsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsb0NBQW9DLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0QsT0FBTyxLQUFLLENBQUMsTUFBTSxLQUFLLE1BQU0seUNBQXlDLENBQUMsS0FBSyxDQUFDO1lBQzVFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsdURBQXVELENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQUMsT0FBTyxDQUFDLHFFQUFxRSxDQUFDLENBQUM7SUFBQyxDQUFDO0FBQzdGLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLENBQ2hELE9BQTZCLEVBQzdCLEtBQTJCLEVBQ2xCLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsS0FBSyxLQUFLLENBQUM7QUFFNUUsTUFBTSxDQUFDLE1BQU0sZ0NBQWdDLEdBQUcsQ0FDOUMsUUFBaUIsRUFDVSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUN4QyxjQUFjLENBQUMsUUFBUSxLQUFLLElBQUksSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQztJQUNsRSxNQUFNLFNBQVMsR0FBRyxRQUFtQyxDQUFDO0lBQ3RELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxDQUFVLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xGLE1BQU0sVUFBVSxHQUFHLG9CQUFvQixDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BFLGNBQWMsQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLFVBQVUsQ0FBQyxDQUFDO0lBQzVDLE1BQU0sU0FBUyxHQUFHLElBQUksS0FBSyxPQUFPO1FBQ2hDLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDO1FBQ3hCLENBQUMsQ0FBQyxJQUFJLEtBQUssVUFBVTtZQUNuQixDQUFDLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQztZQUM3RCxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3BFLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDcEQsWUFBWSxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxTQUFTO0tBQzlGLENBQUMsQ0FBQztJQUNILE1BQU0sY0FBYyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM5RCxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0RCxjQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsS0FBSyxTQUFTLElBQUksY0FBYyxDQUFDLEtBQUssS0FBSyxJQUFJO1dBQzFFLFNBQVMsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUMvQyxNQUFNLElBQUksR0FBa0M7UUFDMUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQ3ZDLFNBQVM7UUFDVCxjQUFjO1FBQ2QsS0FBSyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQzdCLFNBQVM7S0FDVixDQUFDO0lBQ0YsSUFBSSxJQUFJLEtBQUssT0FBTztRQUFFLE9BQU87WUFDM0IsR0FBRyxJQUFJO1lBQ1AsSUFBSTtZQUNKLEVBQUUsRUFBRSxVQUFVO1lBQ2Qsa0JBQWtCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztTQUN4RCxDQUFDO0lBQ0YsSUFBSSxJQUFJLEtBQUssVUFBVTtRQUFFLE9BQU87WUFDOUIsR0FBRyxJQUFJO1lBQ1AsSUFBSTtZQUNKLEVBQUUsRUFBRSxXQUFXO1lBQ2YsZUFBZSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDO1lBQ2pELGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUM7WUFDbkQsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztTQUNwRCxDQUFDO0lBQ0YsT0FBTztRQUNMLEdBQUcsSUFBSTtRQUNQLElBQUk7UUFDSixFQUFFLEVBQUUsUUFBUTtRQUNaLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUM7UUFDbkQsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztRQUNuRCxpQkFBaUIsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDO0tBQ3RELENBQUM7QUFDSixDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sQ0FBQyxNQUFNLHNDQUFzQyxHQUFHLENBQ3BELFFBQWlCLEVBQ2dCLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO0lBQzlDLGNBQWMsQ0FBQyxRQUFRLEtBQUssSUFBSSxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQVUsRUFBRyxRQUFvQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RHLE1BQU0sV0FBVyxHQUFHLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQztJQUMxRixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ3BELE1BQU0sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxzQkFBc0IsRUFBRSxTQUFTLEVBQUUsT0FBTztRQUMxRixXQUFXO0tBQ1osQ0FBQyxDQUFDO0lBQ0gsTUFBTSxPQUFPLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hELE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUM7SUFDdkUsTUFBTSxJQUFJLEdBQUc7UUFDWCxJQUFJO1FBQ0osVUFBVSxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQ3ZDLFNBQVM7UUFDVCxTQUFTLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDckMsb0JBQW9CLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQztRQUNoRSxPQUFPLEVBQUUsT0FBcUQ7UUFDOUQsS0FBSyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0tBQzlCLENBQUM7SUFDRixPQUFPLElBQUksS0FBSyxTQUFTO1FBQ3ZCLENBQUMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxFQUFFLElBQUksRUFBRSx5QkFBeUIsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLHlCQUF5QixDQUFDLEVBQUU7UUFDMUYsQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDO0FBQzdFLENBQUMsQ0FBQyxDQUFDIn0=