sliftutils 1.4.81 → 1.4.82

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.
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
+ //exports.InMemoryDatabase = void 0;
4
+ // Rough byte size of a value, for the read/written-bytes metrics.
5
+ function sizeOf(value) {
6
+ if (value === undefined || value === null) {
7
+ return 0;
8
+ }
9
+ if (value instanceof Uint8Array) {
10
+ return value.byteLength;
11
+ }
12
+ if (typeof value === "string") {
13
+ return value.length;
14
+ }
15
+ if (typeof value === "number") {
16
+ return 8;
17
+ }
18
+ if (typeof value === "boolean") {
19
+ return 1;
20
+ }
21
+ if (Array.isArray(value)) {
22
+ let total = 0;
23
+ for (const entry of value) {
24
+ total += sizeOf(entry);
25
+ }
26
+ return total;
27
+ }
28
+ if (typeof value === "object") {
29
+ let total = 0;
30
+ const record = value;
31
+ for (const key of Object.keys(record)) {
32
+ total += sizeOf(record[key]);
33
+ }
34
+ return total;
35
+ }
36
+ return 0;
37
+ }
38
+ // Record the property path a dereference lambda walks, so a write/delete can be applied at it.
39
+ function capturePath(deref) {
40
+ const path = [];
41
+ const handler = {
42
+ get(_target, key) {
43
+ if (typeof key === "string") {
44
+ path.push(key);
45
+ }
46
+ return new Proxy({}, handler);
47
+ },
48
+ };
49
+ deref(new Proxy({}, handler));
50
+ return path;
51
+ }
52
+ function setPath(root, path, value) {
53
+ let node = root;
54
+ for (let index = 0; index < path.length - 1; index++) {
55
+ const key = path[index];
56
+ const next = node[key];
57
+ if (!next || typeof next !== "object") {
58
+ node[key] = {};
59
+ }
60
+ node = node[key];
61
+ }
62
+ node[path[path.length - 1]] = value;
63
+ }
64
+ function deletePath(root, path) {
65
+ let node = root;
66
+ for (let index = 0; index < path.length - 1; index++) {
67
+ const next = node[path[index]];
68
+ if (!next || typeof next !== "object") {
69
+ return;
70
+ }
71
+ node = next;
72
+ }
73
+ delete node[path[path.length - 1]];
74
+ }
75
+ // In-memory Database for tests/dev: holds the whole root as a plain object and counts every call plus the
76
+ // bytes flowing through. Synchronous and always "synced", so reads only return undefined for a genuinely
77
+ // missing scalar (a missing transaction set reads as empty inside the set helpers).
78
+ class InMemoryDatabase {
79
+ constructor(initial) {
80
+ this.readCalls = 0;
81
+ this.writeCalls = 0;
82
+ this.deleteCalls = 0;
83
+ this.bytesRead = 0;
84
+ this.bytesWritten = 0;
85
+ this.root = initial;
86
+ }
87
+ readData(deref) {
88
+ this.readCalls++;
89
+ const result = deref(this.root);
90
+ this.bytesRead += sizeOf(result);
91
+ return result;
92
+ }
93
+ writeData(deref, newValue) {
94
+ this.writeCalls++;
95
+ this.bytesWritten += sizeOf(newValue);
96
+ setPath(this.root, capturePath(deref), newValue);
97
+ }
98
+ deleteData(deref) {
99
+ this.deleteCalls++;
100
+ deletePath(this.root, capturePath(deref));
101
+ }
102
+ }
103
+ exports.InMemoryDatabase = InMemoryDatabase;
104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5NZW1vcnlEYXRhYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImluTWVtb3J5RGF0YWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsa0VBQWtFO0FBQ2xFLFNBQVMsTUFBTSxDQUFDLEtBQWM7SUFDMUIsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN4QyxPQUFPLENBQUMsQ0FBQztJQUNiLENBQUM7SUFDRCxJQUFJLEtBQUssWUFBWSxVQUFVLEVBQUUsQ0FBQztRQUM5QixPQUFPLEtBQUssQ0FBQyxVQUFVLENBQUM7SUFDNUIsQ0FBQztJQUNELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDNUIsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBQ3hCLENBQUM7SUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzVCLE9BQU8sQ0FBQyxDQUFDO0lBQ2IsQ0FBQztJQUNELElBQUksT0FBTyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDN0IsT0FBTyxDQUFDLENBQUM7SUFDYixDQUFDO0lBQ0QsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdkIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN4QixLQUFLLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM1QixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDZCxNQUFNLE1BQU0sR0FBRyxLQUFnQyxDQUFDO1FBQ2hELEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFN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Q0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxTQUFTLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFDRCxTQUFTLENBQVEsS0FBNEIsRUFBRSxRQUFlO1FBQzFELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsWUFBWSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN0QyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsS0FBbUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFDRCxVQUFVLENBQUMsS0FBOEI7UUFDckMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxLQUFtQyxDQUFDLENBQUMsQ0FBQztJQUM1RSxDQUFDO0NBQ0o7QUEzQkQsNENBMkJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGF0YWJhc2UgfSBmcm9tIFwiLi9EYXRhYmFzZVwiO1xuXG4vLyBSb3VnaCBieXRlIHNpemUgb2YgYSB2YWx1ZSwgZm9yIHRoZSByZWFkL3dyaXR0ZW4tYnl0ZXMgbWV0cmljcy5cbmZ1bmN0aW9uIHNpemVPZih2YWx1ZTogdW5rbm93bik6IG51bWJlciB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlLmJ5dGVMZW5ndGg7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlLmxlbmd0aDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICByZXR1cm4gODtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHZhbHVlKSB7XG4gICAgICAgICAgICB0b3RhbCArPSBzaXplT2YoZW50cnkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0b3RhbDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgICBjb25zdCByZWNvcmQgPSB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocmVjb3JkKSkge1xuICAgICAgICAgICAgdG90YWwgKz0gc2l6ZU9mKHJlY29yZFtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdG90YWw7XG4gICAgfVxuICAgIHJldHVybiAwO1xufVxuXG4vLyBSZWNvcmQgdGhlIHByb3BlcnR5IHBhdGggYSBkZXJlZmVyZW5jZSBsYW1iZGEgd2Fsa3MsIHNvIGEgd3JpdGUvZGVsZXRlIGNhbiBiZSBhcHBsaWVkIGF0IGl0LlxuZnVuY3Rpb24gY2FwdHVyZVBhdGgoZGVyZWY6IChyb290OiB1bmtub3duKSA9PiB1bmtub3duKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHBhdGg6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgaGFuZGxlcjogUHJveHlIYW5kbGVyPG9iamVjdD4gPSB7XG4gICAgICAgIGdldChfdGFyZ2V0LCBrZXkpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgcGF0aC5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb3h5KHt9LCBoYW5kbGVyKTtcbiAgICAgICAgfSxcbiAgICB9O1xuICAgIGRlcmVmKG5ldyBQcm94eSh7fSwgaGFuZGxlcikpO1xuICAgIHJldHVybiBwYXRoO1xufVxuXG5mdW5jdGlvbiBzZXRQYXRoKHJvb3Q6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBwYXRoOiBzdHJpbmdbXSwgdmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgICBsZXQgbm9kZSA9IHJvb3Q7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHBhdGgubGVuZ3RoIC0gMTsgaW5kZXgrKykge1xuICAgICAgICBjb25zdCBrZXkgPSBwYXRoW2luZGV4XTtcbiAgICAgICAgY29uc3QgbmV4dCA9IG5vZGVba2V5XTtcbiAgICAgICAgaWYgKCFuZXh0IHx8IHR5cGVvZiBuZXh0ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICBub2RlW2tleV0gPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBub2RlID0gbm9kZVtrZXldIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIH1cbiAgICBub2RlW3BhdGhbcGF0aC5sZW5ndGggLSAxXV0gPSB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gZGVsZXRlUGF0aChyb290OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgcGF0aDogc3RyaW5nW10pOiB2b2lkIHtcbiAgICBsZXQgbm9kZSA9IHJvb3Q7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHBhdGgubGVuZ3RoIC0gMTsgaW5kZXgrKykge1xuICAgICAgICBjb25zdCBuZXh0ID0gbm9kZVtwYXRoW2luZGV4XV07XG4gICAgICAgIGlmICghbmV4dCB8fCB0eXBlb2YgbmV4dCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUgPSBuZXh0IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIH1cbiAgICBkZWxldGUgbm9kZVtwYXRoW3BhdGgubGVuZ3RoIC0gMV1dO1xufVxuXG4vLyBJbi1tZW1vcnkgRGF0YWJhc2UgZm9yIHRlc3RzL2RldjogaG9sZHMgdGhlIHdob2xlIHJvb3QgYXMgYSBwbGFpbiBvYmplY3QgYW5kIGNvdW50cyBldmVyeSBjYWxsIHBsdXMgdGhlXG4vLyBieXRlcyBmbG93aW5nIHRocm91Z2guIFN5bmNocm9ub3VzIGFuZCBhbHdheXMgXCJzeW5jZWRcIiwgc28gcmVhZHMgb25seSByZXR1cm4gdW5kZWZpbmVkIGZvciBhIGdlbnVpbmVseVxuLy8gbWlzc2luZyBzY2FsYXIgKGEgbWlzc2luZyB0cmFuc2FjdGlvbiBzZXQgcmVhZHMgYXMgZW1wdHkgaW5zaWRlIHRoZSBzZXQgaGVscGVycykuXG5leHBvcnQgY2xhc3MgSW5NZW1vcnlEYXRhYmFzZTxSb290PiBpbXBsZW1lbnRzIERhdGFiYXNlPFJvb3Q+IHtcbiAgICBwdWJsaWMgcmVhZENhbGxzID0gMDtcbiAgICBwdWJsaWMgd3JpdGVDYWxscyA9IDA7XG4gICAgcHVibGljIGRlbGV0ZUNhbGxzID0gMDtcbiAgICBwdWJsaWMgYnl0ZXNSZWFkID0gMDtcbiAgICBwdWJsaWMgYnl0ZXNXcml0dGVuID0gMDtcbiAgICBwcml2YXRlIHJvb3Q6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4gICAgY29uc3RydWN0b3IoaW5pdGlhbDogUm9vdCkge1xuICAgICAgICB0aGlzLnJvb3QgPSBpbml0aWFsIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIH1cblxuICAgIHJlYWREYXRhPFZhbHVlPihkZXJlZjogKHJvb3Q6IFJvb3QpID0+IFZhbHVlKTogVmFsdWUgfCB1bmRlZmluZWQge1xuICAgICAgICB0aGlzLnJlYWRDYWxscysrO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBkZXJlZih0aGlzLnJvb3QgYXMgUm9vdCk7XG4gICAgICAgIHRoaXMuYnl0ZXNSZWFkICs9IHNpemVPZihyZXN1bHQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICB3cml0ZURhdGE8VmFsdWU+KGRlcmVmOiAocm9vdDogUm9vdCkgPT4gVmFsdWUsIG5ld1ZhbHVlOiBWYWx1ZSk6IHZvaWQge1xuICAgICAgICB0aGlzLndyaXRlQ2FsbHMrKztcbiAgICAgICAgdGhpcy5ieXRlc1dyaXR0ZW4gKz0gc2l6ZU9mKG5ld1ZhbHVlKTtcbiAgICAgICAgc2V0UGF0aCh0aGlzLnJvb3QsIGNhcHR1cmVQYXRoKGRlcmVmIGFzIChyb290OiB1bmtub3duKSA9PiB1bmtub3duKSwgbmV3VmFsdWUpO1xuICAgIH1cbiAgICBkZWxldGVEYXRhKGRlcmVmOiAocm9vdDogUm9vdCkgPT4gdW5rbm93bik6IHZvaWQge1xuICAgICAgICB0aGlzLmRlbGV0ZUNhbGxzKys7XG4gICAgICAgIGRlbGV0ZVBhdGgodGhpcy5yb290LCBjYXB0dXJlUGF0aChkZXJlZiBhcyAocm9vdDogdW5rbm93bikgPT4gdW5rbm93bikpO1xuICAgIH1cbn1cbiJdfQ==
105
+ /* _JS_SOURCE_HASH = "aa6987f940c5d431dfd1c6d9989fec9aef7d35056bea35397ec8e94982f2c3ca"; */
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const inMemoryDatabase_1 = require("./inMemoryDatabase");
8
+ const ivfEmbeddingDatabase_1 = require("./ivfEmbeddingDatabase");
9
+ const embeddingFormats_1 = require("../embeddingFormats");
10
+ const faceFramesData_1 = require("../faceFramesData");
11
+ // Exercises the tiered IVF embedding database through the in-memory Database wrapper, which counts every
12
+ // read/write/delete call and the bytes through each, across dataset sizes and load patterns, with timing.
13
+ const DIM = 512;
14
+ const FILE_NAME = "faceFrames2_full.f32";
15
+ const MODEL = "buffalo_l";
16
+ const FORMAT = "q8g8_2048";
17
+ async function loadFloats(count) {
18
+ const byteLength = count * DIM * 4;
19
+ const filePath = await (0, faceFramesData_1.ensureFaceData)(FILE_NAME, byteLength);
20
+ const buffer = Buffer.alloc(byteLength);
21
+ const handle = fs_1.default.openSync(filePath, "r");
22
+ fs_1.default.readSync(handle, buffer, 0, byteLength, 0);
23
+ fs_1.default.closeSync(handle);
24
+ return new Float32Array(buffer.buffer, buffer.byteOffset, count * DIM);
25
+ }
26
+ async function buildInputs(count) {
27
+ const floats = await loadFloats(count);
28
+ const inputs = [];
29
+ for (let index = 0; index < count; index++) {
30
+ const slice = floats.subarray(index * DIM, (index + 1) * DIM);
31
+ inputs.push({ ref: "e" + index, embedding: (0, embeddingFormats_1.encodeEmbedding)({ input: slice, format: FORMAT, model: MODEL }) });
32
+ }
33
+ return inputs;
34
+ }
35
+ function freshDatabase(config) {
36
+ const root = { config, count: 0, flat: {}, steps: {}, centroids: {}, cells: {} };
37
+ return new inMemoryDatabase_1.InMemoryDatabase(root);
38
+ }
39
+ function pad(value, width) {
40
+ return String(value).padStart(width);
41
+ }
42
+ async function main() {
43
+ const config = { model: MODEL, format: FORMAT, cellTargetSize: 128 };
44
+ const runs = [
45
+ { size: 10000, batch: 1 },
46
+ { size: 10000, batch: 100 },
47
+ { size: 100000, batch: 1000 },
48
+ ];
49
+ let maxSize = 0;
50
+ for (const run of runs) {
51
+ if (run.size > maxSize) {
52
+ maxSize = run.size;
53
+ }
54
+ }
55
+ const loadStart = Date.now();
56
+ const allInputs = await buildInputs(maxSize);
57
+ console.log(`loaded + encoded ${maxSize} embeddings in ${((Date.now() - loadStart) / 1000).toFixed(1)}s\n`);
58
+ console.log(`${pad("added", 7)} ${pad("batch", 5)} | ${pad("secs", 7)} ${pad("reads", 8)} ${pad("writes", 8)} ${pad("deletes", 8)} ${pad("readMB", 9)} ${pad("writeMB", 8)} | recall`);
59
+ for (const run of runs) {
60
+ const database = freshDatabase(config);
61
+ const start = Date.now();
62
+ for (let offset = 0; offset < run.size; offset += run.batch) {
63
+ (0, ivfEmbeddingDatabase_1.insertEmbeddings)(database, allInputs.slice(offset, offset + run.batch));
64
+ }
65
+ const seconds = (Date.now() - start) / 1000;
66
+ let found = 0;
67
+ const sampleCount = 100;
68
+ for (let index = 0; index < sampleCount; index++) {
69
+ const query = allInputs[Math.floor(index * run.size / sampleCount)];
70
+ const hits = (0, ivfEmbeddingDatabase_1.searchEmbeddings)(database, query.embedding, { probeBudget: 512, resultCount: 1 });
71
+ if (hits && hits.length && hits[0].ref === query.ref) {
72
+ found++;
73
+ }
74
+ }
75
+ const recall = (found / sampleCount).toFixed(2);
76
+ console.log(`${pad(run.size, 7)} ${pad(run.batch, 5)} | ${pad(seconds.toFixed(1), 7)} ${pad(database.readCalls, 8)} ${pad(database.writeCalls, 8)} ${pad(database.deleteCalls, 8)} ${pad((database.bytesRead / 1e6).toFixed(0), 9)} ${pad((database.bytesWritten / 1e6).toFixed(0), 8)} | ${recall}`);
77
+ }
78
+ }
79
+ main();
80
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXZmRGJDaGVjay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIml2ZkRiQ2hlY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw0Q0FBb0I7QUFDcEIseURBQXNEO0FBQ3RELGlFQUF5SDtBQUN6SCwwREFBdUU7QUFDdkUsc0RBQW1EO0FBRW5ELHlHQUF5RztBQUN6RywwR0FBMEc7QUFFMUcsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLE1BQU0sU0FBUyxHQUFHLHNCQUFzQixDQUFDO0FBQ3pDLE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQztBQUMxQixNQUFNLE1BQU0sR0FBb0IsV0FBVyxDQUFDO0FBRTVDLEtBQUssVUFBVSxVQUFVLENBQUMsS0FBYTtJQUNuQyxNQUFNLFVBQVUsR0FBRyxLQUFLLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztJQUNuQyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUEsK0JBQWMsRUFBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDN0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN4QyxNQUFNLE1BQU0sR0FBRyxZQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUMxQyxZQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM5QyxZQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JCLE9BQU8sSUFBSSxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztBQUMzRSxDQUFDO0FBRUQsS0FBSyxVQUFVLFdBQVcsQ0FBQyxLQUFhO0lBQ3BDLE1BQU0sTUFBTSxHQUFHLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFD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QUNaLENBQUM7UUFDTCxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hELE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzFTLENBQUM7QUFDTCxDQUFDO0FBRUQsSUFBSSxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBJbk1lbW9yeURhdGFiYXNlIH0gZnJvbSBcIi4vaW5NZW1vcnlEYXRhYmFzZVwiO1xuaW1wb3J0IHsgSXZmRW1iZWRkaW5nUm9vdCwgSXZmQ29uZmlnLCBFbWJlZGRpbmdJbnB1dCwgaW5zZXJ0RW1iZWRkaW5ncywgc2VhcmNoRW1iZWRkaW5ncyB9IGZyb20gXCIuL2l2ZkVtYmVkZGluZ0RhdGFiYXNlXCI7XG5pbXBvcnQgeyBlbmNvZGVFbWJlZGRpbmcsIEVtYmVkZGluZ0Zvcm1hdCB9IGZyb20gXCIuLi9lbWJlZGRpbmdGb3JtYXRzXCI7XG5pbXBvcnQgeyBlbnN1cmVGYWNlRGF0YSB9IGZyb20gXCIuLi9mYWNlRnJhbWVzRGF0YVwiO1xuXG4vLyBFeGVyY2lzZXMgdGhlIHRpZXJlZCBJVkYgZW1iZWRkaW5nIGRhdGFiYXNlIHRocm91Z2ggdGhlIGluLW1lbW9yeSBEYXRhYmFzZSB3cmFwcGVyLCB3aGljaCBjb3VudHMgZXZlcnlcbi8vIHJlYWQvd3JpdGUvZGVsZXRlIGNhbGwgYW5kIHRoZSBieXRlcyB0aHJvdWdoIGVhY2gsIGFjcm9zcyBkYXRhc2V0IHNpemVzIGFuZCBsb2FkIHBhdHRlcm5zLCB3aXRoIHRpbWluZy5cblxuY29uc3QgRElNID0gNTEyO1xuY29uc3QgRklMRV9OQU1FID0gXCJmYWNlRnJhbWVzMl9mdWxsLmYzMlwiO1xuY29uc3QgTU9ERUwgPSBcImJ1ZmZhbG9fbFwiO1xuY29uc3QgRk9STUFUOiBFbWJlZGRpbmdGb3JtYXQgPSBcInE4ZzhfMjA0OFwiO1xuXG5hc3luYyBmdW5jdGlvbiBsb2FkRmxvYXRzKGNvdW50OiBudW1iZXIpOiBQcm9taXNlPEZsb2F0MzJBcnJheT4ge1xuICAgIGNvbnN0IGJ5dGVMZW5ndGggPSBjb3VudCAqIERJTSAqIDQ7XG4gICAgY29uc3QgZmlsZVBhdGggPSBhd2FpdCBlbnN1cmVGYWNlRGF0YShGSUxFX05BTUUsIGJ5dGVMZW5ndGgpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhieXRlTGVuZ3RoKTtcbiAgICBjb25zdCBoYW5kbGUgPSBmcy5vcGVuU3luYyhmaWxlUGF0aCwgXCJyXCIpO1xuICAgIGZzLnJlYWRTeW5jKGhhbmRsZSwgYnVmZmVyLCAwLCBieXRlTGVuZ3RoLCAwKTtcbiAgICBmcy5jbG9zZVN5bmMoaGFuZGxlKTtcbiAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBidWZmZXIuYnl0ZU9mZnNldCwgY291bnQgKiBESU0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBidWlsZElucHV0cyhjb3VudDogbnVtYmVyKTogUHJvbWlzZTxFbWJlZGRpbmdJbnB1dFtdPiB7XG4gICAgY29uc3QgZmxvYXRzID0gYXdhaXQgbG9hZEZsb2F0cyhjb3VudCk7XG4gICAgY29uc3QgaW5wdXRzOiBFbWJlZGRpbmdJbnB1dFtdID0gW107XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGNvdW50OyBpbmRleCsrKSB7XG4gICAgICAgIGNvbnN0IHNsaWNlID0gZmxvYXRzLnN1YmFycmF5KGluZGV4ICogRElNLCAoaW5kZXggKyAxKSAqIERJTSk7XG4gICAgICAgIGlucHV0cy5wdXNoKHsgcmVmOiBcImVcIiArIGluZGV4LCBlbWJlZGRpbmc6IGVuY29kZUVtYmVkZGluZyh7IGlucHV0OiBzbGljZSwgZm9ybWF0OiBGT1JNQVQsIG1vZGVsOiBNT0RFTCB9KSB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGlucHV0cztcbn1cblxuZnVuY3Rpb24gZnJlc2hEYXRhYmFzZShjb25maWc6IEl2ZkNvbmZpZyk6IEluTWVtb3J5RGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4ge1xuICAgIGNvbnN0IHJvb3Q6IEl2ZkVtYmVkZGluZ1Jvb3QgPSB7IGNvbmZpZywgY291bnQ6IDAsIGZsYXQ6IHt9LCBzdGVwczoge30sIGNlbnRyb2lkczoge30sIGNlbGxzOiB7fSB9O1xuICAgIHJldHVybiBuZXcgSW5NZW1vcnlEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290Pihyb290KTtcbn1cblxuZnVuY3Rpb24gcGFkKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIsIHdpZHRoOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBTdHJpbmcodmFsdWUpLnBhZFN0YXJ0KHdpZHRoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbWFpbigpIHtcbiAgICBjb25zdCBjb25maWc6IEl2ZkNvbmZpZyA9IHsgbW9kZWw6IE1PREVMLCBmb3JtYXQ6IEZPUk1BVCwgY2VsbFRhcmdldFNpemU6IDEyOCB9O1xuICAgIGNvbnN0IHJ1bnM6IHsgc2l6ZTogbnVtYmVyOyBiYXRjaDogbnVtYmVyIH1bXSA9IFtcbiAgICAgICAgeyBzaXplOiAxMDAwMCwgYmF0Y2g6IDEgfSxcbiAgICAgICAgeyBzaXplOiAxMDAwMCwgYmF0Y2g6IDEwMCB9LFxuICAgICAgICB7IHNpemU6IDEwMDAwMCwgYmF0Y2g6IDEwMDAgfSxcbiAgICBdO1xuXG4gICAgbGV0IG1heFNpemUgPSAwO1xuICAgIGZvciAoY29uc3QgcnVuIG9mIHJ1bnMpIHtcbiAgICAgICAgaWYgKHJ1bi5zaXplID4gbWF4U2l6ZSkge1xuICAgICAgICAgICAgbWF4U2l6ZSA9IHJ1bi5zaXplO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGxvYWRTdGFydCA9IERhdGUubm93KCk7XG4gICAgY29uc3QgYWxsSW5wdXRzID0gYXdhaXQgYnVpbGRJbnB1dHMobWF4U2l6ZSk7XG4gICAgY29uc29sZS5sb2coYGxvYWRlZCArIGVuY29kZWQgJHttYXhTaXplfSBlbWJlZGRpbmdzIGluICR7KChEYXRlLm5vdygpIC0gbG9hZFN0YXJ0KSAvIDEwMDApLnRvRml4ZWQoMSl9c1xcbmApO1xuXG4gICAgY29uc29sZS5sb2coYCR7cGFkKFwiYWRkZWRcIiwgNyl9ICR7cGFkKFwiYmF0Y2hcIiwgNSl9IHwgJHtwYWQoXCJzZWNzXCIsIDcpfSAke3BhZChcInJlYWRzXCIsIDgpfSAke3BhZChcIndyaXRlc1wiLCA4KX0gJHtwYWQoXCJkZWxldGVzXCIsIDgpfSAke3BhZChcInJlYWRNQlwiLCA5KX0gJHtwYWQoXCJ3cml0ZU1CXCIsIDgpfSB8IHJlY2FsbGApO1xuICAgIGZvciAoY29uc3QgcnVuIG9mIHJ1bnMpIHtcbiAgICAgICAgY29uc3QgZGF0YWJhc2UgPSBmcmVzaERhdGFiYXNlKGNvbmZpZyk7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgcnVuLnNpemU7IG9mZnNldCArPSBydW4uYmF0Y2gpIHtcbiAgICAgICAgICAgIGluc2VydEVtYmVkZGluZ3MoZGF0YWJhc2UsIGFsbElucHV0cy5zbGljZShvZmZzZXQsIG9mZnNldCArIHJ1bi5iYXRjaCkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSAoRGF0ZS5ub3coKSAtIHN0YXJ0KSAvIDEwMDA7XG5cbiAgICAgICAgbGV0IGZvdW5kID0gMDtcbiAgICAgICAgY29uc3Qgc2FtcGxlQ291bnQgPSAxMDA7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBzYW1wbGVDb3VudDsgaW5kZXgrKykge1xuICAgICAgICAgICAgY29uc3QgcXVlcnkgPSBhbGxJbnB1dHNbTWF0aC5mbG9vcihpbmRleCAqIHJ1bi5zaXplIC8gc2FtcGxlQ291bnQpXTtcbiAgICAgICAgICAgIGNvbnN0IGhpdHMgPSBzZWFyY2hFbWJlZGRpbmdzKGRhdGFiYXNlLCBxdWVyeS5lbWJlZGRpbmcsIHsgcHJvYmVCdWRnZXQ6IDUxMiwgcmVzdWx0Q291bnQ6IDEgfSk7XG4gICAgICAgICAgICBpZiAoaGl0cyAmJiBoaXRzLmxlbmd0aCAmJiBoaXRzWzBdLnJlZiA9PT0gcXVlcnkucmVmKSB7XG4gICAgICAgICAgICAgICAgZm91bmQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZWNhbGwgPSAoZm91bmQgLyBzYW1wbGVDb3VudCkudG9GaXhlZCgyKTtcbiAgICAgICAgY29uc29sZS5sb2coYCR7cGFkKHJ1bi5zaXplLCA3KX0gJHtwYWQocnVuLmJhdGNoLCA1KX0gfCAke3BhZChzZWNvbmRzLnRvRml4ZWQoMSksIDcpfSAke3BhZChkYXRhYmFzZS5yZWFkQ2FsbHMsIDgpfSAke3BhZChkYXRhYmFzZS53cml0ZUNhbGxzLCA4KX0gJHtwYWQoZGF0YWJhc2UuZGVsZXRlQ2FsbHMsIDgpfSAke3BhZCgoZGF0YWJhc2UuYnl0ZXNSZWFkIC8gMWU2KS50b0ZpeGVkKDApLCA5KX0gJHtwYWQoKGRhdGFiYXNlLmJ5dGVzV3JpdHRlbiAvIDFlNikudG9GaXhlZCgwKSwgOCl9IHwgJHtyZWNhbGx9YCk7XG4gICAgfVxufVxuXG5tYWluKCk7XG4iXX0//=
81
+ /* _JS_SOURCE_HASH = "31db07ffef35ecca7578f435bb6db898fafcf77607d50d5ffd52abaf2d4a1490"; */
@@ -0,0 +1,334 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
+ //exports.removeEmbeddings = exports.insertEmbeddings = exports.searchEmbeddings = exports.rebuildStructure = void 0;
4
+ const Database_1 = require("./Database");
5
+ const transactionSet_1 = require("./transactionSet");
6
+ const embeddingFormats_1 = require("../embeddingFormats");
7
+ // Below this many embeddings we skip the IVF entirely (flat store). 1024 = a clean power of two.
8
+ const FLAT_LIMIT = 1024;
9
+ // Force a from-scratch rebuild once at each of these (multiples of 4 above FLAT_LIMIT, up to ~16k), gated by a step flag so each runs at most once ever.
10
+ const REGENERATE_AT = [4096, 16384];
11
+ const STEP_IVF = "ivf";
12
+ // On delete, the member's exact cell plus this many nearby cells are checked, in case a rebuild left it non-optimal.
13
+ const DELETE_FALLBACK_CELLS = 10;
14
+ const REBALANCE_ITERATIONS = 4;
15
+ function flatStore(database) {
16
+ return (0, Database_1.namespaceDatabase)(database, root => root.flat);
17
+ }
18
+ function centroidStore(database) {
19
+ return (0, Database_1.namespaceDatabase)(database, root => root.centroids);
20
+ }
21
+ function cellStore(database, cellId) {
22
+ return (0, Database_1.namespaceDatabase)(database, root => root.cells[cellId]);
23
+ }
24
+ function readSteps(database) {
25
+ var _a;
26
+ return (_a = database.readData(root => root.steps)) !== null && _a !== void 0 ? _a : {};
27
+ }
28
+ function readCount(database) {
29
+ var _a;
30
+ return (_a = database.readData(root => root.count)) !== null && _a !== void 0 ? _a : 0;
31
+ }
32
+ function rankCellsByCloseness(embedding, centroids) {
33
+ const ranked = [];
34
+ for (const cellId of centroids.keys()) {
35
+ ranked.push({ cellId, closeness: (0, embeddingFormats_1.getCloseness)(embedding, centroids.get(cellId)) });
36
+ }
37
+ ranked.sort((left, right) => right.closeness - left.closeness);
38
+ return ranked.map(entry => entry.cellId);
39
+ }
40
+ // Per-write chance of a full rebuild. Zero at/under the target size, then rises (cubically) past it so cells
41
+ // stay roughly between target and ~2x target.
42
+ function rebalanceProbability(fillRatio) {
43
+ if (fillRatio <= 1) {
44
+ return 0;
45
+ }
46
+ const over = fillRatio - 1;
47
+ return Math.min(1, over * over * over * 0.25);
48
+ }
49
+ // k-means. Decodes every member to a pooled float32 buffer ONCE, then assigns with a plain internal float
50
+ // dot (no getCloseness call — comparing two float vectors is trivial) and keeps centroids as float means,
51
+ // encoding them to StoredEmbedding only at the end. Releases the borrowed buffers when done.
52
+ function clusterMembers(members, clusterCount, config) {
53
+ const memberFloats = [];
54
+ for (const member of members) {
55
+ memberFloats.push((0, embeddingFormats_1.embeddingToFloat32)(member.embedding, true));
56
+ }
57
+ const length = memberFloats.length ? memberFloats[0].length : 0;
58
+ let centroids = [];
59
+ const seedStep = members.length / clusterCount;
60
+ for (let clusterIndex = 0; clusterIndex < clusterCount; clusterIndex++) {
61
+ centroids.push(new Float32Array(memberFloats[Math.floor(clusterIndex * seedStep)]));
62
+ }
63
+ let groups = [];
64
+ for (let iteration = 0; iteration < REBALANCE_ITERATIONS; iteration++) {
65
+ groups = [];
66
+ for (let clusterIndex = 0; clusterIndex < centroids.length; clusterIndex++) {
67
+ groups.push([]);
68
+ }
69
+ for (let memberIndex = 0; memberIndex < memberFloats.length; memberIndex++) {
70
+ const memberFloat = memberFloats[memberIndex];
71
+ let bestIndex = 0;
72
+ let bestDot = -Infinity;
73
+ for (let centroidIndex = 0; centroidIndex < centroids.length; centroidIndex++) {
74
+ const centroidFloat = centroids[centroidIndex];
75
+ let dot = 0;
76
+ for (let dim = 0; dim < length; dim++) {
77
+ dot += memberFloat[dim] * centroidFloat[dim];
78
+ }
79
+ if (dot > bestDot) {
80
+ bestDot = dot;
81
+ bestIndex = centroidIndex;
82
+ }
83
+ }
84
+ groups[bestIndex].push(memberIndex);
85
+ }
86
+ const nextCentroids = [];
87
+ const nextGroups = [];
88
+ for (const group of groups) {
89
+ if (!group.length) {
90
+ continue;
91
+ }
92
+ const mean = new Float32Array(length);
93
+ for (const memberIndex of group) {
94
+ const memberFloat = memberFloats[memberIndex];
95
+ for (let dim = 0; dim < length; dim++) {
96
+ mean[dim] += memberFloat[dim];
97
+ }
98
+ }
99
+ let norm = 0;
100
+ for (let dim = 0; dim < length; dim++) {
101
+ norm += mean[dim] * mean[dim];
102
+ }
103
+ const magnitude = Math.sqrt(norm) || 1;
104
+ for (let dim = 0; dim < length; dim++) {
105
+ mean[dim] /= magnitude;
106
+ }
107
+ nextCentroids.push(mean);
108
+ nextGroups.push(group);
109
+ }
110
+ centroids = nextCentroids;
111
+ groups = nextGroups;
112
+ }
113
+ const result = [];
114
+ for (let clusterIndex = 0; clusterIndex < centroids.length; clusterIndex++) {
115
+ const centroid = (0, embeddingFormats_1.encodeEmbedding)({ input: centroids[clusterIndex], format: config.format, model: config.model });
116
+ const cellMembers = [];
117
+ for (const memberIndex of groups[clusterIndex]) {
118
+ cellMembers.push(members[memberIndex]);
119
+ }
120
+ result.push({ centroid, members: cellMembers });
121
+ }
122
+ for (const memberFloat of memberFloats) {
123
+ (0, embeddingFormats_1.releaseFloat32)(memberFloat);
124
+ }
125
+ return result;
126
+ }
127
+ // Re-cluster EVERY embedding (flat tier + all cells) into a fresh IVF, clear the flat tier, and mark IVF
128
+ // mode. This is the rearranger: run probabilistically as the set grows, once at each regenerate threshold,
129
+ // and once to upgrade from flat. Reads everything it uses, so it bails (does nothing) if anything isn't
130
+ // synced and the caller's retry re-runs it; no caller cares about its result.
131
+ function rebuildStructure(database) {
132
+ const config = database.readData(root => root.config);
133
+ if (!config)
134
+ return;
135
+ const allMembers = [];
136
+ const flat = (0, transactionSet_1.transactionRead)(flatStore(database));
137
+ if (!flat)
138
+ return;
139
+ for (const ref of flat.keys()) {
140
+ allMembers.push({ ref, embedding: flat.get(ref) });
141
+ }
142
+ const centroids = (0, transactionSet_1.transactionRead)(centroidStore(database));
143
+ if (!centroids)
144
+ return;
145
+ const oldCellIds = Array.from(centroids.keys());
146
+ const cellStores = database.readData(root => oldCellIds.map(cellId => root.cells[cellId]));
147
+ if (!cellStores)
148
+ return;
149
+ for (const store of cellStores) {
150
+ const members = (0, transactionSet_1.replayTransactionStore)(store);
151
+ for (const ref of members.keys()) {
152
+ allMembers.push({ ref, embedding: members.get(ref) });
153
+ }
154
+ }
155
+ if (!allMembers.length)
156
+ return;
157
+ const clusterCount = Math.max(1, Math.round(allMembers.length / config.cellTargetSize));
158
+ const clusters = clusterMembers(allMembers, clusterCount, config);
159
+ const newCellIds = new Set();
160
+ const centroidWrites = [];
161
+ for (const cluster of clusters) {
162
+ const cellId = (0, embeddingFormats_1.hashEmbedding)(cluster.centroid);
163
+ newCellIds.add(cellId);
164
+ centroidWrites.push({ key: cellId, value: cluster.centroid });
165
+ const memberWrites = cluster.members.map(member => ({ key: member.ref, value: member.embedding }));
166
+ (0, transactionSet_1.transactionMutate)(cellStore(database, cellId), memberWrites);
167
+ }
168
+ for (const oldCellId of oldCellIds) {
169
+ if (newCellIds.has(oldCellId)) {
170
+ continue;
171
+ }
172
+ centroidWrites.push({ key: oldCellId, value: undefined });
173
+ database.deleteData(root => root.cells[oldCellId]);
174
+ }
175
+ (0, transactionSet_1.transactionMutate)(centroidStore(database), centroidWrites);
176
+ database.deleteData(root => root.flat);
177
+ database.writeData(root => root.count, allMembers.length);
178
+ database.writeData(root => root.steps[STEP_IVF], true);
179
+ }
180
+ exports.rebuildStructure = rebuildStructure;
181
+ function searchEmbeddings(database, query, options) {
182
+ const config = database.readData(root => root.config);
183
+ if (!config)
184
+ return undefined;
185
+ const steps = readSteps(database);
186
+ const hits = [];
187
+ if (!steps[STEP_IVF]) {
188
+ const flat = (0, transactionSet_1.transactionRead)(flatStore(database));
189
+ if (!flat)
190
+ return undefined;
191
+ for (const ref of flat.keys()) {
192
+ hits.push({ ref, closeness: (0, embeddingFormats_1.getCloseness)(query, flat.get(ref)) });
193
+ }
194
+ hits.sort((left, right) => right.closeness - left.closeness);
195
+ return hits.slice(0, options.resultCount);
196
+ }
197
+ const centroids = (0, transactionSet_1.transactionRead)(centroidStore(database));
198
+ if (!centroids)
199
+ return undefined;
200
+ if (!centroids.size)
201
+ return [];
202
+ const probeCellCount = Math.max(1, Math.ceil(options.probeBudget / config.cellTargetSize));
203
+ const probeCellIds = rankCellsByCloseness(query, centroids).slice(0, probeCellCount);
204
+ const stores = database.readData(root => probeCellIds.map(cellId => root.cells[cellId]));
205
+ if (!stores)
206
+ return undefined;
207
+ for (const store of stores) {
208
+ const members = (0, transactionSet_1.replayTransactionStore)(store);
209
+ for (const ref of members.keys()) {
210
+ hits.push({ ref, closeness: (0, embeddingFormats_1.getCloseness)(query, members.get(ref)) });
211
+ }
212
+ }
213
+ hits.sort((left, right) => right.closeness - left.closeness);
214
+ return hits.slice(0, options.resultCount);
215
+ }
216
+ exports.searchEmbeddings = searchEmbeddings;
217
+ function insertEmbeddings(database, items) {
218
+ if (!items.length)
219
+ return true;
220
+ const config = database.readData(root => root.config);
221
+ if (!config)
222
+ return undefined;
223
+ const steps = readSteps(database);
224
+ const newCount = readCount(database) + items.length;
225
+ if (!steps[STEP_IVF]) {
226
+ const flatWrites = items.map(item => ({ key: item.ref, value: item.embedding }));
227
+ (0, transactionSet_1.transactionMutate)(flatStore(database), flatWrites);
228
+ database.writeData(root => root.count, newCount);
229
+ if (newCount > FLAT_LIMIT) {
230
+ rebuildStructure(database);
231
+ }
232
+ return true;
233
+ }
234
+ const centroids = (0, transactionSet_1.transactionRead)(centroidStore(database));
235
+ if (!centroids)
236
+ return undefined;
237
+ const itemsByCell = new Map();
238
+ for (const item of items) {
239
+ const cellId = rankCellsByCloseness(item.embedding, centroids)[0];
240
+ let group = itemsByCell.get(cellId);
241
+ if (!group) {
242
+ group = [];
243
+ itemsByCell.set(cellId, group);
244
+ }
245
+ group.push(item);
246
+ }
247
+ for (const cellId of itemsByCell.keys()) {
248
+ const group = itemsByCell.get(cellId);
249
+ const memberWrites = group.map(item => ({ key: item.ref, value: item.embedding }));
250
+ (0, transactionSet_1.transactionMutate)(cellStore(database, cellId), memberWrites);
251
+ }
252
+ database.writeData(root => root.count, newCount);
253
+ let regenerated = false;
254
+ for (const threshold of REGENERATE_AT) {
255
+ const stepName = "regen" + threshold;
256
+ if (!steps[stepName] && newCount > threshold) {
257
+ rebuildStructure(database);
258
+ database.writeData(root => root.steps[stepName], true);
259
+ regenerated = true;
260
+ }
261
+ }
262
+ if (!regenerated) {
263
+ const averageFill = newCount / Math.max(1, centroids.size) / config.cellTargetSize;
264
+ if (Math.random() < rebalanceProbability(averageFill)) {
265
+ rebuildStructure(database);
266
+ }
267
+ }
268
+ return true;
269
+ }
270
+ exports.insertEmbeddings = insertEmbeddings;
271
+ function removeEmbeddings(database, items) {
272
+ if (!items.length)
273
+ return true;
274
+ const steps = readSteps(database);
275
+ const count = readCount(database);
276
+ if (!steps[STEP_IVF]) {
277
+ const flatDeletes = items.map(item => ({ key: item.ref, value: undefined }));
278
+ (0, transactionSet_1.transactionMutate)(flatStore(database), flatDeletes);
279
+ database.writeData(root => root.count, Math.max(0, count - items.length));
280
+ return true;
281
+ }
282
+ const centroids = (0, transactionSet_1.transactionRead)(centroidStore(database));
283
+ if (!centroids)
284
+ return undefined;
285
+ if (!centroids.size)
286
+ return true;
287
+ const candidatesByItem = [];
288
+ const candidateSet = new Set();
289
+ for (const item of items) {
290
+ const cellIds = rankCellsByCloseness(item.embedding, centroids).slice(0, 1 + DELETE_FALLBACK_CELLS);
291
+ candidatesByItem.push({ ref: item.ref, cellIds });
292
+ for (const cellId of cellIds) {
293
+ candidateSet.add(cellId);
294
+ }
295
+ }
296
+ const candidateCellIds = Array.from(candidateSet);
297
+ const stores = database.readData(root => candidateCellIds.map(cellId => root.cells[cellId]));
298
+ if (!stores)
299
+ return undefined;
300
+ const membersByCell = new Map();
301
+ for (let index = 0; index < candidateCellIds.length; index++) {
302
+ membersByCell.set(candidateCellIds[index], (0, transactionSet_1.replayTransactionStore)(stores[index]));
303
+ }
304
+ const deletesByCell = new Map();
305
+ for (const candidate of candidatesByItem) {
306
+ for (const cellId of candidate.cellIds) {
307
+ const members = membersByCell.get(cellId);
308
+ if (!members || !members.has(candidate.ref)) {
309
+ continue;
310
+ }
311
+ let refs = deletesByCell.get(cellId);
312
+ if (!refs) {
313
+ refs = [];
314
+ deletesByCell.set(cellId, refs);
315
+ }
316
+ refs.push(candidate.ref);
317
+ break;
318
+ }
319
+ }
320
+ let deletedCount = 0;
321
+ for (const cellId of deletesByCell.keys()) {
322
+ const refs = deletesByCell.get(cellId);
323
+ deletedCount += refs.length;
324
+ const memberDeletes = refs.map(ref => ({ key: ref, value: undefined }));
325
+ (0, transactionSet_1.transactionMutate)(cellStore(database, cellId), memberDeletes);
326
+ }
327
+ if (deletedCount) {
328
+ database.writeData(root => root.count, Math.max(0, count - deletedCount));
329
+ }
330
+ return true;
331
+ }
332
+ exports.removeEmbeddings = removeEmbeddings;
333
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXZmRW1iZWRkaW5nRGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpdmZFbWJlZGRpbmdEYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBeUQ7QUFDekQscURBQW1IO0FBQ25ILDBEQUF5SjtBQTBCekosaUdBQWlHO0FBQ2pHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQztBQUN4Qix5SkFBeUo7QUFDekosTUFBTSxhQUFhLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDcEMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDO0FBQ3ZCLHFIQUFxSDtBQUNySCxNQUFNLHFCQUFxQixHQUFHLEVBQUUsQ0FBQztBQUNqQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUUvQixTQUFTLFNBQVMsQ0FBQyxRQUFvQztJQUNuRCxPQUFPLElBQUEsNEJBQWlCLEVBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFDRCxTQUFTLGFBQWEsQ0FBQyxRQUFvQztJQUN2RCxPQUFPLElBQUEsNEJBQWlCLEVBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFDRCxTQUFTLFNBQVMsQ0FBQyxRQUFvQyxFQUFFLE1BQWM7SUFDbkUsT0FBTyxJQUFBLDRCQUFpQixFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUNuRSxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsUUFBb0M7O0lBQ25ELE9BQU8sTUFBQSxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQ0FBSSxFQUFFLENBQUM7QUFDdkQsQ0FBQztB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QUFZLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBakVELDRDQWlFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGFiYXNlLCBuYW1lc3BhY2VEYXRhYmFzZSB9IGZyb20gXCIuL0RhdGFiYXNlXCI7XG5pbXBvcnQgeyBUcmFuc2FjdGlvblNldFN0b3JlLCB0cmFuc2FjdGlvblJlYWQsIHRyYW5zYWN0aW9uTXV0YXRlLCByZXBsYXlUcmFuc2FjdGlvblN0b3JlIH0gZnJvbSBcIi4vdHJhbnNhY3Rpb25TZXRcIjtcbmltcG9ydCB7IFN0b3JlZEVtYmVkZGluZywgRW1iZWRkaW5nRm9ybWF0LCBnZXRDbG9zZW5lc3MsIGVtYmVkZGluZ1RvRmxvYXQzMiwgcmVsZWFzZUZsb2F0MzIsIGVuY29kZUVtYmVkZGluZywgaGFzaEVtYmVkZGluZyB9IGZyb20gXCIuLi9lbWJlZGRpbmdGb3JtYXRzXCI7XG5cbmV4cG9ydCB0eXBlIEl2ZkNvbmZpZyA9IHtcbiAgICBtb2RlbDogc3RyaW5nO1xuICAgIGZvcm1hdDogRW1iZWRkaW5nRm9ybWF0O1xuICAgIC8vIFRhcmdldCBudW1iZXIgb2YgZW1iZWRkaW5ncyBwZXIgY2VsbC5cbiAgICBjZWxsVGFyZ2V0U2l6ZTogbnVtYmVyO1xufTtcblxuLy8gVGllcmVkIHN0b3JhZ2UuIEJlbG93IEZMQVRfTElNSVQgZW1iZWRkaW5ncyB0aGUgd2hvbGUgc2V0IGxpdmVzIGluIG9uZSBmbGF0IHRyYW5zYWN0aW9uIHNldCAobm8gSVZGKTtcbi8vIG9uY2UgaXQgZ3Jvd3MgcGFzdCB0aGF0IHdlIGJ1aWxkIHRoZSBJVkYgKGNlbnRyb2lkcyArIHBlci1jZWxsIHNldHMpIGFuZCBzdGF5IHRoZXJlIGZvcmV2ZXIuIGBjb3VudGAgaXNcbi8vIHRoZSBsaXZlIGVtYmVkZGluZyBjb3VudCAocmUtZGVyaXZlZCBleGFjdGx5IG9uIGEgcmVidWlsZCkuIGBzdGVwc2AgcmVjb3JkcyBvbmUtdGltZSB1cGdyYWRlcyB0aGF0IG11c3Rcbi8vIG5ldmVyIHJlLXJ1biBldmVuIGlmIHRoZSBzZXQgbGF0ZXIgc2hyaW5rcyBhbmQgcmVncm93cy5cbmV4cG9ydCB0eXBlIEl2ZkVtYmVkZGluZ1Jvb3QgPSB7XG4gICAgY29uZmlnOiBJdmZDb25maWc7XG4gICAgY291bnQ6IG51bWJlcjtcbiAgICBmbGF0OiBUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz47XG4gICAgc3RlcHM6IHsgW3N0ZXA6IHN0cmluZ106IGJvb2xlYW4gfTtcbiAgICBjZW50cm9pZHM6IFRyYW5zYWN0aW9uU2V0U3RvcmU8U3RvcmVkRW1iZWRkaW5nPjtcbiAgICBjZWxsczogeyBbY2VsbElkOiBzdHJpbmddOiBUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz4gfTtcbn07XG5cbmV4cG9ydCB0eXBlIEVtYmVkZGluZ0lucHV0ID0geyByZWY6IHN0cmluZzsgZW1iZWRkaW5nOiBTdG9yZWRFbWJlZGRpbmcgfTtcbmV4cG9ydCB0eXBlIFNlYXJjaEhpdCA9IHsgcmVmOiBzdHJpbmc7IGNsb3NlbmVzczogbnVtYmVyIH07XG50eXBlIENlbGxFbnRyeSA9IHsgcmVmOiBzdHJpbmc7IGVtYmVkZGluZzogU3RvcmVkRW1iZWRkaW5nIH07XG5cbi8vIEJlbG93IHRoaXMgbWFueSBlbWJlZGRpbmdzIHdlIHNraXAgdGhlIElWRiBlbnRpcmVseSAoZmxhdCBzdG9yZSkuIDEwMjQgPSBhIGNsZWFuIHBvd2VyIG9mIHR3by5cbmNvbnN0IEZMQVRfTElNSVQgPSAxMDI0O1xuLy8gRm9yY2UgYSBmcm9tLXNjcmF0Y2ggcmVidWlsZCBvbmNlIGF0IGVhY2ggb2YgdGhlc2UgKG11bHRpcGxlcyBvZiA0IGFib3ZlIEZMQVRfTElNSVQsIHVwIHRvIH4xNmspLCBnYXRlZCBieSBhIHN0ZXAgZmxhZyBzbyBlYWNoIHJ1bnMgYXQgbW9zdCBvbmNlIGV2ZXIuXG5jb25zdCBSRUdFTkVSQVRFX0FUID0gWzQwOTYsIDE2Mzg0XTtcbmNvbnN0IFNURVBfSVZGID0gXCJpdmZcIjtcbi8vIE9uIGRlbGV0ZSwgdGhlIG1lbWJlcidzIGV4YWN0IGNlbGwgcGx1cyB0aGlzIG1hbnkgbmVhcmJ5IGNlbGxzIGFyZSBjaGVja2VkLCBpbiBjYXNlIGEgcmVidWlsZCBsZWZ0IGl0IG5vbi1vcHRpbWFsLlxuY29uc3QgREVMRVRFX0ZBTExCQUNLX0NFTExTID0gMTA7XG5jb25zdCBSRUJBTEFOQ0VfSVRFUkFUSU9OUyA9IDQ7XG5cbmZ1bmN0aW9uIGZsYXRTdG9yZShkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4pOiBEYXRhYmFzZTxUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz4+IHtcbiAgICByZXR1cm4gbmFtZXNwYWNlRGF0YWJhc2UoZGF0YWJhc2UsIHJvb3QgPT4gcm9vdC5mbGF0KTtcbn1cbmZ1bmN0aW9uIGNlbnRyb2lkU3RvcmUoZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+KTogRGF0YWJhc2U8VHJhbnNhY3Rpb25TZXRTdG9yZTxTdG9yZWRFbWJlZGRpbmc+PiB7XG4gICAgcmV0dXJuIG5hbWVzcGFjZURhdGFiYXNlKGRhdGFiYXNlLCByb290ID0+IHJvb3QuY2VudHJvaWRzKTtcbn1cbmZ1bmN0aW9uIGNlbGxTdG9yZShkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4sIGNlbGxJZDogc3RyaW5nKTogRGF0YWJhc2U8VHJhbnNhY3Rpb25TZXRTdG9yZTxTdG9yZWRFbWJlZGRpbmc+PiB7XG4gICAgcmV0dXJuIG5hbWVzcGFjZURhdGFiYXNlKGRhdGFiYXNlLCByb290ID0+IHJvb3QuY2VsbHNbY2VsbElkXSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRTdGVwcyhkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4pOiB7IFtzdGVwOiBzdHJpbmddOiBib29sZWFuIH0ge1xuICAgIHJldHVybiBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3Quc3RlcHMpID8/IHt9O1xufVxuZnVuY3Rpb24gcmVhZENvdW50KGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290Pik6IG51bWJlciB7XG4gICAgcmV0dXJuIGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb3VudCkgPz8gMDtcbn1cblxuZnVuY3Rpb24gcmFua0NlbGxzQnlDbG9zZW5lc3MoZW1iZWRkaW5nOiBTdG9yZWRFbWJlZGRpbmcsIGNlbnRyb2lkczogTWFwPHN0cmluZywgU3RvcmVkRW1iZWRkaW5nPik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCByYW5rZWQ6IHsgY2VsbElkOiBzdHJpbmc7IGNsb3NlbmVzczogbnVtYmVyIH1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2VsbElkIG9mIGNlbnRyb2lkcy5rZXlzKCkpIHtcbiAgICAgICAgcmFua2VkLnB1c2goeyBjZWxsSWQsIGNsb3NlbmVzczogZ2V0Q2xvc2VuZXNzKGVtYmVkZGluZywgY2VudHJvaWRzLmdldChjZWxsSWQpISkgfSk7XG4gICAgfVxuICAgIHJhbmtlZC5zb3J0KChsZWZ0LCByaWdodCkgPT4gcmlnaHQuY2xvc2VuZXNzIC0gbGVmdC5jbG9zZW5lc3MpO1xuICAgIHJldHVybiByYW5rZWQubWFwKGVudHJ5ID0+IGVudHJ5LmNlbGxJZCk7XG59XG5cbi8vIFBlci13cml0ZSBjaGFuY2Ugb2YgYSBmdWxsIHJlYnVpbGQuIFplcm8gYXQvdW5kZXIgdGhlIHRhcmdldCBzaXplLCB0aGVuIHJpc2VzIChjdWJpY2FsbHkpIHBhc3QgaXQgc28gY2VsbHNcbi8vIHN0YXkgcm91Z2hseSBiZXR3ZWVuIHRhcmdldCBhbmQgfjJ4IHRhcmdldC5cbmZ1bmN0aW9uIHJlYmFsYW5jZVByb2JhYmlsaXR5KGZpbGxSYXRpbzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoZmlsbFJhdGlvIDw9IDEpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNvbnN0IG92ZXIgPSBmaWxsUmF0aW8gLSAxO1xuICAgIHJldHVybiBNYXRoLm1pbigxLCBvdmVyICogb3ZlciAqIG92ZXIgKiAwLjI1KTtcbn1cblxuLy8gay1tZWFucy4gRGVjb2RlcyBldmVyeSBtZW1iZXIgdG8gYSBwb29sZWQgZmxvYXQzMiBidWZmZXIgT05DRSwgdGhlbiBhc3NpZ25zIHdpdGggYSBwbGFpbiBpbnRlcm5hbCBmbG9hdFxuLy8gZG90IChubyBnZXRDbG9zZW5lc3MgY2FsbCDigJQgY29tcGFyaW5nIHR3byBmbG9hdCB2ZWN0b3JzIGlzIHRyaXZpYWwpIGFuZCBrZWVwcyBjZW50cm9pZHMgYXMgZmxvYXQgbWVhbnMsXG4vLyBlbmNvZGluZyB0aGVtIHRvIFN0b3JlZEVtYmVkZGluZyBvbmx5IGF0IHRoZSBlbmQuIFJlbGVhc2VzIHRoZSBib3Jyb3dlZCBidWZmZXJzIHdoZW4gZG9uZS5cbmZ1bmN0aW9uIGNsdXN0ZXJNZW1iZXJzKG1lbWJlcnM6IENlbGxFbnRyeVtdLCBjbHVzdGVyQ291bnQ6IG51bWJlciwgY29uZmlnOiBJdmZDb25maWcpOiB7IGNlbnRyb2lkOiBTdG9yZWRFbWJlZGRpbmc7IG1lbWJlcnM6IENlbGxFbnRyeVtdIH1bXSB7XG4gICAgY29uc3QgbWVtYmVyRmxvYXRzOiBGbG9hdDMyQXJyYXlbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgbWVtYmVyIG9mIG1lbWJlcnMpIHtcbiAgICAgICAgbWVtYmVyRmxvYXRzLnB1c2goZW1iZWRkaW5nVG9GbG9hdDMyKG1lbWJlci5lbWJlZGRpbmcsIHRydWUpKTtcbiAgICB9XG4gICAgY29uc3QgbGVuZ3RoID0gbWVtYmVyRmxvYXRzLmxlbmd0aCA/IG1lbWJlckZsb2F0c1swXS5sZW5ndGggOiAwO1xuICAgIGxldCBjZW50cm9pZHM6IEZsb2F0MzJBcnJheVtdID0gW107XG4gICAgY29uc3Qgc2VlZFN0ZXAgPSBtZW1iZXJzLmxlbmd0aCAvIGNsdXN0ZXJDb3VudDtcbiAgICBmb3IgKGxldCBjbHVzdGVySW5kZXggPSAwOyBjbHVzdGVySW5kZXggPCBjbHVzdGVyQ291bnQ7IGNsdXN0ZXJJbmRleCsrKSB7XG4gICAgICAgIGNlbnRyb2lkcy5wdXNoKG5ldyBGbG9hdDMyQXJyYXkobWVtYmVyRmxvYXRzW01hdGguZmxvb3IoY2x1c3RlckluZGV4ICogc2VlZFN0ZXApXSkpO1xuICAgIH1cbiAgICBsZXQgZ3JvdXBzOiBudW1iZXJbXVtdID0gW107XG4gICAgZm9yIChsZXQgaXRlcmF0aW9uID0gMDsgaXRlcmF0aW9uIDwgUkVCQUxBTkNFX0lURVJBVElPTlM7IGl0ZXJhdGlvbisrKSB7XG4gICAgICAgIGdyb3VwcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBjbHVzdGVySW5kZXggPSAwOyBjbHVzdGVySW5kZXggPCBjZW50cm9pZHMubGVuZ3RoOyBjbHVzdGVySW5kZXgrKykge1xuICAgICAgICAgICAgZ3JvdXBzLnB1c2goW10pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG1lbWJlckluZGV4ID0gMDsgbWVtYmVySW5kZXggPCBtZW1iZXJGbG9hdHMubGVuZ3RoOyBtZW1iZXJJbmRleCsrKSB7XG4gICAgICAgICAgICBjb25zdCBtZW1iZXJGbG9hdCA9IG1lbWJlckZsb2F0c1ttZW1iZXJJbmRleF07XG4gICAgICAgICAgICBsZXQgYmVzdEluZGV4ID0gMDtcbiAgICAgICAgICAgIGxldCBiZXN0RG90ID0gLUluZmluaXR5O1xuICAgICAgICAgICAgZm9yIChsZXQgY2VudHJvaWRJbmRleCA9IDA7IGNlbnRyb2lkSW5kZXggPCBjZW50cm9pZHMubGVuZ3RoOyBjZW50cm9pZEluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjZW50cm9pZEZsb2F0ID0gY2VudHJvaWRzW2NlbnRyb2lkSW5kZXhdO1xuICAgICAgICAgICAgICAgIGxldCBkb3QgPSAwO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGxlbmd0aDsgZGltKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZG90ICs9IG1lbWJlckZsb2F0W2RpbV0gKiBjZW50cm9pZEZsb2F0W2RpbV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkb3QgPiBiZXN0RG90KSB7XG4gICAgICAgICAgICAgICAgICAgIGJlc3REb3QgPSBkb3Q7XG4gICAgICAgICAgICAgICAgICAgIGJlc3RJbmRleCA9IGNlbnRyb2lkSW5kZXg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ3JvdXBzW2Jlc3RJbmRleF0ucHVzaChtZW1iZXJJbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV4dENlbnRyb2lkczogRmxvYXQzMkFycmF5W10gPSBbXTtcbiAgICAgICAgY29uc3QgbmV4dEdyb3VwczogbnVtYmVyW11bXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIGdyb3Vwcykge1xuICAgICAgICAgICAgaWYgKCFncm91cC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG1lYW4gPSBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1lbWJlckluZGV4IG9mIGdyb3VwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWVtYmVyRmxvYXQgPSBtZW1iZXJGbG9hdHNbbWVtYmVySW5kZXhdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGxlbmd0aDsgZGltKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbWVhbltkaW1dICs9IG1lbWJlckZsb2F0W2RpbV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IG5vcm0gPSAwO1xuICAgICAgICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgbGVuZ3RoOyBkaW0rKykge1xuICAgICAgICAgICAgICAgIG5vcm0gKz0gbWVhbltkaW1dICogbWVhbltkaW1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWFnbml0dWRlID0gTWF0aC5zcXJ0KG5vcm0pIHx8IDE7XG4gICAgICAgICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBsZW5ndGg7IGRpbSsrKSB7XG4gICAgICAgICAgICAgICAgbWVhbltkaW1dIC89IG1hZ25pdHVkZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5leHRDZW50cm9pZHMucHVzaChtZWFuKTtcbiAgICAgICAgICAgIG5leHRHcm91cHMucHVzaChncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgY2VudHJvaWRzID0gbmV4dENlbnRyb2lkcztcbiAgICAgICAgZ3JvdXBzID0gbmV4dEdyb3VwcztcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0OiB7IGNlbnRyb2lkOiBTdG9yZWRFbWJlZGRpbmc7IG1lbWJlcnM6IENlbGxFbnRyeVtdIH1bXSA9IFtdO1xuICAgIGZvciAobGV0IGNsdXN0ZXJJbmRleCA9IDA7IGNsdXN0ZXJJbmRleCA8IGNlbnRyb2lkcy5sZW5ndGg7IGNsdXN0ZXJJbmRleCsrKSB7XG4gICAgICAgIGNvbnN0IGNlbnRyb2lkID0gZW5jb2RlRW1iZWRkaW5nKHsgaW5wdXQ6IGNlbnRyb2lkc1tjbHVzdGVySW5kZXhdLCBmb3JtYXQ6IGNvbmZpZy5mb3JtYXQsIG1vZGVsOiBjb25maWcubW9kZWwgfSk7XG4gICAgICAgIGNvbnN0IGNlbGxNZW1iZXJzOiBDZWxsRW50cnlbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IG1lbWJlckluZGV4IG9mIGdyb3Vwc1tjbHVzdGVySW5kZXhdKSB7XG4gICAgICAgICAgICBjZWxsTWVtYmVycy5wdXNoKG1lbWJlcnNbbWVtYmVySW5kZXhdKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQucHVzaCh7IGNlbnRyb2lkLCBtZW1iZXJzOiBjZWxsTWVtYmVycyB9KTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBtZW1iZXJGbG9hdCBvZiBtZW1iZXJGbG9hdHMpIHtcbiAgICAgICAgcmVsZWFzZUZsb2F0MzIobWVtYmVyRmxvYXQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG4vLyBSZS1jbHVzdGVyIEVWRVJZIGVtYmVkZGluZyAoZmxhdCB0aWVyICsgYWxsIGNlbGxzKSBpbnRvIGEgZnJlc2ggSVZGLCBjbGVhciB0aGUgZmxhdCB0aWVyLCBhbmQgbWFyayBJVkZcbi8vIG1vZGUuIFRoaXMgaXMgdGhlIHJlYXJyYW5nZXI6IHJ1biBwcm9iYWJpbGlzdGljYWxseSBhcyB0aGUgc2V0IGdyb3dzLCBvbmNlIGF0IGVhY2ggcmVnZW5lcmF0ZSB0aHJlc2hvbGQsXG4vLyBhbmQgb25jZSB0byB1cGdyYWRlIGZyb20gZmxhdC4gUmVhZHMgZXZlcnl0aGluZyBpdCB1c2VzLCBzbyBpdCBiYWlscyAoZG9lcyBub3RoaW5nKSBpZiBhbnl0aGluZyBpc24ndFxuLy8gc3luY2VkIGFuZCB0aGUgY2FsbGVyJ3MgcmV0cnkgcmUtcnVucyBpdDsgbm8gY2FsbGVyIGNhcmVzIGFib3V0IGl0cyByZXN1bHQuXG5leHBvcnQgZnVuY3Rpb24gcmVidWlsZFN0cnVjdHVyZShkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4pOiB2b2lkIHtcbiAgICBjb25zdCBjb25maWcgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3QuY29uZmlnKTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuO1xuXG4gICAgY29uc3QgYWxsTWVtYmVyczogQ2VsbEVudHJ5W10gPSBbXTtcbiAgICBjb25zdCBmbGF0ID0gdHJhbnNhY3Rpb25SZWFkKGZsYXRTdG9yZShkYXRhYmFzZSkpO1xuICAgIGlmICghZmxhdCkgcmV0dXJuO1xuICAgIGZvciAoY29uc3QgcmVmIG9mIGZsYXQua2V5cygpKSB7XG4gICAgICAgIGFsbE1lbWJlcnMucHVzaCh7IHJlZiwgZW1iZWRkaW5nOiBmbGF0LmdldChyZWYpISB9KTtcbiAgICB9XG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuO1xuICAgIGNvbnN0IG9sZENlbGxJZHMgPSBBcnJheS5mcm9tKGNlbnRyb2lkcy5rZXlzKCkpO1xuICAgIGNvbnN0IGNlbGxTdG9yZXMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IG9sZENlbGxJZHMubWFwKGNlbGxJZCA9PiByb290LmNlbGxzW2NlbGxJZF0pKTtcbiAgICBpZiAoIWNlbGxTdG9yZXMpIHJldHVybjtcbiAgICBmb3IgKGNvbnN0IHN0b3JlIG9mIGNlbGxTdG9yZXMpIHtcbiAgICAgICAgY29uc3QgbWVtYmVycyA9IHJlcGxheVRyYW5zYWN0aW9uU3RvcmU8U3RvcmVkRW1iZWRkaW5nPihzdG9yZSk7XG4gICAgICAgIGZvciAoY29uc3QgcmVmIG9mIG1lbWJlcnMua2V5cygpKSB7XG4gICAgICAgICAgICBhbGxNZW1iZXJzLnB1c2goeyByZWYsIGVtYmVkZGluZzogbWVtYmVycy5nZXQocmVmKSEgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFhbGxNZW1iZXJzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgY29uc3QgY2x1c3RlckNvdW50ID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChhbGxNZW1iZXJzLmxlbmd0aCAvIGNvbmZpZy5jZWxsVGFyZ2V0U2l6ZSkpO1xuICAgIGNvbnN0IGNsdXN0ZXJzID0gY2x1c3Rlck1lbWJlcnMoYWxsTWVtYmVycywgY2x1c3RlckNvdW50LCBjb25maWcpO1xuXG4gICAgY29uc3QgbmV3Q2VsbElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGNlbnRyb2lkV3JpdGVzOiB7IGtleTogc3RyaW5nOyB2YWx1ZTogU3RvcmVkRW1iZWRkaW5nIHwgdW5kZWZpbmVkIH1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2x1c3RlciBvZiBjbHVzdGVycykge1xuICAgICAgICBjb25zdCBjZWxsSWQgPSBoYXNoRW1iZWRkaW5nKGNsdXN0ZXIuY2VudHJvaWQpO1xuICAgICAgICBuZXdDZWxsSWRzLmFkZChjZWxsSWQpO1xuICAgICAgICBjZW50cm9pZFdyaXRlcy5wdXNoKHsga2V5OiBjZWxsSWQsIHZhbHVlOiBjbHVzdGVyLmNlbnRyb2lkIH0pO1xuICAgICAgICBjb25zdCBtZW1iZXJXcml0ZXMgPSBjbHVzdGVyLm1lbWJlcnMubWFwKG1lbWJlciA9PiAoeyBrZXk6IG1lbWJlci5yZWYsIHZhbHVlOiBtZW1iZXIuZW1iZWRkaW5nIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoY2VsbFN0b3JlKGRhdGFiYXNlLCBjZWxsSWQpLCBtZW1iZXJXcml0ZXMpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG9sZENlbGxJZCBvZiBvbGRDZWxsSWRzKSB7XG4gICAgICAgIGlmIChuZXdDZWxsSWRzLmhhcyhvbGRDZWxsSWQpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjZW50cm9pZFdyaXRlcy5wdXNoKHsga2V5OiBvbGRDZWxsSWQsIHZhbHVlOiB1bmRlZmluZWQgfSk7XG4gICAgICAgIGRhdGFiYXNlLmRlbGV0ZURhdGEocm9vdCA9PiByb290LmNlbGxzW29sZENlbGxJZF0pO1xuICAgIH1cbiAgICB0cmFuc2FjdGlvbk11dGF0ZShjZW50cm9pZFN0b3JlKGRhdGFiYXNlKSwgY2VudHJvaWRXcml0ZXMpO1xuICAgIGRhdGFiYXNlLmRlbGV0ZURhdGEocm9vdCA9PiByb290LmZsYXQpO1xuICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIGFsbE1lbWJlcnMubGVuZ3RoKTtcbiAgICBkYXRhYmFzZS53cml0ZURhdGEocm9vdCA9PiByb290LnN0ZXBzW1NURVBfSVZGXSwgdHJ1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZWFyY2hFbWJlZGRpbmdzKFxuICAgIGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290PixcbiAgICBxdWVyeTogU3RvcmVkRW1iZWRkaW5nLFxuICAgIG9wdGlvbnM6IHsgcHJvYmVCdWRnZXQ6IG51bWJlcjsgcmVzdWx0Q291bnQ6IG51bWJlciB9LFxuKTogU2VhcmNoSGl0W10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb25maWcpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IHN0ZXBzID0gcmVhZFN0ZXBzKGRhdGFiYXNlKTtcblxuICAgIGNvbnN0IGhpdHM6IFNlYXJjaEhpdFtdID0gW107XG4gICAgaWYgKCFzdGVwc1tTVEVQX0lWRl0pIHtcbiAgICAgICAgY29uc3QgZmxhdCA9IHRyYW5zYWN0aW9uUmVhZChmbGF0U3RvcmUoZGF0YWJhc2UpKTtcbiAgICAgICAgaWYgKCFmbGF0KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBmb3IgKGNvbnN0IHJlZiBvZiBmbGF0LmtleXMoKSkge1xuICAgICAgICAgICAgaGl0cy5wdXNoKHsgcmVmLCBjbG9zZW5lc3M6IGdldENsb3NlbmVzcyhxdWVyeSwgZmxhdC5nZXQocmVmKSEpIH0pO1xuICAgICAgICB9XG4gICAgICAgIGhpdHMuc29ydCgobGVmdCwgcmlnaHQpID0+IHJpZ2h0LmNsb3NlbmVzcyAtIGxlZnQuY2xvc2VuZXNzKTtcbiAgICAgICAgcmV0dXJuIGhpdHMuc2xpY2UoMCwgb3B0aW9ucy5yZXN1bHRDb3VudCk7XG4gICAgfVxuXG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoIWNlbnRyb2lkcy5zaXplKSByZXR1cm4gW107XG4gICAgY29uc3QgcHJvYmVDZWxsQ291bnQgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwob3B0aW9ucy5wcm9iZUJ1ZGdldCAvIGNvbmZpZy5jZWxsVGFyZ2V0U2l6ZSkpO1xuICAgIGNvbnN0IHByb2JlQ2VsbElkcyA9IHJhbmtDZWxsc0J5Q2xvc2VuZXNzKHF1ZXJ5LCBjZW50cm9pZHMpLnNsaWNlKDAsIHByb2JlQ2VsbENvdW50KTtcbiAgICBjb25zdCBzdG9yZXMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHByb2JlQ2VsbElkcy5tYXAoY2VsbElkID0+IHJvb3QuY2VsbHNbY2VsbElkXSkpO1xuICAgIGlmICghc3RvcmVzKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGZvciAoY29uc3Qgc3RvcmUgb2Ygc3RvcmVzKSB7XG4gICAgICAgIGNvbnN0IG1lbWJlcnMgPSByZXBsYXlUcmFuc2FjdGlvblN0b3JlPFN0b3JlZEVtYmVkZGluZz4oc3RvcmUpO1xuICAgICAgICBmb3IgKGNvbnN0IHJlZiBvZiBtZW1iZXJzLmtleXMoKSkge1xuICAgICAgICAgICAgaGl0cy5wdXNoKHsgcmVmLCBjbG9zZW5lc3M6IGdldENsb3NlbmVzcyhxdWVyeSwgbWVtYmVycy5nZXQocmVmKSEpIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGhpdHMuc29ydCgobGVmdCwgcmlnaHQpID0+IHJpZ2h0LmNsb3NlbmVzcyAtIGxlZnQuY2xvc2VuZXNzKTtcbiAgICByZXR1cm4gaGl0cy5zbGljZSgwLCBvcHRpb25zLnJlc3VsdENvdW50KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydEVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIGl0ZW1zOiBFbWJlZGRpbmdJbnB1dFtdLFxuKTogdHJ1ZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGNvbmZpZyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb25maWcpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IHN0ZXBzID0gcmVhZFN0ZXBzKGRhdGFiYXNlKTtcbiAgICBjb25zdCBuZXdDb3VudCA9IHJlYWRDb3VudChkYXRhYmFzZSkgKyBpdGVtcy5sZW5ndGg7XG5cbiAgICBpZiAoIXN0ZXBzW1NURVBfSVZGXSkge1xuICAgICAgICBjb25zdCBmbGF0V3JpdGVzID0gaXRlbXMubWFwKGl0ZW0gPT4gKHsga2V5OiBpdGVtLnJlZiwgdmFsdWU6IGl0ZW0uZW1iZWRkaW5nIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoZmxhdFN0b3JlKGRhdGFiYXNlKSwgZmxhdFdyaXRlcyk7XG4gICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIG5ld0NvdW50KTtcbiAgICAgICAgaWYgKG5ld0NvdW50ID4gRkxBVF9MSU1JVCkge1xuICAgICAgICAgICAgcmVidWlsZFN0cnVjdHVyZShkYXRhYmFzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCBpdGVtc0J5Q2VsbCA9IG5ldyBNYXA8c3RyaW5nLCBFbWJlZGRpbmdJbnB1dFtdPigpO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBjb25zdCBjZWxsSWQgPSByYW5rQ2VsbHNCeUNsb3NlbmVzcyhpdGVtLmVtYmVkZGluZywgY2VudHJvaWRzKVswXTtcbiAgICAgICAgbGV0IGdyb3VwID0gaXRlbXNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgIGlmICghZ3JvdXApIHtcbiAgICAgICAgICAgIGdyb3VwID0gW107XG4gICAgICAgICAgICBpdGVtc0J5Q2VsbC5zZXQoY2VsbElkLCBncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgZ3JvdXAucHVzaChpdGVtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBjZWxsSWQgb2YgaXRlbXNCeUNlbGwua2V5cygpKSB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gaXRlbXNCeUNlbGwuZ2V0KGNlbGxJZCkhO1xuICAgICAgICBjb25zdCBtZW1iZXJXcml0ZXMgPSBncm91cC5tYXAoaXRlbSA9PiAoeyBrZXk6IGl0ZW0ucmVmLCB2YWx1ZTogaXRlbS5lbWJlZGRpbmcgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShjZWxsU3RvcmUoZGF0YWJhc2UsIGNlbGxJZCksIG1lbWJlcldyaXRlcyk7XG4gICAgfVxuICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIG5ld0NvdW50KTtcblxuICAgIGxldCByZWdlbmVyYXRlZCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgdGhyZXNob2xkIG9mIFJFR0VORVJBVEVfQVQpIHtcbiAgICAgICAgY29uc3Qgc3RlcE5hbWUgPSBcInJlZ2VuXCIgKyB0aHJlc2hvbGQ7XG4gICAgICAgIGlmICghc3RlcHNbc3RlcE5hbWVdICYmIG5ld0NvdW50ID4gdGhyZXNob2xkKSB7XG4gICAgICAgICAgICByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlKTtcbiAgICAgICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3Quc3RlcHNbc3RlcE5hbWVdLCB0cnVlKTtcbiAgICAgICAgICAgIHJlZ2VuZXJhdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXJlZ2VuZXJhdGVkKSB7XG4gICAgICAgIGNvbnN0IGF2ZXJhZ2VGaWxsID0gbmV3Q291bnQgLyBNYXRoLm1heCgxLCBjZW50cm9pZHMuc2l6ZSkgLyBjb25maWcuY2VsbFRhcmdldFNpemU7XG4gICAgICAgIGlmIChNYXRoLnJhbmRvbSgpIDwgcmViYWxhbmNlUHJvYmFiaWxpdHkoYXZlcmFnZUZpbGwpKSB7XG4gICAgICAgICAgICByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIGl0ZW1zOiBFbWJlZGRpbmdJbnB1dFtdLFxuKTogdHJ1ZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IHN0ZXBzID0gcmVhZFN0ZXBzKGRhdGFiYXNlKTtcbiAgICBjb25zdCBjb3VudCA9IHJlYWRDb3VudChkYXRhYmFzZSk7XG5cbiAgICBpZiAoIXN0ZXBzW1NURVBfSVZGXSkge1xuICAgICAgICBjb25zdCBmbGF0RGVsZXRlcyA9IGl0ZW1zLm1hcChpdGVtID0+ICh7IGtleTogaXRlbS5yZWYsIHZhbHVlOiB1bmRlZmluZWQgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShmbGF0U3RvcmUoZGF0YWJhc2UpLCBmbGF0RGVsZXRlcyk7XG4gICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIE1hdGgubWF4KDAsIGNvdW50IC0gaXRlbXMubGVuZ3RoKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGNlbnRyb2lkcyA9IHRyYW5zYWN0aW9uUmVhZChjZW50cm9pZFN0b3JlKGRhdGFiYXNlKSk7XG4gICAgaWYgKCFjZW50cm9pZHMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFjZW50cm9pZHMuc2l6ZSkgcmV0dXJuIHRydWU7XG5cbiAgICBjb25zdCBjYW5kaWRhdGVzQnlJdGVtOiB7IHJlZjogc3RyaW5nOyBjZWxsSWRzOiBzdHJpbmdbXSB9W10gPSBbXTtcbiAgICBjb25zdCBjYW5kaWRhdGVTZXQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgY29uc3QgY2VsbElkcyA9IHJhbmtDZWxsc0J5Q2xvc2VuZXNzKGl0ZW0uZW1iZWRkaW5nLCBjZW50cm9pZHMpLnNsaWNlKDAsIDEgKyBERUxFVEVfRkFMTEJBQ0tfQ0VMTFMpO1xuICAgICAgICBjYW5kaWRhdGVzQnlJdGVtLnB1c2goeyByZWY6IGl0ZW0ucmVmLCBjZWxsSWRzIH0pO1xuICAgICAgICBmb3IgKGNvbnN0IGNlbGxJZCBvZiBjZWxsSWRzKSB7XG4gICAgICAgICAgICBjYW5kaWRhdGVTZXQuYWRkKGNlbGxJZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjYW5kaWRhdGVDZWxsSWRzID0gQXJyYXkuZnJvbShjYW5kaWRhdGVTZXQpO1xuICAgIGNvbnN0IHN0b3JlcyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gY2FuZGlkYXRlQ2VsbElkcy5tYXAoY2VsbElkID0+IHJvb3QuY2VsbHNbY2VsbElkXSkpO1xuICAgIGlmICghc3RvcmVzKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IG1lbWJlcnNCeUNlbGwgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgU3RvcmVkRW1iZWRkaW5nPj4oKTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgY2FuZGlkYXRlQ2VsbElkcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgbWVtYmVyc0J5Q2VsbC5zZXQoY2FuZGlkYXRlQ2VsbElkc1tpbmRleF0sIHJlcGxheVRyYW5zYWN0aW9uU3RvcmUoc3RvcmVzW2luZGV4XSkpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlbGV0ZXNCeUNlbGwgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KCk7XG4gICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgY2FuZGlkYXRlc0J5SXRlbSkge1xuICAgICAgICBmb3IgKGNvbnN0IGNlbGxJZCBvZiBjYW5kaWRhdGUuY2VsbElkcykge1xuICAgICAgICAgICAgY29uc3QgbWVtYmVycyA9IG1lbWJlcnNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgICAgICBpZiAoIW1lbWJlcnMgfHwgIW1lbWJlcnMuaGFzKGNhbmRpZGF0ZS5yZWYpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgcmVmcyA9IGRlbGV0ZXNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgICAgICBpZiAoIXJlZnMpIHtcbiAgICAgICAgICAgICAgICByZWZzID0gW107XG4gICAgICAgICAgICAgICAgZGVsZXRlc0J5Q2VsbC5zZXQoY2VsbElkLCByZWZzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZnMucHVzaChjYW5kaWRhdGUucmVmKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGRlbGV0ZWRDb3VudCA9IDA7XG4gICAgZm9yIChjb25zdCBjZWxsSWQgb2YgZGVsZXRlc0J5Q2VsbC5rZXlzKCkpIHtcbiAgICAgICAgY29uc3QgcmVmcyA9IGRlbGV0ZXNCeUNlbGwuZ2V0KGNlbGxJZCkhO1xuICAgICAgICBkZWxldGVkQ291bnQgKz0gcmVmcy5sZW5ndGg7XG4gICAgICAgIGNvbnN0IG1lbWJlckRlbGV0ZXMgPSByZWZzLm1hcChyZWYgPT4gKHsga2V5OiByZWYsIHZhbHVlOiB1bmRlZmluZWQgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShjZWxsU3RvcmUoZGF0YWJhc2UsIGNlbGxJZCksIG1lbWJlckRlbGV0ZXMpO1xuICAgIH1cbiAgICBpZiAoZGVsZXRlZENvdW50KSB7XG4gICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIE1hdGgubWF4KDAsIGNvdW50IC0gZGVsZXRlZENvdW50KSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuIl19
334
+ /* _JS_SOURCE_HASH = "6bb25c321db29d41be7eec5ac48ec8aad9563a1f8c7710e6700a8deb6ed719c9"; */