@redaksjon/protokoll 1.0.12 → 1.0.13
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/dist/{index2.js → configDiscovery.js} +909 -3382
- package/dist/configDiscovery.js.map +1 -0
- package/dist/index.js +3 -31
- package/dist/index.js.map +1 -1
- package/dist/mcp/server-http.js +84 -45
- package/dist/mcp/server-http.js.map +1 -1
- package/dist/mcp/server.js +10 -16
- package/dist/mcp/server.js.map +1 -1
- package/docs/CHANGES_CURSOR_INTEGRATION.md +166 -0
- package/docs/CURSOR_INTEGRATION.md +234 -0
- package/docs/MCP_SERVER_MODES.md +146 -0
- package/docs/QUICK_REFERENCE_AI_ASSISTANTS.md +81 -0
- package/package.json +5 -3
- package/vite.config.ts +6 -5
- package/vitest.config.ts +7 -24
- package/BUG_FIX_CONTEXT_DIRECTORY.md +0 -147
- package/MIGRATION_2025_SUMMARY.md +0 -215
- package/TRANSCRIPT_DATE_CHANGE_IMPLEMENTATION.md +0 -192
- package/VALIDATION_TEST_COVERAGE.md +0 -165
- package/dist/feedback.js +0 -1999
- package/dist/feedback.js.map +0 -1
- package/dist/frontmatter.js +0 -517
- package/dist/frontmatter.js.map +0 -1
- package/dist/index2.js.map +0 -1
- package/dist/scripts/fix-duplicate-delimiters.js +0 -78
- package/dist/scripts/fix-duplicate-delimiters.js.map +0 -1
- package/dist/scripts/migrate-titles-to-frontmatter.js +0 -88
- package/dist/scripts/migrate-titles-to-frontmatter.js.map +0 -1
- package/dist/scripts/migrate-transcripts-2025.js +0 -276
- package/dist/scripts/migrate-transcripts-2025.js.map +0 -1
- package/dist/scripts/verify-migration-2025.js +0 -122
- package/dist/scripts/verify-migration-2025.js.map +0 -1
- package/scripts/fix-duplicate-delimiters.ts +0 -112
- package/scripts/migrate-titles-to-frontmatter.ts +0 -129
- package/scripts/migrate-transcripts-2025.ts +0 -415
- package/scripts/verify-migration-2025.ts +0 -158
package/dist/frontmatter.js
DELETED
|
@@ -1,517 +0,0 @@
|
|
|
1
|
-
import matter from 'gray-matter';
|
|
2
|
-
|
|
3
|
-
const formatMetadataMarkdown = (metadata) => {
|
|
4
|
-
const lines = [];
|
|
5
|
-
if (metadata.title) {
|
|
6
|
-
lines.push(`# ${metadata.title}`);
|
|
7
|
-
lines.push("");
|
|
8
|
-
}
|
|
9
|
-
lines.push("## Metadata");
|
|
10
|
-
lines.push("");
|
|
11
|
-
if (metadata.date) {
|
|
12
|
-
const dateStr = metadata.date.toLocaleDateString("en-US", {
|
|
13
|
-
year: "numeric",
|
|
14
|
-
month: "long",
|
|
15
|
-
day: "numeric"
|
|
16
|
-
});
|
|
17
|
-
lines.push(`**Date**: ${dateStr}`);
|
|
18
|
-
if (metadata.recordingTime) {
|
|
19
|
-
lines.push(`**Time**: ${metadata.recordingTime}`);
|
|
20
|
-
} else {
|
|
21
|
-
const timeStr = metadata.date.toLocaleTimeString("en-US", {
|
|
22
|
-
hour: "2-digit",
|
|
23
|
-
minute: "2-digit",
|
|
24
|
-
hour12: true
|
|
25
|
-
});
|
|
26
|
-
lines.push(`**Time**: ${timeStr}`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
lines.push("");
|
|
30
|
-
if (metadata.project) {
|
|
31
|
-
lines.push(`**Project**: ${metadata.project}`);
|
|
32
|
-
if (metadata.projectId) {
|
|
33
|
-
lines.push(`**Project ID**: \`${metadata.projectId}\``);
|
|
34
|
-
}
|
|
35
|
-
lines.push("");
|
|
36
|
-
}
|
|
37
|
-
if (metadata.routing) {
|
|
38
|
-
lines.push("### Routing");
|
|
39
|
-
lines.push("");
|
|
40
|
-
lines.push(`**Destination**: ${metadata.routing.destination}`);
|
|
41
|
-
lines.push(`**Confidence**: ${(metadata.routing.confidence * 100).toFixed(1)}%`);
|
|
42
|
-
lines.push("");
|
|
43
|
-
if (metadata.routing.signals.length > 0) {
|
|
44
|
-
lines.push("**Classification Signals**:");
|
|
45
|
-
for (const signal of metadata.routing.signals) {
|
|
46
|
-
const signalType = signal.type.replace(/_/g, " ");
|
|
47
|
-
const weight = (signal.weight * 100).toFixed(0);
|
|
48
|
-
lines.push(`- ${signalType}: "${signal.value}" (${weight}% weight)`);
|
|
49
|
-
}
|
|
50
|
-
lines.push("");
|
|
51
|
-
}
|
|
52
|
-
if (metadata.routing.reasoning) {
|
|
53
|
-
lines.push(`**Reasoning**: ${metadata.routing.reasoning}`);
|
|
54
|
-
lines.push("");
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if (metadata.tags && metadata.tags.length > 0) {
|
|
58
|
-
lines.push("**Tags**: " + metadata.tags.map((tag) => `\`${tag}\``).join(", "));
|
|
59
|
-
lines.push("");
|
|
60
|
-
}
|
|
61
|
-
if (metadata.duration) {
|
|
62
|
-
lines.push(`**Duration**: ${metadata.duration}`);
|
|
63
|
-
lines.push("");
|
|
64
|
-
}
|
|
65
|
-
lines.push("---");
|
|
66
|
-
lines.push("");
|
|
67
|
-
return lines.join("\n");
|
|
68
|
-
};
|
|
69
|
-
const formatEntityMetadataMarkdown = (metadata) => {
|
|
70
|
-
if (!metadata.entities) {
|
|
71
|
-
return "";
|
|
72
|
-
}
|
|
73
|
-
const lines = [];
|
|
74
|
-
lines.push("");
|
|
75
|
-
lines.push("---");
|
|
76
|
-
lines.push("");
|
|
77
|
-
lines.push("## Entity References");
|
|
78
|
-
lines.push("");
|
|
79
|
-
lines.push("<!-- Machine-readable entity metadata for indexing and querying -->");
|
|
80
|
-
lines.push("");
|
|
81
|
-
if (metadata.entities.people && metadata.entities.people.length > 0) {
|
|
82
|
-
lines.push("### People");
|
|
83
|
-
lines.push("");
|
|
84
|
-
for (const person of metadata.entities.people) {
|
|
85
|
-
lines.push(`- \`${person.id}\`: ${person.name}`);
|
|
86
|
-
}
|
|
87
|
-
lines.push("");
|
|
88
|
-
}
|
|
89
|
-
if (metadata.entities.projects && metadata.entities.projects.length > 0) {
|
|
90
|
-
lines.push("### Projects");
|
|
91
|
-
lines.push("");
|
|
92
|
-
for (const project of metadata.entities.projects) {
|
|
93
|
-
lines.push(`- \`${project.id}\`: ${project.name}`);
|
|
94
|
-
}
|
|
95
|
-
lines.push("");
|
|
96
|
-
}
|
|
97
|
-
if (metadata.entities.terms && metadata.entities.terms.length > 0) {
|
|
98
|
-
lines.push("### Terms");
|
|
99
|
-
lines.push("");
|
|
100
|
-
for (const term of metadata.entities.terms) {
|
|
101
|
-
lines.push(`- \`${term.id}\`: ${term.name}`);
|
|
102
|
-
}
|
|
103
|
-
lines.push("");
|
|
104
|
-
}
|
|
105
|
-
if (metadata.entities.companies && metadata.entities.companies.length > 0) {
|
|
106
|
-
lines.push("### Companies");
|
|
107
|
-
lines.push("");
|
|
108
|
-
for (const company of metadata.entities.companies) {
|
|
109
|
-
lines.push(`- \`${company.id}\`: ${company.name}`);
|
|
110
|
-
}
|
|
111
|
-
lines.push("");
|
|
112
|
-
}
|
|
113
|
-
return lines.join("\n");
|
|
114
|
-
};
|
|
115
|
-
const parseEntityMetadata = (content) => {
|
|
116
|
-
const headerIndex = content.indexOf("## Entity References");
|
|
117
|
-
if (headerIndex === -1) {
|
|
118
|
-
return void 0;
|
|
119
|
-
}
|
|
120
|
-
let contentStart = headerIndex + "## Entity References".length;
|
|
121
|
-
while (contentStart < content.length && (content[contentStart] === "\n" || content[contentStart] === "\r" || content[contentStart] === " " || content[contentStart] === " ")) {
|
|
122
|
-
contentStart++;
|
|
123
|
-
}
|
|
124
|
-
const remainingContent = content.substring(contentStart);
|
|
125
|
-
const nextHeaderMatch = remainingContent.match(/\n## /);
|
|
126
|
-
const sectionContent = nextHeaderMatch ? remainingContent.substring(0, nextHeaderMatch.index) : remainingContent;
|
|
127
|
-
const entities = {
|
|
128
|
-
people: [],
|
|
129
|
-
projects: [],
|
|
130
|
-
terms: [],
|
|
131
|
-
companies: []
|
|
132
|
-
};
|
|
133
|
-
const parseEntities = (type) => {
|
|
134
|
-
const typeMap = {
|
|
135
|
-
"People": "person",
|
|
136
|
-
"Projects": "project",
|
|
137
|
-
"Terms": "term",
|
|
138
|
-
"Companies": "company"
|
|
139
|
-
};
|
|
140
|
-
const entityType = typeMap[type];
|
|
141
|
-
const sectionHeader = `### ${type}`;
|
|
142
|
-
const sectionStart = sectionContent.indexOf(sectionHeader);
|
|
143
|
-
if (sectionStart === -1) return [];
|
|
144
|
-
const headerEnd = sectionStart + sectionHeader.length;
|
|
145
|
-
let sectionTextStart = headerEnd;
|
|
146
|
-
while (sectionTextStart < sectionContent.length && (sectionContent[sectionTextStart] === "\n" || sectionContent[sectionTextStart] === "\r" || sectionContent[sectionTextStart] === " ")) {
|
|
147
|
-
sectionTextStart++;
|
|
148
|
-
}
|
|
149
|
-
const afterSection = sectionContent.substring(sectionTextStart);
|
|
150
|
-
const nextSection = afterSection.search(/\n###/);
|
|
151
|
-
const sectionText = nextSection === -1 ? afterSection : afterSection.substring(0, nextSection);
|
|
152
|
-
const items = [];
|
|
153
|
-
const lines = sectionText.split("\n");
|
|
154
|
-
for (const line of lines) {
|
|
155
|
-
const trimmed = line.trim();
|
|
156
|
-
const match = trimmed.match(/^- `([^`]+)`:\s*(.+)$/);
|
|
157
|
-
if (match) {
|
|
158
|
-
items.push({
|
|
159
|
-
id: match[1],
|
|
160
|
-
name: match[2].trim(),
|
|
161
|
-
type: entityType
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return items;
|
|
166
|
-
};
|
|
167
|
-
entities.people = parseEntities("People");
|
|
168
|
-
entities.projects = parseEntities("Projects");
|
|
169
|
-
entities.terms = parseEntities("Terms");
|
|
170
|
-
entities.companies = parseEntities("Companies");
|
|
171
|
-
const hasEntities = entities.people.length > 0 || entities.projects.length > 0 || entities.terms.length > 0 || entities.companies.length > 0;
|
|
172
|
-
return hasEntities ? entities : void 0;
|
|
173
|
-
};
|
|
174
|
-
const createRoutingMetadata = (decision) => {
|
|
175
|
-
return {
|
|
176
|
-
destination: decision.destination.path,
|
|
177
|
-
confidence: decision.confidence,
|
|
178
|
-
signals: decision.signals,
|
|
179
|
-
reasoning: decision.reasoning
|
|
180
|
-
};
|
|
181
|
-
};
|
|
182
|
-
const formatDuration = (seconds) => {
|
|
183
|
-
const minutes = Math.floor(seconds / 60);
|
|
184
|
-
const secs = Math.round(seconds % 60);
|
|
185
|
-
if (minutes === 0) {
|
|
186
|
-
return `${secs}s`;
|
|
187
|
-
}
|
|
188
|
-
if (secs === 0) {
|
|
189
|
-
return `${minutes}m`;
|
|
190
|
-
}
|
|
191
|
-
return `${minutes}m ${secs}s`;
|
|
192
|
-
};
|
|
193
|
-
const formatTime = (date) => {
|
|
194
|
-
return date.toLocaleTimeString("en-US", {
|
|
195
|
-
hour: "2-digit",
|
|
196
|
-
minute: "2-digit",
|
|
197
|
-
hour12: true
|
|
198
|
-
});
|
|
199
|
-
};
|
|
200
|
-
const extractTopicFromSignals = (signals) => {
|
|
201
|
-
const topicSignal = signals.find((s) => s.type === "topic" || s.type === "context_type");
|
|
202
|
-
return topicSignal?.value;
|
|
203
|
-
};
|
|
204
|
-
const extractTagsFromSignals = (signals) => {
|
|
205
|
-
const tags = signals.filter((s) => s.type !== "context_type").map((s) => s.value).filter((v) => typeof v === "string");
|
|
206
|
-
return Array.from(new Set(tags));
|
|
207
|
-
};
|
|
208
|
-
const VALID_STATUSES = [
|
|
209
|
-
"initial",
|
|
210
|
-
"enhanced",
|
|
211
|
-
"reviewed",
|
|
212
|
-
"in_progress",
|
|
213
|
-
"closed",
|
|
214
|
-
"archived"
|
|
215
|
-
];
|
|
216
|
-
const isValidStatus = (status) => {
|
|
217
|
-
return VALID_STATUSES.includes(status);
|
|
218
|
-
};
|
|
219
|
-
const generateTaskId = () => {
|
|
220
|
-
const timestamp = Date.now();
|
|
221
|
-
const random = Math.random().toString(36).substring(2, 8);
|
|
222
|
-
return `task-${timestamp}-${random}`;
|
|
223
|
-
};
|
|
224
|
-
const createTask = (description) => {
|
|
225
|
-
return {
|
|
226
|
-
id: generateTaskId(),
|
|
227
|
-
description,
|
|
228
|
-
status: "open",
|
|
229
|
-
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
230
|
-
};
|
|
231
|
-
};
|
|
232
|
-
const updateStatus = (metadata, newStatus) => {
|
|
233
|
-
const oldStatus = metadata.status;
|
|
234
|
-
if (oldStatus === newStatus) {
|
|
235
|
-
return metadata;
|
|
236
|
-
}
|
|
237
|
-
const transition = {
|
|
238
|
-
from: oldStatus || "reviewed",
|
|
239
|
-
to: newStatus,
|
|
240
|
-
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
241
|
-
};
|
|
242
|
-
return {
|
|
243
|
-
...metadata,
|
|
244
|
-
status: newStatus,
|
|
245
|
-
history: [...metadata.history || [], transition]
|
|
246
|
-
};
|
|
247
|
-
};
|
|
248
|
-
const applyLifecycleDefaults = (metadata) => {
|
|
249
|
-
return {
|
|
250
|
-
...metadata,
|
|
251
|
-
status: metadata.status ?? "reviewed",
|
|
252
|
-
history: metadata.history ?? [],
|
|
253
|
-
tasks: metadata.tasks ?? []
|
|
254
|
-
};
|
|
255
|
-
};
|
|
256
|
-
const completeTask = (metadata, taskId) => {
|
|
257
|
-
const tasks = metadata.tasks || [];
|
|
258
|
-
const taskIndex = tasks.findIndex((t) => t.id === taskId);
|
|
259
|
-
if (taskIndex === -1) {
|
|
260
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
261
|
-
}
|
|
262
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
263
|
-
const updatedTasks = [...tasks];
|
|
264
|
-
updatedTasks[taskIndex] = {
|
|
265
|
-
...updatedTasks[taskIndex],
|
|
266
|
-
status: "done",
|
|
267
|
-
changed: now,
|
|
268
|
-
completed: now
|
|
269
|
-
};
|
|
270
|
-
return {
|
|
271
|
-
...metadata,
|
|
272
|
-
tasks: updatedTasks
|
|
273
|
-
};
|
|
274
|
-
};
|
|
275
|
-
const deleteTask = (metadata, taskId) => {
|
|
276
|
-
const tasks = metadata.tasks || [];
|
|
277
|
-
const taskIndex = tasks.findIndex((t) => t.id === taskId);
|
|
278
|
-
if (taskIndex === -1) {
|
|
279
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
280
|
-
}
|
|
281
|
-
return {
|
|
282
|
-
...metadata,
|
|
283
|
-
tasks: tasks.filter((t) => t.id !== taskId)
|
|
284
|
-
};
|
|
285
|
-
};
|
|
286
|
-
const addTask = (metadata, description) => {
|
|
287
|
-
const task = createTask(description);
|
|
288
|
-
return {
|
|
289
|
-
metadata: {
|
|
290
|
-
...metadata,
|
|
291
|
-
tasks: [...metadata.tasks || [], task]
|
|
292
|
-
},
|
|
293
|
-
task
|
|
294
|
-
};
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
function parseOldMetadataSection(content) {
|
|
298
|
-
const metadata = {};
|
|
299
|
-
const metadataMatch = content.match(/## Metadata\s*\n([\s\S]*?)(?:\n---|\n##|$)/);
|
|
300
|
-
if (!metadataMatch) {
|
|
301
|
-
return metadata;
|
|
302
|
-
}
|
|
303
|
-
const metadataSection = metadataMatch[1];
|
|
304
|
-
const projectMatch = metadataSection.match(/\*\*Project\*\*:\s*(.+)/);
|
|
305
|
-
if (projectMatch) {
|
|
306
|
-
metadata.project = projectMatch[1].trim();
|
|
307
|
-
}
|
|
308
|
-
const projectIdMatch = metadataSection.match(/\*\*Project ID\*\*:\s*`([^`]+)`/);
|
|
309
|
-
if (projectIdMatch) {
|
|
310
|
-
metadata.projectId = projectIdMatch[1].trim();
|
|
311
|
-
}
|
|
312
|
-
const tagsMatch = metadataSection.match(/\*\*Tags\*\*:\s*(.+)/);
|
|
313
|
-
if (tagsMatch) {
|
|
314
|
-
const tagsStr = tagsMatch[1];
|
|
315
|
-
const tags = tagsStr.match(/`([^`]+)`/g);
|
|
316
|
-
if (tags) {
|
|
317
|
-
metadata.tags = tags.map((t) => t.replace(/`/g, "").trim());
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
const dateMatch = metadataSection.match(/\*\*Date\*\*:\s*(.+)/);
|
|
321
|
-
if (dateMatch) {
|
|
322
|
-
const dateStr = dateMatch[1].trim();
|
|
323
|
-
const parsed = new Date(dateStr);
|
|
324
|
-
if (!isNaN(parsed.getTime())) {
|
|
325
|
-
metadata.date = parsed;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
const timeMatch = metadataSection.match(/\*\*Time\*\*:\s*(.+)/);
|
|
329
|
-
if (timeMatch) {
|
|
330
|
-
metadata.recordingTime = timeMatch[1].trim();
|
|
331
|
-
}
|
|
332
|
-
const routingMatch = metadataSection.match(/### Routing\s+([\s\S]*?)(?:\n###|\n##|$)/);
|
|
333
|
-
if (routingMatch) {
|
|
334
|
-
const routingSection = routingMatch[1];
|
|
335
|
-
const destMatch = routingSection.match(/\*\*Destination\*\*:\s*(.+)/);
|
|
336
|
-
const confMatch = routingSection.match(/\*\*Confidence\*\*:\s*([\d.]+)%/);
|
|
337
|
-
const reasoningMatch = routingSection.match(/\*\*Reasoning\*\*:\s*(.+)/);
|
|
338
|
-
if (destMatch || confMatch) {
|
|
339
|
-
metadata.routing = {
|
|
340
|
-
destination: destMatch ? destMatch[1].trim() : "",
|
|
341
|
-
confidence: confMatch ? parseFloat(confMatch[1]) / 100 : 0,
|
|
342
|
-
signals: [],
|
|
343
|
-
reasoning: reasoningMatch ? reasoningMatch[1].trim() : ""
|
|
344
|
-
};
|
|
345
|
-
const signalsMatch = routingSection.match(/\*\*Classification Signals\*\*:\s+([\s\S]*?)(?:\n\*\*|$)/);
|
|
346
|
-
if (signalsMatch) {
|
|
347
|
-
const signalsText = signalsMatch[1];
|
|
348
|
-
const signalLines = signalsText.split("\n").filter((l) => l.trim().startsWith("-"));
|
|
349
|
-
for (const line of signalLines) {
|
|
350
|
-
const signalMatch = line.match(/- ([^:]+):\s*"([^"]+)"\s*\((\d+)% weight\)/);
|
|
351
|
-
if (signalMatch) {
|
|
352
|
-
const typeStr = signalMatch[1].trim().replace(/ /g, "_");
|
|
353
|
-
const validTypes = ["explicit_phrase", "associated_person", "associated_company", "topic", "context_type"];
|
|
354
|
-
const type = validTypes.includes(typeStr) ? typeStr : "topic";
|
|
355
|
-
metadata.routing.signals.push({
|
|
356
|
-
type,
|
|
357
|
-
value: signalMatch[2].trim(),
|
|
358
|
-
weight: parseFloat(signalMatch[3]) / 100
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
return metadata;
|
|
366
|
-
}
|
|
367
|
-
function parseTranscriptContent(content) {
|
|
368
|
-
const { data: frontmatter, content: rawBody } = matter(content);
|
|
369
|
-
const needsMigration = isOldFormat(content, frontmatter);
|
|
370
|
-
let metadata = {
|
|
371
|
-
title: frontmatter.title,
|
|
372
|
-
date: frontmatter.date ? new Date(frontmatter.date) : void 0,
|
|
373
|
-
recordingTime: frontmatter.recordingTime,
|
|
374
|
-
duration: frontmatter.duration,
|
|
375
|
-
project: frontmatter.project,
|
|
376
|
-
projectId: frontmatter.projectId,
|
|
377
|
-
tags: frontmatter.tags,
|
|
378
|
-
confidence: frontmatter.confidence,
|
|
379
|
-
routing: frontmatter.routing,
|
|
380
|
-
status: frontmatter.status,
|
|
381
|
-
history: frontmatter.history,
|
|
382
|
-
tasks: frontmatter.tasks,
|
|
383
|
-
entities: frontmatter.entities
|
|
384
|
-
};
|
|
385
|
-
if (needsMigration) {
|
|
386
|
-
const oldMetadata = parseOldMetadataSection(content);
|
|
387
|
-
metadata = {
|
|
388
|
-
...oldMetadata,
|
|
389
|
-
...metadata.title !== void 0 && { title: metadata.title },
|
|
390
|
-
...metadata.date !== void 0 && { date: metadata.date },
|
|
391
|
-
...metadata.recordingTime !== void 0 && { recordingTime: metadata.recordingTime },
|
|
392
|
-
...metadata.duration !== void 0 && { duration: metadata.duration },
|
|
393
|
-
...metadata.project !== void 0 && { project: metadata.project },
|
|
394
|
-
...metadata.projectId !== void 0 && { projectId: metadata.projectId },
|
|
395
|
-
...metadata.tags !== void 0 && { tags: metadata.tags },
|
|
396
|
-
...metadata.confidence !== void 0 && { confidence: metadata.confidence },
|
|
397
|
-
...metadata.routing !== void 0 && { routing: metadata.routing },
|
|
398
|
-
...metadata.status !== void 0 && { status: metadata.status },
|
|
399
|
-
...metadata.history !== void 0 && { history: metadata.history },
|
|
400
|
-
...metadata.tasks !== void 0 && { tasks: metadata.tasks },
|
|
401
|
-
...metadata.entities !== void 0 && { entities: metadata.entities }
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
if (!metadata.entities) {
|
|
405
|
-
const extractedEntities = parseEntityMetadata(rawBody);
|
|
406
|
-
if (extractedEntities) {
|
|
407
|
-
metadata.entities = extractedEntities;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
let cleanBody = rawBody;
|
|
411
|
-
const titleMatch = rawBody.match(/^#\s+(.+)$/m);
|
|
412
|
-
if (!metadata.title && titleMatch) {
|
|
413
|
-
metadata.title = titleMatch[1].trim();
|
|
414
|
-
cleanBody = rawBody.replace(/^#\s+.+$/m, "").trim();
|
|
415
|
-
} else if (metadata.title && titleMatch) {
|
|
416
|
-
cleanBody = rawBody.replace(/^#\s+.+$/m, "").trim();
|
|
417
|
-
}
|
|
418
|
-
metadata = applyLifecycleDefaults(metadata);
|
|
419
|
-
cleanBody = stripLegacySections(cleanBody);
|
|
420
|
-
return {
|
|
421
|
-
metadata,
|
|
422
|
-
body: cleanBody,
|
|
423
|
-
needsMigration
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
function isOldFormat(content, frontmatter) {
|
|
427
|
-
if (!content.startsWith("---")) {
|
|
428
|
-
return true;
|
|
429
|
-
}
|
|
430
|
-
if (!frontmatter.entities && content.includes("## Entity References")) {
|
|
431
|
-
return true;
|
|
432
|
-
}
|
|
433
|
-
if (content.includes("\n## Metadata\n")) {
|
|
434
|
-
return true;
|
|
435
|
-
}
|
|
436
|
-
return false;
|
|
437
|
-
}
|
|
438
|
-
function stripLegacySections(body) {
|
|
439
|
-
let clean = body;
|
|
440
|
-
clean = clean.replace(/^(\s*)## Metadata[\s\S]*?\n---\n/, "");
|
|
441
|
-
const entityRefPattern = /\n---\s*\n+## Entity References[\s\S]*$/;
|
|
442
|
-
if (entityRefPattern.test(clean)) {
|
|
443
|
-
clean = clean.replace(entityRefPattern, "");
|
|
444
|
-
} else {
|
|
445
|
-
const endPattern = /\n## Entity References\s*\n[\s\S]*$/;
|
|
446
|
-
if (endPattern.test(clean)) {
|
|
447
|
-
const match = clean.match(endPattern);
|
|
448
|
-
if (match) {
|
|
449
|
-
const entitySection = match[0];
|
|
450
|
-
const otherHeaders = entitySection.match(/\n## (?!Entity References)/g);
|
|
451
|
-
if (!otherHeaders || otherHeaders.length === 0) {
|
|
452
|
-
clean = clean.replace(endPattern, "");
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
return clean.trim();
|
|
458
|
-
}
|
|
459
|
-
function hasEntities(entities) {
|
|
460
|
-
if (!entities) return false;
|
|
461
|
-
return !!(entities.people?.length || entities.projects?.length || entities.terms?.length || entities.companies?.length);
|
|
462
|
-
}
|
|
463
|
-
function buildFrontmatter(metadata) {
|
|
464
|
-
const fm = {};
|
|
465
|
-
if (metadata.title) fm.title = metadata.title;
|
|
466
|
-
if (metadata.date) fm.date = metadata.date.toISOString();
|
|
467
|
-
if (metadata.recordingTime) fm.recordingTime = metadata.recordingTime;
|
|
468
|
-
if (metadata.duration) fm.duration = metadata.duration;
|
|
469
|
-
if (metadata.project) fm.project = metadata.project;
|
|
470
|
-
if (metadata.projectId) fm.projectId = metadata.projectId;
|
|
471
|
-
if (metadata.tags && metadata.tags.length > 0) fm.tags = metadata.tags;
|
|
472
|
-
if (metadata.confidence !== void 0) fm.confidence = metadata.confidence;
|
|
473
|
-
if (metadata.routing) fm.routing = metadata.routing;
|
|
474
|
-
if (metadata.status) fm.status = metadata.status;
|
|
475
|
-
if (metadata.history && metadata.history.length > 0) fm.history = metadata.history;
|
|
476
|
-
if (metadata.tasks && metadata.tasks.length > 0) fm.tasks = metadata.tasks;
|
|
477
|
-
if (hasEntities(metadata.entities)) {
|
|
478
|
-
fm.entities = metadata.entities;
|
|
479
|
-
}
|
|
480
|
-
return fm;
|
|
481
|
-
}
|
|
482
|
-
function stringifyTranscript(metadata, body) {
|
|
483
|
-
const frontmatter = buildFrontmatter(metadata);
|
|
484
|
-
let cleanBody = stripLegacySections(body);
|
|
485
|
-
cleanBody = cleanBody.replace(/^---\s*\n/, "").trim();
|
|
486
|
-
if (metadata.title) {
|
|
487
|
-
const h1Pattern = new RegExp(`^#\\s+${escapeRegex(metadata.title)}\\s*$`, "m");
|
|
488
|
-
cleanBody = cleanBody.replace(h1Pattern, "").trim();
|
|
489
|
-
cleanBody = cleanBody.replace(/^#\s+.+$/m, "").trim();
|
|
490
|
-
}
|
|
491
|
-
return matter.stringify(cleanBody + "\n", frontmatter);
|
|
492
|
-
}
|
|
493
|
-
function escapeRegex(str) {
|
|
494
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
495
|
-
}
|
|
496
|
-
function updateTranscript(originalContent, updates) {
|
|
497
|
-
const parsed = parseTranscriptContent(originalContent);
|
|
498
|
-
const newMetadata = {
|
|
499
|
-
...parsed.metadata,
|
|
500
|
-
...updates.metadata
|
|
501
|
-
};
|
|
502
|
-
const newBody = updates.body ?? parsed.body;
|
|
503
|
-
return stringifyTranscript(newMetadata, newBody);
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
const frontmatter = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
|
507
|
-
__proto__: null,
|
|
508
|
-
buildFrontmatter,
|
|
509
|
-
hasEntities,
|
|
510
|
-
parseTranscriptContent,
|
|
511
|
-
stringifyTranscript,
|
|
512
|
-
stripLegacySections,
|
|
513
|
-
updateTranscript
|
|
514
|
-
}, Symbol.toStringTag, { value: 'Module' }));
|
|
515
|
-
|
|
516
|
-
export { VALID_STATUSES as V, addTask as a, applyLifecycleDefaults as b, buildFrontmatter as c, completeTask as d, createRoutingMetadata as e, createTask as f, deleteTask as g, extractTagsFromSignals as h, extractTopicFromSignals as i, formatDuration as j, formatEntityMetadataMarkdown as k, formatMetadataMarkdown as l, formatTime as m, generateTaskId as n, hasEntities as o, isValidStatus as p, parseEntityMetadata as q, parseTranscriptContent as r, stringifyTranscript as s, stripLegacySections as t, updateStatus as u, updateTranscript as v, frontmatter as w };
|
|
517
|
-
//# sourceMappingURL=frontmatter.js.map
|
package/dist/frontmatter.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"frontmatter.js","sources":["../src/util/metadata.ts","../src/util/frontmatter.ts"],"sourcesContent":["import * as Routing from '@/routing';\n\n// ============================================================================\n// Lifecycle Types\n// ============================================================================\n\n/**\n * Transcript lifecycle status\n * - initial: Whisper transcription complete\n * - enhanced: Context-aware enhancement complete\n * - reviewed: User has reviewed the transcript\n * - in_progress: Has outstanding tasks to complete\n * - closed: All work complete, no pending tasks\n * - archived: Archived for long-term storage\n */\nexport type TranscriptStatus = 'initial' | 'enhanced' | 'reviewed' | 'in_progress' | 'closed' | 'archived';\n\n/**\n * Record of a status transition with timestamp\n */\nexport interface StatusTransition {\n from: TranscriptStatus;\n to: TranscriptStatus;\n at: string; // ISO 8601 timestamp\n}\n\n/**\n * A follow-up task associated with a transcript\n */\nexport interface Task {\n id: string; // generated unique ID (e.g., task-1234567890-abc123)\n description: string;\n status: 'open' | 'done';\n created: string; // ISO 8601 timestamp\n changed?: string; // ISO 8601 timestamp - when last modified\n completed?: string; // ISO 8601 timestamp - when marked done\n}\n\n// ============================================================================\n// Entity Types\n// ============================================================================\n\nexport interface EntityReference {\n id: string;\n name: string;\n type: 'person' | 'project' | 'term' | 'company';\n}\n\nexport interface TranscriptMetadata {\n // Core fields\n title?: string;\n project?: string;\n projectId?: string;\n routing?: RoutingMetadata;\n tags?: string[];\n date?: Date;\n recordingTime?: string;\n confidence?: number;\n duration?: string;\n \n // Lifecycle fields\n status?: TranscriptStatus;\n history?: StatusTransition[];\n tasks?: Task[];\n \n // Entity references - entities mentioned/used in this transcript\n entities?: {\n people?: EntityReference[];\n projects?: EntityReference[];\n terms?: EntityReference[];\n companies?: EntityReference[];\n };\n}\n\nexport interface RoutingMetadata {\n destination: string;\n confidence: number;\n signals: Routing.ClassificationSignal[];\n reasoning: string;\n}\n\n/**\n * Format metadata as Markdown heading section\n */\nexport const formatMetadataMarkdown = (metadata: TranscriptMetadata): string => {\n const lines: string[] = [];\n \n // Title section\n if (metadata.title) {\n lines.push(`# ${metadata.title}`);\n lines.push('');\n }\n \n // Metadata frontmatter as readable markdown\n lines.push('## Metadata');\n lines.push('');\n \n // Date and Time\n if (metadata.date) {\n const dateStr = metadata.date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n lines.push(`**Date**: ${dateStr}`);\n \n if (metadata.recordingTime) {\n lines.push(`**Time**: ${metadata.recordingTime}`);\n } else {\n const timeStr = metadata.date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n lines.push(`**Time**: ${timeStr}`);\n }\n }\n \n lines.push('');\n \n // Project\n if (metadata.project) {\n lines.push(`**Project**: ${metadata.project}`);\n if (metadata.projectId) {\n lines.push(`**Project ID**: \\`${metadata.projectId}\\``);\n }\n lines.push('');\n }\n \n // Routing Information\n if (metadata.routing) {\n lines.push('### Routing');\n lines.push('');\n lines.push(`**Destination**: ${metadata.routing.destination}`);\n lines.push(`**Confidence**: ${(metadata.routing.confidence * 100).toFixed(1)}%`);\n lines.push('');\n \n if (metadata.routing.signals.length > 0) {\n lines.push('**Classification Signals**:');\n for (const signal of metadata.routing.signals) {\n const signalType = signal.type.replace(/_/g, ' ');\n const weight = (signal.weight * 100).toFixed(0);\n lines.push(`- ${signalType}: \"${signal.value}\" (${weight}% weight)`);\n }\n lines.push('');\n }\n \n if (metadata.routing.reasoning) {\n lines.push(`**Reasoning**: ${metadata.routing.reasoning}`);\n lines.push('');\n }\n }\n \n // Tags\n if (metadata.tags && metadata.tags.length > 0) {\n lines.push('**Tags**: ' + metadata.tags.map(tag => `\\`${tag}\\``).join(', '));\n lines.push('');\n }\n \n // Duration\n if (metadata.duration) {\n lines.push(`**Duration**: ${metadata.duration}`);\n lines.push('');\n }\n \n // Separator\n lines.push('---');\n lines.push('');\n \n return lines.join('\\n');\n};\n\n/**\n * Format entity metadata as Markdown footer section\n * This goes at the END of the transcript for machine readability\n */\nexport const formatEntityMetadataMarkdown = (metadata: TranscriptMetadata): string => {\n if (!metadata.entities) {\n return '';\n }\n \n const lines: string[] = [];\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('## Entity References');\n lines.push('');\n lines.push('<!-- Machine-readable entity metadata for indexing and querying -->');\n lines.push('');\n \n // People\n if (metadata.entities.people && metadata.entities.people.length > 0) {\n lines.push('### People');\n lines.push('');\n for (const person of metadata.entities.people) {\n lines.push(`- \\`${person.id}\\`: ${person.name}`);\n }\n lines.push('');\n }\n \n // Projects\n if (metadata.entities.projects && metadata.entities.projects.length > 0) {\n lines.push('### Projects');\n lines.push('');\n for (const project of metadata.entities.projects) {\n lines.push(`- \\`${project.id}\\`: ${project.name}`);\n }\n lines.push('');\n }\n \n // Terms\n if (metadata.entities.terms && metadata.entities.terms.length > 0) {\n lines.push('### Terms');\n lines.push('');\n for (const term of metadata.entities.terms) {\n lines.push(`- \\`${term.id}\\`: ${term.name}`);\n }\n lines.push('');\n }\n \n // Companies\n if (metadata.entities.companies && metadata.entities.companies.length > 0) {\n lines.push('### Companies');\n lines.push('');\n for (const company of metadata.entities.companies) {\n lines.push(`- \\`${company.id}\\`: ${company.name}`);\n }\n lines.push('');\n }\n \n return lines.join('\\n');\n};\n\n/**\n * Parse entity metadata from a transcript\n * Reads the Entity References section if present\n */\nexport const parseEntityMetadata = (content: string): TranscriptMetadata['entities'] | undefined => {\n // Find the Entity References section\n // Look for \"## Entity References\" and capture everything after it until the next \"##\" header or end of content\n const headerIndex = content.indexOf('## Entity References');\n if (headerIndex === -1) {\n return undefined;\n }\n \n // Find the start of the content (after the header and any whitespace/newlines)\n let contentStart = headerIndex + '## Entity References'.length;\n // Skip whitespace and newlines\n while (contentStart < content.length && (content[contentStart] === '\\n' || content[contentStart] === '\\r' || content[contentStart] === ' ' || content[contentStart] === '\\t')) {\n contentStart++;\n }\n \n // Find the end - look for next \"##\" at start of line or end of content\n const remainingContent = content.substring(contentStart);\n const nextHeaderMatch = remainingContent.match(/\\n## /);\n const sectionContent = nextHeaderMatch \n ? remainingContent.substring(0, nextHeaderMatch.index)\n : remainingContent;\n const entities: NonNullable<TranscriptMetadata['entities']> = {\n people: [],\n projects: [],\n terms: [],\n companies: [],\n };\n \n // Parse each entity type\n const parseEntities = (type: 'People' | 'Projects' | 'Terms' | 'Companies'): EntityReference[] => {\n // Map plural type names to singular entity types\n const typeMap: Record<string, 'person' | 'project' | 'term' | 'company'> = {\n 'People': 'person',\n 'Projects': 'project',\n 'Terms': 'term',\n 'Companies': 'company',\n };\n \n const entityType = typeMap[type];\n \n // Find the section for this type\n const sectionHeader = `### ${type}`;\n const sectionStart = sectionContent.indexOf(sectionHeader);\n if (sectionStart === -1) return [];\n \n // Find the end (next ### or end of content)\n // Skip past the header line (including newline)\n const headerEnd = sectionStart + sectionHeader.length;\n let sectionTextStart = headerEnd;\n // Skip whitespace and newlines after the header\n while (sectionTextStart < sectionContent.length && \n (sectionContent[sectionTextStart] === '\\n' || sectionContent[sectionTextStart] === '\\r' || sectionContent[sectionTextStart] === ' ')) {\n sectionTextStart++;\n }\n \n const afterSection = sectionContent.substring(sectionTextStart);\n const nextSection = afterSection.search(/\\n###/);\n const sectionText = nextSection === -1 ? afterSection : afterSection.substring(0, nextSection);\n \n // Extract items - match format: \"- `id`: name\"\n // Match bullet point with backticked ID and name\n const items: EntityReference[] = [];\n // Use multiline regex to match across lines, look for \"- `id`: name\" pattern\n const lines = sectionText.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n // Match: \"- `id`: name\" or \"- `id`:name\" (with or without space after colon)\n const match = trimmed.match(/^- `([^`]+)`:\\s*(.+)$/);\n if (match) {\n items.push({\n id: match[1],\n name: match[2].trim(),\n type: entityType,\n });\n }\n }\n \n return items;\n };\n \n entities.people = parseEntities('People');\n entities.projects = parseEntities('Projects');\n entities.terms = parseEntities('Terms');\n entities.companies = parseEntities('Companies');\n \n // Only return if we found any entities\n const hasEntities = \n entities.people.length > 0 ||\n entities.projects.length > 0 ||\n entities.terms.length > 0 ||\n entities.companies.length > 0;\n \n return hasEntities ? entities : undefined;\n};\n\n/**\n * Extract routing metadata from a RouteDecision\n */\nexport const createRoutingMetadata = (decision: Routing.RouteDecision): RoutingMetadata => {\n return {\n destination: decision.destination.path,\n confidence: decision.confidence,\n signals: decision.signals,\n reasoning: decision.reasoning,\n };\n};\n\n/**\n * Format duration in seconds to readable format (e.g., \"2m 30s\")\n */\nexport const formatDuration = (seconds: number): string => {\n const minutes = Math.floor(seconds / 60);\n const secs = Math.round(seconds % 60);\n \n if (minutes === 0) {\n return `${secs}s`;\n }\n \n if (secs === 0) {\n return `${minutes}m`;\n }\n \n return `${minutes}m ${secs}s`;\n};\n\n/**\n * Format time as HH:MM AM/PM\n */\nexport const formatTime = (date: Date): string => {\n return date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n};\n\n/**\n * Extract topic from routing signals\n */\nexport const extractTopicFromSignals = (signals: Routing.ClassificationSignal[]): string | undefined => {\n const topicSignal = signals.find(s => s.type === 'topic' || s.type === 'context_type');\n return topicSignal?.value;\n};\n\n/**\n * Extract all tags from routing signals\n * Tags are deduplicated to avoid duplicates from multiple signal sources\n */\nexport const extractTagsFromSignals = (signals: Routing.ClassificationSignal[]): string[] => {\n const tags = signals\n .filter(s => s.type !== 'context_type') // Skip generic context type\n .map(s => s.value)\n .filter((v): v is string => typeof v === 'string');\n \n // Deduplicate tags using Set\n return Array.from(new Set(tags));\n};\n\n// ============================================================================\n// Lifecycle Utilities\n// ============================================================================\n\n/**\n * Valid transcript statuses for validation\n */\nexport const VALID_STATUSES: TranscriptStatus[] = [\n 'initial', 'enhanced', 'reviewed', 'in_progress', 'closed', 'archived'\n];\n\n/**\n * Check if a string is a valid TranscriptStatus\n */\nexport const isValidStatus = (status: string): status is TranscriptStatus => {\n return VALID_STATUSES.includes(status as TranscriptStatus);\n};\n\n/**\n * Generate a unique task ID\n */\nexport const generateTaskId = (): string => {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `task-${timestamp}-${random}`;\n};\n\n/**\n * Create a new task\n */\nexport const createTask = (description: string): Task => {\n return {\n id: generateTaskId(),\n description,\n status: 'open',\n created: new Date().toISOString(),\n };\n};\n\n/**\n * Update transcript status and record the transition in history\n * Returns unchanged metadata if status is the same (no duplicate history)\n */\nexport const updateStatus = (\n metadata: TranscriptMetadata,\n newStatus: TranscriptStatus\n): TranscriptMetadata => {\n const oldStatus = metadata.status;\n \n // Don't add duplicate history if status unchanged\n if (oldStatus === newStatus) {\n return metadata;\n }\n \n const transition: StatusTransition = {\n from: oldStatus || 'reviewed',\n to: newStatus,\n at: new Date().toISOString(),\n };\n \n return {\n ...metadata,\n status: newStatus,\n history: [...(metadata.history || []), transition],\n };\n};\n\n/**\n * Apply default lifecycle fields to metadata\n * Used during lazy migration of old-format transcripts\n */\nexport const applyLifecycleDefaults = (metadata: TranscriptMetadata): TranscriptMetadata => {\n return {\n ...metadata,\n status: metadata.status ?? 'reviewed',\n history: metadata.history ?? [],\n tasks: metadata.tasks ?? [],\n };\n};\n\n/**\n * Complete a task by ID\n */\nexport const completeTask = (metadata: TranscriptMetadata, taskId: string): TranscriptMetadata => {\n const tasks = metadata.tasks || [];\n const taskIndex = tasks.findIndex(t => t.id === taskId);\n \n if (taskIndex === -1) {\n throw new Error(`Task not found: ${taskId}`);\n }\n \n const now = new Date().toISOString();\n const updatedTasks = [...tasks];\n updatedTasks[taskIndex] = {\n ...updatedTasks[taskIndex],\n status: 'done',\n changed: now,\n completed: now,\n };\n \n return {\n ...metadata,\n tasks: updatedTasks,\n };\n};\n\n/**\n * Delete a task by ID\n */\nexport const deleteTask = (metadata: TranscriptMetadata, taskId: string): TranscriptMetadata => {\n const tasks = metadata.tasks || [];\n const taskIndex = tasks.findIndex(t => t.id === taskId);\n \n if (taskIndex === -1) {\n throw new Error(`Task not found: ${taskId}`);\n }\n \n return {\n ...metadata,\n tasks: tasks.filter(t => t.id !== taskId),\n };\n};\n\n/**\n * Add a task to metadata\n */\nexport const addTask = (metadata: TranscriptMetadata, description: string): { metadata: TranscriptMetadata; task: Task } => {\n const task = createTask(description);\n \n return {\n metadata: {\n ...metadata,\n tasks: [...(metadata.tasks || []), task],\n },\n task,\n };\n};\n\n\n","/**\n * Frontmatter parsing utilities using gray-matter\n * \n * This module provides reliable YAML frontmatter parsing for transcript files,\n * consolidating all machine-readable data in frontmatter.\n */\n\nimport matter from 'gray-matter';\nimport { TranscriptMetadata, parseEntityMetadata, applyLifecycleDefaults, TranscriptStatus, StatusTransition, Task } from './metadata';\n\nexport interface ParsedFrontmatter {\n /** Parsed metadata from frontmatter (with lifecycle defaults applied) */\n metadata: TranscriptMetadata;\n /** Clean body content (no entity section, no legacy metadata sections) */\n body: string;\n /** Whether this file needs migration (old format detected) */\n needsMigration: boolean;\n}\n\n// Re-export types for convenience\nexport type { TranscriptMetadata, TranscriptStatus, StatusTransition, Task };\n\n/**\n * Parse old-style ## Metadata section from body content\n */\nfunction parseOldMetadataSection(content: string): Partial<TranscriptMetadata> {\n const metadata: Partial<TranscriptMetadata> = {};\n \n // Find the ## Metadata section\n // Look for ## Metadata followed by content until we hit --- or another ## or end of string\n const metadataMatch = content.match(/## Metadata\\s*\\n([\\s\\S]*?)(?:\\n---|\\n##|$)/);\n if (!metadataMatch) {\n return metadata;\n }\n \n const metadataSection = metadataMatch[1];\n \n // Extract project\n const projectMatch = metadataSection.match(/\\*\\*Project\\*\\*:\\s*(.+)/);\n if (projectMatch) {\n metadata.project = projectMatch[1].trim();\n }\n \n // Extract project ID\n const projectIdMatch = metadataSection.match(/\\*\\*Project ID\\*\\*:\\s*`([^`]+)`/);\n if (projectIdMatch) {\n metadata.projectId = projectIdMatch[1].trim();\n }\n \n // Extract tags\n const tagsMatch = metadataSection.match(/\\*\\*Tags\\*\\*:\\s*(.+)/);\n if (tagsMatch) {\n const tagsStr = tagsMatch[1];\n // Tags are formatted as `tag1`, `tag2`, `tag3`\n const tags = tagsStr.match(/`([^`]+)`/g);\n if (tags) {\n metadata.tags = tags.map(t => t.replace(/`/g, '').trim());\n }\n }\n \n // Extract date\n const dateMatch = metadataSection.match(/\\*\\*Date\\*\\*:\\s*(.+)/);\n if (dateMatch) {\n const dateStr = dateMatch[1].trim();\n // Try to parse the date (format: \"December 22, 2025\")\n const parsed = new Date(dateStr);\n if (!isNaN(parsed.getTime())) {\n metadata.date = parsed;\n }\n }\n \n // Extract time\n const timeMatch = metadataSection.match(/\\*\\*Time\\*\\*:\\s*(.+)/);\n if (timeMatch) {\n metadata.recordingTime = timeMatch[1].trim();\n }\n \n // Extract routing information\n const routingMatch = metadataSection.match(/### Routing\\s+([\\s\\S]*?)(?:\\n###|\\n##|$)/);\n if (routingMatch) {\n const routingSection = routingMatch[1];\n \n const destMatch = routingSection.match(/\\*\\*Destination\\*\\*:\\s*(.+)/);\n const confMatch = routingSection.match(/\\*\\*Confidence\\*\\*:\\s*([\\d.]+)%/);\n const reasoningMatch = routingSection.match(/\\*\\*Reasoning\\*\\*:\\s*(.+)/);\n \n if (destMatch || confMatch) {\n metadata.routing = {\n destination: destMatch ? destMatch[1].trim() : '',\n confidence: confMatch ? parseFloat(confMatch[1]) / 100 : 0,\n signals: [],\n reasoning: reasoningMatch ? reasoningMatch[1].trim() : '',\n };\n \n // Extract classification signals\n const signalsMatch = routingSection.match(/\\*\\*Classification Signals\\*\\*:\\s+([\\s\\S]*?)(?:\\n\\*\\*|$)/);\n if (signalsMatch) {\n const signalsText = signalsMatch[1];\n const signalLines = signalsText.split('\\n').filter(l => l.trim().startsWith('-'));\n \n for (const line of signalLines) {\n // Format: - topic: \"Node.js\" (30% weight)\n const signalMatch = line.match(/- ([^:]+):\\s*\"([^\"]+)\"\\s*\\((\\d+)% weight\\)/);\n if (signalMatch) {\n const typeStr = signalMatch[1].trim().replace(/ /g, '_');\n // Map to valid signal types\n const validTypes = ['explicit_phrase', 'associated_person', 'associated_company', 'topic', 'context_type'];\n const type = validTypes.includes(typeStr) ? typeStr : 'topic';\n \n metadata.routing.signals.push({\n type: type as 'explicit_phrase' | 'associated_person' | 'associated_company' | 'topic' | 'context_type',\n value: signalMatch[2].trim(),\n weight: parseFloat(signalMatch[3]) / 100,\n });\n }\n }\n }\n }\n }\n \n return metadata;\n}\n\n/**\n * Parse a transcript file using gray-matter\n * Handles both new format (all metadata in frontmatter) and old format (entities in body)\n */\nexport function parseTranscriptContent(content: string): ParsedFrontmatter {\n // Parse frontmatter using gray-matter\n const { data: frontmatter, content: rawBody } = matter(content);\n \n // Detect if this is old format\n const needsMigration = isOldFormat(content, frontmatter);\n \n // Build metadata from frontmatter\n let metadata: TranscriptMetadata = {\n title: frontmatter.title,\n date: frontmatter.date ? new Date(frontmatter.date) : undefined,\n recordingTime: frontmatter.recordingTime,\n duration: frontmatter.duration,\n project: frontmatter.project,\n projectId: frontmatter.projectId,\n tags: frontmatter.tags,\n confidence: frontmatter.confidence,\n routing: frontmatter.routing,\n status: frontmatter.status,\n history: frontmatter.history,\n tasks: frontmatter.tasks,\n entities: frontmatter.entities,\n };\n \n // If old format, parse the ## Metadata section from the original content\n // (not rawBody, because gray-matter might have consumed it)\n if (needsMigration) {\n const oldMetadata = parseOldMetadataSection(content);\n // Merge: start with old metadata, then overlay frontmatter values (if present)\n // Only overlay non-undefined values from frontmatter\n metadata = {\n ...oldMetadata,\n ...(metadata.title !== undefined && { title: metadata.title }),\n ...(metadata.date !== undefined && { date: metadata.date }),\n ...(metadata.recordingTime !== undefined && { recordingTime: metadata.recordingTime }),\n ...(metadata.duration !== undefined && { duration: metadata.duration }),\n ...(metadata.project !== undefined && { project: metadata.project }),\n ...(metadata.projectId !== undefined && { projectId: metadata.projectId }),\n ...(metadata.tags !== undefined && { tags: metadata.tags }),\n ...(metadata.confidence !== undefined && { confidence: metadata.confidence }),\n ...(metadata.routing !== undefined && { routing: metadata.routing }),\n ...(metadata.status !== undefined && { status: metadata.status }),\n ...(metadata.history !== undefined && { history: metadata.history }),\n ...(metadata.tasks !== undefined && { tasks: metadata.tasks }),\n ...(metadata.entities !== undefined && { entities: metadata.entities }),\n };\n }\n \n // If entities not in frontmatter, try to extract from body (old format)\n if (!metadata.entities) {\n const extractedEntities = parseEntityMetadata(rawBody);\n if (extractedEntities) {\n metadata.entities = extractedEntities;\n }\n }\n \n // Extract title from body if not in frontmatter (old format)\n let cleanBody = rawBody;\n const titleMatch = rawBody.match(/^#\\s+(.+)$/m);\n \n if (!metadata.title && titleMatch) {\n // No title in frontmatter, extract from H1\n metadata.title = titleMatch[1].trim();\n cleanBody = rawBody.replace(/^#\\s+.+$/m, '').trim();\n } else if (metadata.title && titleMatch) {\n // Title in frontmatter, remove H1 from body\n cleanBody = rawBody.replace(/^#\\s+.+$/m, '').trim();\n }\n \n // Apply lifecycle defaults\n metadata = applyLifecycleDefaults(metadata);\n \n // Clean the body (remove entity section if present)\n cleanBody = stripLegacySections(cleanBody);\n \n return {\n metadata,\n body: cleanBody,\n needsMigration,\n };\n}\n\n/**\n * Detect if a file is in old format\n */\nfunction isOldFormat(content: string, frontmatter: Record<string, unknown>): boolean {\n // No frontmatter at all\n if (!content.startsWith('---')) {\n return true;\n }\n \n // Has frontmatter but entities are in body, not frontmatter\n if (!frontmatter.entities && content.includes('## Entity References')) {\n return true;\n }\n \n // Has legacy ## Metadata section in body\n if (content.includes('\\n## Metadata\\n')) {\n return true;\n }\n \n return false;\n}\n\n/**\n * Strip legacy sections from body content\n * Removes: ## Entity References, ## Metadata\n * Note: This must be careful not to remove these patterns if they appear in code blocks\n */\nexport function stripLegacySections(body: string): string {\n let clean = body;\n \n // Remove ## Metadata section (at start, before content)\n // This is trickier - it's between title and content\n // Pattern: ## Metadata ... --- (the --- is the separator before content)\n // Only match if it's at the start of the content (after optional whitespace)\n clean = clean.replace(/^(\\s*)## Metadata[\\s\\S]*?\\n---\\n/, '');\n \n // Remove ## Entity References section (at end of file)\n // Pattern: optional separator (---), then ## Entity References, then everything after\n // We need to be more careful here to avoid matching inside code blocks\n // Look for the pattern at the end of the file, after a separator\n const entityRefPattern = /\\n---\\s*\\n+## Entity References[\\s\\S]*$/;\n if (entityRefPattern.test(clean)) {\n clean = clean.replace(entityRefPattern, '');\n } else {\n // Try without the separator (some files might not have it)\n // But only if it's truly at the end (no other ## headers after it)\n const endPattern = /\\n## Entity References\\s*\\n[\\s\\S]*$/;\n if (endPattern.test(clean)) {\n // Check if there are any other ## headers after this point\n const match = clean.match(endPattern);\n if (match) {\n const entitySection = match[0];\n // If there are no other ## headers in this section (except Entity References sub-headers like ### Projects)\n // then it's safe to remove\n const otherHeaders = entitySection.match(/\\n## (?!Entity References)/g);\n if (!otherHeaders || otherHeaders.length === 0) {\n clean = clean.replace(endPattern, '');\n }\n }\n }\n }\n \n return clean.trim();\n}\n\n/**\n * Check if metadata has any entities\n */\nexport function hasEntities(entities: TranscriptMetadata['entities']): boolean {\n if (!entities) return false;\n return !!(\n entities.people?.length || \n entities.projects?.length || \n entities.terms?.length || \n entities.companies?.length\n );\n}\n\n// ============================================================================\n// Writing Functions\n// ============================================================================\n\n/**\n * Build a frontmatter object from TranscriptMetadata\n * Only includes non-empty values to keep YAML clean\n */\nexport function buildFrontmatter(metadata: TranscriptMetadata): Record<string, unknown> {\n const fm: Record<string, unknown> = {};\n \n // Core fields\n if (metadata.title) fm.title = metadata.title;\n if (metadata.date) fm.date = metadata.date.toISOString();\n if (metadata.recordingTime) fm.recordingTime = metadata.recordingTime;\n if (metadata.duration) fm.duration = metadata.duration;\n if (metadata.project) fm.project = metadata.project;\n if (metadata.projectId) fm.projectId = metadata.projectId;\n if (metadata.tags && metadata.tags.length > 0) fm.tags = metadata.tags;\n if (metadata.confidence !== undefined) fm.confidence = metadata.confidence;\n \n // Routing\n if (metadata.routing) fm.routing = metadata.routing;\n \n // Lifecycle\n if (metadata.status) fm.status = metadata.status;\n if (metadata.history && metadata.history.length > 0) fm.history = metadata.history;\n if (metadata.tasks && metadata.tasks.length > 0) fm.tasks = metadata.tasks;\n \n // Entities (now in frontmatter, not in body)\n if (hasEntities(metadata.entities)) {\n fm.entities = metadata.entities;\n }\n \n return fm;\n}\n\n/**\n * Stringify a transcript with YAML frontmatter\n * Uses gray-matter for consistent output\n * Ensures title is ONLY in frontmatter, never in body\n */\nexport function stringifyTranscript(metadata: TranscriptMetadata, body: string): string {\n const frontmatter = buildFrontmatter(metadata);\n \n // Clean the body (remove any legacy sections)\n let cleanBody = stripLegacySections(body);\n \n // Remove any leading frontmatter delimiters from the body\n // This can happen if the body was extracted incorrectly or has leftover delimiters\n cleanBody = cleanBody.replace(/^---\\s*\\n/, '').trim();\n \n // Remove H1 title from body if it matches the frontmatter title\n // Title should ONLY be in frontmatter\n if (metadata.title) {\n // Remove exact H1 match\n const h1Pattern = new RegExp(`^#\\\\s+${escapeRegex(metadata.title)}\\\\s*$`, 'm');\n cleanBody = cleanBody.replace(h1Pattern, '').trim();\n \n // Also remove any H1 at the start of the body (common pattern)\n cleanBody = cleanBody.replace(/^#\\s+.+$/m, '').trim();\n }\n \n // Use gray-matter to create the output\n // It handles YAML serialization, escaping, etc.\n return matter.stringify(cleanBody + '\\n', frontmatter);\n}\n\n/**\n * Escape special regex characters in a string\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Update a transcript's content while preserving/updating metadata\n * This is the main function for saving transcripts in the new format\n */\nexport function updateTranscript(\n originalContent: string,\n updates: {\n body?: string;\n metadata?: Partial<TranscriptMetadata>;\n }\n): string {\n // Parse the original\n const parsed = parseTranscriptContent(originalContent);\n \n // Merge metadata updates\n const newMetadata: TranscriptMetadata = {\n ...parsed.metadata,\n ...updates.metadata,\n };\n \n // Use updated body or original\n const newBody = updates.body ?? parsed.body;\n \n // Stringify with new format\n return stringifyTranscript(newMetadata, newBody);\n}\n"],"names":[],"mappings":";;AAoFO,MAAM,sBAAA,GAAyB,CAAC,QAAA,KAAyC;AAC5E,EAAA,MAAM,QAAkB,EAAC;AAGzB,EAAA,IAAI,SAAS,KAAA,EAAO;AAChB,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,QAAA,CAAS,KAAK,CAAA,CAAE,CAAA;AAChC,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,KAAA,CAAM,KAAK,aAAa,CAAA;AACxB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAGb,EAAA,IAAI,SAAS,IAAA,EAAM;AACf,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,kBAAA,CAAmB,OAAA,EAAS;AAAA,MACtD,IAAA,EAAM,SAAA;AAAA,MACN,KAAA,EAAO,MAAA;AAAA,MACP,GAAA,EAAK;AAAA,KACR,CAAA;AACD,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,OAAO,CAAA,CAAE,CAAA;AAEjC,IAAA,IAAI,SAAS,aAAA,EAAe;AACxB,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,QAAA,CAAS,aAAa,CAAA,CAAE,CAAA;AAAA,IACpD,CAAA,MAAO;AACH,MAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,CAAK,kBAAA,CAAmB,OAAA,EAAS;AAAA,QACtD,IAAA,EAAM,SAAA;AAAA,QACN,MAAA,EAAQ,SAAA;AAAA,QACR,MAAA,EAAQ;AAAA,OACX,CAAA;AACD,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,UAAA,EAAa,OAAO,CAAA,CAAE,CAAA;AAAA,IACrC;AAAA,EACJ;AAEA,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAGb,EAAA,IAAI,SAAS,OAAA,EAAS;AAClB,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,aAAA,EAAgB,QAAA,CAAS,OAAO,CAAA,CAAE,CAAA;AAC7C,IAAA,IAAI,SAAS,SAAA,EAAW;AACpB,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,kBAAA,EAAqB,QAAA,CAAS,SAAS,CAAA,EAAA,CAAI,CAAA;AAAA,IAC1D;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,SAAS,OAAA,EAAS;AAClB,IAAA,KAAA,CAAM,KAAK,aAAa,CAAA;AACxB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,iBAAA,EAAoB,QAAA,CAAS,OAAA,CAAQ,WAAW,CAAA,CAAE,CAAA;AAC7D,IAAA,KAAA,CAAM,IAAA,CAAK,oBAAoB,QAAA,CAAS,OAAA,CAAQ,aAAa,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,CAAG,CAAA;AAC/E,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAEb,IAAA,IAAI,QAAA,CAAS,OAAA,CAAQ,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AACrC,MAAA,KAAA,CAAM,KAAK,6BAA6B,CAAA;AACxC,MAAA,KAAA,MAAW,MAAA,IAAU,QAAA,CAAS,OAAA,CAAQ,OAAA,EAAS;AAC3C,QAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,MAAM,GAAG,CAAA;AAChD,QAAA,MAAM,MAAA,GAAA,CAAU,MAAA,CAAO,MAAA,GAAS,GAAA,EAAK,QAAQ,CAAC,CAAA;AAC9C,QAAA,KAAA,CAAM,IAAA,CAAK,KAAK,UAAU,CAAA,GAAA,EAAM,OAAO,KAAK,CAAA,GAAA,EAAM,MAAM,CAAA,SAAA,CAAW,CAAA;AAAA,MACvE;AACA,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,IACjB;AAEA,IAAA,IAAI,QAAA,CAAS,QAAQ,SAAA,EAAW;AAC5B,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,eAAA,EAAkB,QAAA,CAAS,OAAA,CAAQ,SAAS,CAAA,CAAE,CAAA;AACzD,MAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,IACjB;AAAA,EACJ;AAGA,EAAA,IAAI,QAAA,CAAS,IAAA,IAAQ,QAAA,CAAS,IAAA,CAAK,SAAS,CAAA,EAAG;AAC3C,IAAA,KAAA,CAAM,IAAA,CAAK,YAAA,GAAe,QAAA,CAAS,IAAA,CAAK,GAAA,CAAI,CAAA,GAAA,KAAO,CAAA,EAAA,EAAK,GAAG,CAAA,EAAA,CAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA;AAC3E,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,SAAS,QAAA,EAAU;AACnB,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,cAAA,EAAiB,QAAA,CAAS,QAAQ,CAAA,CAAE,CAAA;AAC/C,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAEb,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAC1B;AAMO,MAAM,4BAAA,GAA+B,CAAC,QAAA,KAAyC;AAClF,EAAA,IAAI,CAAC,SAAS,QAAA,EAAU;AACpB,IAAA,OAAO,EAAA;AAAA,EACX;AAEA,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,sBAAsB,CAAA;AACjC,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,qEAAqE,CAAA;AAChF,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAGb,EAAA,IAAI,SAAS,QAAA,CAAS,MAAA,IAAU,SAAS,QAAA,CAAS,MAAA,CAAO,SAAS,CAAA,EAAG;AACjE,IAAA,KAAA,CAAM,KAAK,YAAY,CAAA;AACvB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,MAAA,IAAU,QAAA,CAAS,QAAA,CAAS,MAAA,EAAQ;AAC3C,MAAA,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,MAAA,CAAO,EAAE,CAAA,IAAA,EAAO,MAAA,CAAO,IAAI,CAAA,CAAE,CAAA;AAAA,IACnD;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,SAAS,QAAA,CAAS,QAAA,IAAY,SAAS,QAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AACrE,IAAA,KAAA,CAAM,KAAK,cAAc,CAAA;AACzB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,OAAA,IAAW,QAAA,CAAS,QAAA,CAAS,QAAA,EAAU;AAC9C,MAAA,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,OAAA,CAAQ,EAAE,CAAA,IAAA,EAAO,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AAAA,IACrD;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,SAAS,QAAA,CAAS,KAAA,IAAS,SAAS,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,EAAG;AAC/D,IAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AACtB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,IAAA,IAAQ,QAAA,CAAS,QAAA,CAAS,KAAA,EAAO;AACxC,MAAA,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,IAAA,CAAK,EAAE,CAAA,IAAA,EAAO,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AAAA,IAC/C;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,SAAS,QAAA,CAAS,SAAA,IAAa,SAAS,QAAA,CAAS,SAAA,CAAU,SAAS,CAAA,EAAG;AACvE,IAAA,KAAA,CAAM,KAAK,eAAe,CAAA;AAC1B,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,OAAA,IAAW,QAAA,CAAS,QAAA,CAAS,SAAA,EAAW;AAC/C,MAAA,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,OAAA,CAAQ,EAAE,CAAA,IAAA,EAAO,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AAAA,IACrD;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAC1B;AAMO,MAAM,mBAAA,GAAsB,CAAC,OAAA,KAAgE;AAGhG,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,sBAAsB,CAAA;AAC1D,EAAA,IAAI,gBAAgB,EAAA,EAAI;AACpB,IAAA,OAAO,MAAA;AAAA,EACX;AAGA,EAAA,IAAI,YAAA,GAAe,cAAc,sBAAA,CAAuB,MAAA;AAExD,EAAA,OAAO,eAAe,OAAA,CAAQ,MAAA,KAAW,QAAQ,YAAY,CAAA,KAAM,QAAQ,OAAA,CAAQ,YAAY,CAAA,KAAM,IAAA,IAAQ,QAAQ,YAAY,CAAA,KAAM,OAAO,OAAA,CAAQ,YAAY,MAAM,GAAA,CAAA,EAAO;AAC3K,IAAA,YAAA,EAAA;AAAA,EACJ;AAGA,EAAA,MAAM,gBAAA,GAAmB,OAAA,CAAQ,SAAA,CAAU,YAAY,CAAA;AACvD,EAAA,MAAM,eAAA,GAAkB,gBAAA,CAAiB,KAAA,CAAM,OAAO,CAAA;AACtD,EAAA,MAAM,iBAAiB,eAAA,GACjB,gBAAA,CAAiB,UAAU,CAAA,EAAG,eAAA,CAAgB,KAAK,CAAA,GACnD,gBAAA;AACN,EAAA,MAAM,QAAA,GAAwD;AAAA,IAC1D,QAAQ,EAAC;AAAA,IACT,UAAU,EAAC;AAAA,IACX,OAAO,EAAC;AAAA,IACR,WAAW;AAAC,GAChB;AAGA,EAAA,MAAM,aAAA,GAAgB,CAAC,IAAA,KAA2E;AAE9F,IAAA,MAAM,OAAA,GAAqE;AAAA,MACvE,QAAA,EAAU,QAAA;AAAA,MACV,UAAA,EAAY,SAAA;AAAA,MACZ,OAAA,EAAS,MAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACjB;AAEA,IAAA,MAAM,UAAA,GAAa,QAAQ,IAAI,CAAA;AAG/B,IAAA,MAAM,aAAA,GAAgB,OAAO,IAAI,CAAA,CAAA;AACjC,IAAA,MAAM,YAAA,GAAe,cAAA,CAAe,OAAA,CAAQ,aAAa,CAAA;AACzD,IAAA,IAAI,YAAA,KAAiB,EAAA,EAAI,OAAO,EAAC;AAIjC,IAAA,MAAM,SAAA,GAAY,eAAe,aAAA,CAAc,MAAA;AAC/C,IAAA,IAAI,gBAAA,GAAmB,SAAA;AAEvB,IAAA,OAAO,gBAAA,GAAmB,cAAA,CAAe,MAAA,KACjC,cAAA,CAAe,gBAAgB,CAAA,KAAM,IAAA,IAAQ,cAAA,CAAe,gBAAgB,CAAA,KAAM,IAAA,IAAQ,cAAA,CAAe,gBAAgB,MAAM,GAAA,CAAA,EAAM;AACzI,MAAA,gBAAA,EAAA;AAAA,IACJ;AAEA,IAAA,MAAM,YAAA,GAAe,cAAA,CAAe,SAAA,CAAU,gBAAgB,CAAA;AAC9D,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,MAAA,CAAO,OAAO,CAAA;AAC/C,IAAA,MAAM,cAAc,WAAA,KAAgB,EAAA,GAAK,eAAe,YAAA,CAAa,SAAA,CAAU,GAAG,WAAW,CAAA;AAI7F,IAAA,MAAM,QAA2B,EAAC;AAElC,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,IAAI,CAAA;AACpC,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACtB,MAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,uBAAuB,CAAA;AACnD,MAAA,IAAI,KAAA,EAAO;AACP,QAAA,KAAA,CAAM,IAAA,CAAK;AAAA,UACP,EAAA,EAAI,MAAM,CAAC,CAAA;AAAA,UACX,IAAA,EAAM,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,UACpB,IAAA,EAAM;AAAA,SACT,CAAA;AAAA,MACL;AAAA,IACJ;AAEA,IAAA,OAAO,KAAA;AAAA,EACX,CAAA;AAEA,EAAA,QAAA,CAAS,MAAA,GAAS,cAAc,QAAQ,CAAA;AACxC,EAAA,QAAA,CAAS,QAAA,GAAW,cAAc,UAAU,CAAA;AAC5C,EAAA,QAAA,CAAS,KAAA,GAAQ,cAAc,OAAO,CAAA;AACtC,EAAA,QAAA,CAAS,SAAA,GAAY,cAAc,WAAW,CAAA;AAG9C,EAAA,MAAM,WAAA,GACF,QAAA,CAAS,MAAA,CAAO,MAAA,GAAS,KACzB,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,CAAA,IAC3B,SAAS,KAAA,CAAM,MAAA,GAAS,CAAA,IACxB,QAAA,CAAS,UAAU,MAAA,GAAS,CAAA;AAEhC,EAAA,OAAO,cAAc,QAAA,GAAW,MAAA;AACpC;AAKO,MAAM,qBAAA,GAAwB,CAAC,QAAA,KAAqD;AACvF,EAAA,OAAO;AAAA,IACH,WAAA,EAAa,SAAS,WAAA,CAAY,IAAA;AAAA,IAClC,YAAY,QAAA,CAAS,UAAA;AAAA,IACrB,SAAS,QAAA,CAAS,OAAA;AAAA,IAClB,WAAW,QAAA,CAAS;AAAA,GACxB;AACJ;AAKO,MAAM,cAAA,GAAiB,CAAC,OAAA,KAA4B;AACvD,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,EAAE,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,EAAE,CAAA;AAEpC,EAAA,IAAI,YAAY,CAAA,EAAG;AACf,IAAA,OAAO,GAAG,IAAI,CAAA,CAAA,CAAA;AAAA,EAClB;AAEA,EAAA,IAAI,SAAS,CAAA,EAAG;AACZ,IAAA,OAAO,GAAG,OAAO,CAAA,CAAA,CAAA;AAAA,EACrB;AAEA,EAAA,OAAO,CAAA,EAAG,OAAO,CAAA,EAAA,EAAK,IAAI,CAAA,CAAA,CAAA;AAC9B;AAKO,MAAM,UAAA,GAAa,CAAC,IAAA,KAAuB;AAC9C,EAAA,OAAO,IAAA,CAAK,mBAAmB,OAAA,EAAS;AAAA,IACpC,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,MAAA,EAAQ;AAAA,GACX,CAAA;AACL;AAKO,MAAM,uBAAA,GAA0B,CAAC,OAAA,KAAgE;AACpG,EAAA,MAAM,WAAA,GAAc,QAAQ,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,OAAA,IAAW,CAAA,CAAE,IAAA,KAAS,cAAc,CAAA;AACrF,EAAA,OAAO,WAAA,EAAa,KAAA;AACxB;AAMO,MAAM,sBAAA,GAAyB,CAAC,OAAA,KAAsD;AACzF,EAAA,MAAM,OAAO,OAAA,CACR,MAAA,CAAO,OAAK,CAAA,CAAE,IAAA,KAAS,cAAc,CAAA,CACrC,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAA,CAChB,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,MAAM,QAAQ,CAAA;AAGrD,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,GAAA,CAAI,IAAI,CAAC,CAAA;AACnC;AASO,MAAM,cAAA,GAAqC;AAAA,EAC9C,SAAA;AAAA,EAAW,UAAA;AAAA,EAAY,UAAA;AAAA,EAAY,aAAA;AAAA,EAAe,QAAA;AAAA,EAAU;AAChE;AAKO,MAAM,aAAA,GAAgB,CAAC,MAAA,KAA+C;AACzE,EAAA,OAAO,cAAA,CAAe,SAAS,MAA0B,CAAA;AAC7D;AAKO,MAAM,iBAAiB,MAAc;AACxC,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,EAAA,MAAM,MAAA,GAAS,KAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA;AACxD,EAAA,OAAO,CAAA,KAAA,EAAQ,SAAS,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AACtC;AAKO,MAAM,UAAA,GAAa,CAAC,WAAA,KAA8B;AACrD,EAAA,OAAO;AAAA,IACH,IAAI,cAAA,EAAe;AAAA,IACnB,WAAA;AAAA,IACA,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAA,iBAAS,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,GACpC;AACJ;AAMO,MAAM,YAAA,GAAe,CACxB,QAAA,EACA,SAAA,KACqB;AACrB,EAAA,MAAM,YAAY,QAAA,CAAS,MAAA;AAG3B,EAAA,IAAI,cAAc,SAAA,EAAW;AACzB,IAAA,OAAO,QAAA;AAAA,EACX;AAEA,EAAA,MAAM,UAAA,GAA+B;AAAA,IACjC,MAAM,SAAA,IAAa,UAAA;AAAA,IACnB,EAAA,EAAI,SAAA;AAAA,IACJ,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,GAC/B;AAEA,EAAA,OAAO;AAAA,IACH,GAAG,QAAA;AAAA,IACH,MAAA,EAAQ,SAAA;AAAA,IACR,SAAS,CAAC,GAAI,SAAS,OAAA,IAAW,IAAK,UAAU;AAAA,GACrD;AACJ;AAMO,MAAM,sBAAA,GAAyB,CAAC,QAAA,KAAqD;AACxF,EAAA,OAAO;AAAA,IACH,GAAG,QAAA;AAAA,IACH,MAAA,EAAQ,SAAS,MAAA,IAAU,UAAA;AAAA,IAC3B,OAAA,EAAS,QAAA,CAAS,OAAA,IAAW,EAAC;AAAA,IAC9B,KAAA,EAAO,QAAA,CAAS,KAAA,IAAS;AAAC,GAC9B;AACJ;AAKO,MAAM,YAAA,GAAe,CAAC,QAAA,EAA8B,MAAA,KAAuC;AAC9F,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,IAAS,EAAC;AACjC,EAAA,MAAM,YAAY,KAAA,CAAM,SAAA,CAAU,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,MAAM,CAAA;AAEtD,EAAA,IAAI,cAAc,EAAA,EAAI;AAClB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAE,CAAA;AAAA,EAC/C;AAEA,EAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,EAAA,MAAM,YAAA,GAAe,CAAC,GAAG,KAAK,CAAA;AAC9B,EAAA,YAAA,CAAa,SAAS,CAAA,GAAI;AAAA,IACtB,GAAG,aAAa,SAAS,CAAA;AAAA,IACzB,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,GAAA;AAAA,IACT,SAAA,EAAW;AAAA,GACf;AAEA,EAAA,OAAO;AAAA,IACH,GAAG,QAAA;AAAA,IACH,KAAA,EAAO;AAAA,GACX;AACJ;AAKO,MAAM,UAAA,GAAa,CAAC,QAAA,EAA8B,MAAA,KAAuC;AAC5F,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,IAAS,EAAC;AACjC,EAAA,MAAM,YAAY,KAAA,CAAM,SAAA,CAAU,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,MAAM,CAAA;AAEtD,EAAA,IAAI,cAAc,EAAA,EAAI;AAClB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAE,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO;AAAA,IACH,GAAG,QAAA;AAAA,IACH,OAAO,KAAA,CAAM,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,MAAM;AAAA,GAC5C;AACJ;AAKO,MAAM,OAAA,GAAU,CAAC,QAAA,EAA8B,WAAA,KAAsE;AACxH,EAAA,MAAM,IAAA,GAAO,WAAW,WAAW,CAAA;AAEnC,EAAA,OAAO;AAAA,IACH,QAAA,EAAU;AAAA,MACN,GAAG,QAAA;AAAA,MACH,OAAO,CAAC,GAAI,SAAS,KAAA,IAAS,IAAK,IAAI;AAAA,KAC3C;AAAA,IACA;AAAA,GACJ;AACJ;;AC1fA,SAAS,wBAAwB,OAAA,EAA8C;AAC3E,EAAA,MAAM,WAAwC,EAAC;AAI/C,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,KAAA,CAAM,4CAA4C,CAAA;AAChF,EAAA,IAAI,CAAC,aAAA,EAAe;AAChB,IAAA,OAAO,QAAA;AAAA,EACX;AAEA,EAAA,MAAM,eAAA,GAAkB,cAAc,CAAC,CAAA;AAGvC,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,KAAA,CAAM,yBAAyB,CAAA;AACpE,EAAA,IAAI,YAAA,EAAc;AACd,IAAA,QAAA,CAAS,OAAA,GAAU,YAAA,CAAa,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,EAC5C;AAGA,EAAA,MAAM,cAAA,GAAiB,eAAA,CAAgB,KAAA,CAAM,iCAAiC,CAAA;AAC9E,EAAA,IAAI,cAAA,EAAgB;AAChB,IAAA,QAAA,CAAS,SAAA,GAAY,cAAA,CAAe,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,EAChD;AAGA,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,KAAA,CAAM,sBAAsB,CAAA;AAC9D,EAAA,IAAI,SAAA,EAAW;AACX,IAAA,MAAM,OAAA,GAAU,UAAU,CAAC,CAAA;AAE3B,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,YAAY,CAAA;AACvC,IAAA,IAAI,IAAA,EAAM;AACN,MAAA,QAAA,CAAS,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,QAAQ,IAAA,EAAM,EAAE,CAAA,CAAE,IAAA,EAAM,CAAA;AAAA,IAC5D;AAAA,EACJ;AAGA,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,KAAA,CAAM,sBAAsB,CAAA;AAC9D,EAAA,IAAI,SAAA,EAAW;AACX,IAAA,MAAM,OAAA,GAAU,SAAA,CAAU,CAAC,CAAA,CAAE,IAAA,EAAK;AAElC,IAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,OAAO,CAAA;AAC/B,IAAA,IAAI,CAAC,KAAA,CAAM,MAAA,CAAO,OAAA,EAAS,CAAA,EAAG;AAC1B,MAAA,QAAA,CAAS,IAAA,GAAO,MAAA;AAAA,IACpB;AAAA,EACJ;AAGA,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,KAAA,CAAM,sBAAsB,CAAA;AAC9D,EAAA,IAAI,SAAA,EAAW;AACX,IAAA,QAAA,CAAS,aAAA,GAAgB,SAAA,CAAU,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,EAC/C;AAGA,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,KAAA,CAAM,0CAA0C,CAAA;AACrF,EAAA,IAAI,YAAA,EAAc;AACd,IAAA,MAAM,cAAA,GAAiB,aAAa,CAAC,CAAA;AAErC,IAAA,MAAM,SAAA,GAAY,cAAA,CAAe,KAAA,CAAM,6BAA6B,CAAA;AACpE,IAAA,MAAM,SAAA,GAAY,cAAA,CAAe,KAAA,CAAM,iCAAiC,CAAA;AACxE,IAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,KAAA,CAAM,2BAA2B,CAAA;AAEvE,IAAA,IAAI,aAAa,SAAA,EAAW;AACxB,MAAA,QAAA,CAAS,OAAA,GAAU;AAAA,QACf,aAAa,SAAA,GAAY,SAAA,CAAU,CAAC,CAAA,CAAE,MAAK,GAAI,EAAA;AAAA,QAC/C,YAAY,SAAA,GAAY,UAAA,CAAW,UAAU,CAAC,CAAC,IAAI,GAAA,GAAM,CAAA;AAAA,QACzD,SAAS,EAAC;AAAA,QACV,WAAW,cAAA,GAAiB,cAAA,CAAe,CAAC,CAAA,CAAE,MAAK,GAAI;AAAA,OAC3D;AAGA,MAAA,MAAM,YAAA,GAAe,cAAA,CAAe,KAAA,CAAM,0DAA0D,CAAA;AACpG,MAAA,IAAI,YAAA,EAAc;AACd,QAAA,MAAM,WAAA,GAAc,aAAa,CAAC,CAAA;AAClC,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,EAAK,CAAE,UAAA,CAAW,GAAG,CAAC,CAAA;AAEhF,QAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAE5B,UAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,4CAA4C,CAAA;AAC3E,UAAA,IAAI,WAAA,EAAa;AACb,YAAA,MAAM,OAAA,GAAU,YAAY,CAAC,CAAA,CAAE,MAAK,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA;AAEvD,YAAA,MAAM,aAAa,CAAC,iBAAA,EAAmB,mBAAA,EAAqB,oBAAA,EAAsB,SAAS,cAAc,CAAA;AACzG,YAAA,MAAM,IAAA,GAAO,UAAA,CAAW,QAAA,CAAS,OAAO,IAAI,OAAA,GAAU,OAAA;AAEtD,YAAA,QAAA,CAAS,OAAA,CAAQ,QAAQ,IAAA,CAAK;AAAA,cAC1B,IAAA;AAAA,cACA,KAAA,EAAO,WAAA,CAAY,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,cAC3B,MAAA,EAAQ,UAAA,CAAW,WAAA,CAAY,CAAC,CAAC,CAAA,GAAI;AAAA,aACxC,CAAA;AAAA,UACL;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,EAAA,OAAO,QAAA;AACX;AAMO,SAAS,uBAAuB,OAAA,EAAoC;AAEvE,EAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,SAAS,OAAA,EAAQ,GAAI,OAAO,OAAO,CAAA;AAG9D,EAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,OAAA,EAAS,WAAW,CAAA;AAGvD,EAAA,IAAI,QAAA,GAA+B;AAAA,IAC/B,OAAO,WAAA,CAAY,KAAA;AAAA,IACnB,MAAM,WAAA,CAAY,IAAA,GAAO,IAAI,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA,GAAI,MAAA;AAAA,IACtD,eAAe,WAAA,CAAY,aAAA;AAAA,IAC3B,UAAU,WAAA,CAAY,QAAA;AAAA,IACtB,SAAS,WAAA,CAAY,OAAA;AAAA,IACrB,WAAW,WAAA,CAAY,SAAA;AAAA,IACvB,MAAM,WAAA,CAAY,IAAA;AAAA,IAClB,YAAY,WAAA,CAAY,UAAA;AAAA,IACxB,SAAS,WAAA,CAAY,OAAA;AAAA,IACrB,QAAQ,WAAA,CAAY,MAAA;AAAA,IACpB,SAAS,WAAA,CAAY,OAAA;AAAA,IACrB,OAAO,WAAA,CAAY,KAAA;AAAA,IACnB,UAAU,WAAA,CAAY;AAAA,GAC1B;AAIA,EAAA,IAAI,cAAA,EAAgB;AAChB,IAAA,MAAM,WAAA,GAAc,wBAAwB,OAAO,CAAA;AAGnD,IAAA,QAAA,GAAW;AAAA,MACP,GAAG,WAAA;AAAA,MACH,GAAI,QAAA,CAAS,KAAA,KAAU,UAAa,EAAE,KAAA,EAAO,SAAS,KAAA,EAAM;AAAA,MAC5D,GAAI,QAAA,CAAS,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,MACzD,GAAI,QAAA,CAAS,aAAA,KAAkB,UAAa,EAAE,aAAA,EAAe,SAAS,aAAA,EAAc;AAAA,MACpF,GAAI,QAAA,CAAS,QAAA,KAAa,UAAa,EAAE,QAAA,EAAU,SAAS,QAAA,EAAS;AAAA,MACrE,GAAI,QAAA,CAAS,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,SAAS,OAAA,EAAQ;AAAA,MAClE,GAAI,QAAA,CAAS,SAAA,KAAc,UAAa,EAAE,SAAA,EAAW,SAAS,SAAA,EAAU;AAAA,MACxE,GAAI,QAAA,CAAS,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,MACzD,GAAI,QAAA,CAAS,UAAA,KAAe,UAAa,EAAE,UAAA,EAAY,SAAS,UAAA,EAAW;AAAA,MAC3E,GAAI,QAAA,CAAS,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,SAAS,OAAA,EAAQ;AAAA,MAClE,GAAI,QAAA,CAAS,MAAA,KAAW,UAAa,EAAE,MAAA,EAAQ,SAAS,MAAA,EAAO;AAAA,MAC/D,GAAI,QAAA,CAAS,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,SAAS,OAAA,EAAQ;AAAA,MAClE,GAAI,QAAA,CAAS,KAAA,KAAU,UAAa,EAAE,KAAA,EAAO,SAAS,KAAA,EAAM;AAAA,MAC5D,GAAI,QAAA,CAAS,QAAA,KAAa,UAAa,EAAE,QAAA,EAAU,SAAS,QAAA;AAAS,KACzE;AAAA,EACJ;AAGA,EAAA,IAAI,CAAC,SAAS,QAAA,EAAU;AACpB,IAAA,MAAM,iBAAA,GAAoB,oBAAoB,OAAO,CAAA;AACrD,IAAA,IAAI,iBAAA,EAAmB;AACnB,MAAA,QAAA,CAAS,QAAA,GAAW,iBAAA;AAAA,IACxB;AAAA,EACJ;AAGA,EAAA,IAAI,SAAA,GAAY,OAAA;AAChB,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,KAAA,CAAM,aAAa,CAAA;AAE9C,EAAA,IAAI,CAAC,QAAA,CAAS,KAAA,IAAS,UAAA,EAAY;AAE/B,IAAA,QAAA,CAAS,KAAA,GAAQ,UAAA,CAAW,CAAC,CAAA,CAAE,IAAA,EAAK;AACpC,IAAA,SAAA,GAAY,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,EAAE,EAAE,IAAA,EAAK;AAAA,EACtD,CAAA,MAAA,IAAW,QAAA,CAAS,KAAA,IAAS,UAAA,EAAY;AAErC,IAAA,SAAA,GAAY,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,EAAE,EAAE,IAAA,EAAK;AAAA,EACtD;AAGA,EAAA,QAAA,GAAW,uBAAuB,QAAQ,CAAA;AAG1C,EAAA,SAAA,GAAY,oBAAoB,SAAS,CAAA;AAEzC,EAAA,OAAO;AAAA,IACH,QAAA;AAAA,IACA,IAAA,EAAM,SAAA;AAAA,IACN;AAAA,GACJ;AACJ;AAKA,SAAS,WAAA,CAAY,SAAiB,WAAA,EAA+C;AAEjF,EAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,KAAK,CAAA,EAAG;AAC5B,IAAA,OAAO,IAAA;AAAA,EACX;AAGA,EAAA,IAAI,CAAC,WAAA,CAAY,QAAA,IAAY,OAAA,CAAQ,QAAA,CAAS,sBAAsB,CAAA,EAAG;AACnE,IAAA,OAAO,IAAA;AAAA,EACX;AAGA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,iBAAiB,CAAA,EAAG;AACrC,IAAA,OAAO,IAAA;AAAA,EACX;AAEA,EAAA,OAAO,KAAA;AACX;AAOO,SAAS,oBAAoB,IAAA,EAAsB;AACtD,EAAA,IAAI,KAAA,GAAQ,IAAA;AAMZ,EAAA,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,kCAAA,EAAoC,EAAE,CAAA;AAM5D,EAAA,MAAM,gBAAA,GAAmB,yCAAA;AACzB,EAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,KAAK,CAAA,EAAG;AAC9B,IAAA,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,gBAAA,EAAkB,EAAE,CAAA;AAAA,EAC9C,CAAA,MAAO;AAGH,IAAA,MAAM,UAAA,GAAa,qCAAA;AACnB,IAAA,IAAI,UAAA,CAAW,IAAA,CAAK,KAAK,CAAA,EAAG;AAExB,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,UAAU,CAAA;AACpC,MAAA,IAAI,KAAA,EAAO;AACP,QAAA,MAAM,aAAA,GAAgB,MAAM,CAAC,CAAA;AAG7B,QAAA,MAAM,YAAA,GAAe,aAAA,CAAc,KAAA,CAAM,6BAA6B,CAAA;AACtE,QAAA,IAAI,CAAC,YAAA,IAAgB,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG;AAC5C,UAAA,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAAA,QACxC;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,EAAA,OAAO,MAAM,IAAA,EAAK;AACtB;AAKO,SAAS,YAAY,QAAA,EAAmD;AAC3E,EAAA,IAAI,CAAC,UAAU,OAAO,KAAA;AACtB,EAAA,OAAO,CAAC,EACJ,QAAA,CAAS,MAAA,EAAQ,MAAA,IACjB,QAAA,CAAS,QAAA,EAAU,MAAA,IACnB,QAAA,CAAS,KAAA,EAAO,MAAA,IAChB,QAAA,CAAS,SAAA,EAAW,MAAA,CAAA;AAE5B;AAUO,SAAS,iBAAiB,QAAA,EAAuD;AACpF,EAAA,MAAM,KAA8B,EAAC;AAGrC,EAAA,IAAI,QAAA,CAAS,KAAA,EAAO,EAAA,CAAG,KAAA,GAAQ,QAAA,CAAS,KAAA;AACxC,EAAA,IAAI,SAAS,IAAA,EAAM,EAAA,CAAG,IAAA,GAAO,QAAA,CAAS,KAAK,WAAA,EAAY;AACvD,EAAA,IAAI,QAAA,CAAS,aAAA,EAAe,EAAA,CAAG,aAAA,GAAgB,QAAA,CAAS,aAAA;AACxD,EAAA,IAAI,QAAA,CAAS,QAAA,EAAU,EAAA,CAAG,QAAA,GAAW,QAAA,CAAS,QAAA;AAC9C,EAAA,IAAI,QAAA,CAAS,OAAA,EAAS,EAAA,CAAG,OAAA,GAAU,QAAA,CAAS,OAAA;AAC5C,EAAA,IAAI,QAAA,CAAS,SAAA,EAAW,EAAA,CAAG,SAAA,GAAY,QAAA,CAAS,SAAA;AAChD,EAAA,IAAI,QAAA,CAAS,QAAQ,QAAA,CAAS,IAAA,CAAK,SAAS,CAAA,EAAG,EAAA,CAAG,OAAO,QAAA,CAAS,IAAA;AAClE,EAAA,IAAI,QAAA,CAAS,UAAA,KAAe,MAAA,EAAW,EAAA,CAAG,aAAa,QAAA,CAAS,UAAA;AAGhE,EAAA,IAAI,QAAA,CAAS,OAAA,EAAS,EAAA,CAAG,OAAA,GAAU,QAAA,CAAS,OAAA;AAG5C,EAAA,IAAI,QAAA,CAAS,MAAA,EAAQ,EAAA,CAAG,MAAA,GAAS,QAAA,CAAS,MAAA;AAC1C,EAAA,IAAI,QAAA,CAAS,WAAW,QAAA,CAAS,OAAA,CAAQ,SAAS,CAAA,EAAG,EAAA,CAAG,UAAU,QAAA,CAAS,OAAA;AAC3E,EAAA,IAAI,QAAA,CAAS,SAAS,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,EAAG,EAAA,CAAG,QAAQ,QAAA,CAAS,KAAA;AAGrE,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,QAAQ,CAAA,EAAG;AAChC,IAAA,EAAA,CAAG,WAAW,QAAA,CAAS,QAAA;AAAA,EAC3B;AAEA,EAAA,OAAO,EAAA;AACX;AAOO,SAAS,mBAAA,CAAoB,UAA8B,IAAA,EAAsB;AACpF,EAAA,MAAM,WAAA,GAAc,iBAAiB,QAAQ,CAAA;AAG7C,EAAA,IAAI,SAAA,GAAY,oBAAoB,IAAI,CAAA;AAIxC,EAAA,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,WAAA,EAAa,EAAE,EAAE,IAAA,EAAK;AAIpD,EAAA,IAAI,SAAS,KAAA,EAAO;AAEhB,IAAA,MAAM,SAAA,GAAY,IAAI,MAAA,CAAO,CAAA,MAAA,EAAS,YAAY,QAAA,CAAS,KAAK,CAAC,CAAA,KAAA,CAAA,EAAS,GAAG,CAAA;AAC7E,IAAA,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,SAAA,EAAW,EAAE,EAAE,IAAA,EAAK;AAGlD,IAAA,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,WAAA,EAAa,EAAE,EAAE,IAAA,EAAK;AAAA,EACxD;AAIA,EAAA,OAAO,MAAA,CAAO,SAAA,CAAU,SAAA,GAAY,IAAA,EAAM,WAAW,CAAA;AACzD;AAKA,SAAS,YAAY,GAAA,EAAqB;AACtC,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,qBAAA,EAAuB,MAAM,CAAA;AACpD;AAMO,SAAS,gBAAA,CACZ,iBACA,OAAA,EAIM;AAEN,EAAA,MAAM,MAAA,GAAS,uBAAuB,eAAe,CAAA;AAGrD,EAAA,MAAM,WAAA,GAAkC;AAAA,IACpC,GAAG,MAAA,CAAO,QAAA;AAAA,IACV,GAAG,OAAA,CAAQ;AAAA,GACf;AAGA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,IAAQ,MAAA,CAAO,IAAA;AAGvC,EAAA,OAAO,mBAAA,CAAoB,aAAa,OAAO,CAAA;AACnD;;;;;;;;;;;;;;"}
|