@mnaoumov/obsidian-lib 6.2.1 → 7.0.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.
- package/components/file-explorer-root-menu-component/package.json +6 -0
- package/data-stores/data-store-replica/package.json +6 -0
- package/data-stores/data-store-seeds/package.json +6 -0
- package/data-stores/data-store-transport/package.json +6 -0
- package/data-stores/index/package.json +6 -0
- package/data-stores/local-data-store/package.json +6 -0
- package/data-stores/package.json +6 -0
- package/data-stores/shared-data-store/package.json +6 -0
- package/dist/lib/cjs/__merged.cjs +29 -1
- package/dist/lib/cjs/__merged.d.cts +6 -0
- package/dist/lib/cjs/components/file-explorer-root-menu-component.cjs +343 -0
- package/dist/lib/cjs/components/file-explorer-root-menu-component.d.cts +125 -0
- package/dist/lib/cjs/components/index.cjs +4 -1
- package/dist/lib/cjs/components/index.d.cts +1 -0
- package/dist/lib/cjs/data-stores/data-store-replica.cjs +263 -0
- package/dist/lib/cjs/data-stores/data-store-replica.d.cts +112 -0
- package/dist/lib/cjs/data-stores/data-store-seeds.cjs +204 -0
- package/dist/lib/cjs/data-stores/data-store-seeds.d.cts +133 -0
- package/dist/lib/cjs/data-stores/data-store-transport.cjs +347 -0
- package/dist/lib/cjs/data-stores/data-store-transport.d.cts +125 -0
- package/dist/lib/cjs/data-stores/index.cjs +120 -0
- package/dist/lib/cjs/data-stores/index.d.cts +6 -0
- package/dist/lib/cjs/data-stores/local-data-store.cjs +258 -0
- package/dist/lib/cjs/data-stores/local-data-store.d.cts +119 -0
- package/dist/lib/cjs/data-stores/shared-data-store.cjs +431 -0
- package/dist/lib/cjs/data-stores/shared-data-store.d.cts +137 -0
- package/dist/lib/cjs/generated-during-build.cjs +1 -1
- package/dist/lib/cjs/index.cjs +4 -1
- package/dist/lib/cjs/index.d.cts +1 -0
- package/dist/lib/esm/__merged.d.mts +6 -0
- package/dist/lib/esm/__merged.mjs +29 -1
- package/dist/lib/esm/components/file-explorer-root-menu-component.d.mts +125 -0
- package/dist/lib/esm/components/file-explorer-root-menu-component.mjs +257 -0
- package/dist/lib/esm/components/index.d.mts +1 -0
- package/dist/lib/esm/components/index.mjs +3 -1
- package/dist/lib/esm/data-stores/data-store-replica.d.mts +112 -0
- package/dist/lib/esm/data-stores/data-store-replica.mjs +173 -0
- package/dist/lib/esm/data-stores/data-store-seeds.d.mts +133 -0
- package/dist/lib/esm/data-stores/data-store-seeds.mjs +115 -0
- package/dist/lib/esm/data-stores/data-store-transport.d.mts +125 -0
- package/dist/lib/esm/data-stores/data-store-transport.mjs +259 -0
- package/dist/lib/esm/data-stores/index.d.mts +6 -0
- package/dist/lib/esm/data-stores/index.mjs +18 -0
- package/dist/lib/esm/data-stores/local-data-store.d.mts +119 -0
- package/dist/lib/esm/data-stores/local-data-store.mjs +170 -0
- package/dist/lib/esm/data-stores/shared-data-store.d.mts +137 -0
- package/dist/lib/esm/data-stores/shared-data-store.mjs +346 -0
- package/dist/lib/esm/generated-during-build.mjs +1 -1
- package/dist/lib/esm/index.d.mts +1 -0
- package/dist/lib/esm/index.mjs +3 -1
- package/package.json +38 -17
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
(function () {
|
|
6
|
+
function ensureBrowserProcess() {
|
|
7
|
+
const browserProcess = {
|
|
8
|
+
browser: true,
|
|
9
|
+
cwd() {
|
|
10
|
+
return "/";
|
|
11
|
+
},
|
|
12
|
+
env: {},
|
|
13
|
+
platform: "android"
|
|
14
|
+
};
|
|
15
|
+
const existingProcess = globalThis.process;
|
|
16
|
+
if (!existingProcess) {
|
|
17
|
+
globalThis.process = browserProcess;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (existingProcess.versions?.node) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const existingProcessRecord = existingProcess;
|
|
24
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
25
|
+
existingProcessRecord[key] ??= value;
|
|
26
|
+
}
|
|
27
|
+
existingProcessRecord["browser"] = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ensureBrowserProcess();
|
|
31
|
+
})();
|
|
32
|
+
|
|
33
|
+
import { ensureNonNullable } from "@mnaoumov/typescript-lib/type-guards";
|
|
34
|
+
import { Notice } from "obsidian";
|
|
35
|
+
import { getObsidianLibDebugger } from "../debug.mjs";
|
|
36
|
+
const DEFAULT_MAX_FILE_BYTES = 1e6;
|
|
37
|
+
const MIN_FILE_BYTES = 256;
|
|
38
|
+
const MAX_FILE_BYTES = 4e6;
|
|
39
|
+
const DOCUMENT_PREFIX = "```json\n";
|
|
40
|
+
const DOCUMENT_SUFFIX = "\n```\n";
|
|
41
|
+
const BISECTION_DIVISOR = 2;
|
|
42
|
+
const HEX_RADIX = 16;
|
|
43
|
+
const HEX_BYTE_LENGTH = 2;
|
|
44
|
+
class DataStoreTransport {
|
|
45
|
+
/**
|
|
46
|
+
* Creates a bounded vault transport.
|
|
47
|
+
*
|
|
48
|
+
* @param params - Adapter, identity and file bounds.
|
|
49
|
+
*/
|
|
50
|
+
constructor(params) {
|
|
51
|
+
this.params = params;
|
|
52
|
+
this.adapter = params.adapter;
|
|
53
|
+
const folder = params.folder ?? "Plugin data";
|
|
54
|
+
if (!folder || folder.split("/").some((part) => !part || part.startsWith(".") || part.includes("\\")) || !/^[\w-]+$/.test(params.pluginId) || !/^[\w-]+$/.test(params.storeId)) {
|
|
55
|
+
throw new Error("Data store requires a non-dot vault folder and safe plugin/store ids");
|
|
56
|
+
}
|
|
57
|
+
this.root = `${folder}/${params.pluginId}/${params.storeId}`;
|
|
58
|
+
this.maxFileBytes = params.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES;
|
|
59
|
+
if (!Number.isSafeInteger(this.maxFileBytes) || this.maxFileBytes < MIN_FILE_BYTES || this.maxFileBytes > MAX_FILE_BYTES) {
|
|
60
|
+
throw new Error("Data-store file limit must be between 256 and 4000000 bytes");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
params;
|
|
64
|
+
/**
|
|
65
|
+
* Maximum encoded bytes per document.
|
|
66
|
+
*/
|
|
67
|
+
maxFileBytes;
|
|
68
|
+
/**
|
|
69
|
+
* Full vault-relative store root.
|
|
70
|
+
*/
|
|
71
|
+
root;
|
|
72
|
+
/**
|
|
73
|
+
* Vault adapter used by this transport.
|
|
74
|
+
*/
|
|
75
|
+
adapter;
|
|
76
|
+
/**
|
|
77
|
+
* Tests the complete encoded size without writing.
|
|
78
|
+
*
|
|
79
|
+
* @param value - JSON payload.
|
|
80
|
+
* @returns Whether its document fits the configured cap.
|
|
81
|
+
*/
|
|
82
|
+
fits(value) {
|
|
83
|
+
return new TextEncoder().encode(this.encode(value)).length <= this.maxFileBytes;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Lists the store's files recursively, never leaving its folder.
|
|
87
|
+
*
|
|
88
|
+
* @returns Vault-relative paths.
|
|
89
|
+
*/
|
|
90
|
+
async list() {
|
|
91
|
+
if (!await this.adapter.exists(this.root)) {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
const pending = [this.root];
|
|
95
|
+
const files = [];
|
|
96
|
+
while (pending.length > 0) {
|
|
97
|
+
const folder = ensureNonNullable(pending.shift());
|
|
98
|
+
const children = await this.adapter.list(folder);
|
|
99
|
+
files.push(...children.files.filter((path) => path.startsWith(`${folder}/`)));
|
|
100
|
+
pending.push(...children.folders.filter((path) => path.startsWith(`${folder}/`)));
|
|
101
|
+
}
|
|
102
|
+
return files.sort();
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Reads a complete fenced JSON document. Partial or not-yet-delivered documents are ignored.
|
|
106
|
+
*
|
|
107
|
+
* @param path - Vault-relative file within this store.
|
|
108
|
+
* @returns Parsed JSON, or `undefined` for an incomplete document.
|
|
109
|
+
*/
|
|
110
|
+
async read(path) {
|
|
111
|
+
this.checkPath(path);
|
|
112
|
+
if (!await this.adapter.exists(path)) {
|
|
113
|
+
return void 0;
|
|
114
|
+
}
|
|
115
|
+
let text;
|
|
116
|
+
try {
|
|
117
|
+
text = await this.adapter.read(path);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (!await this.adapter.exists(path)) {
|
|
120
|
+
return void 0;
|
|
121
|
+
}
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
this.checkSize(text);
|
|
125
|
+
if (!text.startsWith(DOCUMENT_PREFIX) || !text.endsWith(DOCUMENT_SUFFIX)) {
|
|
126
|
+
return void 0;
|
|
127
|
+
}
|
|
128
|
+
const parsed = JSON.parse(text.slice(DOCUMENT_PREFIX.length, -DOCUMENT_SUFFIX.length));
|
|
129
|
+
return parsed;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Reads a snapshot only after every numbered chunk arrives and passes its SHA-256 check.
|
|
133
|
+
*
|
|
134
|
+
* @param path - Vault-relative manifest path.
|
|
135
|
+
* @returns Its payload, or `undefined` while delivery is incomplete.
|
|
136
|
+
*/
|
|
137
|
+
async readSnapshot(path) {
|
|
138
|
+
const manifest = await this.read(path);
|
|
139
|
+
if (typeof manifest !== "object" || manifest === null || !("format" in manifest) || manifest.format !== 1 || !("hashes" in manifest) || !Array.isArray(manifest.hashes) || manifest.hashes.length === 0 || manifest.hashes.some((hash) => typeof hash !== "string")) {
|
|
140
|
+
return void 0;
|
|
141
|
+
}
|
|
142
|
+
const chunks = [];
|
|
143
|
+
for (const [index, hash] of manifest.hashes.entries()) {
|
|
144
|
+
const chunk = await this.read(`${path.slice(0, -".md".length)}-${String(index)}.md`);
|
|
145
|
+
if (typeof chunk !== "string" || await digest(chunk) !== hash) {
|
|
146
|
+
return void 0;
|
|
147
|
+
}
|
|
148
|
+
chunks.push(chunk);
|
|
149
|
+
}
|
|
150
|
+
const parsed = JSON.parse(chunks.join(""));
|
|
151
|
+
return parsed;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Removes a document owned by the caller's device.
|
|
155
|
+
*
|
|
156
|
+
* @param path - Vault-relative file within this store.
|
|
157
|
+
* @returns A promise that resolves after removal.
|
|
158
|
+
*/
|
|
159
|
+
async remove(path) {
|
|
160
|
+
this.checkPath(path);
|
|
161
|
+
await this.adapter.remove(path);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Writes a complete document, refusing an oversized write before adapter mutation.
|
|
165
|
+
*
|
|
166
|
+
* @param path - Vault-relative file within this store.
|
|
167
|
+
* @param value - JSON-compatible payload.
|
|
168
|
+
* @returns A promise that resolves once the adapter finishes writing.
|
|
169
|
+
*/
|
|
170
|
+
async write(path, value) {
|
|
171
|
+
this.checkPath(path);
|
|
172
|
+
const text = this.encode(value);
|
|
173
|
+
this.checkSize(text);
|
|
174
|
+
const parts = path.split("/");
|
|
175
|
+
parts.pop();
|
|
176
|
+
let folder = "";
|
|
177
|
+
for (const part of parts) {
|
|
178
|
+
folder = folder ? `${folder}/${part}` : part;
|
|
179
|
+
if (!await this.adapter.exists(folder)) {
|
|
180
|
+
try {
|
|
181
|
+
await this.adapter.mkdir(folder);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
if (!await this.adapter.exists(folder)) {
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
await this.adapter.write(path, text);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Publishes bounded immutable chunks before their manifest. Readers verify delivery completeness.
|
|
193
|
+
*
|
|
194
|
+
* @param params - Unique base path and snapshot payload.
|
|
195
|
+
* @returns A promise that resolves when the manifest has been published.
|
|
196
|
+
*/
|
|
197
|
+
async writeSnapshot(params) {
|
|
198
|
+
const payload = JSON.stringify(params.payload);
|
|
199
|
+
if (payload === void 0) {
|
|
200
|
+
throw new Error("Snapshot must be JSON-compatible");
|
|
201
|
+
}
|
|
202
|
+
const chunks = [];
|
|
203
|
+
let offset = 0;
|
|
204
|
+
while (offset < payload.length) {
|
|
205
|
+
let low = 1;
|
|
206
|
+
let high = Math.min(payload.length - offset, this.maxFileBytes);
|
|
207
|
+
while (low < high) {
|
|
208
|
+
const middle = Math.ceil((low + high) / BISECTION_DIVISOR);
|
|
209
|
+
if (this.fits(payload.slice(offset, offset + middle))) {
|
|
210
|
+
low = middle;
|
|
211
|
+
} else {
|
|
212
|
+
high = middle - 1;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
chunks.push(payload.slice(offset, offset + low));
|
|
216
|
+
offset += low;
|
|
217
|
+
}
|
|
218
|
+
const hashes = [];
|
|
219
|
+
for (const chunk of chunks) {
|
|
220
|
+
hashes.push(await digest(chunk));
|
|
221
|
+
}
|
|
222
|
+
const manifest = { format: 1, hashes };
|
|
223
|
+
this.checkSize(this.encode(manifest));
|
|
224
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
225
|
+
await this.write(`${params.base}-${String(index)}.md`, chunk);
|
|
226
|
+
}
|
|
227
|
+
await this.write(`${params.base}.md`, manifest);
|
|
228
|
+
}
|
|
229
|
+
checkPath(path) {
|
|
230
|
+
if (!path.startsWith(`${this.root}/`) || path.split("/").some((part) => !part || part.startsWith(".") || part.includes("\\"))) {
|
|
231
|
+
throw new Error("Data-store path leaves its configured folder");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
checkSize(text) {
|
|
235
|
+
const size = new TextEncoder().encode(text).length;
|
|
236
|
+
if (size <= this.maxFileBytes) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const message = `Plugin data store: ${String(size)} bytes exceeds the ${String(this.maxFileBytes)} byte file limit.`;
|
|
240
|
+
new Notice(message);
|
|
241
|
+
getObsidianLibDebugger("DataStore")(message);
|
|
242
|
+
throw new Error(message);
|
|
243
|
+
}
|
|
244
|
+
encode(value) {
|
|
245
|
+
const json = JSON.stringify(value);
|
|
246
|
+
if (json === void 0) {
|
|
247
|
+
throw new Error("Data-store payload must be JSON-compatible");
|
|
248
|
+
}
|
|
249
|
+
return `${DOCUMENT_PREFIX}${json}${DOCUMENT_SUFFIX}`;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async function digest(text) {
|
|
253
|
+
const hash = await window.crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
|
|
254
|
+
return [...new Uint8Array(hash)].map((byte) => byte.toString(HEX_RADIX).padStart(HEX_BYTE_LENGTH, "0")).join("");
|
|
255
|
+
}
|
|
256
|
+
export {
|
|
257
|
+
DataStoreTransport
|
|
258
|
+
};
|
|
259
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kYXRhLXN0b3Jlcy9kYXRhLXN0b3JlLXRyYW5zcG9ydC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbi8qKlxuICogQGZpbGVcbiAqXG4gKiBTaXplLWJvdW5kZWQgTWFya2Rvd24gdHJhbnNwb3J0IGNhcnJpZWQgYnkgdmF1bHQgc3luY2hyb25pemF0aW9uIHdpdGggZGVmYXVsdCBmaWxlIHR5cGVzLlxuICovXG5cbmltcG9ydCB0eXBlIHsgRGF0YUFkYXB0ZXIgfSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB7IGVuc3VyZU5vbk51bGxhYmxlIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL3R5cGUtZ3VhcmRzJztcbmltcG9ydCB7IE5vdGljZSB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHsgZ2V0T2JzaWRpYW5MaWJEZWJ1Z2dlciB9IGZyb20gJy4uL2RlYnVnLnRzJztcblxuY29uc3QgREVGQVVMVF9NQVhfRklMRV9CWVRFUyA9IDFfMDAwXzAwMDtcbmNvbnN0IE1JTl9GSUxFX0JZVEVTID0gMjU2O1xuY29uc3QgTUFYX0ZJTEVfQllURVMgPSA0XzAwMF8wMDA7XG5jb25zdCBET0NVTUVOVF9QUkVGSVggPSAnYGBganNvblxcbic7XG5jb25zdCBET0NVTUVOVF9TVUZGSVggPSAnXFxuYGBgXFxuJztcbmNvbnN0IEJJU0VDVElPTl9ESVZJU09SID0gMjtcbmNvbnN0IEhFWF9SQURJWCA9IDE2O1xuY29uc3QgSEVYX0JZVEVfTEVOR1RIID0gMjtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB0aGUgc2hhcmVkLXN0b3JlIHZhdWx0IHRyYW5zcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRhU3RvcmVUcmFuc3BvcnRDb25zdHJ1Y3RvclBhcmFtcyB7XG4gIC8qKlxuICAgKiBWYXVsdCBhZGFwdGVyOyBubyBkZXNrdG9wIGZpbGVzeXN0ZW0gQVBJcyBhcmUgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IGFkYXB0ZXI6IERhdGFBZGFwdGVyO1xuICAvKipcbiAgICogQ29uZmlndXJhYmxlIG5vbi1kb3QgdmF1bHQgZm9sZGVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgJ1BsdWdpbiBkYXRhJ2BcbiAgICovXG4gIHJlYWRvbmx5IGZvbGRlcj86IHN0cmluZztcbiAgLyoqXG4gICAqIE1heGltdW0gVVRGLTggYnl0ZXMgaW4gYW55IGZpbGUsIGluY2x1ZGluZyBpdHMgTWFya2Rvd24gd3JhcHBlci5cbiAgICpcbiAgICogQGRlZmF1bHQgYDEwMDAwMDBgXG4gICAqL1xuICByZWFkb25seSBtYXhGaWxlQnl0ZXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQbHVnaW4gbWFuaWZlc3QgaWQuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuICAvKipcbiAgICogU3RvcmUgbmFtZSBpbmNsdWRpbmcgaXRzIGNvbnN1bWVyIHNjaGVtYSB2ZXJzaW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RvcmVJZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHB1Ymxpc2hpbmcgYSBjaHVua2VkIHNuYXBzaG90LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFTdG9yZVRyYW5zcG9ydFdyaXRlU25hcHNob3RQYXJhbXMge1xuICAvKipcbiAgICogVmF1bHQtcmVsYXRpdmUgYmFzZSBwYXRoIHdpdGhvdXQgdGhlIGAubWRgIGV4dGVuc2lvbi4gVXNlIGEgZnJlc2ggdW5pcXVlIG5hbWUgZm9yIGV2ZXJ5IHB1YmxpY2F0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgYmFzZTogc3RyaW5nO1xuICAvKipcbiAgICogSlNPTi1jb21wYXRpYmxlIHNuYXBzaG90LCBpbmNsdWRpbmcgaXRzIGNvbnN1bWVyIHNjaGVtYSBhbmQgY292ZXJhZ2UgbWV0YWRhdGEuXG4gICAqL1xuICByZWFkb25seSBwYXlsb2FkOiB1bmtub3duO1xufVxuXG4vKipcbiAqIEEgc3RvcmUtc2NvcGVkIHRyYW5zcG9ydC4gRXZlcnkgcHVibGlzaGVkIGRvY3VtZW50IGlzIGltbXV0YWJsZSBleGNlcHQgZGV2aWNlIGFja25vd2xlZGdlbWVudHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhU3RvcmVUcmFuc3BvcnQge1xuICAvKipcbiAgICogTWF4aW11bSBlbmNvZGVkIGJ5dGVzIHBlciBkb2N1bWVudC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBtYXhGaWxlQnl0ZXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIEZ1bGwgdmF1bHQtcmVsYXRpdmUgc3RvcmUgcm9vdC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSByb290OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBWYXVsdCBhZGFwdGVyIHVzZWQgYnkgdGhpcyB0cmFuc3BvcnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYWRhcHRlcjogRGF0YUFkYXB0ZXI7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBib3VuZGVkIHZhdWx0IHRyYW5zcG9ydC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIEFkYXB0ZXIsIGlkZW50aXR5IGFuZCBmaWxlIGJvdW5kcy5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVhZG9ubHkgcGFyYW1zOiBEYXRhU3RvcmVUcmFuc3BvcnRDb25zdHJ1Y3RvclBhcmFtcykge1xuICAgIHRoaXMuYWRhcHRlciA9IHBhcmFtcy5hZGFwdGVyO1xuICAgIGNvbnN0IGZvbGRlciA9IHBhcmFtcy5mb2xkZXIgPz8gJ1BsdWdpbiBkYXRhJztcbiAgICBpZiAoXG4gICAgICAhZm9sZGVyIHx8IGZvbGRlci5zcGxpdCgnLycpLnNvbWUoKHBhcnQpID0+ICFwYXJ0IHx8IHBhcnQuc3RhcnRzV2l0aCgnLicpIHx8IHBhcnQuaW5jbHVkZXMoJ1xcXFwnKSlcbiAgICAgIHx8ICEvXltcXHctXSskLy50ZXN0KHBhcmFtcy5wbHVnaW5JZCkgfHwgIS9eW1xcdy1dKyQvLnRlc3QocGFyYW1zLnN0b3JlSWQpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RhdGEgc3RvcmUgcmVxdWlyZXMgYSBub24tZG90IHZhdWx0IGZvbGRlciBhbmQgc2FmZSBwbHVnaW4vc3RvcmUgaWRzJyk7XG4gICAgfVxuICAgIHRoaXMucm9vdCA9IGAke2ZvbGRlcn0vJHtwYXJhbXMucGx1Z2luSWR9LyR7cGFyYW1zLnN0b3JlSWR9YDtcbiAgICB0aGlzLm1heEZpbGVCeXRlcyA9IHBhcmFtcy5tYXhGaWxlQnl0ZXMgPz8gREVGQVVMVF9NQVhfRklMRV9CWVRFUztcbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHRoaXMubWF4RmlsZUJ5dGVzKSB8fCB0aGlzLm1heEZpbGVCeXRlcyA8IE1JTl9GSUxFX0JZVEVTIHx8IHRoaXMubWF4RmlsZUJ5dGVzID4gTUFYX0ZJTEVfQllURVMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRGF0YS1zdG9yZSBmaWxlIGxpbWl0IG11c3QgYmUgYmV0d2VlbiAyNTYgYW5kIDQwMDAwMDAgYnl0ZXMnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGVzdHMgdGhlIGNvbXBsZXRlIGVuY29kZWQgc2l6ZSB3aXRob3V0IHdyaXRpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIEpTT04gcGF5bG9hZC5cbiAgICogQHJldHVybnMgV2hldGhlciBpdHMgZG9jdW1lbnQgZml0cyB0aGUgY29uZmlndXJlZCBjYXAuXG4gICAqL1xuICBwdWJsaWMgZml0cyh2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUodGhpcy5lbmNvZGUodmFsdWUpKS5sZW5ndGggPD0gdGhpcy5tYXhGaWxlQnl0ZXM7XG4gIH1cblxuICAvKipcbiAgICogTGlzdHMgdGhlIHN0b3JlJ3MgZmlsZXMgcmVjdXJzaXZlbHksIG5ldmVyIGxlYXZpbmcgaXRzIGZvbGRlci5cbiAgICpcbiAgICogQHJldHVybnMgVmF1bHQtcmVsYXRpdmUgcGF0aHMuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgbGlzdCgpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgaWYgKCFhd2FpdCB0aGlzLmFkYXB0ZXIuZXhpc3RzKHRoaXMucm9vdCkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgY29uc3QgcGVuZGluZyA9IFt0aGlzLnJvb3RdO1xuICAgIGNvbnN0IGZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIHdoaWxlIChwZW5kaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGZvbGRlciA9IGVuc3VyZU5vbk51bGxhYmxlKHBlbmRpbmcuc2hpZnQoKSk7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IGF3YWl0IHRoaXMuYWRhcHRlci5saXN0KGZvbGRlcik7XG4gICAgICBmaWxlcy5wdXNoKC4uLmNoaWxkcmVuLmZpbGVzLmZpbHRlcigocGF0aCkgPT4gcGF0aC5zdGFydHNXaXRoKGAke2ZvbGRlcn0vYCkpKTtcbiAgICAgIHBlbmRpbmcucHVzaCguLi5jaGlsZHJlbi5mb2xkZXJzLmZpbHRlcigocGF0aCkgPT4gcGF0aC5zdGFydHNXaXRoKGAke2ZvbGRlcn0vYCkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGVzLnNvcnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBhIGNvbXBsZXRlIGZlbmNlZCBKU09OIGRvY3VtZW50LiBQYXJ0aWFsIG9yIG5vdC15ZXQtZGVsaXZlcmVkIGRvY3VtZW50cyBhcmUgaWdub3JlZC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBWYXVsdC1yZWxhdGl2ZSBmaWxlIHdpdGhpbiB0aGlzIHN0b3JlLlxuICAgKiBAcmV0dXJucyBQYXJzZWQgSlNPTiwgb3IgYHVuZGVmaW5lZGAgZm9yIGFuIGluY29tcGxldGUgZG9jdW1lbnQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVhZChwYXRoOiBzdHJpbmcpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICB0aGlzLmNoZWNrUGF0aChwYXRoKTtcbiAgICBpZiAoIWF3YWl0IHRoaXMuYWRhcHRlci5leGlzdHMocGF0aCkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGxldCB0ZXh0OiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIHRleHQgPSBhd2FpdCB0aGlzLmFkYXB0ZXIucmVhZChwYXRoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKCFhd2FpdCB0aGlzLmFkYXB0ZXIuZXhpc3RzKHBhdGgpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgdGhpcy5jaGVja1NpemUodGV4dCk7XG4gICAgaWYgKCF0ZXh0LnN0YXJ0c1dpdGgoRE9DVU1FTlRfUFJFRklYKSB8fCAhdGV4dC5lbmRzV2l0aChET0NVTUVOVF9TVUZGSVgpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWQ6IHVua25vd24gPSBKU09OLnBhcnNlKHRleHQuc2xpY2UoRE9DVU1FTlRfUFJFRklYLmxlbmd0aCwgLURPQ1VNRU5UX1NVRkZJWC5sZW5ndGgpKTtcbiAgICByZXR1cm4gcGFyc2VkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIGEgc25hcHNob3Qgb25seSBhZnRlciBldmVyeSBudW1iZXJlZCBjaHVuayBhcnJpdmVzIGFuZCBwYXNzZXMgaXRzIFNIQS0yNTYgY2hlY2suXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIC0gVmF1bHQtcmVsYXRpdmUgbWFuaWZlc3QgcGF0aC5cbiAgICogQHJldHVybnMgSXRzIHBheWxvYWQsIG9yIGB1bmRlZmluZWRgIHdoaWxlIGRlbGl2ZXJ5IGlzIGluY29tcGxldGUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVhZFNuYXBzaG90KHBhdGg6IHN0cmluZyk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgdGhpcy5yZWFkKHBhdGgpO1xuICAgIGlmIChcbiAgICAgIHR5cGVvZiBtYW5pZmVzdCAhPT0gJ29iamVjdCcgfHwgbWFuaWZlc3QgPT09IG51bGwgfHwgISgnZm9ybWF0JyBpbiBtYW5pZmVzdCkgfHwgbWFuaWZlc3QuZm9ybWF0ICE9PSAxXG4gICAgICB8fCAhKCdoYXNoZXMnIGluIG1hbmlmZXN0KSB8fCAhQXJyYXkuaXNBcnJheShtYW5pZmVzdC5oYXNoZXMpXG4gICAgICB8fCBtYW5pZmVzdC5oYXNoZXMubGVuZ3RoID09PSAwIHx8IG1hbmlmZXN0Lmhhc2hlcy5zb21lKChoYXNoOiB1bmtub3duKSA9PiB0eXBlb2YgaGFzaCAhPT0gJ3N0cmluZycpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBjaHVua3M6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCBbaW5kZXgsIGhhc2hdIG9mIG1hbmlmZXN0Lmhhc2hlcy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IGNodW5rID0gYXdhaXQgdGhpcy5yZWFkKGAke3BhdGguc2xpY2UoMCwgLScubWQnLmxlbmd0aCl9LSR7U3RyaW5nKGluZGV4KX0ubWRgKTtcbiAgICAgIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnIHx8IGF3YWl0IGRpZ2VzdChjaHVuaykgIT09IGhhc2gpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkOiB1bmtub3duID0gSlNPTi5wYXJzZShjaHVua3Muam9pbignJykpO1xuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGRvY3VtZW50IG93bmVkIGJ5IHRoZSBjYWxsZXIncyBkZXZpY2UuXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIC0gVmF1bHQtcmVsYXRpdmUgZmlsZSB3aXRoaW4gdGhpcyBzdG9yZS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgcmVtb3ZhbC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyByZW1vdmUocGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5jaGVja1BhdGgocGF0aCk7XG4gICAgYXdhaXQgdGhpcy5hZGFwdGVyLnJlbW92ZShwYXRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgYSBjb21wbGV0ZSBkb2N1bWVudCwgcmVmdXNpbmcgYW4gb3ZlcnNpemVkIHdyaXRlIGJlZm9yZSBhZGFwdGVyIG11dGF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aCAtIFZhdWx0LXJlbGF0aXZlIGZpbGUgd2l0aGluIHRoaXMgc3RvcmUuXG4gICAqIEBwYXJhbSB2YWx1ZSAtIEpTT04tY29tcGF0aWJsZSBwYXlsb2FkLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBhZGFwdGVyIGZpbmlzaGVzIHdyaXRpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgd3JpdGUocGF0aDogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuY2hlY2tQYXRoKHBhdGgpO1xuICAgIGNvbnN0IHRleHQgPSB0aGlzLmVuY29kZSh2YWx1ZSk7XG4gICAgdGhpcy5jaGVja1NpemUodGV4dCk7XG4gICAgY29uc3QgcGFydHMgPSBwYXRoLnNwbGl0KCcvJyk7XG4gICAgcGFydHMucG9wKCk7XG4gICAgbGV0IGZvbGRlciA9ICcnO1xuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgZm9sZGVyID0gZm9sZGVyID8gYCR7Zm9sZGVyfS8ke3BhcnR9YCA6IHBhcnQ7XG4gICAgICBpZiAoIWF3YWl0IHRoaXMuYWRhcHRlci5leGlzdHMoZm9sZGVyKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHRoaXMuYWRhcHRlci5ta2Rpcihmb2xkZXIpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGlmICghYXdhaXQgdGhpcy5hZGFwdGVyLmV4aXN0cyhmb2xkZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgYXdhaXQgdGhpcy5hZGFwdGVyLndyaXRlKHBhdGgsIHRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFB1Ymxpc2hlcyBib3VuZGVkIGltbXV0YWJsZSBjaHVua3MgYmVmb3JlIHRoZWlyIG1hbmlmZXN0LiBSZWFkZXJzIHZlcmlmeSBkZWxpdmVyeSBjb21wbGV0ZW5lc3MuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBVbmlxdWUgYmFzZSBwYXRoIGFuZCBzbmFwc2hvdCBwYXlsb2FkLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBtYW5pZmVzdCBoYXMgYmVlbiBwdWJsaXNoZWQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgd3JpdGVTbmFwc2hvdChwYXJhbXM6IERhdGFTdG9yZVRyYW5zcG9ydFdyaXRlU25hcHNob3RQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkocGFyYW1zLnBheWxvYWQpO1xuICAgIGlmIChwYXlsb2FkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU25hcHNob3QgbXVzdCBiZSBKU09OLWNvbXBhdGlibGUnKTtcbiAgICB9XG4gICAgY29uc3QgY2h1bmtzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIHdoaWxlIChvZmZzZXQgPCBwYXlsb2FkLmxlbmd0aCkge1xuICAgICAgbGV0IGxvdyA9IDE7XG4gICAgICBsZXQgaGlnaCA9IE1hdGgubWluKHBheWxvYWQubGVuZ3RoIC0gb2Zmc2V0LCB0aGlzLm1heEZpbGVCeXRlcyk7XG4gICAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgICBjb25zdCBtaWRkbGUgPSBNYXRoLmNlaWwoKGxvdyArIGhpZ2gpIC8gQklTRUNUSU9OX0RJVklTT1IpO1xuICAgICAgICBpZiAodGhpcy5maXRzKHBheWxvYWQuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBtaWRkbGUpKSkge1xuICAgICAgICAgIGxvdyA9IG1pZGRsZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdoID0gbWlkZGxlIC0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2h1bmtzLnB1c2gocGF5bG9hZC5zbGljZShvZmZzZXQsIG9mZnNldCArIGxvdykpO1xuICAgICAgb2Zmc2V0ICs9IGxvdztcbiAgICB9XG4gICAgY29uc3QgaGFzaGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2h1bmsgb2YgY2h1bmtzKSB7XG4gICAgICBoYXNoZXMucHVzaChhd2FpdCBkaWdlc3QoY2h1bmspKTtcbiAgICB9XG4gICAgY29uc3QgbWFuaWZlc3QgPSB7IGZvcm1hdDogMSwgaGFzaGVzIH07XG4gICAgdGhpcy5jaGVja1NpemUodGhpcy5lbmNvZGUobWFuaWZlc3QpKTtcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgY2h1bmtdIG9mIGNodW5rcy5lbnRyaWVzKCkpIHtcbiAgICAgIGF3YWl0IHRoaXMud3JpdGUoYCR7cGFyYW1zLmJhc2V9LSR7U3RyaW5nKGluZGV4KX0ubWRgLCBjaHVuayk7XG4gICAgfVxuICAgIGF3YWl0IHRoaXMud3JpdGUoYCR7cGFyYW1zLmJhc2V9Lm1kYCwgbWFuaWZlc3QpO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja1BhdGgocGF0aDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFwYXRoLnN0YXJ0c1dpdGgoYCR7dGhpcy5yb290fS9gKSB8fCBwYXRoLnNwbGl0KCcvJykuc29tZSgocGFydCkgPT4gIXBhcnQgfHwgcGFydC5zdGFydHNXaXRoKCcuJykgfHwgcGFydC5pbmNsdWRlcygnXFxcXCcpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdEYXRhLXN0b3JlIHBhdGggbGVhdmVzIGl0cyBjb25maWd1cmVkIGZvbGRlcicpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tTaXplKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHNpemUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUodGV4dCkubGVuZ3RoO1xuICAgIGlmIChzaXplIDw9IHRoaXMubWF4RmlsZUJ5dGVzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG1lc3NhZ2UgPSBgUGx1Z2luIGRhdGEgc3RvcmU6ICR7U3RyaW5nKHNpemUpfSBieXRlcyBleGNlZWRzIHRoZSAke1N0cmluZyh0aGlzLm1heEZpbGVCeXRlcyl9IGJ5dGUgZmlsZSBsaW1pdC5gO1xuICAgIG5ldyBOb3RpY2UobWVzc2FnZSk7XG4gICAgZ2V0T2JzaWRpYW5MaWJEZWJ1Z2dlcignRGF0YVN0b3JlJykobWVzc2FnZSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbmNvZGUodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGNvbnN0IGpzb24gPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgaWYgKGpzb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdEYXRhLXN0b3JlIHBheWxvYWQgbXVzdCBiZSBKU09OLWNvbXBhdGlibGUnKTtcbiAgICB9XG4gICAgcmV0dXJuIGAke0RPQ1VNRU5UX1BSRUZJWH0ke2pzb259JHtET0NVTUVOVF9TVUZGSVh9YDtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBkaWdlc3QodGV4dDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgaGFzaCA9IGF3YWl0IHdpbmRvdy5jcnlwdG8uc3VidGxlLmRpZ2VzdCgnU0hBLTI1NicsIG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSh0ZXh0KSk7XG4gIHJldHVybiBbLi4ubmV3IFVpbnQ4QXJyYXkoaGFzaCldLm1hcCgoYnl0ZSkgPT4gYnl0ZS50b1N0cmluZyhIRVhfUkFESVgpLnBhZFN0YXJ0KEhFWF9CWVRFX0xFTkdUSCwgJzAnKSkuam9pbignJyk7XG59XG5cbi8qIGVzbGludC1lbmFibGUgbi9uby11bnN1cHBvcnRlZC1mZWF0dXJlcy9ub2RlLWJ1aWx0aW5zIC0tIFRoZXNlIGFyZSBPYnNpZGlhbiByZW5kZXJlciBXZWIgQVBJcywgbm90IE5vZGUgYnVpbHRpbnMuICovXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBU0EsU0FBUyx5QkFBeUI7QUFDbEMsU0FBUyxjQUFjO0FBRXZCLFNBQVMsOEJBQThCO0FBRXZDLE1BQU0seUJBQXlCO0FBQy9CLE1BQU0saUJBQWlCO0FBQ3ZCLE1BQU0saUJBQWlCO0FBQ3ZCLE1BQU0sa0JBQWtCO0FBQ3hCLE1BQU0sa0JBQWtCO0FBQ3hCLE1BQU0sb0JBQW9CO0FBQzFCLE1BQU0sWUFBWTtBQUNsQixNQUFNLGtCQUFrQjtBQWlEakIsTUFBTSxtQkFBbUI7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFtQnZCLFlBQStCLFFBQTZDO0FBQTdDO0FBQ3BDLFNBQUssVUFBVSxPQUFPO0FBQ3RCLFVBQU0sU0FBUyxPQUFPLFVBQVU7QUFDaEMsUUFDRSxDQUFDLFVBQVUsT0FBTyxNQUFNLEdBQUcsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLFFBQVEsS0FBSyxXQUFXLEdBQUcsS0FBSyxLQUFLLFNBQVMsSUFBSSxDQUFDLEtBQzdGLENBQUMsV0FBVyxLQUFLLE9BQU8sUUFBUSxLQUFLLENBQUMsV0FBVyxLQUFLLE9BQU8sT0FBTyxHQUN2RTtBQUNBLFlBQU0sSUFBSSxNQUFNLHNFQUFzRTtBQUFBLElBQ3hGO0FBQ0EsU0FBSyxPQUFPLEdBQUcsTUFBTSxJQUFJLE9BQU8sUUFBUSxJQUFJLE9BQU8sT0FBTztBQUMxRCxTQUFLLGVBQWUsT0FBTyxnQkFBZ0I7QUFDM0MsUUFBSSxDQUFDLE9BQU8sY0FBYyxLQUFLLFlBQVksS0FBSyxLQUFLLGVBQWUsa0JBQWtCLEtBQUssZUFBZSxnQkFBZ0I7QUFDeEgsWUFBTSxJQUFJLE1BQU0sNkRBQTZEO0FBQUEsSUFDL0U7QUFBQSxFQUNGO0FBQUEsRUFkc0M7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWZ0QjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBSUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlHO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUE2QlosS0FBSyxPQUF5QjtBQUNuQyxXQUFPLElBQUksWUFBWSxFQUFFLE9BQU8sS0FBSyxPQUFPLEtBQUssQ0FBQyxFQUFFLFVBQVUsS0FBSztBQUFBLEVBQ3JFO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBT0EsTUFBYSxPQUEwQjtBQUNyQyxRQUFJLENBQUMsTUFBTSxLQUFLLFFBQVEsT0FBTyxLQUFLLElBQUksR0FBRztBQUN6QyxhQUFPLENBQUM7QUFBQSxJQUNWO0FBQ0EsVUFBTSxVQUFVLENBQUMsS0FBSyxJQUFJO0FBQzFCLFVBQU0sUUFBa0IsQ0FBQztBQUN6QixXQUFPLFFBQVEsU0FBUyxHQUFHO0FBQ3pCLFlBQU0sU0FBUyxrQkFBa0IsUUFBUSxNQUFNLENBQUM7QUFDaEQsWUFBTSxXQUFXLE1BQU0sS0FBSyxRQUFRLEtBQUssTUFBTTtBQUMvQyxZQUFNLEtBQUssR0FBRyxTQUFTLE1BQU0sT0FBTyxDQUFDLFNBQVMsS0FBSyxXQUFXLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUM1RSxjQUFRLEtBQUssR0FBRyxTQUFTLFFBQVEsT0FBTyxDQUFDLFNBQVMsS0FBSyxXQUFXLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUFBLElBQ2xGO0FBQ0EsV0FBTyxNQUFNLEtBQUs7QUFBQSxFQUNwQjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUUEsTUFBYSxLQUFLLE1BQWdDO0FBQ2hELFNBQUssVUFBVSxJQUFJO0FBQ25CLFFBQUksQ0FBQyxNQUFNLEtBQUssUUFBUSxPQUFPLElBQUksR0FBRztBQUNwQyxhQUFPO0FBQUEsSUFDVDtBQUNBLFFBQUk7QUFDSixRQUFJO0FBQ0YsYUFBTyxNQUFNLEtBQUssUUFBUSxLQUFLLElBQUk7QUFBQSxJQUNyQyxTQUFTLE9BQU87QUFDZCxVQUFJLENBQUMsTUFBTSxLQUFLLFFBQVEsT0FBTyxJQUFJLEdBQUc7QUFDcEMsZUFBTztBQUFBLE1BQ1Q7QUFDQSxZQUFNO0FBQUEsSUFDUjtBQUNBLFNBQUssVUFBVSxJQUFJO0FBQ25CLFFBQUksQ0FBQyxLQUFLLFdBQVcsZUFBZSxLQUFLLENBQUMsS0FBSyxTQUFTLGVBQWUsR0FBRztBQUN4RSxhQUFPO0FBQUEsSUFDVDtBQUNBLFVBQU0sU0FBa0IsS0FBSyxNQUFNLEtBQUssTUFBTSxnQkFBZ0IsUUFBUSxDQUFDLGdCQUFnQixNQUFNLENBQUM7QUFDOUYsV0FBTztBQUFBLEVBQ1Q7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE1BQWEsYUFBYSxNQUFnQztBQUN4RCxVQUFNLFdBQVcsTUFBTSxLQUFLLEtBQUssSUFBSTtBQUNyQyxRQUNFLE9BQU8sYUFBYSxZQUFZLGFBQWEsUUFBUSxFQUFFLFlBQVksYUFBYSxTQUFTLFdBQVcsS0FDakcsRUFBRSxZQUFZLGFBQWEsQ0FBQyxNQUFNLFFBQVEsU0FBUyxNQUFNLEtBQ3pELFNBQVMsT0FBTyxXQUFXLEtBQUssU0FBUyxPQUFPLEtBQUssQ0FBQyxTQUFrQixPQUFPLFNBQVMsUUFBUSxHQUNuRztBQUNBLGFBQU87QUFBQSxJQUNUO0FBQ0EsVUFBTSxTQUFtQixDQUFDO0FBQzFCLGVBQVcsQ0FBQyxPQUFPLElBQUksS0FBSyxTQUFTLE9BQU8sUUFBUSxHQUFHO0FBQ3JELFlBQU0sUUFBUSxNQUFNLEtBQUssS0FBSyxHQUFHLEtBQUssTUFBTSxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsSUFBSSxPQUFPLEtBQUssQ0FBQyxLQUFLO0FBQ25GLFVBQUksT0FBTyxVQUFVLFlBQVksTUFBTSxPQUFPLEtBQUssTUFBTSxNQUFNO0FBQzdELGVBQU87QUFBQSxNQUNUO0FBQ0EsYUFBTyxLQUFLLEtBQUs7QUFBQSxJQUNuQjtBQUNBLFVBQU0sU0FBa0IsS0FBSyxNQUFNLE9BQU8sS0FBSyxFQUFFLENBQUM7QUFDbEQsV0FBTztBQUFBLEVBQ1Q7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE1BQWEsT0FBTyxNQUE2QjtBQUMvQyxTQUFLLFVBQVUsSUFBSTtBQUNuQixVQUFNLEtBQUssUUFBUSxPQUFPLElBQUk7QUFBQSxFQUNoQztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFTQSxNQUFhLE1BQU0sTUFBYyxPQUErQjtBQUM5RCxTQUFLLFVBQVUsSUFBSTtBQUNuQixVQUFNLE9BQU8sS0FBSyxPQUFPLEtBQUs7QUFDOUIsU0FBSyxVQUFVLElBQUk7QUFDbkIsVUFBTSxRQUFRLEtBQUssTUFBTSxHQUFHO0FBQzVCLFVBQU0sSUFBSTtBQUNWLFFBQUksU0FBUztBQUNiLGVBQVcsUUFBUSxPQUFPO0FBQ3hCLGVBQVMsU0FBUyxHQUFHLE1BQU0sSUFBSSxJQUFJLEtBQUs7QUFDeEMsVUFBSSxDQUFDLE1BQU0sS0FBSyxRQUFRLE9BQU8sTUFBTSxHQUFHO0FBQ3RDLFlBQUk7QUFDRixnQkFBTSxLQUFLLFFBQVEsTUFBTSxNQUFNO0FBQUEsUUFDakMsU0FBUyxPQUFPO0FBQ2QsY0FBSSxDQUFDLE1BQU0sS0FBSyxRQUFRLE9BQU8sTUFBTSxHQUFHO0FBQ3RDLGtCQUFNO0FBQUEsVUFDUjtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUNBLFVBQU0sS0FBSyxRQUFRLE1BQU0sTUFBTSxJQUFJO0FBQUEsRUFDckM7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE1BQWEsY0FBYyxRQUE4RDtBQUN2RixVQUFNLFVBQVUsS0FBSyxVQUFVLE9BQU8sT0FBTztBQUM3QyxRQUFJLFlBQVksUUFBVztBQUN6QixZQUFNLElBQUksTUFBTSxrQ0FBa0M7QUFBQSxJQUNwRDtBQUNBLFVBQU0sU0FBbUIsQ0FBQztBQUMxQixRQUFJLFNBQVM7QUFDYixXQUFPLFNBQVMsUUFBUSxRQUFRO0FBQzlCLFVBQUksTUFBTTtBQUNWLFVBQUksT0FBTyxLQUFLLElBQUksUUFBUSxTQUFTLFFBQVEsS0FBSyxZQUFZO0FBQzlELGFBQU8sTUFBTSxNQUFNO0FBQ2pCLGNBQU0sU0FBUyxLQUFLLE1BQU0sTUFBTSxRQUFRLGlCQUFpQjtBQUN6RCxZQUFJLEtBQUssS0FBSyxRQUFRLE1BQU0sUUFBUSxTQUFTLE1BQU0sQ0FBQyxHQUFHO0FBQ3JELGdCQUFNO0FBQUEsUUFDUixPQUFPO0FBQ0wsaUJBQU8sU0FBUztBQUFBLFFBQ2xCO0FBQUEsTUFDRjtBQUNBLGFBQU8sS0FBSyxRQUFRLE1BQU0sUUFBUSxTQUFTLEdBQUcsQ0FBQztBQUMvQyxnQkFBVTtBQUFBLElBQ1o7QUFDQSxVQUFNLFNBQW1CLENBQUM7QUFDMUIsZUFBVyxTQUFTLFFBQVE7QUFDMUIsYUFBTyxLQUFLLE1BQU0sT0FBTyxLQUFLLENBQUM7QUFBQSxJQUNqQztBQUNBLFVBQU0sV0FBVyxFQUFFLFFBQVEsR0FBRyxPQUFPO0FBQ3JDLFNBQUssVUFBVSxLQUFLLE9BQU8sUUFBUSxDQUFDO0FBQ3BDLGVBQVcsQ0FBQyxPQUFPLEtBQUssS0FBSyxPQUFPLFFBQVEsR0FBRztBQUM3QyxZQUFNLEtBQUssTUFBTSxHQUFHLE9BQU8sSUFBSSxJQUFJLE9BQU8sS0FBSyxDQUFDLE9BQU8sS0FBSztBQUFBLElBQzlEO0FBQ0EsVUFBTSxLQUFLLE1BQU0sR0FBRyxPQUFPLElBQUksT0FBTyxRQUFRO0FBQUEsRUFDaEQ7QUFBQSxFQUVRLFVBQVUsTUFBb0I7QUFDcEMsUUFBSSxDQUFDLEtBQUssV0FBVyxHQUFHLEtBQUssSUFBSSxHQUFHLEtBQUssS0FBSyxNQUFNLEdBQUcsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLFFBQVEsS0FBSyxXQUFXLEdBQUcsS0FBSyxLQUFLLFNBQVMsSUFBSSxDQUFDLEdBQUc7QUFDN0gsWUFBTSxJQUFJLE1BQU0sOENBQThDO0FBQUEsSUFDaEU7QUFBQSxFQUNGO0FBQUEsRUFFUSxVQUFVLE1BQW9CO0FBQ3BDLFVBQU0sT0FBTyxJQUFJLFlBQVksRUFBRSxPQUFPLElBQUksRUFBRTtBQUM1QyxRQUFJLFFBQVEsS0FBSyxjQUFjO0FBQzdCO0FBQUEsSUFDRjtBQUNBLFVBQU0sVUFBVSxzQkFBc0IsT0FBTyxJQUFJLENBQUMsc0JBQXNCLE9BQU8sS0FBSyxZQUFZLENBQUM7QUFDakcsUUFBSSxPQUFPLE9BQU87QUFDbEIsMkJBQXVCLFdBQVcsRUFBRSxPQUFPO0FBQzNDLFVBQU0sSUFBSSxNQUFNLE9BQU87QUFBQSxFQUN6QjtBQUFBLEVBRVEsT0FBTyxPQUF3QjtBQUNyQyxVQUFNLE9BQU8sS0FBSyxVQUFVLEtBQUs7QUFDakMsUUFBSSxTQUFTLFFBQVc7QUFDdEIsWUFBTSxJQUFJLE1BQU0sNENBQTRDO0FBQUEsSUFDOUQ7QUFDQSxXQUFPLEdBQUcsZUFBZSxHQUFHLElBQUksR0FBRyxlQUFlO0FBQUEsRUFDcEQ7QUFDRjtBQUVBLGVBQWUsT0FBTyxNQUErQjtBQUNuRCxRQUFNLE9BQU8sTUFBTSxPQUFPLE9BQU8sT0FBTyxPQUFPLFdBQVcsSUFBSSxZQUFZLEVBQUUsT0FBTyxJQUFJLENBQUM7QUFDeEYsU0FBTyxDQUFDLEdBQUcsSUFBSSxXQUFXLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLEtBQUssU0FBUyxTQUFTLEVBQUUsU0FBUyxpQkFBaUIsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFO0FBQ2pIOyIsIm5hbWVzIjpbXX0=
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference path="../library-references.d.mts" />
|
|
2
|
+
export * as 'data-store-replica' from './data-store-replica.mjs';
|
|
3
|
+
export * as 'data-store-seeds' from './data-store-seeds.mjs';
|
|
4
|
+
export * as 'data-store-transport' from './data-store-transport.mjs';
|
|
5
|
+
export * as 'local-data-store' from './local-data-store.mjs';
|
|
6
|
+
export * as 'shared-data-store' from './shared-data-store.mjs';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as data_store_replica from "./data-store-replica.mjs";
|
|
7
|
+
import * as data_store_seeds from "./data-store-seeds.mjs";
|
|
8
|
+
import * as data_store_transport from "./data-store-transport.mjs";
|
|
9
|
+
import * as local_data_store from "./local-data-store.mjs";
|
|
10
|
+
import * as shared_data_store from "./shared-data-store.mjs";
|
|
11
|
+
export {
|
|
12
|
+
data_store_replica as "data-store-replica",
|
|
13
|
+
data_store_seeds as "data-store-seeds",
|
|
14
|
+
data_store_transport as "data-store-transport",
|
|
15
|
+
local_data_store as "local-data-store",
|
|
16
|
+
shared_data_store as "shared-data-store"
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL2RhdGEtc3RvcmVzL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKiBUSElTIElTIEEgR0VORVJBVEVEL0JVTkRMRUQgRklMRSBCWSBCVUlMRCBTQ1JJUFQgKi9cblxuZXhwb3J0ICogYXMgJ2RhdGEtc3RvcmUtcmVwbGljYScgZnJvbSAnLi9kYXRhLXN0b3JlLXJlcGxpY2EudHMnO1xuZXhwb3J0ICogYXMgJ2RhdGEtc3RvcmUtc2VlZHMnIGZyb20gJy4vZGF0YS1zdG9yZS1zZWVkcy50cyc7XG5leHBvcnQgKiBhcyAnZGF0YS1zdG9yZS10cmFuc3BvcnQnIGZyb20gJy4vZGF0YS1zdG9yZS10cmFuc3BvcnQudHMnO1xuZXhwb3J0ICogYXMgJ2xvY2FsLWRhdGEtc3RvcmUnIGZyb20gJy4vbG9jYWwtZGF0YS1zdG9yZS50cyc7XG5leHBvcnQgKiBhcyAnc2hhcmVkLWRhdGEtc3RvcmUnIGZyb20gJy4vc2hhcmVkLWRhdGEtc3RvcmUudHMnO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7QUFFQSxZQUFZQSx3QkFBMEI7QUFDdEMsWUFBWUMsc0JBQXdCO0FBQ3BDLFlBQVlDLDBCQUE0QjtBQUN4QyxZQUFZQyxzQkFBd0I7QUFDcEMsWUFBWUMsdUJBQXlCOyIsCiAgIm5hbWVzIjogWyJkYXRhLXN0b3JlLXJlcGxpY2EiLCAiZGF0YS1zdG9yZS1zZWVkcyIsICJkYXRhLXN0b3JlLXRyYW5zcG9ydCIsICJsb2NhbC1kYXRhLXN0b3JlIiwgInNoYXJlZC1kYXRhLXN0b3JlIl0KfQo=
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/// <reference path="../library-references.d.mts" />
|
|
2
|
+
/// <reference lib="dom" />
|
|
3
|
+
/**
|
|
4
|
+
* @file
|
|
5
|
+
*
|
|
6
|
+
* Record-based device-local persistence, isolated by vault, plugin and store.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Atomic mutations of a local record store.
|
|
10
|
+
*/
|
|
11
|
+
export interface LocalDataStoreCommitParams {
|
|
12
|
+
/**
|
|
13
|
+
* Key/value pairs to write.
|
|
14
|
+
*/
|
|
15
|
+
readonly entries: readonly (readonly [string, unknown])[];
|
|
16
|
+
/**
|
|
17
|
+
* Keys removed in the same transaction as the writes.
|
|
18
|
+
*
|
|
19
|
+
* @default `[]`
|
|
20
|
+
*/
|
|
21
|
+
readonly removedKeys?: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Parameters for opening a local store.
|
|
25
|
+
*/
|
|
26
|
+
export interface LocalDataStoreOpenParams {
|
|
27
|
+
/**
|
|
28
|
+
* IndexedDB implementation, injectable for tests.
|
|
29
|
+
*/
|
|
30
|
+
readonly factory?: IDBFactory;
|
|
31
|
+
/**
|
|
32
|
+
* Plugin manifest id.
|
|
33
|
+
*/
|
|
34
|
+
readonly pluginId: string;
|
|
35
|
+
/**
|
|
36
|
+
* Store name and schema version chosen by the consumer.
|
|
37
|
+
*/
|
|
38
|
+
readonly storeId: string;
|
|
39
|
+
/**
|
|
40
|
+
* Stable, device-local vault identity; never the vault display name.
|
|
41
|
+
*/
|
|
42
|
+
readonly vaultId: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A local store holds structured-cloneable values; it never writes to the vault.
|
|
46
|
+
*/
|
|
47
|
+
export declare class LocalDataStore {
|
|
48
|
+
private readonly database;
|
|
49
|
+
private constructor();
|
|
50
|
+
/**
|
|
51
|
+
* Opens an isolated database. Writes resolve only once their transaction commits.
|
|
52
|
+
*
|
|
53
|
+
* @param params - Store identity and optional IndexedDB implementation.
|
|
54
|
+
* @returns The connected store; close it when its owner unloads.
|
|
55
|
+
*/
|
|
56
|
+
static open(params: LocalDataStoreOpenParams): Promise<LocalDataStore>;
|
|
57
|
+
/**
|
|
58
|
+
* Deletes every record in this store only.
|
|
59
|
+
*
|
|
60
|
+
* @returns A promise that resolves after commit.
|
|
61
|
+
*/
|
|
62
|
+
clear(): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Closes this connection without deleting its records.
|
|
65
|
+
*/
|
|
66
|
+
close(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Commits several record changes atomically without serializing the rest of the database.
|
|
69
|
+
*
|
|
70
|
+
* @param params - Writes and deletions in one transaction.
|
|
71
|
+
* @returns A promise that resolves only after all changes commit.
|
|
72
|
+
*/
|
|
73
|
+
commit(params: LocalDataStoreCommitParams): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Deletes a record.
|
|
76
|
+
*
|
|
77
|
+
* @param key - Record key.
|
|
78
|
+
* @returns A promise that resolves after commit.
|
|
79
|
+
*/
|
|
80
|
+
delete(key: string): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Reads all records in key order.
|
|
83
|
+
*
|
|
84
|
+
* @returns Detached key/value pairs.
|
|
85
|
+
*/
|
|
86
|
+
entries(): Promise<[string, unknown][]>;
|
|
87
|
+
/**
|
|
88
|
+
* Serializes a shared-store operation across connections, windows and bundled library copies.
|
|
89
|
+
*
|
|
90
|
+
* @typeParam T - Callback result.
|
|
91
|
+
* @param callback - Work performed while holding this database's Web Lock.
|
|
92
|
+
* @returns The callback result after releasing the lock.
|
|
93
|
+
*/
|
|
94
|
+
exclusive<T>(callback: () => Promise<T>): Promise<T>;
|
|
95
|
+
/**
|
|
96
|
+
* Reads a record.
|
|
97
|
+
*
|
|
98
|
+
* @param key - Record key.
|
|
99
|
+
* @returns Its value, or `undefined` when absent.
|
|
100
|
+
*/
|
|
101
|
+
get(key: string): Promise<unknown>;
|
|
102
|
+
/**
|
|
103
|
+
* Initializes a record once, atomically across connections.
|
|
104
|
+
*
|
|
105
|
+
* @param key - Record key.
|
|
106
|
+
* @param value - Value used only when the key is absent.
|
|
107
|
+
* @returns The existing or newly committed value.
|
|
108
|
+
*/
|
|
109
|
+
getOrCreate(key: string, value: unknown): Promise<unknown>;
|
|
110
|
+
/**
|
|
111
|
+
* Writes a structured-cloneable value.
|
|
112
|
+
*
|
|
113
|
+
* @param key - Record key.
|
|
114
|
+
* @param value - Value to persist.
|
|
115
|
+
* @returns A promise that resolves after commit.
|
|
116
|
+
*/
|
|
117
|
+
set(key: string, value: unknown): Promise<void>;
|
|
118
|
+
private run;
|
|
119
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class LocalDataStore {
|
|
7
|
+
constructor(database) {
|
|
8
|
+
this.database = database;
|
|
9
|
+
}
|
|
10
|
+
database;
|
|
11
|
+
/**
|
|
12
|
+
* Opens an isolated database. Writes resolve only once their transaction commits.
|
|
13
|
+
*
|
|
14
|
+
* @param params - Store identity and optional IndexedDB implementation.
|
|
15
|
+
* @returns The connected store; close it when its owner unloads.
|
|
16
|
+
*/
|
|
17
|
+
static async open(params) {
|
|
18
|
+
const name = `obsidian-lib:${JSON.stringify([params.vaultId, params.pluginId, params.storeId])}`;
|
|
19
|
+
const request = (params.factory ?? indexedDB).open(name, 1);
|
|
20
|
+
return await new Promise((resolve, reject) => {
|
|
21
|
+
request.onupgradeneeded = () => {
|
|
22
|
+
request.result.createObjectStore("records");
|
|
23
|
+
};
|
|
24
|
+
request.addEventListener("error", () => {
|
|
25
|
+
reject(new Error("Could not open local data store", { cause: request.error }));
|
|
26
|
+
});
|
|
27
|
+
request.onsuccess = () => {
|
|
28
|
+
const database = request.result;
|
|
29
|
+
database.onversionchange = () => {
|
|
30
|
+
database.close();
|
|
31
|
+
};
|
|
32
|
+
resolve(new LocalDataStore(database));
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Deletes every record in this store only.
|
|
38
|
+
*
|
|
39
|
+
* @returns A promise that resolves after commit.
|
|
40
|
+
*/
|
|
41
|
+
async clear() {
|
|
42
|
+
await this.run("readwrite", (store) => store.clear());
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Closes this connection without deleting its records.
|
|
46
|
+
*/
|
|
47
|
+
close() {
|
|
48
|
+
this.database.close();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Commits several record changes atomically without serializing the rest of the database.
|
|
52
|
+
*
|
|
53
|
+
* @param params - Writes and deletions in one transaction.
|
|
54
|
+
* @returns A promise that resolves only after all changes commit.
|
|
55
|
+
*/
|
|
56
|
+
async commit(params) {
|
|
57
|
+
await this.run("readwrite", (store) => {
|
|
58
|
+
for (const key of params.removedKeys ?? []) {
|
|
59
|
+
store.delete(key);
|
|
60
|
+
}
|
|
61
|
+
for (const [key, value] of params.entries) {
|
|
62
|
+
store.put(value, key);
|
|
63
|
+
}
|
|
64
|
+
return store.count();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Deletes a record.
|
|
69
|
+
*
|
|
70
|
+
* @param key - Record key.
|
|
71
|
+
* @returns A promise that resolves after commit.
|
|
72
|
+
*/
|
|
73
|
+
async delete(key) {
|
|
74
|
+
await this.run("readwrite", (store) => store.delete(key));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Reads all records in key order.
|
|
78
|
+
*
|
|
79
|
+
* @returns Detached key/value pairs.
|
|
80
|
+
*/
|
|
81
|
+
async entries() {
|
|
82
|
+
const records = [];
|
|
83
|
+
await this.run("readonly", (store) => {
|
|
84
|
+
const request = store.openCursor();
|
|
85
|
+
request.onsuccess = () => {
|
|
86
|
+
const cursor = request.result;
|
|
87
|
+
if (!cursor) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (typeof cursor.key !== "string") {
|
|
91
|
+
throw new TypeError("Local data-store key is not a string");
|
|
92
|
+
}
|
|
93
|
+
records.push([cursor.key, cursor.value]);
|
|
94
|
+
cursor.continue();
|
|
95
|
+
};
|
|
96
|
+
return request;
|
|
97
|
+
});
|
|
98
|
+
return records;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Serializes a shared-store operation across connections, windows and bundled library copies.
|
|
102
|
+
*
|
|
103
|
+
* @typeParam T - Callback result.
|
|
104
|
+
* @param callback - Work performed while holding this database's Web Lock.
|
|
105
|
+
* @returns The callback result after releasing the lock.
|
|
106
|
+
*/
|
|
107
|
+
async exclusive(callback) {
|
|
108
|
+
return await window.navigator.locks.request(this.database.name, callback);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Reads a record.
|
|
112
|
+
*
|
|
113
|
+
* @param key - Record key.
|
|
114
|
+
* @returns Its value, or `undefined` when absent.
|
|
115
|
+
*/
|
|
116
|
+
async get(key) {
|
|
117
|
+
return await this.run("readonly", (store) => store.get(key));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Initializes a record once, atomically across connections.
|
|
121
|
+
*
|
|
122
|
+
* @param key - Record key.
|
|
123
|
+
* @param value - Value used only when the key is absent.
|
|
124
|
+
* @returns The existing or newly committed value.
|
|
125
|
+
*/
|
|
126
|
+
async getOrCreate(key, value) {
|
|
127
|
+
return await this.run("readwrite", (store) => {
|
|
128
|
+
const request = store.get(key);
|
|
129
|
+
request.onsuccess = () => {
|
|
130
|
+
if (request.result === void 0) {
|
|
131
|
+
store.put(value, key);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
return request;
|
|
135
|
+
}).then((existing) => existing === void 0 ? value : existing);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Writes a structured-cloneable value.
|
|
139
|
+
*
|
|
140
|
+
* @param key - Record key.
|
|
141
|
+
* @param value - Value to persist.
|
|
142
|
+
* @returns A promise that resolves after commit.
|
|
143
|
+
*/
|
|
144
|
+
async set(key, value) {
|
|
145
|
+
await this.run("readwrite", (store) => store.put(value, key));
|
|
146
|
+
}
|
|
147
|
+
async run(mode, action) {
|
|
148
|
+
return await new Promise((resolve, reject) => {
|
|
149
|
+
const transaction = this.database.transaction("records", mode);
|
|
150
|
+
let request;
|
|
151
|
+
try {
|
|
152
|
+
request = action(transaction.objectStore("records"));
|
|
153
|
+
} catch (error) {
|
|
154
|
+
transaction.abort();
|
|
155
|
+
reject(error instanceof Error ? error : new Error("Local data-store transaction failed", { cause: error }));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
transaction.oncomplete = () => {
|
|
159
|
+
resolve(request.result);
|
|
160
|
+
};
|
|
161
|
+
transaction.addEventListener("abort", () => {
|
|
162
|
+
reject(new Error("Local data-store transaction aborted", { cause: transaction.error }));
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
export {
|
|
168
|
+
LocalDataStore
|
|
169
|
+
};
|
|
170
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL2RhdGEtc3RvcmVzL2xvY2FsLWRhdGEtc3RvcmUudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qIGVzbGludC1kaXNhYmxlIG4vbm8tdW5zdXBwb3J0ZWQtZmVhdHVyZXMvbm9kZS1idWlsdGlucyAtLSBUaGVzZSBhcmUgT2JzaWRpYW4gcmVuZGVyZXIgV2ViIEFQSXMsIG5vdCBOb2RlIGJ1aWx0aW5zLiAqL1xuLyoqXG4gKiBAZmlsZVxuICpcbiAqIFJlY29yZC1iYXNlZCBkZXZpY2UtbG9jYWwgcGVyc2lzdGVuY2UsIGlzb2xhdGVkIGJ5IHZhdWx0LCBwbHVnaW4gYW5kIHN0b3JlLlxuICovXG5cbi8qKlxuICogQXRvbWljIG11dGF0aW9ucyBvZiBhIGxvY2FsIHJlY29yZCBzdG9yZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMb2NhbERhdGFTdG9yZUNvbW1pdFBhcmFtcyB7XG4gIC8qKlxuICAgKiBLZXkvdmFsdWUgcGFpcnMgdG8gd3JpdGUuXG4gICAqL1xuICByZWFkb25seSBlbnRyaWVzOiByZWFkb25seSAocmVhZG9ubHkgW3N0cmluZywgdW5rbm93bl0pW107XG4gIC8qKlxuICAgKiBLZXlzIHJlbW92ZWQgaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb24gYXMgdGhlIHdyaXRlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgYFtdYFxuICAgKi9cbiAgcmVhZG9ubHkgcmVtb3ZlZEtleXM/OiByZWFkb25seSBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciBvcGVuaW5nIGEgbG9jYWwgc3RvcmUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTG9jYWxEYXRhU3RvcmVPcGVuUGFyYW1zIHtcbiAgLyoqXG4gICAqIEluZGV4ZWREQiBpbXBsZW1lbnRhdGlvbiwgaW5qZWN0YWJsZSBmb3IgdGVzdHMuXG4gICAqL1xuICByZWFkb25seSBmYWN0b3J5PzogSURCRmFjdG9yeTtcbiAgLyoqXG4gICAqIFBsdWdpbiBtYW5pZmVzdCBpZC5cbiAgICovXG4gIHJlYWRvbmx5IHBsdWdpbklkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTdG9yZSBuYW1lIGFuZCBzY2hlbWEgdmVyc2lvbiBjaG9zZW4gYnkgdGhlIGNvbnN1bWVyLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RvcmVJZDogc3RyaW5nO1xuICAvKipcbiAgICogU3RhYmxlLCBkZXZpY2UtbG9jYWwgdmF1bHQgaWRlbnRpdHk7IG5ldmVyIHRoZSB2YXVsdCBkaXNwbGF5IG5hbWUuXG4gICAqL1xuICByZWFkb25seSB2YXVsdElkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBsb2NhbCBzdG9yZSBob2xkcyBzdHJ1Y3R1cmVkLWNsb25lYWJsZSB2YWx1ZXM7IGl0IG5ldmVyIHdyaXRlcyB0byB0aGUgdmF1bHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2NhbERhdGFTdG9yZSB7XG4gIHByaXZhdGUgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBkYXRhYmFzZTogSURCRGF0YWJhc2UpIHt9XG5cbiAgLyoqXG4gICAqIE9wZW5zIGFuIGlzb2xhdGVkIGRhdGFiYXNlLiBXcml0ZXMgcmVzb2x2ZSBvbmx5IG9uY2UgdGhlaXIgdHJhbnNhY3Rpb24gY29tbWl0cy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFN0b3JlIGlkZW50aXR5IGFuZCBvcHRpb25hbCBJbmRleGVkREIgaW1wbGVtZW50YXRpb24uXG4gICAqIEByZXR1cm5zIFRoZSBjb25uZWN0ZWQgc3RvcmU7IGNsb3NlIGl0IHdoZW4gaXRzIG93bmVyIHVubG9hZHMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIG9wZW4ocGFyYW1zOiBMb2NhbERhdGFTdG9yZU9wZW5QYXJhbXMpOiBQcm9taXNlPExvY2FsRGF0YVN0b3JlPiB7XG4gICAgY29uc3QgbmFtZSA9IGBvYnNpZGlhbi1saWI6JHtKU09OLnN0cmluZ2lmeShbcGFyYW1zLnZhdWx0SWQsIHBhcmFtcy5wbHVnaW5JZCwgcGFyYW1zLnN0b3JlSWRdKX1gO1xuICAgIGNvbnN0IHJlcXVlc3QgPSAocGFyYW1zLmZhY3RvcnkgPz8gaW5kZXhlZERCKS5vcGVuKG5hbWUsIDEpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICByZXF1ZXN0Lm9udXBncmFkZW5lZWRlZCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgcmVxdWVzdC5yZXN1bHQuY3JlYXRlT2JqZWN0U3RvcmUoJ3JlY29yZHMnKTtcbiAgICAgIH07XG4gICAgICByZXF1ZXN0LmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgKCk6IHZvaWQgPT4ge1xuICAgICAgICByZWplY3QobmV3IEVycm9yKCdDb3VsZCBub3Qgb3BlbiBsb2NhbCBkYXRhIHN0b3JlJywgeyBjYXVzZTogcmVxdWVzdC5lcnJvciB9KSk7XG4gICAgICB9KTtcbiAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBjb25zdCBkYXRhYmFzZSA9IHJlcXVlc3QucmVzdWx0O1xuICAgICAgICBkYXRhYmFzZS5vbnZlcnNpb25jaGFuZ2UgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgZGF0YWJhc2UuY2xvc2UoKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmVzb2x2ZShuZXcgTG9jYWxEYXRhU3RvcmUoZGF0YWJhc2UpKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBldmVyeSByZWNvcmQgaW4gdGhpcyBzdG9yZSBvbmx5LlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBjb21taXQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgY2xlYXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5ydW4oJ3JlYWR3cml0ZScsIChzdG9yZSkgPT4gc3RvcmUuY2xlYXIoKSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIHRoaXMgY29ubmVjdGlvbiB3aXRob3V0IGRlbGV0aW5nIGl0cyByZWNvcmRzLlxuICAgKi9cbiAgcHVibGljIGNsb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0YWJhc2UuY2xvc2UoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21taXRzIHNldmVyYWwgcmVjb3JkIGNoYW5nZXMgYXRvbWljYWxseSB3aXRob3V0IHNlcmlhbGl6aW5nIHRoZSByZXN0IG9mIHRoZSBkYXRhYmFzZS5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFdyaXRlcyBhbmQgZGVsZXRpb25zIGluIG9uZSB0cmFuc2FjdGlvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgb25seSBhZnRlciBhbGwgY2hhbmdlcyBjb21taXQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgY29tbWl0KHBhcmFtczogTG9jYWxEYXRhU3RvcmVDb21taXRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnJ1bigncmVhZHdyaXRlJywgKHN0b3JlKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBwYXJhbXMucmVtb3ZlZEtleXMgPz8gW10pIHtcbiAgICAgICAgc3RvcmUuZGVsZXRlKGtleSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBwYXJhbXMuZW50cmllcykge1xuICAgICAgICBzdG9yZS5wdXQodmFsdWUsIGtleSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RvcmUuY291bnQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGEgcmVjb3JkLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gUmVjb3JkIGtleS5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgY29tbWl0LlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGRlbGV0ZShrZXk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMucnVuKCdyZWFkd3JpdGUnLCAoc3RvcmUpID0+IHN0b3JlLmRlbGV0ZShrZXkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBhbGwgcmVjb3JkcyBpbiBrZXkgb3JkZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIERldGFjaGVkIGtleS92YWx1ZSBwYWlycy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBlbnRyaWVzKCk6IFByb21pc2U8W3N0cmluZywgdW5rbm93bl1bXT4ge1xuICAgIGNvbnN0IHJlY29yZHM6IFtzdHJpbmcsIHVua25vd25dW10gPSBbXTtcbiAgICBhd2FpdCB0aGlzLnJ1bigncmVhZG9ubHknLCAoc3RvcmUpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5vcGVuQ3Vyc29yKCk7XG4gICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgY3Vyc29yID0gcmVxdWVzdC5yZXN1bHQ7XG4gICAgICAgIGlmICghY3Vyc29yKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBjdXJzb3Iua2V5ICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0xvY2FsIGRhdGEtc3RvcmUga2V5IGlzIG5vdCBhIHN0cmluZycpO1xuICAgICAgICB9XG4gICAgICAgIHJlY29yZHMucHVzaChbY3Vyc29yLmtleSwgY3Vyc29yLnZhbHVlXSk7XG4gICAgICAgIGN1cnNvci5jb250aW51ZSgpO1xuICAgICAgfTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0pO1xuICAgIHJldHVybiByZWNvcmRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZXMgYSBzaGFyZWQtc3RvcmUgb3BlcmF0aW9uIGFjcm9zcyBjb25uZWN0aW9ucywgd2luZG93cyBhbmQgYnVuZGxlZCBsaWJyYXJ5IGNvcGllcy5cbiAgICpcbiAgICogQHR5cGVQYXJhbSBUIC0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBXb3JrIHBlcmZvcm1lZCB3aGlsZSBob2xkaW5nIHRoaXMgZGF0YWJhc2UncyBXZWIgTG9jay5cbiAgICogQHJldHVybnMgVGhlIGNhbGxiYWNrIHJlc3VsdCBhZnRlciByZWxlYXNpbmcgdGhlIGxvY2suXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZXhjbHVzaXZlPFQ+KGNhbGxiYWNrOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgcmV0dXJuIGF3YWl0IHdpbmRvdy5uYXZpZ2F0b3IubG9ja3MucmVxdWVzdCh0aGlzLmRhdGFiYXNlLm5hbWUsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBhIHJlY29yZC5cbiAgICpcbiAgICogQHBhcmFtIGtleSAtIFJlY29yZCBrZXkuXG4gICAqIEByZXR1cm5zIEl0cyB2YWx1ZSwgb3IgYHVuZGVmaW5lZGAgd2hlbiBhYnNlbnQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0KGtleTogc3RyaW5nKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuPHVua25vd24+KCdyZWFkb25seScsIChzdG9yZSkgPT4gc3RvcmUuZ2V0KGtleSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIGEgcmVjb3JkIG9uY2UsIGF0b21pY2FsbHkgYWNyb3NzIGNvbm5lY3Rpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IC0gUmVjb3JkIGtleS5cbiAgICogQHBhcmFtIHZhbHVlIC0gVmFsdWUgdXNlZCBvbmx5IHdoZW4gdGhlIGtleSBpcyBhYnNlbnQuXG4gICAqIEByZXR1cm5zIFRoZSBleGlzdGluZyBvciBuZXdseSBjb21taXR0ZWQgdmFsdWUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0T3JDcmVhdGUoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuPHVua25vd24+KCdyZWFkd3JpdGUnLCAoc3RvcmUpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5nZXQoa2V5KTtcbiAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAocmVxdWVzdC5yZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHN0b3JlLnB1dCh2YWx1ZSwga2V5KTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0pLnRoZW4oKGV4aXN0aW5nKSA9PiBleGlzdGluZyA9PT0gdW5kZWZpbmVkID8gdmFsdWUgOiBleGlzdGluZyk7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIGEgc3RydWN0dXJlZC1jbG9uZWFibGUgdmFsdWUuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgLSBSZWNvcmQga2V5LlxuICAgKiBAcGFyYW0gdmFsdWUgLSBWYWx1ZSB0byBwZXJzaXN0LlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBjb21taXQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMucnVuKCdyZWFkd3JpdGUnLCAoc3RvcmUpID0+IHN0b3JlLnB1dCh2YWx1ZSwga2V5KSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJ1bjxUPihtb2RlOiBJREJUcmFuc2FjdGlvbk1vZGUsIGFjdGlvbjogKHN0b3JlOiBJREJPYmplY3RTdG9yZSkgPT4gSURCUmVxdWVzdDxUPik6IFByb21pc2U8VD4ge1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuZGF0YWJhc2UudHJhbnNhY3Rpb24oJ3JlY29yZHMnLCBtb2RlKTtcbiAgICAgIGxldCByZXF1ZXN0OiBJREJSZXF1ZXN0PFQ+O1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVxdWVzdCA9IGFjdGlvbih0cmFuc2FjdGlvbi5vYmplY3RTdG9yZSgncmVjb3JkcycpKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRyYW5zYWN0aW9uLmFib3J0KCk7XG4gICAgICAgIHJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoJ0xvY2FsIGRhdGEtc3RvcmUgdHJhbnNhY3Rpb24gZmFpbGVkJywgeyBjYXVzZTogZXJyb3IgfSkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0cmFuc2FjdGlvbi5vbmNvbXBsZXRlID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICByZXNvbHZlKHJlcXVlc3QucmVzdWx0KTtcbiAgICAgIH07XG4gICAgICB0cmFuc2FjdGlvbi5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsICgpOiB2b2lkID0+IHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignTG9jYWwgZGF0YS1zdG9yZSB0cmFuc2FjdGlvbiBhYm9ydGVkJywgeyBjYXVzZTogdHJhbnNhY3Rpb24uZXJyb3IgfSkpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyogZXNsaW50LWVuYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7O0FBZ0RPLE1BQU0sZUFBZTtBQUFBLEVBQ2xCLFlBQTZCLFVBQXVCO0FBQXZCO0FBQUEsRUFBd0I7QUFBQSxFQUF4QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBUXJDLGFBQW9CLEtBQUssUUFBMkQ7QUFDbEYsVUFBTSxPQUFPLGdCQUFnQixLQUFLLFVBQVUsQ0FBQyxP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
|