sliftutils 1.7.90 → 1.7.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +38 -79
- package/misc/https/dist/cloudflareHelpers.ts.cache +2 -2
- package/misc/https/dist/dns.ts.cache +2 -2
- package/package.json +1 -1
- package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/blockCache.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/mergeLock.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/streamLog.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/syncClient.ts.cache +2 -2
- package/storage/IArchives.d.ts +1 -0
- package/storage/IArchives.ts +3 -0
- package/storage/remoteStorage/accessStats.d.ts +12 -0
- package/storage/remoteStorage/accessStats.ts +47 -0
- package/storage/remoteStorage/blobStore.d.ts +6 -1
- package/storage/remoteStorage/blobStore.ts +34 -5
- package/storage/remoteStorage/createArchives.ts +13 -6
- package/storage/remoteStorage/dist/accessStats.ts.cache +42 -3
- package/storage/remoteStorage/dist/blobStore.ts.cache +6 -3
- package/storage/remoteStorage/dist/intermediateManagement.ts.cache +56 -50
- package/storage/remoteStorage/dist/storageController.ts.cache +36 -29
- package/storage/remoteStorage/dist/storageServerState.ts.cache +110 -233
- package/storage/remoteStorage/dist/storeConfig.ts.cache +2 -2
- package/storage/remoteStorage/dist/storePlan.ts.cache +4 -56
- package/storage/remoteStorage/intermediateManagement.d.ts +2 -3
- package/storage/remoteStorage/intermediateManagement.ts +53 -46
- package/storage/remoteStorage/storageController.ts +22 -14
- package/storage/remoteStorage/storageServerState.d.ts +15 -55
- package/storage/remoteStorage/storageServerState.ts +106 -268
- package/storage/remoteStorage/storeConfig.d.ts +2 -0
- package/storage/remoteStorage/storeConfig.ts +2 -0
- package/storage/remoteStorage/storePlan.d.ts +0 -20
- package/storage/remoteStorage/storePlan.ts +1 -69
|
@@ -113,3 +113,50 @@ export function clearAccountAccessStats(account: string): void {
|
|
|
113
113
|
console.log(`Cleared the in-memory access statistics for account ${account}`);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
+
|
|
117
|
+
export type BucketWriteStats = {
|
|
118
|
+
/** Every set call the bucket accepted */
|
|
119
|
+
originalWrites: number;
|
|
120
|
+
originalBytes: number;
|
|
121
|
+
/** What actually reached the sources. Fast writes coalesce repeated writes to the same key, so this is lower than the original counts (and is what the disk actually did). */
|
|
122
|
+
flushedWrites: number;
|
|
123
|
+
flushedBytes: number;
|
|
124
|
+
};
|
|
125
|
+
function emptyWriteStats(): BucketWriteStats {
|
|
126
|
+
return { originalWrites: 0, originalBytes: 0, flushedWrites: 0, flushedBytes: 0 };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// In memory only, keyed `${account}/${bucketName}`: totals since this process started (or the last clearWriteStats). Persisting them to disk was more machinery than the numbers were worth.
|
|
130
|
+
const writeStats = new Map<string, BucketWriteStats>();
|
|
131
|
+
|
|
132
|
+
export function countBucketWrite(key: string, kind: "original" | "flushed", bytes: number): void {
|
|
133
|
+
let stats = writeStats.get(key);
|
|
134
|
+
if (!stats) {
|
|
135
|
+
stats = emptyWriteStats();
|
|
136
|
+
writeStats.set(key, stats);
|
|
137
|
+
}
|
|
138
|
+
if (kind === "original") {
|
|
139
|
+
stats.originalWrites++;
|
|
140
|
+
stats.originalBytes += bytes;
|
|
141
|
+
} else {
|
|
142
|
+
stats.flushedWrites++;
|
|
143
|
+
stats.flushedBytes += bytes;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function getBucketWriteStats(key: string): BucketWriteStats {
|
|
148
|
+
return writeStats.get(key) || emptyWriteStats();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Zeroes the write statistics of every bucket in the account. */
|
|
152
|
+
export function debugClearAccountWriteStats(account: string): number {
|
|
153
|
+
let prefix = `${account}/`;
|
|
154
|
+
let cleared = 0;
|
|
155
|
+
for (let key of [...writeStats.keys()]) {
|
|
156
|
+
if (!key.startsWith(prefix)) continue;
|
|
157
|
+
writeStats.delete(key);
|
|
158
|
+
cleared++;
|
|
159
|
+
}
|
|
160
|
+
console.log(`Cleared the write statistics of ${cleared} buckets in account ${account}`);
|
|
161
|
+
return cleared;
|
|
162
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
import { IArchives, ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, ChangesAfterConfig, FindConfig, SourceConfig, SyncActivity } from "../IArchives";
|
|
3
|
+
import { IArchives, ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, ChangesAfterConfig, FindConfig, RemoteConfig, SourceConfig, SyncActivity } from "../IArchives";
|
|
4
4
|
import { StoreSync } from "./storeSync";
|
|
5
5
|
import { StoreConfig } from "./storeConfig";
|
|
6
6
|
export declare const WINDOW_END_FLUSH_MARGIN: number;
|
|
@@ -57,6 +57,8 @@ export declare class BlobStore {
|
|
|
57
57
|
/** Hands a running source a changed config, so an endpoint we already talk to is never rebuilt just because a flag moved. */
|
|
58
58
|
applySource?: ((source: IArchives, sourceConfig: SourceConfig | undefined, writeDelay: number) => void) | undefined;
|
|
59
59
|
onIndexChanged?: ((key: string) => void) | undefined;
|
|
60
|
+
/** Called every time this store applies a routing config to itself (startup, an operator's write, a peer's copy arriving) - the store is the one that knows when a config landed, and the server arms window-boundary scans from it. */
|
|
61
|
+
onRoutingApplied?: ((routing: RemoteConfig) => void) | undefined;
|
|
60
62
|
onWriteCounted?: ((kind: "original" | "flushed", bytes: number) => void) | undefined;
|
|
61
63
|
resolveSourceUrl?: ((url: string) => IArchives) | undefined;
|
|
62
64
|
} | undefined);
|
|
@@ -65,6 +67,7 @@ export declare class BlobStore {
|
|
|
65
67
|
/** What this store is configured to be. It owns this: the routing config is a file IN the store, so the store reads it, applies it to itself, and re-applies it whenever the file changes - by our own write, or by a peer's copy arriving through synchronization. */
|
|
66
68
|
storeConfig: StoreConfig;
|
|
67
69
|
private appliedRoutingVersion;
|
|
70
|
+
private appliedRouting;
|
|
68
71
|
init: {
|
|
69
72
|
(): Promise<void>;
|
|
70
73
|
reset(): void;
|
|
@@ -251,6 +254,8 @@ export declare class BlobStore {
|
|
|
251
254
|
* reason it aimed here is that its config was stale.
|
|
252
255
|
*/
|
|
253
256
|
private assertWriteTarget;
|
|
257
|
+
/** Exactly why this store has no configuration entries - which of the three possible reasons it is, with the values that decided it, because "not configured" alone is undiagnosable. */
|
|
258
|
+
private unconfiguredDetail;
|
|
254
259
|
/**
|
|
255
260
|
* Whether a routing config may be written here. Two rules, and this is the one place either is
|
|
256
261
|
* applied - a config only ever enters the system through a write, so a config that got in is a
|
|
@@ -3,7 +3,7 @@ import { lazy } from "socket-function/src/caching";
|
|
|
3
3
|
import { timeInMinute, sort } from "socket-function/src/misc";
|
|
4
4
|
import {
|
|
5
5
|
IArchives, ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, ChangesAfterConfig, FindConfig, HostedConfig, RemoteConfig, SourceConfig, assertValidLastModified,
|
|
6
|
-
windowsAcceptWrites, SyncActivity, FULL_ROUTE, FULL_VALID_WINDOW, STORAGE_WRONG_VALID_WINDOW, STORAGE_WRONG_ROUTE,
|
|
6
|
+
windowsAcceptWrites, SyncActivity, FULL_ROUTE, FULL_VALID_WINDOW, STORAGE_WRONG_VALID_WINDOW, STORAGE_WRONG_ROUTE, STORAGE_NOT_CONFIGURED,
|
|
7
7
|
} from "../IArchives";
|
|
8
8
|
import { ArchivesDisk, applyFindInfoShape } from "../ArchivesDisk";
|
|
9
9
|
import { ROUTING_FILE, getRoute, routeContains, routeIntersection, parseRoutingData, assertValidRemoteConfig, getConfigVersion, sourceIdentity, sourcePersistentUrl } from "./remoteConfig";
|
|
@@ -100,6 +100,8 @@ export class BlobStore {
|
|
|
100
100
|
applySource?: (source: IArchives, sourceConfig: SourceConfig | undefined, writeDelay: number) => void;
|
|
101
101
|
// Called whenever a key's index entry changes (our own writes AND files pulled in via synchronization) — how the storage server notices routing config updates.
|
|
102
102
|
onIndexChanged?: (key: string) => void;
|
|
103
|
+
/** Called every time this store applies a routing config to itself (startup, an operator's write, a peer's copy arriving) - the store is the one that knows when a config landed, and the server arms window-boundary scans from it. */
|
|
104
|
+
onRoutingApplied?: (routing: RemoteConfig) => void;
|
|
103
105
|
// Every accepted write ("original") and every write that actually reached the sources ("flushed"). Fast writes coalesce, so the two counts differ.
|
|
104
106
|
onWriteCounted?: (kind: "original" | "flushed", bytes: number) => void;
|
|
105
107
|
// Resolves a persisted source URL (see ArchivesSource.url) to a cached IArchives, so entries whose holder is no longer configured can still be read
|
|
@@ -120,6 +122,8 @@ export class BlobStore {
|
|
|
120
122
|
public storeConfig: StoreConfig;
|
|
121
123
|
// The routing config this store last applied, so a write of an identical (or older) one is not re-applied
|
|
122
124
|
private appliedRoutingVersion = -1;
|
|
125
|
+
// ...and the config itself, so a rejection can say exactly what the store IS running instead of guessing
|
|
126
|
+
private appliedRouting: RemoteConfig | undefined;
|
|
123
127
|
|
|
124
128
|
// #region Main interface
|
|
125
129
|
|
|
@@ -159,9 +163,18 @@ export class BlobStore {
|
|
|
159
163
|
if (routing && !entries.length) {
|
|
160
164
|
console.warn(`The routing config in store ${this.folder} (version ${getConfigVersion(routing)}) does not name this store (${JSON.stringify(this.storeName)}) as one of ours, so it stays a disk-only store`);
|
|
161
165
|
}
|
|
166
|
+
let previousVersion = this.appliedRoutingVersion;
|
|
167
|
+
let newVersion = routing && getConfigVersion(routing) || -1;
|
|
168
|
+
if (newVersion !== previousVersion) {
|
|
169
|
+
console.log(`Store ${JSON.stringify(this.storeName)} (folder ${this.folder}) adopted routing config version ${previousVersion} -> ${newVersion}: ${entries.length} entr${entries.length === 1 && "y" || "ies"} of ours ${JSON.stringify(entries.map(x => ({ validWindow: x.validWindow, route: x.route || FULL_ROUTE })))}, ${peers.length} peer(s)`);
|
|
170
|
+
}
|
|
162
171
|
this.storeConfig.update(entries);
|
|
163
172
|
this.updateSources(this.planSources(peers));
|
|
164
|
-
this.appliedRoutingVersion =
|
|
173
|
+
this.appliedRoutingVersion = newVersion;
|
|
174
|
+
this.appliedRouting = routing;
|
|
175
|
+
if (routing) {
|
|
176
|
+
this.config?.onRoutingApplied?.(routing);
|
|
177
|
+
}
|
|
165
178
|
}
|
|
166
179
|
|
|
167
180
|
// The routing config as this store holds it, read straight off its folder: the store may be configuring itself before it has scanned anything, and this file is what decides what a scan would even talk to
|
|
@@ -785,8 +798,9 @@ export class BlobStore {
|
|
|
785
798
|
*/
|
|
786
799
|
private assertWriteTarget(key: string, route: number, lastModified: number | undefined): void {
|
|
787
800
|
if (!this.storeConfig.all().length) {
|
|
788
|
-
|
|
789
|
-
|
|
801
|
+
let detail = this.unconfiguredDetail();
|
|
802
|
+
logWrongTargetRejection(`Rejecting write of ${JSON.stringify(key)}: ${detail}`);
|
|
803
|
+
throw new Error(`${STORAGE_NOT_CONFIGURED} Cannot write ${JSON.stringify(key)}: ${detail} Data written to a store with no configuration entry would never be scanned or reconciled, so accepting it would silently lose it. Re-resolve the currently valid source and retry - or, if this store is genuinely meant to take this write, write the bucket's routing config with an entry naming it on this server.`);
|
|
790
804
|
}
|
|
791
805
|
if (!lastModified) {
|
|
792
806
|
this.assertFreshWriteTarget(key, Date.now(), route);
|
|
@@ -798,6 +812,21 @@ export class BlobStore {
|
|
|
798
812
|
throw new Error(`${STORAGE_WRONG_ROUTE} This store does not handle route ${route} (key ${JSON.stringify(key)}, our routes: ${JSON.stringify(this.storeConfig.all().map(x => x.route || FULL_ROUTE))}, store ${this.folder}). Re-resolve the source for this key and retry.`);
|
|
799
813
|
}
|
|
800
814
|
|
|
815
|
+
/** Exactly why this store has no configuration entries - which of the three possible reasons it is, with the values that decided it, because "not configured" alone is undiagnosable. */
|
|
816
|
+
private unconfiguredDetail(): string {
|
|
817
|
+
let routing = this.appliedRouting;
|
|
818
|
+
let identity = `store ${JSON.stringify(this.storeName)} (folder ${this.folder})`;
|
|
819
|
+
if (!routing) {
|
|
820
|
+
return `${identity} has no routing config at all - nothing has ever written ${JSON.stringify(ROUTING_FILE)} into it.`;
|
|
821
|
+
}
|
|
822
|
+
let objects = routing.sources.filter(x => typeof x !== "string") as SourceConfig[];
|
|
823
|
+
let named = objects.filter(x => x.name === this.storeName);
|
|
824
|
+
if (!named.length) {
|
|
825
|
+
return `${identity} is running routing config version ${getConfigVersion(routing)}, which has no entry named ${JSON.stringify(this.storeName)} (its entries are named ${JSON.stringify(objects.map(x => x.name))}).`;
|
|
826
|
+
}
|
|
827
|
+
return `${identity} is running routing config version ${getConfigVersion(routing)}, whose ${named.length} entr${named.length === 1 && "y" || "ies"} named ${JSON.stringify(this.storeName)} point(s) at ${JSON.stringify(named.map(x => x.url))} - none of which is THIS server, so the config says this store lives elsewhere.`;
|
|
828
|
+
}
|
|
829
|
+
|
|
801
830
|
/**
|
|
802
831
|
* Whether a routing config may be written here. Two rules, and this is the one place either is
|
|
803
832
|
* applied - a config only ever enters the system through a write, so a config that got in is a
|
|
@@ -821,7 +850,7 @@ export class BlobStore {
|
|
|
821
850
|
let timeValid = this.storeConfig.all().filter(x => writeTime >= x.validWindow[0] && writeTime < x.validWindow[1]);
|
|
822
851
|
if (!timeValid.length) {
|
|
823
852
|
logWrongTargetRejection(`Rejecting fresh write of ${JSON.stringify(key)} (store ${this.folder}): writeTime ${writeTime} (${new Date(writeTime).toISOString()}) is outside all our valid windows ${JSON.stringify(this.storeConfig.all().map(x => x.validWindow))} (a switchover moved the write target)`);
|
|
824
|
-
throw new Error(`${STORAGE_WRONG_VALID_WINDOW}
|
|
853
|
+
throw new Error(`${STORAGE_WRONG_VALID_WINDOW} Cannot write ${JSON.stringify(key)}: its write time ${writeTime} (${new Date(writeTime).toISOString()}) is outside every valid window of store ${JSON.stringify(this.storeName)} (windows: ${JSON.stringify(this.storeConfig.all().map(x => x.validWindow))}, folder ${this.folder}) - a switchover moved the write target. Re-resolve the currently valid source and retry.`);
|
|
825
854
|
}
|
|
826
855
|
if (!timeValid.some(x => routeContains(x.route, route))) {
|
|
827
856
|
logWrongTargetRejection(`Rejecting fresh write of ${JSON.stringify(key)} (store ${this.folder}): route ${route} is outside our routes ${JSON.stringify(timeValid.map(x => x.route || FULL_ROUTE))} at writeTime ${writeTime} (the client's shard config is stale)`);
|
|
@@ -3,7 +3,7 @@ import { delay } from "socket-function/src/batching";
|
|
|
3
3
|
import {
|
|
4
4
|
IArchives, RemoteConfig, RemoteConfigBase, SourceConfig,
|
|
5
5
|
ArchiveFileInfo, ArchivesConfig, ArchivesSyncStatus, ChangesAfterConfig, DelConfig, FindConfig, GetConfig, GetInfoConfig, MoveFileConfig, SetConfig, SetLargeFileConfig, STORAGE_WRONG_VALID_WINDOW,
|
|
6
|
-
STORAGE_WRONG_ROUTE, FULL_ROUTE, VARIABLE_SHARD, LARGE_SET_THRESHOLD, bufferChunkStream,
|
|
6
|
+
STORAGE_WRONG_ROUTE, STORAGE_NOT_CONFIGURED, FULL_ROUTE, VARIABLE_SHARD, LARGE_SET_THRESHOLD, bufferChunkStream,
|
|
7
7
|
} from "../IArchives";
|
|
8
8
|
import { copyArchiveFile } from "../archiveHelpers";
|
|
9
9
|
import {
|
|
@@ -451,11 +451,11 @@ export class ArchivesChain implements IArchives {
|
|
|
451
451
|
errors.push(message);
|
|
452
452
|
continue;
|
|
453
453
|
}
|
|
454
|
-
// A wrong-window/route rejection means OUR config
|
|
455
|
-
if ((message.includes(STORAGE_WRONG_VALID_WINDOW) || message.includes(STORAGE_WRONG_ROUTE)) && !retriedWrongTarget) {
|
|
454
|
+
// A wrong-window/route/unconfigured rejection means OUR config disagrees with the server's, so every source we'd fall back to is judged by the same stale config - refresh it and restart the pass instead
|
|
455
|
+
if ((message.includes(STORAGE_WRONG_VALID_WINDOW) || message.includes(STORAGE_WRONG_ROUTE) || message.includes(STORAGE_NOT_CONFIGURED)) && !retriedWrongTarget) {
|
|
456
456
|
retriedWrongTarget = true;
|
|
457
457
|
wrongTarget = true;
|
|
458
|
-
await this.prepareWrongTargetRetry(state, message.includes(STORAGE_WRONG_VALID_WINDOW) && "window" || "route");
|
|
458
|
+
await this.prepareWrongTargetRetry(state, message.includes(STORAGE_WRONG_VALID_WINDOW) && "window" || message.includes(STORAGE_WRONG_ROUTE) && "route" || "unconfigured");
|
|
459
459
|
break;
|
|
460
460
|
}
|
|
461
461
|
if (source.isConnected()) throw e;
|
|
@@ -481,6 +481,7 @@ export class ArchivesChain implements IArchives {
|
|
|
481
481
|
private async runPrimary<T>(config: { write?: boolean; route?: number; timeout?: SmartTimeout }, run: (archives: IArchives, sourceUrl: string) => Promise<T>): Promise<T> {
|
|
482
482
|
let retriedWrongWindow = false;
|
|
483
483
|
let retriedWrongRoute = false;
|
|
484
|
+
let retriedNotConfigured = false;
|
|
484
485
|
let deadline = Date.now() + PRIMARY_RETRY_TIMEOUT;
|
|
485
486
|
let attempt = 0;
|
|
486
487
|
while (true) {
|
|
@@ -509,6 +510,11 @@ export class ArchivesChain implements IArchives {
|
|
|
509
510
|
await this.prepareWrongTargetRetry(state, "route");
|
|
510
511
|
continue;
|
|
511
512
|
}
|
|
513
|
+
if (message.includes(STORAGE_NOT_CONFIGURED) && !retriedNotConfigured) {
|
|
514
|
+
retriedNotConfigured = true;
|
|
515
|
+
await this.prepareWrongTargetRetry(state, "unconfigured");
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
512
518
|
if (target && !target.isConnected()) target.noteFailure();
|
|
513
519
|
if (!config.write && target && (attempt === 1 || attempt % 3 === 0)) {
|
|
514
520
|
// The reason we try the HTTP request: httpsRequest has better DNS retrying capabilities than our WebSocket server (we have more control over it), so just using it can fix some DNS issues, which can propagate to fix the WebSocket connection. It is still the primary source's own data, so the no-fallback semantics hold - and ArchivesUrl has no setup cost, so making one on the spot is fine.
|
|
@@ -570,7 +576,7 @@ export class ArchivesChain implements IArchives {
|
|
|
570
576
|
}
|
|
571
577
|
|
|
572
578
|
private lastConfigRefresh = 0;
|
|
573
|
-
private async prepareWrongTargetRetry(state: ChainState, kind: "window" | "route"): Promise<void> {
|
|
579
|
+
private async prepareWrongTargetRetry(state: ChainState, kind: "window" | "route" | "unconfigured"): Promise<void> {
|
|
574
580
|
if (kind === "window") {
|
|
575
581
|
let now = Date.now();
|
|
576
582
|
let nearBoundary = state.sources.some(source => source.config.validWindow.some(t => t > 0 && t < Number.MAX_SAFE_INTEGER && Math.abs(t - now) <= WRONG_TARGET_BOUNDARY_WINDOW));
|
|
@@ -582,7 +588,8 @@ export class ArchivesChain implements IArchives {
|
|
|
582
588
|
}
|
|
583
589
|
if (Date.now() - this.lastConfigRefresh < CONFIG_REFRESH_THROTTLE) return;
|
|
584
590
|
this.lastConfigRefresh = Date.now();
|
|
585
|
-
|
|
591
|
+
let reason = kind === "window" && "wrong valid window" || kind === "route" && "wrong route" || "the store has no configuration entry on that server";
|
|
592
|
+
console.log(`Write rejected by ${this.getDebugName()} (${reason}): our config disagrees with the server's (likely stale, or a deploy switchover); refreshing it and retrying`);
|
|
586
593
|
await this.refreshActiveConfig();
|
|
587
594
|
}
|
|
588
595
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
3
|
-
//exports.clearAccountAccessStats = exports.readAccessSummaries = exports.getAccessTotals = exports.trackAccessCall = exports.trackAccess = void 0;
|
|
3
|
+
//exports.debugClearAccountWriteStats = exports.getBucketWriteStats = exports.countBucketWrite = exports.clearAccountAccessStats = exports.readAccessSummaries = exports.getAccessTotals = exports.trackAccessCall = exports.trackAccess = void 0;
|
|
4
4
|
const treeSummary_1 = require("../../treeSummary");
|
|
5
5
|
const EXPECTED_OUTPUT_COUNT = 100;
|
|
6
6
|
const accounts = new Map();
|
|
@@ -105,5 +105,44 @@ function clearAccountAccessStats(account) {
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
exports.clearAccountAccessStats = clearAccountAccessStats;
|
|
108
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzU3RhdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhY2Nlc3NTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtREFBOEQ7QUFFOUQsTUFBTSxxQkFBcUIsR0FBRyxHQUFHLENBQUM7QUFjbEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQXVDLENBQUM7QUFFaEUsU0FBUyxRQUFRLENBQUMsUUFBd0M7SUFDdEQsT0FBTyxJQUFJLHlCQUFXLENBQWtDO1FBQ3BELE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJO1FBQzVCLGFBQWEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ25DLFlBQVksRUFBRSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUM3QixPQUFPLENBQUMsS0FBSyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBQ0QsY0FBYyxFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQy9CLE1BQU0sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQztRQUNqQyxDQUFDO1FBQ0QsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUs7UUFDbkMsbUJBQW1CLEVBQUUscUJBQXFCO0tBQzdDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCx5TUFBeU07QUFDek0sU0FBZ0IsV0FBVyxDQUFDLE1BQTJFO0lBQ25HLElBQUksVUFBVSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNkLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxVQUFV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QztJQUN0QixzSEFBc0g7SUFDdEgsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQztJQUM5QixJQUFJLE1BQU0sQ0FBQyxZQUFZLElBQUksUUFBUSxFQUFFLENBQUM7UUFDbEMsT0FBTyxRQUFRLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDekQsQ0FBQztBQVZELGtEQVVDO0FBRUQsU0FBZ0IsdUJBQXVCLENBQUMsT0FBZTtJQUNuRCxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLHVEQUF1RCxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ2xGLENBQUM7QUFDTCxDQUFDO0FBSkQsMERBSUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUcmVlU3VtbWFyeSwgU3VtbWFyeUVudHJ5IH0gZnJvbSBcIi4uLy4uL3RyZWVTdW1tYXJ5XCI7XG5cbmNvbnN0IEVYUEVDVEVEX09VVFBVVF9DT1VOVCA9IDEwMDtcblxuZXhwb3J0IHR5cGUgQWNjZXNzU3VtbWFyeVN0YXRlID0geyB0b3RhbDogbnVtYmVyIH07XG5leHBvcnQgdHlwZSBBY2Nlc3NUb3RhbHMgPSB7IFtvcGVyYXRpb246IHN0cmluZ106IHsgY291bnQ6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfTtcblxudHlwZSBBY2Nlc3NWYWx1ZSA9IHsgcGF0aDogc3RyaW5nOyBzaXplOiBudW1iZXIgfTtcbnR5cGUgT3BlcmF0aW9uU3RhdHMgPSB7XG4gICAgdG90YWxDb3VudDogbnVtYmVyO1xuICAgIHRvdGFsU2l6ZTogbnVtYmVyO1xuICAgIGNvdW50VHJlZTogVHJlZVN1bW1hcnk8QWNjZXNzVmFsdWUsIEFjY2Vzc1N1bW1hcnlTdGF0ZT47XG4gICAgLy8gT25seSBleGlzdHMgZm9yIG9wZXJhdGlvbnMgdHJhY2tlZCB3aXRoIHNpemVzOyBjb3VudC1vbmx5IG9wZXJhdGlvbnMgKGdldEluZm8sIGRlbCwgLi4uKSBoYXZlIG5vIG1lYW5pbmdmdWwgc2l6ZSBicmVha2Rvd24uXG4gICAgc2l6ZVRyZWU/OiBUcmVlU3VtbWFyeTxBY2Nlc3NWYWx1ZSwgQWNjZXNzU3VtbWFyeVN0YXRlPjtcbn07XG5cbmNvbnN0IGFjY291bnRzID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIE9wZXJhdGlvblN0YXRzPj4oKTtcblxuZnVuY3Rpb24gbWFrZVRyZWUoZ2V0VmFsdWU6ICh2YWx1ZTogQWNjZXNzVmFsdWUpID0+IG51bWJlcik6IFRyZWVTdW1tYXJ5PEFjY2Vzc1ZhbHVlLCBBY2Nlc3NTdW1tYXJ5U3RhdGU+IHtcbiAgICByZXR1cm4gbmV3IFRyZWVTdW1tYXJ5PEFjY2Vzc1ZhbHVlLCBBY2Nlc3NTdW1tYXJ5U3RhdGU+KHtcbiAgICAgICAgZ2V0UGF0aDogdmFsdWUgPT4gdmFsdWUucGF0aCxcbiAgICAgICAgY3JlYXRlU3VtbWFyeTogKCkgPT4gKHsgdG90YWw6IDAgfSksXG4gICAgICAgIGFkZFRvU3VtbWFyeTogKHZhbHVlLCBzdW1tYXJ5KSA9PiB7XG4gICAgICAgICAgICBzdW1tYXJ5LnRvdGFsICs9IGdldFZhbHVlKHZhbHVlKTtcbiAgICAgICAgfSxcbiAgICAgICAgbWVyZ2VTdW1tYXJpZXM6ICh0YXJnZXQsIHNvdXJjZSkgPT4ge1xuICAgICAgICAgICAgdGFyZ2V0LnRvdGFsICs9IHNvdXJjZS50b3RhbDtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0V2VpZ2h0OiBzdW1tYXJ5ID0+IHN1bW1hcnkudG90YWwsXG4gICAgICAgIGV4cGVjdGVkT3V0cHV0Q291bnQ6IEVYUEVDVEVEX09VVFBVVF9DT1VOVCxcbiAgICB9KTtcbn1cblxuLyoqIENvdW50cyBvbmUgc3RvcmFnZSBhY2Nlc3MsIGluIG1lbW9yeSBvbmx5LiBzaXplIGlzIHRoZSBieXRlcyBpbnZvbHZlZCAoMCB3aGVuIHRoZSB0YXJnZXQgZG9lcyBub3QgZXhpc3QpOyBvbWl0IGl0IGVudGlyZWx5IGZvciBvcGVyYXRpb25zIHRoYXQgb25seSBjb3VudCBjYWxscywgd2hpY2ggdGhlbiBvbmx5IGdldCBhIGNvdW50IHRyZWUuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhY2tBY2Nlc3MoY29uZmlnOiB7IGFjY291bnQ6IHN0cmluZzsgb3BlcmF0aW9uOiBzdHJpbmc7IHBhdGg6IHN0cmluZzsgc2l6ZT86IG51bWJlciB9KTogdm9pZCB7XG4gICAgbGV0IG9wZXJhdGlvbnMgPSBhY2NvdW50cy5nZXQoY29uZmlnLmFjY291bnQpO1xuICAgIGlmICghb3BlcmF0aW9ucykge1xuICAgICAgICBvcGVyYXRpb25zID0gbmV3IE1hcCgpO1xuICAgICAgICBhY2NvdW50cy5zZXQoY29uZmlnLmFjY291bnQsIG9wZXJhdGlvbnMpO1xuICAgIH1cbiAgICBsZXQgc3RhdHMgPSBvcGVyYXRpb25zLmdldChjb25maWcub3BlcmF0aW9uKTtcbiAgICBpZiAoIXN0YXRzKSB7XG4gICAgICAgIHN0YXRzID0geyB0b3RhbENvdW50OiAwLCB0b3RhbFNpemU6IDAsIGNvdW50VHJlZTogbWFrZVRyZWUoKCkgPT4gMSkgfTtcbiAgICAgICAgb3BlcmF0aW9ucy5zZXQoY29uZmlnLm9wZXJhdGlvbiwgc3RhdHMpO1xuICAgIH1cbiAgICBsZXQgdmFsdWU6IEFjY2Vzc1ZhbHVlID0geyBwYXRoOiBjb25maWcucGF0aCwgc2l6ZTogY29uZmlnLnNpemUgfHwgMCB9O1xuICAgIHN0YXRzLnRvdGFsQ291bnQrKztcbiAgICBzdGF0cy5jb3VudFRyZWUuYWRkKHZhbHVlKTtcbiAgICBpZiAoY29uZmlnLnNpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsZXQgc2l6ZVRyZWUgPSBzdGF0cy5zaXplVHJlZTtcbiAgICAgICAgaWYgKCFzaXplVHJlZSkge1xuICAgICAgICAgICAgc2l6ZVRyZWUgPSBtYWtlVHJlZSh2ID0+IHYuc2l6ZSk7XG4gICAgICAgICAgICBzdGF0cy5zaXplVHJlZSA9IHNpemVUcmVlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRzLnRvdGFsU2l6ZSArPSBjb25maWcuc2l6ZTtcbiAgICAgICAgc2l6ZVRyZWUuYWRkKHZhbHVlKTtcbiAgICB9XG59XG5cbi8qKiBNZXRob2QgZGVjb3JhdG9yIGZhY3RvcnksIGZvciBBUEkgbWV0aG9kcyB3aG9zZSBzaW5nbGUgY29uZmlnLW9iamVjdCBhcmd1bWVudCBoYXMgYWNjb3VudCBhbmQgYnVja2V0TmFtZTogdHJhY2tzIHRoZSBhY2Nlc3MgKGFzIGBidWNrZXROYW1lL3BhdGhgKSBhZnRlciB0aGUgbWV0aG9kIHN1Y2NlZWRzLiBTaXplcyBjb21lIGZyb20gdGhlIGNvbmZpZydzIGRhdGEgKHdyaXRlcykgb3IgdGhlIHJlc3VsdCdzIGRhdGEgKHJlYWRzKTsgb3BlcmF0aW9ucyB3aXRob3V0IGVpdGhlciBhcmUgY291bnQtb25seS4gQXJyYXkgcmVzdWx0cyAobGlzdGluZ3MgLSBmaW5kSW5mbywgZ2V0Q2hhbmdlc0FmdGVyKSBhcmUgdHJhY2tlZCBhcyB0d28gYnJlYWtkb3duczogXCI8b3A+IHF1ZXJpZXNcIiAtIG9uZSBhY2Nlc3MgcGVyIENBTEwsIGF0IHRoZSBxdWVyeSBwcmVmaXgsIHNpemVkIGJ5IHRoZSBudW1iZXIgb2YgcmVzdWx0cyAoc28gdGhlIHRyZWUgc2hvd3Mgd2hpY2ggUVVFUlkgcmV0dXJucyB0aGUgbW9zdCkgLSBhbmQgXCI8b3A+IHJlc3VsdHNcIiAtIG9uZSBjb3VudC1vbmx5IGFjY2VzcyBwZXIgcmV0dXJuZWQgcGF0aCAoc28gdGhlIHRyZWUgc2hvd3Mgd2hpY2ggUEFUSFMgY29tZSBiYWNrIG1vc3QpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYWNrQWNjZXNzQ2FsbChvcGVyYXRpb246IHN0cmluZykge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0OiB1bmtub3duLCBrZXk6IHN0cmluZywgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yKTogdm9pZCB7XG4gICAgICAgIGxldCBvcmlnaW5hbCA9IGRlc2NyaXB0b3IudmFsdWUgYXMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gUHJvbWlzZTx1bmtub3duPjtcbiAgICAgICAgZGVzY3JpcHRvci52YWx1ZSA9IGFzeW5jIGZ1bmN0aW9uICguLi5hcmdzOiB1bmtub3duW10pOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgICAgIGxldCBjb25maWcgPSBhcmdzWzBdIGFzIHsgYWNjb3VudDogc3RyaW5nOyBidWNrZXROYW1lOiBzdHJpbmc7IHBhdGg/OiBzdHJpbmc7IHByZWZpeD86IHN0cmluZzsgZGF0YT86IEJ1ZmZlciB9O1xuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgbGV0IGJhc2UgPSBgJHtjb25maWcuYnVja2V0TmFtZX0vYDtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgcXVlcnksIHNpemVkIGJ5IGhvdyBtYW55IHJlc3VsdHMgaXQgcmV0dXJuZWQgKHdoaWNoIHF1ZXJ5IGlzIGhlYXZpZXN0KTsgYW5kIGVhY2ggcmV0dXJuZWQgcGF0aCwgY291bnQtb25seSAod2hpY2ggcGF0aHMgY29tZSBiYWNrIG1vc3QpXG4gICAgICAgICAgICAgICAgdHJhY2tBY2Nlc3MoeyBhY2NvdW50OiBjb25maWcuYWNjb3VudCwgb3BlcmF0aW9uOiBgJHtvcGVyYXRpb259IHF1ZXJpZXNgLCBwYXRoOiBiYXNlICsgKGNvbmZpZy5wcmVmaXggfHwgY29uZmlnLnBhdGggfHwgXCJcIiksIHNpemU6IHJlc3VsdC5sZW5ndGggfSk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgcmVzdWx0IGFzIHsgcGF0aDogc3RyaW5nIH1bXSkge1xuICAgICAgICAgICAgICAgICAgICB0cmFja0FjY2Vzcyh7IGFjY291bnQ6IGNvbmZpZy5hY2NvdW50LCBvcGVyYXRpb246IGAke29wZXJhdGlvbn0gcmVzdWx0c2AsIHBhdGg6IGJhc2UgKyBlbnRyeS5wYXRoIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHNpemU6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChjb25maWcuZGF0YSkge1xuICAgICAgICAgICAgICAgIHNpemUgPSBjb25maWcuZGF0YS5sZW5ndGg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBkYXRhID0gKHJlc3VsdCBhcyB7IGRhdGE/OiBCdWZmZXIgfSB8IHVuZGVmaW5lZCk/LmRhdGE7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEpIHNpemUgPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyYWNrQWNjZXNzKHsgYWNjb3VudDogY29uZmlnLmFjY291bnQsIG9wZXJhdGlvbiwgcGF0aDogYmFzZSArIGNvbmZpZy5wYXRoLCBzaXplIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWNjZXNzVG90YWxzKGFjY291bnQ6IHN0cmluZyk6IEFjY2Vzc1RvdGFscyB7XG4gICAgbGV0IHJlc3VsdDogQWNjZXNzVG90YWxzID0ge307XG4gICAgbGV0IG9wZXJhdGlvbnMgPSBhY2NvdW50cy5nZXQoYWNjb3VudCk7XG4gICAgaWYgKCFvcGVyYXRpb25zKSByZXR1cm4gcmVzdWx0O1xuICAgIGZvciAobGV0IFtvcGVyYXRpb24sIHN0YXRzXSBvZiBvcGVyYXRpb25zKSB7XG4gICAgICAgIHJlc3VsdFtvcGVyYXRpb25dID0geyBjb3VudDogc3RhdHMudG90YWxDb3VudCwgc2l6ZTogc3RhdHMudG90YWxTaXplIH07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkQWNjZXNzU3VtbWFyaWVzKGNvbmZpZzogeyBhY2NvdW50OiBzdHJpbmc7IG9wZXJhdGlvbjogc3RyaW5nOyBtYXhDb3VudDogbnVtYmVyOyB3ZWlnaHRCeVNpemU/OiBib29sZWFuIH0pOiBTdW1tYXJ5RW50cnk8QWNjZXNzU3VtbWFyeVN0YXRlPltdIHtcbiAgICBsZXQgb3BlcmF0aW9ucyA9IGFjY291bnRzLmdldChjb25maWcuYWNjb3VudCk7XG4gICAgbGV0IHN0YXRzID0gb3BlcmF0aW9ucyAmJiBvcGVyYXRpb25zLmdldChjb25maWcub3BlcmF0aW9uKTtcbiAgICBpZiAoIXN0YXRzKSByZXR1cm4gW107XG4gICAgLy8gQ291bnQtb25seSBvcGVyYXRpb25zIGhhdmUgbm8gc2l6ZSB0cmVlLCBpbiB3aGljaCBjYXNlIHdlaWdodEJ5U2l6ZSBpcyBpZ25vcmVkIGFuZCB0aGUgY291bnQgYnJlYWtkb3duIGlzIHJldHVybmVkLlxuICAgIGxldCBzaXplVHJlZSA9IHN0YXRzLnNpemVUcmVlO1xuICAgIGlmIChjb25maWcud2VpZ2h0QnlTaXplICYmIHNpemVUcmVlKSB7XG4gICAgICAgIHJldHVybiBzaXplVHJlZS5nZXRTdW1tYXJpZXMoY29uZmlnLm1heENvdW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHN0YXRzLmNvdW50VHJlZS5nZXRTdW1tYXJpZXMoY29uZmlnLm1heENvdW50KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyQWNjb3VudEFjY2Vzc1N0YXRzKGFjY291bnQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmIChhY2NvdW50cy5kZWxldGUoYWNjb3VudCkpIHtcbiAgICAgICAgY29uc29sZS5sb2coYENsZWFyZWQgdGhlIGluLW1lbW9yeSBhY2Nlc3Mgc3RhdGlzdGljcyBmb3IgYWNjb3VudCAke2FjY291bnR9YCk7XG4gICAgfVxufVxuIl19
|
|
109
|
-
|
|
108
|
+
function emptyWriteStats() {
|
|
109
|
+
return { originalWrites: 0, originalBytes: 0, flushedWrites: 0, flushedBytes: 0 };
|
|
110
|
+
}
|
|
111
|
+
// In memory only, keyed `${account}/${bucketName}`: totals since this process started (or the last clearWriteStats). Persisting them to disk was more machinery than the numbers were worth.
|
|
112
|
+
const writeStats = new Map();
|
|
113
|
+
function countBucketWrite(key, kind, bytes) {
|
|
114
|
+
let stats = writeStats.get(key);
|
|
115
|
+
if (!stats) {
|
|
116
|
+
stats = emptyWriteStats();
|
|
117
|
+
writeStats.set(key, stats);
|
|
118
|
+
}
|
|
119
|
+
if (kind === "original") {
|
|
120
|
+
stats.originalWrites++;
|
|
121
|
+
stats.originalBytes += bytes;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
stats.flushedWrites++;
|
|
125
|
+
stats.flushedBytes += bytes;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.countBucketWrite = countBucketWrite;
|
|
129
|
+
function getBucketWriteStats(key) {
|
|
130
|
+
return writeStats.get(key) || emptyWriteStats();
|
|
131
|
+
}
|
|
132
|
+
exports.getBucketWriteStats = getBucketWriteStats;
|
|
133
|
+
/** Zeroes the write statistics of every bucket in the account. */
|
|
134
|
+
function debugClearAccountWriteStats(account) {
|
|
135
|
+
let prefix = `${account}/`;
|
|
136
|
+
let cleared = 0;
|
|
137
|
+
for (let key of [...writeStats.keys()]) {
|
|
138
|
+
if (!key.startsWith(prefix))
|
|
139
|
+
continue;
|
|
140
|
+
writeStats.delete(key);
|
|
141
|
+
cleared++;
|
|
142
|
+
}
|
|
143
|
+
console.log(`Cleared the write statistics of ${cleared} buckets in account ${account}`);
|
|
144
|
+
return cleared;
|
|
145
|
+
}
|
|
146
|
+
exports.debugClearAccountWriteStats = debugClearAccountWriteStats;
|
|
147
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzU3RhdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhY2Nlc3NTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtREFBOEQ7QUFFOUQsTUFBTSxxQkFBcUIsR0FBRyxHQUFHLENBQUM7QUFjbEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQXVDLENBQUM7QUFFaEUsU0FBUyxRQUFRLENBQUMsUUFBd0M7SUFDdEQsT0FBTyxJQUFJLHlCQUFXLENBQWtDO1FBQ3BELE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJO1FBQzVCLGFBQWEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ25DLFlBQVksRUFBRSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUM3QixPQUFPLENBQUMsS0FBSyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBQ0QsY0FBYyxFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQy9CLE1BQU0sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQztRQUNqQyxDQUFDO1FBQ0QsU0FBUyxFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUs7UUFDbkMsbUJBQW1CLEVBQUUscUJBQXFCO0tBQzdDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCx5TUFBeU07QUFDek0sU0FBZ0IsV0FBVyxDQUFDLE1BQTJFO0lBQ25HLElBQUksVUFBVSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNkLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxVQUFV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QixLQUFLLENBQUMsYUFBYSxJQUFJLEtBQUssQ0FBQztJQUNqQyxDQUFDO1NBQU0sQ0FBQztRQUNKLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN0QixLQUFLLENBQUMsWUFBWSxJQUFJLEtBQUssQ0FBQztJQUNoQyxDQUFDO0FBQ0wsQ0FBQztBQWJELDRDQWFDO0FBRUQsU0FBZ0IsbUJBQW1CLENBQUMsR0FBVztJQUMzQyxPQUFPLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksZUFBZSxFQUFFLENBQUM7QUFDcEQsQ0FBQztBQUZELGtEQUVDO0FBRUQsa0VBQWtFO0FBQ2xFLFNBQWdCLDJCQUEyQixDQUFDLE9BQWU7SUFDdkQsSUFBSSxNQUFNLEdBQUcsR0FBRyxPQUFPLEdBQUcsQ0FBQztJQUMzQixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDaEIsS0FBSyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFBRSxTQUFTO1FBQ3RDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQ0FBbUMsT0FBTyx1QkFBdUIsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUN4RixPQUFPLE9BQU8sQ0FBQztBQUNuQixDQUFDO0FBVkQsa0VBVUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUcmVlU3VtbWFyeSwgU3VtbWFyeUVudHJ5IH0gZnJvbSBcIi4uLy4uL3RyZWVTdW1tYXJ5XCI7XG5cbmNvbnN0IEVYUEVDVEVEX09VVFBVVF9DT1VOVCA9IDEwMDtcblxuZXhwb3J0IHR5cGUgQWNjZXNzU3VtbWFyeVN0YXRlID0geyB0b3RhbDogbnVtYmVyIH07XG5leHBvcnQgdHlwZSBBY2Nlc3NUb3RhbHMgPSB7IFtvcGVyYXRpb246IHN0cmluZ106IHsgY291bnQ6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfTtcblxudHlwZSBBY2Nlc3NWYWx1ZSA9IHsgcGF0aDogc3RyaW5nOyBzaXplOiBudW1iZXIgfTtcbnR5cGUgT3BlcmF0aW9uU3RhdHMgPSB7XG4gICAgdG90YWxDb3VudDogbnVtYmVyO1xuICAgIHRvdGFsU2l6ZTogbnVtYmVyO1xuICAgIGNvdW50VHJlZTogVHJlZVN1bW1hcnk8QWNjZXNzVmFsdWUsIEFjY2Vzc1N1bW1hcnlTdGF0ZT47XG4gICAgLy8gT25seSBleGlzdHMgZm9yIG9wZXJhdGlvbnMgdHJhY2tlZCB3aXRoIHNpemVzOyBjb3VudC1vbmx5IG9wZXJhdGlvbnMgKGdldEluZm8sIGRlbCwgLi4uKSBoYXZlIG5vIG1lYW5pbmdmdWwgc2l6ZSBicmVha2Rvd24uXG4gICAgc2l6ZVRyZWU/OiBUcmVlU3VtbWFyeTxBY2Nlc3NWYWx1ZSwgQWNjZXNzU3VtbWFyeVN0YXRlPjtcbn07XG5cbmNvbnN0IGFjY291bnRzID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIE9wZXJhdGlvblN0YXRzPj4oKTtcblxuZnVuY3Rpb24gbWFrZVRyZWUoZ2V0VmFsdWU6ICh2YWx1ZTogQWNjZXNzVmFsdWUpID0+IG51bWJlcik6IFRyZWVTdW1tYXJ5PEFjY2Vzc1ZhbHVlLCBBY2Nlc3NTdW1tYXJ5U3RhdGU+IHtcbiAgICByZXR1cm4gbmV3IFRyZWVTdW1tYXJ5PEFjY2Vzc1ZhbHVlLCBBY2Nlc3NTdW1tYXJ5U3RhdGU+KHtcbiAgICAgICAgZ2V0UGF0aDogdmFsdWUgPT4gdmFsdWUucGF0aCxcbiAgICAgICAgY3JlYXRlU3VtbWFyeTogKCkgPT4gKHsgdG90YWw6IDAgfSksXG4gICAgICAgIGFkZFRvU3VtbWFyeTogKHZhbHVlLCBzdW1tYXJ5KSA9PiB7XG4gICAgICAgICAgICBzdW1tYXJ5LnRvdGFsICs9IGdldFZhbHVlKHZhbHVlKTtcbiAgICAgICAgfSxcbiAgICAgICAgbWVyZ2VTdW1tYXJpZXM6ICh0YXJnZXQsIHNvdXJjZSkgPT4ge1xuICAgICAgICAgICAgdGFyZ2V0LnRvdGFsICs9IHNvdXJjZS50b3RhbDtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0V2VpZ2h0OiBzdW1tYXJ5ID0+IHN1bW1hcnkudG90YWwsXG4gICAgICAgIGV4cGVjdGVkT3V0cHV0Q291bnQ6IEVYUEVDVEVEX09VVFBVVF9DT1VOVCxcbiAgICB9KTtcbn1cblxuLyoqIENvdW50cyBvbmUgc3RvcmFnZSBhY2Nlc3MsIGluIG1lbW9yeSBvbmx5LiBzaXplIGlzIHRoZSBieXRlcyBpbnZvbHZlZCAoMCB3aGVuIHRoZSB0YXJnZXQgZG9lcyBub3QgZXhpc3QpOyBvbWl0IGl0IGVudGlyZWx5IGZvciBvcGVyYXRpb25zIHRoYXQgb25seSBjb3VudCBjYWxscywgd2hpY2ggdGhlbiBvbmx5IGdldCBhIGNvdW50IHRyZWUuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhY2tBY2Nlc3MoY29uZmlnOiB7IGFjY291bnQ6IHN0cmluZzsgb3BlcmF0aW9uOiBzdHJpbmc7IHBhdGg6IHN0cmluZzsgc2l6ZT86IG51bWJlciB9KTogdm9pZCB7XG4gICAgbGV0IG9wZXJhdGlvbnMgPSBhY2NvdW50cy5nZXQoY29uZmlnLmFjY291bnQpO1xuICAgIGlmICghb3BlcmF0aW9ucykge1xuICAgICAgICBvcGVyYXRpb25zID0gbmV3IE1hcCgpO1xuICAgICAgICBhY2NvdW50cy5zZXQoY29uZmlnLmFjY291bnQsIG9wZXJhdGlvbnMpO1xuICAgIH1cbiAgICBsZXQgc3RhdHMgPSBvcGVyYXRpb25zLmdldChjb25maWcub3BlcmF0aW9uKTtcbiAgICBpZiAoIXN0YXRzKSB7XG4gICAgICAgIHN0YXRzID0geyB0b3RhbENvdW50OiAwLCB0b3RhbFNpemU6IDAsIGNvdW50VHJlZTogbWFrZVRyZWUoKCkgPT4gMSkgfTtcbiAgICAgICAgb3BlcmF0aW9ucy5zZXQoY29uZmlnLm9wZXJhdGlvbiwgc3RhdHMpO1xuICAgIH1cbiAgICBsZXQgdmFsdWU6IEFjY2Vzc1ZhbHVlID0geyBwYXRoOiBjb25maWcucGF0aCwgc2l6ZTogY29uZmlnLnNpemUgfHwgMCB9O1xuICAgIHN0YXRzLnRvdGFsQ291bnQrKztcbiAgICBzdGF0cy5jb3VudFRyZWUuYWRkKHZhbHVlKTtcbiAgICBpZiAoY29uZmlnLnNpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsZXQgc2l6ZVRyZWUgPSBzdGF0cy5zaXplVHJlZTtcbiAgICAgICAgaWYgKCFzaXplVHJlZSkge1xuICAgICAgICAgICAgc2l6ZVRyZWUgPSBtYWtlVHJlZSh2ID0+IHYuc2l6ZSk7XG4gICAgICAgICAgICBzdGF0cy5zaXplVHJlZSA9IHNpemVUcmVlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRzLnRvdGFsU2l6ZSArPSBjb25maWcuc2l6ZTtcbiAgICAgICAgc2l6ZVRyZWUuYWRkKHZhbHVlKTtcbiAgICB9XG59XG5cbi8qKiBNZXRob2QgZGVjb3JhdG9yIGZhY3RvcnksIGZvciBBUEkgbWV0aG9kcyB3aG9zZSBzaW5nbGUgY29uZmlnLW9iamVjdCBhcmd1bWVudCBoYXMgYWNjb3VudCBhbmQgYnVja2V0TmFtZTogdHJhY2tzIHRoZSBhY2Nlc3MgKGFzIGBidWNrZXROYW1lL3BhdGhgKSBhZnRlciB0aGUgbWV0aG9kIHN1Y2NlZWRzLiBTaXplcyBjb21lIGZyb20gdGhlIGNvbmZpZydzIGRhdGEgKHdyaXRlcykgb3IgdGhlIHJlc3VsdCdzIGRhdGEgKHJlYWRzKTsgb3BlcmF0aW9ucyB3aXRob3V0IGVpdGhlciBhcmUgY291bnQtb25seS4gQXJyYXkgcmVzdWx0cyAobGlzdGluZ3MgLSBmaW5kSW5mbywgZ2V0Q2hhbmdlc0FmdGVyKSBhcmUgdHJhY2tlZCBhcyB0d28gYnJlYWtkb3duczogXCI8b3A+IHF1ZXJpZXNcIiAtIG9uZSBhY2Nlc3MgcGVyIENBTEwsIGF0IHRoZSBxdWVyeSBwcmVmaXgsIHNpemVkIGJ5IHRoZSBudW1iZXIgb2YgcmVzdWx0cyAoc28gdGhlIHRyZWUgc2hvd3Mgd2hpY2ggUVVFUlkgcmV0dXJucyB0aGUgbW9zdCkgLSBhbmQgXCI8b3A+IHJlc3VsdHNcIiAtIG9uZSBjb3VudC1vbmx5IGFjY2VzcyBwZXIgcmV0dXJuZWQgcGF0aCAoc28gdGhlIHRyZWUgc2hvd3Mgd2hpY2ggUEFUSFMgY29tZSBiYWNrIG1vc3QpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYWNrQWNjZXNzQ2FsbChvcGVyYXRpb246IHN0cmluZykge1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0OiB1bmtub3duLCBrZXk6IHN0cmluZywgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yKTogdm9pZCB7XG4gICAgICAgIGxldCBvcmlnaW5hbCA9IGRlc2NyaXB0b3IudmFsdWUgYXMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gUHJvbWlzZTx1bmtub3duPjtcbiAgICAgICAgZGVzY3JpcHRvci52YWx1ZSA9IGFzeW5jIGZ1bmN0aW9uICguLi5hcmdzOiB1bmtub3duW10pOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgICAgIGxldCBjb25maWcgPSBhcmdzWzBdIGFzIHsgYWNjb3VudDogc3RyaW5nOyBidWNrZXROYW1lOiBzdHJpbmc7IHBhdGg/OiBzdHJpbmc7IHByZWZpeD86IHN0cmluZzsgZGF0YT86IEJ1ZmZlciB9O1xuICAgICAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgbGV0IGJhc2UgPSBgJHtjb25maWcuYnVja2V0TmFtZX0vYDtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgcXVlcnksIHNpemVkIGJ5IGhvdyBtYW55IHJlc3VsdHMgaXQgcmV0dXJuZWQgKHdoaWNoIHF1ZXJ5IGlzIGhlYXZpZXN0KTsgYW5kIGVhY2ggcmV0dXJuZWQgcGF0aCwgY291bnQtb25seSAod2hpY2ggcGF0aHMgY29tZSBiYWNrIG1vc3QpXG4gICAgICAgICAgICAgICAgdHJhY2tBY2Nlc3MoeyBhY2NvdW50OiBjb25maWcuYWNjb3VudCwgb3BlcmF0aW9uOiBgJHtvcGVyYXRpb259IHF1ZXJpZXNgLCBwYXRoOiBiYXNlICsgKGNvbmZpZy5wcmVmaXggfHwgY29uZmlnLnBhdGggfHwgXCJcIiksIHNpemU6IHJlc3VsdC5sZW5ndGggfSk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgcmVzdWx0IGFzIHsgcGF0aDogc3RyaW5nIH1bXSkge1xuICAgICAgICAgICAgICAgICAgICB0cmFja0FjY2Vzcyh7IGFjY291bnQ6IGNvbmZpZy5hY2NvdW50LCBvcGVyYXRpb246IGAke29wZXJhdGlvbn0gcmVzdWx0c2AsIHBhdGg6IGJhc2UgKyBlbnRyeS5wYXRoIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHNpemU6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChjb25maWcuZGF0YSkge1xuICAgICAgICAgICAgICAgIHNpemUgPSBjb25maWcuZGF0YS5sZW5ndGg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBkYXRhID0gKHJlc3VsdCBhcyB7IGRhdGE/OiBCdWZmZXIgfSB8IHVuZGVmaW5lZCk/LmRhdGE7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEpIHNpemUgPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyYWNrQWNjZXNzKHsgYWNjb3VudDogY29uZmlnLmFjY291bnQsIG9wZXJhdGlvbiwgcGF0aDogYmFzZSArIGNvbmZpZy5wYXRoLCBzaXplIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWNjZXNzVG90YWxzKGFjY291bnQ6IHN0cmluZyk6IEFjY2Vzc1RvdGFscyB7XG4gICAgbGV0IHJlc3VsdDogQWNjZXNzVG90YWxzID0ge307XG4gICAgbGV0IG9wZXJhdGlvbnMgPSBhY2NvdW50cy5nZXQoYWNjb3VudCk7XG4gICAgaWYgKCFvcGVyYXRpb25zKSByZXR1cm4gcmVzdWx0O1xuICAgIGZvciAobGV0IFtvcGVyYXRpb24sIHN0YXRzXSBvZiBvcGVyYXRpb25zKSB7XG4gICAgICAgIHJlc3VsdFtvcGVyYXRpb25dID0geyBjb3VudDogc3RhdHMudG90YWxDb3VudCwgc2l6ZTogc3RhdHMudG90YWxTaXplIH07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkQWNjZXNzU3VtbWFyaWVzKGNvbmZpZzogeyBhY2NvdW50OiBzdHJpbmc7IG9wZXJhdGlvbjogc3RyaW5nOyBtYXhDb3VudDogbnVtYmVyOyB3ZWlnaHRCeVNpemU/OiBib29sZWFuIH0pOiBTdW1tYXJ5RW50cnk8QWNjZXNzU3VtbWFyeVN0YXRlPltdIHtcbiAgICBsZXQgb3BlcmF0aW9ucyA9IGFjY291bnRzLmdldChjb25maWcuYWNjb3VudCk7XG4gICAgbGV0IHN0YXRzID0gb3BlcmF0aW9ucyAmJiBvcGVyYXRpb25zLmdldChjb25maWcub3BlcmF0aW9uKTtcbiAgICBpZiAoIXN0YXRzKSByZXR1cm4gW107XG4gICAgLy8gQ291bnQtb25seSBvcGVyYXRpb25zIGhhdmUgbm8gc2l6ZSB0cmVlLCBpbiB3aGljaCBjYXNlIHdlaWdodEJ5U2l6ZSBpcyBpZ25vcmVkIGFuZCB0aGUgY291bnQgYnJlYWtkb3duIGlzIHJldHVybmVkLlxuICAgIGxldCBzaXplVHJlZSA9IHN0YXRzLnNpemVUcmVlO1xuICAgIGlmIChjb25maWcud2VpZ2h0QnlTaXplICYmIHNpemVUcmVlKSB7XG4gICAgICAgIHJldHVybiBzaXplVHJlZS5nZXRTdW1tYXJpZXMoY29uZmlnLm1heENvdW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHN0YXRzLmNvdW50VHJlZS5nZXRTdW1tYXJpZXMoY29uZmlnLm1heENvdW50KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyQWNjb3VudEFjY2Vzc1N0YXRzKGFjY291bnQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmIChhY2NvdW50cy5kZWxldGUoYWNjb3VudCkpIHtcbiAgICAgICAgY29uc29sZS5sb2coYENsZWFyZWQgdGhlIGluLW1lbW9yeSBhY2Nlc3Mgc3RhdGlzdGljcyBmb3IgYWNjb3VudCAke2FjY291bnR9YCk7XG4gICAgfVxufVxuXG5leHBvcnQgdHlwZSBCdWNrZXRXcml0ZVN0YXRzID0ge1xuICAgIC8qKiBFdmVyeSBzZXQgY2FsbCB0aGUgYnVja2V0IGFjY2VwdGVkICovXG4gICAgb3JpZ2luYWxXcml0ZXM6IG51bWJlcjtcbiAgICBvcmlnaW5hbEJ5dGVzOiBudW1iZXI7XG4gICAgLyoqIFdoYXQgYWN0dWFsbHkgcmVhY2hlZCB0aGUgc291cmNlcy4gRmFzdCB3cml0ZXMgY29hbGVzY2UgcmVwZWF0ZWQgd3JpdGVzIHRvIHRoZSBzYW1lIGtleSwgc28gdGhpcyBpcyBsb3dlciB0aGFuIHRoZSBvcmlnaW5hbCBjb3VudHMgKGFuZCBpcyB3aGF0IHRoZSBkaXNrIGFjdHVhbGx5IGRpZCkuICovXG4gICAgZmx1c2hlZFdyaXRlczogbnVtYmVyO1xuICAgIGZsdXNoZWRCeXRlczogbnVtYmVyO1xufTtcbmZ1bmN0aW9uIGVtcHR5V3JpdGVTdGF0cygpOiBCdWNrZXRXcml0ZVN0YXRzIHtcbiAgICByZXR1cm4geyBvcmlnaW5hbFdyaXRlczogMCwgb3JpZ2luYWxCeXRlczogMCwgZmx1c2hlZFdyaXRlczogMCwgZmx1c2hlZEJ5dGVzOiAwIH07XG59XG5cbi8vIEluIG1lbW9yeSBvbmx5LCBrZXllZCBgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YDogdG90YWxzIHNpbmNlIHRoaXMgcHJvY2VzcyBzdGFydGVkIChvciB0aGUgbGFzdCBjbGVhcldyaXRlU3RhdHMpLiBQZXJzaXN0aW5nIHRoZW0gdG8gZGlzayB3YXMgbW9yZSBtYWNoaW5lcnkgdGhhbiB0aGUgbnVtYmVycyB3ZXJlIHdvcnRoLlxuY29uc3Qgd3JpdGVTdGF0cyA9IG5ldyBNYXA8c3RyaW5nLCBCdWNrZXRXcml0ZVN0YXRzPigpO1xuXG5leHBvcnQgZnVuY3Rpb24gY291bnRCdWNrZXRXcml0ZShrZXk6IHN0cmluZywga2luZDogXCJvcmlnaW5hbFwiIHwgXCJmbHVzaGVkXCIsIGJ5dGVzOiBudW1iZXIpOiB2b2lkIHtcbiAgICBsZXQgc3RhdHMgPSB3cml0ZVN0YXRzLmdldChrZXkpO1xuICAgIGlmICghc3RhdHMpIHtcbiAgICAgICAgc3RhdHMgPSBlbXB0eVdyaXRlU3RhdHMoKTtcbiAgICAgICAgd3JpdGVTdGF0cy5zZXQoa2V5LCBzdGF0cyk7XG4gICAgfVxuICAgIGlmIChraW5kID09PSBcIm9yaWdpbmFsXCIpIHtcbiAgICAgICAgc3RhdHMub3JpZ2luYWxXcml0ZXMrKztcbiAgICAgICAgc3RhdHMub3JpZ2luYWxCeXRlcyArPSBieXRlcztcbiAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0cy5mbHVzaGVkV3JpdGVzKys7XG4gICAgICAgIHN0YXRzLmZsdXNoZWRCeXRlcyArPSBieXRlcztcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCdWNrZXRXcml0ZVN0YXRzKGtleTogc3RyaW5nKTogQnVja2V0V3JpdGVTdGF0cyB7XG4gICAgcmV0dXJuIHdyaXRlU3RhdHMuZ2V0KGtleSkgfHwgZW1wdHlXcml0ZVN0YXRzKCk7XG59XG5cbi8qKiBaZXJvZXMgdGhlIHdyaXRlIHN0YXRpc3RpY3Mgb2YgZXZlcnkgYnVja2V0IGluIHRoZSBhY2NvdW50LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlYnVnQ2xlYXJBY2NvdW50V3JpdGVTdGF0cyhhY2NvdW50OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGxldCBwcmVmaXggPSBgJHthY2NvdW50fS9gO1xuICAgIGxldCBjbGVhcmVkID0gMDtcbiAgICBmb3IgKGxldCBrZXkgb2YgWy4uLndyaXRlU3RhdHMua2V5cygpXSkge1xuICAgICAgICBpZiAoIWtleS5zdGFydHNXaXRoKHByZWZpeCkpIGNvbnRpbnVlO1xuICAgICAgICB3cml0ZVN0YXRzLmRlbGV0ZShrZXkpO1xuICAgICAgICBjbGVhcmVkKys7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBDbGVhcmVkIHRoZSB3cml0ZSBzdGF0aXN0aWNzIG9mICR7Y2xlYXJlZH0gYnVja2V0cyBpbiBhY2NvdW50ICR7YWNjb3VudH1gKTtcbiAgICByZXR1cm4gY2xlYXJlZDtcbn1cbiJdfQ==
|
|
148
|
+
/* _JS_SOURCE_HASH = "dbfda82861ecf9c4e32ff89d5c1d8a7e4da239832af22846537b6dc240a78494"; */
|