sliftutils 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/.gitignore +38 -0
  2. package/assets/icon128.png +0 -0
  3. package/assets/icon16.png +0 -0
  4. package/assets/icon48.png +0 -0
  5. package/build-electron/assets/icon128.png +0 -0
  6. package/build-electron/assets/icon16.png +0 -0
  7. package/build-electron/assets/icon48.png +0 -0
  8. package/build-electron/electron/electronIndex.html +12 -0
  9. package/build-electron/electronMain.js +5185 -0
  10. package/build-electron/electronRenderer.js +20852 -0
  11. package/build-extension/assets/icon128.png +0 -0
  12. package/build-extension/assets/icon16.png +0 -0
  13. package/build-extension/assets/icon48.png +0 -0
  14. package/build-extension/extBackground.js +5246 -0
  15. package/build-extension/extContentScript.js +5243 -0
  16. package/build-extension/manifest.json +29 -0
  17. package/build-nodejs/server.js +198610 -0
  18. package/build-web/assets/icon128.png +0 -0
  19. package/build-web/assets/icon16.png +0 -0
  20. package/build-web/assets/icon48.png +0 -0
  21. package/build-web/browser.js +199266 -0
  22. package/build-web/web/index.html +32 -0
  23. package/builders/dist/electronBuild.ts.cache +105 -0
  24. package/builders/dist/extensionBuild.ts.cache +146 -0
  25. package/builders/dist/generateIndexDts.ts.cache +74 -0
  26. package/builders/dist/hotReload.ts.cache +93 -0
  27. package/builders/dist/nodeJSBuild.ts.cache +29 -0
  28. package/builders/dist/watch.ts.cache +163 -0
  29. package/builders/dist/webBuild.ts.cache +81 -0
  30. package/builders/generateIndexDts.ts +1 -1
  31. package/bundler/dist/bundleEntry.ts.cache +48 -0
  32. package/bundler/dist/bundleEntryCaller.ts.cache +18 -0
  33. package/bundler/dist/bundleRequire.ts.cache +246 -0
  34. package/bundler/dist/bundleWrapper.ts.cache +101 -0
  35. package/bundler/dist/bundler.ts.cache +66 -0
  36. package/bundler/dist/sourceMaps.ts.cache +210 -0
  37. package/dist/electronMain.ts.cache +27 -0
  38. package/dist/electronRenderer.tsx.cache +62 -0
  39. package/electron/dist/electronMain.ts.cache +26 -0
  40. package/electron/dist/electronRenderer.tsx.cache +64 -0
  41. package/extension/dist/extBackground.ts.cache +20 -0
  42. package/extension/dist/extContentScript.ts.cache +17 -0
  43. package/index.d.ts +478 -0
  44. package/misc/dist/environment.ts.cache +50 -0
  45. package/misc/dist/fs.ts.cache +29 -0
  46. package/nodejs/dist/exampleFile.ts.cache +11 -0
  47. package/nodejs/dist/server.ts.cache +15 -0
  48. package/package.json +5 -1
  49. package/render-utils/dist/observer.tsx.cache +33 -0
  50. package/storage/CachedStorage.d.ts +2 -0
  51. package/storage/DelayedStorage.d.ts +14 -0
  52. package/storage/DiskCollection.d.ts +99 -0
  53. package/storage/FileFolderAPI.d.ts +71 -0
  54. package/storage/IStorage.d.ts +38 -0
  55. package/storage/IndexedDBFileFolderAPI.d.ts +6 -0
  56. package/storage/JSONStorage.d.ts +16 -0
  57. package/storage/PendingManager.d.ts +6 -0
  58. package/storage/PendingStorage.d.ts +18 -0
  59. package/storage/PrivateFileSystemStorage.d.ts +23 -0
  60. package/storage/StorageObservable.d.ts +32 -0
  61. package/storage/TransactionStorage.d.ts +46 -0
  62. package/storage/dist/CachedStorage.ts.cache +31 -0
  63. package/storage/dist/DelayedStorage.ts.cache +35 -0
  64. package/storage/dist/DiskCollection.ts.cache +241 -0
  65. package/storage/dist/FileFolderAPI.tsx.cache +345 -0
  66. package/storage/dist/IndexedDBFileFolderAPI.ts.cache +142 -0
  67. package/storage/dist/JSONStorage.ts.cache +38 -0
  68. package/storage/dist/PendingManager.tsx.cache +73 -0
  69. package/storage/dist/PendingStorage.ts.cache +49 -0
  70. package/storage/dist/PrivateFileSystemStorage.ts.cache +178 -0
  71. package/storage/dist/StorageObservable.ts.cache +120 -0
  72. package/storage/dist/TransactionStorage.ts.cache +421 -0
  73. package/storage/dist/fileSystemPointer.ts.cache +77 -0
  74. package/storage/fileSystemPointer.d.ts +11 -0
  75. package/tsconfig.declarations.json +3 -1
  76. package/web/dist/browser.tsx.cache +66 -0
  77. package/yarn.lock +1752 -0
