@narrative-os/engine 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/agents/canonValidator.d.ts +9 -0
  2. package/dist/agents/canonValidator.js +51 -0
  3. package/dist/agents/chapterPlanner.d.ts +50 -0
  4. package/dist/agents/chapterPlanner.js +250 -0
  5. package/dist/agents/completeness.d.ts +7 -0
  6. package/dist/agents/completeness.js +51 -0
  7. package/dist/agents/memoryExtractor.d.ts +12 -0
  8. package/dist/agents/memoryExtractor.js +82 -0
  9. package/dist/agents/stateUpdater.d.ts +30 -0
  10. package/dist/agents/stateUpdater.js +150 -0
  11. package/dist/agents/storyDirector.d.ts +40 -0
  12. package/dist/agents/storyDirector.js +213 -0
  13. package/dist/agents/summarizer.d.ts +8 -0
  14. package/dist/agents/summarizer.js +56 -0
  15. package/dist/agents/tensionController.d.ts +68 -0
  16. package/dist/agents/tensionController.js +197 -0
  17. package/dist/agents/writer.d.ts +12 -0
  18. package/dist/agents/writer.js +148 -0
  19. package/dist/constraints/constraintGraph.d.ts +117 -0
  20. package/dist/constraints/constraintGraph.js +381 -0
  21. package/dist/constraints/validator.d.ts +58 -0
  22. package/dist/constraints/validator.js +236 -0
  23. package/dist/index.d.ts +25 -0
  24. package/dist/index.js +115 -0
  25. package/dist/llm/client.d.ts +14 -0
  26. package/dist/llm/client.js +108 -0
  27. package/dist/memory/canonStore.d.ts +20 -0
  28. package/dist/memory/canonStore.js +110 -0
  29. package/dist/memory/memoryRetriever.d.ts +28 -0
  30. package/dist/memory/memoryRetriever.js +126 -0
  31. package/dist/memory/stateUpdater.d.ts +49 -0
  32. package/dist/memory/stateUpdater.js +315 -0
  33. package/dist/memory/vectorStore.d.ts +41 -0
  34. package/dist/memory/vectorStore.js +166 -0
  35. package/dist/pipeline/generateChapter.d.ts +17 -0
  36. package/dist/pipeline/generateChapter.js +75 -0
  37. package/dist/story/bible.d.ts +4 -0
  38. package/dist/story/bible.js +53 -0
  39. package/dist/story/state.d.ts +3 -0
  40. package/dist/story/state.js +27 -0
  41. package/dist/story/structuredState.d.ts +39 -0
  42. package/dist/story/structuredState.js +159 -0
  43. package/dist/test/canon.test.d.ts +1 -0
  44. package/dist/test/canon.test.js +104 -0
  45. package/dist/test/chapter-planner.test.d.ts +1 -0
  46. package/dist/test/chapter-planner.test.js +171 -0
  47. package/dist/test/constraints.test.d.ts +1 -0
  48. package/dist/test/constraints.test.js +210 -0
  49. package/dist/test/simple.test.d.ts +1 -0
  50. package/dist/test/simple.test.js +51 -0
  51. package/dist/test/state-updater.test.d.ts +1 -0
  52. package/dist/test/state-updater.test.js +200 -0
  53. package/dist/test/story-director.test.d.ts +1 -0
  54. package/dist/test/story-director.test.js +142 -0
  55. package/dist/test/structured-state.test.d.ts +1 -0
  56. package/dist/test/structured-state.test.js +144 -0
  57. package/dist/test/tension-controller.test.d.ts +1 -0
  58. package/dist/test/tension-controller.test.js +116 -0
  59. package/dist/test/vector-memory.test.d.ts +1 -0
  60. package/dist/test/vector-memory.test.js +153 -0
  61. package/dist/test/world-simulation.test.d.ts +1 -0
  62. package/dist/test/world-simulation.test.js +152 -0
  63. package/dist/types/index.d.ts +79 -0
  64. package/dist/types/index.js +3 -0
  65. package/dist/world/characterAgent.d.ts +73 -0
  66. package/dist/world/characterAgent.js +232 -0
  67. package/dist/world/eventResolver.d.ts +52 -0
  68. package/dist/world/eventResolver.js +205 -0
  69. package/dist/world/worldState.d.ts +93 -0
  70. package/dist/world/worldState.js +258 -0
  71. package/package.json +43 -0
