sliftutils 1.7.10 → 1.7.11
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/examplestorage/exampleserver.ts +0 -2
- package/index.d.ts +290 -54
- package/misc/dist/environment.ts.cache +3 -3
- package/misc/dist/getSecret.ts.cache +139 -0
- package/misc/dist/strings.ts.cache +13 -0
- package/misc/dist/zip.ts.cache +9 -0
- package/misc/getSecret.ts +38 -16
- package/misc/https/cloudflareHelpers.d.ts +19 -0
- package/misc/https/cloudflareHelpers.ts +69 -0
- package/misc/https/dist/certs.ts.cache +115 -179
- package/misc/https/dist/cloudflareHelpers.ts.cache +68 -0
- package/misc/https/dist/dns.ts.cache +112 -100
- package/misc/https/dist/hostServer.ts.cache +130 -0
- package/misc/https/dist/httpsCerts.ts.cache +24 -5
- package/misc/https/dist/persistentLocalStorage.ts.cache +3 -2
- package/misc/https/dns.d.ts +41 -12
- package/misc/https/dns.ts +104 -101
- package/misc/https/hostServer.d.ts +0 -6
- package/misc/https/hostServer.ts +9 -5
- package/package.json +2 -2
- package/render-utils/dist/observer.tsx.cache +3 -2
- package/spec.txt +0 -90
- package/storage/ArchivesDisk.d.ts +2 -0
- package/storage/ArchivesDisk.ts +7 -3
- package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +1242 -0
- package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +513 -0
- package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +352 -0
- package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +306 -0
- package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +435 -0
- package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +58 -0
- package/storage/BulkDatabase2/dist/blockCache.ts.cache +179 -0
- package/storage/BulkDatabase2/dist/mergeLock.ts.cache +149 -0
- package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +101 -0
- package/storage/BulkDatabase2/dist/streamLog.ts.cache +227 -0
- package/storage/BulkDatabase2/dist/syncClient.ts.cache +104 -0
- package/storage/IArchives.d.ts +47 -15
- package/storage/IArchives.ts +86 -31
- package/storage/backblaze.d.ts +15 -0
- package/storage/backblaze.ts +199 -79
- package/storage/dist/ArchivesDisk.ts.cache +373 -0
- package/storage/dist/FileFolderAPI.tsx.cache +508 -65
- package/storage/dist/IArchives.ts.cache +44 -0
- package/storage/dist/IndexedDBFileFolderAPI.ts.cache +8 -2
- package/storage/dist/JSONStorage.ts.cache +6 -2
- package/storage/dist/PendingManager.tsx.cache +1 -1
- package/storage/dist/TransactionStorage.ts.cache +231 -92
- package/storage/dist/backblaze.ts.cache +797 -0
- package/storage/dist/fileSystemPointer.ts.cache +36 -3
- package/storage/dist/remoteFileStorage.ts.cache +495 -0
- package/storage/remoteStorage/ArchivesRemote.d.ts +5 -1
- package/storage/remoteStorage/ArchivesRemote.ts +28 -8
- package/storage/remoteStorage/ArchivesUrl.d.ts +2 -0
- package/storage/remoteStorage/ArchivesUrl.ts +16 -4
- package/storage/remoteStorage/blobStore.d.ts +52 -3
- package/storage/remoteStorage/blobStore.ts +414 -101
- package/storage/remoteStorage/createArchives.d.ts +31 -10
- package/storage/remoteStorage/createArchives.ts +470 -253
- package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +197 -0
- package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +85 -0
- package/storage/remoteStorage/dist/accessPage.tsx.cache +222 -0
- package/storage/remoteStorage/dist/blobStore.ts.cache +837 -0
- package/storage/remoteStorage/dist/cliArgs.ts.cache +16 -0
- package/storage/remoteStorage/dist/createArchives.ts.cache +610 -0
- package/storage/remoteStorage/dist/remoteConfig.ts.cache +206 -0
- package/storage/remoteStorage/dist/sourceWrapper.ts.cache +223 -0
- package/storage/remoteStorage/dist/storageController.ts.cache +500 -0
- package/storage/remoteStorage/dist/storageServer.ts.cache +106 -0
- package/storage/remoteStorage/dist/storageServerCli.ts.cache +39 -0
- package/storage/remoteStorage/dist/storageServerState.ts.cache +518 -0
- package/storage/remoteStorage/remoteConfig.d.ts +8 -0
- package/storage/remoteStorage/remoteConfig.ts +105 -5
- package/storage/remoteStorage/sourceWrapper.d.ts +41 -0
- package/storage/remoteStorage/sourceWrapper.ts +223 -0
- package/storage/remoteStorage/spec.md +31 -0
- package/storage/remoteStorage/storageController.d.ts +11 -0
- package/storage/remoteStorage/storageController.ts +109 -40
- package/storage/remoteStorage/storageServer.d.ts +0 -5
- package/storage/remoteStorage/storageServer.ts +17 -10
- package/storage/remoteStorage/storageServerCli.ts +0 -3
- package/storage/remoteStorage/storageServerState.d.ts +7 -1
- package/storage/remoteStorage/storageServerState.ts +230 -48
- package/testsite/server.ts +0 -2
- package/yarn.lock +11 -6
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
3
|
+
//exports.orderStreamEntries = exports.loadStreamEntries = exports.loadFileReader = exports.makeRawGetRange = exports.LoadedIndex = exports.MissingFileError = void 0;
|
|
4
|
+
const BulkDatabaseFormat_1 = require("./BulkDatabaseFormat");
|
|
5
|
+
const blockCache_1 = require("./blockCache");
|
|
6
|
+
const streamLog_1 = require("./streamLog");
|
|
7
|
+
const format_1 = require("socket-function/src/formatting/format");
|
|
8
|
+
const logColors_1 = require("socket-function/src/formatting/logColors");
|
|
9
|
+
// Duplicated from BulkDatabaseBase to avoid a circular import — used only to build a fuller storage-relative path for log messages.
|
|
10
|
+
const BULK_ROOT_FOLDER = "bulkDatabases2";
|
|
11
|
+
class MissingFileError extends Error {
|
|
12
|
+
}
|
|
13
|
+
exports.MissingFileError = MissingFileError;
|
|
14
|
+
class FilesChangedError extends Error {
|
|
15
|
+
}
|
|
16
|
+
const MAX_READ_ATTEMPTS = 8;
|
|
17
|
+
function nullJoin(a, b) {
|
|
18
|
+
return a + String.fromCharCode(0) + b;
|
|
19
|
+
}
|
|
20
|
+
// A loaded snapshot of one collection's on-disk state: the resolved reader + the per-file decoded sub-
|
|
21
|
+
// readers it stitched, the stream file sizes/times it observed, and the sync (reactive) caches that
|
|
22
|
+
// surface column/field reads. Built once via LoadedIndex.build — eagerly, so the swap into a fresh
|
|
23
|
+
// LoadedIndex never blocks a read on a synchronous rebuild.
|
|
24
|
+
class LoadedIndex {
|
|
25
|
+
constructor(name, storage, bulkFiles, streamFiles, reader, streamTimes, streamSizes, streamRowsOnDisk, streamBytesOnDisk, subCaches) {
|
|
26
|
+
this.name = name;
|
|
27
|
+
this.storage = storage;
|
|
28
|
+
this.bulkFiles = bulkFiles;
|
|
29
|
+
this.streamFiles = streamFiles;
|
|
30
|
+
this.reader = reader;
|
|
31
|
+
this.streamTimes = streamTimes;
|
|
32
|
+
this.streamSizes = streamSizes;
|
|
33
|
+
this.streamRowsOnDisk = streamRowsOnDisk;
|
|
34
|
+
this.streamBytesOnDisk = streamBytesOnDisk;
|
|
35
|
+
this.subCaches = subCaches;
|
|
36
|
+
this.baseColumns = new Map();
|
|
37
|
+
this.baseColumnsLoading = new Set();
|
|
38
|
+
this.baseFields = new Map();
|
|
39
|
+
this.baseFieldsLoading = new Set();
|
|
40
|
+
// Last-known values from the previous index, served until this index loads its own fresh value, so
|
|
41
|
+
// a swap doesn't flash empty in sync reads. Cleared per-entry when the fresh value lands.
|
|
42
|
+
this.staleBaseColumns = new Map();
|
|
43
|
+
this.staleBaseFields = new Map();
|
|
44
|
+
this.keys = new Set(reader.keys);
|
|
45
|
+
this.fileSet = new Set([...bulkFiles.map(f => f.fileName), ...streamFiles.map(f => f.fileName)]);
|
|
46
|
+
}
|
|
47
|
+
get totalBytes() { return this.reader.totalBytes; }
|
|
48
|
+
get rowCount() { return this.reader.rowCount; }
|
|
49
|
+
isLive(key) { return this.keys.has(key); }
|
|
50
|
+
static async build(config) {
|
|
51
|
+
var _a, _b;
|
|
52
|
+
const start = Date.now();
|
|
53
|
+
let { bulkFiles, streamFiles } = config;
|
|
54
|
+
let attempt = 0;
|
|
55
|
+
while (true) {
|
|
56
|
+
const tolerateMissing = attempt >= MAX_READ_ATTEMPTS;
|
|
57
|
+
try {
|
|
58
|
+
let filesChanged = false;
|
|
59
|
+
const [bulkReadersRaw, streamData] = await Promise.all([
|
|
60
|
+
Promise.all(bulkFiles.map(async (f) => {
|
|
61
|
+
try {
|
|
62
|
+
return await loadFileReader(config.name, config.storage, f, config.subCaches.bulk);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
if (e instanceof MissingFileError) {
|
|
66
|
+
filesChanged = true;
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
if (config.onUnreadableFile)
|
|
70
|
+
await config.onUnreadableFile(f, e.message);
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
})),
|
|
74
|
+
loadStreamEntries(config.name, config.storage, streamFiles, config.subCaches.stream),
|
|
75
|
+
]);
|
|
76
|
+
if (streamData.missing)
|
|
77
|
+
filesChanged = true;
|
|
78
|
+
if (filesChanged && !tolerateMissing)
|
|
79
|
+
throw new FilesChangedError();
|
|
80
|
+
const bulkReaders = bulkReadersRaw.filter((r) => !!r);
|
|
81
|
+
const readers = [];
|
|
82
|
+
let streamTimes = new Map();
|
|
83
|
+
const ordered = orderStreamEntries(streamData.entries);
|
|
84
|
+
if (ordered.length) {
|
|
85
|
+
const stream = (0, streamLog_1.streamReaderFromEntries)(ordered, streamData.totalBytes);
|
|
86
|
+
readers.push(stream.reader);
|
|
87
|
+
streamTimes = stream.times;
|
|
88
|
+
}
|
|
89
|
+
readers.push(...bulkReaders);
|
|
90
|
+
const reader = joinBulkDatabases(readers);
|
|
91
|
+
pruneSubCaches(bulkFiles, streamFiles, config.subCaches);
|
|
92
|
+
const elapsed = Date.now() - start;
|
|
93
|
+
if (elapsed > 50) {
|
|
94
|
+
let bytesRead = streamData.totalBytes;
|
|
95
|
+
for (const r of bulkReaders)
|
|
96
|
+
bytesRead += (_b = (_a = r.columns.find(c => c.column === BulkDatabaseFormat_1.KEY_COLUMN)) === null || _a === void 0 ? void 0 : _a.byteSize) !== null && _b !== void 0 ? _b : 0;
|
|
97
|
+
console.log(`${(0, logColors_1.blue)(config.name)} loaded in ${(0, logColors_1.red)((0, format_1.formatTime)(elapsed))} (${(0, logColors_1.blue)((0, format_1.formatNumber)(reader.rowCount))} rows, ${bulkFiles.length} bulk + ${streamFiles.length} stream files, read ${(0, logColors_1.blue)((0, format_1.formatNumber)(bytesRead))}B)`);
|
|
98
|
+
}
|
|
99
|
+
return new LoadedIndex(config.name, config.storage, bulkFiles, streamFiles, reader, streamTimes, streamData.sizes, streamData.entries.length, streamData.totalBytes, config.subCaches);
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (e instanceof FilesChangedError) {
|
|
103
|
+
attempt++;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
throw e;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Adopts the previous index's loaded base values as STALE on this one, so a sync read mid-swap can
|
|
111
|
+
// serve the old value (patched with the current overlay) instead of flashing empty while the fresh
|
|
112
|
+
// load runs. Per-entry: dropped when the fresh value lands here.
|
|
113
|
+
inheritStaleFrom(prev) {
|
|
114
|
+
for (const [k, v] of prev.baseColumns)
|
|
115
|
+
this.staleBaseColumns.set(k, v);
|
|
116
|
+
for (const [k, v] of prev.staleBaseColumns)
|
|
117
|
+
if (!this.staleBaseColumns.has(k))
|
|
118
|
+
this.staleBaseColumns.set(k, v);
|
|
119
|
+
for (const [k, v] of prev.baseFields)
|
|
120
|
+
this.staleBaseFields.set(k, v);
|
|
121
|
+
for (const [k, v] of prev.staleBaseFields)
|
|
122
|
+
if (!this.staleBaseFields.has(k))
|
|
123
|
+
this.staleBaseFields.set(k, v);
|
|
124
|
+
}
|
|
125
|
+
async getColumn(column) {
|
|
126
|
+
return this.reader.getColumn(column);
|
|
127
|
+
}
|
|
128
|
+
async getSingleField(key, column) {
|
|
129
|
+
return this.reader.getSingleField(key, column);
|
|
130
|
+
}
|
|
131
|
+
ensureBaseColumn(column, onLoaded) {
|
|
132
|
+
if (this.baseColumns.has(column) || this.baseColumnsLoading.has(column))
|
|
133
|
+
return;
|
|
134
|
+
this.baseColumnsLoading.add(column);
|
|
135
|
+
void (async () => {
|
|
136
|
+
try {
|
|
137
|
+
const value = await this.reader.getColumn(column);
|
|
138
|
+
this.baseColumns.set(column, value);
|
|
139
|
+
this.staleBaseColumns.delete(column);
|
|
140
|
+
this.baseColumnsLoading.delete(column);
|
|
141
|
+
onLoaded();
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
this.baseColumnsLoading.delete(column);
|
|
145
|
+
console.warn(`${this.name}.getColumnSync(${JSON.stringify(column)}) load failed, will retry: ${e.message}`);
|
|
146
|
+
}
|
|
147
|
+
})();
|
|
148
|
+
}
|
|
149
|
+
ensureBaseField(key, column, onLoaded) {
|
|
150
|
+
const ck = nullJoin(column, key);
|
|
151
|
+
if (this.baseFields.has(ck) || this.baseFieldsLoading.has(ck))
|
|
152
|
+
return;
|
|
153
|
+
this.baseFieldsLoading.add(ck);
|
|
154
|
+
void (async () => {
|
|
155
|
+
try {
|
|
156
|
+
const value = await this.reader.getSingleField(key, column);
|
|
157
|
+
this.baseFields.set(ck, value);
|
|
158
|
+
this.staleBaseFields.delete(ck);
|
|
159
|
+
this.baseFieldsLoading.delete(ck);
|
|
160
|
+
onLoaded();
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
this.baseFieldsLoading.delete(ck);
|
|
164
|
+
console.warn(`${this.name}.getSingleFieldSync(${JSON.stringify(key)}, ${JSON.stringify(column)}) load failed, will retry: ${e.message}`);
|
|
165
|
+
}
|
|
166
|
+
})();
|
|
167
|
+
}
|
|
168
|
+
// Returns the loaded value (fresh if available, else last-known stale) for the column, or undefined
|
|
169
|
+
// if neither is present yet. The boolean indicates whether the returned value is fresh; callers may
|
|
170
|
+
// skip caching a stale value.
|
|
171
|
+
getBaseColumn(column) {
|
|
172
|
+
const fresh = this.baseColumns.get(column);
|
|
173
|
+
if (fresh)
|
|
174
|
+
return { entries: fresh, fresh: true };
|
|
175
|
+
const stale = this.staleBaseColumns.get(column);
|
|
176
|
+
if (stale)
|
|
177
|
+
return { entries: stale, fresh: false };
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
getBaseField(key, column) {
|
|
181
|
+
const ck = nullJoin(column, key);
|
|
182
|
+
if (this.baseFields.has(ck))
|
|
183
|
+
return { value: this.baseFields.get(ck), fresh: true, loaded: true };
|
|
184
|
+
if (this.staleBaseFields.has(ck))
|
|
185
|
+
return { value: this.staleBaseFields.get(ck), fresh: false, loaded: true };
|
|
186
|
+
return { value: undefined, fresh: false, loaded: false };
|
|
187
|
+
}
|
|
188
|
+
isBaseColumnLoaded(column) {
|
|
189
|
+
return this.baseColumns.has(column) || this.staleBaseColumns.has(column);
|
|
190
|
+
}
|
|
191
|
+
isBaseFieldLoaded(key, column) {
|
|
192
|
+
const ck = nullJoin(column, key);
|
|
193
|
+
return this.baseFields.has(ck) || this.staleBaseFields.has(ck);
|
|
194
|
+
}
|
|
195
|
+
// Drops in-memory loaded values for this index, so a subsequent read reloads fresh from disk. Used
|
|
196
|
+
// by reloadFromDisk() — a hard reset, no stale fallback survives.
|
|
197
|
+
dropLoadedValues() {
|
|
198
|
+
this.baseColumns.clear();
|
|
199
|
+
this.baseColumnsLoading.clear();
|
|
200
|
+
this.baseFields.clear();
|
|
201
|
+
this.baseFieldsLoading.clear();
|
|
202
|
+
this.staleBaseColumns.clear();
|
|
203
|
+
this.staleBaseFields.clear();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
exports.LoadedIndex = LoadedIndex;
|
|
207
|
+
async function makeRawGetRange(storage, fileName) {
|
|
208
|
+
const info = await storage.getInfo(fileName);
|
|
209
|
+
if (!info)
|
|
210
|
+
throw new MissingFileError(`bulk file ${fileName} is missing`);
|
|
211
|
+
const rawGetRange = async (start, end) => {
|
|
212
|
+
if (end <= start)
|
|
213
|
+
return BulkDatabaseFormat_1.EMPTY_BUFFER;
|
|
214
|
+
const buf = await storage.getRange(fileName, { start, end });
|
|
215
|
+
if (!buf)
|
|
216
|
+
throw new MissingFileError(`range [${start}, ${end}) of ${fileName} is missing`);
|
|
217
|
+
return buf;
|
|
218
|
+
};
|
|
219
|
+
return { rawGetRange, size: info.size };
|
|
220
|
+
}
|
|
221
|
+
exports.makeRawGetRange = makeRawGetRange;
|
|
222
|
+
async function loadFileReader(name, storage, f, cache) {
|
|
223
|
+
const cached = cache.get(f.fileName);
|
|
224
|
+
if (cached)
|
|
225
|
+
return cached;
|
|
226
|
+
const raw = await makeRawGetRange(storage, f.fileName);
|
|
227
|
+
const fileId = nullJoin(name, f.fileName);
|
|
228
|
+
const opened = await blockCache_1.blockCache.open(fileId, raw.size, raw.rawGetRange);
|
|
229
|
+
const reader = await (0, BulkDatabaseFormat_1.loadBulkDatabase)({ totalBytes: opened.uncompressedSize, getRange: opened.getRange, name: `${BULK_ROOT_FOLDER}/${name}/${f.fileName}` });
|
|
230
|
+
cache.set(f.fileName, reader);
|
|
231
|
+
return reader;
|
|
232
|
+
}
|
|
233
|
+
exports.loadFileReader = loadFileReader;
|
|
234
|
+
async function loadStreamEntries(name, storage, streamFiles, cache) {
|
|
235
|
+
const sizes = new Map();
|
|
236
|
+
if (!streamFiles.length)
|
|
237
|
+
return { entries: [], totalBytes: 0, missing: false, sizes };
|
|
238
|
+
let missing = false;
|
|
239
|
+
const perFile = await Promise.all(streamFiles.map(async (f) => {
|
|
240
|
+
try {
|
|
241
|
+
const info = await storage.getInfo(f.fileName);
|
|
242
|
+
if (!info) {
|
|
243
|
+
missing = true;
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
const size = info.size;
|
|
247
|
+
sizes.set(f.fileName, size);
|
|
248
|
+
const cached = cache.get(f.fileName);
|
|
249
|
+
if (cached && cached.readSize === size)
|
|
250
|
+
return { fileName: f.fileName, size, entries: cached.entries };
|
|
251
|
+
if (size === 0) {
|
|
252
|
+
cache.set(f.fileName, { readSize: 0, parsedPos: 0, entries: [] });
|
|
253
|
+
return { fileName: f.fileName, size: 0, entries: [] };
|
|
254
|
+
}
|
|
255
|
+
// Append-only: a larger size means new bytes at the tail, parse only those.
|
|
256
|
+
if (cached && size > cached.readSize) {
|
|
257
|
+
const suffix = await storage.getRange(f.fileName, { start: cached.parsedPos, end: size });
|
|
258
|
+
if (!suffix) {
|
|
259
|
+
missing = true;
|
|
260
|
+
return undefined;
|
|
261
|
+
}
|
|
262
|
+
const parsed = (0, streamLog_1.parseStream)(suffix);
|
|
263
|
+
if (parsed.badBytes > 0)
|
|
264
|
+
console.warn(`${name} stream file ${f.fileName} had ${parsed.badBytes} trailing bad/incomplete bytes (stopped reading there)`);
|
|
265
|
+
const entries = parsed.entries.length ? cached.entries.concat(parsed.entries) : cached.entries;
|
|
266
|
+
const parsedPos = cached.parsedPos + (suffix.length - parsed.badBytes);
|
|
267
|
+
cache.set(f.fileName, { readSize: size, parsedPos, entries });
|
|
268
|
+
return { fileName: f.fileName, size, entries };
|
|
269
|
+
}
|
|
270
|
+
const buffer = await storage.getRange(f.fileName, { start: 0, end: size });
|
|
271
|
+
if (!buffer) {
|
|
272
|
+
missing = true;
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
const parsed = (0, streamLog_1.parseStream)(buffer);
|
|
276
|
+
if (parsed.badBytes > 0)
|
|
277
|
+
console.warn(`${name} stream file ${f.fileName} had ${parsed.badBytes} trailing bad/incomplete bytes (stopped reading there)`);
|
|
278
|
+
cache.set(f.fileName, { readSize: size, parsedPos: size - parsed.badBytes, entries: parsed.entries });
|
|
279
|
+
return { fileName: f.fileName, size, entries: parsed.entries };
|
|
280
|
+
}
|
|
281
|
+
catch (_a) {
|
|
282
|
+
missing = true;
|
|
283
|
+
return undefined;
|
|
284
|
+
}
|
|
285
|
+
}));
|
|
286
|
+
const entries = [];
|
|
287
|
+
let totalBytes = 0;
|
|
288
|
+
for (const pf of perFile) {
|
|
289
|
+
if (!pf)
|
|
290
|
+
continue;
|
|
291
|
+
totalBytes += pf.size;
|
|
292
|
+
for (const entry of pf.entries)
|
|
293
|
+
entries.push({ time: entry.time, fileName: pf.fileName, entry });
|
|
294
|
+
}
|
|
295
|
+
return { entries, totalBytes, missing, sizes };
|
|
296
|
+
}
|
|
297
|
+
exports.loadStreamEntries = loadStreamEntries;
|
|
298
|
+
function orderStreamEntries(entries) {
|
|
299
|
+
entries.sort((a, b) => {
|
|
300
|
+
if (a.time !== b.time)
|
|
301
|
+
return a.time - b.time;
|
|
302
|
+
return a.fileName < b.fileName && -1 || a.fileName > b.fileName && 1 || 0;
|
|
303
|
+
});
|
|
304
|
+
return entries.map(e => e.entry);
|
|
305
|
+
}
|
|
306
|
+
exports.orderStreamEntries = orderStreamEntries;
|
|
307
|
+
function pruneSubCaches(bulkFiles, streamFiles, subCaches) {
|
|
308
|
+
const liveBulk = new Set(bulkFiles.map(f => f.fileName));
|
|
309
|
+
const liveStream = new Set(streamFiles.map(f => f.fileName));
|
|
310
|
+
for (const n of subCaches.bulk.keys())
|
|
311
|
+
if (!liveBulk.has(n))
|
|
312
|
+
subCaches.bulk.delete(n);
|
|
313
|
+
for (const n of subCaches.stream.keys())
|
|
314
|
+
if (!liveStream.has(n))
|
|
315
|
+
subCaches.stream.delete(n);
|
|
316
|
+
}
|
|
317
|
+
// A corrupt/unreadable column in ONE underlying file must not break the whole joined read. When a
|
|
318
|
+
// source's column read throws, we drop that source for that column (falling through to older readers,
|
|
319
|
+
// exactly as if the file never set the column) and warn once per (file, column) so the corruption is
|
|
320
|
+
// visible without flooding the log on every rebuild.
|
|
321
|
+
const warnedCorruptReads = new Set();
|
|
322
|
+
function warnCorruptRead(db, column, e) {
|
|
323
|
+
const path = db.name || "(unknown source)";
|
|
324
|
+
const dedupeKey = nullJoin(path, column);
|
|
325
|
+
if (warnedCorruptReads.has(dedupeKey))
|
|
326
|
+
return;
|
|
327
|
+
warnedCorruptReads.add(dedupeKey);
|
|
328
|
+
console.warn(`${(0, logColors_1.red)("corrupt read")}: file ${path} column ${JSON.stringify(column)} could not be read - skipping it (its data is dropped from results): ${e.message}`);
|
|
329
|
+
}
|
|
330
|
+
function joinBulkDatabases(databases) {
|
|
331
|
+
var _a, _b;
|
|
332
|
+
const deleteTime = new Map();
|
|
333
|
+
for (const db of databases) {
|
|
334
|
+
if (!db.deleteTimes)
|
|
335
|
+
continue;
|
|
336
|
+
for (const [key, t] of db.deleteTimes)
|
|
337
|
+
deleteTime.set(key, Math.max((_a = deleteTime.get(key)) !== null && _a !== void 0 ? _a : -Infinity, t));
|
|
338
|
+
}
|
|
339
|
+
const keyTime = new Map();
|
|
340
|
+
for (const db of databases) {
|
|
341
|
+
for (const [key, t] of db.keyTimes)
|
|
342
|
+
keyTime.set(key, Math.max((_b = keyTime.get(key)) !== null && _b !== void 0 ? _b : -Infinity, t));
|
|
343
|
+
}
|
|
344
|
+
const delOf = (key) => { var _a; return (_a = deleteTime.get(key)) !== null && _a !== void 0 ? _a : -Infinity; };
|
|
345
|
+
const keys = [];
|
|
346
|
+
for (const [key, t] of keyTime)
|
|
347
|
+
if (t > delOf(key))
|
|
348
|
+
keys.push(key);
|
|
349
|
+
const columns = [];
|
|
350
|
+
const columnByName = new Map();
|
|
351
|
+
for (const db of databases) {
|
|
352
|
+
for (const col of db.columns) {
|
|
353
|
+
let existing = columnByName.get(col.column);
|
|
354
|
+
if (!existing) {
|
|
355
|
+
existing = { column: col.column, byteSize: 0 };
|
|
356
|
+
columnByName.set(col.column, existing);
|
|
357
|
+
columns.push(existing);
|
|
358
|
+
}
|
|
359
|
+
existing.byteSize += col.byteSize;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
totalBytes: databases.reduce((acc, db) => acc + db.totalBytes, 0),
|
|
364
|
+
rowCount: keys.length,
|
|
365
|
+
keys,
|
|
366
|
+
rawKeyCount: databases.reduce((acc, db) => { var _a, _b; return acc + db.keyTimes.size + ((_b = (_a = db.deleteTimes) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0); }, 0),
|
|
367
|
+
readerCount: databases.length,
|
|
368
|
+
columns,
|
|
369
|
+
keyTimes: keyTime,
|
|
370
|
+
deleteTimes: deleteTime,
|
|
371
|
+
async getColumn(column) {
|
|
372
|
+
const perReader = await Promise.all(databases.map(async (db) => {
|
|
373
|
+
if (!db.columns.some(c => c.column === column))
|
|
374
|
+
return undefined;
|
|
375
|
+
try {
|
|
376
|
+
const entries = await db.getColumn(column);
|
|
377
|
+
return new Map(entries.map(e => [e.key, { value: e.value, time: e.time }]));
|
|
378
|
+
}
|
|
379
|
+
catch (e) {
|
|
380
|
+
warnCorruptRead(db, column, e);
|
|
381
|
+
return undefined;
|
|
382
|
+
}
|
|
383
|
+
}));
|
|
384
|
+
return keys.map(key => {
|
|
385
|
+
var _a;
|
|
386
|
+
let bestTime = -Infinity;
|
|
387
|
+
let bestVal;
|
|
388
|
+
let found = false;
|
|
389
|
+
for (const m of perReader) {
|
|
390
|
+
const cell = m && m.get(key);
|
|
391
|
+
if (!cell || cell.value === BulkDatabaseFormat_1.ABSENT)
|
|
392
|
+
continue;
|
|
393
|
+
if (cell.time > bestTime) {
|
|
394
|
+
bestTime = cell.time;
|
|
395
|
+
bestVal = cell.value;
|
|
396
|
+
found = true;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const live = found && bestTime > delOf(key);
|
|
400
|
+
return { key, value: live ? bestVal : undefined, time: live ? bestTime : ((_a = keyTime.get(key)) !== null && _a !== void 0 ? _a : 0) };
|
|
401
|
+
});
|
|
402
|
+
},
|
|
403
|
+
async getSingleField(key, column) {
|
|
404
|
+
const kt = keyTime.get(key);
|
|
405
|
+
if (kt === undefined || kt <= delOf(key))
|
|
406
|
+
return undefined;
|
|
407
|
+
let bestTime = -Infinity;
|
|
408
|
+
let bestVal;
|
|
409
|
+
let found = false;
|
|
410
|
+
for (const db of databases) {
|
|
411
|
+
if (!db.columns.some(c => c.column === column))
|
|
412
|
+
continue;
|
|
413
|
+
let r;
|
|
414
|
+
try {
|
|
415
|
+
r = await db.getSingleField(key, column);
|
|
416
|
+
}
|
|
417
|
+
catch (e) {
|
|
418
|
+
warnCorruptRead(db, column, e);
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
if (r === BulkDatabaseFormat_1.ABSENT)
|
|
422
|
+
continue;
|
|
423
|
+
if (r.time > bestTime) {
|
|
424
|
+
bestTime = r.time;
|
|
425
|
+
bestVal = r.value;
|
|
426
|
+
found = true;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const live = found && bestTime > delOf(key);
|
|
430
|
+
return { value: live ? bestVal : undefined, time: live ? bestTime : kt };
|
|
431
|
+
},
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTG9hZGVkSW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJMb2FkZWRJbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSw2REFBa0g7QUFDbEgsNkNBQW9EO0FBQ3BELDJDQUFrRztBQUNsRyxrRUFBaUY7QUFDakYsd0VBQXFFO0FBRXJFLG9JQUFvSTtBQUNwSSxNQUFNLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO0FBTTFDLE1BQWEsZ0JBQWlCLFNBQVEsS0FBSztDQUFJO0FBQS9DLDRDQUErQztBQUMvQyxNQUFNLGlCQUFrQixTQUFRLEtBQUs7Q0FBSTtBQW9CekMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQUM7QUFFNUIsU0FBUyxRQUFRLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDbEMsT0FBTyxDQUFDLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUMsQ0FBQztBQUVELHVHQUF1RztBQUN2RyxvR0FBb0c7QUFDcEcsbUdBQW1HO0FBQ25HLDREQUE0RDtBQUM1RCxNQUFhLFdBQVc7SUFDcEIsWUFDb0IsSUFBWSxFQUNaLE9BQW9CLEVBQ3BCLFNBQXlCLEVBQ3pCLFdBQTZCLEVBQzdCLE1BQXNCLEVBQ3RCLFdBQWdDLEVBQ2hDLFdBQWdDLEVBQ2hDLGdCQUF3QixFQUN4QixpQkFBeUIsRUFDekIsU0FBMEI7UUFUMUIsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUNaLFlBQU8sR0FBUCxPQUFPLENBQWE7UUFDcEIsY0FBUyxHQUFULFNBQVMsQ0FBZ0I7UUFDekIsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO1FBQzdCLFdBQU0sR0FBTixNQUFNLENBQWdCO1FBQ3RCLGdCQUFXLEdBQVgsV0FBVyxDQUFxQjtRQUNoQyxnQkFBVyxHQUFYLFdBQVcsQ0FBcUI7UUFDaEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFRO1FBQ3hCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBUTtRQUN6QixjQUFT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SSxDQUFDLENBQUM7Z0JBQ04sSUFBSSxDQUFDO29CQUNELENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUM3QyxDQUFDO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ1QsZUFBZSxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQy9CLFNBQVM7Z0JBQ2IsQ0FBQztnQkFDRCxJQUFJLENBQUMsS0FBSywyQkFBTTtvQkFBRSxTQUFTO2dCQUMzQixJQUFJLENBQUMsQ0FBQyxJQUFJLEdBQUcsUUFBUSxFQUFFLENBQUM7b0JBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUM7b0JBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztnQkFBQyxDQUFDO1lBQ2xGLENBQUM7WUFDRCxNQUFNLElBQUksR0FBRyxLQUFLLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QyxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUM3RSxDQUFDO0tBQ0osQ0FBQztBQUNOLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEZpbGVTdG9yYWdlIH0gZnJvbSBcIi4uL0ZpbGVGb2xkZXJBUElcIjtcbmltcG9ydCB7IEFCU0VOVCwgQmFzZUJ1bGtEYXRhYmFzZVJlYWRlciwgRU1QVFlfQlVGRkVSLCBLRVlfQ09MVU1OLCBsb2FkQnVsa0RhdGFiYXNlIH0gZnJvbSBcIi4vQnVsa0RhdGFiYXNlRm9ybWF0XCI7XG5pbXBvcnQgeyBibG9ja0NhY2hlLCBHZXRSYW5nZSB9IGZyb20gXCIuL2Jsb2NrQ2FjaGVcIjtcbmltcG9ydCB7IFNUUkVBTV9FWFRFTlNJT04sIFN0cmVhbUVudHJ5LCBwYXJzZVN0cmVhbSwgc3RyZWFtUmVhZGVyRnJvbUVudHJpZXMgfSBmcm9tIFwiLi9zdHJlYW1Mb2dcIjtcbmltcG9ydCB7IGZvcm1hdE51bWJlciwgZm9ybWF0VGltZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2Zvcm1hdHRpbmcvZm9ybWF0XCI7XG5pbXBvcnQgeyBibHVlLCByZWQgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9mb3JtYXR0aW5nL2xvZ0NvbG9yc1wiO1xuXG4vLyBEdXBsaWNhdGVkIGZyb20gQnVsa0RhdGFiYXNlQmFzZSB0byBhdm9pZCBhIGNpcmN1bGFyIGltcG9ydCDigJQgdXNlZCBvbmx5IHRvIGJ1aWxkIGEgZnVsbGVyIHN0b3JhZ2UtcmVsYXRpdmUgcGF0aCBmb3IgbG9nIG1lc3NhZ2VzLlxuY29uc3QgQlVMS19ST09UX0ZPTERFUiA9IFwiYnVsa0RhdGFiYXNlczJcIjtcblxuZXhwb3J0IHR5cGUgQnVsa0ZpbGVJbmZvID0geyBmaWxlTmFtZTogc3RyaW5nOyBsZXZlbDogbnVtYmVyOyB0aW1lc3RhbXA6IG51bWJlciB9O1xuZXhwb3J0IHR5cGUgU3RyZWFtRmlsZUluZm8gPSB7IGZpbGVOYW1lOiBzdHJpbmc7IHRpbWVzdGFtcDogbnVtYmVyIH07XG5leHBvcnQgdHlwZSBTdHJlYW1SZWFkZXJDYWNoZUVudHJ5ID0geyByZWFkU2l6ZTogbnVtYmVyOyBwYXJzZWRQb3M6IG51bWJlcjsgZW50cmllczogU3RyZWFtRW50cnlbXSB9O1xuXG5leHBvcnQgY2xhc3MgTWlzc2luZ0ZpbGVFcnJvciBleHRlbmRzIEVycm9yIHsgfVxuY2xhc3MgRmlsZXNDaGFuZ2VkRXJyb3IgZXh0ZW5kcyBFcnJvciB7IH1cblxuZXhwb3J0IHR5cGUgUmVzb2x2ZWRSZWFkZXIgPSB7XG4gICAgcm93Q291bnQ6IG51bWJlcjtcbiAgICB0b3RhbEJ5dGVzOiBudW1iZXI7XG4gICAga2V5czogc3RyaW5nW107XG4gICAgcmF3S2V5Q291bnQ6IG51bWJlcjtcbiAgICByZWFkZXJDb3VudDogbnVtYmVyO1xuICAgIGNvbHVtbnM6IHsgY29sdW1uOiBzdHJpbmc7IGJ5dGVTaXplOiBudW1iZXIgfVtdO1xuICAgIGtleVRpbWVzOiBNYXA8c3RyaW5nLCBudW1iZXI+O1xuICAgIGRlbGV0ZVRpbWVzOiBNYXA8c3RyaW5nLCBudW1iZXI+O1xuICAgIGdldENvbHVtbjogKGNvbHVtbjogc3RyaW5nKSA9PiBQcm9taXNlPHsga2V5OiBzdHJpbmc7IHZhbHVlOiB1bmtub3duOyB0aW1lOiBudW1iZXIgfVtdPjtcbiAgICBnZXRTaW5nbGVGaWVsZDogKGtleTogc3RyaW5nLCBjb2x1bW46IHN0cmluZykgPT4gUHJvbWlzZTx7IHZhbHVlOiB1bmtub3duOyB0aW1lOiBudW1iZXIgfSB8IHVuZGVmaW5lZD47XG59O1xuXG5leHBvcnQgdHlwZSBTdWJSZWFkZXJDYWNoZXMgPSB7XG4gICAgYnVsazogTWFwPHN0cmluZywgQmFzZUJ1bGtEYXRhYmFzZVJlYWRlcj47XG4gICAgc3RyZWFtOiBNYXA8c3RyaW5nLCBTdHJlYW1SZWFkZXJDYWNoZUVudHJ5Pjtcbn07XG5cbmNvbnN0IE1BWF9SRUFEX0FUVEVNUFRTID0gODtcblxuZnVuY3Rpb24gbnVsbEpvaW4oYTogc3RyaW5nLCBiOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBhICsgU3RyaW5nLmZyb21DaGFyQ29kZSgwKSArIGI7XG59XG5cbi8vIEEgbG9hZGVkIHNuYXBzaG90IG9mIG9uZSBjb2xsZWN0aW9uJ3Mgb24tZGlzayBzdGF0ZTogdGhlIHJlc29sdmVkIHJlYWRlciArIHRoZSBwZXItZmlsZSBkZWNvZGVkIHN1Yi1cbi8vIHJlYWRlcnMgaXQgc3RpdGNoZWQsIHRoZSBzdHJlYW0gZmlsZSBzaXplcy90aW1lcyBpdCBvYnNlcnZlZCwgYW5kIHRoZSBzeW5jIChyZWFjdGl2ZSkgY2FjaGVzIHRoYXRcbi8vIHN1cmZhY2UgY29sdW1uL2ZpZWxkIHJlYWRzLiBCdWlsdCBvbmNlIHZpYSBMb2FkZWRJbmRleC5idWlsZCDigJQgZWFnZXJseSwgc28gdGhlIHN3YXAgaW50byBhIGZyZXNoXG4vLyBMb2FkZWRJbmRleCBuZXZlciBibG9ja3MgYSByZWFkIG9uIGEgc3luY2hyb25vdXMgcmVidWlsZC5cbmV4cG9ydCBjbGFzcyBMb2FkZWRJbmRleDxUIGV4dGVuZHMgeyBrZXk6IHN0cmluZyB9PiB7XG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZyxcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IHN0b3JhZ2U6IEZpbGVTdG9yYWdlLFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgYnVsa0ZpbGVzOiBCdWxrRmlsZUluZm9bXSxcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IHN0cmVhbUZpbGVzOiBTdHJlYW1GaWxlSW5mb1tdLFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgcmVhZGVyOiBSZXNvbHZlZFJlYWRlcixcbiAgICAgICAgcHVibGljIHJlYWRvbmx5IHN0cmVhbVRpbWVzOiBNYXA8c3RyaW5nLCBudW1iZXI+LFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgc3RyZWFtU2l6ZXM6IE1hcDxzdHJpbmcsIG51bWJlcj4sXG4gICAgICAgIHB1YmxpYyByZWFkb25seSBzdHJlYW1Sb3dzT25EaXNrOiBudW1iZXIsXG4gICAgICAgIHB1YmxpYyByZWFkb25seSBzdHJlYW1CeXRlc09uRGlzazogbnVtYmVyLFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgc3ViQ2FjaGVzOiBTdWJSZWFkZXJDYWNoZXMsXG4gICAgKSB7XG4gICAgICAgIHRoaXMua2V5cyA9IG5ldyBTZXQocmVhZGVyLmtleXMpO1xuICAgICAgICB0aGlzLmZpbGVTZXQgPSBuZXcgU2V0KFsuLi5idWxrRmlsZXMubWFwKGYgPT4gZi5maWxlTmFtZSksIC4uLnN0cmVhbUZpbGVzLm1hcChmID0+IGYuZmlsZU5hbWUpXSk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlYWRvbmx5IGtleXM6IFNldDxzdHJpbmc+O1xuICAgIHB1YmxpYyByZWFkb25seSBmaWxlU2V0OiBTZXQ8c3RyaW5nPjtcblxuICAgIHByaXZhdGUgYmFzZUNvbHVtbnMgPSBuZXcgTWFwPHN0cmluZywgeyBrZXk6IHN0cmluZzsgdmFsdWU6IHVua25vd247IHRpbWU6IG51bWJlciB9W10+KCk7XG4gICAgcHJpdmF0ZSBiYXNlQ29sdW1uc0xvYWRpbmcgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIGJhc2VGaWVsZHMgPSBuZXcgTWFwPHN0cmluZywgeyB2YWx1ZTogdW5rbm93bjsgdGltZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+KCk7XG4gICAgcHJpdmF0ZSBiYXNlRmllbGRzTG9hZGluZyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIC8vIExhc3Qta25vd24gdmFsdWVzIGZyb20gdGhlIHByZXZpb3VzIGluZGV4LCBzZXJ2ZWQgdW50aWwgdGhpcyBpbmRleCBsb2FkcyBpdHMgb3duIGZyZXNoIHZhbHVlLCBzb1xuICAgIC8vIGEgc3dhcCBkb2Vzbid0IGZsYXNoIGVtcHR5IGluIHN5bmMgcmVhZHMuIENsZWFyZWQgcGVyLWVudHJ5IHdoZW4gdGhlIGZyZXNoIHZhbHVlIGxhbmRzLlxuICAgIHByaXZhdGUgc3RhbGVCYXNlQ29sdW1ucyA9IG5ldyBNYXA8c3RyaW5nLCB7IGtleTogc3RyaW5nOyB2YWx1ZTogdW5rbm93bjsgdGltZTogbnVtYmVyIH1bXT4oKTtcbiAgICBwcml2YXRlIHN0YWxlQmFzZUZpZWxkcyA9IG5ldyBNYXA8c3RyaW5nLCB7IHZhbHVlOiB1bmtub3duOyB0aW1lOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4oKTtcblxuICAgIGdldCB0b3RhbEJ5dGVzKCk6IG51bWJlciB7IHJldHVybiB0aGlzLnJlYWRlci50b3RhbEJ5dGVzOyB9XG4gICAgZ2V0IHJvd0NvdW50KCk6IG51bWJlciB7IHJldHVybiB0aGlzLnJlYWRlci5yb3dDb3VudDsgfVxuXG4gICAgaXNMaXZlKGtleTogc3RyaW5nKTogYm9vbGVhbiB7IHJldHVybiB0aGlzLmtleXMuaGFzKGtleSk7IH1cblxuICAgIHN0YXRpYyBhc3luYyBidWlsZDxUIGV4dGVuZHMgeyBrZXk6IHN0cmluZyB9Pihjb25maWc6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgICBzdG9yYWdlOiBGaWxlU3RvcmFnZTtcbiAgICAgICAgYnVsa0ZpbGVzOiBCdWxrRmlsZUluZm9bXTtcbiAgICAgICAgc3RyZWFtRmlsZXM6IFN0cmVhbUZpbGVJbmZvW107XG4gICAgICAgIHN1YkNhY2hlczogU3ViUmVhZGVyQ2FjaGVzO1xuICAgICAgICBvblVucmVhZGFibGVGaWxlPzogKGZpbGU6IEJ1bGtGaWxlSW5mbywgbWVzc2FnZTogc3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgIH0pOiBQcm9taXNlPExvYWRlZEluZGV4PFQ+PiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgbGV0IHsgYnVsa0ZpbGVzLCBzdHJlYW1GaWxlcyB9ID0gY29uZmlnO1xuICAgICAgICBsZXQgYXR0ZW1wdCA9IDA7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBjb25zdCB0b2xlcmF0ZU1pc3NpbmcgPSBhdHRlbXB0ID49IE1BWF9SRUFEX0FUVEVNUFRTO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgZmlsZXNDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgY29uc3QgW2J1bGtSZWFkZXJzUmF3LCBzdHJlYW1EYXRhXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICAgICAgUHJvbWlzZS5hbGwoYnVsa0ZpbGVzLm1hcChhc3luYyBmID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGxvYWRGaWxlUmVhZGVyKGNvbmZpZy5uYW1lLCBjb25maWcuc3RvcmFnZSwgZiwgY29uZmlnLnN1YkNhY2hlcy5idWxrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIE1pc3NpbmdGaWxlRXJyb3IpIHsgZmlsZXNDaGFuZ2VkID0gdHJ1ZTsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb25maWcub25VbnJlYWRhYmxlRmlsZSkgYXdhaXQgY29uZmlnLm9uVW5yZWFkYWJsZUZpbGUoZiwgKGUgYXMgRXJyb3IpLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAgICAgICAgbG9hZFN0cmVhbUVudHJpZXMoY29uZmlnLm5hbWUsIGNvbmZpZy5zdG9yYWdlLCBzdHJlYW1GaWxlcywgY29uZmlnLnN1YkNhY2hlcy5zdHJlYW0pLFxuICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIGlmIChzdHJlYW1EYXRhLm1pc3NpbmcpIGZpbGVzQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgaWYgKGZpbGVzQ2hhbmdlZCAmJiAhdG9sZXJhdGVNaXNzaW5nKSB0aHJvdyBuZXcgRmlsZXNDaGFuZ2VkRXJyb3IoKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGJ1bGtSZWFkZXJzID0gYnVsa1JlYWRlcnNSYXcuZmlsdGVyKChyKTogciBpcyBCYXNlQnVsa0RhdGFiYXNlUmVhZGVyID0+ICEhcik7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVhZGVyczogQmFzZUJ1bGtEYXRhYmFzZVJlYWRlcltdID0gW107XG4gICAgICAgICAgICAgICAgbGV0IHN0cmVhbVRpbWVzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvcmRlcmVkID0gb3JkZXJTdHJlYW1FbnRyaWVzKHN0cmVhbURhdGEuZW50cmllcyk7XG4gICAgICAgICAgICAgICAgaWYgKG9yZGVyZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IHN0cmVhbVJlYWRlckZyb21FbnRyaWVzKG9yZGVyZWQsIHN0cmVhbURhdGEudG90YWxCeXRlcyk7XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlcnMucHVzaChzdHJlYW0ucmVhZGVyKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtVGltZXMgPSBzdHJlYW0udGltZXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlYWRlcnMucHVzaCguLi5idWxrUmVhZGVycyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVhZGVyID0gam9pbkJ1bGtEYXRhYmFzZXMocmVhZGVycyk7XG5cbiAgICAgICAgICAgICAgICBwcnVuZVN1YkNhY2hlcyhidWxrRmlsZXMsIHN0cmVhbUZpbGVzLCBjb25maWcuc3ViQ2FjaGVzKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGVsYXBzZWQgPSBEYXRlLm5vdygpIC0gc3RhcnQ7XG4gICAgICAgICAgICAgICAgaWYgKGVsYXBzZWQgPiA1MCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgYnl0ZXNSZWFkID0gc3RyZWFtRGF0YS50b3RhbEJ5dGVzO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHIgb2YgYnVsa1JlYWRlcnMpIGJ5dGVzUmVhZCArPSByLmNvbHVtbnMuZmluZChjID0+IGMuY29sdW1uID09PSBLRVlfQ09MVU1OKT8uYnl0ZVNpemUgPz8gMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYCR7Ymx1ZShjb25maWcubmFtZSl9IGxvYWRlZCBpbiAke3JlZChmb3JtYXRUaW1lKGVsYXBzZWQpKX0gKCR7Ymx1ZShmb3JtYXROdW1iZXIocmVhZGVyLnJvd0NvdW50KSl9IHJvd3MsICR7YnVsa0ZpbGVzLmxlbmd0aH0gYnVsayArICR7c3RyZWFtRmlsZXMubGVuZ3RofSBzdHJlYW0gZmlsZXMsIHJlYWQgJHtibHVlKGZvcm1hdE51bWJlcihieXRlc1JlYWQpKX1CKWApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTG9hZGVkSW5kZXg8VD4oXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICBjb25maWcuc3RvcmFnZSxcbiAgICAgICAgICAgICAgICAgICAgYnVsa0ZpbGVzLFxuICAgICAgICAgICAgICAgICAgICBzdHJlYW1GaWxlcyxcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLFxuICAgICAgICAgICAgICAgICAgICBzdHJlYW1UaW1lcyxcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRGF0YS5zaXplcyxcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRGF0YS5lbnRyaWVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRGF0YS50b3RhbEJ5dGVzLFxuICAgICAgICAgICAgICAgICAgICBjb25maWcuc3ViQ2FjaGVzLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBGaWxlc0NoYW5nZWRFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBhdHRlbXB0Kys7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRvcHRzIHRoZSBwcmV2aW91cyBpbmRleCdzIGxvYWRlZCBiYXNlIHZhbHVlcyBhcyBTVEFMRSBvbiB0aGlzIG9uZSwgc28gYSBzeW5jIHJlYWQgbWlkLXN3YXAgY2FuXG4gICAgLy8gc2VydmUgdGhlIG9sZCB2YWx1ZSAocGF0Y2hlZCB3aXRoIHRoZSBjdXJyZW50IG92ZXJsYXkpIGluc3RlYWQgb2YgZmxhc2hpbmcgZW1wdHkgd2hpbGUgdGhlIGZyZXNoXG4gICAgLy8gbG9hZCBydW5zLiBQZXItZW50cnk6IGRyb3BwZWQgd2hlbiB0aGUgZnJlc2ggdmFsdWUgbGFuZHMgaGVyZS5cbiAgICBpbmhlcml0U3RhbGVGcm9tKHByZXY6IExvYWRlZEluZGV4PFQ+KTogdm9pZCB7XG4gICAgICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIHByZXYuYmFzZUNvbHVtbnMpIHRoaXMuc3RhbGVCYXNlQ29sdW1ucy5zZXQoaywgdik7XG4gICAgICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIHByZXYuc3RhbGVCYXNlQ29sdW1ucykgaWYgKCF0aGlzLnN0YWxlQmFzZUNvbHVtbnMuaGFzKGspKSB0aGlzLnN0YWxlQmFzZUNvbHVtbnMuc2V0KGssIHYpO1xuICAgICAgICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBwcmV2LmJhc2VGaWVsZHMpIHRoaXMuc3RhbGVCYXNlRmllbGRzLnNldChrLCB2KTtcbiAgICAgICAgZm9yIChjb25zdCBbaywgdl0gb2YgcHJldi5zdGFsZUJhc2VGaWVsZHMpIGlmICghdGhpcy5zdGFsZUJhc2VGaWVsZHMuaGFzKGspKSB0aGlzLnN0YWxlQmFzZUZpZWxkcy5zZXQoaywgdik7XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0Q29sdW1uKGNvbHVtbjogc3RyaW5nKTogUHJvbWlzZTx7IGtleTogc3RyaW5nOyB2YWx1ZTogdW5rbm93bjsgdGltZTogbnVtYmVyIH1bXT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkZXIuZ2V0Q29sdW1uKGNvbHVtbik7XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0U2luZ2xlRmllbGQoa2V5OiBzdHJpbmcsIGNvbHVtbjogc3RyaW5nKTogUHJvbWlzZTx7IHZhbHVlOiB1bmtub3duOyB0aW1lOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkZXIuZ2V0U2luZ2xlRmllbGQoa2V5LCBjb2x1bW4pO1xuICAgIH1cblxuICAgIGVuc3VyZUJhc2VDb2x1bW4oY29sdW1uOiBzdHJpbmcsIG9uTG9hZGVkOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmJhc2VDb2x1bW5zLmhhcyhjb2x1bW4pIHx8IHRoaXMuYmFzZUNvbHVtbnNMb2FkaW5nLmhhcyhjb2x1bW4pKSByZXR1cm47XG4gICAgICAgIHRoaXMuYmFzZUNvbHVtbnNMb2FkaW5nLmFkZChjb2x1bW4pO1xuICAgICAgICB2b2lkIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgdGhpcy5yZWFkZXIuZ2V0Q29sdW1uKGNvbHVtbik7XG4gICAgICAgICAgICAgICAgdGhpcy5iYXNlQ29sdW1ucy5zZXQoY29sdW1uLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGFsZUJhc2VDb2x1bW5zLmRlbGV0ZShjb2x1bW4pO1xuICAgICAgICAgICAgICAgIHRoaXMuYmFzZUNvbHVtbnNMb2FkaW5nLmRlbGV0ZShjb2x1bW4pO1xuICAgICAgICAgICAgICAgIG9uTG9hZGVkKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5iYXNlQ29sdW1uc0xvYWRpbmcuZGVsZXRlKGNvbHVtbik7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGAke3RoaXMubmFtZX0uZ2V0Q29sdW1uU3luYygke0pTT04uc3RyaW5naWZ5KGNvbHVtbil9KSBsb2FkIGZhaWxlZCwgd2lsbCByZXRyeTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICB9XG5cbiAgICBlbnN1cmVCYXNlRmllbGQoa2V5OiBzdHJpbmcsIGNvbHVtbjogc3RyaW5nLCBvbkxvYWRlZDogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgICAgICBjb25zdCBjayA9IG51bGxKb2luKGNvbHVtbiwga2V5KTtcbiAgICAgICAgaWYgKHRoaXMuYmFzZUZpZWxkcy5oYXMoY2spIHx8IHRoaXMuYmFzZUZpZWxkc0xvYWRpbmcuaGFzKGNrKSkgcmV0dXJuO1xuICAgICAgICB0aGlzLmJhc2VGaWVsZHNMb2FkaW5nLmFkZChjayk7XG4gICAgICAgIHZvaWQgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCB0aGlzLnJlYWRlci5nZXRTaW5nbGVGaWVsZChrZXksIGNvbHVtbik7XG4gICAgICAgICAgICAgICAgdGhpcy5iYXNlRmllbGRzLnNldChjaywgdmFsdWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhbGVCYXNlRmllbGRzLmRlbGV0ZShjayk7XG4gICAgICAgICAgICAgICAgdGhpcy5iYXNlRmllbGRzTG9hZGluZy5kZWxldGUoY2spO1xuICAgICAgICAgICAgICAgIG9uTG9hZGVkKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5iYXNlRmllbGRzTG9hZGluZy5kZWxldGUoY2spO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgJHt0aGlzLm5hbWV9LmdldFNpbmdsZUZpZWxkU3luYygke0pTT04uc3RyaW5naWZ5KGtleSl9LCAke0pTT04uc3RyaW5naWZ5KGNvbHVtbil9KSBsb2FkIGZhaWxlZCwgd2lsbCByZXRyeTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm5zIHRoZSBsb2FkZWQgdmFsdWUgKGZyZXNoIGlmIGF2YWlsYWJsZSwgZWxzZSBsYXN0LWtub3duIHN0YWxlKSBmb3IgdGhlIGNvbHVtbiwgb3IgdW5kZWZpbmVkXG4gICAgLy8gaWYgbmVpdGhlciBpcyBwcmVzZW50IHlldC4gVGhlIGJvb2xlYW4gaW5kaWNhdGVzIHdoZXRoZXIgdGhlIHJldHVybmVkIHZhbHVlIGlzIGZyZXNoOyBjYWxsZXJzIG1heVxuICAgIC8vIHNraXAgY2FjaGluZyBhIHN0YWxlIHZhbHVlLlxuICAgIGdldEJhc2VDb2x1bW4oY29sdW1uOiBzdHJpbmcpOiB7IGVudHJpZXM6IHsga2V5OiBzdHJpbmc7IHZhbHVlOiB1bmtub3duOyB0aW1lOiBudW1iZXIgfVtdOyBmcmVzaDogYm9vbGVhbiB9IHwgdW5kZWZpbmVkIHtcbiAgICAgICAgY29uc3QgZnJlc2ggPSB0aGlzLmJhc2VDb2x1bW5zLmdldChjb2x1bW4pO1xuICAgICAgICBpZiAoZnJlc2gpIHJldHVybiB7IGVudHJpZXM6IGZyZXNoLCBmcmVzaDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBzdGFsZSA9IHRoaXMuc3RhbGVCYXNlQ29sdW1ucy5nZXQoY29sdW1uKTtcbiAgICAgICAgaWYgKHN0YWxlKSByZXR1cm4geyBlbnRyaWVzOiBzdGFsZSwgZnJlc2g6IGZhbHNlIH07XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZ2V0QmFzZUZpZWxkKGtleTogc3RyaW5nLCBjb2x1bW46IHN0cmluZyk6IHsgdmFsdWU6IHsgdmFsdWU6IHVua25vd247IHRpbWU6IG51bWJlciB9IHwgdW5kZWZpbmVkOyBmcmVzaDogYm9vbGVhbjsgbG9hZGVkOiBib29sZWFuIH0ge1xuICAgICAgICBjb25zdCBjayA9IG51bGxKb2luKGNvbHVtbiwga2V5KTtcbiAgICAgICAgaWYgKHRoaXMuYmFzZUZpZWxkcy5oYXMoY2spKSByZXR1cm4geyB2YWx1ZTogdGhpcy5iYXNlRmllbGRzLmdldChjayksIGZyZXNoOiB0cnVlLCBsb2FkZWQ6IHRydWUgfTtcbiAgICAgICAgaWYgKHRoaXMuc3RhbGVCYXNlRmllbGRzLmhhcyhjaykpIHJldHVybiB7IHZhbHVlOiB0aGlzLnN0YWxlQmFzZUZpZWxkcy5nZXQoY2spLCBmcmVzaDogZmFsc2UsIGxvYWRlZDogdHJ1ZSB9O1xuICAgICAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBmcmVzaDogZmFsc2UsIGxvYWRlZDogZmFsc2UgfTtcbiAgICB9XG5cbiAgICBpc0Jhc2VDb2x1bW5Mb2FkZWQoY29sdW1uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmFzZUNvbHVtbnMuaGFzKGNvbHVtbikgfHwgdGhpcy5zdGFsZUJhc2VDb2x1bW5zLmhhcyhjb2x1bW4pO1xuICAgIH1cblxuICAgIGlzQmFzZUZpZWxkTG9hZGVkKGtleTogc3RyaW5nLCBjb2x1bW46IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBjayA9IG51bGxKb2luKGNvbHVtbiwga2V5KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmFzZUZpZWxkcy5oYXMoY2spIHx8IHRoaXMuc3RhbGVCYXNlRmllbGRzLmhhcyhjayk7XG4gICAgfVxuXG4gICAgLy8gRHJvcHMgaW4tbWVtb3J5IGxvYWRlZCB2YWx1ZXMgZm9yIHRoaXMgaW5kZXgsIHNvIGEgc3Vic2VxdWVudCByZWFkIHJlbG9hZHMgZnJlc2ggZnJvbSBkaXNrLiBVc2VkXG4gICAgLy8gYnkgcmVsb2FkRnJvbURpc2soKSDigJQgYSBoYXJkIHJlc2V0LCBubyBzdGFsZSBmYWxsYmFjayBzdXJ2aXZlcy5cbiAgICBkcm9wTG9hZGVkVmFsdWVzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmJhc2VDb2x1bW5zLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuYmFzZUNvbHVtbnNMb2FkaW5nLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuYmFzZUZpZWxkcy5jbGVhcigpO1xuICAgICAgICB0aGlzLmJhc2VGaWVsZHNMb2FkaW5nLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuc3RhbGVCYXNlQ29sdW1ucy5jbGVhcigpO1xuICAgICAgICB0aGlzLnN0YWxlQmFzZUZpZWxkcy5jbGVhcigpO1xuICAgIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1ha2VSYXdHZXRSYW5nZShzdG9yYWdlOiBGaWxlU3RvcmFnZSwgZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8eyByYXdHZXRSYW5nZTogR2V0UmFuZ2U7IHNpemU6IG51bWJlciB9PiB7XG4gICAgY29uc3QgaW5mbyA9IGF3YWl0IHN0b3JhZ2UuZ2V0SW5mbyhmaWxlTmFtZSk7XG4gICAgaWYgKCFpbmZvKSB0aHJvdyBuZXcgTWlzc2luZ0ZpbGVFcnJvcihgYnVsayBmaWxlICR7ZmlsZU5hbWV9IGlzIG1pc3NpbmdgKTtcbiAgICBjb25zdCByYXdHZXRSYW5nZTogR2V0UmFuZ2UgPSBhc3luYyAoc3RhcnQsIGVuZCkgPT4ge1xuICAgICAgICBpZiAoZW5kIDw9IHN0YXJ0KSByZXR1cm4gRU1QVFlfQlVGRkVSO1xuICAgICAgICBjb25zdCBidWYgPSBhd2FpdCBzdG9yYWdlLmdldFJhbmdlKGZpbGVOYW1lLCB7IHN0YXJ0LCBlbmQgfSk7XG4gICAgICAgIGlmICghYnVmKSB0aHJvdyBuZXcgTWlzc2luZ0ZpbGVFcnJvcihgcmFuZ2UgWyR7c3RhcnR9LCAke2VuZH0pIG9mICR7ZmlsZU5hbWV9IGlzIG1pc3NpbmdgKTtcbiAgICAgICAgcmV0dXJuIGJ1ZjtcbiAgICB9O1xuICAgIHJldHVybiB7IHJhd0dldFJhbmdlLCBzaXplOiBpbmZvLnNpemUgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRGaWxlUmVhZGVyKG5hbWU6IHN0cmluZywgc3RvcmFnZTogRmlsZVN0b3JhZ2UsIGY6IEJ1bGtGaWxlSW5mbywgY2FjaGU6IE1hcDxzdHJpbmcsIEJhc2VCdWxrRGF0YWJhc2VSZWFkZXI+KTogUHJvbWlzZTxCYXNlQnVsa0RhdGFiYXNlUmVhZGVyPiB7XG4gICAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGYuZmlsZU5hbWUpO1xuICAgIGlmIChjYWNoZWQpIHJldHVybiBjYWNoZWQ7XG4gICAgY29uc3QgcmF3ID0gYXdhaXQgbWFrZVJhd0dldFJhbmdlKHN0b3JhZ2UsIGYuZmlsZU5hbWUpO1xuICAgIGNvbnN0IGZpbGVJZCA9IG51bGxKb2luKG5hbWUsIGYuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG9wZW5lZCA9IGF3YWl0IGJsb2NrQ2FjaGUub3BlbihmaWxlSWQsIHJhdy5zaXplLCByYXcucmF3R2V0UmFuZ2UpO1xuICAgIGNvbnN0IHJlYWRlciA9IGF3YWl0IGxvYWRCdWxrRGF0YWJhc2UoeyB0b3RhbEJ5dGVzOiBvcGVuZWQudW5jb21wcmVzc2VkU2l6ZSwgZ2V0UmFuZ2U6IG9wZW5lZC5nZXRSYW5nZSwgbmFtZTogYCR7QlVMS19ST09UX0ZPTERFUn0vJHtuYW1lfS8ke2YuZmlsZU5hbWV9YCB9KTtcbiAgICBjYWNoZS5zZXQoZi5maWxlTmFtZSwgcmVhZGVyKTtcbiAgICByZXR1cm4gcmVhZGVyO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZFN0cmVhbUVudHJpZXMoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHN0b3JhZ2U6IEZpbGVTdG9yYWdlLFxuICAgIHN0cmVhbUZpbGVzOiBTdHJlYW1GaWxlSW5mb1tdLFxuICAgIGNhY2hlOiBNYXA8c3RyaW5nLCBTdHJlYW1SZWFkZXJDYWNoZUVudHJ5Pixcbik6IFByb21pc2U8eyBlbnRyaWVzOiB7IHRpbWU6IG51bWJlcjsgZmlsZU5hbWU6IHN0cmluZzsgZW50cnk6IFN0cmVhbUVudHJ5IH1bXTsgdG90YWxCeXRlczogbnVtYmVyOyBtaXNzaW5nOiBib29sZWFuOyBzaXplczogTWFwPHN0cmluZywgbnVtYmVyPiB9PiB7XG4gICAgY29uc3Qgc2l6ZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGlmICghc3RyZWFtRmlsZXMubGVuZ3RoKSByZXR1cm4geyBlbnRyaWVzOiBbXSwgdG90YWxCeXRlczogMCwgbWlzc2luZzogZmFsc2UsIHNpemVzIH07XG4gICAgbGV0IG1pc3NpbmcgPSBmYWxzZTtcbiAgICBjb25zdCBwZXJGaWxlID0gYXdhaXQgUHJvbWlzZS5hbGwoc3RyZWFtRmlsZXMubWFwKGFzeW5jIChmKTogUHJvbWlzZTx7IGZpbGVOYW1lOiBzdHJpbmc7IHNpemU6IG51bWJlcjsgZW50cmllczogU3RyZWFtRW50cnlbXSB9IHwgdW5kZWZpbmVkPiA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBpbmZvID0gYXdhaXQgc3RvcmFnZS5nZXRJbmZvKGYuZmlsZU5hbWUpO1xuICAgICAgICAgICAgaWYgKCFpbmZvKSB7IG1pc3NpbmcgPSB0cnVlOyByZXR1cm4gdW5kZWZpbmVkOyB9XG4gICAgICAgICAgICBjb25zdCBzaXplID0gaW5mby5zaXplO1xuICAgICAgICAgICAgc2l6ZXMuc2V0KGYuZmlsZU5hbWUsIHNpemUpO1xuICAgICAgICAgICAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGYuZmlsZU5hbWUpO1xuICAgICAgICAgICAgaWYgKGNhY2hlZCAmJiBjYWNoZWQucmVhZFNpemUgPT09IHNpemUpIHJldHVybiB7IGZpbGVOYW1lOiBmLmZpbGVOYW1lLCBzaXplLCBlbnRyaWVzOiBjYWNoZWQuZW50cmllcyB9O1xuICAgICAgICAgICAgaWYgKHNpemUgPT09IDApIHsgY2FjaGUuc2V0KGYuZmlsZU5hbWUsIHsgcmVhZFNpemU6IDAsIHBhcnNlZFBvczogMCwgZW50cmllczogW10gfSk7IHJldHVybiB7IGZpbGVOYW1lOiBmLmZpbGVOYW1lLCBzaXplOiAwLCBlbnRyaWVzOiBbXSB9OyB9XG4gICAgICAgICAgICAvLyBBcHBlbmQtb25seTogYSBsYXJnZXIgc2l6ZSBtZWFucyBuZXcgYnl0ZXMgYXQgdGhlIHRhaWwsIHBhcnNlIG9ubHkgdGhvc2UuXG4gICAgICAgICAgICBpZiAoY2FjaGVkICYmIHNpemUgPiBjYWNoZWQucmVhZFNpemUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdWZmaXggPSBhd2FpdCBzdG9yYWdlLmdldFJhbmdlKGYuZmlsZU5hbWUsIHsgc3RhcnQ6IGNhY2hlZC5wYXJzZWRQb3MsIGVuZDogc2l6ZSB9KTtcbiAgICAgICAgICAgICAgICBpZiAoIXN1ZmZpeCkgeyBtaXNzaW5nID0gdHJ1ZTsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlU3RyZWFtKHN1ZmZpeCk7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlZC5iYWRCeXRlcyA+IDApIGNvbnNvbGUud2FybihgJHtuYW1lfSBzdHJlYW0gZmlsZSAke2YuZmlsZU5hbWV9IGhhZCAke3BhcnNlZC5iYWRCeXRlc30gdHJhaWxpbmcgYmFkL2luY29tcGxldGUgYnl0ZXMgKHN0b3BwZWQgcmVhZGluZyB0aGVyZSlgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRyaWVzID0gcGFyc2VkLmVudHJpZXMubGVuZ3RoID8gY2FjaGVkLmVudHJpZXMuY29uY2F0KHBhcnNlZC5lbnRyaWVzKSA6IGNhY2hlZC5lbnRyaWVzO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZFBvcyA9IGNhY2hlZC5wYXJzZWRQb3MgKyAoc3VmZml4Lmxlbmd0aCAtIHBhcnNlZC5iYWRCeXRlcyk7XG4gICAgICAgICAgICAgICAgY2FjaGUuc2V0KGYuZmlsZU5hbWUsIHsgcmVhZFNpemU6IHNpemUsIHBhcnNlZFBvcywgZW50cmllcyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBmaWxlTmFtZTogZi5maWxlTmFtZSwgc2l6ZSwgZW50cmllcyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgc3RvcmFnZS5nZXRSYW5nZShmLmZpbGVOYW1lLCB7IHN0YXJ0OiAwLCBlbmQ6IHNpemUgfSk7XG4gICAgICAgICAgICBpZiAoIWJ1ZmZlcikgeyBtaXNzaW5nID0gdHJ1ZTsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuICAgICAgICAgICAgY29uc3QgcGFyc2VkID0gcGFyc2VTdHJlYW0oYnVmZmVyKTtcbiAgICAgICAgICAgIGlmIChwYXJzZWQuYmFkQnl0ZXMgPiAwKSBjb25zb2xlLndhcm4oYCR7bmFtZX0gc3RyZWFtIGZpbGUgJHtmLmZpbGVOYW1lfSBoYWQgJHtwYXJzZWQuYmFkQnl0ZXN9IHRyYWlsaW5nIGJhZC9pbmNvbXBsZXRlIGJ5dGVzIChzdG9wcGVkIHJlYWRpbmcgdGhlcmUpYCk7XG4gICAgICAgICAgICBjYWNoZS5zZXQoZi5maWxlTmFtZSwgeyByZWFkU2l6ZTogc2l6ZSwgcGFyc2VkUG9zOiBzaXplIC0gcGFyc2VkLmJhZEJ5dGVzLCBlbnRyaWVzOiBwYXJzZWQuZW50cmllcyB9KTtcbiAgICAgICAgICAgIHJldHVybiB7IGZpbGVOYW1lOiBmLmZpbGVOYW1lLCBzaXplLCBlbnRyaWVzOiBwYXJzZWQuZW50cmllcyB9O1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIG1pc3NpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH0pKTtcbiAgICBjb25zdCBlbnRyaWVzOiB7IHRpbWU6IG51bWJlcjsgZmlsZU5hbWU6IHN0cmluZzsgZW50cnk6IFN0cmVhbUVudHJ5IH1bXSA9IFtdO1xuICAgIGxldCB0b3RhbEJ5dGVzID0gMDtcbiAgICBmb3IgKGNvbnN0IHBmIG9mIHBlckZpbGUpIHtcbiAgICAgICAgaWYgKCFwZikgY29udGludWU7XG4gICAgICAgIHRvdGFsQnl0ZXMgKz0gcGYuc2l6ZTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBwZi5lbnRyaWVzKSBlbnRyaWVzLnB1c2goeyB0aW1lOiBlbnRyeS50aW1lLCBmaWxlTmFtZTogcGYuZmlsZU5hbWUsIGVudHJ5IH0pO1xuICAgIH1cbiAgICByZXR1cm4geyBlbnRyaWVzLCB0b3RhbEJ5dGVzLCBtaXNzaW5nLCBzaXplcyB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb3JkZXJTdHJlYW1FbnRyaWVzKGVudHJpZXM6IHsgdGltZTogbnVtYmVyOyBmaWxlTmFtZTogc3RyaW5nOyBlbnRyeTogU3RyZWFtRW50cnkgfVtdKTogU3RyZWFtRW50cnlbXSB7XG4gICAgZW50cmllcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgIGlmIChhLnRpbWUgIT09IGIudGltZSkgcmV0dXJuIGEudGltZSAtIGIudGltZTtcbiAgICAgICAgcmV0dXJuIGEuZmlsZU5hbWUgPCBiLmZpbGVOYW1lICYmIC0xIHx8IGEuZmlsZU5hbWUgPiBiLmZpbGVOYW1lICYmIDEgfHwgMDtcbiAgICB9KTtcbiAgICByZXR1cm4gZW50cmllcy5tYXAoZSA9PiBlLmVudHJ5KTtcbn1cblxuZnVuY3Rpb24gcHJ1bmVTdWJDYWNoZXMoYnVsa0ZpbGVzOiBCdWxrRmlsZUluZm9bXSwgc3RyZWFtRmlsZXM6IFN0cmVhbUZpbGVJbmZvW10sIHN1YkNhY2hlczogU3ViUmVhZGVyQ2FjaGVzKSB7XG4gICAgY29uc3QgbGl2ZUJ1bGsgPSBuZXcgU2V0KGJ1bGtGaWxlcy5tYXAoZiA9PiBmLmZpbGVOYW1lKSk7XG4gICAgY29uc3QgbGl2ZVN0cmVhbSA9IG5ldyBTZXQoc3RyZWFtRmlsZXMubWFwKGYgPT4gZi5maWxlTmFtZSkpO1xuICAgIGZvciAoY29uc3QgbiBvZiBzdWJDYWNoZXMuYnVsay5rZXlzKCkpIGlmICghbGl2ZUJ1bGsuaGFzKG4pKSBzdWJDYWNoZXMuYnVsay5kZWxldGUobik7XG4gICAgZm9yIChjb25zdCBuIG9mIHN1YkNhY2hlcy5zdHJlYW0ua2V5cygpKSBpZiAoIWxpdmVTdHJlYW0uaGFzKG4pKSBzdWJDYWNoZXMuc3RyZWFtLmRlbGV0ZShuKTtcbn1cblxuLy8gQSBjb3JydXB0L3VucmVhZGFibGUgY29sdW1uIGluIE9ORSB1bmRlcmx5aW5nIGZpbGUgbXVzdCBub3QgYnJlYWsgdGhlIHdob2xlIGpvaW5lZCByZWFkLiBXaGVuIGFcbi8vIHNvdXJjZSdzIGNvbHVtbiByZWFkIHRocm93cywgd2UgZHJvcCB0aGF0IHNvdXJjZSBmb3IgdGhhdCBjb2x1bW4gKGZhbGxpbmcgdGhyb3VnaCB0byBvbGRlciByZWFkZXJzLFxuLy8gZXhhY3RseSBhcyBpZiB0aGUgZmlsZSBuZXZlciBzZXQgdGhlIGNvbHVtbikgYW5kIHdhcm4gb25jZSBwZXIgKGZpbGUsIGNvbHVtbikgc28gdGhlIGNvcnJ1cHRpb24gaXNcbi8vIHZpc2libGUgd2l0aG91dCBmbG9vZGluZyB0aGUgbG9nIG9uIGV2ZXJ5IHJlYnVpbGQuXG5jb25zdCB3YXJuZWRDb3JydXB0UmVhZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbmZ1bmN0aW9uIHdhcm5Db3JydXB0UmVhZChkYjogQmFzZUJ1bGtEYXRhYmFzZVJlYWRlciwgY29sdW1uOiBzdHJpbmcsIGU6IHVua25vd24pOiB2b2lkIHtcbiAgICBjb25zdCBwYXRoID0gZGIubmFtZSB8fCBcIih1bmtub3duIHNvdXJjZSlcIjtcbiAgICBjb25zdCBkZWR1cGVLZXkgPSBudWxsSm9pbihwYXRoLCBjb2x1bW4pO1xuICAgIGlmICh3YXJuZWRDb3JydXB0UmVhZHMuaGFzKGRlZHVwZUtleSkpIHJldHVybjtcbiAgICB3YXJuZWRDb3JydXB0UmVhZHMuYWRkKGRlZHVwZUtleSk7XG4gICAgY29uc29sZS53YXJuKGAke3JlZChcImNvcnJ1cHQgcmVhZFwiKX06IGZpbGUgJHtwYXRofSBjb2x1bW4gJHtKU09OLnN0cmluZ2lmeShjb2x1bW4pfSBjb3VsZCBub3QgYmUgcmVhZCAtIHNraXBwaW5nIGl0IChpdHMgZGF0YSBpcyBkcm9wcGVkIGZyb20gcmVzdWx0cyk6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG59XG5cbmZ1bmN0aW9uIGpvaW5CdWxrRGF0YWJhc2VzKGRhdGFiYXNlczogQmFzZUJ1bGtEYXRhYmFzZVJlYWRlcltdKTogUmVzb2x2ZWRSZWFkZXIge1xuICAgIGNvbnN0IGRlbGV0ZVRpbWUgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGZvciAoY29uc3QgZGIgb2YgZGF0YWJhc2VzKSB7XG4gICAgICAgIGlmICghZGIuZGVsZXRlVGltZXMpIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHRdIG9mIGRiLmRlbGV0ZVRpbWVzKSBkZWxldGVUaW1lLnNldChrZXksIE1hdGgubWF4KGRlbGV0ZVRpbWUuZ2V0KGtleSkgPz8gLUluZmluaXR5LCB0KSk7XG4gICAgfVxuICAgIGNvbnN0IGtleVRpbWUgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGZvciAoY29uc3QgZGIgb2YgZGF0YWJhc2VzKSB7XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdF0gb2YgZGIua2V5VGltZXMpIGtleVRpbWUuc2V0KGtleSwgTWF0aC5tYXgoa2V5VGltZS5nZXQoa2V5KSA/PyAtSW5maW5pdHksIHQpKTtcbiAgICB9XG4gICAgY29uc3QgZGVsT2YgPSAoa2V5OiBzdHJpbmcpID0+IGRlbGV0ZVRpbWUuZ2V0KGtleSkgPz8gLUluZmluaXR5O1xuICAgIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCBba2V5LCB0XSBvZiBrZXlUaW1lKSBpZiAodCA+IGRlbE9mKGtleSkpIGtleXMucHVzaChrZXkpO1xuXG4gICAgY29uc3QgY29sdW1uczogeyBjb2x1bW46IHN0cmluZzsgYnl0ZVNpemU6IG51bWJlciB9W10gPSBbXTtcbiAgICBjb25zdCBjb2x1bW5CeU5hbWUgPSBuZXcgTWFwPHN0cmluZywgeyBjb2x1bW46IHN0cmluZzsgYnl0ZVNpemU6IG51bWJlciB9PigpO1xuICAgIGZvciAoY29uc3QgZGIgb2YgZGF0YWJhc2VzKSB7XG4gICAgICAgIGZvciAoY29uc3QgY29sIG9mIGRiLmNvbHVtbnMpIHtcbiAgICAgICAgICAgIGxldCBleGlzdGluZyA9IGNvbHVtbkJ5TmFtZS5nZXQoY29sLmNvbHVtbik7XG4gICAgICAgICAgICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmcgPSB7IGNvbHVtbjogY29sLmNvbHVtbiwgYnl0ZVNpemU6IDAgfTtcbiAgICAgICAgICAgICAgICBjb2x1bW5CeU5hbWUuc2V0KGNvbC5jb2x1bW4sIGV4aXN0aW5nKTtcbiAgICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goZXhpc3RpbmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXhpc3RpbmcuYnl0ZVNpemUgKz0gY29sLmJ5dGVTaXplO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdG90YWxCeXRlczogZGF0YWJhc2VzLnJlZHVjZSgoYWNjLCBkYikgPT4gYWNjICsgZGIudG90YWxCeXRlcywgMCksXG4gICAgICAgIHJvd0NvdW50OiBrZXlzLmxlbmd0aCxcbiAgICAgICAga2V5cyxcbiAgICAgICAgcmF3S2V5Q291bnQ6IGRhdGFiYXNlcy5yZWR1Y2UoKGFjYywgZGIpID0+IGFjYyArIGRiLmtleVRpbWVzLnNpemUgKyAoZGIuZGVsZXRlVGltZXM/LnNpemUgPz8gMCksIDApLFxuICAgICAgICByZWFkZXJDb3VudDogZGF0YWJhc2VzLmxlbmd0aCxcbiAgICAgICAgY29sdW1ucyxcbiAgICAgICAga2V5VGltZXM6IGtleVRpbWUsXG4gICAgICAgIGRlbGV0ZVRpbWVzOiBkZWxldGVUaW1lLFxuICAgICAgICBhc3luYyBnZXRDb2x1bW4oY29sdW1uKSB7XG4gICAgICAgICAgICBjb25zdCBwZXJSZWFkZXIgPSBhd2FpdCBQcm9taXNlLmFsbChkYXRhYmFzZXMubWFwKGFzeW5jIGRiID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWRiLmNvbHVtbnMuc29tZShjID0+IGMuY29sdW1uID09PSBjb2x1bW4pKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVudHJpZXMgPSBhd2FpdCBkYi5nZXRDb2x1bW4oY29sdW1uKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXAoZW50cmllcy5tYXAoZSA9PiBbZS5rZXksIHsgdmFsdWU6IGUudmFsdWUsIHRpbWU6IGUudGltZSB9XSkpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgd2FybkNvcnJ1cHRSZWFkKGRiLCBjb2x1bW4sIGUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIHJldHVybiBrZXlzLm1hcChrZXkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBiZXN0VGltZSA9IC1JbmZpbml0eTtcbiAgICAgICAgICAgICAgICBsZXQgYmVzdFZhbDogdW5rbm93bjtcbiAgICAgICAgICAgICAgICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG0gb2YgcGVyUmVhZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbGwgPSBtICYmIG0uZ2V0KGtleSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2VsbCB8fCBjZWxsLnZhbHVlID09PSBBQlNFTlQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbC50aW1lID4gYmVzdFRpbWUpIHsgYmVzdFRpbWUgPSBjZWxsLnRpbWU7IGJlc3RWYWwgPSBjZWxsLnZhbHVlOyBmb3VuZCA9IHRydWU7IH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgbGl2ZSA9IGZvdW5kICYmIGJlc3RUaW1lID4gZGVsT2Yoa2V5KTtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBrZXksIHZhbHVlOiBsaXZlID8gYmVzdFZhbCA6IHVuZGVmaW5lZCwgdGltZTogbGl2ZSA/IGJlc3RUaW1lIDogKGtleVRpbWUuZ2V0KGtleSkgPz8gMCkgfTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICBhc3luYyBnZXRTaW5nbGVGaWVsZChrZXksIGNvbHVtbikge1xuICAgICAgICAgICAgY29uc3Qga3QgPSBrZXlUaW1lLmdldChrZXkpO1xuICAgICAgICAgICAgaWYgKGt0ID09PSB1bmRlZmluZWQgfHwga3QgPD0gZGVsT2Yoa2V5KSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGxldCBiZXN0VGltZSA9IC1JbmZpbml0eTtcbiAgICAgICAgICAgIGxldCBiZXN0VmFsOiB1bmtub3duO1xuICAgICAgICAgICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGRiIG9mIGRhdGFiYXNlcykge1xuICAgICAgICAgICAgICAgIGlmICghZGIuY29sdW1ucy5zb21lKGMgPT4gYy5jb2x1bW4gPT09IGNvbHVtbikpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGxldCByO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHIgPSBhd2FpdCBkYi5nZXRTaW5nbGVGaWVsZChrZXksIGNvbHVtbik7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICB3YXJuQ29ycnVwdFJlYWQoZGIsIGNvbHVtbiwgZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAociA9PT0gQUJTRU5UKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBpZiAoci50aW1lID4gYmVzdFRpbWUpIHsgYmVzdFRpbWUgPSByLnRpbWU7IGJlc3RWYWwgPSByLnZhbHVlOyBmb3VuZCA9IHRydWU7IH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGxpdmUgPSBmb3VuZCAmJiBiZXN0VGltZSA+IGRlbE9mKGtleSk7XG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbGl2ZSA/IGJlc3RWYWwgOiB1bmRlZmluZWQsIHRpbWU6IGxpdmUgPyBiZXN0VGltZSA6IGt0IH07XG4gICAgICAgIH0sXG4gICAgfTtcbn1cbiJdfQ==
|
|
435
|
+
/* _JS_SOURCE_HASH = "08d023e467f7929194485c2e9e317afa50d1a1153cc906e80e96e8dce7814579"; */
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
3
|
+
//exports.WriteOverlay = exports.DELETED = void 0;
|
|
4
|
+
exports.DELETED = Symbol("deleted");
|
|
5
|
+
// In-memory pending mutations layered on top of a LoadedIndex. Each entry carries the write's unique
|
|
6
|
+
// timestamp so cross-tab writes can be ordered + the swap can drop entries the new index already
|
|
7
|
+
// covers. Methods that mutate report which columns invalidate ("all" if the key's liveness flipped),
|
|
8
|
+
// so the host can drop the right caches without scanning every column.
|
|
9
|
+
class WriteOverlay {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.entries = new Map();
|
|
12
|
+
}
|
|
13
|
+
get size() { return this.entries.size; }
|
|
14
|
+
get(key) { return this.entries.get(key); }
|
|
15
|
+
has(key) { return this.entries.has(key); }
|
|
16
|
+
keys() { return this.entries.keys(); }
|
|
17
|
+
[Symbol.iterator]() { return this.entries[Symbol.iterator](); }
|
|
18
|
+
writeRow(key, row, time, wasLive) {
|
|
19
|
+
const existing = this.entries.get(key);
|
|
20
|
+
const value = existing && existing.value !== exports.DELETED ? { ...existing.value, ...row } : { ...row };
|
|
21
|
+
this.entries.set(key, { time, value });
|
|
22
|
+
return { invalidatedColumns: wasLive ? Object.keys(row) : "all" };
|
|
23
|
+
}
|
|
24
|
+
deleteKey(key, time, wasLive) {
|
|
25
|
+
this.entries.set(key, { time, value: exports.DELETED });
|
|
26
|
+
return { invalidatedColumns: wasLive ? "all" : [] };
|
|
27
|
+
}
|
|
28
|
+
clear() { this.entries.clear(); }
|
|
29
|
+
// Drop entries the new index already reflects (its keyTime or deleteTime ≥ the entry's time). The
|
|
30
|
+
// remaining entries are writes the index doesn't yet see — they have to keep serving reads.
|
|
31
|
+
sweepCovered(authority) {
|
|
32
|
+
for (const [key, entry] of this.entries) {
|
|
33
|
+
if (entry.time <= authority(key))
|
|
34
|
+
this.entries.delete(key);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Apply this overlay onto the base column entries. A column-unset overlay entry leaves the base
|
|
38
|
+
// value+time in place (a partial write only overrides the columns it set).
|
|
39
|
+
patchColumn(base, column) {
|
|
40
|
+
if (this.entries.size === 0)
|
|
41
|
+
return base;
|
|
42
|
+
const map = new Map(base.map(e => [e.key, { value: e.value, time: e.time }]));
|
|
43
|
+
for (const [key, entry] of this.entries) {
|
|
44
|
+
if (entry.value === exports.DELETED) {
|
|
45
|
+
map.delete(key);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (column in entry.value)
|
|
49
|
+
map.set(key, { value: entry.value[column], time: entry.time });
|
|
50
|
+
else if (!map.has(key))
|
|
51
|
+
map.set(key, { value: undefined, time: entry.time });
|
|
52
|
+
}
|
|
53
|
+
return [...map].map(([key, v]) => ({ key, value: v.value, time: v.time }));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.WriteOverlay = WriteOverlay;
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV3JpdGVPdmVybGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiV3JpdGVPdmVybGF5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFhLFFBQUEsT0FBTyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUl6QyxxR0FBcUc7QUFDckcsaUdBQWlHO0FBQ2pHLHFHQUFxRztBQUNyRyx1RUFBdUU7QUFDdkUsTUFBYSxZQUFZO0lBQXpCO1FBQ1ksWUFBTyxHQUFHLElBQUksR0FBRyxFQUF3QixDQUFDO0lBMEN0RCxDQUFDO0lBeENHLElBQUksSUFBSSxLQUFhLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2hELEdBQUcsQ0FBQyxHQUFXLElBQThCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVFLEdBQUcsQ0FBQyxHQUFXLElBQWEsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0QsSUFBSSxLQUErQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFL0QsUUFBUSxDQUFDLEdBQVcsRUFBRSxHQUE0QixFQUFFLElBQVksRUFBRSxPQUFnQjtRQUM5RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QyxNQUFNLEtBQUssR0FBRyxRQUFRLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxlQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUMsS0FBSyxF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Q0Qsb0NBMkNDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IERFTEVURUQgPSBTeW1ib2woXCJkZWxldGVkXCIpO1xuXG5leHBvcnQgdHlwZSBPdmVybGF5RW50cnkgPSB7IHRpbWU6IG51bWJlcjsgdmFsdWU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdHlwZW9mIERFTEVURUQgfTtcblxuLy8gSW4tbWVtb3J5IHBlbmRpbmcgbXV0YXRpb25zIGxheWVyZWQgb24gdG9wIG9mIGEgTG9hZGVkSW5kZXguIEVhY2ggZW50cnkgY2FycmllcyB0aGUgd3JpdGUncyB1bmlxdWVcbi8vIHRpbWVzdGFtcCBzbyBjcm9zcy10YWIgd3JpdGVzIGNhbiBiZSBvcmRlcmVkICsgdGhlIHN3YXAgY2FuIGRyb3AgZW50cmllcyB0aGUgbmV3IGluZGV4IGFscmVhZHlcbi8vIGNvdmVycy4gTWV0aG9kcyB0aGF0IG11dGF0ZSByZXBvcnQgd2hpY2ggY29sdW1ucyBpbnZhbGlkYXRlIChcImFsbFwiIGlmIHRoZSBrZXkncyBsaXZlbmVzcyBmbGlwcGVkKSxcbi8vIHNvIHRoZSBob3N0IGNhbiBkcm9wIHRoZSByaWdodCBjYWNoZXMgd2l0aG91dCBzY2FubmluZyBldmVyeSBjb2x1bW4uXG5leHBvcnQgY2xhc3MgV3JpdGVPdmVybGF5IHtcbiAgICBwcml2YXRlIGVudHJpZXMgPSBuZXcgTWFwPHN0cmluZywgT3ZlcmxheUVudHJ5PigpO1xuXG4gICAgZ2V0IHNpemUoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuZW50cmllcy5zaXplOyB9XG4gICAgZ2V0KGtleTogc3RyaW5nKTogT3ZlcmxheUVudHJ5IHwgdW5kZWZpbmVkIHsgcmV0dXJuIHRoaXMuZW50cmllcy5nZXQoa2V5KTsgfVxuICAgIGhhcyhrZXk6IHN0cmluZyk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5lbnRyaWVzLmhhcyhrZXkpOyB9XG4gICAga2V5cygpOiBJdGVyYWJsZUl0ZXJhdG9yPHN0cmluZz4geyByZXR1cm4gdGhpcy5lbnRyaWVzLmtleXMoKTsgfVxuICAgIFtTeW1ib2wuaXRlcmF0b3JdKCkgeyByZXR1cm4gdGhpcy5lbnRyaWVzW1N5bWJvbC5pdGVyYXRvcl0oKTsgfVxuXG4gICAgd3JpdGVSb3coa2V5OiBzdHJpbmcsIHJvdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIHRpbWU6IG51bWJlciwgd2FzTGl2ZTogYm9vbGVhbik6IHsgaW52YWxpZGF0ZWRDb2x1bW5zOiBJdGVyYWJsZTxzdHJpbmc+IHwgXCJhbGxcIiB9IHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmVudHJpZXMuZ2V0KGtleSk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gZXhpc3RpbmcgJiYgZXhpc3RpbmcudmFsdWUgIT09IERFTEVURUQgPyB7IC4uLmV4aXN0aW5nLnZhbHVlLCAuLi5yb3cgfSA6IHsgLi4ucm93IH07XG4gICAgICAgIHRoaXMuZW50cmllcy5zZXQoa2V5LCB7IHRpbWUsIHZhbHVlIH0pO1xuICAgICAgICByZXR1cm4geyBpbnZhbGlkYXRlZENvbHVtbnM6IHdhc0xpdmUgPyBPYmplY3Qua2V5cyhyb3cpIDogXCJhbGxcIiB9O1xuICAgIH1cblxuICAgIGRlbGV0ZUtleShrZXk6IHN0cmluZywgdGltZTogbnVtYmVyLCB3YXNMaXZlOiBib29sZWFuKTogeyBpbnZhbGlkYXRlZENvbHVtbnM6IEl0ZXJhYmxlPHN0cmluZz4gfCBcImFsbFwiIH0ge1xuICAgICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwgeyB0aW1lLCB2YWx1ZTogREVMRVRFRCB9KTtcbiAgICAgICAgcmV0dXJuIHsgaW52YWxpZGF0ZWRDb2x1bW5zOiB3YXNMaXZlID8gXCJhbGxcIiA6IFtdIH07XG4gICAgfVxuXG4gICAgY2xlYXIoKTogdm9pZCB7IHRoaXMuZW50cmllcy5jbGVhcigpOyB9XG5cbiAgICAvLyBEcm9wIGVudHJpZXMgdGhlIG5ldyBpbmRleCBhbHJlYWR5IHJlZmxlY3RzIChpdHMga2V5VGltZSBvciBkZWxldGVUaW1lIOKJpSB0aGUgZW50cnkncyB0aW1lKS4gVGhlXG4gICAgLy8gcmVtYWluaW5nIGVudHJpZXMgYXJlIHdyaXRlcyB0aGUgaW5kZXggZG9lc24ndCB5ZXQgc2VlIOKAlCB0aGV5IGhhdmUgdG8ga2VlcCBzZXJ2aW5nIHJlYWRzLlxuICAgIHN3ZWVwQ292ZXJlZChhdXRob3JpdHk6IChrZXk6IHN0cmluZykgPT4gbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgZW50cnldIG9mIHRoaXMuZW50cmllcykge1xuICAgICAgICAgICAgaWYgKGVudHJ5LnRpbWUgPD0gYXV0aG9yaXR5KGtleSkpIHRoaXMuZW50cmllcy5kZWxldGUoa2V5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFwcGx5IHRoaXMgb3ZlcmxheSBvbnRvIHRoZSBiYXNlIGNvbHVtbiBlbnRyaWVzLiBBIGNvbHVtbi11bnNldCBvdmVybGF5IGVudHJ5IGxlYXZlcyB0aGUgYmFzZVxuICAgIC8vIHZhbHVlK3RpbWUgaW4gcGxhY2UgKGEgcGFydGlhbCB3cml0ZSBvbmx5IG92ZXJyaWRlcyB0aGUgY29sdW1ucyBpdCBzZXQpLlxuICAgIHBhdGNoQ29sdW1uKGJhc2U6IHsga2V5OiBzdHJpbmc7IHZhbHVlOiB1bmtub3duOyB0aW1lOiBudW1iZXIgfVtdLCBjb2x1bW46IHN0cmluZyk6IHsga2V5OiBzdHJpbmc7IHZhbHVlOiB1bmtub3duOyB0aW1lOiBudW1iZXIgfVtdIHtcbiAgICAgICAgaWYgKHRoaXMuZW50cmllcy5zaXplID09PSAwKSByZXR1cm4gYmFzZTtcbiAgICAgICAgY29uc3QgbWFwID0gbmV3IE1hcChiYXNlLm1hcChlID0+IFtlLmtleSwgeyB2YWx1ZTogZS52YWx1ZSwgdGltZTogZS50aW1lIH1dKSk7XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgZW50cnldIG9mIHRoaXMuZW50cmllcykge1xuICAgICAgICAgICAgaWYgKGVudHJ5LnZhbHVlID09PSBERUxFVEVEKSB7IG1hcC5kZWxldGUoa2V5KTsgY29udGludWU7IH1cbiAgICAgICAgICAgIGlmIChjb2x1bW4gaW4gZW50cnkudmFsdWUpIG1hcC5zZXQoa2V5LCB7IHZhbHVlOiBlbnRyeS52YWx1ZVtjb2x1bW5dLCB0aW1lOiBlbnRyeS50aW1lIH0pO1xuICAgICAgICAgICAgZWxzZSBpZiAoIW1hcC5oYXMoa2V5KSkgbWFwLnNldChrZXksIHsgdmFsdWU6IHVuZGVmaW5lZCwgdGltZTogZW50cnkudGltZSB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gWy4uLm1hcF0ubWFwKChba2V5LCB2XSkgPT4gKHsga2V5LCB2YWx1ZTogdi52YWx1ZSwgdGltZTogdi50aW1lIH0pKTtcbiAgICB9XG59XG4iXX0=
|
|
58
|
+
/* _JS_SOURCE_HASH = "209264a8708c7ad5dd2423a93289a7c044b6b8efb117a9e1ba74ae94fdf81902"; */
|