@@ -0,0 +1,421 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
+ //exports.TransactionStorage = void 0;
4
+ const misc_1 = require("socket-function/src/misc");
5
+ const zip_1 = require("../misc/zip");
6
+ const batching_1 = require("socket-function/src/batching");
7
+ const format_1 = require("socket-function/src/formatting/format");
8
+ const PendingManager_1 = require("./PendingManager");
9
+ const buildFlag_1 = require("../../buildFlag");
10
+ /*
11
+ // Spec:
12
+ // - Zip individual large values
13
+ // - Stores a transaction log
14
+ // - Transaction log has a header, which is JSON, for things such as "zipped"
15
+ // - Transaction log uses length prefixed values, with a special 8 bytes to denote the end,
16
+ // and 8 for the start.
17
+ // - When transaction log is iterated on, if the bytes at the end (using the length prefix)
18
+ // don't match the end bytes OR the start bytes are wrong, we skip the start bytes,
19
+ // and iterating until we find new start bytes that match our special bytes. Then we try
20
+ // to read these values.
21
+ // - Each transaction entry has a byte for flags, one bit which denotes if the value is zipped or not.
22
+ // - Compresses the log after there are 3X entries than keys (and > 100)
23
+ // - Both dedupe keys, and zip
24
+ // - Assumes all files in rawStorage ending with .tx are transaction logs
25
+ // - Names files like `${generation}.tx`
26
+ // - When compressing, we increment the generation, and write to a new file, and delete
27
+ // any generations that are older than the new one
28
+ // - On reading, we read from all generation files that exist, in case some are corrupted
29
+ // - On load, loads in all transaction logs, and stores all values in a Map<string, Buffer>
30
+ // - On writes immediately updates the in memory Map, and then writes to the transaction log
31
+ // - Caches the last transaction file name in memory
32
+ // - Makes sure all file system writes (but not Map updates) are done with fileLockSection,
33
+ // so they never overlap.
34
+ // - Buffers pending appends in memory, so they can written all at once (after the first one
35
+ // is blocking in fileLockSection).
36
+
37
+ UPDATE now we use chunks, because append is too slow.
38
+
39
+ IMPORTANT! If there are multiple writers, we clobber writes from other writers when we compress
40
+ */
41
+ const FILE_CHUNK_SIZE = 1024 * 1024;
42
+ const FILE_ZIP_THRESHOLD = 16 * 1024 * 1024;
43
+ const ZIP_THRESHOLD = 4096;
44
+ const START_BYTES = Buffer.from([236, 49, 112, 121, 27, 127, 227, 63]);
45
+ const END_BYTES = Buffer.from([220, 111, 243, 202, 200, 79, 213, 63]);
46
+ // Delay writes, so we batch better, and thrash the disk less
47
+ const WRITE_DELAY = 500;
48
+ const fileLockSection = (0, batching_1.runInSerial)(async (fnc) => {
49
+ await fnc();
50
+ });
51
+ const CHUNK_EXT = ".chunk";
52
+ const ourId = Date.now() + Math.random();
53
+ class TransactionStorage {
54
+ constructor(rawStorage, debugName, writeDelay = WRITE_DELAY) {
55
+ this.rawStorage = rawStorage;
56
+ this.debugName = debugName;
57
+ this.writeDelay = writeDelay;
58
+ this.cache = new Map();
59
+ this.currentChunk = 0;
60
+ this.currentChunkSize = 0;
61
+ this.entryCount = 0;
62
+ this.init = this.loadAllTransactions();
63
+ this.pendingAppends = [];
64
+ this.extraAppends = 0;
65
+ this.updatePendingAppends = (0, misc_1.throttleFunction)(100, async () => {
66
+ let appendCount = this.pendingAppends.length + this.extraAppends;
67
+ let group = `Transaction (${this.debugName})`;
68
+ //console.log(`Update pending appends ${group}: ${appendCount}`);
69
+ if (!appendCount) {
70
+ (0, PendingManager_1.setPending)(group, "");
71
+ return;
72
+ }
73
+ (0, PendingManager_1.setPending)(group, `Pending appends: ${appendCount}`);
74
+ });
75
+ this.compressing = false;
76
+ TransactionStorage.allStorage.push(this);
77
+ }
78
+ // Helps get rid of parse errors which constantly log. Also, uses less space
79
+ static async compressAll() {
80
+ for (let storage of TransactionStorage.allStorage) {
81
+ await storage.compressTransactionLog(true);
82
+ }
83
+ }
84
+ getChunk(chunk) { return `${chunk}_${ourId}${CHUNK_EXT}`; }
85
+ async get(key) {
86
+ await this.init;
87
+ const value = this.cache.get(key);
88
+ if (value && value.isZipped && value.value) {
89
+ value.value = await zip_1.Zip.gunzip(value.value);
90
+ value.isZipped = false;
91
+ }
92
+ return value === null || value === void 0 ? void 0 : value.value;
93
+ }
94
+ async set(key, value) {
95
+ if (this.init)
96
+ await this.init;
97
+ // Time is set on disk write, as Date.now() is too slow
98
+ let entry = { key, value, isZipped: false, time: 0 };
99
+ this.cache.set(key, entry);
100
+ if (value.length >= ZIP_THRESHOLD) {
101
+ value = await zip_1.Zip.gzip(value);
102
+ entry.value = value;
103
+ entry.isZipped = true;
104
+ }
105
+ await this.pushAppend(entry);
106
+ }
107
+ async remove(key) {
108
+ if (this.init)
109
+ await this.init;
110
+ this.cache.delete(key);
111
+ await this.pushAppend({ key, value: undefined, isZipped: false, time: 0 });
112
+ }
113
+ async getInfo(key) {
114
+ await this.init;
115
+ const value = this.cache.get(key);
116
+ if (!(value === null || value === void 0 ? void 0 : value.value))
117
+ return undefined;
118
+ return { size: value.value.length, lastModified: value.time };
119
+ }
120
+ async pushAppend(entry) {
121
+ this.entryCount++;
122
+ this.pendingAppends.push(entry);
123
+ void this.updatePendingAppends();
124
+ if (this.pendingWrite)
125
+ return this.pendingWrite;
126
+ this.pendingWrite = fileLockSection(async () => {
127
+ // Delay to allow batching, and deduping
128
+ await new Promise(resolve => setTimeout(resolve, this.writeDelay));
129
+ let curAppends = this.pendingAppends;
130
+ this.pendingAppends = [];
131
+ this.pendingWrite = undefined;
132
+ {
133
+ let appendsDeduped = new Map();
134
+ for (const entry of curAppends) {
135
+ appendsDeduped.set(entry.key, entry);
136
+ }
137
+ curAppends = Array.from(appendsDeduped.values());
138
+ }
139
+ this.extraAppends += curAppends.length;
140
+ void this.updatePendingAppends();
141
+ if (curAppends.length === 0)
142
+ return;
143
+ try {
144
+ let time = Date.now();
145
+ for (let entry of curAppends) {
146
+ entry.time = time;
147
+ }
148
+ let newSum = 0;
149
+ let buffers = [];
150
+ for (const entry of curAppends) {
151
+ let buffer = this.serializeTransactionEntry(entry);
152
+ buffers.push(buffer);
153
+ newSum += buffer.length;
154
+ }
155
+ let newChunks = this.chunkBuffers(buffers);
156
+ for (let chunk of newChunks) {
157
+ let file = this.getChunk(this.currentChunk);
158
+ if (!await this.rawStorage.get(file)) {
159
+ let { header, headerBuffer } = this.getHeader(false);
160
+ await this.rawStorage.set(file, headerBuffer);
161
+ }
162
+ let content = chunk.buffer;
163
+ await this.rawStorage.append(file, content);
164
+ this.currentChunkSize += content.length;
165
+ if (this.currentChunkSize >= FILE_CHUNK_SIZE) {
166
+ this.currentChunk++;
167
+ this.currentChunkSize = 0;
168
+ }
169
+ }
170
+ await this.compressTransactionLog();
171
+ }
172
+ finally {
173
+ this.extraAppends -= curAppends.length;
174
+ void this.updatePendingAppends();
175
+ }
176
+ });
177
+ await this.pendingWrite;
178
+ }
179
+ async getKeys() {
180
+ if (this.init)
181
+ await this.init;
182
+ return Array.from(this.cache.keys());
183
+ }
184
+ async loadAllTransactions() {
185
+ if ((0, buildFlag_1.isInBuild)())
186
+ return;
187
+ let time = Date.now();
188
+ const keys = await this.rawStorage.getKeys();
189
+ const transactionFiles = keys.filter(key => key.endsWith(CHUNK_EXT));
190
+ (0, misc_1.sort)(transactionFiles, x => parseInt(x));
191
+ let size = 0;
192
+ for (const file of transactionFiles) {
193
+ let chunk = parseInt(file);
194
+ let curSize = await this.loadTransactionFile(file);
195
+ if (chunk >= this.currentChunk) {
196
+ this.currentChunk = chunk;
197
+ this.currentChunkSize = curSize;
198
+ }
199
+ size += curSize;
200
+ }
201
+ time = Date.now() - time;
202
+ if (time > 50) {
203
+ console.log(`Loaded ${this.debugName} in ${(0, format_1.formatTime)(time)}, ${(0, format_1.formatNumber)(this.cache.size)} keys, ${(0, format_1.formatNumber)(size)}B`);
204
+ }
205
+ this.init = undefined;
206
+ }
207
+ async loadTransactionFile(filename) {
208
+ const fullFile = await this.rawStorage.get(filename);
209
+ if (!fullFile)
210
+ return 0;
211
+ if (fullFile.length < 4) {
212
+ //console.error(`Transaction in ${this.debugName} file ${filename} is too small, skipping`);
213
+ return 0;
214
+ }
215
+ let headerSize = fullFile.readUInt32LE(0);
216
+ let headerBuffer = fullFile.slice(4, 4 + headerSize);
217
+ let header;
218
+ try {
219
+ header = JSON.parse(headerBuffer.toString());
220
+ }
221
+ catch (e) {
222
+ console.error(`Failed to parse header of transaction file in ${this.debugName}, ${filename}`);
223
+ return 0;
224
+ }
225
+ let content = fullFile.slice(4 + headerSize);
226
+ if (header.zipped) {
227
+ content = await zip_1.Zip.gunzip(content);
228
+ }
229
+ let offset = 0;
230
+ let entries = [];
231
+ while (offset < content.length) {
232
+ if (!content.slice(offset, offset + START_BYTES.length).equals(START_BYTES)) {
233
+ let s = offset;
234
+ while (offset < content.length && !content.slice(offset, offset + START_BYTES.length).equals(START_BYTES)) {
235
+ offset++;
236
+ }
237
+ let len = offset - s;
238
+ console.warn(`Found bad bytes in ${filename}, skipping ${len} bytes at offset ${s}. Total file bytes ${content.length}, read ${entries.length} entries`);
239
+ if (offset >= content.length)
240
+ break;
241
+ }
242
+ let entryObj;
243
+ try {
244
+ entryObj = this.readTransactionEntry(content, offset);
245
+ }
246
+ catch (e) {
247
+ if (e.message.includes("Read past end of buffer")) {
248
+ offset += 1;
249
+ continue;
250
+ }
251
+ throw e;
252
+ }
253
+ if (!entryObj) {
254
+ console.warn(`Failed to read transaction entry in in ${this.debugName}, file ${filename} at offset ${offset}, skipping bad bytes, reading remainder of file`);
255
+ offset++;
256
+ continue;
257
+ }
258
+ this.entryCount++;
259
+ let { entry } = entryObj;
260
+ offset = entryObj.offset;
261
+ entries.push(entry);
262
+ if (entry.value === undefined) {
263
+ this.cache.delete(entry.key);
264
+ }
265
+ else {
266
+ let prev = this.cache.get(entry.key);
267
+ if (prev && (prev.time > entry.time)) {
268
+ continue;
269
+ }
270
+ this.cache.set(entry.key, entry);
271
+ }
272
+ }
273
+ return fullFile.length;
274
+ }
275
+ readTransactionEntry(buffer, offset) {
276
+ function readSlice(count) {
277
+ const slice = buffer.slice(offset, offset + count);
278
+ if (slice.length < count)
279
+ throw new Error(`Read past end of buffer at offset ${offset}/${buffer.length}`);
280
+ offset += count;
281
+ return slice;
282
+ }
283
+ if (!readSlice(START_BYTES.length).equals(START_BYTES))
284
+ return undefined;
285
+ const keyLength = readSlice(4).readUInt32LE(0);
286
+ const valueLength = readSlice(4).readUInt32LE(0);
287
+ const time = readSlice(8).readDoubleLE(0);
288
+ const flags = readSlice(1).readUInt8(0);
289
+ const key = readSlice(keyLength).toString();
290
+ let value = readSlice(valueLength);
291
+ if (!readSlice(END_BYTES.length).equals(END_BYTES))
292
+ return undefined;
293
+ let isZipped = (flags & 1) === 1;
294
+ let isDelete = (flags & 2) === 2;
295
+ let entry = { key, value, isZipped, time };
296
+ if (isDelete) {
297
+ entry.value = undefined;
298
+ }
299
+ return { entry, offset };
300
+ }
301
+ // TODO: Make this directly go from TransactionEntry[] to Buffer, by pre-allocating, so it is more efficient
302
+ serializeTransactionEntry(entry) {
303
+ var _a;
304
+ let keyBuffer = Buffer.from(entry.key);
305
+ const buffer = Buffer.alloc(START_BYTES.length + 4 + 4 + 8 + 1 + keyBuffer.length + (((_a = entry.value) === null || _a === void 0 ? void 0 : _a.length) || 0) + END_BYTES.length);
306
+ let offset = 0;
307
+ START_BYTES.copy(buffer, offset);
308
+ offset += START_BYTES.length;
309
+ buffer.writeUInt32LE(keyBuffer.length, offset);
310
+ offset += 4;
311
+ buffer.writeUInt32LE(entry.value ? entry.value.length : 0, offset);
312
+ offset += 4;
313
+ buffer.writeDoubleLE(entry.time, offset);
314
+ offset += 8;
315
+ let flags = 0;
316
+ if (entry.isZipped)
317
+ flags |= 1;
318
+ if (entry.value === undefined)
319
+ flags |= 2;
320
+ buffer.writeUInt8(flags, offset);
321
+ offset += 1;
322
+ keyBuffer.copy(buffer, offset);
323
+ offset += keyBuffer.length;
324
+ if (entry.value) {
325
+ entry.value.copy(buffer, offset);
326
+ offset += entry.value.length;
327
+ }
328
+ END_BYTES.copy(buffer, offset);
329
+ offset += END_BYTES.length;
330
+ return buffer;
331
+ }
332
+ getHeader(zip) {
333
+ const header = { zipped: zip };
334
+ let headerBuffer = Buffer.from(JSON.stringify(header));
335
+ let headerSize = Buffer.alloc(4);
336
+ headerSize.writeUInt32LE(headerBuffer.length, 0);
337
+ return { header, headerBuffer: Buffer.concat([headerSize, headerBuffer]) };
338
+ }
339
+ chunkBuffers(buffers) {
340
+ let newChunks = [];
341
+ newChunks.push({ buffers: [], size: 0 });
342
+ for (const buffer of buffers) {
343
+ if (newChunks[newChunks.length - 1].size + buffer.length >= FILE_CHUNK_SIZE) {
344
+ newChunks.push({ buffers: [], size: 0 });
345
+ }
346
+ newChunks[newChunks.length - 1].buffers.push(buffer);
347
+ newChunks[newChunks.length - 1].size += buffer.length;
348
+ }
349
+ return newChunks.map(x => ({ buffer: Buffer.concat(x.buffers), size: x.size }));
350
+ }
351
+ async compressTransactionLog(force) {
352
+ if (this.compressing)
353
+ return;
354
+ this.compressing = true;
355
+ let existingDiskEntries = await this.rawStorage.getKeys();
356
+ existingDiskEntries = existingDiskEntries.filter(x => x.endsWith(CHUNK_EXT));
357
+ let compressNow = force || (this.entryCount > 100 && this.entryCount > this.cache.size * 3
358
+ // NOTE: This compress check breaks down if we only have very large values, but... those
359
+ // don't work ANYWAYS (it is better to use one file per value instead).
360
+ // - Maybe we should throw, or at least warn, on sets of value > 1MB,
361
+ // at which point they should just use a file per value
362
+ || existingDiskEntries.length > Math.max(10, Math.ceil(this.entryCount / 1000))
363
+ || existingDiskEntries.length > 1000 * 10);
364
+ if (!compressNow)
365
+ return;
366
+ console.log(`Compressing ${this.debugName} transaction log, ${this.entryCount} entries, ${this.cache.size} keys`);
367
+ // Load off disk, in case there are other writes. We still race with them, but at least
368
+ // this reduces the race condition considerably
369
+ (0, misc_1.sort)(existingDiskEntries, x => parseInt(x));
370
+ for (let entry of existingDiskEntries) {
371
+ await this.loadTransactionFile(entry);
372
+ }
373
+ this.entryCount = this.cache.size;
374
+ let nextStart = Math.max(...existingDiskEntries.map(x => parseInt(x))) + 1;
375
+ let buffers = [];
376
+ for (const entry of this.cache.values()) {
377
+ let buffer = this.serializeTransactionEntry(entry);
378
+ buffers.push(buffer);
379
+ }
380
+ let newChunks = this.chunkBuffers(buffers);
381
+ let curChunk = nextStart;
382
+ for (let chunk of newChunks) {
383
+ let file = this.getChunk(curChunk++);
384
+ let content = chunk.buffer;
385
+ let { header, headerBuffer } = this.getHeader(
386
+ // AND, never compress the last one, otherwise we can't append to it!
387
+ content.length >= FILE_ZIP_THRESHOLD && chunk !== newChunks[newChunks.length - 1]);
388
+ if (header.zipped) {
389
+ content = await zip_1.Zip.gzip(content);
390
+ }
391
+ let buffer = Buffer.concat([headerBuffer, content]);
392
+ await this.rawStorage.set(file, buffer);
393
+ }
394
+ // This is the ONLY time we can delete old files, as we know for sure the new file has all of our data.
395
+ // Any future readers won't know this, unless they write it themselves (or unless they audit it against
396
+ // the other generations, which is annoying).
397
+ for (const file of existingDiskEntries) {
398
+ await this.rawStorage.remove(file);
399
+ }
400
+ this.currentChunk = curChunk;
401
+ }
402
+ async reset() {
403
+ await fileLockSection(async () => {
404
+ let existingDiskEntries = await this.rawStorage.getKeys();
405
+ existingDiskEntries = existingDiskEntries.filter(x => x.endsWith(CHUNK_EXT));
406
+ try {
407
+ await Promise.allSettled(existingDiskEntries.map(x => this.rawStorage.remove(x)));
408
+ }
409
+ catch (_a) { }
410
+ this.pendingAppends = [];
411
+ this.cache.clear();
412
+ this.currentChunk = 0;
413
+ this.currentChunkSize = 0;
414
+ this.entryCount = 0;
415
+ });
416
+ }
417
+ }
418
+ exports.TransactionStorage = TransactionStorage;
419
+ TransactionStorage.allStorage = [];
420
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25TdG9yYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiVHJhbnNhY3Rpb25TdG9yYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1EQUE4RTtBQUU5RSxxQ0FBa0M7QUFDbEMsMkRBQTJEO0FBQzNELGtFQUFpRjtBQUNqRixxREFBOEM7QUFDOUMsK0NBQTRDO0FBRTVDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUE4QkU7QUFHRixNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBRXBDLE1BQU0sa0JBQWtCLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFFNUMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN2RSxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdEUsNkRBQTZEO0FBQzdELE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQWF4QixNQUFNLGVBQWUsR0FBRyxJQUFBLHNCQUFXLEVBQUMsS0FBSyxFQUFFLEdBQXdCLEVBQUUsRUFBRTtJQUNuRSxNQUFNLEdBQUcsRUFBRSxDQUFDO0FBQ2hCLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDO0FBQzNCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFFekMsTUFB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RyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RGLENBQUM7WUFBQyxXQUFNLENBQUMsQ0FBQyxDQUFDO1lBRVgsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1lBQzFCLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQzs7QUE5WkwsZ0RBK1pDO0FBelprQiw2QkFBVSxHQUF5QixFQUFFLEFBQTNCLENBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUHJvbWlzZU9iaiwgc29ydCwgdGhyb3R0bGVGdW5jdGlvbiB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL21pc2NcIjtcbmltcG9ydCB7IElTdG9yYWdlLCBJU3RvcmFnZVJhdyB9IGZyb20gXCIuL0lTdG9yYWdlXCI7XG5pbXBvcnQgeyBaaXAgfSBmcm9tIFwiLi4vbWlzYy96aXBcIjtcbmltcG9ydCB7IHJ1bkluU2VyaWFsIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvYmF0Y2hpbmdcIjtcbmltcG9ydCB7IGZvcm1hdE51bWJlciwgZm9ybWF0VGltZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2Zvcm1hdHRpbmcvZm9ybWF0XCI7XG5pbXBvcnQgeyBzZXRQZW5kaW5nIH0gZnJvbSBcIi4vUGVuZGluZ01hbmFnZXJcIjtcbmltcG9ydCB7IGlzSW5CdWlsZCB9IGZyb20gXCIuLi8uLi9idWlsZEZsYWdcIjtcblxuLypcbi8vIFNwZWM6XG4vLyAgICAgIC0gWmlwIGluZGl2aWR1YWwgbGFyZ2UgdmFsdWVzXG4vLyAgICAgIC0gU3RvcmVzIGEgdHJhbnNhY3Rpb24gbG9nXG4vLyAgICAgICAgICAtIFRyYW5zYWN0aW9uIGxvZyBoYXMgYSBoZWFkZXIsIHdoaWNoIGlzIEpTT04sIGZvciB0aGluZ3Mgc3VjaCBhcyBcInppcHBlZFwiXG4vLyAgICAgICAgICAtIFRyYW5zYWN0aW9uIGxvZyB1c2VzIGxlbmd0aCBwcmVmaXhlZCB2YWx1ZXMsIHdpdGggYSBzcGVjaWFsIDggYnl0ZXMgdG8gZGVub3RlIHRoZSBlbmQsXG4vLyAgICAgICAgICAgICAgYW5kIDggZm9yIHRoZSBzdGFydC5cbi8vICAgICAgICAgIC0gV2hlbiB0cmFuc2FjdGlvbiBsb2cgaXMgaXRlcmF0ZWQgb24sIGlmIHRoZSBieXRlcyBhdCB0aGUgZW5kICh1c2luZyB0aGUgbGVuZ3RoIHByZWZpeClcbi8vICAgICAgICAgICAgICBkb24ndCBtYXRjaCB0aGUgZW5kIGJ5dGVzIE9SIHRoZSBzdGFydCBieXRlcyBhcmUgd3JvbmcsIHdlIHNraXAgdGhlIHN0YXJ0IGJ5dGVzLFxuLy8gICAgICAgICAgICAgIGFuZCBpdGVyYXRpbmcgdW50aWwgd2UgZmluZCBuZXcgc3RhcnQgYnl0ZXMgdGhhdCBtYXRjaCBvdXIgc3BlY2lhbCBieXRlcy4gVGhlbiB3ZSB0cnlcbi8vICAgICAgICAgICAgICB0byByZWFkIHRoZXNlIHZhbHVlcy5cbi8vICAgICAgICAgIC0gRWFjaCB0cmFuc2FjdGlvbiBlbnRyeSBoYXMgYSBieXRlIGZvciBmbGFncywgb25lIGJpdCB3aGljaCBkZW5vdGVzIGlmIHRoZSB2YWx1ZSBpcyB6aXBwZWQgb3Igbm90LlxuLy8gICAgICAtIENvbXByZXNzZXMgdGhlIGxvZyBhZnRlciB0aGVyZSBhcmUgM1ggZW50cmllcyB0aGFuIGtleXMgKGFuZCA+IDEwMClcbi8vICAgICAgICAgIC0gQm90aCBkZWR1cGUga2V5cywgYW5kIHppcFxuLy8gICAgICAtIEFzc3VtZXMgYWxsIGZpbGVzIGluIHJhd1N0b3JhZ2UgZW5kaW5nIHdpdGggLnR4IGFyZSB0cmFuc2FjdGlvbiBsb2dzXG4vLyAgICAgIC0gTmFtZXMgZmlsZXMgbGlrZSBgJHtnZW5lcmF0aW9ufS50eGBcbi8vICAgICAgICAgIC0gV2hlbiBjb21wcmVzc2luZywgd2UgaW5jcmVtZW50IHRoZSBnZW5lcmF0aW9uLCBhbmQgd3JpdGUgdG8gYSBuZXcgZmlsZSwgYW5kIGRlbGV0ZVxuLy8gICAgICAgICAgICAgIGFueSBnZW5lcmF0aW9ucyB0aGF0IGFyZSBvbGRlciB0aGFuIHRoZSBuZXcgb25lXG4vLyAgICAgICAgICAtIE9uIHJlYWRpbmcsIHdlIHJlYWQgZnJvbSBhbGwgZ2VuZXJhdGlvbiBmaWxlcyB0aGF0IGV4aXN0LCBpbiBjYXNlIHNvbWUgYXJlIGNvcnJ1cHRlZFxuLy8gICAgICAtIE9uIGxvYWQsIGxvYWRzIGluIGFsbCB0cmFuc2FjdGlvbiBsb2dzLCBhbmQgc3RvcmVzIGFsbCB2YWx1ZXMgaW4gYSBNYXA8c3RyaW5nLCBCdWZmZXI+XG4vLyAgICAgIC0gT24gd3JpdGVzIGltbWVkaWF0ZWx5IHVwZGF0ZXMgdGhlIGluIG1lbW9yeSBNYXAsIGFuZCB0aGVuIHdyaXRlcyB0byB0aGUgdHJhbnNhY3Rpb24gbG9nXG4vLyAgICAgIC0gQ2FjaGVzIHRoZSBsYXN0IHRyYW5zYWN0aW9uIGZpbGUgbmFtZSBpbiBtZW1vcnlcbi8vICAgICAgLSBNYWtlcyBzdXJlIGFsbCBmaWxlIHN5c3RlbSB3cml0ZXMgKGJ1dCBub3QgTWFwIHVwZGF0ZXMpIGFyZSBkb25lIHdpdGggZmlsZUxvY2tTZWN0aW9uLFxuLy8gICAgICAgICAgc28gdGhleSBuZXZlciBvdmVybGFwLlxuLy8gICAgICAtIEJ1ZmZlcnMgcGVuZGluZyBhcHBlbmRzIGluIG1lbW9yeSwgc28gdGhleSBjYW4gd3JpdHRlbiBhbGwgYXQgb25jZSAoYWZ0ZXIgdGhlIGZpcnN0IG9uZVxuLy8gICAgICAgICAgaXMgYmxvY2tpbmcgaW4gZmlsZUxvY2tTZWN0aW9uKS5cblxuVVBEQVRFIG5vdyB3ZSB1c2UgY2h1bmtzLCBiZWNhdXNlIGFwcGVuZCBpcyB0b28gc2xvdy5cblxuSU1QT1JUQU5UISBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgd3JpdGVycywgd2UgY2xvYmJlciB3cml0ZXMgZnJvbSBvdGhlciB3cml0ZXJzIHdoZW4gd2UgY29tcHJlc3NcbiovXG5cblxuY29uc3QgRklMRV9DSFVOS19TSVpFID0gMTAyNCAqIDEwMjQ7XG5cbmNvbnN0IEZJTEVfWklQX1RIUkVTSE9MRCA9IDE2ICogMTAyNCAqIDEwMjQ7XG5cbmNvbnN0IFpJUF9USFJFU0hPTEQgPSA0MDk2O1xuY29uc3QgU1RBUlRfQllURVMgPSBCdWZmZXIuZnJvbShbMjM2LCA0OSwgMTEyLCAxMjEsIDI3LCAxMjcsIDIyNywgNjNdKTtcbmNvbnN0IEVORF9CWVRFUyA9IEJ1ZmZlci5mcm9tKFsyMjAsIDExMSwgMjQzLCAyMDIsIDIwMCwgNzksIDIxMywgNjNdKTtcbi8vIERlbGF5IHdyaXRlcywgc28gd2UgYmF0Y2ggYmV0dGVyLCBhbmQgdGhyYXNoIHRoZSBkaXNrIGxlc3NcbmNvbnN0IFdSSVRFX0RFTEFZID0gNTAwO1xuXG5pbnRlcmZhY2UgVHJhbnNhY3Rpb25FbnRyeSB7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgdmFsdWU6IEJ1ZmZlciB8IHVuZGVmaW5lZDtcbiAgICBpc1ppcHBlZDogYm9vbGVhbjtcbiAgICB0aW1lOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBUcmFuc2FjdGlvbkhlYWRlciB7XG4gICAgemlwcGVkOiBib29sZWFuO1xufVxuXG5jb25zdCBmaWxlTG9ja1NlY3Rpb24gPSBydW5JblNlcmlhbChhc3luYyAoZm5jOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSA9PiB7XG4gICAgYXdhaXQgZm5jKCk7XG59KTtcblxuY29uc3QgQ0hVTktfRVhUID0gXCIuY2h1bmtcIjtcbmNvbnN0IG91cklkID0gRGF0ZS5ub3coKSArIE1hdGgucmFuZG9tKCk7XG5cbmV4cG9ydCBjbGFzcyBUcmFuc2FjdGlvblN0b3JhZ2UgaW1wbGVtZW50cyBJU3RvcmFnZTxCdWZmZXI+IHtcbiAgICBwdWJsaWMgY2FjaGU6IE1hcDxzdHJpbmcsIFRyYW5zYWN0aW9uRW50cnk+ID0gbmV3IE1hcCgpO1xuICAgIHByaXZhdGUgY3VycmVudENodW5rID0gMDtcbiAgICBwcml2YXRlIGN1cnJlbnRDaHVua1NpemUgPSAwO1xuICAgIHByaXZhdGUgZW50cnlDb3VudCA9IDA7XG5cbiAgICBwcml2YXRlIHN0YXRpYyBhbGxTdG9yYWdlOiBUcmFuc2FjdGlvblN0b3JhZ2VbXSA9IFtdO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmF3U3RvcmFnZTogSVN0b3JhZ2VSYXcsXG4gICAgICAgIHByaXZhdGUgZGVidWdOYW1lOiBzdHJpbmcsXG4gICAgICAgIHByaXZhdGUgd3JpdGVEZWxheSA9IFdSSVRFX0RFTEFZXG4gICAgKSB7XG4gICAgICAgIFRyYW5zYWN0aW9uU3RvcmFnZS5hbGxTdG9yYWdlLnB1c2godGhpcyk7XG4gICAgfVxuICAgIC8vIEhlbHBzIGdldCByaWQgb2YgcGFyc2UgZXJyb3JzIHdoaWNoIGNvbnN0YW50bHkgbG9nLiBBbHNvLCB1c2VzIGxlc3Mgc3BhY2VcbiAgICBwdWJsaWMgc3RhdGljIGFzeW5jIGNvbXByZXNzQWxsKCkge1xuICAgICAgICBmb3IgKGxldCBzdG9yYWdlIG9mIFRyYW5zYWN0aW9uU3RvcmFnZS5hbGxTdG9yYWdlKSB7XG4gICAgICAgICAgICBhd2FpdCBzdG9yYWdlLmNvbXByZXNzVHJhbnNhY3Rpb25Mb2codHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXQ6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQgPSB0aGlzLmxvYWRBbGxUcmFuc2FjdGlvbnMoKTtcblxuICAgIHByaXZhdGUgZ2V0Q2h1bmsoY2h1bms6IG51bWJlcikgeyByZXR1cm4gYCR7Y2h1bmt9XyR7b3VySWR9JHtDSFVOS19FWFR9YDsgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdDtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgICAgICBpZiAodmFsdWUgJiYgdmFsdWUuaXNaaXBwZWQgJiYgdmFsdWUudmFsdWUpIHtcbiAgICAgICAgICAgIHZhbHVlLnZhbHVlID0gYXdhaXQgWmlwLmd1bnppcCh2YWx1ZS52YWx1ZSk7XG4gICAgICAgICAgICB2YWx1ZS5pc1ppcHBlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZT8udmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldChrZXk6IHN0cmluZywgdmFsdWU6IEJ1ZmZlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5pbml0KSBhd2FpdCB0aGlzLmluaXQ7XG5cbiAgICAgICAgLy8gVGltZSBpcyBzZXQgb24gZGlzayB3cml0ZSwgYXMgRGF0ZS5ub3coKSBpcyB0b28gc2xvd1xuICAgICAgICBsZXQgZW50cnk6IFRyYW5zYWN0aW9uRW50cnkgPSB7IGtleSwgdmFsdWUsIGlzWmlwcGVkOiBmYWxzZSwgdGltZTogMCB9O1xuICAgICAgICB0aGlzLmNhY2hlLnNldChrZXksIGVudHJ5KTtcblxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoID49IFpJUF9USFJFU0hPTEQpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYXdhaXQgWmlwLmd6aXAodmFsdWUpO1xuICAgICAgICAgICAgZW50cnkudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgIGVudHJ5LmlzWmlwcGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLnB1c2hBcHBlbmQoZW50cnkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZW1vdmUoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMuaW5pdCkgYXdhaXQgdGhpcy5pbml0O1xuICAgICAgICB0aGlzLmNhY2hlLmRlbGV0ZShrZXkpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMucHVzaEFwcGVuZCh7IGtleSwgdmFsdWU6IHVuZGVmaW5lZCwgaXNaaXBwZWQ6IGZhbHNlLCB0aW1lOiAwIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRJbmZvKGtleTogc3RyaW5nKTogUHJvbWlzZTx7IHNpemU6IG51bWJlcjsgbGFzdE1vZGlmaWVkOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmluaXQ7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5jYWNoZS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKCF2YWx1ZT8udmFsdWUpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7IHNpemU6IHZhbHVlLnZhbHVlLmxlbmd0aCwgbGFzdE1vZGlmaWVkOiB2YWx1ZS50aW1lIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwZW5kaW5nQXBwZW5kczogVHJhbnNhY3Rpb25FbnRyeVtdID0gW107XG4gICAgcHJpdmF0ZSBleHRyYUFwcGVuZHMgPSAwO1xuICAgIHByaXZhdGUgcGVuZGluZ1dyaXRlOiBQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkO1xuICAgIGFzeW5jIHB1c2hBcHBlbmQoZW50cnk6IFRyYW5zYWN0aW9uRW50cnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5lbnRyeUNvdW50Kys7XG4gICAgICAgIHRoaXMucGVuZGluZ0FwcGVuZHMucHVzaChlbnRyeSk7XG4gICAgICAgIHZvaWQgdGhpcy51cGRhdGVQZW5kaW5nQXBwZW5kcygpO1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nV3JpdGUpIHJldHVybiB0aGlzLnBlbmRpbmdXcml0ZTtcbiAgICAgICAgdGhpcy5wZW5kaW5nV3JpdGUgPSBmaWxlTG9ja1NlY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gRGVsYXkgdG8gYWxsb3cgYmF0Y2hpbmcsIGFuZCBkZWR1cGluZ1xuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIHRoaXMud3JpdGVEZWxheSkpO1xuICAgICAgICAgICAgbGV0IGN1ckFwcGVuZHMgPSB0aGlzLnBlbmRpbmdBcHBlbmRzO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nQXBwZW5kcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5wZW5kaW5nV3JpdGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGV0IGFwcGVuZHNEZWR1cGVkOiBNYXA8c3RyaW5nLCBUcmFuc2FjdGlvbkVudHJ5PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGN1ckFwcGVuZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgYXBwZW5kc0RlZHVwZWQuc2V0KGVudHJ5LmtleSwgZW50cnkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjdXJBcHBlbmRzID0gQXJyYXkuZnJvbShhcHBlbmRzRGVkdXBlZC52YWx1ZXMoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmV4dHJhQXBwZW5kcyArPSBjdXJBcHBlbmRzLmxlbmd0aDtcbiAgICAgICAgICAgIHZvaWQgdGhpcy51cGRhdGVQZW5kaW5nQXBwZW5kcygpO1xuICAgICAgICAgICAgaWYgKGN1ckFwcGVuZHMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICAgICAgICB0cnkge1xuXG4gICAgICAgICAgICAgICAgbGV0IHRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGVudHJ5IG9mIGN1ckFwcGVuZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgZW50cnkudGltZSA9IHRpbWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IG5ld1N1bSA9IDA7XG4gICAgICAgICAgICAgICAgbGV0IGJ1ZmZlcnM6IEJ1ZmZlcltdID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBjdXJBcHBlbmRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBidWZmZXIgPSB0aGlzLnNlcmlhbGl6ZVRyYW5zYWN0aW9uRW50cnkoZW50cnkpO1xuICAgICAgICAgICAgICAgICAgICBidWZmZXJzLnB1c2goYnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgbmV3U3VtICs9IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IG5ld0NodW5rcyA9IHRoaXMuY2h1bmtCdWZmZXJzKGJ1ZmZlcnMpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGNodW5rIG9mIG5ld0NodW5rcykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZmlsZSA9IHRoaXMuZ2V0Q2h1bmsodGhpcy5jdXJyZW50Q2h1bmspO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWF3YWl0IHRoaXMucmF3U3RvcmFnZS5nZXQoZmlsZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB7IGhlYWRlciwgaGVhZGVyQnVmZmVyIH0gPSB0aGlzLmdldEhlYWRlcihmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJhd1N0b3JhZ2Uuc2V0KGZpbGUsIGhlYWRlckJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRlbnQgPSBjaHVuay5idWZmZXI7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmF3U3RvcmFnZS5hcHBlbmQoZmlsZSwgY29udGVudCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudENodW5rU2l6ZSArPSBjb250ZW50Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudENodW5rU2l6ZSA+PSBGSUxFX0NIVU5LX1NJWkUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudENodW5rKys7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDaHVua1NpemUgPSAwO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jb21wcmVzc1RyYW5zYWN0aW9uTG9nKCk7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXh0cmFBcHBlbmRzIC09IGN1ckFwcGVuZHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHZvaWQgdGhpcy51cGRhdGVQZW5kaW5nQXBwZW5kcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nV3JpdGU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVQZW5kaW5nQXBwZW5kcyA9IHRocm90dGxlRnVuY3Rpb24oMTAwLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGxldCBhcHBlbmRDb3VudCA9IHRoaXMucGVuZGluZ0FwcGVuZHMubGVuZ3RoICsgdGhpcy5leHRyYUFwcGVuZHM7XG4gICAgICAgIGxldCBncm91cCA9IGBUcmFuc2FjdGlvbiAoJHt0aGlzLmRlYnVnTmFtZX0pYDtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhgVXBkYXRlIHBlbmRpbmcgYXBwZW5kcyAke2dyb3VwfTogJHthcHBlbmRDb3VudH1gKTtcbiAgICAgICAgaWYgKCFhcHBlbmRDb3VudCkge1xuICAgICAgICAgICAgc2V0UGVuZGluZyhncm91cCwgXCJcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc2V0UGVuZGluZyhncm91cCwgYFBlbmRpbmcgYXBwZW5kczogJHthcHBlbmRDb3VudH1gKTtcbiAgICB9KTtcblxuICAgIHB1YmxpYyBhc3luYyBnZXRLZXlzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgICAgaWYgKHRoaXMuaW5pdCkgYXdhaXQgdGhpcy5pbml0O1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmNhY2hlLmtleXMoKSk7XG4gICAgfVxuXG5cbiAgICBwcml2YXRlIGFzeW5jIGxvYWRBbGxUcmFuc2FjdGlvbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChpc0luQnVpbGQoKSkgcmV0dXJuO1xuICAgICAgICBsZXQgdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCB0aGlzLnJhd1N0b3JhZ2UuZ2V0S2V5cygpO1xuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbkZpbGVzID0ga2V5cy5maWx0ZXIoa2V5ID0+IGtleS5lbmRzV2l0aChDSFVOS19FWFQpKTtcblxuICAgICAgICBzb3J0KHRyYW5zYWN0aW9uRmlsZXMsIHggPT4gcGFyc2VJbnQoeCkpO1xuXG4gICAgICAgIGxldCBzaXplID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIHRyYW5zYWN0aW9uRmlsZXMpIHtcbiAgICAgICAgICAgIGxldCBjaHVuayA9IHBhcnNlSW50KGZpbGUpO1xuICAgICAgICAgICAgbGV0IGN1clNpemUgPSBhd2FpdCB0aGlzLmxvYWRUcmFuc2FjdGlvbkZpbGUoZmlsZSk7XG4gICAgICAgICAgICBpZiAoY2h1bmsgPj0gdGhpcy5jdXJyZW50Q2h1bmspIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDaHVuayA9IGNodW5rO1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudENodW5rU2l6ZSA9IGN1clNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaXplICs9IGN1clNpemU7XG4gICAgICAgIH1cbiAgICAgICAgdGltZSA9IERhdGUubm93KCkgLSB0aW1lO1xuICAgICAgICBpZiAodGltZSA+IDUwKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgTG9hZGVkICR7dGhpcy5kZWJ1Z05hbWV9IGluICR7Zm9ybWF0VGltZSh0aW1lKX0sICR7Zm9ybWF0TnVtYmVyKHRoaXMuY2FjaGUuc2l6ZSl9IGtleXMsICR7Zm9ybWF0TnVtYmVyKHNpemUpfUJgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaW5pdCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGxvYWRUcmFuc2FjdGlvbkZpbGUoZmlsZW5hbWU6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgICAgIGNvbnN0IGZ1bGxGaWxlID0gYXdhaXQgdGhpcy5yYXdTdG9yYWdlLmdldChmaWxlbmFtZSk7XG4gICAgICAgIGlmICghZnVsbEZpbGUpIHJldHVybiAwO1xuICAgICAgICBpZiAoZnVsbEZpbGUubGVuZ3RoIDwgNCkge1xuICAgICAgICAgICAgLy9jb25zb2xlLmVycm9yKGBUcmFuc2FjdGlvbiBpbiAke3RoaXMuZGVidWdOYW1lfSBmaWxlICR7ZmlsZW5hbWV9IGlzIHRvbyBzbWFsbCwgc2tpcHBpbmdgKTtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGxldCBoZWFkZXJTaXplID0gZnVsbEZpbGUucmVhZFVJbnQzMkxFKDApO1xuICAgICAgICBsZXQgaGVhZGVyQnVmZmVyID0gZnVsbEZpbGUuc2xpY2UoNCwgNCArIGhlYWRlclNpemUpO1xuICAgICAgICBsZXQgaGVhZGVyOiBUcmFuc2FjdGlvbkhlYWRlcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGhlYWRlciA9IEpTT04ucGFyc2UoaGVhZGVyQnVmZmVyLnRvU3RyaW5nKCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcGFyc2UgaGVhZGVyIG9mIHRyYW5zYWN0aW9uIGZpbGUgaW4gJHt0aGlzLmRlYnVnTmFtZX0sICR7ZmlsZW5hbWV9YCk7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudCA9IGZ1bGxGaWxlLnNsaWNlKDQgKyBoZWFkZXJTaXplKTtcbiAgICAgICAgaWYgKGhlYWRlci56aXBwZWQpIHtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBhd2FpdCBaaXAuZ3VuemlwKGNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICAgIGxldCBlbnRyaWVzOiBUcmFuc2FjdGlvbkVudHJ5W10gPSBbXTtcbiAgICAgICAgd2hpbGUgKG9mZnNldCA8IGNvbnRlbnQubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIWNvbnRlbnQuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBTVEFSVF9CWVRFUy5sZW5ndGgpLmVxdWFscyhTVEFSVF9CWVRFUykpIHtcbiAgICAgICAgICAgICAgICBsZXQgcyA9IG9mZnNldDtcbiAgICAgICAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgY29udGVudC5sZW5ndGggJiYgIWNvbnRlbnQuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBTVEFSVF9CWVRFUy5sZW5ndGgpLmVxdWFscyhTVEFSVF9CWVRFUykpIHtcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0Kys7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBsZW4gPSBvZmZzZXQgLSBzO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgRm91bmQgYmFkIGJ5dGVzIGluICR7ZmlsZW5hbWV9LCBza2lwcGluZyAke2xlbn0gYnl0ZXMgYXQgb2Zmc2V0ICR7c30uIFRvdGFsIGZpbGUgYnl0ZXMgJHtjb250ZW50Lmxlbmd0aH0sIHJlYWQgJHtlbnRyaWVzLmxlbmd0aH0gZW50cmllc2ApO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPj0gY29udGVudC5sZW5ndGgpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGVudHJ5T2JqOiB7IGVudHJ5OiBUcmFuc2FjdGlvbkVudHJ5LCBvZmZzZXQ6IG51bWJlciB9IHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBlbnRyeU9iaiA9IHRoaXMucmVhZFRyYW5zYWN0aW9uRW50cnkoY29udGVudCwgb2Zmc2V0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICAgIGlmIChlLm1lc3NhZ2UuaW5jbHVkZXMoXCJSZWFkIHBhc3QgZW5kIG9mIGJ1ZmZlclwiKSkge1xuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWVudHJ5T2JqKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBGYWlsZWQgdG8gcmVhZCB0cmFuc2FjdGlvbiBlbnRyeSBpbiBpbiAke3RoaXMuZGVidWdOYW1lfSwgZmlsZSAke2ZpbGVuYW1lfSBhdCBvZmZzZXQgJHtvZmZzZXR9LCBza2lwcGluZyBiYWQgYnl0ZXMsIHJlYWRpbmcgcmVtYWluZGVyIG9mIGZpbGVgKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQrKztcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZW50cnlDb3VudCsrO1xuICAgICAgICAgICAgbGV0IHsgZW50cnkgfSA9IGVudHJ5T2JqO1xuICAgICAgICAgICAgb2Zmc2V0ID0gZW50cnlPYmoub2Zmc2V0O1xuICAgICAgICAgICAgZW50cmllcy5wdXNoKGVudHJ5KTtcblxuICAgICAgICAgICAgaWYgKGVudHJ5LnZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlLmRlbGV0ZShlbnRyeS5rZXkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJldiA9IHRoaXMuY2FjaGUuZ2V0KGVudHJ5LmtleSk7XG4gICAgICAgICAgICAgICAgaWYgKHByZXYgJiYgKHByZXYudGltZSA+IGVudHJ5LnRpbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlLnNldChlbnRyeS5rZXksIGVudHJ5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVsbEZpbGUubGVuZ3RoO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVhZFRyYW5zYWN0aW9uRW50cnkoYnVmZmVyOiBCdWZmZXIsIG9mZnNldDogbnVtYmVyKToge1xuICAgICAgICBlbnRyeTogVHJhbnNhY3Rpb25FbnRyeTtcbiAgICAgICAgb2Zmc2V0OiBudW1iZXI7XG4gICAgfSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGZ1bmN0aW9uIHJlYWRTbGljZShjb3VudDogbnVtYmVyKSB7XG4gICAgICAgICAgICBjb25zdCBzbGljZSA9IGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGNvdW50KTtcbiAgICAgICAgICAgIGlmIChzbGljZS5sZW5ndGggPCBjb3VudCkgdGhyb3cgbmV3IEVycm9yKGBSZWFkIHBhc3QgZW5kIG9mIGJ1ZmZlciBhdCBvZmZzZXQgJHtvZmZzZXR9LyR7YnVmZmVyLmxlbmd0aH1gKTtcbiAgICAgICAgICAgIG9mZnNldCArPSBjb3VudDtcbiAgICAgICAgICAgIHJldHVybiBzbGljZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXJlYWRTbGljZShTVEFSVF9CWVRFUy5sZW5ndGgpLmVxdWFscyhTVEFSVF9CWVRFUykpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgY29uc3Qga2V5TGVuZ3RoID0gcmVhZFNsaWNlKDQpLnJlYWRVSW50MzJMRSgwKTtcbiAgICAgICAgY29uc3QgdmFsdWVMZW5ndGggPSByZWFkU2xpY2UoNCkucmVhZFVJbnQzMkxFKDApO1xuICAgICAgICBjb25zdCB0aW1lID0gcmVhZFNsaWNlKDgpLnJlYWREb3VibGVMRSgwKTtcbiAgICAgICAgY29uc3QgZmxhZ3MgPSByZWFkU2xpY2UoMSkucmVhZFVJbnQ4KDApO1xuXG4gICAgICAgIGNvbnN0IGtleSA9IHJlYWRTbGljZShrZXlMZW5ndGgpLnRvU3RyaW5nKCk7XG4gICAgICAgIGxldCB2YWx1ZSA9IHJlYWRTbGljZSh2YWx1ZUxlbmd0aCk7XG5cbiAgICAgICAgaWYgKCFyZWFkU2xpY2UoRU5EX0JZVEVTLmxlbmd0aCkuZXF1YWxzKEVORF9CWVRFUykpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICAgICAgbGV0IGlzWmlwcGVkID0gKGZsYWdzICYgMSkgPT09IDE7XG4gICAgICAgIGxldCBpc0RlbGV0ZSA9IChmbGFncyAmIDIpID09PSAyO1xuXG4gICAgICAgIGxldCBlbnRyeTogVHJhbnNhY3Rpb25FbnRyeSA9IHsga2V5LCB2YWx1ZSwgaXNaaXBwZWQsIHRpbWUgfTtcbiAgICAgICAgaWYgKGlzRGVsZXRlKSB7XG4gICAgICAgICAgICBlbnRyeS52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBlbnRyeSwgb2Zmc2V0IH07XG4gICAgfVxuXG4gICAgLy8gVE9ETzogTWFrZSB0aGlzIGRpcmVjdGx5IGdvIGZyb20gVHJhbnNhY3Rpb25FbnRyeVtdIHRvIEJ1ZmZlciwgYnkgcHJlLWFsbG9jYXRpbmcsIHNvIGl0IGlzIG1vcmUgZWZmaWNpZW50XG4gICAgcHJpdmF0ZSBzZXJpYWxpemVUcmFuc2FjdGlvbkVudHJ5KGVudHJ5OiBUcmFuc2FjdGlvbkVudHJ5KTogQnVmZmVyIHtcbiAgICAgICAgbGV0IGtleUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGVudHJ5LmtleSk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhcbiAgICAgICAgICAgIFNUQVJUX0JZVEVTLmxlbmd0aCArIDQgKyA0ICsgOCArIDEgKyBrZXlCdWZmZXIubGVuZ3RoICsgKGVudHJ5LnZhbHVlPy5sZW5ndGggfHwgMCkgKyBFTkRfQllURVMubGVuZ3RoXG4gICAgICAgICk7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwO1xuXG4gICAgICAgIFNUQVJUX0JZVEVTLmNvcHkoYnVmZmVyLCBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgKz0gU1RBUlRfQllURVMubGVuZ3RoO1xuXG4gICAgICAgIGJ1ZmZlci53cml0ZVVJbnQzMkxFKGtleUJ1ZmZlci5sZW5ndGgsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSA0O1xuXG4gICAgICAgIGJ1ZmZlci53cml0ZVVJbnQzMkxFKGVudHJ5LnZhbHVlID8gZW50cnkudmFsdWUubGVuZ3RoIDogMCwgb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IDQ7XG5cbiAgICAgICAgYnVmZmVyLndyaXRlRG91YmxlTEUoZW50cnkudGltZSwgb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IDg7XG5cbiAgICAgICAgbGV0IGZsYWdzID0gMDtcbiAgICAgICAgaWYgKGVudHJ5LmlzWmlwcGVkKSBmbGFncyB8PSAxO1xuICAgICAgICBpZiAoZW50cnkudmFsdWUgPT09IHVuZGVmaW5lZCkgZmxhZ3MgfD0gMjtcbiAgICAgICAgYnVmZmVyLndyaXRlVUludDgoZmxhZ3MsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSAxO1xuXG4gICAgICAgIGtleUJ1ZmZlci5jb3B5KGJ1ZmZlciwgb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IGtleUJ1ZmZlci5sZW5ndGg7XG5cbiAgICAgICAgaWYgKGVudHJ5LnZhbHVlKSB7XG4gICAgICAgICAgICBlbnRyeS52YWx1ZS5jb3B5KGJ1ZmZlciwgb2Zmc2V0KTtcbiAgICAgICAgICAgIG9mZnNldCArPSBlbnRyeS52YWx1ZS5sZW5ndGg7XG4gICAgICAgIH1cblxuICAgICAgICBFTkRfQllURVMuY29weShidWZmZXIsIG9mZnNldCk7XG4gICAgICAgIG9mZnNldCArPSBFTkRfQllURVMubGVuZ3RoO1xuXG4gICAgICAgIHJldHVybiBidWZmZXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRIZWFkZXIoemlwOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IGhlYWRlcjogVHJhbnNhY3Rpb25IZWFkZXIgPSB7IHppcHBlZDogemlwIH07XG4gICAgICAgIGxldCBoZWFkZXJCdWZmZXIgPSBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShoZWFkZXIpKTtcbiAgICAgICAgbGV0IGhlYWRlclNpemUgPSBCdWZmZXIuYWxsb2MoNCk7XG4gICAgICAgIGhlYWRlclNpemUud3JpdGVVSW50MzJMRShoZWFkZXJCdWZmZXIubGVuZ3RoLCAwKTtcbiAgICAgICAgcmV0dXJuIHsgaGVhZGVyLCBoZWFkZXJCdWZmZXI6IEJ1ZmZlci5jb25jYXQoW2hlYWRlclNpemUsIGhlYWRlckJ1ZmZlcl0pIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaHVua0J1ZmZlcnMoYnVmZmVyczogQnVmZmVyW10pIHtcbiAgICAgICAgbGV0IG5ld0NodW5rczoge1xuICAgICAgICAgICAgYnVmZmVyczogQnVmZmVyW107XG4gICAgICAgICAgICBzaXplOiBudW1iZXI7XG4gICAgICAgIH1bXSA9IFtdO1xuICAgICAgICBuZXdDaHVua3MucHVzaCh7IGJ1ZmZlcnM6IFtdLCBzaXplOiAwIH0pO1xuICAgICAgICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiBidWZmZXJzKSB7XG4gICAgICAgICAgICBpZiAobmV3Q2h1bmtzW25ld0NodW5rcy5sZW5ndGggLSAxXS5zaXplICsgYnVmZmVyLmxlbmd0aCA+PSBGSUxFX0NIVU5LX1NJWkUpIHtcbiAgICAgICAgICAgICAgICBuZXdDaHVua3MucHVzaCh7IGJ1ZmZlcnM6IFtdLCBzaXplOiAwIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV3Q2h1bmtzW25ld0NodW5rcy5sZW5ndGggLSAxXS5idWZmZXJzLnB1c2goYnVmZmVyKTtcbiAgICAgICAgICAgIG5ld0NodW5rc1tuZXdDaHVua3MubGVuZ3RoIC0gMV0uc2l6ZSArPSBidWZmZXIubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdDaHVua3MubWFwKHggPT4gKHsgYnVmZmVyOiBCdWZmZXIuY29uY2F0KHguYnVmZmVycyksIHNpemU6IHguc2l6ZSB9KSk7XG4gICAgfVxuXG5cbiAgICBwcml2YXRlIGNvbXByZXNzaW5nID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBhc3luYyBjb21wcmVzc1RyYW5zYWN0aW9uTG9nKGZvcmNlPzogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAodGhpcy5jb21wcmVzc2luZykgcmV0dXJuO1xuICAgICAgICB0aGlzLmNvbXByZXNzaW5nID0gdHJ1ZTtcblxuICAgICAgICBsZXQgZXhpc3RpbmdEaXNrRW50cmllcyA9IGF3YWl0IHRoaXMucmF3U3RvcmFnZS5nZXRLZXlzKCk7XG4gICAgICAgIGV4aXN0aW5nRGlza0VudHJpZXMgPSBleGlzdGluZ0Rpc2tFbnRyaWVzLmZpbHRlcih4ID0+IHguZW5kc1dpdGgoQ0hVTktfRVhUKSk7XG4gICAgICAgIGxldCBjb21wcmVzc05vdyA9IGZvcmNlIHx8IChcbiAgICAgICAgICAgIHRoaXMuZW50cnlDb3VudCA+IDEwMCAmJiB0aGlzLmVudHJ5Q291bnQgPiB0aGlzLmNhY2hlLnNpemUgKiAzXG4gICAgICAgICAgICAvLyBOT1RFOiBUaGlzIGNvbXByZXNzIGNoZWNrIGJyZWFrcyBkb3duIGlmIHdlIG9ubHkgaGF2ZSB2ZXJ5IGxhcmdlIHZhbHVlcywgYnV0Li4uIHRob3NlXG4gICAgICAgICAgICAvLyAgZG9uJ3Qgd29yayBBTllXQVlTIChpdCBpcyBiZXR0ZXIgdG8gdXNlIG9uZSBmaWxlIHBlciB2YWx1ZSBpbnN0ZWFkKS5cbiAgICAgICAgICAgIC8vICAtIE1heWJlIHdlIHNob3VsZCB0aHJvdywgb3IgYXQgbGVhc3Qgd2Fybiwgb24gc2V0cyBvZiB2YWx1ZSA+IDFNQixcbiAgICAgICAgICAgIC8vICAgICAgYXQgd2hpY2ggcG9pbnQgdGhleSBzaG91bGQganVzdCB1c2UgYSBmaWxlIHBlciB2YWx1ZVxuICAgICAgICAgICAgfHwgZXhpc3RpbmdEaXNrRW50cmllcy5sZW5ndGggPiBNYXRoLm1heCgxMCwgTWF0aC5jZWlsKHRoaXMuZW50cnlDb3VudCAvIDEwMDApKVxuICAgICAgICAgICAgfHwgZXhpc3RpbmdEaXNrRW50cmllcy5sZW5ndGggPiAxMDAwICogMTBcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFjb21wcmVzc05vdykgcmV0dXJuO1xuICAgICAgICBjb25zb2xlLmxvZyhgQ29tcHJlc3NpbmcgJHt0aGlzLmRlYnVnTmFtZX0gdHJhbnNhY3Rpb24gbG9nLCAke3RoaXMuZW50cnlDb3VudH0gZW50cmllcywgJHt0aGlzLmNhY2hlLnNpemV9IGtleXNgKTtcblxuICAgICAgICAvLyBMb2FkIG9mZiBkaXNrLCBpbiBjYXNlIHRoZXJlIGFyZSBvdGhlciB3cml0ZXMuIFdlIHN0aWxsIHJhY2Ugd2l0aCB0aGVtLCBidXQgYXQgbGVhc3RcbiAgICAgICAgLy8gIHRoaXMgcmVkdWNlcyB0aGUgcmFjZSBjb25kaXRpb24gY29uc2lkZXJhYmx5XG5cbiAgICAgICAgc29ydChleGlzdGluZ0Rpc2tFbnRyaWVzLCB4ID0+IHBhcnNlSW50KHgpKTtcbiAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgZXhpc3RpbmdEaXNrRW50cmllcykge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5sb2FkVHJhbnNhY3Rpb25GaWxlKGVudHJ5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZW50cnlDb3VudCA9IHRoaXMuY2FjaGUuc2l6ZTtcblxuICAgICAgICBsZXQgbmV4dFN0YXJ0ID0gTWF0aC5tYXgoLi4uZXhpc3RpbmdEaXNrRW50cmllcy5tYXAoeCA9PiBwYXJzZUludCh4KSkpICsgMTtcblxuICAgICAgICBsZXQgYnVmZmVyczogQnVmZmVyW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLmNhY2hlLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBsZXQgYnVmZmVyID0gdGhpcy5zZXJpYWxpemVUcmFuc2FjdGlvbkVudHJ5KGVudHJ5KTtcbiAgICAgICAgICAgIGJ1ZmZlcnMucHVzaChidWZmZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG5ld0NodW5rcyA9IHRoaXMuY2h1bmtCdWZmZXJzKGJ1ZmZlcnMpO1xuXG4gICAgICAgIGxldCBjdXJDaHVuayA9IG5leHRTdGFydDtcbiAgICAgICAgZm9yIChsZXQgY2h1bmsgb2YgbmV3Q2h1bmtzKSB7XG4gICAgICAgICAgICBsZXQgZmlsZSA9IHRoaXMuZ2V0Q2h1bmsoY3VyQ2h1bmsrKyk7XG4gICAgICAgICAgICBsZXQgY29udGVudCA9IGNodW5rLmJ1ZmZlcjtcbiAgICAgICAgICAgIGxldCB7IGhlYWRlciwgaGVhZGVyQnVmZmVyIH0gPSB0aGlzLmdldEhlYWRlcihcbiAgICAgICAgICAgICAgICAvLyBBTkQsIG5ldmVyIGNvbXByZXNzIHRoZSBsYXN0IG9uZSwgb3RoZXJ3aXNlIHdlIGNhbid0IGFwcGVuZCB0byBpdCFcbiAgICAgICAgICAgICAgICBjb250ZW50Lmxlbmd0aCA+PSBGSUxFX1pJUF9USFJFU0hPTEQgJiYgY2h1bmsgIT09IG5ld0NodW5rc1tuZXdDaHVua3MubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoaGVhZGVyLnppcHBlZCkge1xuICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBhd2FpdCBaaXAuZ3ppcChjb250ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBidWZmZXIgPSBCdWZmZXIuY29uY2F0KFtoZWFkZXJCdWZmZXIsIGNvbnRlbnRdKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmF3U3RvcmFnZS5zZXQoZmlsZSwgYnVmZmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoaXMgaXMgdGhlIE9OTFkgdGltZSB3ZSBjYW4gZGVsZXRlIG9sZCBmaWxlcywgYXMgd2Uga25vdyBmb3Igc3VyZSB0aGUgbmV3IGZpbGUgaGFzIGFsbCBvZiBvdXIgZGF0YS5cbiAgICAgICAgLy8gIEFueSBmdXR1cmUgcmVhZGVycyB3b24ndCBrbm93IHRoaXMsIHVubGVzcyB0aGV5IHdyaXRlIGl0IHRoZW1zZWx2ZXMgKG9yIHVubGVzcyB0aGV5IGF1ZGl0IGl0IGFnYWluc3RcbiAgICAgICAgLy8gICAgICB0aGUgb3RoZXIgZ2VuZXJhdGlvbnMsIHdoaWNoIGlzIGFubm95aW5nKS5cbiAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGV4aXN0aW5nRGlza0VudHJpZXMpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmF3U3RvcmFnZS5yZW1vdmUoZmlsZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmN1cnJlbnRDaHVuayA9IGN1ckNodW5rO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZXNldCgpIHtcbiAgICAgICAgYXdhaXQgZmlsZUxvY2tTZWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGxldCBleGlzdGluZ0Rpc2tFbnRyaWVzID0gYXdhaXQgdGhpcy5yYXdTdG9yYWdlLmdldEtleXMoKTtcbiAgICAgICAgICAgIGV4aXN0aW5nRGlza0VudHJpZXMgPSBleGlzdGluZ0Rpc2tFbnRyaWVzLmZpbHRlcih4ID0+IHguZW5kc1dpdGgoQ0hVTktfRVhUKSk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGV4aXN0aW5nRGlza0VudHJpZXMubWFwKHggPT4gdGhpcy5yYXdTdG9yYWdlLnJlbW92ZSh4KSkpO1xuICAgICAgICAgICAgfSBjYXRjaCB7IH1cblxuICAgICAgICAgICAgdGhpcy5wZW5kaW5nQXBwZW5kcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5jYWNoZS5jbGVhcigpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2h1bmsgPSAwO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2h1bmtTaXplID0gMDtcbiAgICAgICAgICAgIHRoaXMuZW50cnlDb3VudCA9IDA7XG4gICAgICAgIH0pO1xuICAgIH1cbn0iXX0=
421
+ /* _JS_SOURCE_HASH = "d6b565522e0199b1511007a3ea7bb1eef1a46c338996c583da6090466f49bf59"; */
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
+ //exports.getFileSystemPointer = exports.deleteFileSystemPointer = exports.storeFileSystemPointer = void 0;
4
+ const caching_1 = require("socket-function/src/caching");
5
+ const misc_1 = require("socket-function/src/misc");
6
+ const objectStoreName = "fileSystemPointerDB";
7
+ const db = (0, caching_1.lazy)(async () => {
8
+ let db = indexedDB.open("fileSystemPointerDB_f298e962-bd8a-46b9-8098-25db633f4ed3", 1);
9
+ db.addEventListener("upgradeneeded", () => {
10
+ db.result.createObjectStore(objectStoreName, {});
11
+ });
12
+ await new Promise(resolve => db.addEventListener("success", resolve));
13
+ return db.result;
14
+ });
15
+ async function getTransaction() {
16
+ let database = await db();
17
+ if (!database)
18
+ return undefined;
19
+ return database.transaction(objectStoreName, "readwrite").objectStore(objectStoreName);
20
+ }
21
+ async function write(key, value) {
22
+ let transaction = await getTransaction();
23
+ if (!transaction)
24
+ return;
25
+ let req = transaction.put(value, key);
26
+ await new Promise((resolve, reject) => {
27
+ req.addEventListener("success", resolve);
28
+ req.addEventListener("error", reject);
29
+ });
30
+ }
31
+ async function read(key) {
32
+ let transaction = await getTransaction();
33
+ if (!transaction)
34
+ return;
35
+ let req = transaction.get(key);
36
+ await new Promise((resolve, reject) => {
37
+ req.addEventListener("success", resolve);
38
+ req.addEventListener("error", reject);
39
+ });
40
+ return req.result;
41
+ }
42
+ async function storeFileSystemPointer(config) {
43
+ await config.handle.requestPermission({ mode: config.mode });
44
+ let key = (0, misc_1.nextId)() + "_" + config.mode;
45
+ await write(key, config.handle);
46
+ return key;
47
+ }
48
+ exports.storeFileSystemPointer = storeFileSystemPointer;
49
+ async function deleteFileSystemPointer(pointer) {
50
+ let transaction = await getTransaction();
51
+ if (!transaction)
52
+ return;
53
+ let req = transaction.delete(pointer);
54
+ await new Promise((resolve, reject) => {
55
+ req.addEventListener("success", resolve);
56
+ req.addEventListener("error", reject);
57
+ });
58
+ }
59
+ exports.deleteFileSystemPointer = deleteFileSystemPointer;
60
+ async function getFileSystemPointer(config) {
61
+ const handle = await read(config.pointer);
62
+ if (!handle)
63
+ return;
64
+ let mode = config.pointer.split("_").at(-1);
65
+ return {
66
+ async onUserActivation(modeOverride) {
67
+ let testMode = await handle.queryPermission({ mode: mode });
68
+ if (testMode !== mode) {
69
+ await handle.requestPermission({ mode: modeOverride !== null && modeOverride !== void 0 ? modeOverride : mode });
70
+ }
71
+ return handle;
72
+ }
73
+ };
74
+ }
75
+ exports.getFileSystemPointer = getFileSystemPointer;
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZVN5c3RlbVBvaW50ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJmaWxlU3lzdGVtUG9pbnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5REFBbUQ7QUFDbkQsbURBQWtEO0FBRWxELE1BQU0sZUFBZSxHQUFHLHFCQUFxQixDQUFDO0FBQzlDLE1BQU0sRUFBRSxHQUFHLElBQUEsY0FBSSxFQUFDLEtBQUssSUFBSSxFQUFFO0lBQ3ZCLElBQUksRUFBRSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsMERBQTBELEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkYsRUFBRSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7UUFDdEMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7SUFDSCxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3RFLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQztBQUNyQixDQUFDLENBQUMsQ0FBQztBQUNILEtBQUssVUFBVSxjQUFjO0lBQ3pCLElBQUksUUFBUSxHQUFHLE1BQU0sRUFBRSxFQUFFLENBQUM7SUFDMUIsSUFBSSxDQUFDLFFBQVE7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNoQyxPQUFPLFFBQVEsQ0FBQyxXQUFXLENBQUMsZUFBZSxFQUFFLFdBQVcsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUMzRixDQUFDO0FBQ0QsS0FBSyxVQUFVLEtBQUssQ0FBQyxHQUFXLEVBQUUsS0FBdUQ7SUFDckYsSUFBSSxXQUFXLEdBQUcsTUFBTSxjQUFjLEVBQUUsQ0FBQztJQUN6QyxJQUFJLENBQUMsV0FBVztRQUFFLE9BQU87SUFDekIsSUFBSSxHQUFH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O0tBQ0osQ0FBQztBQUNOLENBQUM7QUF2QkQsb0RBdUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbGF6eSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2NhY2hpbmdcIjtcbmltcG9ydCB7IG5leHRJZCB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL21pc2NcIjtcblxuY29uc3Qgb2JqZWN0U3RvcmVOYW1lID0gXCJmaWxlU3lzdGVtUG9pbnRlckRCXCI7XG5jb25zdCBkYiA9IGxhenkoYXN5bmMgKCkgPT4ge1xuICAgIGxldCBkYiA9IGluZGV4ZWREQi5vcGVuKFwiZmlsZVN5c3RlbVBvaW50ZXJEQl9mMjk4ZTk2Mi1iZDhhLTQ2YjktODA5OC0yNWRiNjMzZjRlZDNcIiwgMSk7XG4gICAgZGIuYWRkRXZlbnRMaXN0ZW5lcihcInVwZ3JhZGVuZWVkZWRcIiwgKCkgPT4ge1xuICAgICAgICBkYi5yZXN1bHQuY3JlYXRlT2JqZWN0U3RvcmUob2JqZWN0U3RvcmVOYW1lLCB7fSk7XG4gICAgfSk7XG4gICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBkYi5hZGRFdmVudExpc3RlbmVyKFwic3VjY2Vzc1wiLCByZXNvbHZlKSk7XG4gICAgcmV0dXJuIGRiLnJlc3VsdDtcbn0pO1xuYXN5bmMgZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb24oKSB7XG4gICAgbGV0IGRhdGFiYXNlID0gYXdhaXQgZGIoKTtcbiAgICBpZiAoIWRhdGFiYXNlKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHJldHVybiBkYXRhYmFzZS50cmFuc2FjdGlvbihvYmplY3RTdG9yZU5hbWUsIFwicmVhZHdyaXRlXCIpLm9iamVjdFN0b3JlKG9iamVjdFN0b3JlTmFtZSk7XG59XG5hc3luYyBmdW5jdGlvbiB3cml0ZShrZXk6IHN0cmluZywgdmFsdWU6IEZpbGVTeXN0ZW1GaWxlSGFuZGxlIHwgRmlsZVN5c3RlbURpcmVjdG9yeUhhbmRsZSkge1xuICAgIGxldCB0cmFuc2FjdGlvbiA9IGF3YWl0IGdldFRyYW5zYWN0aW9uKCk7XG4gICAgaWYgKCF0cmFuc2FjdGlvbikgcmV0dXJuO1xuICAgIGxldCByZXEgPSB0cmFuc2FjdGlvbi5wdXQodmFsdWUsIGtleSk7XG4gICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICByZXEuYWRkRXZlbnRMaXN0ZW5lcihcInN1Y2Nlc3NcIiwgcmVzb2x2ZSk7XG4gICAgICAgIHJlcS5hZGRFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgICB9KTtcbn1cbmFzeW5jIGZ1bmN0aW9uIHJlYWQoa2V5OiBzdHJpbmcpOiBQcm9taXNlPEZpbGVTeXN0ZW1GaWxlSGFuZGxlIHwgRmlsZVN5c3RlbURpcmVjdG9yeUhhbmRsZSB8IHVuZGVmaW5lZD4ge1xuICAgIGxldCB0cmFuc2FjdGlvbiA9IGF3YWl0IGdldFRyYW5zYWN0aW9uKCk7XG4gICAgaWYgKCF0cmFuc2FjdGlvbikgcmV0dXJuO1xuICAgIGxldCByZXEgPSB0cmFuc2FjdGlvbi5nZXQoa2V5KTtcbiAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHJlcS5hZGRFdmVudExpc3RlbmVyKFwic3VjY2Vzc1wiLCByZXNvbHZlKTtcbiAgICAgICAgcmVxLmFkZEV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCByZWplY3QpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXEucmVzdWx0O1xufVxuXG5leHBvcnQgdHlwZSBGaWxlU3lzdGVtUG9pbnRlciA9IHN0cmluZztcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdG9yZUZpbGVTeXN0ZW1Qb2ludGVyKGNvbmZpZzoge1xuICAgIG1vZGU6IFwicmVhZFwiIHwgXCJyZWFkd3JpdGVcIjtcbiAgICBoYW5kbGU6IEZpbGVTeXN0ZW1GaWxlSGFuZGxlIHwgRmlsZVN5c3RlbURpcmVjdG9yeUhhbmRsZTtcbn0pOiBQcm9taXNlPEZpbGVTeXN0ZW1Qb2ludGVyPiB7XG4gICAgYXdhaXQgKGNvbmZpZy5oYW5kbGUgYXMgYW55KS5yZXF1ZXN0UGVybWlzc2lvbih7IG1vZGU6IGNvbmZpZy5tb2RlIH0pO1xuICAgIGxldCBrZXkgPSBuZXh0SWQoKSArIFwiX1wiICsgY29uZmlnLm1vZGU7XG4gICAgYXdhaXQgd3JpdGUoa2V5LCBjb25maWcuaGFuZGxlKTtcbiAgICByZXR1cm4ga2V5O1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlbGV0ZUZpbGVTeXN0ZW1Qb2ludGVyKHBvaW50ZXI6IEZpbGVTeXN0ZW1Qb2ludGVyKSB7XG4gICAgbGV0IHRyYW5zYWN0aW9uID0gYXdhaXQgZ2V0VHJhbnNhY3Rpb24oKTtcbiAgICBpZiAoIXRyYW5zYWN0aW9uKSByZXR1cm47XG4gICAgbGV0IHJlcSA9IHRyYW5zYWN0aW9uLmRlbGV0ZShwb2ludGVyKTtcbiAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHJlcS5hZGRFdmVudExpc3RlbmVyKFwic3VjY2Vzc1wiLCByZXNvbHZlKTtcbiAgICAgICAgcmVxLmFkZEV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLCByZWplY3QpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RmlsZVN5c3RlbVBvaW50ZXIoY29uZmlnOiB7XG4gICAgcG9pbnRlcjogRmlsZVN5c3RlbVBvaW50ZXI7XG59KTogUHJvbWlzZTx7XG4gICAgLy8gTk9URTogV2UgaGF2ZSB0byBjYWxsIHJlcXVlc3RQZXJtaXNzaW9uLCBzby4uLiB1c2VyIGFjdGl2YXRpb24gaXMgcmVxdWlyZWQgKGFzIGluLFxuICAgIC8vICB0aGlzIG5lZWQgdG8gYmUgY2FsbGVkIGluc2lkZSBvZiBhIGJ1dHRvbikuXG4gICAgLy8gSU1QT1JUQU5UISBJbiBzb21lIGNpcmN1bXN0YW5jZXMgdXNlciBhY3RpdmF0aW9uIGlzIG5vdCByZXF1aXJlZCAod2l0aCBtdWx0aXBsZSB0YWJzLFxuICAgIC8vICAgICAgYW5kIHBvdGVudGlhbGx5IHdpdGggaHR0cHM6Ly9kZXZlbG9wZXIuY2hyb21lLmNvbS9ibG9nL3BlcnNpc3RlbnQtcGVybWlzc2lvbnMtZm9yLXRoZS1maWxlLXN5c3RlbS1hY2Nlc3MtYXBpKSxcbiAgICAvLyAgICAgIHNvLi4uIHRyeWluZyB0byBjYWxsIG9uVXNlckFjdGl2YXRpb24gaW1tbWVkaWF0ZWx5IGlzIGEgZ29vZCBpZGVhIChhbHRob3VnaCBpdCBtaWdodCB0aHJvdykuXG4gICAgb25Vc2VyQWN0aXZhdGlvbihtb2RlT3ZlcnJpZGU/OiBcInJlYWRcIiB8IFwicmVhZHdyaXRlXCIpOiBQcm9taXNlPEZpbGVTeXN0ZW1GaWxlSGFuZGxlIHwgRmlsZVN5c3RlbURpcmVjdG9yeUhhbmRsZT5cbn0gfCB1bmRlZmluZWRcbj4ge1xuICAgIGNvbnN0IGhhbmRsZSA9IGF3YWl0IHJlYWQoY29uZmlnLnBvaW50ZXIpO1xuICAgIGlmICghaGFuZGxlKSByZXR1cm47XG4gICAgbGV0IG1vZGUgPSBjb25maWcucG9pbnRlci5zcGxpdChcIl9cIikuYXQoLTEpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGFzeW5jIG9uVXNlckFjdGl2YXRpb24obW9kZU92ZXJyaWRlKSB7XG4gICAgICAgICAgICBsZXQgdGVzdE1vZGUgPSBhd2FpdCAoaGFuZGxlIGFzIGFueSkucXVlcnlQZXJtaXNzaW9uKHsgbW9kZTogbW9kZSB9KTtcbiAgICAgICAgICAgIGlmICh0ZXN0TW9kZSAhPT0gbW9kZSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IChoYW5kbGUgYXMgYW55KS5yZXF1ZXN0UGVybWlzc2lvbih7IG1vZGU6IG1vZGVPdmVycmlkZSA/PyBtb2RlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGhhbmRsZTtcbiAgICAgICAgfVxuICAgIH07XG59Il19
77
+ /* _JS_SOURCE_HASH = "48ea788e6857a9aab2e957d5ebef940a9cec94997aaf61e8855616fc40d95197"; */
@@ -0,0 +1,11 @@
1
+ export type FileSystemPointer = string;
2
+ export declare function storeFileSystemPointer(config: {
3
+ mode: "read" | "readwrite";
4
+ handle: FileSystemFileHandle | FileSystemDirectoryHandle;
5
+ }): Promise<FileSystemPointer>;
6
+ export declare function deleteFileSystemPointer(pointer: FileSystemPointer): Promise<void>;
7
+ export declare function getFileSystemPointer(config: {
8
+ pointer: FileSystemPointer;
9
+ }): Promise<{
10
+ onUserActivation(modeOverride?: "read" | "readwrite"): Promise<FileSystemFileHandle | FileSystemDirectoryHandle>;
11
+ } | undefined>;
@@ -10,7 +10,9 @@
10
10
  "render-utils/**/*.ts",
11
11
  "render-utils/**/*.tsx",
12
12
  "misc/**/*.ts",
13
- "misc/**/*.tsx"
13
+ "misc/**/*.tsx",
14
+ "storage/**/*.ts",
15
+ "storage/**/*.tsx"
14
16
  ],
15
17
  "exclude": [
16
18
  "node_modules",