@dbx-tools/cache 0.0.0-stage → 0.9.120
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/LICENSE +202 -0
- package/README.md +41 -2
- package/index.ts +8 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +7 -0
- package/lib/src/cache.d.ts +64 -0
- package/lib/src/cache.js +363 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +82 -4
- package/src/cache.ts +494 -0
package/lib/src/cache.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory-first Cacheable and Keyv composition.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { EventEmitter } from "node:events";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { projectUtils } from "@dbx-tools/core";
|
|
9
|
+
import { errorUtils, log } from "@dbx-tools/shared-core";
|
|
10
|
+
import { Cacheable, CacheableHooks, createKeyv, KeyvCacheableMemory, } from "cacheable";
|
|
11
|
+
import envPaths from "env-paths";
|
|
12
|
+
import { KeyvFile } from "keyv-file";
|
|
13
|
+
const DEFAULT_MAX_ENTRIES = 1_000;
|
|
14
|
+
const DEFAULT_WRITE_DELAY_MS = 25;
|
|
15
|
+
const ERROR_VALUE_PREFIX = "__dbx_tools_cached_on_error__:";
|
|
16
|
+
const ENVELOPE_VERSION = 1;
|
|
17
|
+
const logger = log.logger("cache");
|
|
18
|
+
const states = new WeakMap();
|
|
19
|
+
const projectCaches = new Map();
|
|
20
|
+
/**
|
|
21
|
+
* Keyv adapter that composes arbitrary ordered levels behind Cacheable's one
|
|
22
|
+
* secondary-store slot and owns tracked write-behind persistence.
|
|
23
|
+
*/
|
|
24
|
+
class TieredStoreAdapter extends EventEmitter {
|
|
25
|
+
opts = {};
|
|
26
|
+
namespace;
|
|
27
|
+
levels;
|
|
28
|
+
pending = new Map();
|
|
29
|
+
promotions = new Set();
|
|
30
|
+
writeDelayMs;
|
|
31
|
+
flushPromise;
|
|
32
|
+
timer;
|
|
33
|
+
disconnected = false;
|
|
34
|
+
constructor(levels, writeDelayMs) {
|
|
35
|
+
super();
|
|
36
|
+
this.levels = levels;
|
|
37
|
+
this.writeDelayMs = writeDelayMs;
|
|
38
|
+
}
|
|
39
|
+
async get(key) {
|
|
40
|
+
const mutation = this.pending.get(key);
|
|
41
|
+
if (mutation?.kind === "delete")
|
|
42
|
+
return undefined;
|
|
43
|
+
if (mutation?.kind === "set")
|
|
44
|
+
return mutation.value;
|
|
45
|
+
for (const [index, level] of this.levels.entries()) {
|
|
46
|
+
const value = await level.store.get(key);
|
|
47
|
+
if (value === undefined)
|
|
48
|
+
continue;
|
|
49
|
+
if (index > 0)
|
|
50
|
+
this.promote(key, value, this.levels.slice(0, index));
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
async getMany(keys) {
|
|
56
|
+
return Promise.all(keys.map((key) => this.get(key)));
|
|
57
|
+
}
|
|
58
|
+
set(key, value, ttl) {
|
|
59
|
+
this.assertConnected();
|
|
60
|
+
this.pending.set(key, { kind: "set", value, ...(ttl === undefined ? {} : { ttl }) });
|
|
61
|
+
this.schedule();
|
|
62
|
+
return Promise.resolve(true);
|
|
63
|
+
}
|
|
64
|
+
async setMany(values) {
|
|
65
|
+
for (const entry of values)
|
|
66
|
+
await this.set(entry.key, entry.value, entry.ttl);
|
|
67
|
+
}
|
|
68
|
+
delete(key) {
|
|
69
|
+
this.assertConnected();
|
|
70
|
+
this.pending.set(key, { kind: "delete" });
|
|
71
|
+
this.schedule();
|
|
72
|
+
return Promise.resolve(true);
|
|
73
|
+
}
|
|
74
|
+
async deleteMany(keys) {
|
|
75
|
+
await Promise.all(keys.map((key) => this.delete(key)));
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
async has(key) {
|
|
79
|
+
const pending = this.pending.get(key);
|
|
80
|
+
if (pending)
|
|
81
|
+
return pending.kind === "set";
|
|
82
|
+
for (const level of this.levels) {
|
|
83
|
+
if (level.store.has ? await level.store.has(key) : (await level.store.get(key)) !== undefined) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
async clear() {
|
|
90
|
+
this.assertConnected();
|
|
91
|
+
await this.flush();
|
|
92
|
+
this.pending.clear();
|
|
93
|
+
await settleLevels(this.levels, (level) => level.store.clear(), "clear");
|
|
94
|
+
}
|
|
95
|
+
async flush() {
|
|
96
|
+
if (this.timer) {
|
|
97
|
+
clearTimeout(this.timer);
|
|
98
|
+
this.timer = undefined;
|
|
99
|
+
}
|
|
100
|
+
if (!this.flushPromise) {
|
|
101
|
+
this.flushPromise = this.flushPending().finally(() => {
|
|
102
|
+
this.flushPromise = undefined;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
await this.flushPromise;
|
|
106
|
+
await this.flushPromotions();
|
|
107
|
+
if (this.pending.size > 0)
|
|
108
|
+
await this.flush();
|
|
109
|
+
}
|
|
110
|
+
async disconnect() {
|
|
111
|
+
if (this.disconnected)
|
|
112
|
+
return;
|
|
113
|
+
await this.flush();
|
|
114
|
+
this.disconnected = true;
|
|
115
|
+
await settleLevels(this.levels.filter((level) => level.store.disconnect), (level) => level.store.disconnect(), "disconnect");
|
|
116
|
+
}
|
|
117
|
+
assertConnected() {
|
|
118
|
+
if (this.disconnected)
|
|
119
|
+
throw new Error("Cache persistence is disconnected");
|
|
120
|
+
}
|
|
121
|
+
schedule() {
|
|
122
|
+
if (this.timer || this.flushPromise)
|
|
123
|
+
return;
|
|
124
|
+
this.timer = setTimeout(() => {
|
|
125
|
+
this.timer = undefined;
|
|
126
|
+
void this.flush().catch((error) => {
|
|
127
|
+
logger.warn("cache persistence flush failed", { error: errorUtils.toError(error) });
|
|
128
|
+
this.emit("error", error);
|
|
129
|
+
});
|
|
130
|
+
}, this.writeDelayMs);
|
|
131
|
+
this.timer.unref?.();
|
|
132
|
+
}
|
|
133
|
+
async flushPending() {
|
|
134
|
+
while (this.pending.size > 0) {
|
|
135
|
+
const batch = new Map(this.pending);
|
|
136
|
+
for (const key of batch.keys())
|
|
137
|
+
this.pending.delete(key);
|
|
138
|
+
const failures = [];
|
|
139
|
+
await Promise.all([...batch].map(async ([key, mutation]) => {
|
|
140
|
+
try {
|
|
141
|
+
await settleLevels(this.levels, (level) => mutation.kind === "set"
|
|
142
|
+
? level.store.set(key, mutation.value, mutation.ttl)
|
|
143
|
+
: level.store.delete(key), mutation.kind);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
failures.push({ key, mutation, error });
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
149
|
+
if (failures.length > 0) {
|
|
150
|
+
for (const failure of failures) {
|
|
151
|
+
if (!this.pending.has(failure.key))
|
|
152
|
+
this.pending.set(failure.key, failure.mutation);
|
|
153
|
+
}
|
|
154
|
+
throw new AggregateError(failures.map((failure) => failure.error), `Cache persistence failed for ${failures.length} mutation(s)`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
promote(key, value, levels) {
|
|
159
|
+
const promotion = settleLevels(levels, (level) => level.store.set(key, value), "promote")
|
|
160
|
+
.catch((error) => {
|
|
161
|
+
logger.warn("cache persistence promotion failed", {
|
|
162
|
+
key,
|
|
163
|
+
error: errorUtils.toError(error),
|
|
164
|
+
});
|
|
165
|
+
})
|
|
166
|
+
.finally(() => {
|
|
167
|
+
this.promotions.delete(promotion);
|
|
168
|
+
});
|
|
169
|
+
this.promotions.add(promotion);
|
|
170
|
+
}
|
|
171
|
+
async flushPromotions() {
|
|
172
|
+
while (this.promotions.size > 0)
|
|
173
|
+
await Promise.all([...this.promotions]);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/** Create a memory-first cache with optional ordered persistent levels. */
|
|
177
|
+
export function createCache(options = {}) {
|
|
178
|
+
const maxEntries = positiveInteger(options.maxEntries, DEFAULT_MAX_ENTRIES, "maxEntries");
|
|
179
|
+
const writeDelayMs = nonNegativeInteger(options.writeDelayMs, DEFAULT_WRITE_DELAY_MS, "writeDelayMs");
|
|
180
|
+
const primary = createKeyv({
|
|
181
|
+
lruSize: maxEntries,
|
|
182
|
+
ttl: options.ttl,
|
|
183
|
+
useClone: options.useClone ?? true,
|
|
184
|
+
});
|
|
185
|
+
const adapter = options.levels?.length
|
|
186
|
+
? new TieredStoreAdapter(options.levels, writeDelayMs)
|
|
187
|
+
: undefined;
|
|
188
|
+
const cache = new Cacheable({
|
|
189
|
+
primary,
|
|
190
|
+
...(adapter ? { secondary: adapter, nonBlocking: true } : {}),
|
|
191
|
+
...(options.cacheId === undefined ? {} : { cacheId: options.cacheId }),
|
|
192
|
+
...(options.maxTtl === undefined ? {} : { maxTtl: options.maxTtl }),
|
|
193
|
+
...(options.namespace === undefined ? {} : { namespace: options.namespace }),
|
|
194
|
+
...(options.stats === undefined ? {} : { stats: options.stats }),
|
|
195
|
+
...(options.tags === undefined ? {} : { tags: options.tags }),
|
|
196
|
+
...(options.ttl === undefined ? {} : { ttl: options.ttl }),
|
|
197
|
+
});
|
|
198
|
+
installValueEnvelope(cache);
|
|
199
|
+
cache.on("error", (error) => {
|
|
200
|
+
logger.warn("cacheable operation failed", { error: errorUtils.toError(error) });
|
|
201
|
+
});
|
|
202
|
+
states.set(cache, { adapter, closed: false });
|
|
203
|
+
return cache;
|
|
204
|
+
}
|
|
205
|
+
/** Resolve the default portable disk path for a project cache scope. */
|
|
206
|
+
export function cachePath(scope, options = {}) {
|
|
207
|
+
const projectName = options.projectName ?? projectUtils.name();
|
|
208
|
+
const root = options.cacheDir ?? envPaths("dbx-tools", { suffix: "" }).cache;
|
|
209
|
+
return join(root, "cache", safeSegment(projectName), `${safeSegment(scope)}.json`);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Return a process-shared project cache. By default it is memory-first with a
|
|
213
|
+
* portable keyv-file secondary scoped by project and logical cache name.
|
|
214
|
+
*/
|
|
215
|
+
export function projectCache(scope, options = {}) {
|
|
216
|
+
const path = cachePath(scope, options);
|
|
217
|
+
const registryKey = JSON.stringify([path, options.disk !== false]);
|
|
218
|
+
const existing = projectCaches.get(registryKey);
|
|
219
|
+
if (existing)
|
|
220
|
+
return existing;
|
|
221
|
+
const levels = [...(options.levels ?? [])];
|
|
222
|
+
if (options.disk !== false) {
|
|
223
|
+
levels.push({
|
|
224
|
+
name: "disk",
|
|
225
|
+
store: new KeyvFile({
|
|
226
|
+
filename: path,
|
|
227
|
+
writeDelay: nonNegativeInteger(options.diskWriteDelayMs, 100, "diskWriteDelayMs"),
|
|
228
|
+
}),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
const cache = createCache({ ...options, levels });
|
|
232
|
+
const state = requireState(cache);
|
|
233
|
+
state.path = path;
|
|
234
|
+
state.registryKey = registryKey;
|
|
235
|
+
projectCaches.set(registryKey, cache);
|
|
236
|
+
return cache;
|
|
237
|
+
}
|
|
238
|
+
/** Wait for all tracked write-behind persistence without closing the cache. */
|
|
239
|
+
export async function flushCache(cache) {
|
|
240
|
+
await requireState(cache).adapter?.flush();
|
|
241
|
+
}
|
|
242
|
+
/** Flush pending persistence and disconnect all cache levels. Idempotent. */
|
|
243
|
+
export async function closeCache(cache) {
|
|
244
|
+
const state = requireState(cache);
|
|
245
|
+
if (state.closed)
|
|
246
|
+
return;
|
|
247
|
+
await state.adapter?.disconnect();
|
|
248
|
+
state.closed = true;
|
|
249
|
+
if (state.registryKey && projectCaches.get(state.registryKey) === cache) {
|
|
250
|
+
projectCaches.delete(state.registryKey);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/** Iterate keys currently retained by the bounded memory primary. */
|
|
254
|
+
export function cacheKeys(cache) {
|
|
255
|
+
const store = cache.primary.store;
|
|
256
|
+
if (!(store instanceof KeyvCacheableMemory)) {
|
|
257
|
+
throw new TypeError("Cache primary is not Cacheable memory");
|
|
258
|
+
}
|
|
259
|
+
return store.store.keys;
|
|
260
|
+
}
|
|
261
|
+
/** Delete a normal cache value and its optional cached-on-error companion. */
|
|
262
|
+
export async function deleteCachedValue(cache, key) {
|
|
263
|
+
const [value, fallback] = await Promise.all([
|
|
264
|
+
cache.delete(key),
|
|
265
|
+
cache.delete(cachedOnErrorKey(key)),
|
|
266
|
+
]);
|
|
267
|
+
return Boolean(value || fallback);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Use Cacheable's native in-flight get-or-set behavior, optionally retaining a
|
|
271
|
+
* successful value under a separate key for recovery when a later loader fails.
|
|
272
|
+
*/
|
|
273
|
+
export async function getOrSet(cache, key, load, options = {}) {
|
|
274
|
+
const { returnCachedOnError = false, cachedOnErrorTtl = 0, ...cacheableOptions } = options;
|
|
275
|
+
if (!returnCachedOnError)
|
|
276
|
+
return cache.getOrSet(key, load, cacheableOptions);
|
|
277
|
+
try {
|
|
278
|
+
return await cache.getOrSet(key, async () => {
|
|
279
|
+
const value = await load();
|
|
280
|
+
await cache.set(cachedOnErrorKey(key), value, { ttl: cachedOnErrorTtl });
|
|
281
|
+
return value;
|
|
282
|
+
}, { ...cacheableOptions, throwErrors: true });
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
const cached = await cache.get(cachedOnErrorKey(key));
|
|
286
|
+
if (cached !== undefined)
|
|
287
|
+
return cached;
|
|
288
|
+
if (cacheableOptions.throwErrors)
|
|
289
|
+
throw error;
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function installValueEnvelope(cache) {
|
|
294
|
+
cache.onHook(CacheableHooks.BEFORE_SET, (item) => {
|
|
295
|
+
item.value = envelope(item.value);
|
|
296
|
+
});
|
|
297
|
+
cache.onHook(CacheableHooks.BEFORE_SET_MANY, (items) => {
|
|
298
|
+
for (const item of items)
|
|
299
|
+
item.value = envelope(item.value);
|
|
300
|
+
});
|
|
301
|
+
cache.onHook(CacheableHooks.AFTER_GET, (item) => {
|
|
302
|
+
if (item.result)
|
|
303
|
+
item.result.value = unwrap(item.result.value);
|
|
304
|
+
});
|
|
305
|
+
cache.onHook(CacheableHooks.AFTER_GET_MANY, (item) => {
|
|
306
|
+
for (const result of item.result) {
|
|
307
|
+
if (result)
|
|
308
|
+
result.value = unwrap(result.value);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
function envelope(value) {
|
|
313
|
+
return { __dbxToolsCacheEnvelope: ENVELOPE_VERSION, value };
|
|
314
|
+
}
|
|
315
|
+
function unwrap(value) {
|
|
316
|
+
return isEnvelope(value) ? value.value : value;
|
|
317
|
+
}
|
|
318
|
+
function isEnvelope(value) {
|
|
319
|
+
return Boolean(value &&
|
|
320
|
+
typeof value === "object" &&
|
|
321
|
+
"__dbxToolsCacheEnvelope" in value &&
|
|
322
|
+
value.__dbxToolsCacheEnvelope === ENVELOPE_VERSION &&
|
|
323
|
+
"value" in value);
|
|
324
|
+
}
|
|
325
|
+
function cachedOnErrorKey(key) {
|
|
326
|
+
return `${ERROR_VALUE_PREFIX}${key}`;
|
|
327
|
+
}
|
|
328
|
+
async function settleLevels(levels, operation, operationName) {
|
|
329
|
+
const results = await Promise.allSettled(levels.map((level) => operation(level)));
|
|
330
|
+
const errors = results.flatMap((result, index) => result.status === "rejected"
|
|
331
|
+
? [
|
|
332
|
+
new Error(`${levels[index]?.name ?? `level-${index + 1}`} ${operationName} failed`, {
|
|
333
|
+
cause: result.reason,
|
|
334
|
+
}),
|
|
335
|
+
]
|
|
336
|
+
: []);
|
|
337
|
+
if (errors.length > 0)
|
|
338
|
+
throw new AggregateError(errors, `Cache ${operationName} failed`);
|
|
339
|
+
}
|
|
340
|
+
function requireState(cache) {
|
|
341
|
+
const state = states.get(cache);
|
|
342
|
+
if (!state)
|
|
343
|
+
throw new TypeError("Cache was not created by @dbx-tools/cache");
|
|
344
|
+
return state;
|
|
345
|
+
}
|
|
346
|
+
function safeSegment(value) {
|
|
347
|
+
return encodeURIComponent(value.trim() || "default");
|
|
348
|
+
}
|
|
349
|
+
function positiveInteger(value, fallback, name) {
|
|
350
|
+
const resolved = value ?? fallback;
|
|
351
|
+
if (!Number.isInteger(resolved) || resolved <= 0) {
|
|
352
|
+
throw new RangeError(`${name} must be a positive integer`);
|
|
353
|
+
}
|
|
354
|
+
return resolved;
|
|
355
|
+
}
|
|
356
|
+
function nonNegativeInteger(value, fallback, name) {
|
|
357
|
+
const resolved = value ?? fallback;
|
|
358
|
+
if (!Number.isInteger(resolved) || resolved < 0) {
|
|
359
|
+
throw new RangeError(`${name} must be a non-negative integer`);
|
|
360
|
+
}
|
|
361
|
+
return resolved;
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDM0MsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNqQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsU0FBUyxFQUNULGNBQWMsRUFDZCxVQUFVLEVBQ1YsbUJBQW1CLEdBSXBCLE1BQU0sV0FBVyxDQUFDO0FBQ25CLE9BQU8sUUFBUSxNQUFNLFdBQVcsQ0FBQztBQUNqQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXJDLE1BQU0sbUJBQW1CLEdBQUcsS0FBSyxDQUFDO0FBQ2xDLE1BQU0sc0JBQXNCLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLE1BQU0sa0JBQWtCLEdBQUcsZ0NBQWdDLENBQUM7QUFDNUQsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7QUFDM0IsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQXFFbkMsTUFBTSxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQXlCLENBQUM7QUFDcEQsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7QUFFbkQ7OztHQUdHO0FBQ0gsTUFBTSxrQkFBbUIsU0FBUSxZQUFZO0lBQ2xDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkIsU0FBUyxDQUFVO0lBRUYsTUFBTSxDQUF3QjtJQUM5QixPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7SUFDdEMsVUFBVSxHQUFHLElBQUksR0FBRyxFQUFpQixDQUFDO0lBQ3RDLFlBQVksQ0FB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QUMsU0FBUyxDQUFDO0lBQ2QsTUFBTSxLQUFLLEdBQUcsSUFBSSxTQUFTLENBQUM7UUFDMUIsT0FBTztRQUNQLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM3RCxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3RFLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbkUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUM1RSxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2hFLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDN0QsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztLQUMzRCxDQUFDLENBQUM7SUFDSCxvQkFBb0IsQ0FBQyxLQUFLLENB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QTJDLENBQUMsQ0FBQztJQUM3RSxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxLQUFhO0lBQ2hDLE9BQU8sa0JBQWtCLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLFNBQVMsQ0FBQyxDQUFDO0FBQ3ZELENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxLQUF5QixFQUFFLFFBQWdCLEVBQUUsSUFBWTtJQUNoRixNQUFNLFFBQVEsR0FBRyxLQUFLLElBQUksUUFBUSxDQUFDO0lBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLFFBQVEsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNqRCxNQUFNLElBQUksVUFBVSxDQUFDLEdBQUcsSUFBSSw2QkFBNkIsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFDRCxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxLQUF5QixFQUFFLFFBQWdCLEVBQUUsSUFBWTtJQUNuRixNQUFNLFFBQVEsR0FBRyxLQUFLLElBQUksUUFBUSxDQUFDO0lBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNoRCxNQUFNLElBQUksVUFBVSxDQUFDLEdBQUcsSUFBSSxpQ0FBaUMsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFDRCxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNZW1vcnktZmlyc3QgQ2FjaGVhYmxlIGFuZCBLZXl2IGNvbXBvc2l0aW9uLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tIFwibm9kZTpldmVudHNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBwcm9qZWN0VXRpbHMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgeyBlcnJvclV0aWxzLCBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHtcbiAgQ2FjaGVhYmxlLFxuICBDYWNoZWFibGVIb29rcyxcbiAgY3JlYXRlS2V5dixcbiAgS2V5dkNhY2hlYWJsZU1lbW9yeSxcbiAgdHlwZSBDYWNoZWFibGVPcHRpb25zLFxuICB0eXBlIEdldE9yU2V0RnVuY3Rpb25PcHRpb25zLFxuICB0eXBlIEtleXZTdG9yZUFkYXB0ZXIsXG59IGZyb20gXCJjYWNoZWFibGVcIjtcbmltcG9ydCBlbnZQYXRocyBmcm9tIFwiZW52LXBhdGhzXCI7XG5pbXBvcnQgeyBLZXl2RmlsZSB9IGZyb20gXCJrZXl2LWZpbGVcIjtcblxuY29uc3QgREVGQVVMVF9NQVhfRU5UUklFUyA9IDFfMDAwO1xuY29uc3QgREVGQVVMVF9XUklURV9ERUxBWV9NUyA9IDI1O1xuY29uc3QgRVJST1JfVkFMVUVfUFJFRklYID0gXCJfX2RieF90b29sc19jYWNoZWRfb25fZXJyb3JfXzpcIjtcbmNvbnN0IEVOVkVMT1BFX1ZFUlNJT04gPSAxO1xuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcImNhY2hlXCIpO1xuXG5pbnRlcmZhY2UgVmFsdWVFbnZlbG9wZSB7XG4gIHJlYWRvbmx5IF9fZGJ4VG9vbHNDYWNoZUVudmVsb3BlOiB0eXBlb2YgRU5WRUxPUEVfVkVSU0lPTjtcbiAgcmVhZG9ubHkgdmFsdWU6IHVua25vd247XG59XG5cbmludGVyZmFjZSBTZXRNdXRhdGlvbiB7XG4gIHJlYWRvbmx5IGtpbmQ6IFwic2V0XCI7XG4gIHJlYWRvbmx5IHR0bD86IG51bWJlcjtcbiAgcmVhZG9ubHkgdmFsdWU6IHVua25vd247XG59XG5cbmludGVyZmFjZSBEZWxldGVNdXRhdGlvbiB7XG4gIHJlYWRvbmx5IGtpbmQ6IFwiZGVsZXRlXCI7XG59XG5cbnR5cGUgTXV0YXRpb24gPSBEZWxldGVNdXRhdGlvbiB8IFNldE11dGF0aW9uO1xuXG5pbnRlcmZhY2UgQ2FjaGVTdGF0ZSB7XG4gIHJlYWRvbmx5IGFkYXB0ZXI/OiBUaWVyZWRTdG9yZUFkYXB0ZXI7XG4gIHBhdGg/OiBzdHJpbmc7XG4gIHJlZ2lzdHJ5S2V5Pzogc3RyaW5nO1xuICBjbG9zZWQ6IGJvb2xlYW47XG59XG5cbi8qKiBPbmUgb3JkZXJlZCBwZXJzaXN0ZW50IGNhY2hlIGxldmVsLiBFYXJsaWVyIGxldmVscyBhcmUgcmVhZCBmaXJzdC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FjaGVMZXZlbCB7XG4gIC8qKiBPcHRpb25hbCBuYW1lIGluY2x1ZGVkIGluIHBlcnNpc3RlbmNlIGVycm9yIG1lc3NhZ2VzLiAqL1xuICByZWFkb25seSBuYW1lPzogc3RyaW5nO1xuICAvKiogS2V5di1jb21wYXRpYmxlIHN0b3JlIGFkYXB0ZXIuICovXG4gIHJlYWRvbmx5IHN0b3JlOiBLZXl2U3RvcmVBZGFwdGVyO1xufVxuXG4vKiogT3B0aW9ucyBmb3IgYW4gQXBwS2l0LWluZGVwZW5kZW50IG1lbW9yeS1maXJzdCBjYWNoZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FjaGVPcHRpb25zIGV4dGVuZHMgUGljazxcbiAgQ2FjaGVhYmxlT3B0aW9ucyxcbiAgXCJjYWNoZUlkXCIgfCBcIm1heFR0bFwiIHwgXCJuYW1lc3BhY2VcIiB8IFwic3RhdHNcIiB8IFwidGFnc1wiIHwgXCJ0dGxcIlxuPiB7XG4gIC8qKiBBZGRpdGlvbmFsIG9yZGVyZWQgcGVyc2lzdGVuY2UgbGV2ZWxzLiBObyBsZXZlbHMgY3JlYXRlcyBhIG1lbW9yeS1vbmx5IGNhY2hlLiAqL1xuICByZWFkb25seSBsZXZlbHM/OiByZWFkb25seSBDYWNoZUxldmVsW107XG4gIC8qKiBNYXhpbXVtIGVudHJpZXMgcmV0YWluZWQgaW4gdGhlIG1lbW9yeSBwcmltYXJ5LiBEZWZhdWx0cyB0byAxLDAwMC4gKi9cbiAgcmVhZG9ubHkgbWF4RW50cmllcz86IG51bWJlcjtcbiAgLyoqIFdoZXRoZXIgbWVtb3J5IHJlYWRzIGNsb25lIHZhbHVlcy4gRGVmYXVsdHMgdG8gdHJ1ZS4gKi9cbiAgcmVhZG9ubHkgdXNlQ2xvbmU/OiBib29sZWFuO1xuICAvKiogRGVsYXkgdXNlZCB0byBjb2FsZXNjZSBwZXJzaXN0ZW5jZSBtdXRhdGlvbnMuIERlZmF1bHRzIHRvIDI1IG1pbGxpc2Vjb25kcy4gKi9cbiAgcmVhZG9ubHkgd3JpdGVEZWxheU1zPzogbnVtYmVyO1xufVxuXG4vKiogT3B0aW9ucyBmb3IgdGhlIGRlZmF1bHQgcHJvamVjdC1zY29wZWQgbWVtb3J5IGFuZCBkaXNrIGNhY2hlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9qZWN0Q2FjaGVPcHRpb25zIGV4dGVuZHMgQ2FjaGVPcHRpb25zIHtcbiAgLyoqIE92ZXJyaWRlIHRoZSBjYWNoZSBkaXJlY3RvcnksIHByaW1hcmlseSBmb3IgdGVzdHMuICovXG4gIHJlYWRvbmx5IGNhY2hlRGlyPzogc3RyaW5nO1xuICAvKiogRGlzYWJsZSB0aGUgZGVmYXVsdCBkaXNrIGxldmVsLiBEZWZhdWx0cyB0byB0cnVlLiAqL1xuICByZWFkb25seSBkaXNrPzogYm9vbGVhbjtcbiAgLyoqIERlbGF5IHVzZWQgYnkga2V5di1maWxlIHRvIGNvYWxlc2NlIGZpbGUgcmV3cml0ZXMuIERlZmF1bHRzIHRvIDEwMCBtaWxsaXNlY29uZHMuICovXG4gIHJlYWRvbmx5IGRpc2tXcml0ZURlbGF5TXM/OiBudW1iZXI7XG4gIC8qKiBPdmVycmlkZSB0aGUgcHJvamVjdCBuYW1lIHJlc29sdmVkIHRocm91Z2ggcHJvamVjdFV0aWxzLm5hbWUoKS4gKi9cbiAgcmVhZG9ubHkgcHJvamVjdE5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKiBPcHRpb25zIGZvciB0aGUgQ2FjaGVhYmxlLWNvbXBhdGlibGUgZ2V0LW9yLXNldCBleHRlbnNpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIEdldE9yU2V0T3B0aW9ucyBleHRlbmRzIEdldE9yU2V0RnVuY3Rpb25PcHRpb25zIHtcbiAgLyoqIFJldHVybiBhIHNlcGFyYXRlbHkgcmV0YWluZWQgc3VjY2Vzc2Z1bCB2YWx1ZSB3aGVuIHRoZSBsb2FkZXIgZmFpbHMuIERlZmF1bHRzIHRvIGZhbHNlLiAqL1xuICByZWFkb25seSByZXR1cm5DYWNoZWRPbkVycm9yPzogYm9vbGVhbjtcbiAgLyoqIFRUTCBmb3IgdGhlIGNhY2hlZC1vbi1lcnJvciB2YWx1ZS4gRGVmYXVsdHMgdG8gMCwgbWVhbmluZyBubyBleHBpcmF0aW9uLiAqL1xuICByZWFkb25seSBjYWNoZWRPbkVycm9yVHRsPzogbnVtYmVyIHwgc3RyaW5nO1xufVxuXG5jb25zdCBzdGF0ZXMgPSBuZXcgV2Vha01hcDxDYWNoZWFibGUsIENhY2hlU3RhdGU+KCk7XG5jb25zdCBwcm9qZWN0Q2FjaGVzID0gbmV3IE1hcDxzdHJpbmcsIENhY2hlYWJsZT4oKTtcblxuLyoqXG4gKiBLZXl2IGFkYXB0ZXIgdGhhdCBjb21wb3NlcyBhcmJpdHJhcnkgb3JkZXJlZCBsZXZlbHMgYmVoaW5kIENhY2hlYWJsZSdzIG9uZVxuICogc2Vjb25kYXJ5LXN0b3JlIHNsb3QgYW5kIG93bnMgdHJhY2tlZCB3cml0ZS1iZWhpbmQgcGVyc2lzdGVuY2UuXG4gKi9cbmNsYXNzIFRpZXJlZFN0b3JlQWRhcHRlciBleHRlbmRzIEV2ZW50RW1pdHRlciBpbXBsZW1lbnRzIEtleXZTdG9yZUFkYXB0ZXIge1xuICByZWFkb25seSBvcHRzID0ge307XG4gIG5hbWVzcGFjZT86IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IGxldmVsczogcmVhZG9ubHkgQ2FjaGVMZXZlbFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IHBlbmRpbmcgPSBuZXcgTWFwPHN0cmluZywgTXV0YXRpb24+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvbW90aW9ucyA9IG5ldyBTZXQ8UHJvbWlzZTx2b2lkPj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSB3cml0ZURlbGF5TXM6IG51bWJlcjtcbiAgcHJpdmF0ZSBmbHVzaFByb21pc2U/OiBQcm9taXNlPHZvaWQ+O1xuICBwcml2YXRlIHRpbWVyPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XG4gIHByaXZhdGUgZGlzY29ubmVjdGVkID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IobGV2ZWxzOiByZWFkb25seSBDYWNoZUxldmVsW10sIHdyaXRlRGVsYXlNczogbnVtYmVyKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmxldmVscyA9IGxldmVscztcbiAgICB0aGlzLndyaXRlRGVsYXlNcyA9IHdyaXRlRGVsYXlNcztcbiAgfVxuXG4gIGFzeW5jIGdldDxWYWx1ZT4oa2V5OiBzdHJpbmcpOiBQcm9taXNlPFZhbHVlIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgbXV0YXRpb24gPSB0aGlzLnBlbmRpbmcuZ2V0KGtleSk7XG4gICAgaWYgKG11dGF0aW9uPy5raW5kID09PSBcImRlbGV0ZVwiKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGlmIChtdXRhdGlvbj8ua2luZCA9PT0gXCJzZXRcIikgcmV0dXJuIG11dGF0aW9uLnZhbHVlIGFzIFZhbHVlO1xuXG4gICAgZm9yIChjb25zdCBbaW5kZXgsIGxldmVsXSBvZiB0aGlzLmxldmVscy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgbGV2ZWwuc3RvcmUuZ2V0PFZhbHVlPihrZXkpO1xuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgaWYgKGluZGV4ID4gMCkgdGhpcy5wcm9tb3RlKGtleSwgdmFsdWUsIHRoaXMubGV2ZWxzLnNsaWNlKDAsIGluZGV4KSk7XG4gICAgICByZXR1cm4gdmFsdWUgYXMgVmFsdWU7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBhc3luYyBnZXRNYW55PFZhbHVlPihrZXlzOiBzdHJpbmdbXSk6IFByb21pc2U8QXJyYXk8VmFsdWUgfCB1bmRlZmluZWQ+PiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGtleXMubWFwKChrZXkpID0+IHRoaXMuZ2V0PFZhbHVlPihrZXkpKSk7XG4gIH1cblxuICBzZXQoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duLCB0dGw/OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0aGlzLmFzc2VydENvbm5lY3RlZCgpO1xuICAgIHRoaXMucGVuZGluZy5zZXQoa2V5LCB7IGtpbmQ6IFwic2V0XCIsIHZhbHVlLCAuLi4odHRsID09PSB1bmRlZmluZWQgPyB7fSA6IHsgdHRsIH0pIH0pO1xuICAgIHRoaXMuc2NoZWR1bGUoKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuICB9XG5cbiAgYXN5bmMgc2V0TWFueSh2YWx1ZXM6IEFycmF5PHsga2V5OiBzdHJpbmc7IHZhbHVlOiB1bmtub3duOyB0dGw/OiBudW1iZXIgfT4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHZhbHVlcykgYXdhaXQgdGhpcy5zZXQoZW50cnkua2V5LCBlbnRyeS52YWx1ZSwgZW50cnkudHRsKTtcbiAgfVxuXG4gIGRlbGV0ZShrZXk6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRoaXMuYXNzZXJ0Q29ubmVjdGVkKCk7XG4gICAgdGhpcy5wZW5kaW5nLnNldChrZXksIHsga2luZDogXCJkZWxldGVcIiB9KTtcbiAgICB0aGlzLnNjaGVkdWxlKCk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0cnVlKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZU1hbnkoa2V5czogc3RyaW5nW10pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChrZXlzLm1hcCgoa2V5KSA9PiB0aGlzLmRlbGV0ZShrZXkpKSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBhc3luYyBoYXMoa2V5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nLmdldChrZXkpO1xuICAgIGlmIChwZW5kaW5nKSByZXR1cm4gcGVuZGluZy5raW5kID09PSBcInNldFwiO1xuICAgIGZvciAoY29uc3QgbGV2ZWwgb2YgdGhpcy5sZXZlbHMpIHtcbiAgICAgIGlmIChcbiAgICAgICAgbGV2ZWwuc3RvcmUuaGFzID8gYXdhaXQgbGV2ZWwuc3RvcmUuaGFzKGtleSkgOiAoYXdhaXQgbGV2ZWwuc3RvcmUuZ2V0KGtleSkpICE9PSB1bmRlZmluZWRcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgYXN5bmMgY2xlYXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5hc3NlcnRDb25uZWN0ZWQoKTtcbiAgICBhd2FpdCB0aGlzLmZsdXNoKCk7XG4gICAgdGhpcy5wZW5kaW5nLmNsZWFyKCk7XG4gICAgYXdhaXQgc2V0dGxlTGV2ZWxzKHRoaXMubGV2ZWxzLCAobGV2ZWwpID0+IGxldmVsLnN0b3JlLmNsZWFyKCksIFwiY2xlYXJcIik7XG4gIH1cblxuICBhc3luYyBmbHVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy50aW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO1xuICAgICAgdGhpcy50aW1lciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmZsdXNoUHJvbWlzZSkge1xuICAgICAgdGhpcy5mbHVzaFByb21pc2UgPSB0aGlzLmZsdXNoUGVuZGluZygpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICB0aGlzLmZsdXNoUHJvbWlzZSA9IHVuZGVmaW5lZDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLmZsdXNoUHJvbWlzZTtcbiAgICBhd2FpdCB0aGlzLmZsdXNoUHJvbW90aW9ucygpO1xuICAgIGlmICh0aGlzLnBlbmRpbmcuc2l6ZSA+IDApIGF3YWl0IHRoaXMuZmx1c2goKTtcbiAgfVxuXG4gIGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuZGlzY29ubmVjdGVkKSByZXR1cm47XG4gICAgYXdhaXQgdGhpcy5mbHVzaCgpO1xuICAgIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgICBhd2FpdCBzZXR0bGVMZXZlbHMoXG4gICAgICB0aGlzLmxldmVscy5maWx0ZXIoKGxldmVsKSA9PiBsZXZlbC5zdG9yZS5kaXNjb25uZWN0KSxcbiAgICAgIChsZXZlbCkgPT4gbGV2ZWwuc3RvcmUuZGlzY29ubmVjdCEoKSxcbiAgICAgIFwiZGlzY29ubmVjdFwiLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzc2VydENvbm5lY3RlZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNjb25uZWN0ZWQpIHRocm93IG5ldyBFcnJvcihcIkNhY2hlIHBlcnNpc3RlbmNlIGlzIGRpc2Nvbm5lY3RlZFwiKTtcbiAgfVxuXG4gIHByaXZhdGUgc2NoZWR1bGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudGltZXIgfHwgdGhpcy5mbHVzaFByb21pc2UpIHJldHVybjtcbiAgICB0aGlzLnRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnRpbWVyID0gdW5kZWZpbmVkO1xuICAgICAgdm9pZCB0aGlzLmZsdXNoKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKFwiY2FjaGUgcGVyc2lzdGVuY2UgZmx1c2ggZmFpbGVkXCIsIHsgZXJyb3I6IGVycm9yVXRpbHMudG9FcnJvcihlcnJvcikgfSk7XG4gICAgICAgIHRoaXMuZW1pdChcImVycm9yXCIsIGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0sIHRoaXMud3JpdGVEZWxheU1zKTtcbiAgICB0aGlzLnRpbWVyLnVucmVmPy4oKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmx1c2hQZW5kaW5nKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHdoaWxlICh0aGlzLnBlbmRpbmcuc2l6ZSA+IDApIHtcbiAgICAgIGNvbnN0IGJhdGNoID0gbmV3IE1hcCh0aGlzLnBlbmRpbmcpO1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgYmF0Y2gua2V5cygpKSB0aGlzLnBlbmRpbmcuZGVsZXRlKGtleSk7XG4gICAgICBjb25zdCBmYWlsdXJlczogQXJyYXk8eyBrZXk6IHN0cmluZzsgbXV0YXRpb246IE11dGF0aW9uOyBlcnJvcjogdW5rbm93biB9PiA9IFtdO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIFsuLi5iYXRjaF0ubWFwKGFzeW5jIChba2V5LCBtdXRhdGlvbl0pID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgc2V0dGxlTGV2ZWxzKFxuICAgICAgICAgICAgICB0aGlzLmxldmVscyxcbiAgICAgICAgICAgICAgKGxldmVsKSA9PlxuICAgICAgICAgICAgICAgIG11dGF0aW9uLmtpbmQgPT09IFwic2V0XCJcbiAgICAgICAgICAgICAgICAgID8gbGV2ZWwuc3RvcmUuc2V0KGtleSwgbXV0YXRpb24udmFsdWUsIG11dGF0aW9uLnR0bClcbiAgICAgICAgICAgICAgICAgIDogbGV2ZWwuc3RvcmUuZGVsZXRlKGtleSksXG4gICAgICAgICAgICAgIG11dGF0aW9uLmtpbmQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBmYWlsdXJlcy5wdXNoKHsga2V5LCBtdXRhdGlvbiwgZXJyb3IgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICBpZiAoZmFpbHVyZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBmb3IgKGNvbnN0IGZhaWx1cmUgb2YgZmFpbHVyZXMpIHtcbiAgICAgICAgICBpZiAoIXRoaXMucGVuZGluZy5oYXMoZmFpbHVyZS5rZXkpKSB0aGlzLnBlbmRpbmcuc2V0KGZhaWx1cmUua2V5LCBmYWlsdXJlLm11dGF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgQWdncmVnYXRlRXJyb3IoXG4gICAgICAgICAgZmFpbHVyZXMubWFwKChmYWlsdXJlKSA9PiBmYWlsdXJlLmVycm9yKSxcbiAgICAgICAgICBgQ2FjaGUgcGVyc2lzdGVuY2UgZmFpbGVkIGZvciAke2ZhaWx1cmVzLmxlbmd0aH0gbXV0YXRpb24ocylgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHJvbW90ZShrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24sIGxldmVsczogcmVhZG9ubHkgQ2FjaGVMZXZlbFtdKTogdm9pZCB7XG4gICAgY29uc3QgcHJvbW90aW9uID0gc2V0dGxlTGV2ZWxzKGxldmVscywgKGxldmVsKSA9PiBsZXZlbC5zdG9yZS5zZXQoa2V5LCB2YWx1ZSksIFwicHJvbW90ZVwiKVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBsb2dnZXIud2FybihcImNhY2hlIHBlcnNpc3RlbmNlIHByb21vdGlvbiBmYWlsZWRcIiwge1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICBlcnJvcjogZXJyb3JVdGlscy50b0Vycm9yKGVycm9yKSxcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICB0aGlzLnByb21vdGlvbnMuZGVsZXRlKHByb21vdGlvbik7XG4gICAgICB9KTtcbiAgICB0aGlzLnByb21vdGlvbnMuYWRkKHByb21vdGlvbik7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZsdXNoUHJvbW90aW9ucygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB3aGlsZSAodGhpcy5wcm9tb3Rpb25zLnNpemUgPiAwKSBhd2FpdCBQcm9taXNlLmFsbChbLi4udGhpcy5wcm9tb3Rpb25zXSk7XG4gIH1cbn1cblxuLyoqIENyZWF0ZSBhIG1lbW9yeS1maXJzdCBjYWNoZSB3aXRoIG9wdGlvbmFsIG9yZGVyZWQgcGVyc2lzdGVudCBsZXZlbHMuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2FjaGUob3B0aW9uczogQ2FjaGVPcHRpb25zID0ge30pOiBDYWNoZWFibGUge1xuICBjb25zdCBtYXhFbnRyaWVzID0gcG9zaXRpdmVJbnRlZ2VyKG9wdGlvbnMubWF4RW50cmllcywgREVGQVVMVF9NQVhfRU5UUklFUywgXCJtYXhFbnRyaWVzXCIpO1xuICBjb25zdCB3cml0ZURlbGF5TXMgPSBub25OZWdhdGl2ZUludGVnZXIoXG4gICAgb3B0aW9ucy53cml0ZURlbGF5TXMsXG4gICAgREVGQVVMVF9XUklURV9ERUxBWV9NUyxcbiAgICBcIndyaXRlRGVsYXlNc1wiLFxuICApO1xuICBjb25zdCBwcmltYXJ5ID0gY3JlYXRlS2V5dih7XG4gICAgbHJ1U2l6ZTogbWF4RW50cmllcyxcbiAgICB0dGw6IG9wdGlvbnMudHRsLFxuICAgIHVzZUNsb25lOiBvcHRpb25zLnVzZUNsb25lID8/IHRydWUsXG4gIH0pO1xuICBjb25zdCBhZGFwdGVyID0gb3B0aW9ucy5sZXZlbHM/Lmxlbmd0aFxuICAgID8gbmV3IFRpZXJlZFN0b3JlQWRhcHRlcihvcHRpb25zLmxldmVscywgd3JpdGVEZWxheU1zKVxuICAgIDogdW5kZWZpbmVkO1xuICBjb25zdCBjYWNoZSA9IG5ldyBDYWNoZWFibGUoe1xuICAgIHByaW1hcnksXG4gICAgLi4uKGFkYXB0ZXIgPyB7IHNlY29uZGFyeTogYWRhcHRlciwgbm9uQmxvY2tpbmc6IHRydWUgfSA6IHt9KSxcbiAgICAuLi4ob3B0aW9ucy5jYWNoZUlkID09PSB1bmRlZmluZWQgPyB7fSA6IHsgY2FjaGVJZDogb3B0aW9ucy5jYWNoZUlkIH0pLFxuICAgIC4uLihvcHRpb25zLm1heFR0bCA9PT0gdW5kZWZpbmVkID8ge30gOiB7IG1heFR0bDogb3B0aW9ucy5tYXhUdGwgfSksXG4gICAgLi4uKG9wdGlvbnMubmFtZXNwYWNlID09PSB1bmRlZmluZWQgPyB7fSA6IHsgbmFtZXNwYWNlOiBvcHRpb25zLm5hbWVzcGFjZSB9KSxcbiAgICAuLi4ob3B0aW9ucy5zdGF0cyA9PT0gdW5kZWZpbmVkID8ge30gOiB7IHN0YXRzOiBvcHRpb25zLnN0YXRzIH0pLFxuICAgIC4uLihvcHRpb25zLnRhZ3MgPT09IHVuZGVmaW5lZCA/IHt9IDogeyB0YWdzOiBvcHRpb25zLnRhZ3MgfSksXG4gICAgLi4uKG9wdGlvbnMudHRsID09PSB1bmRlZmluZWQgPyB7fSA6IHsgdHRsOiBvcHRpb25zLnR0bCB9KSxcbiAgfSk7XG4gIGluc3RhbGxWYWx1ZUVudmVsb3BlKGNhY2hlKTtcbiAgY2FjaGUub24oXCJlcnJvclwiLCAoZXJyb3IpID0+IHtcbiAgICBsb2dnZXIud2FybihcImNhY2hlYWJsZSBvcGVyYXRpb24gZmFpbGVkXCIsIHsgZXJyb3I6IGVycm9yVXRpbHMudG9FcnJvcihlcnJvcikgfSk7XG4gIH0pO1xuICBzdGF0ZXMuc2V0KGNhY2hlLCB7IGFkYXB0ZXIsIGNsb3NlZDogZmFsc2UgfSk7XG4gIHJldHVybiBjYWNoZTtcbn1cblxuLyoqIFJlc29sdmUgdGhlIGRlZmF1bHQgcG9ydGFibGUgZGlzayBwYXRoIGZvciBhIHByb2plY3QgY2FjaGUgc2NvcGUuICovXG5leHBvcnQgZnVuY3Rpb24gY2FjaGVQYXRoKFxuICBzY29wZTogc3RyaW5nLFxuICBvcHRpb25zOiBQaWNrPFByb2plY3RDYWNoZU9wdGlvbnMsIFwiY2FjaGVEaXJcIiB8IFwicHJvamVjdE5hbWVcIj4gPSB7fSxcbik6IHN0cmluZyB7XG4gIGNvbnN0IHByb2plY3ROYW1lID0gb3B0aW9ucy5wcm9qZWN0TmFtZSA/PyBwcm9qZWN0VXRpbHMubmFtZSgpO1xuICBjb25zdCByb290ID0gb3B0aW9ucy5jYWNoZURpciA/PyBlbnZQYXRocyhcImRieC10b29sc1wiLCB7IHN1ZmZpeDogXCJcIiB9KS5jYWNoZTtcbiAgcmV0dXJuIGpvaW4ocm9vdCwgXCJjYWNoZVwiLCBzYWZlU2VnbWVudChwcm9qZWN0TmFtZSksIGAke3NhZmVTZWdtZW50KHNjb3BlKX0uanNvbmApO1xufVxuXG4vKipcbiAqIFJldHVybiBhIHByb2Nlc3Mtc2hhcmVkIHByb2plY3QgY2FjaGUuIEJ5IGRlZmF1bHQgaXQgaXMgbWVtb3J5LWZpcnN0IHdpdGggYVxuICogcG9ydGFibGUga2V5di1maWxlIHNlY29uZGFyeSBzY29wZWQgYnkgcHJvamVjdCBhbmQgbG9naWNhbCBjYWNoZSBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvamVjdENhY2hlKHNjb3BlOiBzdHJpbmcsIG9wdGlvbnM6IFByb2plY3RDYWNoZU9wdGlvbnMgPSB7fSk6IENhY2hlYWJsZSB7XG4gIGNvbnN0IHBhdGggPSBjYWNoZVBhdGgoc2NvcGUsIG9wdGlvbnMpO1xuICBjb25zdCByZWdpc3RyeUtleSA9IEpTT04uc3RyaW5naWZ5KFtwYXRoLCBvcHRpb25zLmRpc2sgIT09IGZhbHNlXSk7XG4gIGNvbnN0IGV4aXN0aW5nID0gcHJvamVjdENhY2hlcy5nZXQocmVnaXN0cnlLZXkpO1xuICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZztcblxuICBjb25zdCBsZXZlbHMgPSBbLi4uKG9wdGlvbnMubGV2ZWxzID8/IFtdKV07XG4gIGlmIChvcHRpb25zLmRpc2sgIT09IGZhbHNlKSB7XG4gICAgbGV2ZWxzLnB1c2goe1xuICAgICAgbmFtZTogXCJkaXNrXCIsXG4gICAgICBzdG9yZTogbmV3IEtleXZGaWxlKHtcbiAgICAgICAgZmlsZW5hbWU6IHBhdGgsXG4gICAgICAgIHdyaXRlRGVsYXk6IG5vbk5lZ2F0aXZlSW50ZWdlcihvcHRpb25zLmRpc2tXcml0ZURlbGF5TXMsIDEwMCwgXCJkaXNrV3JpdGVEZWxheU1zXCIpLFxuICAgICAgfSksXG4gICAgfSk7XG4gIH1cbiAgY29uc3QgY2FjaGUgPSBjcmVhdGVDYWNoZSh7IC4uLm9wdGlvbnMsIGxldmVscyB9KTtcbiAgY29uc3Qgc3RhdGUgPSByZXF1aXJlU3RhdGUoY2FjaGUpO1xuICBzdGF0ZS5wYXRoID0gcGF0aDtcbiAgc3RhdGUucmVnaXN0cnlLZXkgPSByZWdpc3RyeUtleTtcbiAgcHJvamVjdENhY2hlcy5zZXQocmVnaXN0cnlLZXksIGNhY2hlKTtcbiAgcmV0dXJuIGNhY2hlO1xufVxuXG4vKiogV2FpdCBmb3IgYWxsIHRyYWNrZWQgd3JpdGUtYmVoaW5kIHBlcnNpc3RlbmNlIHdpdGhvdXQgY2xvc2luZyB0aGUgY2FjaGUuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmx1c2hDYWNoZShjYWNoZTogQ2FjaGVhYmxlKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IHJlcXVpcmVTdGF0ZShjYWNoZSkuYWRhcHRlcj8uZmx1c2goKTtcbn1cblxuLyoqIEZsdXNoIHBlbmRpbmcgcGVyc2lzdGVuY2UgYW5kIGRpc2Nvbm5lY3QgYWxsIGNhY2hlIGxldmVscy4gSWRlbXBvdGVudC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZUNhY2hlKGNhY2hlOiBDYWNoZWFibGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qgc3RhdGUgPSByZXF1aXJlU3RhdGUoY2FjaGUpO1xuICBpZiAoc3RhdGUuY2xvc2VkKSByZXR1cm47XG4gIGF3YWl0IHN0YXRlLmFkYXB0ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgc3RhdGUuY2xvc2VkID0gdHJ1ZTtcbiAgaWYgKHN0YXRlLnJlZ2lzdHJ5S2V5ICYmIHByb2plY3RDYWNoZXMuZ2V0KHN0YXRlLnJlZ2lzdHJ5S2V5KSA9PT0gY2FjaGUpIHtcbiAgICBwcm9qZWN0Q2FjaGVzLmRlbGV0ZShzdGF0ZS5yZWdpc3RyeUtleSk7XG4gIH1cbn1cblxuLyoqIEl0ZXJhdGUga2V5cyBjdXJyZW50bHkgcmV0YWluZWQgYnkgdGhlIGJvdW5kZWQgbWVtb3J5IHByaW1hcnkuICovXG5leHBvcnQgZnVuY3Rpb24gY2FjaGVLZXlzKGNhY2hlOiBDYWNoZWFibGUpOiBJdGVyYWJsZUl0ZXJhdG9yPHN0cmluZz4ge1xuICBjb25zdCBzdG9yZSA9IGNhY2hlLnByaW1hcnkuc3RvcmU7XG4gIGlmICghKHN0b3JlIGluc3RhbmNlb2YgS2V5dkNhY2hlYWJsZU1lbW9yeSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2FjaGUgcHJpbWFyeSBpcyBub3QgQ2FjaGVhYmxlIG1lbW9yeVwiKTtcbiAgfVxuICByZXR1cm4gc3RvcmUuc3RvcmUua2V5cztcbn1cblxuLyoqIERlbGV0ZSBhIG5vcm1hbCBjYWNoZSB2YWx1ZSBhbmQgaXRzIG9wdGlvbmFsIGNhY2hlZC1vbi1lcnJvciBjb21wYW5pb24uICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVsZXRlQ2FjaGVkVmFsdWUoY2FjaGU6IENhY2hlYWJsZSwga2V5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgW3ZhbHVlLCBmYWxsYmFja10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgY2FjaGUuZGVsZXRlKGtleSksXG4gICAgY2FjaGUuZGVsZXRlKGNhY2hlZE9uRXJyb3JLZXkoa2V5KSksXG4gIF0pO1xuICByZXR1cm4gQm9vbGVhbih2YWx1ZSB8fCBmYWxsYmFjayk7XG59XG5cbi8qKlxuICogVXNlIENhY2hlYWJsZSdzIG5hdGl2ZSBpbi1mbGlnaHQgZ2V0LW9yLXNldCBiZWhhdmlvciwgb3B0aW9uYWxseSByZXRhaW5pbmcgYVxuICogc3VjY2Vzc2Z1bCB2YWx1ZSB1bmRlciBhIHNlcGFyYXRlIGtleSBmb3IgcmVjb3Zlcnkgd2hlbiBhIGxhdGVyIGxvYWRlciBmYWlscy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldE9yU2V0PFQ+KFxuICBjYWNoZTogQ2FjaGVhYmxlLFxuICBrZXk6IHN0cmluZyxcbiAgbG9hZDogKCkgPT4gUHJvbWlzZTxUPixcbiAgb3B0aW9uczogR2V0T3JTZXRPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPFQgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgeyByZXR1cm5DYWNoZWRPbkVycm9yID0gZmFsc2UsIGNhY2hlZE9uRXJyb3JUdGwgPSAwLCAuLi5jYWNoZWFibGVPcHRpb25zIH0gPSBvcHRpb25zO1xuICBpZiAoIXJldHVybkNhY2hlZE9uRXJyb3IpIHJldHVybiBjYWNoZS5nZXRPclNldChrZXksIGxvYWQsIGNhY2hlYWJsZU9wdGlvbnMpO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGNhY2hlLmdldE9yU2V0KFxuICAgICAga2V5LFxuICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IGxvYWQoKTtcbiAgICAgICAgYXdhaXQgY2FjaGUuc2V0KGNhY2hlZE9uRXJyb3JLZXkoa2V5KSwgdmFsdWUsIHsgdHRsOiBjYWNoZWRPbkVycm9yVHRsIH0pO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9LFxuICAgICAgeyAuLi5jYWNoZWFibGVPcHRpb25zLCB0aHJvd0Vycm9yczogdHJ1ZSB9LFxuICAgICk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2FjaGVkID0gYXdhaXQgY2FjaGUuZ2V0PFQ+KGNhY2hlZE9uRXJyb3JLZXkoa2V5KSk7XG4gICAgaWYgKGNhY2hlZCAhPT0gdW5kZWZpbmVkKSByZXR1cm4gY2FjaGVkO1xuICAgIGlmIChjYWNoZWFibGVPcHRpb25zLnRocm93RXJyb3JzKSB0aHJvdyBlcnJvcjtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluc3RhbGxWYWx1ZUVudmVsb3BlKGNhY2hlOiBDYWNoZWFibGUpOiB2b2lkIHtcbiAgY2FjaGUub25Ib29rKENhY2hlYWJsZUhvb2tzLkJFRk9SRV9TRVQsIChpdGVtKSA9PiB7XG4gICAgaXRlbS52YWx1ZSA9IGVudmVsb3BlKGl0ZW0udmFsdWUpO1xuICB9KTtcbiAgY2FjaGUub25Ib29rKENhY2hlYWJsZUhvb2tzLkJFRk9SRV9TRVRfTUFOWSwgKGl0ZW1zKSA9PiB7XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSBpdGVtLnZhbHVlID0gZW52ZWxvcGUoaXRlbS52YWx1ZSk7XG4gIH0pO1xuICBjYWNoZS5vbkhvb2soQ2FjaGVhYmxlSG9va3MuQUZURVJfR0VULCAoaXRlbSkgPT4ge1xuICAgIGlmIChpdGVtLnJlc3VsdCkgaXRlbS5yZXN1bHQudmFsdWUgPSB1bndyYXAoaXRlbS5yZXN1bHQudmFsdWUpO1xuICB9KTtcbiAgY2FjaGUub25Ib29rKENhY2hlYWJsZUhvb2tzLkFGVEVSX0dFVF9NQU5ZLCAoaXRlbSkgPT4ge1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGl0ZW0ucmVzdWx0KSB7XG4gICAgICBpZiAocmVzdWx0KSByZXN1bHQudmFsdWUgPSB1bndyYXAocmVzdWx0LnZhbHVlKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBlbnZlbG9wZSh2YWx1ZTogdW5rbm93bik6IFZhbHVlRW52ZWxvcGUge1xuICByZXR1cm4geyBfX2RieFRvb2xzQ2FjaGVFbnZlbG9wZTogRU5WRUxPUEVfVkVSU0lPTiwgdmFsdWUgfTtcbn1cblxuZnVuY3Rpb24gdW53cmFwKHZhbHVlOiB1bmtub3duKTogdW5rbm93biB7XG4gIHJldHVybiBpc0VudmVsb3BlKHZhbHVlKSA/IHZhbHVlLnZhbHVlIDogdmFsdWU7XG59XG5cbmZ1bmN0aW9uIGlzRW52ZWxvcGUodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBWYWx1ZUVudmVsb3BlIHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgdmFsdWUgJiZcbiAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICBcIl9fZGJ4VG9vbHNDYWNoZUVudmVsb3BlXCIgaW4gdmFsdWUgJiZcbiAgICAodmFsdWUgYXMgVmFsdWVFbnZlbG9wZSkuX19kYnhUb29sc0NhY2hlRW52ZWxvcGUgPT09IEVOVkVMT1BFX1ZFUlNJT04gJiZcbiAgICBcInZhbHVlXCIgaW4gdmFsdWUsXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNhY2hlZE9uRXJyb3JLZXkoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7RVJST1JfVkFMVUVfUFJFRklYfSR7a2V5fWA7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNldHRsZUxldmVscyhcbiAgbGV2ZWxzOiByZWFkb25seSBDYWNoZUxldmVsW10sXG4gIG9wZXJhdGlvbjogKGxldmVsOiBDYWNoZUxldmVsKSA9PiB1bmtub3duIHwgUHJvbWlzZTx1bmtub3duPixcbiAgb3BlcmF0aW9uTmFtZTogc3RyaW5nLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQobGV2ZWxzLm1hcCgobGV2ZWwpID0+IG9wZXJhdGlvbihsZXZlbCkpKTtcbiAgY29uc3QgZXJyb3JzID0gcmVzdWx0cy5mbGF0TWFwKChyZXN1bHQsIGluZGV4KSA9PlxuICAgIHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIlxuICAgICAgPyBbXG4gICAgICAgICAgbmV3IEVycm9yKGAke2xldmVsc1tpbmRleF0/Lm5hbWUgPz8gYGxldmVsLSR7aW5kZXggKyAxfWB9ICR7b3BlcmF0aW9uTmFtZX0gZmFpbGVkYCwge1xuICAgICAgICAgICAgY2F1c2U6IHJlc3VsdC5yZWFzb24sXG4gICAgICAgICAgfSksXG4gICAgICAgIF1cbiAgICAgIDogW10sXG4gICk7XG4gIGlmIChlcnJvcnMubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKGVycm9ycywgYENhY2hlICR7b3BlcmF0aW9uTmFtZX0gZmFpbGVkYCk7XG59XG5cbmZ1bmN0aW9uIHJlcXVpcmVTdGF0ZShjYWNoZTogQ2FjaGVhYmxlKTogQ2FjaGVTdGF0ZSB7XG4gIGNvbnN0IHN0YXRlID0gc3RhdGVzLmdldChjYWNoZSk7XG4gIGlmICghc3RhdGUpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYWNoZSB3YXMgbm90IGNyZWF0ZWQgYnkgQGRieC10b29scy9jYWNoZVwiKTtcbiAgcmV0dXJuIHN0YXRlO1xufVxuXG5mdW5jdGlvbiBzYWZlU2VnbWVudCh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZS50cmltKCkgfHwgXCJkZWZhdWx0XCIpO1xufVxuXG5mdW5jdGlvbiBwb3NpdGl2ZUludGVnZXIodmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCwgZmFsbGJhY2s6IG51bWJlciwgbmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgY29uc3QgcmVzb2x2ZWQgPSB2YWx1ZSA/PyBmYWxsYmFjaztcbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHJlc29sdmVkKSB8fCByZXNvbHZlZCA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYCR7bmFtZX0gbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXJgKTtcbiAgfVxuICByZXR1cm4gcmVzb2x2ZWQ7XG59XG5cbmZ1bmN0aW9uIG5vbk5lZ2F0aXZlSW50ZWdlcih2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkLCBmYWxsYmFjazogbnVtYmVyLCBuYW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCByZXNvbHZlZCA9IHZhbHVlID8/IGZhbGxiYWNrO1xuICBpZiAoIU51bWJlci5pc0ludGVnZXIocmVzb2x2ZWQpIHx8IHJlc29sdmVkIDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGAke25hbWV9IG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlcmApO1xuICB9XG4gIHJldHVybiByZXNvbHZlZDtcbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/cache.ts","../index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,84 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbx-tools/cache",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"description": "Memory-first Cacheable and Keyv storage with project-scoped persistence and tracked write-behind",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/reggie-db/dbx-tools.git",
|
|
7
|
+
"directory": "packages/js/node/cache"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "projen build",
|
|
11
|
+
"compile": "projen compile",
|
|
12
|
+
"default": "projen default",
|
|
13
|
+
"package": "projen package",
|
|
14
|
+
"post-compile": "projen post-compile",
|
|
15
|
+
"pre-compile": "projen pre-compile",
|
|
16
|
+
"prepack": "projen prepack",
|
|
17
|
+
"test": "projen test",
|
|
18
|
+
"watch": "projen watch",
|
|
19
|
+
"projen": "projen"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^24.6.0",
|
|
23
|
+
"typescript": "^5.9.3",
|
|
24
|
+
"vitest": "3.2.4"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@dbx-tools/core": "^0.9.120",
|
|
28
|
+
"@dbx-tools/shared-core": "^0.9.120",
|
|
29
|
+
"cacheable": "2.5.0",
|
|
30
|
+
"env-paths": "^4.0.0",
|
|
31
|
+
"keyv-file": "5.3.5"
|
|
32
|
+
},
|
|
33
|
+
"main": "./lib/index.js",
|
|
34
|
+
"license": "Apache-2.0",
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"main": "./lib/index.js",
|
|
38
|
+
"types": "./lib/index.d.ts",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./lib/index.d.ts",
|
|
42
|
+
"default": "./lib/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./cache": {
|
|
45
|
+
"types": "./lib/src/cache.d.ts",
|
|
46
|
+
"default": "./lib/src/cache.js"
|
|
47
|
+
},
|
|
48
|
+
"./*": {
|
|
49
|
+
"types": "./lib/src/*/index.d.ts",
|
|
50
|
+
"default": "./lib/src/*/index.js"
|
|
51
|
+
},
|
|
52
|
+
"./package.json": "./package.json"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"version": "0.9.120",
|
|
56
|
+
"types": "./lib/index.d.ts",
|
|
57
|
+
"dbxToolsConfig": {
|
|
58
|
+
"tags": [
|
|
59
|
+
"node"
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
"type": "module",
|
|
63
|
+
"exports": {
|
|
64
|
+
".": {
|
|
65
|
+
"types": "./lib/index.d.ts",
|
|
66
|
+
"default": "./lib/index.js"
|
|
67
|
+
},
|
|
68
|
+
"./cache": {
|
|
69
|
+
"types": "./lib/src/cache.d.ts",
|
|
70
|
+
"default": "./lib/src/cache.js"
|
|
71
|
+
},
|
|
72
|
+
"./*": {
|
|
73
|
+
"types": "./lib/src/*/index.d.ts",
|
|
74
|
+
"default": "./lib/src/*/index.js"
|
|
75
|
+
},
|
|
76
|
+
"./package.json": "./package.json"
|
|
77
|
+
},
|
|
78
|
+
"files": [
|
|
79
|
+
"index.ts",
|
|
80
|
+
"src",
|
|
81
|
+
"lib"
|
|
82
|
+
],
|
|
83
|
+
"//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"bunx projen\"."
|
|
84
|
+
}
|