@push.rocks/smartnetwork 4.9.0 → 4.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,15 +28,15 @@ export interface IIpIntelligenceOptions {
28
28
  timeout?: number;
29
29
  /**
30
30
  * Optional injected smartdns client. When provided, IpIntelligence will
31
- * not create or destroy its own client (the owner — typically SmartNetwork —
31
+ * not create or terminate its own client (the owner — typically SmartNetwork —
32
32
  * manages lifecycle). When omitted, a short-lived client is created per
33
- * Team Cymru lookup and destroyed in finally.
33
+ * Team Cymru lookup and terminated in finally.
34
34
  */
35
35
  dnsClient?: InstanceType<typeof plugins.smartdns.dnsClientMod.Smartdns>;
36
36
  }
37
37
  /**
38
38
  * IpIntelligence provides IP address intelligence by combining three data sources:
39
- * - RDAP (direct to RIRs) for registration/org data
39
+ * - RDAP (direct to RIRs, via @push.rocks/smartwhois) for registration/org data
40
40
  * - Team Cymru DNS for ASN
41
41
  * - MaxMind GeoLite2 (in-memory MMDB) for geolocation
42
42
  */
@@ -48,47 +48,30 @@ export declare class IpIntelligence {
48
48
  private asnReader;
49
49
  private lastFetchTime;
50
50
  private refreshPromise;
51
- private bootstrapEntries;
52
- private bootstrapPromise;
51
+ private readonly rdapClient;
53
52
  private readonly sharedDnsClient;
53
+ private ownedDnsClient;
54
+ private dnsLifecycleQueue;
54
55
  constructor(options?: IIpIntelligenceOptions);
55
56
  /**
56
57
  * Get comprehensive IP intelligence for the given IP address.
57
58
  * Runs RDAP, Team Cymru DNS, and MaxMind lookups in parallel.
58
59
  */
59
60
  getIntelligence(ip: string): Promise<IIpIntelligenceResult>;
61
+ /** Retry and confirm cleanup of a standalone DNS client, if one is retained. */
62
+ stop(): Promise<void>;
60
63
  /**
61
- * Load and cache the IANA RDAP bootstrap file
62
- */
63
- private ensureBootstrap;
64
- /**
65
- * Find the RDAP base URL for a given IP via longest-prefix match
66
- */
67
- private matchRir;
68
- /**
69
- * Query RDAP for registration data
64
+ * Query RDAP for registration data via the smartwhois RdapClient (IPv4 and IPv6).
70
65
  */
71
66
  private queryRdap;
72
- private parseRdapNetworkInfo;
73
- private extractRdapCidrs;
74
- /**
75
- * Extract the 'fn' (formatted name) from an entity's vcardArray
76
- */
77
- private extractVcardFn;
78
- /**
79
- * Extract email from an entity's vcardArray
80
- */
81
- private extractVcardEmail;
82
- /**
83
- * Extract country from an entity's vcardArray address field
84
- */
85
- private extractVcardCountry;
86
67
  /**
87
68
  * Query Team Cymru DNS for ASN information.
88
69
  * Query format: reversed.ip.origin.asn.cymru.com TXT
89
70
  * Response: "ASN | prefix | CC | rir | date"
90
71
  */
91
72
  private queryTeamCymru;
73
+ private enqueueDnsLifecycle;
74
+ private terminateOwnedDnsClient;
92
75
  /**
93
76
  * Ensure MMDB readers are initialized. Downloads on first call,
94
77
  * triggers background refresh if stale.
@@ -106,12 +89,4 @@ export declare class IpIntelligence {
106
89
  * Query MaxMind for geo + ASN data
107
90
  */
108
91
  private queryMaxMind;
109
- /**
110
- * Convert an IPv4 address string to a 32-bit unsigned number
111
- */
112
- private ipToNumber;
113
- private ipv4RangeToCidrs;
114
- private ipv4ToBigInt;
115
- private numberToIpv4;
116
- private powerOfTwoExponent;
117
92
  }
@@ -3,13 +3,11 @@ import { getLogger } from './logging.js';
3
3
  // CDN URLs for GeoLite2 MMDB files (served via jsDelivr from npm packages)
4
4
  const CITY_MMDB_URL = 'https://cdn.jsdelivr.net/npm/@ip-location-db/geolite2-city-mmdb/geolite2-city-ipv4.mmdb';
5
5
  const ASN_MMDB_URL = 'https://cdn.jsdelivr.net/npm/@ip-location-db/geolite2-asn-mmdb/geolite2-asn-ipv4.mmdb';
6
- // IANA bootstrap for RDAP
7
- const IANA_BOOTSTRAP_IPV4_URL = 'https://data.iana.org/rdap/ipv4.json';
8
6
  const DEFAULT_DB_MAX_AGE = 7 * 24 * 60 * 60 * 1000; // 7 days
9
7
  const DEFAULT_TIMEOUT = 5000;
10
8
  /**
11
9
  * IpIntelligence provides IP address intelligence by combining three data sources:
12
- * - RDAP (direct to RIRs) for registration/org data
10
+ * - RDAP (direct to RIRs, via @push.rocks/smartwhois) for registration/org data
13
11
  * - Team Cymru DNS for ASN
14
12
  * - MaxMind GeoLite2 (in-memory MMDB) for geolocation
15
13
  */
