@sochdb/sochdb 0.4.0 → 0.4.2
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/README.md +416 -34
- package/_bin/aarch64-apple-darwin/libsochdb_storage.dylib +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-bulk +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-grpc-server +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-server +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb-bulk.exe +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb-grpc-server.exe +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb_storage.dll +0 -0
- package/_bin/x86_64-unknown-linux-gnu/libsochdb_storage.so +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-bulk +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-grpc-server +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-server +0 -0
- package/bin/sochdb-bulk.js +1 -1
- package/bin/sochdb-grpc-server.js +1 -1
- package/bin/sochdb-server.js +1 -1
- package/dist/cjs/context-builder.js +280 -0
- package/dist/cjs/database.js +2 -2
- package/dist/cjs/embedded/database.js +2 -2
- package/dist/cjs/embedded/ffi/hnsw-bindings.js +295 -0
- package/dist/cjs/embedded/ffi/library-finder.js +10 -3
- package/dist/cjs/embedded/index.js +5 -2
- package/dist/cjs/errors.js +99 -7
- package/dist/cjs/index.js +46 -6
- package/dist/cjs/ipc-client.js +2 -2
- package/dist/cjs/memory/consolidation.js +202 -0
- package/dist/cjs/memory/extraction.js +181 -0
- package/dist/cjs/memory/index.js +26 -0
- package/dist/cjs/memory/retrieval.js +232 -0
- package/dist/cjs/memory/types.js +69 -0
- package/dist/cjs/namespace.js +255 -0
- package/dist/cjs/queue.js +289 -0
- package/dist/cjs/semantic-cache.js +220 -0
- package/dist/esm/context-builder.js +280 -0
- package/dist/esm/database.js +2 -2
- package/dist/esm/embedded/database.js +2 -2
- package/dist/esm/embedded/ffi/hnsw-bindings.js +316 -0
- package/dist/esm/embedded/ffi/library-finder.js +10 -3
- package/dist/esm/embedded/index.js +5 -2
- package/dist/esm/errors.js +107 -7
- package/dist/esm/index.js +46 -6
- package/dist/esm/ipc-client.js +2 -2
- package/dist/esm/memory/consolidation.js +206 -0
- package/dist/esm/memory/extraction.js +185 -0
- package/dist/esm/memory/index.js +26 -0
- package/dist/esm/memory/retrieval.js +243 -0
- package/dist/esm/memory/types.js +72 -0
- package/dist/esm/namespace.js +262 -0
- package/dist/esm/queue.js +291 -0
- package/dist/esm/semantic-cache.js +223 -0
- package/dist/types/context-builder.d.ts +97 -0
- package/dist/types/context-builder.d.ts.map +1 -0
- package/dist/types/database.d.ts +1 -1
- package/dist/types/embedded/database.d.ts +1 -1
- package/dist/types/embedded/ffi/hnsw-bindings.d.ts +90 -0
- package/dist/types/embedded/ffi/hnsw-bindings.d.ts.map +1 -0
- package/dist/types/embedded/ffi/library-finder.d.ts.map +1 -1
- package/dist/types/embedded/index.d.ts +1 -0
- package/dist/types/embedded/index.d.ts.map +1 -1
- package/dist/types/errors.d.ts +57 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/index.d.ts +15 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/ipc-client.d.ts +1 -1
- package/dist/types/memory/consolidation.d.ts +66 -0
- package/dist/types/memory/consolidation.d.ts.map +1 -0
- package/dist/types/memory/extraction.d.ts +82 -0
- package/dist/types/memory/extraction.d.ts.map +1 -0
- package/dist/types/memory/index.d.ts +10 -0
- package/dist/types/memory/index.d.ts.map +1 -0
- package/dist/types/memory/retrieval.d.ts +46 -0
- package/dist/types/memory/retrieval.d.ts.map +1 -0
- package/dist/types/memory/types.d.ts +147 -0
- package/dist/types/memory/types.d.ts.map +1 -0
- package/dist/types/namespace.d.ts +129 -0
- package/dist/types/namespace.d.ts.map +1 -0
- package/dist/types/queue.d.ts +120 -0
- package/dist/types/queue.d.ts.map +1 -0
- package/dist/types/semantic-cache.d.ts +84 -0
- package/dist/types/semantic-cache.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Context Query Builder for LLM Context Assembly
|
|
4
|
+
*
|
|
5
|
+
* Token-aware context assembly with priority-based truncation.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.ContextQueryBuilder = exports.TruncationStrategy = exports.ContextOutputFormat = void 0;
|
|
9
|
+
exports.createContextBuilder = createContextBuilder;
|
|
10
|
+
var ContextOutputFormat;
|
|
11
|
+
(function (ContextOutputFormat) {
|
|
12
|
+
ContextOutputFormat["TOON"] = "toon";
|
|
13
|
+
ContextOutputFormat["JSON"] = "json";
|
|
14
|
+
ContextOutputFormat["MARKDOWN"] = "markdown";
|
|
15
|
+
})(ContextOutputFormat || (exports.ContextOutputFormat = ContextOutputFormat = {}));
|
|
16
|
+
var TruncationStrategy;
|
|
17
|
+
(function (TruncationStrategy) {
|
|
18
|
+
TruncationStrategy["TAIL_DROP"] = "tail_drop";
|
|
19
|
+
TruncationStrategy["HEAD_DROP"] = "head_drop";
|
|
20
|
+
TruncationStrategy["PROPORTIONAL"] = "proportional";
|
|
21
|
+
})(TruncationStrategy || (exports.TruncationStrategy = TruncationStrategy = {}));
|
|
22
|
+
/**
|
|
23
|
+
* Context Query Builder for assembling LLM context
|
|
24
|
+
*/
|
|
25
|
+
class ContextQueryBuilder {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.tokenBudget = 4096;
|
|
28
|
+
this.format = ContextOutputFormat.TOON;
|
|
29
|
+
this.truncation = TruncationStrategy.TAIL_DROP;
|
|
30
|
+
this.sections = [];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Set session ID for context
|
|
34
|
+
*/
|
|
35
|
+
forSession(sessionId) {
|
|
36
|
+
this.sessionId = sessionId;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Set token budget
|
|
41
|
+
*/
|
|
42
|
+
withBudget(tokens) {
|
|
43
|
+
this.tokenBudget = tokens;
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Set output format
|
|
48
|
+
*/
|
|
49
|
+
setFormat(format) {
|
|
50
|
+
this.format = format;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Set truncation strategy
|
|
55
|
+
*/
|
|
56
|
+
setTruncation(strategy) {
|
|
57
|
+
this.truncation = strategy;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Add literal text section
|
|
62
|
+
*/
|
|
63
|
+
literal(name, priority, text) {
|
|
64
|
+
const tokenCount = this.estimateTokens(text);
|
|
65
|
+
this.sections.push({
|
|
66
|
+
name,
|
|
67
|
+
priority,
|
|
68
|
+
content: text,
|
|
69
|
+
tokenCount,
|
|
70
|
+
});
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Start a new section
|
|
75
|
+
*/
|
|
76
|
+
section(name, priority) {
|
|
77
|
+
this.currentSection = {
|
|
78
|
+
name,
|
|
79
|
+
priority,
|
|
80
|
+
content: '',
|
|
81
|
+
tokenCount: 0,
|
|
82
|
+
};
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Add content to current section
|
|
87
|
+
*/
|
|
88
|
+
get(path) {
|
|
89
|
+
if (!this.currentSection) {
|
|
90
|
+
throw new Error('No active section. Call section() first.');
|
|
91
|
+
}
|
|
92
|
+
this.currentSection.content += `GET ${path}\n`;
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Add last N records query
|
|
97
|
+
*/
|
|
98
|
+
last(n, table) {
|
|
99
|
+
if (!this.currentSection) {
|
|
100
|
+
throw new Error('No active section. Call section() first.');
|
|
101
|
+
}
|
|
102
|
+
this.currentSection.content += `LAST ${n} FROM ${table}\n`;
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Add where equals condition
|
|
107
|
+
*/
|
|
108
|
+
whereEq(field, value) {
|
|
109
|
+
if (!this.currentSection) {
|
|
110
|
+
throw new Error('No active section. Call section() first.');
|
|
111
|
+
}
|
|
112
|
+
this.currentSection.content += `WHERE ${field} = ${JSON.stringify(value)}\n`;
|
|
113
|
+
return this;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Add vector search
|
|
117
|
+
*/
|
|
118
|
+
search(collection, embedding, k) {
|
|
119
|
+
if (!this.currentSection) {
|
|
120
|
+
throw new Error('No active section. Call section() first.');
|
|
121
|
+
}
|
|
122
|
+
this.currentSection.content += `SEARCH ${collection} WITH ${embedding} LIMIT ${k}\n`;
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Add SQL query
|
|
127
|
+
*/
|
|
128
|
+
sql(query) {
|
|
129
|
+
if (!this.currentSection) {
|
|
130
|
+
throw new Error('No active section. Call section() first.');
|
|
131
|
+
}
|
|
132
|
+
this.currentSection.content += `SQL: ${query}\n`;
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Finish current section
|
|
137
|
+
*/
|
|
138
|
+
done() {
|
|
139
|
+
if (this.currentSection) {
|
|
140
|
+
this.currentSection.tokenCount = this.estimateTokens(this.currentSection.content);
|
|
141
|
+
this.sections.push(this.currentSection);
|
|
142
|
+
this.currentSection = undefined;
|
|
143
|
+
}
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Execute and build context
|
|
148
|
+
*/
|
|
149
|
+
execute() {
|
|
150
|
+
// Finish any pending section
|
|
151
|
+
if (this.currentSection) {
|
|
152
|
+
this.done();
|
|
153
|
+
}
|
|
154
|
+
// Sort sections by priority (lower = higher priority)
|
|
155
|
+
const sortedSections = [...this.sections].sort((a, b) => a.priority - b.priority);
|
|
156
|
+
// Calculate total tokens
|
|
157
|
+
let totalTokens = sortedSections.reduce((sum, s) => sum + s.tokenCount, 0);
|
|
158
|
+
// Truncate if needed
|
|
159
|
+
const truncatedSections = [];
|
|
160
|
+
const includedSections = [];
|
|
161
|
+
if (totalTokens <= this.tokenBudget) {
|
|
162
|
+
// No truncation needed
|
|
163
|
+
for (const section of sortedSections) {
|
|
164
|
+
includedSections.push(section);
|
|
165
|
+
truncatedSections.push({
|
|
166
|
+
name: section.name,
|
|
167
|
+
tokenCount: section.tokenCount,
|
|
168
|
+
truncated: false,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// Apply truncation strategy
|
|
174
|
+
let remainingBudget = this.tokenBudget;
|
|
175
|
+
if (this.truncation === TruncationStrategy.TAIL_DROP) {
|
|
176
|
+
// Include sections in priority order until budget exhausted
|
|
177
|
+
for (const section of sortedSections) {
|
|
178
|
+
if (section.tokenCount <= remainingBudget) {
|
|
179
|
+
includedSections.push(section);
|
|
180
|
+
remainingBudget -= section.tokenCount;
|
|
181
|
+
truncatedSections.push({
|
|
182
|
+
name: section.name,
|
|
183
|
+
tokenCount: section.tokenCount,
|
|
184
|
+
truncated: false,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
truncatedSections.push({
|
|
189
|
+
name: section.name,
|
|
190
|
+
tokenCount: 0,
|
|
191
|
+
truncated: true,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else if (this.truncation === TruncationStrategy.PROPORTIONAL) {
|
|
197
|
+
// Proportionally reduce all sections
|
|
198
|
+
const ratio = this.tokenBudget / totalTokens;
|
|
199
|
+
for (const section of sortedSections) {
|
|
200
|
+
const allocatedTokens = Math.floor(section.tokenCount * ratio);
|
|
201
|
+
const truncatedContent = this.truncateText(section.content, allocatedTokens);
|
|
202
|
+
includedSections.push({
|
|
203
|
+
...section,
|
|
204
|
+
content: truncatedContent,
|
|
205
|
+
tokenCount: allocatedTokens,
|
|
206
|
+
});
|
|
207
|
+
truncatedSections.push({
|
|
208
|
+
name: section.name,
|
|
209
|
+
tokenCount: allocatedTokens,
|
|
210
|
+
truncated: allocatedTokens < section.tokenCount,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Build final context based on format
|
|
216
|
+
let text = '';
|
|
217
|
+
let actualTokens = 0;
|
|
218
|
+
if (this.format === ContextOutputFormat.TOON) {
|
|
219
|
+
text = this.buildToonFormat(includedSections);
|
|
220
|
+
}
|
|
221
|
+
else if (this.format === ContextOutputFormat.JSON) {
|
|
222
|
+
text = this.buildJsonFormat(includedSections);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
text = this.buildMarkdownFormat(includedSections);
|
|
226
|
+
}
|
|
227
|
+
actualTokens = this.estimateTokens(text);
|
|
228
|
+
return {
|
|
229
|
+
text,
|
|
230
|
+
tokenCount: actualTokens,
|
|
231
|
+
sections: truncatedSections,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
// Helper methods
|
|
235
|
+
estimateTokens(text) {
|
|
236
|
+
// Rough estimate: ~4 characters per token for English
|
|
237
|
+
return Math.ceil(text.length / 4);
|
|
238
|
+
}
|
|
239
|
+
truncateText(text, maxTokens) {
|
|
240
|
+
const maxChars = maxTokens * 4;
|
|
241
|
+
if (text.length <= maxChars) {
|
|
242
|
+
return text;
|
|
243
|
+
}
|
|
244
|
+
return text.substring(0, maxChars) + '...';
|
|
245
|
+
}
|
|
246
|
+
buildToonFormat(sections) {
|
|
247
|
+
const lines = [];
|
|
248
|
+
for (const section of sections) {
|
|
249
|
+
lines.push(`[${section.name}]`);
|
|
250
|
+
lines.push(section.content);
|
|
251
|
+
lines.push('');
|
|
252
|
+
}
|
|
253
|
+
return lines.join('\n');
|
|
254
|
+
}
|
|
255
|
+
buildJsonFormat(sections) {
|
|
256
|
+
const obj = {};
|
|
257
|
+
for (const section of sections) {
|
|
258
|
+
obj[section.name] = section.content;
|
|
259
|
+
}
|
|
260
|
+
return JSON.stringify(obj, null, 2);
|
|
261
|
+
}
|
|
262
|
+
buildMarkdownFormat(sections) {
|
|
263
|
+
const lines = [];
|
|
264
|
+
for (const section of sections) {
|
|
265
|
+
lines.push(`## ${section.name}`);
|
|
266
|
+
lines.push('');
|
|
267
|
+
lines.push(section.content);
|
|
268
|
+
lines.push('');
|
|
269
|
+
}
|
|
270
|
+
return lines.join('\n');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
exports.ContextQueryBuilder = ContextQueryBuilder;
|
|
274
|
+
/**
|
|
275
|
+
* Create a context query builder
|
|
276
|
+
*/
|
|
277
|
+
function createContextBuilder() {
|
|
278
|
+
return new ContextQueryBuilder();
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC1idWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnRleHQtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7R0FJRzs7O0FBc1RILG9EQUVDO0FBdFRELElBQVksbUJBSVg7QUFKRCxXQUFZLG1CQUFtQjtJQUM3QixvQ0FBYSxDQUFBO0lBQ2Isb0NBQWEsQ0FBQTtJQUNiLDRDQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUFKVyxtQkFBbUIsbUNBQW5CLG1CQUFtQixRQUk5QjtBQUVELElBQVksa0JBSVg7QUFKRCxXQUFZLGtCQUFrQjtJQUM1Qiw2Q0FBdUIsQ0FBQTtJQUN2Qiw2Q0FBdUIsQ0FBQTtJQUN2QixtREFBNkIsQ0FBQTtBQUMvQixDQUFDLEVBSlcsa0JBQWtCLGtDQUFsQixrQkFBa0IsUUFJN0I7QUFlRDs7R0FFRztBQUNILE1BQWEsbUJBQW1CO0lBQWhDO1FBRVUsZ0JBQVcsR0FBVyxJQUFJLENBQUM7UUFDM0IsV0FBTSxHQUF3QixtQkFBbUIsQ0FBQyxJQUFJLENBQUM7UUFDdkQsZUFBVSxHQUF1QixrQkFBa0IsQ0FBQyxTQUFTLENBQUM7UUFDOUQsYUFBUSxHQUFjLEVBQUUsQ0FBQztJQThRbkMsQ0FBQztJQTNRQzs7T0FFRztJQUNILFVBQVUsQ0FBQyxTQUFpQjtRQUMxQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7T0FFRztJQUNILFVBQVUsQ0FBQyxNQUFjO1FBQ3ZCLElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDO1FBQzFCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxDQUFDLE1BQTJCO1FBQ25DLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFB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YSxFQUFFLENBQUM7UUFFM0IsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUMvQixLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDakMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNmLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVCLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakIsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxQixDQUFDO0NBQ0Y7QUFuUkQsa0RBbVJDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixvQkFBb0I7SUFDbEMsT0FBTyxJQUFJLG1CQUFtQixFQUFFLENBQUM7QUFDbkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29udGV4dCBRdWVyeSBCdWlsZGVyIGZvciBMTE0gQ29udGV4dCBBc3NlbWJseVxuICogXG4gKiBUb2tlbi1hd2FyZSBjb250ZXh0IGFzc2VtYmx5IHdpdGggcHJpb3JpdHktYmFzZWQgdHJ1bmNhdGlvbi5cbiAqL1xuXG5leHBvcnQgZW51bSBDb250ZXh0T3V0cHV0Rm9ybWF0IHtcbiAgVE9PTiA9ICd0b29uJyxcbiAgSlNPTiA9ICdqc29uJyxcbiAgTUFSS0RPV04gPSAnbWFya2Rvd24nLFxufVxuXG5leHBvcnQgZW51bSBUcnVuY2F0aW9uU3RyYXRlZ3kge1xuICBUQUlMX0RST1AgPSAndGFpbF9kcm9wJywgICAgICAgLy8gRHJvcCBmcm9tIGVuZFxuICBIRUFEX0RST1AgPSAnaGVhZF9kcm9wJywgICAgICAgLy8gRHJvcCBmcm9tIGJlZ2lubmluZ1xuICBQUk9QT1JUSU9OQUwgPSAncHJvcG9ydGlvbmFsJywgLy8gUHJvcG9ydGlvbmFsIGFjcm9zcyBzZWN0aW9uc1xufVxuXG5pbnRlcmZhY2UgU2VjdGlvbiB7XG4gIG5hbWU6IHN0cmluZztcbiAgcHJpb3JpdHk6IG51bWJlcjtcbiAgY29udGVudDogc3RyaW5nO1xuICB0b2tlbkNvdW50OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udGV4dFJlc3VsdCB7XG4gIHRleHQ6IHN0cmluZztcbiAgdG9rZW5Db3VudDogbnVtYmVyO1xuICBzZWN0aW9uczogQXJyYXk8eyBuYW1lOiBzdHJpbmc7IHRva2VuQ291bnQ6IG51bWJlcjsgdHJ1bmNhdGVkOiBib29sZWFuIH0+O1xufVxuXG4vKipcbiAqIENvbnRleHQgUXVlcnkgQnVpbGRlciBmb3IgYXNzZW1ibGluZyBMTE0gY29udGV4dFxuICovXG5leHBvcnQgY2xhc3MgQ29udGV4dFF1ZXJ5QnVpbGRlciB7XG4gIHByaXZhdGUgc2Vzc2lvbklkPzogc3RyaW5nO1xuICBwcml2YXRlIHRva2VuQnVkZ2V0OiBudW1iZXIgPSA0MDk2O1xuICBwcml2YXRlIGZvcm1hdDogQ29udGV4dE91dHB1dEZvcm1hdCA9IENvbnRleHRPdXRwdXRGb3JtYXQuVE9PTjtcbiAgcHJpdmF0ZSB0cnVuY2F0aW9uOiBUcnVuY2F0aW9uU3RyYXRlZ3kgPSBUcnVuY2F0aW9uU3RyYXRlZ3kuVEFJTF9EUk9QO1xuICBwcml2YXRlIHNlY3Rpb25zOiBTZWN0aW9uW10gPSBbXTtcbiAgcHJpdmF0ZSBjdXJyZW50U2VjdGlvbj86IFNlY3Rpb247XG5cbiAgLyoqXG4gICAqIFNldCBzZXNzaW9uIElEIGZvciBjb250ZXh0XG4gICAqL1xuICBmb3JTZXNzaW9uKHNlc3Npb25JZDogc3RyaW5nKTogdGhpcyB7XG4gICAgdGhpcy5zZXNzaW9uSWQgPSBzZXNzaW9uSWQ7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRva2VuIGJ1ZGdldFxuICAgKi9cbiAgd2l0aEJ1ZGdldCh0b2tlbnM6IG51bWJlcik6IHRoaXMge1xuICAgIHRoaXMudG9rZW5CdWRnZXQgPSB0b2tlbnM7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0IG91dHB1dCBmb3JtYXRcbiAgICovXG4gIHNldEZvcm1hdChmb3JtYXQ6IENvbnRleHRPdXRwdXRGb3JtYXQpOiB0aGlzIHtcbiAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdHJ1bmNhdGlvbiBzdHJhdGVneVxuICAgKi9cbiAgc2V0VHJ1bmNhdGlvbihzdHJhdGVneTogVHJ1bmNhdGlvblN0cmF0ZWd5KTogdGhpcyB7XG4gICAgdGhpcy50cnVuY2F0aW9uID0gc3RyYXRlZ3k7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGxpdGVyYWwgdGV4dCBzZWN0aW9uXG4gICAqL1xuICBsaXRlcmFsKG5hbWU6IHN0cmluZywgcHJpb3JpdHk6IG51bWJlciwgdGV4dDogc3RyaW5nKTogdGhpcyB7XG4gICAgY29uc3QgdG9rZW5Db3VudCA9IHRoaXMuZXN0aW1hdGVUb2tlbnModGV4dCk7XG4gICAgdGhpcy5zZWN0aW9ucy5wdXNoKHtcbiAgICAgIG5hbWUsXG4gICAgICBwcmlvcml0eSxcbiAgICAgIGNvbnRlbnQ6IHRleHQsXG4gICAgICB0b2tlbkNvdW50LFxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IGEgbmV3IHNlY3Rpb25cbiAgICovXG4gIHNlY3Rpb24obmFtZTogc3RyaW5nLCBwcmlvcml0eTogbnVtYmVyKTogdGhpcyB7XG4gICAgdGhpcy5jdXJyZW50U2VjdGlvbiA9IHtcbiAgICAgIG5hbWUsXG4gICAgICBwcmlvcml0eSxcbiAgICAgIGNvbnRlbnQ6ICcnLFxuICAgICAgdG9rZW5Db3VudDogMCxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBjb250ZW50IHRvIGN1cnJlbnQgc2VjdGlvblxuICAgKi9cbiAgZ2V0KHBhdGg6IHN0cmluZyk6IHRoaXMge1xuICAgIGlmICghdGhpcy5jdXJyZW50U2VjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBhY3RpdmUgc2VjdGlvbi4gQ2FsbCBzZWN0aW9uKCkgZmlyc3QuJyk7XG4gICAgfVxuICAgIHRoaXMuY3VycmVudFNlY3Rpb24uY29udGVudCArPSBgR0VUICR7cGF0aH1cXG5gO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBsYXN0IE4gcmVjb3JkcyBxdWVyeVxuICAgKi9cbiAgbGFzdChuOiBudW1iZXIsIHRhYmxlOiBzdHJpbmcpOiB0aGlzIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudFNlY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gYWN0aXZlIHNlY3Rpb24uIENhbGwgc2VjdGlvbigpIGZpcnN0LicpO1xuICAgIH1cbiAgICB0aGlzLmN1cnJlbnRTZWN0aW9uLmNvbnRlbnQgKz0gYExBU1QgJHtufSBGUk9NICR7dGFibGV9XFxuYDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgd2hlcmUgZXF1YWxzIGNvbmRpdGlvblxuICAgKi9cbiAgd2hlcmVFcShmaWVsZDogc3RyaW5nLCB2YWx1ZTogYW55KTogdGhpcyB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnRTZWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGFjdGl2ZSBzZWN0aW9uLiBDYWxsIHNlY3Rpb24oKSBmaXJzdC4nKTtcbiAgICB9XG4gICAgdGhpcy5jdXJyZW50U2VjdGlvbi5jb250ZW50ICs9IGBXSEVSRSAke2ZpZWxkfSA9ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfVxcbmA7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHZlY3RvciBzZWFyY2hcbiAgICovXG4gIHNlYXJjaChjb2xsZWN0aW9uOiBzdHJpbmcsIGVtYmVkZGluZzogc3RyaW5nLCBrOiBudW1iZXIpOiB0aGlzIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudFNlY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gYWN0aXZlIHNlY3Rpb24uIENhbGwgc2VjdGlvbigpIGZpcnN0LicpO1xuICAgIH1cbiAgICB0aGlzLmN1cnJlbnRTZWN0aW9uLmNvbnRlbnQgKz0gYFNFQVJDSCAke2NvbGxlY3Rpb259IFdJVEggJHtlbWJlZGRpbmd9IExJTUlUICR7a31cXG5gO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBTUUwgcXVlcnlcbiAgICovXG4gIHNxbChxdWVyeTogc3RyaW5nKTogdGhpcyB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnRTZWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGFjdGl2ZSBzZWN0aW9uLiBDYWxsIHNlY3Rpb24oKSBmaXJzdC4nKTtcbiAgICB9XG4gICAgdGhpcy5jdXJyZW50U2VjdGlvbi5jb250ZW50ICs9IGBTUUw6ICR7cXVlcnl9XFxuYDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5pc2ggY3VycmVudCBzZWN0aW9uXG4gICAqL1xuICBkb25lKCk6IHRoaXMge1xuICAgIGlmICh0aGlzLmN1cnJlbnRTZWN0aW9uKSB7XG4gICAgICB0aGlzLmN1cnJlbnRTZWN0aW9uLnRva2VuQ291bnQgPSB0aGlzLmVzdGltYXRlVG9rZW5zKHRoaXMuY3VycmVudFNlY3Rpb24uY29udGVudCk7XG4gICAgICB0aGlzLnNlY3Rpb25zLnB1c2godGhpcy5jdXJyZW50U2VjdGlvbik7XG4gICAgICB0aGlzLmN1cnJlbnRTZWN0aW9uID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGFuZCBidWlsZCBjb250ZXh0XG4gICAqL1xuICBleGVjdXRlKCk6IENvbnRleHRSZXN1bHQge1xuICAgIC8vIEZpbmlzaCBhbnkgcGVuZGluZyBzZWN0aW9uXG4gICAgaWYgKHRoaXMuY3VycmVudFNlY3Rpb24pIHtcbiAgICAgIHRoaXMuZG9uZSgpO1xuICAgIH1cblxuICAgIC8vIFNvcnQgc2VjdGlvbnMgYnkgcHJpb3JpdHkgKGxvd2VyID0gaGlnaGVyIHByaW9yaXR5KVxuICAgIGNvbnN0IHNvcnRlZFNlY3Rpb25zID0gWy4uLnRoaXMuc2VjdGlvbnNdLnNvcnQoKGEsIGIpID0+IGEucHJpb3JpdHkgLSBiLnByaW9yaXR5KTtcblxuICAgIC8vIENhbGN1bGF0ZSB0b3RhbCB0b2tlbnNcbiAgICBsZXQgdG90YWxUb2tlbnMgPSBzb3J0ZWRTZWN0aW9ucy5yZWR1Y2UoKHN1bSwgcykgPT4gc3VtICsgcy50b2tlbkNvdW50LCAwKTtcblxuICAgIC8vIFRydW5jYXRlIGlmIG5lZWRlZFxuICAgIGNvbnN0IHRydW5jYXRlZFNlY3Rpb25zOiBBcnJheTx7IG5hbWU6IHN0cmluZzsgdG9rZW5Db3VudDogbnVtYmVyOyB0cnVuY2F0ZWQ6IGJvb2xlYW4gfT4gPSBbXTtcbiAgICBjb25zdCBpbmNsdWRlZFNlY3Rpb25zOiBTZWN0aW9uW10gPSBbXTtcblxuICAgIGlmICh0b3RhbFRva2VucyA8PSB0aGlzLnRva2VuQnVkZ2V0KSB7XG4gICAgICAvLyBObyB0cnVuY2F0aW9uIG5lZWRlZFxuICAgICAgZm9yIChjb25zdCBzZWN0aW9uIG9mIHNvcnRlZFNlY3Rpb25zKSB7XG4gICAgICAgIGluY2x1ZGVkU2VjdGlvbnMucHVzaChzZWN0aW9uKTtcbiAgICAgICAgdHJ1bmNhdGVkU2VjdGlvbnMucHVzaCh7XG4gICAgICAgICAgbmFtZTogc2VjdGlvbi5uYW1lLFxuICAgICAgICAgIHRva2VuQ291bnQ6IHNlY3Rpb24udG9rZW5Db3VudCxcbiAgICAgICAgICB0cnVuY2F0ZWQ6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXBwbHkgdHJ1bmNhdGlvbiBzdHJhdGVneVxuICAgICAgbGV0IHJlbWFpbmluZ0J1ZGdldCA9IHRoaXMudG9rZW5CdWRnZXQ7XG5cbiAgICAgIGlmICh0aGlzLnRydW5jYXRpb24gPT09IFRydW5jYXRpb25TdHJhdGVneS5UQUlMX0RST1ApIHtcbiAgICAgICAgLy8gSW5jbHVkZSBzZWN0aW9ucyBpbiBwcmlvcml0eSBvcmRlciB1bnRpbCBidWRnZXQgZXhoYXVzdGVkXG4gICAgICAgIGZvciAoY29uc3Qgc2VjdGlvbiBvZiBzb3J0ZWRTZWN0aW9ucykge1xuICAgICAgICAgIGlmIChzZWN0aW9uLnRva2VuQ291bnQgPD0gcmVtYWluaW5nQnVkZ2V0KSB7XG4gICAgICAgICAgICBpbmNsdWRlZFNlY3Rpb25zLnB1c2goc2VjdGlvbik7XG4gICAgICAgICAgICByZW1haW5pbmdCdWRnZXQgLT0gc2VjdGlvbi50b2tlbkNvdW50O1xuICAgICAgICAgICAgdHJ1bmNhdGVkU2VjdGlvbnMucHVzaCh7XG4gICAgICAgICAgICAgIG5hbWU6IHNlY3Rpb24ubmFtZSxcbiAgICAgICAgICAgICAgdG9rZW5Db3VudDogc2VjdGlvbi50b2tlbkNvdW50LFxuICAgICAgICAgICAgICB0cnVuY2F0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRydW5jYXRlZFNlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICBuYW1lOiBzZWN0aW9uLm5hbWUsXG4gICAgICAgICAgICAgIHRva2VuQ291bnQ6IDAsXG4gICAgICAgICAgICAgIHRydW5jYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0aGlzLnRydW5jYXRpb24gPT09IFRydW5jYXRpb25TdHJhdGVneS5QUk9QT1JUSU9OQUwpIHtcbiAgICAgICAgLy8gUHJvcG9ydGlvbmFsbHkgcmVkdWNlIGFsbCBzZWN0aW9uc1xuICAgICAgICBjb25zdCByYXRpbyA9IHRoaXMudG9rZW5CdWRnZXQgLyB0b3RhbFRva2VucztcbiAgICAgICAgZm9yIChjb25zdCBzZWN0aW9uIG9mIHNvcnRlZFNlY3Rpb25zKSB7XG4gICAgICAgICAgY29uc3QgYWxsb2NhdGVkVG9rZW5zID0gTWF0aC5mbG9vcihzZWN0aW9uLnRva2VuQ291bnQgKiByYXRpbyk7XG4gICAgICAgICAgY29uc3QgdHJ1bmNhdGVkQ29udGVudCA9IHRoaXMudHJ1bmNhdGVUZXh0KHNlY3Rpb24uY29udGVudCwgYWxsb2NhdGVkVG9rZW5zKTtcbiAgICAgICAgICBpbmNsdWRlZFNlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgLi4uc2VjdGlvbixcbiAgICAgICAgICAgIGNvbnRlbnQ6IHRydW5jYXRlZENvbnRlbnQsXG4gICAgICAgICAgICB0b2tlbkNvdW50OiBhbGxvY2F0ZWRUb2tlbnMsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdHJ1bmNhdGVkU2VjdGlvbnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBzZWN0aW9uLm5hbWUsXG4gICAgICAgICAgICB0b2tlbkNvdW50OiBhbGxvY2F0ZWRUb2tlbnMsXG4gICAgICAgICAgICB0cnVuY2F0ZWQ6IGFsbG9jYXRlZFRva2VucyA8IHNlY3Rpb24udG9rZW5Db3VudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEJ1aWxkIGZpbmFsIGNvbnRleHQgYmFzZWQgb24gZm9ybWF0XG4gICAgbGV0IHRleHQgPSAnJztcbiAgICBsZXQgYWN0dWFsVG9rZW5zID0gMDtcblxuICAgIGlmICh0aGlzLmZvcm1hdCA9PT0gQ29udGV4dE91dHB1dEZvcm1hdC5UT09OKSB7XG4gICAgICB0ZXh0ID0gdGhpcy5idWlsZFRvb25Gb3JtYXQoaW5jbHVkZWRTZWN0aW9ucyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmZvcm1hdCA9PT0gQ29udGV4dE91dHB1dEZvcm1hdC5KU09OKSB7XG4gICAgICB0ZXh0ID0gdGhpcy5idWlsZEpzb25Gb3JtYXQoaW5jbHVkZWRTZWN0aW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRleHQgPSB0aGlzLmJ1aWxkTWFya2Rvd25Gb3JtYXQoaW5jbHVkZWRTZWN0aW9ucyk7XG4gICAgfVxuXG4gICAgYWN0dWFsVG9rZW5zID0gdGhpcy5lc3RpbWF0ZVRva2Vucyh0ZXh0KTtcblxuICAgIHJldHVybiB7XG4gICAgICB0ZXh0LFxuICAgICAgdG9rZW5Db3VudDogYWN0dWFsVG9rZW5zLFxuICAgICAgc2VjdGlvbnM6IHRydW5jYXRlZFNlY3Rpb25zLFxuICAgIH07XG4gIH1cblxuICAvLyBIZWxwZXIgbWV0aG9kc1xuICBwcml2YXRlIGVzdGltYXRlVG9rZW5zKHRleHQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgLy8gUm91Z2ggZXN0aW1hdGU6IH40IGNoYXJhY3RlcnMgcGVyIHRva2VuIGZvciBFbmdsaXNoXG4gICAgcmV0dXJuIE1hdGguY2VpbCh0ZXh0Lmxlbmd0aCAvIDQpO1xuICB9XG5cbiAgcHJpdmF0ZSB0cnVuY2F0ZVRleHQodGV4dDogc3RyaW5nLCBtYXhUb2tlbnM6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgbWF4Q2hhcnMgPSBtYXhUb2tlbnMgKiA0O1xuICAgIGlmICh0ZXh0Lmxlbmd0aCA8PSBtYXhDaGFycykge1xuICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0LnN1YnN0cmluZygwLCBtYXhDaGFycykgKyAnLi4uJztcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRUb29uRm9ybWF0KHNlY3Rpb25zOiBTZWN0aW9uW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIFxuICAgIGZvciAoY29uc3Qgc2VjdGlvbiBvZiBzZWN0aW9ucykge1xuICAgICAgbGluZXMucHVzaChgWyR7c2VjdGlvbi5uYW1lfV1gKTtcbiAgICAgIGxpbmVzLnB1c2goc2VjdGlvbi5jb250ZW50KTtcbiAgICAgIGxpbmVzLnB1c2goJycpO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gbGluZXMuam9pbignXFxuJyk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkSnNvbkZvcm1hdChzZWN0aW9uczogU2VjdGlvbltdKTogc3RyaW5nIHtcbiAgICBjb25zdCBvYmo6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IHNlY3Rpb24gb2Ygc2VjdGlvbnMpIHtcbiAgICAgIG9ialtzZWN0aW9uLm5hbWVdID0gc2VjdGlvbi5jb250ZW50O1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqLCBudWxsLCAyKTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRNYXJrZG93bkZvcm1hdChzZWN0aW9uczogU2VjdGlvbltdKTogc3RyaW5nIHtcbiAgICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IHNlY3Rpb24gb2Ygc2VjdGlvbnMpIHtcbiAgICAgIGxpbmVzLnB1c2goYCMjICR7c2VjdGlvbi5uYW1lfWApO1xuICAgICAgbGluZXMucHVzaCgnJyk7XG4gICAgICBsaW5lcy5wdXNoKHNlY3Rpb24uY29udGVudCk7XG4gICAgICBsaW5lcy5wdXNoKCcnKTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgY29udGV4dCBxdWVyeSBidWlsZGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDb250ZXh0QnVpbGRlcigpOiBDb250ZXh0UXVlcnlCdWlsZGVyIHtcbiAgcmV0dXJuIG5ldyBDb250ZXh0UXVlcnlCdWlsZGVyKCk7XG59XG4iXX0=
|