@@ -0,0 +1,315 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stateUpdaterPipeline = exports.StateUpdaterPipeline = void 0;
4
+ const client_js_1 = require("../llm/client.js");
5
+ const STATE_EXTRACTION_PROMPT = `You are a narrative state extractor. Analyze this chapter and extract all state changes.
6
+
7
+ ## Story Bible
8
+
9
+ **Title:** {{title}}
10
+ **Genre:** {{genre}}
11
+
12
+ ## Chapter {{chapterNumber}}: {{chapterTitle}}
13
+
14
+ {{chapterContent}}
15
+
16
+ ## Current Character States
17
+
18
+ {{characters}}
19
+
20
+ ## Current Plot Threads
21
+
22
+ {{plotThreads}}
23
+
24
+ ## Extraction Task
25
+
26
+ Extract the following:
27
+
28
+ 1. **Character Changes**: How do characters change? (emotion, location, knowledge, relationships, goals)
29
+ 2. **Plot Thread Changes**: How do plot threads progress? (status, tension, summary updates)
30
+ 3. **New Facts**: Any new canon facts established?
31
+ 4. **World Changes**: Any changes to the world setting?
32
+
33
+ Output JSON:
34
+ {
35
+ "characterChanges": [
36
+ {
37
+ "name": "character name",
38
+ "emotionalState": "new emotional state or null",
39
+ "location": "new location or null",
40
+ "newKnowledge": ["facts learned"],
41
+ "relationshipChanges": [{"with": "other character", "newStatus": "relationship"}],
42
+ "newGoal": "new goal or null"
43
+ }
44
+ ],
45
+ "plotThreadChanges": [
46
+ {
47
+ "id": "thread id",
48
+ "status": "new status or null",
49
+ "tensionDelta": 0.1,
50
+ "newSummary": "updated summary or null"
51
+ }
52
+ ],
53
+ "newFacts": [
54
+ {
55
+ "category": "character|world|plot",
56
+ "subject": "subject",
57
+ "attribute": "attribute",
58
+ "value": "value"
59
+ }
60
+ ],
61
+ "worldChanges": ["any changes to the world"]
62
+ }`;
63
+ class StateUpdaterPipeline {
64
+ /**
65
+ * Run the complete post-chapter update pipeline
66
+ */
67
+ async update(context) {
68
+ const { chapter, bible, currentState, canon, vectorStore, constraintGraph } = context;
69
+ const changes = [];
70
+ let memoriesAdded = 0;
71
+ let canonFactsAdded = 0;
72
+ // Step 1: Extract state changes using LLM
73
+ const extraction = await this.extractChanges(chapter, bible, currentState);
74
+ // Step 2: Update structured state
75
+ let newState = { ...currentState };
76
+ newState.chapter = chapter.number;
77
+ // Apply character changes
78
+ for (const change of extraction.characterChanges) {
79
+ if (newState.characters[change.name]) {
80
+ const char = newState.characters[change.name];
81
+ if (change.emotionalState) {
82
+ char.emotionalState = change.emotionalState;
83
+ changes.push({
84
+ type: 'character',
85
+ description: `${change.name} emotional state → ${change.emotionalState}`,
86
+ chapter: chapter.number,
87
+ });
88
+ }
89
+ if (change.location) {
90
+ const oldLocation = char.location;
91
+ char.location = change.location;
92
+ changes.push({
93
+ type: 'character',
94
+ description: `${change.name} moved: ${oldLocation} → ${change.location}`,
95
+ chapter: chapter.number,
96
+ });
97
+ // Update constraint graph
98
+ constraintGraph.updateCharacterLocation(change.name, change.location, chapter.number);
99
+ }
100
+ if (change.newKnowledge) {
101
+ char.knowledge = [...char.knowledge, ...change.newKnowledge];
102
+ // Add to constraint graph
103
+ for (const knowledge of change.newKnowledge) {
104
+ const factId = `fact-${this.sanitizeId(knowledge)}`;
105
+ if (!constraintGraph.getNode(factId)) {
106
+ constraintGraph.addNode({
107
+ id: factId,
108
+ type: 'fact',
109
+ label: knowledge,
110
+ properties: {},
111
+ chapterEstablished: chapter.number,
112
+ });
113
+ }
114
+ constraintGraph.addEdge({
115
+ id: `edge-${change.name}-knows-${factId}`,
116
+ from: `char-${change.name}`,
117
+ to: factId,
118
+ type: 'knows',
119
+ properties: { since: chapter.number },
120
+ });
121
+ }
122
+ }
123
+ if (change.relationshipChanges) {
124
+ for (const rel of change.relationshipChanges) {
125
+ char.relationships[rel.with] = rel.newStatus;
126
+ }
127
+ }
128
+ if (change.newGoal) {
129
+ char.goals = [...char.goals, change.newGoal];
130
+ }
131
+ }
132
+ }
133
+ // Apply plot thread changes
134
+ for (const change of extraction.plotThreadChanges) {
135
+ if (newState.plotThreads[change.id]) {
136
+ const thread = newState.plotThreads[change.id];
137
+ if (change.status) {
138
+ thread.status = change.status;
139
+ }
140
+ if (change.tensionDelta) {
141
+ thread.tension = Math.max(0, Math.min(1, thread.tension + change.tensionDelta));
142
+ }
143
+ if (change.newSummary) {
144
+ thread.summary = change.newSummary;
145
+ }
146
+ thread.lastChapter = chapter.number;
147
+ changes.push({
148
+ type: 'plot',
149
+ description: `${thread.name} updated: ${change.status || 'progress'}`,
150
+ chapter: chapter.number,
151
+ });
152
+ }
153
+ }
154
+ // Step 3: Add new canon facts
155
+ for (const fact of extraction.newFacts) {
156
+ // In real implementation, would add to canon store
157
+ canonFactsAdded++;
158
+ changes.push({
159
+ type: 'canon',
160
+ description: `Canon: ${fact.subject} ${fact.attribute} = ${fact.value}`,
161
+ chapter: chapter.number,
162
+ });
163
+ }
164
+ // Step 4: Extract and add narrative memories
165
+ const memories = await this.extractMemories(chapter, bible);
166
+ for (const memory of memories) {
167
+ await vectorStore.addMemory({
168
+ storyId: chapter.storyId,
169
+ chapterNumber: chapter.number,
170
+ content: memory.content,
171
+ category: memory.category,
172
+ timestamp: new Date(),
173
+ });
174
+ memoriesAdded++;
175
+ }
176
+ changes.push({
177
+ type: 'memory',
178
+ description: `${memoriesAdded} narrative memories extracted`,
179
+ chapter: chapter.number,
180
+ });
181
+ // Step 5: Add event to constraint graph
182
+ constraintGraph.addEvent(`ch${chapter.number}`, chapter.summary, Object.keys(newState.characters), chapter.number);
183
+ // Step 6: Update recent events
184
+ newState.recentEvents = [...newState.recentEvents, chapter.summary].slice(-10);
185
+ return {
186
+ structuredState: newState,
187
+ memoriesAdded,
188
+ canonFactsAdded,
189
+ graphUpdated: true,
190
+ changes,
191
+ };
192
+ }
193
+ /**
194
+ * Extract state changes from chapter
195
+ */
196
+ async extractChanges(chapter, bible, state) {
197
+ const characters = Object.values(state.characters)
198
+ .map(c => `- ${c.name}: ${c.emotionalState}, at ${c.location}`)
199
+ .join('\n');
200
+ const plotThreads = Object.values(state.plotThreads)
201
+ .map(t => `- ${t.name} (${t.status}, ${Math.round(t.tension * 100)}% tension)`)
202
+ .join('\n');
203
+ const prompt = STATE_EXTRACTION_PROMPT
204
+ .replace('{{title}}', bible.title)
205
+ .replace('{{genre}}', bible.genre)
206
+ .replace('{{chapterNumber}}', chapter.number.toString())
207
+ .replace('{{chapterTitle}}', chapter.title)
208
+ .replace('{{chapterContent}}', chapter.content.substring(0, 5000))
209
+ .replace('{{characters}}', characters)
210
+ .replace('{{plotThreads}}', plotThreads);
211
+ const result = await (0, client_js_1.getLLM)().completeJSON(prompt, {
212
+ temperature: 0.3,
213
+ maxTokens: 2000,
214
+ });
215
+ return result;
216
+ }
217
+ /**
218
+ * Extract narrative memories from chapter
219
+ */
220
+ async extractMemories(chapter, bible) {
221
+ // Simplified memory extraction
222
+ // In real implementation, would use MemoryExtractor agent
223
+ const memories = [];
224
+ // Extract key events from summary
225
+ if (chapter.summary) {
226
+ memories.push({
227
+ content: chapter.summary,
228
+ category: 'event',
229
+ });
230
+ }
231
+ // Add chapter title as memory
232
+ memories.push({
233
+ content: `Chapter ${chapter.number}: ${chapter.title}`,
234
+ category: 'plot',
235
+ });
236
+ return memories;
237
+ }
238
+ /**
239
+ * Quick update without LLM (for testing)
240
+ */
241
+ async quickUpdate(context) {
242
+ const { chapter, currentState, vectorStore, constraintGraph } = context;
243
+ const changes = [];
244
+ let newState = { ...currentState };
245
+ newState.chapter = chapter.number;
246
+ // Add basic memories
247
+ await vectorStore.addMemory({
248
+ storyId: chapter.storyId,
249
+ chapterNumber: chapter.number,
250
+ content: chapter.summary,
251
+ category: 'event',
252
+ timestamp: new Date(),
253
+ });
254
+ await vectorStore.addMemory({
255
+ storyId: chapter.storyId,
256
+ chapterNumber: chapter.number,
257
+ content: `Chapter ${chapter.number}: ${chapter.title}`,
258
+ category: 'plot',
259
+ timestamp: new Date(),
260
+ });
261
+ changes.push({
262
+ type: 'memory',
263
+ description: `2 memories added (quick mode)`,
264
+ chapter: chapter.number,
265
+ });
266
+ // Update recent events
267
+ newState.recentEvents = [...newState.recentEvents, chapter.summary].slice(-10);
268
+ // Add to constraint graph
269
+ constraintGraph.addEvent(`ch${chapter.number}`, chapter.summary, Object.keys(newState.characters), chapter.number);
270
+ return {
271
+ structuredState: newState,
272
+ memoriesAdded: 2,
273
+ canonFactsAdded: 0,
274
+ graphUpdated: true,
275
+ changes,
276
+ };
277
+ }
278
+ /**
279
+ * Format update result
280
+ */
281
+ formatResult(result) {
282
+ const lines = ['## State Update Result'];
283
+ lines.push(`\n**Memories Added:** ${result.memoriesAdded}`);
284
+ lines.push(`**Canon Facts Added:** ${result.canonFactsAdded}`);
285
+ lines.push(`**Graph Updated:** ${result.graphUpdated ? '✅' : '❌'}`);
286
+ if (result.changes.length > 0) {
287
+ lines.push('\n**Changes:**');
288
+ const byType = {
289
+ character: [],
290
+ plot: [],
291
+ world: [],
292
+ canon: [],
293
+ memory: [],
294
+ };
295
+ for (const change of result.changes) {
296
+ byType[change.type].push(change);
297
+ }
298
+ for (const [type, changes] of Object.entries(byType)) {
299
+ if (changes.length > 0) {
300
+ lines.push(`\n*${type.charAt(0).toUpperCase() + type.slice(1)}:*`);
301
+ for (const change of changes) {
302
+ lines.push(` - ${change.description}`);
303
+ }
304
+ }
305
+ }
306
+ }
307
+ return lines.join('\n');
308
+ }
309
+ sanitizeId(str) {
310
+ return str.replace(/[^a-zA-Z0-9]/g, '_').substring(0, 50);
311
+ }
312
+ }
313
+ exports.StateUpdaterPipeline = StateUpdaterPipeline;
314
+ exports.stateUpdaterPipeline = new StateUpdaterPipeline();
315
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGVVcGRhdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21lbW9yeS9zdGF0ZVVwZGF0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0RBQTBDO0FBOEIxQyxNQUFNLHVCQUF1QixHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUF5RDlCLENBQUM7QUFFSCxNQUFhLG9CQUFvQjtJQUMvQjs7T0FFRztJQUNILEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBc0I7UUFDakMsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLEdBQUcsT0FBTyxDQUFDO1FBRXRGLE1BQU0sT0FBTyxHQUFrQixFQUFFLENBQUM7UUFDbEMsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLElBQUksZUFBZSxHQUFHLENBQUMsQ0FBQztRQUV4QiwwQ0FBMEM7UUFDMUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFM0Usa0NBQWtDO1FBQ2xDLElBQUksUUFBUSxHQUFHLEVBQUUsR0FBRyxZQUFZLEVBQUUsQ0FBQztRQUNuQyxRQUFRLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFFbEMsMEJBQTBCO1FBQzFCLEtBQUssTUFBTSxNQUFNLElBQUksVUFBVSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDakQsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFOUMsSUFBSSxNQUFNLENBQUMsY0FBYyxFQUFF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QUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ25FLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7d0JBQzdCLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztvQkFDMUMsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVPLFVBQVUsQ0FBQyxHQUFXO1FBQzVCLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM1RCxDQUFDO0NBQ0Y7QUF0VkQsb0RBc1ZDO0FBRVksUUFBQSxvQkFBb0IsR0FBRyxJQUFJLG9CQUFvQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRMTE0gfSBmcm9tICcuLi9sbG0vY2xpZW50LmpzJztcclxuaW1wb3J0IHR5cGUgeyBDaGFwdGVyLCBTdG9yeUJpYmxlIH0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xyXG5pbXBvcnQgdHlwZSB7IFN0b3J5U3RydWN0dXJlZFN0YXRlLCBDaGFyYWN0ZXJTdGF0ZSwgUGxvdFRocmVhZFN0YXRlIH0gZnJvbSAnLi4vc3Rvcnkvc3RydWN0dXJlZFN0YXRlLmpzJztcclxuaW1wb3J0IHR5cGUgeyBWZWN0b3JTdG9yZSwgTmFycmF0aXZlTWVtb3J5IH0gZnJvbSAnLi92ZWN0b3JTdG9yZS5qcyc7XHJcbmltcG9ydCB0eXBlIHsgQ2Fub25TdG9yZSB9IGZyb20gJy4vY2Fub25TdG9yZS5qcyc7XHJcbmltcG9ydCB7IENvbnN0cmFpbnRHcmFwaCB9IGZyb20gJy4uL2NvbnN0cmFpbnRzL2NvbnN0cmFpbnRHcmFwaC5qcyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVXBkYXRlUmVzdWx0IHtcclxuICBzdHJ1Y3R1cmVkU3RhdGU6IFN0b3J5U3RydWN0dXJlZFN0YXRlO1xyXG4gIG1lbW9yaWVzQWRkZWQ6IG51bWJlcjtcclxuICBjYW5vbkZhY3RzQWRkZWQ6IG51bWJlcjtcclxuICBncmFwaFVwZGF0ZWQ6IGJvb2xlYW47XHJcbiAgY2hhbmdlczogU3RhdGVDaGFuZ2VbXTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBTdGF0ZUNoYW5nZSB7XHJcbiAgdHlwZTogJ2NoYXJhY3RlcicgfCAncGxvdCcgfCAnd29ybGQnIHwgJ2Nhbm9uJyB8ICdtZW1vcnknO1xyXG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XHJcbiAgY2hhcHRlcjogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZUNvbnRleHQge1xyXG4gIGNoYXB0ZXI6IENoYXB0ZXI7XHJcbiAgYmlibGU6IFN0b3J5QmlibGU7XHJcbiAgY3VycmVudFN0YXRlOiBTdG9yeVN0cnVjdHVyZWRTdGF0ZTtcclxuICBjYW5vbjogQ2Fub25TdG9yZTtcclxuICB2ZWN0b3JTdG9yZTogVmVjdG9yU3RvcmU7XHJcbiAgY29uc3RyYWludEdyYXBoOiBDb25zdHJhaW50R3JhcGg7XHJcbn1cclxuXHJcbmNvbnN0IFNUQVRFX0VYVFJBQ1RJT05fUFJPTVBUID0gYFlvdSBhcmUgYSBuYXJyYXRpdmUgc3RhdGUgZXh0cmFjdG9yLiBBbmFseXplIHRoaXMgY2hhcHRlciBhbmQgZXh0cmFjdCBhbGwgc3RhdGUgY2hhbmdlcy5cclxuXHJcbiMjIFN0b3J5IEJpYmxlXHJcblxyXG4qKlRpdGxlOioqIHt7dGl0bGV9fVxyXG4qKkdlbnJlOioqIHt7Z2VucmV9fVxyXG5cclxuIyMgQ2hhcHRlciB7e2NoYXB0ZXJOdW1iZXJ9fToge3tjaGFwdGVyVGl0bGV9fVxyXG5cclxue3tjaGFwdGVyQ29udGVudH19XHJcblxyXG4jIyBDdXJyZW50IENoYXJhY3RlciBTdGF0ZXNcclxuXHJcbnt7Y2hhcmFjdGVyc319XHJcblxyXG4jIyBDdXJyZW50IFBsb3QgVGhyZWFkc1xyXG5cclxue3twbG90VGhyZWFkc319XHJcblxyXG4jIyBFeHRyYWN0aW9uIFRhc2tcclxuXHJcbkV4dHJhY3QgdGhlIGZvbGxvd2luZzpcclxuXHJcbjEuICoqQ2hhcmFjdGVyIENoYW5nZXMqKjogSG93IGRvIGNoYXJhY3RlcnMgY2hhbmdlPyAoZW1vdGlvbiwgbG9jYXRpb24sIGtub3dsZWRnZSwgcmVsYXRpb25zaGlwcywgZ29hbHMpXHJcbjIuICoqUGxvdCBUaHJlYWQgQ2hhbmdlcyoqOiBIb3cgZG8gcGxvdCB0aHJlYWRzIHByb2dyZXNzPyAoc3RhdHVzLCB0ZW5zaW9uLCBzdW1tYXJ5IHVwZGF0ZXMpXHJcbjMuICoqTmV3IEZhY3RzKio6IEFueSBuZXcgY2Fub24gZmFjdHMgZXN0YWJsaXNoZWQ/XHJcbjQuICoqV29ybGQgQ2hhbmdlcyoqOiBBbnkgY2hhbmdlcyB0byB0aGUgd29ybGQgc2V0dGluZz9cclxuXHJcbk91dHB1dCBKU09OOlxyXG57XHJcbiAgXCJjaGFyYWN0ZXJDaGFuZ2VzXCI6IFtcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiY2hhcmFjdGVyIG5hbWVcIixcclxuICAgICAgXCJlbW90aW9uYWxTdGF0ZVwiOiBcIm5ldyBlbW90aW9uYWwgc3RhdGUgb3IgbnVsbFwiLFxyXG4gICAgICBcImxvY2F0aW9uXCI6IFwibmV3IGxvY2F0aW9uIG9yIG51bGxcIixcclxuICAgICAgXCJuZXdLbm93bGVkZ2VcIjogW1wiZmFjdHMgbGVhcm5lZFwiXSxcclxuICAgICAgXCJyZWxhdGlvbnNoaXBDaGFuZ2VzXCI6IFt7XCJ3aXRoXCI6IFwib3RoZXIgY2hhcmFjdGVyXCIsIFwibmV3U3RhdHVzXCI6IFwicmVsYXRpb25zaGlwXCJ9XSxcclxuICAgICAgXCJuZXdHb2FsXCI6IFwibmV3IGdvYWwgb3IgbnVsbFwiXHJcbiAgICB9XHJcbiAgXSxcclxuICBcInBsb3RUaHJlYWRDaGFuZ2VzXCI6IFtcclxuICAgIHtcclxuICAgICAgXCJpZFwiOiBcInRocmVhZCBpZFwiLFxyXG4gICAgICBcInN0YXR1c1wiOiBcIm5ldyBzdGF0dXMgb3IgbnVsbFwiLFxyXG4gICAgICBcInRlbnNpb25EZWx0YVwiOiAwLjEsXHJcbiAgICAgIFwibmV3U3VtbWFyeVwiOiBcInVwZGF0ZWQgc3VtbWFyeSBvciBudWxsXCJcclxuICAgIH1cclxuICBdLFxyXG4gIFwibmV3RmFjdHNcIjogW1xyXG4gICAge1xyXG4gICAgICBcImNhdGVnb3J5XCI6IFwiY2hhcmFjdGVyfHdvcmxkfHBsb3RcIixcclxuICAgICAgXCJzdWJqZWN0XCI6IFwic3ViamVjdFwiLFxyXG4gICAgICBcImF0dHJpYnV0ZVwiOiBcImF0dHJpYnV0ZVwiLFxyXG4gICAgICBcInZhbHVlXCI6IFwidmFsdWVcIlxyXG4gICAgfVxyXG4gIF0sXHJcbiAgXCJ3b3JsZENoYW5nZXNcIjogW1wiYW55IGNoYW5nZXMgdG8gdGhlIHdvcmxkXCJdXHJcbn1gO1xyXG5cclxuZXhwb3J0IGNsYXNzIFN0YXRlVXBkYXRlclBpcGVsaW5lIHtcclxuICAvKipcclxuICAgKiBSdW4gdGhlIGNvbXBsZXRlIHBvc3QtY2hhcHRlciB1cGRhdGUgcGlwZWxpbmVcclxuICAgKi9cclxuICBhc3luYyB1cGRhdGUoY29udGV4dDogVXBkYXRlQ29udGV4dCk6IFByb21pc2U8U3RhdGVVcGRhdGVSZXN1bHQ+IHtcclxuICAgIGNvbnN0IHsgY2hhcHRlciwgYmlibGUsIGN1cnJlbnRTdGF0ZSwgY2Fub24sIHZlY3RvclN0b3JlLCBjb25zdHJhaW50R3JhcGggfSA9IGNvbnRleHQ7XHJcbiAgICBcclxuICAgIGNvbnN0IGNoYW5nZXM6IFN0YXRlQ2hhbmdlW10gPSBbXTtcclxuICAgIGxldCBtZW1vcmllc0FkZGVkID0gMDtcclxuICAgIGxldCBjYW5vbkZhY3RzQWRkZWQgPSAwO1xyXG4gICAgXHJcbiAgICAvLyBTdGVwIDE6IEV4dHJhY3Qgc3RhdGUgY2hhbmdlcyB1c2luZyBMTE1cclxuICAgIGNvbnN0IGV4dHJhY3Rpb24gPSBhd2FpdCB0aGlzLmV4dHJhY3RDaGFuZ2VzKGNoYXB0ZXIsIGJpYmxlLCBjdXJyZW50U3RhdGUpO1xyXG4gICAgXHJcbiAgICAvLyBTdGVwIDI6IFVwZGF0ZSBzdHJ1Y3R1cmVkIHN0YXRlXHJcbiAgICBsZXQgbmV3U3RhdGUgPSB7IC4uLmN1cnJlbnRTdGF0ZSB9O1xyXG4gICAgbmV3U3RhdGUuY2hhcHRlciA9IGNoYXB0ZXIubnVtYmVyO1xyXG4gICAgXHJcbiAgICAvLyBBcHBseSBjaGFyYWN0ZXIgY2hhbmdlc1xyXG4gICAgZm9yIChjb25zdCBjaGFuZ2Ugb2YgZXh0cmFjdGlvbi5jaGFyYWN0ZXJDaGFuZ2VzKSB7XHJcbiAgICAgIGlmIChuZXdTdGF0ZS5jaGFyYWN0ZXJzW2NoYW5nZS5uYW1lXSkge1xyXG4gICAgICAgIGNvbnN0IGNoYXIgPSBuZXdTdGF0ZS5jaGFyYWN0ZXJzW2NoYW5nZS5uYW1lXTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoY2hhbmdlLmVtb3Rpb25hbFN0YXRlKSB7XHJcbiAgICAgICAgICBjaGFyLmVtb3Rpb25hbFN0YXRlID0gY2hhbmdlLmVtb3Rpb25hbFN0YXRlO1xyXG4gICAgICAgICAgY2hhbmdlcy5wdXNoKHtcclxuICAgICAgICAgICAgdHlwZTogJ2NoYXJhY3RlcicsXHJcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHtjaGFuZ2UubmFtZX0gZW1vdGlvbmFsIHN0YXRlIOKGkiAke2NoYW5nZS5lbW90aW9uYWxTdGF0ZX1gLFxyXG4gICAgICAgICAgICBjaGFwdGVyOiBjaGFwdGVyLm51bWJlcixcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAoY2hhbmdlLmxvY2F0aW9uKSB7XHJcbiAgICAgICAgICBjb25zdCBvbGRMb2NhdGlvbiA9IGNoYXIubG9jYXRpb247XHJcbiAgICAgICAgICBjaGFyLmxvY2F0aW9uID0gY2hhbmdlLmxvY2F0aW9uO1xyXG4gICAgICAgICAgY2hhbmdlcy5wdXNoKHtcclxuICAgICAgICAgICAgdHlwZTogJ2NoYXJhY3RlcicsXHJcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHtjaGFuZ2UubmFtZX0gbW92ZWQ6ICR7b2xkTG9jYXRpb259IOKGkiAke2NoYW5nZS5sb2NhdGlvbn1gLFxyXG4gICAgICAgICAgICBjaGFwdGVyOiBjaGFwdGVyLm51bWJlcixcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICAvLyBVcGRhdGUgY29uc3RyYWludCBncmFwaFxyXG4gICAgICAgICAgY29uc3RyYWludEdyYXBoLnVwZGF0ZUNoYXJhY3RlckxvY2F0aW9uKGNoYW5nZS5uYW1lLCBjaGFuZ2UubG9jYXRpb24sIGNoYXB0ZXIubnVtYmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGNoYW5nZS5uZXdLbm93bGVkZ2UpIHtcclxuICAgICAgICAgIGNoYXIua25vd2xlZGdlID0gWy4uLmNoYXIua25vd2xlZGdlLCAuLi5jaGFuZ2UubmV3S25vd2xlZGdlXTtcclxuICAgICAgICAgIFxyXG4gICAgICAgICAgLy8gQWRkIHRvIGNvbnN0cmFpbnQgZ3JhcGhcclxuICAgICAgICAgIGZvciAoY29uc3Qga25vd2xlZGdlIG9mIGNoYW5nZS5uZXdLbm93bGVkZ2UpIHtcclxuICAgICAgICAgICAgY29uc3QgZmFjdElkID0gYGZhY3QtJHt0aGlzLnNhbml0aXplSWQoa25vd2xlZGdlKX1gO1xyXG4gICAgICAgICAgICBpZiAoIWNvbnN0cmFpbnRHcmFwaC5nZXROb2RlKGZhY3RJZCkpIHtcclxuICAgICAgICAgICAgICBjb25zdHJhaW50R3JhcGguYWRkTm9kZSh7XHJcbiAgICAgICAgICAgICAgICBpZDogZmFjdElkLFxyXG4gICAgICAgICAgICAgICAgdHlwZTogJ2ZhY3QnLFxyXG4gICAgICAgICAgICAgICAgbGFiZWw6IGtub3dsZWRnZSxcclxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IHt9LFxyXG4gICAgICAgICAgICAgICAgY2hhcHRlckVzdGFibGlzaGVkOiBjaGFwdGVyLm51bWJlcixcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3RyYWludEdyYXBoLmFkZEVkZ2Uoe1xyXG4gICAgICAgICAgICAgIGlkOiBgZWRnZS0ke2NoYW5nZS5uYW1lfS1rbm93cy0ke2ZhY3RJZH1gLFxyXG4gICAgICAgICAgICAgIGZyb206IGBjaGFyLSR7Y2hhbmdlLm5hbWV9YCxcclxuICAgICAgICAgICAgICB0bzogZmFjdElkLFxyXG4gICAgICAgICAgICAgIHR5cGU6ICdrbm93cycsXHJcbiAgICAgICAgICAgICAgcHJvcGVydGllczogeyBzaW5jZTogY2hhcHRlci5udW1iZXIgfSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjaGFuZ2UucmVsYXRpb25zaGlwQ2hhbmdlcykge1xyXG4gICAgICAgICAgZm9yIChjb25zdCByZWwgb2YgY2hhbmdlLnJlbGF0aW9uc2hpcENoYW5nZXMpIHtcclxuICAgICAgICAgICAgY2hhci5yZWxhdGlvbnNoaXBzW3JlbC53aXRoXSA9IHJlbC5uZXdTdGF0dXM7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjaGFuZ2UubmV3R29hbCkge1xyXG4gICAgICAgICAgY2hhci5nb2FscyA9IFsuLi5jaGFyLmdvYWxzLCBjaGFuZ2UubmV3R29hbF07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIEFwcGx5IHBsb3QgdGhyZWFkIGNoYW5nZXNcclxuICAgIGZvciAoY29uc3QgY2hhbmdlIG9mIGV4dHJhY3Rpb24ucGxvdFRocmVhZENoYW5nZXMpIHtcclxuICAgICAgaWYgKG5ld1N0YXRlLnBsb3RUaHJlYWRzW2NoYW5nZS5pZF0pIHtcclxuICAgICAgICBjb25zdCB0aHJlYWQgPSBuZXdTdGF0ZS5wbG90VGhyZWFkc1tjaGFuZ2UuaWRdO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjaGFuZ2Uuc3RhdHVzKSB7XHJcbiAgICAgICAgICB0aHJlYWQuc3RhdHVzID0gY2hhbmdlLnN0YXR1cztcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGNoYW5nZS50ZW5zaW9uRGVsdGEpIHtcclxuICAgICAgICAgIHRocmVhZC50ZW5zaW9uID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgdGhyZWFkLnRlbnNpb24gKyBjaGFuZ2UudGVuc2lvbkRlbHRhKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjaGFuZ2UubmV3U3VtbWFyeSkge1xyXG4gICAgICAgICAgdGhyZWFkLnN1bW1hcnkgPSBjaGFuZ2UubmV3U3VtbWFyeTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhyZWFkLmxhc3RDaGFwdGVyID0gY2hhcHRlci5udW1iZXI7XHJcbiAgICAgICAgXHJcbiAgICAgICAgY2hhbmdlcy5wdXNoKHtcclxuICAgICAgICAgIHR5cGU6ICdwbG90JyxcclxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHt0aHJlYWQubmFtZX0gdXBkYXRlZDogJHtjaGFuZ2Uuc3RhdHVzIHx8ICdwcm9ncmVzcyd9YCxcclxuICAgICAgICAgIGNoYXB0ZXI6IGNoYXB0ZXIubnVtYmVyLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIFN0ZXAgMzogQWRkIG5ldyBjYW5vbiBmYWN0c1xyXG4gICAgZm9yIChjb25zdCBmYWN0IG9mIGV4dHJhY3Rpb24ubmV3RmFjdHMpIHtcclxuICAgICAgLy8gSW4gcmVhbCBpbXBsZW1lbnRhdGlvbiwgd291bGQgYWRkIHRvIGNhbm9uIHN0b3JlXHJcbiAgICAgIGNhbm9uRmFjdHNBZGRlZCsrO1xyXG4gICAgICBjaGFuZ2VzLnB1c2goe1xyXG4gICAgICAgIHR5cGU6ICdjYW5vbicsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGBDYW5vbjogJHtmYWN0LnN1YmplY3R9ICR7ZmFjdC5hdHRyaWJ1dGV9ID0gJHtmYWN0LnZhbHVlfWAsXHJcbiAgICAgICAgY2hhcHRlcjogY2hhcHRlci5udW1iZXIsXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBTdGVwIDQ6IEV4dHJhY3QgYW5kIGFkZCBuYXJyYXRpdmUgbWVtb3JpZXNcclxuICAgIGNvbnN0IG1lbW9yaWVzID0gYXdhaXQgdGhpcy5leHRyYWN0TWVtb3JpZXMoY2hhcHRlciwgYmlibGUpO1xyXG4gICAgZm9yIChjb25zdCBtZW1vcnkgb2YgbWVtb3JpZXMpIHtcclxuICAgICAgYXdhaXQgdmVjdG9yU3RvcmUuYWRkTWVtb3J5KHtcclxuICAgICAgICBzdG9yeUlkOiBjaGFwdGVyLnN0b3J5SWQsXHJcbiAgICAgICAgY2hhcHRlck51bWJlcjogY2hhcHRlci5udW1iZXIsXHJcbiAgICAgICAgY29udGVudDogbWVtb3J5LmNvbnRlbnQsXHJcbiAgICAgICAgY2F0ZWdvcnk6IG1lbW9yeS5jYXRlZ29yeSxcclxuICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICAgIH0pO1xyXG4gICAgICBtZW1vcmllc0FkZGVkKys7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGNoYW5nZXMucHVzaCh7XHJcbiAgICAgIHR5cGU6ICdtZW1vcnknLFxyXG4gICAgICBkZXNjcmlwdGlvbjogYCR7bWVtb3JpZXNBZGRlZH0gbmFycmF0aXZlIG1lbW9yaWVzIGV4dHJhY3RlZGAsXHJcbiAgICAgIGNoYXB0ZXI6IGNoYXB0ZXIubnVtYmVyLFxyXG4gICAgfSk7XHJcbiAgICBcclxuICAgIC8vIFN0ZXAgNTogQWRkIGV2ZW50IHRvIGNvbnN0cmFpbnQgZ3JhcGhcclxuICAgIGNvbnN0cmFpbnRHcmFwaC5hZGRFdmVudChcclxuICAgICAgYGNoJHtjaGFwdGVyLm51bWJlcn1gLFxyXG4gICAgICBjaGFwdGVyLnN1bW1hcnksXHJcbiAgICAgIE9iamVjdC5rZXlzKG5ld1N0YXRlLmNoYXJhY3RlcnMpLFxyXG4gICAgICBjaGFwdGVyLm51bWJlclxyXG4gICAgKTtcclxuICAgIFxyXG4gICAgLy8gU3RlcCA2OiBVcGRhdGUgcmVjZW50IGV2ZW50c1xyXG4gICAgbmV3U3RhdGUucmVjZW50RXZlbnRzID0gWy4uLm5ld1N0YXRlLnJlY2VudEV2ZW50cywgY2hhcHRlci5zdW1tYXJ5XS5zbGljZSgtMTApO1xyXG4gICAgXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBzdHJ1Y3R1cmVkU3RhdGU6IG5ld1N0YXRlLFxyXG4gICAgICBtZW1vcmllc0FkZGVkLFxyXG4gICAgICBjYW5vbkZhY3RzQWRkZWQsXHJcbiAgICAgIGdyYXBoVXBkYXRlZDogdHJ1ZSxcclxuICAgICAgY2hhbmdlcyxcclxuICAgIH07XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIEV4dHJhY3Qgc3RhdGUgY2hhbmdlcyBmcm9tIGNoYXB0ZXJcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGV4dHJhY3RDaGFuZ2VzKFxyXG4gICAgY2hhcHRlcjogQ2hhcHRlcixcclxuICAgIGJpYmxlOiBTdG9yeUJpYmxlLFxyXG4gICAgc3RhdGU6IFN0b3J5U3RydWN0dXJlZFN0YXRlXHJcbiAgKTogUHJvbWlzZTx7XHJcbiAgICBjaGFyYWN0ZXJDaGFuZ2VzOiBBcnJheTx7XHJcbiAgICAgIG5hbWU6IHN0cmluZztcclxuICAgICAgZW1vdGlvbmFsU3RhdGU/OiBzdHJpbmc7XHJcbiAgICAgIGxvY2F0aW9uPzogc3RyaW5nO1xyXG4gICAgICBuZXdLbm93bGVkZ2U/OiBzdHJpbmdbXTtcclxuICAgICAgcmVsYXRpb25zaGlwQ2hhbmdlcz86IEFycmF5PHsgd2l0aDogc3RyaW5nOyBuZXdTdGF0dXM6IHN0cmluZyB9PjtcclxuICAgICAgbmV3R29hbD86IHN0cmluZztcclxuICAgIH0+O1xyXG4gICAgcGxvdFRocmVhZENoYW5nZXM6IEFycmF5PHtcclxuICAgICAgaWQ6IHN0cmluZztcclxuICAgICAgc3RhdHVzPzogJ2Rvcm1hbnQnIHwgJ2FjdGl2ZScgfCAnZXNjYWxhdGluZycgfCAncmVzb2x2ZWQnO1xyXG4gICAgICB0ZW5zaW9uRGVsdGE/OiBudW1iZXI7XHJcbiAgICAgIG5ld1N1bW1hcnk/OiBzdHJpbmc7XHJcbiAgICB9PjtcclxuICAgIG5ld0ZhY3RzOiBBcnJheTx7XHJcbiAgICAgIGNhdGVnb3J5OiAnY2hhcmFjdGVyJyB8ICd3b3JsZCcgfCAncGxvdCc7XHJcbiAgICAgIHN1YmplY3Q6IHN0cmluZztcclxuICAgICAgYXR0cmlidXRlOiBzdHJpbmc7XHJcbiAgICAgIHZhbHVlOiBzdHJpbmc7XHJcbiAgICB9PjtcclxuICAgIHdvcmxkQ2hhbmdlczogc3RyaW5nW107XHJcbiAgfT4ge1xyXG4gICAgY29uc3QgY2hhcmFjdGVycyA9IE9iamVjdC52YWx1ZXMoc3RhdGUuY2hhcmFjdGVycylcclxuICAgICAgLm1hcChjID0+IGAtICR7Yy5uYW1lfTogJHtjLmVtb3Rpb25hbFN0YXRlfSwgYXQgJHtjLmxvY2F0aW9ufWApXHJcbiAgICAgIC5qb2luKCdcXG4nKTtcclxuICAgIFxyXG4gICAgY29uc3QgcGxvdFRocmVhZHMgPSBPYmplY3QudmFsdWVzKHN0YXRlLnBsb3RUaHJlYWRzKVxyXG4gICAgICAubWFwKHQgPT4gYC0gJHt0Lm5hbWV9ICgke3Quc3RhdHVzfSwgJHtNYXRoLnJvdW5kKHQudGVuc2lvbiAqIDEwMCl9JSB0ZW5zaW9uKWApXHJcbiAgICAgIC5qb2luKCdcXG4nKTtcclxuICAgIFxyXG4gICAgY29uc3QgcHJvbXB0ID0gU1RBVEVfRVhUUkFDVElPTl9QUk9NUFRcclxuICAgICAgLnJlcGxhY2UoJ3t7dGl0bGV9fScsIGJpYmxlLnRpdGxlKVxyXG4gICAgICAucmVwbGFjZSgne3tnZW5yZX19JywgYmlibGUuZ2VucmUpXHJcbiAgICAgIC5yZXBsYWNlKCd7e2NoYXB0ZXJOdW1iZXJ9fScsIGNoYXB0ZXIubnVtYmVyLnRvU3RyaW5nKCkpXHJcbiAgICAgIC5yZXBsYWNlKCd7e2NoYXB0ZXJUaXRsZX19JywgY2hhcHRlci50aXRsZSlcclxuICAgICAgLnJlcGxhY2UoJ3t7Y2hhcHRlckNvbnRlbnR9fScsIGNoYXB0ZXIuY29udGVudC5zdWJzdHJpbmcoMCwgNTAwMCkpXHJcbiAgICAgIC5yZXBsYWNlKCd7e2NoYXJhY3RlcnN9fScsIGNoYXJhY3RlcnMpXHJcbiAgICAgIC5yZXBsYWNlKCd7e3Bsb3RUaHJlYWRzfX0nLCBwbG90VGhyZWFkcyk7XHJcbiAgICBcclxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldExMTSgpLmNvbXBsZXRlSlNPTjx7XHJcbiAgICAgIGNoYXJhY3RlckNoYW5nZXM6IGFueVtdO1xyXG4gICAgICBwbG90VGhyZWFkQ2hhbmdlczogYW55W107XHJcbiAgICAgIG5ld0ZhY3RzOiBhbnlbXTtcclxuICAgICAgd29ybGRDaGFuZ2VzOiBzdHJpbmdbXTtcclxuICAgIH0+KHByb21wdCwge1xyXG4gICAgICB0ZW1wZXJhdHVyZTogMC4zLFxyXG4gICAgICBtYXhUb2tlbnM6IDIwMDAsXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogRXh0cmFjdCBuYXJyYXRpdmUgbWVtb3JpZXMgZnJvbSBjaGFwdGVyXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyBleHRyYWN0TWVtb3JpZXMoXHJcbiAgICBjaGFwdGVyOiBDaGFwdGVyLFxyXG4gICAgYmlibGU6IFN0b3J5QmlibGVcclxuICApOiBQcm9taXNlPEFycmF5PHsgY29udGVudDogc3RyaW5nOyBjYXRlZ29yeTogTmFycmF0aXZlTWVtb3J5WydjYXRlZ29yeSddIH0+PiB7XHJcbiAgICAvLyBTaW1wbGlmaWVkIG1lbW9yeSBleHRyYWN0aW9uXHJcbiAgICAvLyBJbiByZWFsIGltcGxlbWVudGF0aW9uLCB3b3VsZCB1c2UgTWVtb3J5RXh0cmFjdG9yIGFnZW50XHJcbiAgICBjb25zdCBtZW1vcmllczogQXJyYXk8eyBjb250ZW50OiBzdHJpbmc7IGNhdGVnb3J5OiBOYXJyYXRpdmVNZW1vcnlbJ2NhdGVnb3J5J10gfT4gPSBbXTtcclxuICAgIFxyXG4gICAgLy8gRXh0cmFjdCBrZXkgZXZlbnRzIGZyb20gc3VtbWFyeVxyXG4gICAgaWYgKGNoYXB0ZXIuc3VtbWFyeSkge1xyXG4gICAgICBtZW1vcmllcy5wdXNoKHtcclxuICAgICAgICBjb250ZW50OiBjaGFwdGVyLnN1bW1hcnksXHJcbiAgICAgICAgY2F0ZWdvcnk6ICdldmVudCcsXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBBZGQgY2hhcHRlciB0aXRsZSBhcyBtZW1vcnlcclxuICAgIG1lbW9yaWVzLnB1c2goe1xyXG4gICAgICBjb250ZW50OiBgQ2hhcHRlciAke2NoYXB0ZXIubnVtYmVyfTogJHtjaGFwdGVyLnRpdGxlfWAsXHJcbiAgICAgIGNhdGVnb3J5OiAncGxvdCcsXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgcmV0dXJuIG1lbW9yaWVzO1xyXG4gIH1cclxuICBcclxuICAvKipcclxuICAgKiBRdWljayB1cGRhdGUgd2l0aG91dCBMTE0gKGZvciB0ZXN0aW5nKVxyXG4gICAqL1xyXG4gIGFzeW5jIHF1aWNrVXBkYXRlKGNvbnRleHQ6IFVwZGF0ZUNvbnRleHQpOiBQcm9taXNlPFN0YXRlVXBkYXRlUmVzdWx0PiB7XHJcbiAgICBjb25zdCB7IGNoYXB0ZXIsIGN1cnJlbnRTdGF0ZSwgdmVjdG9yU3RvcmUsIGNvbnN0cmFpbnRHcmFwaCB9ID0gY29udGV4dDtcclxuICAgIFxyXG4gICAgY29uc3QgY2hhbmdlczogU3RhdGVDaGFuZ2VbXSA9IFtdO1xyXG4gICAgbGV0IG5ld1N0YXRlID0geyAuLi5jdXJyZW50U3RhdGUgfTtcclxuICAgIG5ld1N0YXRlLmNoYXB0ZXIgPSBjaGFwdGVyLm51bWJlcjtcclxuICAgIFxyXG4gICAgLy8gQWRkIGJhc2ljIG1lbW9yaWVzXHJcbiAgICBhd2FpdCB2ZWN0b3JTdG9yZS5hZGRNZW1vcnkoe1xyXG4gICAgICBzdG9yeUlkOiBjaGFwdGVyLnN0b3J5SWQsXHJcbiAgICAgIGNoYXB0ZXJOdW1iZXI6IGNoYXB0ZXIubnVtYmVyLFxyXG4gICAgICBjb250ZW50OiBjaGFwdGVyLnN1bW1hcnksXHJcbiAgICAgIGNhdGVnb3J5OiAnZXZlbnQnLFxyXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgYXdhaXQgdmVjdG9yU3RvcmUuYWRkTWVtb3J5KHtcclxuICAgICAgc3RvcnlJZDogY2hhcHRlci5zdG9yeUlkLFxyXG4gICAgICBjaGFwdGVyTnVtYmVyOiBjaGFwdGVyLm51bWJlcixcclxuICAgICAgY29udGVudDogYENoYXB0ZXIgJHtjaGFwdGVyLm51bWJlcn06ICR7Y2hhcHRlci50aXRsZX1gLFxyXG4gICAgICBjYXRlZ29yeTogJ3Bsb3QnLFxyXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgY2hhbmdlcy5wdXNoKHtcclxuICAgICAgdHlwZTogJ21lbW9yeScsXHJcbiAgICAgIGRlc2NyaXB0aW9uOiBgMiBtZW1vcmllcyBhZGRlZCAocXVpY2sgbW9kZSlgLFxyXG4gICAgICBjaGFwdGVyOiBjaGFwdGVyLm51bWJlcixcclxuICAgIH0pO1xyXG4gICAgXHJcbiAgICAvLyBVcGRhdGUgcmVjZW50IGV2ZW50c1xyXG4gICAgbmV3U3RhdGUucmVjZW50RXZlbnRzID0gWy4uLm5ld1N0YXRlLnJlY2VudEV2ZW50cywgY2hhcHRlci5zdW1tYXJ5XS5zbGljZSgtMTApO1xyXG4gICAgXHJcbiAgICAvLyBBZGQgdG8gY29uc3RyYWludCBncmFwaFxyXG4gICAgY29uc3RyYWludEdyYXBoLmFkZEV2ZW50KFxyXG4gICAgICBgY2gke2NoYXB0ZXIubnVtYmVyfWAsXHJcbiAgICAgIGNoYXB0ZXIuc3VtbWFyeSxcclxuICAgICAgT2JqZWN0LmtleXMobmV3U3RhdGUuY2hhcmFjdGVycyksXHJcbiAgICAgIGNoYXB0ZXIubnVtYmVyXHJcbiAgICApO1xyXG4gICAgXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBzdHJ1Y3R1cmVkU3RhdGU6IG5ld1N0YXRlLFxyXG4gICAgICBtZW1vcmllc0FkZGVkOiAyLFxyXG4gICAgICBjYW5vbkZhY3RzQWRkZWQ6IDAsXHJcbiAgICAgIGdyYXBoVXBkYXRlZDogdHJ1ZSxcclxuICAgICAgY2hhbmdlcyxcclxuICAgIH07XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIEZvcm1hdCB1cGRhdGUgcmVzdWx0XHJcbiAgICovXHJcbiAgZm9ybWF0UmVzdWx0KHJlc3VsdDogU3RhdGVVcGRhdGVSZXN1bHQpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gWycjIyBTdGF0ZSBVcGRhdGUgUmVzdWx0J107XHJcbiAgICBcclxuICAgIGxpbmVzLnB1c2goYFxcbioqTWVtb3JpZXMgQWRkZWQ6KiogJHtyZXN1bHQubWVtb3JpZXNBZGRlZH1gKTtcclxuICAgIGxpbmVzLnB1c2goYCoqQ2Fub24gRmFjdHMgQWRkZWQ6KiogJHtyZXN1bHQuY2Fub25GYWN0c0FkZGVkfWApO1xyXG4gICAgbGluZXMucHVzaChgKipHcmFwaCBVcGRhdGVkOioqICR7cmVzdWx0LmdyYXBoVXBkYXRlZCA/ICfinIUnIDogJ+KdjCd9YCk7XHJcbiAgICBcclxuICAgIGlmIChyZXN1bHQuY2hhbmdlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGxpbmVzLnB1c2goJ1xcbioqQ2hhbmdlczoqKicpO1xyXG4gICAgICBcclxuICAgICAgY29uc3QgYnlUeXBlOiBSZWNvcmQ8c3RyaW5nLCBTdGF0ZUNoYW5nZVtdPiA9IHtcclxuICAgICAgICBjaGFyYWN0ZXI6IFtdLFxyXG4gICAgICAgIHBsb3Q6IFtdLFxyXG4gICAgICAgIHdvcmxkOiBbXSxcclxuICAgICAgICBjYW5vbjogW10sXHJcbiAgICAgICAgbWVtb3J5OiBbXSxcclxuICAgICAgfTtcclxuICAgICAgXHJcbiAgICAgIGZvciAoY29uc3QgY2hhbmdlIG9mIHJlc3VsdC5jaGFuZ2VzKSB7XHJcbiAgICAgICAgYnlUeXBlW2NoYW5nZS50eXBlXS5wdXNoKGNoYW5nZSk7XHJcbiAgICAgIH1cclxuICAgICAgXHJcbiAgICAgIGZvciAoY29uc3QgW3R5cGUsIGNoYW5nZXNdIG9mIE9iamVjdC5lbnRyaWVzKGJ5VHlwZSkpIHtcclxuICAgICAgICBpZiAoY2hhbmdlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICBsaW5lcy5wdXNoKGBcXG4qJHt0eXBlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgdHlwZS5zbGljZSgxKX06KmApO1xyXG4gICAgICAgICAgZm9yIChjb25zdCBjaGFuZ2Ugb2YgY2hhbmdlcykge1xyXG4gICAgICAgICAgICBsaW5lcy5wdXNoKGAgIC0gJHtjaGFuZ2UuZGVzY3JpcHRpb259YCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHJldHVybiBsaW5lcy5qb2luKCdcXG4nKTtcclxuICB9XHJcbiAgXHJcbiAgcHJpdmF0ZSBzYW5pdGl6ZUlkKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBzdHIucmVwbGFjZSgvW15hLXpBLVowLTldL2csICdfJykuc3Vic3RyaW5nKDAsIDUwKTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBzdGF0ZVVwZGF0ZXJQaXBlbGluZSA9IG5ldyBTdGF0ZVVwZGF0ZXJQaXBlbGluZSgpO1xyXG4iXX0=
@@ -0,0 +1,41 @@
1
+ export interface NarrativeMemory {
2
+ id: number;
3
+ storyId: string;
4
+ chapterNumber: number;
5
+ content: string;
6
+ category: 'event' | 'character' | 'world' | 'plot';
7
+ timestamp: Date;
8
+ embedding?: number[];
9
+ }
10
+ export interface MemorySearchResult {
11
+ memory: NarrativeMemory;
12
+ score: number;
13
+ }
14
+ export declare class VectorStore {
15
+ private index;
16
+ private memories;
17
+ private dimension;
18
+ private storyId;
19
+ private nextId;
20
+ constructor(storyId: string);
21
+ initialize(maxElements?: number): Promise<void>;
22
+ /**
23
+ * Resize the index to accommodate more memories
24
+ */
25
+ resizeIndex(newMaxElements: number): void;
26
+ /**
27
+ * Ensure capacity for upcoming memories
28
+ */
29
+ ensureCapacity(additionalMemories: number): void;
30
+ addMemory(memory: Omit<NarrativeMemory, 'id' | 'embedding'>): Promise<NarrativeMemory>;
31
+ searchSimilar(query: string, k?: number): Promise<MemorySearchResult[]>;
32
+ searchByCategory(query: string, category: NarrativeMemory['category'], k?: number): Promise<MemorySearchResult[]>;
33
+ getMemoriesByChapter(chapterNumber: number): NarrativeMemory[];
34
+ getAllMemories(): NarrativeMemory[];
35
+ private generateEmbedding;
36
+ private generateMockEmbedding;
37
+ serialize(): string;
38
+ load(data: string): Promise<void>;
39
+ }
40
+ export declare function getVectorStore(storyId: string): VectorStore;
41
+ export declare function clearVectorStore(storyId: string): void;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VectorStore = void 0;
4
+ exports.getVectorStore = getVectorStore;
5
+ exports.clearVectorStore = clearVectorStore;
6
+ const client_js_1 = require("../llm/client.js");
7
+ const hnswlib_node_1 = require("hnswlib-node");
8
+ class VectorStore {
9
+ index = null;
10
+ memories = new Map();
11
+ dimension = 1536; // text-embedding-3-small dimension
12
+ storyId;
13
+ nextId = 0;
14
+ constructor(storyId) {
15
+ this.storyId = storyId;
16
+ }
17
+ async initialize(maxElements = 10000) {
18
+ this.index = new hnswlib_node_1.HierarchicalNSW('cosine', this.dimension);
19
+ this.index.initIndex(maxElements, 16, 200);
20
+ this.nextId = 0;
21
+ this.memories.clear();
22
+ }
23
+ /**
24
+ * Resize the index to accommodate more memories
25
+ */
26
+ resizeIndex(newMaxElements) {
27
+ if (!this.index) {
28
+ throw new Error('VectorStore not initialized. Call initialize() first.');
29
+ }
30
+ if (newMaxElements <= this.memories.size) {
31
+ return; // No need to resize
32
+ }
33
+ this.index.resizeIndex(newMaxElements);
34
+ }
35
+ /**
36
+ * Ensure capacity for upcoming memories
37
+ */
38
+ ensureCapacity(additionalMemories) {
39
+ const requiredCapacity = this.memories.size + additionalMemories;
40
+ const currentCapacity = this.index?.getMaxElements() || 0;
41
+ if (requiredCapacity > currentCapacity) {
42
+ // Add 50% more capacity or use required, whichever is larger
43
+ const newCapacity = Math.max(Math.floor(currentCapacity * 1.5), requiredCapacity);
44
+ this.resizeIndex(newCapacity);
45
+ }
46
+ }
47
+ async addMemory(memory) {
48
+ if (!this.index) {
49
+ throw new Error('VectorStore not initialized. Call initialize() first.');
50
+ }
51
+ // Auto-resize if we're near capacity (add 50% more)
52
+ const currentCapacity = this.index.getMaxElements();
53
+ if (this.memories.size >= currentCapacity - 1) {
54
+ this.resizeIndex(Math.floor(currentCapacity * 1.5));
55
+ }
56
+ const id = this.nextId++;
57
+ // Generate embedding using OpenAI
58
+ const embedding = await this.generateEmbedding(memory.content);
59
+ const fullMemory = {
60
+ ...memory,
61
+ id,
62
+ embedding,
63
+ };
64
+ // Add to HNSW index
65
+ this.index.addPoint(embedding, id);
66
+ this.memories.set(id, fullMemory);
67
+ return fullMemory;
68
+ }
69
+ async searchSimilar(query, k = 5) {
70
+ if (!this.index) {
71
+ throw new Error('VectorStore not initialized. Call initialize() first.');
72
+ }
73
+ const queryEmbedding = await this.generateEmbedding(query);
74
+ const results = this.index.searchKnn(queryEmbedding, k);
75
+ return results.neighbors.map((id, i) => ({
76
+ memory: this.memories.get(id),
77
+ score: results.distances[i],
78
+ }));
79
+ }
80
+ async searchByCategory(query, category, k = 5) {
81
+ const results = await this.searchSimilar(query, k * 2);
82
+ return results
83
+ .filter(r => r.memory.category === category)
84
+ .slice(0, k);
85
+ }
86
+ getMemoriesByChapter(chapterNumber) {
87
+ return Array.from(this.memories.values())
88
+ .filter(m => m.chapterNumber === chapterNumber);
89
+ }
90
+ getAllMemories() {
91
+ return Array.from(this.memories.values());
92
+ }
93
+ async generateEmbedding(text) {
94
+ // Check if we should use mock embeddings (for testing without OpenAI)
95
+ if (process.env.USE_MOCK_EMBEDDINGS === 'true') {
96
+ return this.generateMockEmbedding(text);
97
+ }
98
+ const llm = (0, client_js_1.getLLM)();
99
+ const openai = llm.provider;
100
+ // Access the underlying OpenAI client for embeddings
101
+ const client = openai.client;
102
+ try {
103
+ const response = await client.embeddings.create({
104
+ model: 'text-embedding-3-small',
105
+ input: text,
106
+ });
107
+ return response.data[0].embedding;
108
+ }
109
+ catch (error) {
110
+ // Fall back to mock embeddings if the API fails (e.g., DeepSeek doesn't support embeddings)
111
+ console.log(' [VectorStore] Using mock embeddings (API unavailable)');
112
+ return this.generateMockEmbedding(text);
113
+ }
114
+ }
115
+ generateMockEmbedding(text) {
116
+ // Generate a deterministic mock embedding based on text content
117
+ // This is NOT for production - just for testing without OpenAI API
118
+ const embedding = [];
119
+ let seed = 0;
120
+ for (let i = 0; i < text.length; i++) {
121
+ seed += text.charCodeAt(i);
122
+ }
123
+ for (let i = 0; i < this.dimension; i++) {
124
+ // Simple pseudo-random based on seed
125
+ seed = (seed * 9301 + 49297) % 233280;
126
+ embedding.push((seed / 233280) * 2 - 1); // Range: -1 to 1
127
+ }
128
+ // Normalize the vector
129
+ const norm = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
130
+ return embedding.map(val => val / norm);
131
+ }
132
+ // Serialize for persistence
133
+ serialize() {
134
+ return JSON.stringify({
135
+ storyId: this.storyId,
136
+ nextId: this.nextId,
137
+ memories: Array.from(this.memories.entries()),
138
+ });
139
+ }
140
+ // Deserialize from saved state
141
+ async load(data) {
142
+ const parsed = JSON.parse(data);
143
+ this.memories = new Map(parsed.memories);
144
+ this.nextId = parsed.nextId || this.memories.size;
145
+ // Rebuild HNSW index
146
+ await this.initialize();
147
+ for (const [id, memory] of this.memories) {
148
+ if (memory.embedding) {
149
+ this.index.addPoint(memory.embedding, id);
150
+ }
151
+ }
152
+ }
153
+ }
154
+ exports.VectorStore = VectorStore;
155
+ // Factory for story-specific stores
156
+ const stores = new Map();
157
+ function getVectorStore(storyId) {
158
+ if (!stores.has(storyId)) {
159
+ stores.set(storyId, new VectorStore(storyId));
160
+ }
161
+ return stores.get(storyId);
162
+ }
163
+ function clearVectorStore(storyId) {
164
+ stores.delete(storyId);
165
+ }
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yU3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWVtb3J5L3ZlY3RvclN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQXFNQSx3Q0FLQztBQUVELDRDQUVDO0FBOU1ELGdEQUEwQztBQUMxQywrQ0FBK0M7QUFpQi9DLE1BQWEsV0FBVztJQUNkLEtBQUssR0FBMkIsSUFBSSxDQUFDO0lBQ3JDLFFBQVEsR0FBaUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNuRCxTQUFTLEdBQVcsSUFBSSxDQUFDLENBQUMsbUNBQW1DO0lBQzdELE9BQU8sQ0FBUztJQUNoQixNQUFNLEdBQVcsQ0FBQyxDQUFDO0lBRTNCLFlBQVksT0FBZTtRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUN6QixDQUFDO0lBRUQsS0FBSyxDQUFDLFVBQVUsQ0FBQyxjQUFzQixLQUFLO1FBQzFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSw4QkFBZSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVcsQ0FBQyxjQUFzQjtRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUMzRSxDQUFDO1FBRUQsSUFBSSxjQUFjLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN6QyxPQUFPLENBQUMsb0JBQW9CO1FBQzlCLENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxjQUFjLENBQUMsa0JBQTBCO1FBQ3ZDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7UUFDakUsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFMUQsSUFBSSxnQkFBZ0IsR0FBRyxlQUFlLEVBQUUsQ0FBQztZQUN2Qyw2REFBNkQ7WUFDN0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxHQUFHLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQWlEO1FBQy9ELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1FBQzNFLENBQUM7UUFFRCxvREFBb0Q7UUFDcEQsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNwRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLGVBQWUsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM5QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUV6QixrQ0FBa0M7UUFDbEMsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRS9ELE1BQU0sVUFBVSxHQUFvQjtZQUNsQyxHQUFHLE1BQU07WUFDVCxFQUFFO1lBQ0YsU0FBUztTQUNWLENBQUM7UUFFRixvQkFBb0I7UUFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ25DLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUVsQyxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFhLEVBQUUsSUFBWSxDQUFDO1FBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1FBQzNFLENBQUM7UUFFRCxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFeEQsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQVUsRUFBRSxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdkQsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBRTtZQUM5QixLQUFLLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7U0FDNUIsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEtBQWEsRUFBRSxRQUFxQyxFQUFFLElBQVksQ0FBQztRQUN4RixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2RCxPQUFPLE9BQU87YUFDWCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUM7YUFDM0MsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqQixDQUFDO0lBRUQsb0JBQW9CLENBQUMsYUFBcUI7UUFDeEMsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7YUFDdEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGFBQWEsS0FBSyxhQUFhLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVPLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFZO1FBQzFDLHNFQUFzRTtRQUN0RSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDL0MsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUVELE1BQU0sR0FBRyxHQUFHLElBQUEsa0JBQU0sR0FBRSxDQUFDO1FBQ3JCLE1BQU0sTUFBTSxHQUFJLEdBQVcsQ0FBQyxRQUFRLENBQUM7UUFFckMscURBQXFEO1FBQ3JELE1BQU0sTUFBTSxHQUFJLE1BQWMsQ0FBQyxNQUFNLENBQUM7UUFFdEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztnQkFDOUMsS0FBSyxFQUFFLHdCQUF3QjtnQkFDL0IsS0FBSyxFQUFFLElBQUk7YUFDWixDQUFDLENBQUM7WUFDSCxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3BDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsNEZBQTRGO1lBQzVGLE9BQU8sQ0FBQyxHQUFHLENBQUMseURBQXlELENBQUMsQ0FBQztZQUN2RSxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLHFCQUFxQixDQUFDLElBQVk7UUFDeEMsZ0VBQWdFO1FBQ2hFLG1FQUFtRTtRQUNuRSxNQUFNLFNBQVMsR0FBYSxFQUFFLENBQUM7UUFDL0IsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNyQyxJQUFJLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBRUQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN4QyxxQ0FBcUM7WUFDckMsSUFBSSxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUM7WUFDdEMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7UUFDNUQsQ0FBQztRQUVELHVCQUF1QjtRQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNFLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsNEJBQTRCO0lBQzVCLFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDcEIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQzlDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCwrQkFBK0I7SUFDL0IsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFZO1FBQ3JCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBRWxELHFCQUFxQjtRQUNyQixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN4QixLQUFLLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3pDLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNyQixJQUFJLENBQUMsS0FBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzdDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBOUtELGtDQThLQztBQUVELG9DQUFvQztBQUNwQyxNQUFNLE1BQU0sR0FBNkIsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUVuRCxTQUFnQixjQUFjLENBQUMsT0FBZTtJQUM1QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUUsQ0FBQztBQUM5QixDQUFDO0FBRUQsU0FBZ0IsZ0JBQWdCLENBQUMsT0FBZTtJQUM5QyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRMTE0gfSBmcm9tICcuLi9sbG0vY2xpZW50LmpzJztcclxuaW1wb3J0IHsgSGllcmFyY2hpY2FsTlNXIH0gZnJvbSAnaG5zd2xpYi1ub2RlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmFycmF0aXZlTWVtb3J5IHtcclxuICBpZDogbnVtYmVyO1xyXG4gIHN0b3J5SWQ6IHN0cmluZztcclxuICBjaGFwdGVyTnVtYmVyOiBudW1iZXI7XHJcbiAgY29udGVudDogc3RyaW5nO1xyXG4gIGNhdGVnb3J5OiAnZXZlbnQnIHwgJ2NoYXJhY3RlcicgfCAnd29ybGQnIHwgJ3Bsb3QnO1xyXG4gIHRpbWVzdGFtcDogRGF0ZTtcclxuICBlbWJlZGRpbmc/OiBudW1iZXJbXTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBNZW1vcnlTZWFyY2hSZXN1bHQge1xyXG4gIG1lbW9yeTogTmFycmF0aXZlTWVtb3J5O1xyXG4gIHNjb3JlOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBWZWN0b3JTdG9yZSB7XHJcbiAgcHJpdmF0ZSBpbmRleDogSGllcmFyY2hpY2FsTlNXIHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBtZW1vcmllczogTWFwPG51bWJlciwgTmFycmF0aXZlTWVtb3J5PiA9IG5ldyBNYXAoKTtcclxuICBwcml2YXRlIGRpbWVuc2lvbjogbnVtYmVyID0gMTUzNjsgLy8gdGV4dC1lbWJlZGRpbmctMy1zbWFsbCBkaW1lbnNpb25cclxuICBwcml2YXRlIHN0b3J5SWQ6IHN0cmluZztcclxuICBwcml2YXRlIG5leHRJZDogbnVtYmVyID0gMDtcclxuXHJcbiAgY29uc3RydWN0b3Ioc3RvcnlJZDogc3RyaW5nKSB7XHJcbiAgICB0aGlzLnN0b3J5SWQgPSBzdG9yeUlkO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgaW5pdGlhbGl6ZShtYXhFbGVtZW50czogbnVtYmVyID0gMTAwMDApOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMuaW5kZXggPSBuZXcgSGllcmFyY2hpY2FsTlNXKCdjb3NpbmUnLCB0aGlzLmRpbWVuc2lvbik7XHJcbiAgICB0aGlzLmluZGV4LmluaXRJbmRleChtYXhFbGVtZW50cywgMTYsIDIwMCk7XHJcbiAgICB0aGlzLm5leHRJZCA9IDA7XHJcbiAgICB0aGlzLm1lbW9yaWVzLmNsZWFyKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNpemUgdGhlIGluZGV4IHRvIGFjY29tbW9kYXRlIG1vcmUgbWVtb3JpZXNcclxuICAgKi9cclxuICByZXNpemVJbmRleChuZXdNYXhFbGVtZW50czogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaW5kZXgpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZWN0b3JTdG9yZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBpZiAobmV3TWF4RWxlbWVudHMgPD0gdGhpcy5tZW1vcmllcy5zaXplKSB7XHJcbiAgICAgIHJldHVybjsgLy8gTm8gbmVlZCB0byByZXNpemVcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5pbmRleC5yZXNpemVJbmRleChuZXdNYXhFbGVtZW50cyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFbnN1cmUgY2FwYWNpdHkgZm9yIHVwY29taW5nIG1lbW9yaWVzXHJcbiAgICovXHJcbiAgZW5zdXJlQ2FwYWNpdHkoYWRkaXRpb25hbE1lbW9yaWVzOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGNvbnN0IHJlcXVpcmVkQ2FwYWNpdHkgPSB0aGlzLm1lbW9yaWVzLnNpemUgKyBhZGRpdGlvbmFsTWVtb3JpZXM7XHJcbiAgICBjb25zdCBjdXJyZW50Q2FwYWNpdHkgPSB0aGlzLmluZGV4Py5nZXRNYXhFbGVtZW50cygpIHx8IDA7XHJcbiAgICBcclxuICAgIGlmIChyZXF1aXJlZENhcGFjaXR5ID4gY3VycmVudENhcGFjaXR5KSB7XHJcbiAgICAgIC8vIEFkZCA1MCUgbW9yZSBjYXBhY2l0eSBvciB1c2UgcmVxdWlyZWQsIHdoaWNoZXZlciBpcyBsYXJnZXJcclxuICAgICAgY29uc3QgbmV3Q2FwYWNpdHkgPSBNYXRoLm1heChNYXRoLmZsb29yKGN1cnJlbnRDYXBhY2l0eSAqIDEuNSksIHJlcXVpcmVkQ2FwYWNpdHkpO1xyXG4gICAgICB0aGlzLnJlc2l6ZUluZGV4KG5ld0NhcGFjaXR5KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFzeW5jIGFkZE1lbW9yeShtZW1vcnk6IE9taXQ8TmFycmF0aXZlTWVtb3J5LCAnaWQnIHwgJ2VtYmVkZGluZyc+KTogUHJvbWlzZTxOYXJyYXRpdmVNZW1vcnk+IHtcclxuICAgIGlmICghdGhpcy5pbmRleCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlY3RvclN0b3JlIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0aWFsaXplKCkgZmlyc3QuJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQXV0by1yZXNpemUgaWYgd2UncmUgbmVhciBjYXBhY2l0eSAoYWRkIDUwJSBtb3JlKVxyXG4gICAgY29uc3QgY3VycmVudENhcGFjaXR5ID0gdGhpcy5pbmRleC5nZXRNYXhFbGVtZW50cygpO1xyXG4gICAgaWYgKHRoaXMubWVtb3JpZXMuc2l6ZSA+PSBjdXJyZW50Q2FwYWNpdHkgLSAxKSB7XHJcbiAgICAgIHRoaXMucmVzaXplSW5kZXgoTWF0aC5mbG9vcihjdXJyZW50Q2FwYWNpdHkgKiAxLjUpKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBpZCA9IHRoaXMubmV4dElkKys7XHJcbiAgICBcclxuICAgIC8vIEdlbmVyYXRlIGVtYmVkZGluZyB1c2luZyBPcGVuQUlcclxuICAgIGNvbnN0IGVtYmVkZGluZyA9IGF3YWl0IHRoaXMuZ2VuZXJhdGVFbWJlZGRpbmcobWVtb3J5LmNvbnRlbnQpO1xyXG4gICAgXHJcbiAgICBjb25zdCBmdWxsTWVtb3J5OiBOYXJyYXRpdmVNZW1vcnkgPSB7XHJcbiAgICAgIC4uLm1lbW9yeSxcclxuICAgICAgaWQsXHJcbiAgICAgIGVtYmVkZGluZyxcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkIHRvIEhOU1cgaW5kZXhcclxuICAgIHRoaXMuaW5kZXguYWRkUG9pbnQoZW1iZWRkaW5nLCBpZCk7XHJcbiAgICB0aGlzLm1lbW9yaWVzLnNldChpZCwgZnVsbE1lbW9yeSk7XHJcblxyXG4gICAgcmV0dXJuIGZ1bGxNZW1vcnk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBzZWFyY2hTaW1pbGFyKHF1ZXJ5OiBzdHJpbmcsIGs6IG51bWJlciA9IDUpOiBQcm9taXNlPE1lbW9yeVNlYXJjaFJlc3VsdFtdPiB7XHJcbiAgICBpZiAoIXRoaXMuaW5kZXgpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZWN0b3JTdG9yZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHF1ZXJ5RW1iZWRkaW5nID0gYXdhaXQgdGhpcy5nZW5lcmF0ZUVtYmVkZGluZyhxdWVyeSk7XHJcbiAgICBjb25zdCByZXN1bHRzID0gdGhpcy5pbmRleC5zZWFyY2hLbm4ocXVlcnlFbWJlZGRpbmcsIGspO1xyXG5cclxuICAgIHJldHVybiByZXN1bHRzLm5laWdoYm9ycy5tYXAoKGlkOiBudW1iZXIsIGk6IG51bWJlcikgPT4gKHtcclxuICAgICAgbWVtb3J5OiB0aGlzLm1lbW9yaWVzLmdldChpZCkhLFxyXG4gICAgICBzY29yZTogcmVzdWx0cy5kaXN0YW5jZXNbaV0sXHJcbiAgICB9KSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBzZWFyY2hCeUNhdGVnb3J5KHF1ZXJ5OiBzdHJpbmcsIGNhdGVnb3J5OiBOYXJyYXRpdmVNZW1vcnlbJ2NhdGVnb3J5J10sIGs6IG51bWJlciA9IDUpOiBQcm9taXNlPE1lbW9yeVNlYXJjaFJlc3VsdFtdPiB7XHJcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5zZWFyY2hTaW1pbGFyKHF1ZXJ5LCBrICogMik7XHJcbiAgICByZXR1cm4gcmVzdWx0c1xyXG4gICAgICAuZmlsdGVyKHIgPT4gci5tZW1vcnkuY2F0ZWdvcnkgPT09IGNhdGVnb3J5KVxyXG4gICAgICAuc2xpY2UoMCwgayk7XHJcbiAgfVxyXG5cclxuICBnZXRNZW1vcmllc0J5Q2hhcHRlcihjaGFwdGVyTnVtYmVyOiBudW1iZXIpOiBOYXJyYXRpdmVNZW1vcnlbXSB7XHJcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLm1lbW9yaWVzLnZhbHVlcygpKVxyXG4gICAgICAuZmlsdGVyKG0gPT4gbS5jaGFwdGVyTnVtYmVyID09PSBjaGFwdGVyTnVtYmVyKTtcclxuICB9XHJcblxyXG4gIGdldEFsbE1lbW9yaWVzKCk6IE5hcnJhdGl2ZU1lbW9yeVtdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMubWVtb3JpZXMudmFsdWVzKCkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZUVtYmVkZGluZyh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcltdPiB7XHJcbiAgICAvLyBDaGVjayBpZiB3ZSBzaG91bGQgdXNlIG1vY2sgZW1iZWRkaW5ncyAoZm9yIHRlc3Rpbmcgd2l0aG91dCBPcGVuQUkpXHJcbiAgICBpZiAocHJvY2Vzcy5lbnYuVVNFX01PQ0tfRU1CRURESU5HUyA9PT0gJ3RydWUnKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmdlbmVyYXRlTW9ja0VtYmVkZGluZyh0ZXh0KTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBsbG0gPSBnZXRMTE0oKTtcclxuICAgIGNvbnN0IG9wZW5haSA9IChsbG0gYXMgYW55KS5wcm92aWRlcjtcclxuICAgIFxyXG4gICAgLy8gQWNjZXNzIHRoZSB1bmRlcmx5aW5nIE9wZW5BSSBjbGllbnQgZm9yIGVtYmVkZGluZ3NcclxuICAgIGNvbnN0IGNsaWVudCA9IChvcGVuYWkgYXMgYW55KS5jbGllbnQ7XHJcbiAgICBcclxuICAgIHRyeSB7XHJcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmVtYmVkZGluZ3MuY3JlYXRlKHtcclxuICAgICAgICBtb2RlbDogJ3RleHQtZW1iZWRkaW5nLTMtc21hbGwnLFxyXG4gICAgICAgIGlucHV0OiB0ZXh0LFxyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGFbMF0uZW1iZWRkaW5nO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgLy8gRmFsbCBiYWNrIHRvIG1vY2sgZW1iZWRkaW5ncyBpZiB0aGUgQVBJIGZhaWxzIChlLmcuLCBEZWVwU2VlayBkb2Vzbid0IHN1cHBvcnQgZW1iZWRkaW5ncylcclxuICAgICAgY29uc29sZS5sb2coJyAgW1ZlY3RvclN0b3JlXSBVc2luZyBtb2NrIGVtYmVkZGluZ3MgKEFQSSB1bmF2YWlsYWJsZSknKTtcclxuICAgICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVNb2NrRW1iZWRkaW5nKHRleHQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZW5lcmF0ZU1vY2tFbWJlZGRpbmcodGV4dDogc3RyaW5nKTogbnVtYmVyW10ge1xyXG4gICAgLy8gR2VuZXJhdGUgYSBkZXRlcm1pbmlzdGljIG1vY2sgZW1iZWRkaW5nIGJhc2VkIG9uIHRleHQgY29udGVudFxyXG4gICAgLy8gVGhpcyBpcyBOT1QgZm9yIHByb2R1Y3Rpb24gLSBqdXN0IGZvciB0ZXN0aW5nIHdpdGhvdXQgT3BlbkFJIEFQSVxyXG4gICAgY29uc3QgZW1iZWRkaW5nOiBudW1iZXJbXSA9IFtdO1xyXG4gICAgbGV0IHNlZWQgPSAwO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIHNlZWQgKz0gdGV4dC5jaGFyQ29kZUF0KGkpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGltZW5zaW9uOyBpKyspIHtcclxuICAgICAgLy8gU2ltcGxlIHBzZXVkby1yYW5kb20gYmFzZWQgb24gc2VlZFxyXG4gICAgICBzZWVkID0gKHNlZWQgKiA5MzAxICsgNDkyOTcpICUgMjMzMjgwO1xyXG4gICAgICBlbWJlZGRpbmcucHVzaCgoc2VlZCAvIDIzMzI4MCkgKiAyIC0gMSk7IC8vIFJhbmdlOiAtMSB0byAxXHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIE5vcm1hbGl6ZSB0aGUgdmVjdG9yXHJcbiAgICBjb25zdCBub3JtID0gTWF0aC5zcXJ0KGVtYmVkZGluZy5yZWR1Y2UoKHN1bSwgdmFsKSA9PiBzdW0gKyB2YWwgKiB2YWwsIDApKTtcclxuICAgIHJldHVybiBlbWJlZGRpbmcubWFwKHZhbCA9PiB2YWwgLyBub3JtKTtcclxuICB9XHJcblxyXG4gIC8vIFNlcmlhbGl6ZSBmb3IgcGVyc2lzdGVuY2VcclxuICBzZXJpYWxpemUoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XHJcbiAgICAgIHN0b3J5SWQ6IHRoaXMuc3RvcnlJZCxcclxuICAgICAgbmV4dElkOiB0aGlzLm5leHRJZCxcclxuICAgICAgbWVtb3JpZXM6IEFycmF5LmZyb20odGhpcy5tZW1vcmllcy5lbnRyaWVzKCkpLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyBEZXNlcmlhbGl6ZSBmcm9tIHNhdmVkIHN0YXRlXHJcbiAgYXN5bmMgbG9hZChkYXRhOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoZGF0YSk7XHJcbiAgICB0aGlzLm1lbW9yaWVzID0gbmV3IE1hcChwYXJzZWQubWVtb3JpZXMpO1xyXG4gICAgdGhpcy5uZXh0SWQgPSBwYXJzZWQubmV4dElkIHx8IHRoaXMubWVtb3JpZXMuc2l6ZTtcclxuICAgIFxyXG4gICAgLy8gUmVidWlsZCBITlNXIGluZGV4XHJcbiAgICBhd2FpdCB0aGlzLmluaXRpYWxpemUoKTtcclxuICAgIGZvciAoY29uc3QgW2lkLCBtZW1vcnldIG9mIHRoaXMubWVtb3JpZXMpIHtcclxuICAgICAgaWYgKG1lbW9yeS5lbWJlZGRpbmcpIHtcclxuICAgICAgICB0aGlzLmluZGV4IS5hZGRQb2ludChtZW1vcnkuZW1iZWRkaW5nLCBpZCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8vIEZhY3RvcnkgZm9yIHN0b3J5LXNwZWNpZmljIHN0b3Jlc1xyXG5jb25zdCBzdG9yZXM6IE1hcDxzdHJpbmcsIFZlY3RvclN0b3JlPiA9IG5ldyBNYXAoKTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRWZWN0b3JTdG9yZShzdG9yeUlkOiBzdHJpbmcpOiBWZWN0b3JTdG9yZSB7XHJcbiAgaWYgKCFzdG9yZXMuaGFzKHN0b3J5SWQpKSB7XHJcbiAgICBzdG9yZXMuc2V0KHN0b3J5SWQsIG5ldyBWZWN0b3JTdG9yZShzdG9yeUlkKSk7XHJcbiAgfVxyXG4gIHJldHVybiBzdG9yZXMuZ2V0KHN0b3J5SWQpITtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyVmVjdG9yU3RvcmUoc3RvcnlJZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgc3RvcmVzLmRlbGV0ZShzdG9yeUlkKTtcclxufVxyXG4iXX0=
@@ -0,0 +1,17 @@
1
+ import type { GenerationContext, Chapter, ChapterSummary } from '../types/index.js';
2
+ import type { CanonStore } from '../memory/canonStore.js';
3
+ import type { VectorStore } from '../memory/vectorStore.js';
4
+ export interface GenerateChapterResult {
5
+ chapter: Chapter;
6
+ summary: ChapterSummary;
7
+ violations: string[];
8
+ memoriesExtracted: number;
9
+ }
10
+ export interface GenerateChapterOptions {
11
+ canon?: CanonStore;
12
+ vectorStore?: VectorStore;
13
+ validateCanon?: boolean;
14
+ maxContinuationAttempts?: number;
15
+ retrieveMemories?: boolean;
16
+ }
17
+ export declare function generateChapter(context: GenerationContext, options?: GenerateChapterOptions): Promise<GenerateChapterResult>;