@@ -21,12 +19,16 @@ export class IpIntelligence {
21
19
  this.asnReader = null;
22
20
  this.lastFetchTime = 0;
23
21
  this.refreshPromise = null;
24
- // RDAP bootstrap cache
25
- this.bootstrapEntries = null;
26
- this.bootstrapPromise = null;
22
+ this.ownedDnsClient = null;
23
+ this.dnsLifecycleQueue = Promise.resolve();
27
24
  this.dbMaxAge = options?.dbMaxAge ?? DEFAULT_DB_MAX_AGE;
28
25
  this.timeout = options?.timeout ?? DEFAULT_TIMEOUT;
29
26
  this.sharedDnsClient = options?.dnsClient ?? null;
27
+ this.rdapClient = new plugins.smartwhois.RdapClient({
28
+ requestTimeoutMs: this.timeout,
29
+ totalTimeoutMs: this.timeout,
30
+ userAgent: '@push.rocks/smartnetwork',
31
+ });
30
32
  }
31
33
  /**
32
34
  * Get comprehensive IP intelligence for the given IP address.
@@ -55,6 +57,9 @@ export class IpIntelligence {
55
57
  this.queryTeamCymru(ip),
56
58
  this.queryMaxMind(ip),
57
59
  ]);
60
+ if (cymruResult.status === 'rejected') {
61
+ throw cymruResult.reason;
62
+ }
58
63
  // Merge RDAP results
59
64
  if (rdapResult.status === 'fulfilled' && rdapResult.value) {
60
65
  const rdap = rdapResult.value;
@@ -91,228 +96,33 @@ export class IpIntelligence {
91
96
  // the asnOrg remains null (we don't do an additional lookup)
92
97
  return result;
93
98
  }
94
- // ─── RDAP Subsystem ─────────────────────────────────────────────────
95
- /**
96
- * Load and cache the IANA RDAP bootstrap file
97
- */
98
- async ensureBootstrap() {
99
- if (this.bootstrapEntries)
100
- return;
101
- if (this.bootstrapPromise) {
102
- await this.bootstrapPromise;
103
- return;
104
- }
105
- this.bootstrapPromise = (async () => {
106
- try {
107
- const controller = new AbortController();
108
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
109
- try {
110
- const response = await fetch(IANA_BOOTSTRAP_IPV4_URL, {
111
- signal: controller.signal,
112
- headers: { 'User-Agent': '@push.rocks/smartnetwork' },
113
- });
114
- if (!response.ok)
115
- throw new Error(`HTTP ${response.status}`);
116
- const data = await response.json();
117
- const entries = [];
118
- for (const [prefixes, urls] of data.services) {
119
- const baseUrl = urls[0]; // first URL is preferred
120
- for (const prefix of prefixes) {
121
- const [network, bits] = prefix.split('/');
122
- entries.push({
123
- prefix,
124
- prefixNum: this.ipToNumber(network),
125
- maskBits: parseInt(bits, 10),
126
- baseUrl: baseUrl.replace(/\/$/, ''), // strip trailing slash
127
- });
128
- }
129
- }
130
- // Sort by mask bits descending for longest-prefix match
131
- entries.sort((a, b) => b.maskBits - a.maskBits);
132
- this.bootstrapEntries = entries;
133
- }
134
- finally {
135
- clearTimeout(timeoutId);
136
- }
137
- }
138
- catch (err) {
139
- this.logger.debug?.(`Failed to load RDAP bootstrap: ${err.message}`);
140
- this.bootstrapEntries = []; // empty = all RDAP lookups will skip
141
- }
142
- })();
143
- await this.bootstrapPromise;
144
- this.bootstrapPromise = null;
99
+ /** Retry and confirm cleanup of a standalone DNS client, if one is retained. */
100
+ stop() {
101
+ if (this.sharedDnsClient)
102
+ return Promise.resolve();
103
+ return this.enqueueDnsLifecycle(() => this.terminateOwnedDnsClient());
145
104
  }
105
+ // ─── RDAP Subsystem (delegated to @push.rocks/smartwhois) ───────────
146
106
  /**
147
- * Find the RDAP base URL for a given IP via longest-prefix match
148
- */
149
- matchRir(ip) {
150
- if (!this.bootstrapEntries || this.bootstrapEntries.length === 0)
151
- return null;
152
- const ipNum = this.ipToNumber(ip);
153
- for (const entry of this.bootstrapEntries) {
154
- const mask = (0xFFFFFFFF << (32 - entry.maskBits)) >>> 0;
155
- if ((ipNum & mask) === (entry.prefixNum & mask)) {
156
- return entry.baseUrl;
157
- }
158
- }
159
- return null;
160
- }
161
- /**
162
- * Query RDAP for registration data
107
+ * Query RDAP for registration data via the smartwhois RdapClient (IPv4 and IPv6).
163
108
  */
164
109
  async queryRdap(ip) {
165
- await this.ensureBootstrap();
166
- const baseUrl = this.matchRir(ip);
167
- if (!baseUrl)
168
- return null;
169
- const controller = new AbortController();
170
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
171
110
  try {
172
- const response = await fetch(`${baseUrl}/ip/${ip}`, {
173
- signal: controller.signal,
174
- headers: {
175
- 'Accept': 'application/rdap+json',
176
- 'User-Agent': '@push.rocks/smartnetwork',
177
- },
178
- });
179
- if (!response.ok)
111
+ const rdapRecord = await this.rdapClient.lookupIp(ip);
112
+ if (!rdapRecord)
180
113
  return null;
181
- const data = await response.json();
182
- let registrantOrg = null;
183
- let registrantCountry = data.country || null;
184
- let abuseContact = null;
185
- const { networkRange, networkCidrs } = this.parseRdapNetworkInfo(data);
186
- // Parse entities
187
- if (data.entities && Array.isArray(data.entities)) {
188
- for (const entity of data.entities) {
189
- const roles = entity.roles || [];
190
- if (roles.includes('registrant') || roles.includes('administrative')) {
191
- const orgName = this.extractVcardFn(entity);
192
- if (orgName)
193
- registrantOrg = orgName;
194
- // Try to get country from registrant address if not at top level
195
- if (!registrantCountry) {
196
- registrantCountry = this.extractVcardCountry(entity);
197
- }
198
- }
199
- if (roles.includes('abuse')) {
200
- abuseContact = this.extractVcardEmail(entity);
201
- // Check nested entities for abuse contact
202
- if (!abuseContact && entity.entities) {
203
- for (const subEntity of entity.entities) {
204
- const subRoles = subEntity.roles || [];
205
- if (subRoles.includes('abuse')) {
206
- abuseContact = this.extractVcardEmail(subEntity);
207
- if (abuseContact)
208
- break;
209
- }
210
- }
211
- }
212
- }
213
- }
214
- }
215
- return { registrantOrg, registrantCountry, networkRange, networkCidrs, abuseContact };
216
- }
217
- catch (err) {
218
- this.logger.debug?.(`RDAP query failed for ${ip}: ${err.message}`);
219
- return null;
220
- }
221
- finally {
222
- clearTimeout(timeoutId);
223
- }
224
- }
225
- parseRdapNetworkInfo(data) {
226
- const cidrs = this.extractRdapCidrs(data);
227
- if (cidrs.length > 0) {
228
- return {
229
- networkRange: cidrs[0],
230
- networkCidrs: cidrs,
231
- };
232
- }
233
- if (typeof data.startAddress === 'string' && typeof data.endAddress === 'string') {
234
- const rangeCidrs = this.ipv4RangeToCidrs(data.startAddress, data.endAddress);
235
114
  return {
236
- networkRange: rangeCidrs.length === 1
237
- ? rangeCidrs[0]
238
- : `${data.startAddress} - ${data.endAddress}`,
239
- networkCidrs: rangeCidrs.length > 0 ? rangeCidrs : null,
115
+ registrantOrg: rdapRecord.registrantOrg ?? null,
116
+ registrantCountry: rdapRecord.registrantCountry ?? null,
117
+ networkRange: rdapRecord.networkRange ?? null,
118
+ networkCidrs: rdapRecord.networkCidrs ?? null,
119
+ abuseContact: rdapRecord.abuseEmail ?? null,
240
120
  };
241
121
  }
242
- return { networkRange: null, networkCidrs: null };
243
- }
244
- extractRdapCidrs(data) {
245
- if (!Array.isArray(data.cidr0_cidrs))
246
- return [];
247
- return data.cidr0_cidrs
248
- .map((cidr) => {
249
- const prefix = cidr?.v4prefix || cidr?.v6prefix;
250
- const length = Number(cidr?.length);
251
- if (typeof prefix !== 'string' || !Number.isInteger(length))
252
- return null;
253
- return `${prefix}/${length}`;
254
- })
255
- .filter(Boolean);
256
- }
257
- /**
258
- * Extract the 'fn' (formatted name) from an entity's vcardArray
259
- */
260
- extractVcardFn(entity) {
261
- if (!entity.vcardArray || !Array.isArray(entity.vcardArray))
262
- return null;
263
- const properties = entity.vcardArray[1];
264
- if (!Array.isArray(properties))
265
- return null;
266
- for (const prop of properties) {
267
- if (Array.isArray(prop) && prop[0] === 'fn') {
268
- return prop[3] || null;
269
- }
270
- }
271
- return null;
272
- }
273
- /**
274
- * Extract email from an entity's vcardArray
275
- */
276
- extractVcardEmail(entity) {
277
- if (!entity.vcardArray || !Array.isArray(entity.vcardArray))
278
- return null;
279
- const properties = entity.vcardArray[1];
280
- if (!Array.isArray(properties))
281
- return null;
282
- for (const prop of properties) {
283
- if (Array.isArray(prop) && prop[0] === 'email') {
284
- return prop[3] || null;
285
- }
286
- }
287
- return null;
288
- }
289
- /**
290
- * Extract country from an entity's vcardArray address field
291
- */
292
- extractVcardCountry(entity) {
293
- if (!entity.vcardArray || !Array.isArray(entity.vcardArray))
294
- return null;
295
- const properties = entity.vcardArray[1];
296
- if (!Array.isArray(properties))
122
+ catch (err) {
123
+ this.logger.debug?.(`RDAP query failed for ${ip}: ${err.message}`);
297
124
  return null;
298
- for (const prop of properties) {
299
- if (Array.isArray(prop) && prop[0] === 'adr') {
300
- // The label parameter often contains the full address with country at the end
301
- const label = prop[1]?.label;
302
- if (typeof label === 'string') {
303
- const lines = label.split('\n');
304
- const lastLine = lines[lines.length - 1]?.trim();
305
- if (lastLine && lastLine.length > 1)
306
- return lastLine;
307
- }
308
- // Also check the structured value (7-element array, last element is country)
309
- const value = prop[3];
310
- if (Array.isArray(value) && value.length >= 7 && value[6]) {
311
- return value[6];
312
- }
313
- }
314
125
  }
315
- return null;
316
126
  }
317
127
  // ─── Team Cymru DNS Subsystem ───────────────────────────────────────
318
128
  /**
@@ -321,46 +131,65 @@ export class IpIntelligence {
321
131
  * Response: "ASN | prefix | CC | rir | date"
322
132
  */
323
133
  async queryTeamCymru(ip) {
324
- const external = this.sharedDnsClient !== null;
325
- let dnsClient = this.sharedDnsClient;
326
- try {
327
- const reversed = ip.split('.').reverse().join('.');
328
- const queryName = `${reversed}.origin.asn.cymru.com`;
329
- if (!dnsClient) {
330
- dnsClient = new plugins.smartdns.dnsClientMod.Smartdns({
331
- strategy: 'prefer-system',
332
- allowDohFallback: true,
333
- timeoutMs: this.timeout,
334
- });
134
+ const query = async (dnsClientArg) => {
135
+ try {
136
+ const reversed = ip.split('.').reverse().join('.');
137
+ const queryName = `${reversed}.origin.asn.cymru.com`;
138
+ const records = await dnsClientArg.getRecordsTxt(queryName);
139
+ if (!records || records.length === 0)
140
+ return null;
141
+ // Parse the first TXT record: "13335 | 1.1.1.0/24 | AU | apnic | 2011-08-11"
142
+ const txt = records[0].value || records[0].data;
143
+ if (!txt)
144
+ return null;
145
+ const parts = txt.split('|').map((s) => s.trim());
146
+ if (parts.length < 3)
147
+ return null;
148
+ const asn = parseInt(parts[0], 10);
149
+ if (isNaN(asn))
150
+ return null;
151
+ return {
152
+ asn,
153
+ prefix: parts[1] || '',
154
+ country: parts[2] || '',
155
+ };
335
156
  }
336
- const records = await dnsClient.getRecordsTxt(queryName);
337
- if (!records || records.length === 0)
338
- return null;
339
- // Parse the first TXT record: "13335 | 1.1.1.0/24 | AU | apnic | 2011-08-11"
340
- const txt = records[0].value || records[0].data;
341
- if (!txt)
342
- return null;
343
- const parts = txt.split('|').map((s) => s.trim());
344
- if (parts.length < 3)
345
- return null;
346
- const asn = parseInt(parts[0], 10);
347
- if (isNaN(asn))
157
+ catch (err) {
158
+ this.logger.debug?.(`Team Cymru DNS query failed for ${ip}: ${err.message}`);
348
159
  return null;
349
- return {
350
- asn,
351
- prefix: parts[1] || '',
352
- country: parts[2] || '',
353
- };
354
- }
355
- catch (err) {
356
- this.logger.debug?.(`Team Cymru DNS query failed for ${ip}: ${err.message}`);
357
- return null;
160
+ }
161
+ };
162
+ if (this.sharedDnsClient) {
163
+ return query(this.sharedDnsClient);
358
164
  }
359
- finally {
360
- // Only destroy clients we created ourselves; leave injected ones alone.
361
- if (!external && dnsClient) {
362
- dnsClient.destroy();
165
+ return this.enqueueDnsLifecycle(async () => {
166
+ await this.terminateOwnedDnsClient();
167
+ const dnsClient = new plugins.smartdns.dnsClientMod.Smartdns({
168
+ strategy: 'prefer-system',
169
+ allowDohFallback: true,
170
+ timeoutMs: this.timeout,
171
+ });
172
+ this.ownedDnsClient = dnsClient;
173
+ try {
174
+ return await query(dnsClient);
175
+ }
176
+ finally {
177
+ await this.terminateOwnedDnsClient();
363
178
  }
179
+ });
180
+ }
181
+ enqueueDnsLifecycle(operationArg) {
182
+ const result = this.dnsLifecycleQueue.then(operationArg);
183
+ this.dnsLifecycleQueue = result.then(() => { }, () => { });
184
+ return result;
185
+ }
186
+ async terminateOwnedDnsClient() {
187
+ const dnsClient = this.ownedDnsClient;
188
+ if (!dnsClient)
189
+ return;
190
+ await dnsClient.terminate();
191
+ if (this.ownedDnsClient === dnsClient) {
192
+ this.ownedDnsClient = null;
364
193
  }
365
194
  }
366
195
  // ─── MaxMind GeoLite2 Subsystem ─────────────────────────────────────
@@ -472,67 +301,5 @@ export class IpIntelligence {
472
301
  }
473
302
  return { country, countryCode, city, latitude, longitude, accuracyRadius, timezone, asn, asnOrg };
474
303
  }
475
- // ─── Utilities ──────────────────────────────────────────────────────
476
- /**
477
- * Convert an IPv4 address string to a 32-bit unsigned number
478
- */
479
- ipToNumber(ip) {
480
- const parts = ip.split('.');
481
- return (((parseInt(parts[0], 10) << 24) |
482
- (parseInt(parts[1], 10) << 16) |
483
- (parseInt(parts[2], 10) << 8) |
484
- parseInt(parts[3], 10)) >>> 0);
485
- }
486
- ipv4RangeToCidrs(startIp, endIp) {
487
- const start = this.ipv4ToBigInt(startIp);
488
- const end = this.ipv4ToBigInt(endIp);
489
- if (start === undefined || end === undefined || start > end)
490
- return [];
491
- const cidrs = [];
492
- let current = start;
493
- while (current <= end) {
494
- let maxBlockSize = current === 0n ? 1n << 32n : current & -current;
495
- const remaining = end - current + 1n;
496
- while (maxBlockSize > remaining) {
497
- maxBlockSize = maxBlockSize / 2n;
498
- }
499
- const prefixLength = 32 - this.powerOfTwoExponent(maxBlockSize);
500
- cidrs.push(`${this.numberToIpv4(current)}/${prefixLength}`);
501
- current += maxBlockSize;
502
- }
503
- return cidrs;
504
- }
505
- ipv4ToBigInt(ip) {
506
- const parts = ip.trim().split('.');
507
- if (parts.length !== 4)
508
- return undefined;
509
- let result = 0n;
510
- for (const part of parts) {
511
- if (!/^\d+$/.test(part))
512
- return undefined;
513
- const number = Number(part);
514
- if (!Number.isInteger(number) || number < 0 || number > 255)
515
- return undefined;
516
- result = (result * 256n) + BigInt(number);
517
- }
518
- return result;
519
- }
520
- numberToIpv4(value) {
521
- return [
522
- Number((value >> 24n) & 255n),
523
- Number((value >> 16n) & 255n),
524
- Number((value >> 8n) & 255n),
525
- Number(value & 255n),
526
- ].join('.');
527
- }
528
- powerOfTwoExponent(value) {
529
- let exponent = 0;
530
- let remaining = value;
531
- while (remaining > 1n) {
532
- remaining >>= 1n;
533
- exponent++;
534
- }
535
- return exponent;
536
- }
537
304
  }
538
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRuZXR3b3JrLmNsYXNzZXMuaXBpbnRlbGxpZ2VuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydG5ldHdvcmsuY2xhc3Nlcy5pcGludGVsbGlnZW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDJCQUEyQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUE2RHpDLDJFQUEyRTtBQUMzRSxNQUFNLGFBQWEsR0FBRyx5RkFBeUYsQ0FBQztBQUNoSCxNQUFNLFlBQVksR0FBRyx1RkFBdUYsQ0FBQztBQUU3RywwQkFBMEI7QUFDMUIsTUFBTSx1QkFBdUIsR0FBRyxzQ0FBc0MsQ0FBQztBQUV2RSxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxTQUFTO0FBQzdELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQztBQWlCN0I7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sY0FBYztJQWtCekIsWUFBWSxPQUFnQztRQWpCM0IsV0FBTSxHQUFHLFNBQVMsRUFBRSxDQUFDO1FBSXRDLHVDQUF1QztRQUMvQixlQUFVLEdBQXNELElBQUksQ0FBQztRQUNyRSxjQUFTLEdBQStCLElBQUksQ0FBQztRQUM3QyxrQkFBYSxHQUFHLENBQUMsQ0FBQztRQUNsQixtQkFBYyxHQUF5QixJQUFJLENBQUM7UUFFcEQsdUJBQXVCO1FBQ2YscUJBQWdCLEdBQTZCLElBQUksQ0FBQztRQUNsRCxxQkFBZ0IsR0FBeUIsSUFBSSxDQUFDO1FBTXBELElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSxrQkFBa0IsQ0FBQztRQUN4RCxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksZUFBZSxDQUFDO1FBQ25ELElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxFQUFFLFNBQVMsSUFBSSxJQUFJLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7T0FHRztJQUNJLEtBQUssQ0FBQyxlQUFlLENBQUMsRUFBVTtRQUNyQyxNQUFNLE1BQU0sR0FBMEI7WUFDcEMsR0FBRyxFQUFFLElBQUk7WUFDVCxNQUFNLEVBQUUsSUFBSTtZQUNaLGFBQWEsRUFBRSxJQUFJO1lBQ25CLGlCQUFpQixFQUFFLElBQUk7WUFDdkIsWUFBWSxFQUFFLElBQUk7WUFDbEIsWUFBWSxFQUFFLElBQUk7WUFDbEIsWUFBWSxFQUFFLElBQUk7WUFDbEIsT0FBTyxFQUFFLElBQUk7WUFDYixXQUFXLEVBQUUsSUFBSTtZQUNqQixJQUFJLEVBQUUsSUFBSTtZQUNWLFFBQVEsRUFBRSxJQUFJO1lBQ2QsU0FBUyxFQUFFLElBQUk7WUFDZixjQUFjLEVBQUUsSUFBSTtZQUNwQixRQUFRLEVBQUUsSUFBSTtTQUNmLENBQUM7UUFFRixtQ0FBbUM7UUFDbkMsTUFBTSxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsYUFBYSxDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsVUFBVSxDQUFDO1lBQ3hFLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1NBQ3RCLENBQUMsQ0FBQztRQUVILHFCQUFxQjtRQUNyQixJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssV0FBVyxJQUFJLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxRCxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDO1lBQzlCLE1BQU0sQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztZQUMxQyxNQUFNLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO1lBQ2xELE1BQU0sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztZQUN4QyxNQUFNLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDeEMsTUFBTSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzFDLENBQUM7UUFFRCw2Q0FBNkM7UUFDN0MsSUFBSSxXQUFXLENBQUMsTUFBTSxLQUFLLFdBQVcsSUFBSSxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDNUQsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQztZQUNoQyxNQUFNLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFDekIsQ0FBQztRQUVELHdCQUF3QjtRQUN4QixJQUFJLGFBQWEsQ0FBQyxNQUFNLEtBQUssV0FBVyxJQUFJLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNoRSxNQUFNLEVBQUUsR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDO1lBQy9CLE1BQU0sQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQztZQUM1QixNQUFNLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUM7WUFDcEMsTUFBTSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ3RCLE1BQU0sQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQztZQUM5QixNQUFNLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUM7WUFDaEMsTUFBTSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUMsY0FBYyxDQUFDO1lBQzFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQztZQUU5QixtREFBbUQ7WUFDbkQsSUFBSSxNQUFNLENBQUMsR0FBRyxLQUFLLElBQUksSUFBSSxFQUFFLENBQUMsR0FBRyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUMzQyxNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUM7WUFDdEIsQ0FBQztZQUNELElBQUksRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNkLE1BQU0sQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQztZQUM1QixDQUFDO1FBQ0gsQ0FBQztRQUVELG9GQUFvRjtRQUNwRiw2REFBNkQ7UUFFN0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELHVFQUF1RTtJQUV2RTs7T0FFRztJQUNLLEtBQUssQ0FBQyxlQUFlO1FBQzNCLElBQUksSUFBSSxDQUFDLGdCQUFnQjtZQUFFLE9BQU87UUFDbEMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMxQixNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztZQUM1QixPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ2xDLElBQUksQ0FBQztnQkFDSCxNQUFNLFVBQVUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUN6QyxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDckUsSUFBSSxDQUFDO29CQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLHVCQUF1QixFQUFFO3dCQUNwRCxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07d0JBQ3pCLE9BQU8sRUFBRSxFQUFFLFlBQVksRUFBRSwwQkFBMEIsRUFBRTtxQkFDdEQsQ0FBQyxDQUFDO29CQUNILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRTt3QkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7b0JBQzdELE1BQU0sSUFBSSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBMEMsQ0FBQztvQkFFM0UsTUFBTSxPQUFPLEdBQXNCLEVBQUUsQ0FBQztvQkFDdEMsS0FBSyxNQUFNLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQzt3QkFDN0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMseUJBQXlCO3dCQUNsRCxLQUFLLE1BQU0sTUFBTSxJQUFJLFFBQVEsRUFBRSxDQUFDOzRCQUM5QixNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7NEJBQzFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0NBQ1gsTUFBTTtnQ0FDTixTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUM7Z0NBQ25DLFFBQVEsRUFBRSxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztnQ0FDNUIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLHVCQUF1Qjs2QkFDN0QsQ0FBQyxDQUFDO3dCQUNMLENBQUM7b0JBQ0gsQ0FBQztvQkFFRCx3REFBd0Q7b0JBQ3hELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDaEQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQztnQkFDbEMsQ0FBQzt3QkFBUyxDQUFDO29CQUNULFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDMUIsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO2dCQUNsQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLGtDQUFrQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDckUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQyxDQUFDLHFDQUFxQztZQUNuRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUVMLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQzVCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7SUFDL0IsQ0FBQztJQUVEOztPQUVHO0lBQ0ssUUFBUSxDQUFDLEVBQVU7UUFDekIsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUU5RSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRWxDLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDMUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxVQUFVLElBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ2hELE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQztZQUN2QixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFVO1FBT2hDLE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQzdCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLElBQUksQ0FBQztRQUUxQixNQUFNLFVBQVUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JFLElBQUksQ0FBQztZQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsT0FBTyxPQUFPLEVBQUUsRUFBRSxFQUFFO2dCQUNsRCxNQUFNLEVBQUUsVUFBVSxDQUFDLE1BQU07Z0JBQ3pCLE9BQU8sRUFBRTtvQkFDUCxRQUFRLEVBQUUsdUJBQXVCO29CQUNqQyxZQUFZLEVBQUUsMEJBQTBCO2lCQUN6QzthQUNGLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFBRSxPQUFPLElBQUksQ0FBQztZQUM5QixNQUFNLElBQUksR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQVMsQ0FBQztZQUUxQyxJQUFJLGFBQWEsR0FBa0IsSUFBSSxDQUFDO1lBQ3hDLElBQUksaUJBQWlCLEdBQWtCLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDO1lBQzVELElBQUksWUFBWSxHQUFrQixJQUFJLENBQUM7WUFFdkMsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFdkUsaUJBQWlCO1lBQ2pCLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUNsRCxLQUFLLE1BQU0sTUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDbkMsTUFBTSxLQUFLLEdBQWEsTUFBTSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7b0JBRTNDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQzt3QkFDckUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDNUMsSUFBSSxPQUFPOzRCQUFFLGFBQWEsR0FBRyxPQUFPLENBQUM7d0JBRXJDLGlFQUFpRTt3QkFDakUsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7NEJBQ3ZCLGlCQUFpQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDdkQsQ0FBQztvQkFDSCxDQUFDO29CQUVELElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO3dCQUM1QixZQUFZLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO3dCQUM5QywwQ0FBMEM7d0JBQzFDLElBQUksQ0FBQyxZQUFZLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDOzRCQUNyQyxLQUFLLE1BQU0sU0FBUyxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQ0FDeEMsTUFBTSxRQUFRLEdBQWEsU0FBUyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7Z0NBQ2pELElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO29DQUMvQixZQUFZLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO29DQUNqRCxJQUFJLFlBQVk7d0NBQUUsTUFBTTtnQ0FDMUIsQ0FBQzs0QkFDSCxDQUFDO3dCQUNILENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELE9BQU8sRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsQ0FBQztRQUN4RixDQUFDO1FBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLHlCQUF5QixFQUFFLEtBQUssR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDbkUsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO2dCQUFTLENBQUM7WUFDVCxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxJQUFTO1FBQ3BDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckIsT0FBTztnQkFDTCxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDdEIsWUFBWSxFQUFFLEtBQUs7YUFDcEIsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLE9BQU8sSUFBSSxDQUFDLFlBQVksS0FBSyxRQUFRLElBQUksT0FBTyxJQUFJLENBQUMsVUFBVSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ2pGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM3RSxPQUFPO2dCQUNMLFlBQVksRUFBRSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUM7b0JBQ25DLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO29CQUNmLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLE1BQU0sSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDL0MsWUFBWSxFQUFFLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUk7YUFDeEQsQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDcEQsQ0FBQztJQUVPLGdCQUFnQixDQUFDLElBQVM7UUFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ2hELE9BQU8sSUFBSSxDQUFDLFdBQVc7YUFDcEIsR0FBRyxDQUFDLENBQUMsSUFBUyxFQUFFLEVBQUU7WUFDakIsTUFBTSxNQUFNLEdBQUcsSUFBSSxFQUFFLFFBQVEsSUFBSSxJQUFJLEVBQUUsUUFBUSxDQUFDO1lBQ2hELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDcEMsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUN6RSxPQUFPLEdBQUcsTUFBTSxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQy9CLENBQUMsQ0FBQzthQUNELE1BQU0sQ0FBQyxPQUFPLENBQWEsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7O09BRUc7SUFDSyxjQUFjLENBQUMsTUFBVztRQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3pFLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFNUMsS0FBSyxNQUFNLElBQUksSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUM5QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUM1QyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7WUFDekIsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7T0FFRztJQUNLLGlCQUFpQixDQUFDLE1BQVc7UUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUN6RSxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRTVDLEtBQUssTUFBTSxJQUFJLElBQUksVUFBVSxFQUFFLENBQUM7WUFDOUIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxPQUFPLEVBQUUsQ0FBQztnQkFDL0MsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDO1lBQ3pCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxtQkFBbUIsQ0FBQyxNQUFXO1FBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDekUsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUU1QyxLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzlCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQzdDLDhFQUE4RTtnQkFDOUUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQztnQkFDN0IsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztvQkFDOUIsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDaEMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUM7b0JBQ2pELElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQzt3QkFBRSxPQUFPLFFBQVEsQ0FBQztnQkFDdkQsQ0FBQztnQkFDRCw2RUFBNkU7Z0JBQzdFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUMxRCxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEIsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsdUVBQXVFO0lBRXZFOzs7O09BSUc7SUFDSyxLQUFLLENBQUMsY0FBYyxDQUFDLEVBQVU7UUFDckMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGVBQWUsS0FBSyxJQUFJLENBQUM7UUFDL0MsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUNyQyxJQUFJLENBQUM7WUFDSCxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNuRCxNQUFNLFNBQVMsR0FBRyxHQUFHLFFBQVEsdUJBQXVCLENBQUM7WUFFckQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNmLFNBQVMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztvQkFDckQsUUFBUSxFQUFFLGVBQWU7b0JBQ3pCLGdCQUFnQixFQUFFLElBQUk7b0JBQ3RCLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTztpQkFDeEIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUVsRCw2RUFBNkU7WUFDN0UsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSyxPQUFPLENBQUMsQ0FBQyxDQUFTLENBQUMsSUFBSSxDQUFDO1lBQ3pELElBQUksQ0FBQyxHQUFHO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBRXRCLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUMxRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUVsQyxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ25DLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUU1QixPQUFPO2dCQUNMLEdBQUc7Z0JBQ0gsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFO2dCQUN0QixPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUU7YUFDeEIsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsbUNBQW1DLEVBQUUsS0FBSyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUM3RSxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7Z0JBQVMsQ0FBQztZQUNULHdFQUF3RTtZQUN4RSxJQUFJLENBQUMsUUFBUSxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUMzQixTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdEIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsdUVBQXVFO0lBRXZFOzs7T0FHRztJQUNLLEtBQUssQ0FBQyxhQUFhO1FBQ3pCLElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDdEMsMEJBQTBCO1lBQzFCLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDNUUsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsc0JBQXNCLEVBQUU7cUJBQ2hELEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxtQ0FBbUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7cUJBQ3JGLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BELENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUVELGdDQUFnQztRQUNoQyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixNQUFNLElBQUksQ0FBQyxjQUFjLENBQUM7WUFDMUIsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQ3BELE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUMxQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsc0JBQXNCO1FBQ2xDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO1lBQ2hELElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDO1lBQy9CLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDO1NBQy9CLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBcUMsVUFBVSxDQUFDLENBQUM7UUFDN0YsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFjLFNBQVMsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsMkNBQTJDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQVc7UUFDbkMsTUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUN6QyxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyRSxJQUFJLENBQUM7WUFDSCxNQUFNLFFBQVEsR0FBRyxNQUFNLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ2hDLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTTtnQkFDekIsT0FBTyxFQUFFLEVBQUUsWUFBWSxFQUFFLDBCQUEwQixFQUFFO2FBQ3RELENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLEdBQUcsVUFBVSxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUNyRSxDQUFDO1lBQ0QsTUFBTSxXQUFXLEdBQUcsTUFBTSxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7Z0JBQVMsQ0FBQztZQUNULFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFVO1FBV25DLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzdCLENBQUM7UUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMseUNBQXlDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQzVFLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVyRCxJQUFJLE9BQU8sR0FBa0IsSUFBSSxDQUFDO1FBQ2xDLElBQUksV0FBVyxHQUFrQixJQUFJLENBQUM7UUFDdEMsSUFBSSxJQUFJLEdBQWtCLElBQUksQ0FBQztRQUMvQixJQUFJLFFBQVEsR0FBa0IsSUFBSSxDQUFDO1FBQ25DLElBQUksU0FBUyxHQUFrQixJQUFJLENBQUM7UUFDcEMsSUFBSSxjQUFjLEdBQWtCLElBQUksQ0FBQztRQUN6QyxJQUFJLFFBQVEsR0FBa0IsSUFBSSxDQUFDO1FBQ25DLElBQUksR0FBRyxHQUFrQixJQUFJLENBQUM7UUFDOUIsSUFBSSxNQUFNLEdBQWtCLElBQUksQ0FBQztRQUVqQyxnR0FBZ0c7UUFDaEcsSUFBSSxDQUFDO1lBQ0gsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDM0MsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDZixXQUFXLEdBQUcsVUFBVSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUM7Z0JBQzlDLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQztnQkFDL0IsUUFBUSxHQUFHLFVBQVUsQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDO2dCQUN2QyxTQUFTLEdBQUcsVUFBVSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUM7Z0JBQ3pDLFFBQVEsR0FBRyxVQUFVLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQztnQkFDdkMsbUVBQW1FO2dCQUNuRSxtREFBbUQ7WUFDckQsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsa0NBQWtDLEVBQUUsS0FBSyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM5RSxDQUFDO1FBRUQsYUFBYTtRQUNiLElBQUksQ0FBQztZQUNILE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3pDLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ2QsR0FBRyxHQUFHLFNBQVMsQ0FBQyx3QkFBd0IsSUFBSSxJQUFJLENBQUM7Z0JBQ2pELE1BQU0sR0FBRyxTQUFTLENBQUMsOEJBQThCLElBQUksSUFBSSxDQUFDO1lBQzVELENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEtBQUssR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDN0UsQ0FBQztRQUVELE9BQU8sRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDO0lBQ3BHLENBQUM7SUFFRCx1RUFBdUU7SUFFdkU7O09BRUc7SUFDSyxVQUFVLENBQUMsRUFBVTtRQUMzQixNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLE9BQU8sQ0FDTCxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDOUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM5QixDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzVCLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQ2hDLENBQUM7SUFDSixDQUFDO0lBRU8sZ0JBQWdCLENBQUMsT0FBZSxFQUFFLEtBQWE7UUFDckQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEtBQUssR0FBRyxHQUFHO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFFdkUsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO1FBQzNCLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNwQixPQUFPLE9BQU8sSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUN0QixJQUFJLFlBQVksR0FBRyxPQUFPLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUM7WUFDbkUsTUFBTSxTQUFTLEdBQUcsR0FBRyxHQUFHLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDckMsT0FBTyxZQUFZLEdBQUcsU0FBUyxFQUFFLENBQUM7Z0JBQ2hDLFlBQVksR0FBRyxZQUFZLEdBQUcsRUFBRSxDQUFDO1lBQ25DLENBQUM7WUFDRCxNQUFNLFlBQVksR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2hFLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLFlBQVksRUFBRSxDQUFDLENBQUM7WUFDNUQsT0FBTyxJQUFJLFlBQVksQ0FBQztRQUMxQixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU8sWUFBWSxDQUFDLEVBQVU7UUFDN0IsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU8sU0FBUyxDQUFDO1FBQ3pDLElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNoQixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUMxQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxHQUFHLENBQUMsSUFBSSxNQUFNLEdBQUcsR0FBRztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUM5RSxNQUFNLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sWUFBWSxDQUFDLEtBQWE7UUFDaEMsT0FBTztZQUNMLE1BQU0sQ0FBQyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDN0IsTUFBTSxDQUFDLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztZQUM3QixNQUFNLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1NBQ3JCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsQ0FBQztJQUVPLGtCQUFrQixDQUFDLEtBQWE7UUFDdEMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN0QixPQUFPLFNBQVMsR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUN0QixTQUFTLEtBQUssRUFBRSxDQUFDO1lBQ2pCLFFBQVEsRUFBRSxDQUFDO1FBQ2IsQ0FBQztRQUNELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Q0FDRiJ9
305
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRuZXR3b3JrLmNsYXNzZXMuaXBpbnRlbGxpZ2VuY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydG5ldHdvcmsuY2xhc3Nlcy5pcGludGVsbGlnZW5jZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDJCQUEyQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUE2RHpDLDJFQUEyRTtBQUMzRSxNQUFNLGFBQWEsR0FBRyx5RkFBeUYsQ0FBQztBQUNoSCxNQUFNLFlBQVksR0FBRyx1RkFBdUYsQ0FBQztBQUU3RyxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxTQUFTO0FBQzdELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQztBQUU3Qjs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxjQUFjO0lBbUJ6QixZQUFZLE9BQWdDO1FBbEIzQixXQUFNLEdBQUcsU0FBUyxFQUFFLENBQUM7UUFJdEMsdUNBQXVDO1FBQy9CLGVBQVUsR0FBc0QsSUFBSSxDQUFDO1FBQ3JFLGNBQVMsR0FBK0IsSUFBSSxDQUFDO1FBQzdDLGtCQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLG1CQUFjLEdBQXlCLElBQUksQ0FBQztRQU81QyxtQkFBYyxHQUF1RSxJQUFJLENBQUM7UUFDMUYsc0JBQWlCLEdBQWtCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUczRCxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sRUFBRSxRQUFRLElBQUksa0JBQWtCLENBQUM7UUFDeEQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLEVBQUUsT0FBTyxJQUFJLGVBQWUsQ0FBQztRQUNuRCxJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sRUFBRSxTQUFTLElBQUksSUFBSSxDQUFDO1FBQ2xELElBQUksQ0FBQyxVQUFV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
@@ -69,6 +69,10 @@ type TNetworkCommands = {
69
69
  };
70
70
  };
71
71
  };
72
+ /** Internal marker for an activation failure whose cleanup still needs an owner. */
73
+ export declare class RustNetworkBridgeActivationCleanupError extends AggregateError {
74
+ constructor(activationErrorArg: unknown, cleanupErrorArg: unknown);
75
+ }
72
76
  /**
73
77
  * Singleton bridge to the rustnetwork binary.
74
78
  * Manages the IPC lifecycle for network diagnostics operations.
@@ -77,19 +81,19 @@ export declare class RustNetworkBridge {
77
81
  private static instance;
78
82
  static getInstance(): RustNetworkBridge;
79
83
  private bridge;
84
+ private readonly owners;
85
+ private cleanupRequired;
86
+ private lifecycleQueue;
80
87
  private constructor();
88
+ private enqueueLifecycle;
81
89
  /**
82
- * Spawn the Rust binary and wait for it to be ready.
83
- */
84
- start(): Promise<void>;
85
- /**
86
- * Kill the Rust binary.
90
+ * Acquire the shared Rust binary and wait for it to be ready.
87
91
  */
88
- stop(): Promise<void>;
92
+ start(ownerArg?: object): Promise<void>;
89
93
  /**
90
- * Ensure the bridge is running before sending a command.
94
+ * Release one owner and terminate the Rust binary after the last release.
91
95
  */
92
- private ensureRunning;
96
+ stop(ownerArg?: object): Promise<void>;
93
97
  ping(host: string, count?: number, timeoutMs?: number): Promise<TNetworkCommands['ping']['result']>;
94
98
  traceroute(host: string, maxHops?: number, timeoutMs?: number): Promise<TNetworkCommands['traceroute']['result']>;
95
99
  tcpPortCheck(host: string, port: number, timeoutMs?: number): Promise<TNetworkCommands['tcpPortCheck']['result']>;