crewly 1.20.293 → 1.20.295
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/config/hooks/agent-status/report.sh +11 -7
- package/config/roles/orchestrator/fragments/recovery.md +3 -0
- package/config/roles/orchestrator/prompt.md +3 -3
- package/config/roles/team-leader/tl-addon.md +6 -0
- package/config/skills/orchestrator/find-owner-for/SKILL.md +43 -0
- package/config/skills/orchestrator/find-owner-for/execute.sh +37 -0
- package/config/skills/orchestrator/team-roster/SKILL.md +44 -0
- package/config/skills/orchestrator/team-roster/execute.sh +27 -0
- package/config/skills/team-leader/update-charter/SKILL.md +48 -0
- package/config/skills/team-leader/update-charter/execute.sh +21 -0
- package/dist/backend/backend/src/constants.d.ts +63 -2
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +48 -2
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts +2 -0
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +18 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team-charter.controller.d.ts +20 -0
- package/dist/backend/backend/src/controllers/team/team-charter.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team/team-charter.controller.js +81 -0
- package/dist/backend/backend/src/controllers/team/team-charter.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts +1 -0
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +5 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js +3 -0
- package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/team-roster/team-roster.controller.d.ts +31 -0
- package/dist/backend/backend/src/controllers/team-roster/team-roster.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team-roster/team-roster.controller.js +68 -0
- package/dist/backend/backend/src/controllers/team-roster/team-roster.controller.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +14 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/models/Team.d.ts +3 -0
- package/dist/backend/backend/src/models/Team.d.ts.map +1 -1
- package/dist/backend/backend/src/models/Team.js +3 -0
- package/dist/backend/backend/src/models/Team.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +3 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts +1 -0
- package/dist/backend/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/resource-mode.service.js +4 -3
- package/dist/backend/backend/src/services/agent/resource-mode.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/index.d.ts +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/index.js +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/index.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.js +4 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +2 -2
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/team-roster.module.d.ts +44 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/team-roster.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/team-roster.module.js +61 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/team-roster.module.js.map +1 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +52 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +101 -29
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts +45 -0
- package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/deferred-start-retry.js +70 -0
- package/dist/backend/backend/src/services/messaging/deferred-start-retry.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +13 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +3 -2
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +8 -2
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/backend/backend/src/services/team-roster/team-roster.builder.d.ts +147 -0
- package/dist/backend/backend/src/services/team-roster/team-roster.builder.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-roster/team-roster.builder.js +492 -0
- package/dist/backend/backend/src/services/team-roster/team-roster.builder.js.map +1 -0
- package/dist/backend/backend/src/services/team-roster/team-roster.service.d.ts +79 -0
- package/dist/backend/backend/src/services/team-roster/team-roster.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/team-roster/team-roster.service.js +145 -0
- package/dist/backend/backend/src/services/team-roster/team-roster.service.js.map +1 -0
- package/dist/backend/backend/src/types/index.d.ts +12 -0
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +63 -2
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +48 -2
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/models/Team.d.ts +3 -0
- package/dist/cli/backend/src/models/Team.d.ts.map +1 -1
- package/dist/cli/backend/src/models/Team.js +3 -0
- package/dist/cli/backend/src/models/Team.js.map +1 -1
- package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts +1 -0
- package/dist/cli/backend/src/services/agent/resource-mode.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/resource-mode.service.js +4 -3
- package/dist/cli/backend/src/services/agent/resource-mode.service.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.js +4 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +2 -2
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/team-roster.module.d.ts +44 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/team-roster.module.d.ts.map +1 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/team-roster.module.js +61 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/team-roster.module.js.map +1 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +52 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +101 -29
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +13 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +3 -2
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +8 -2
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/cli/backend/src/services/team-roster/team-roster.builder.d.ts +147 -0
- package/dist/cli/backend/src/services/team-roster/team-roster.builder.d.ts.map +1 -0
- package/dist/cli/backend/src/services/team-roster/team-roster.builder.js +492 -0
- package/dist/cli/backend/src/services/team-roster/team-roster.builder.js.map +1 -0
- package/dist/cli/backend/src/services/team-roster/team-roster.service.d.ts +79 -0
- package/dist/cli/backend/src/services/team-roster/team-roster.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/team-roster/team-roster.service.js +145 -0
- package/dist/cli/backend/src/services/team-roster/team-roster.service.js.map +1 -0
- package/dist/cli/backend/src/types/index.d.ts +12 -0
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team roster builder (specs/2026-10-10-team-roster.md).
|
|
3
|
+
*
|
|
4
|
+
* Pure functions that turn the harness's own records (teams, projects,
|
|
5
|
+
* project tickets, WorkItems, Slack channel mappings) into a short roster of
|
|
6
|
+
* who owns what, render it under a token budget, and rank teams and members
|
|
7
|
+
* for a free-text owner request. No I/O and no LLM: the same input always
|
|
8
|
+
* gives the same roster, so every part is unit-testable.
|
|
9
|
+
*
|
|
10
|
+
* @module services/team-roster/team-roster.builder
|
|
11
|
+
*/
|
|
12
|
+
import { TEAM_ROSTER_CONSTANTS as C } from '../../constants.js';
|
|
13
|
+
import { getTeamLeads } from '../../utils/team.utils.js';
|
|
14
|
+
import { isTeamPausedNow, memberSessionKeys } from '../team/team-pause.registry.js';
|
|
15
|
+
import { tokenize } from '../wiki/wiki-search.service.js';
|
|
16
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
17
|
+
/** Whether a string holds real content. */
|
|
18
|
+
function nonEmpty(s) {
|
|
19
|
+
return typeof s === 'string' && s.trim().length > 0;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Collapse whitespace and cut to a length, marking the cut.
|
|
23
|
+
*
|
|
24
|
+
* @param text - Any text
|
|
25
|
+
* @param max - Longest result (chars)
|
|
26
|
+
* @returns One line of at most `max` chars
|
|
27
|
+
*/
|
|
28
|
+
export function clip(text, max) {
|
|
29
|
+
const one = text.replace(/\s+/g, ' ').trim();
|
|
30
|
+
if (one.length <= max)
|
|
31
|
+
return one;
|
|
32
|
+
return `${one.slice(0, Math.max(1, max - 1)).trimEnd()}…`;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Strip the leading `[Tag]` the harness puts on request-born titles.
|
|
36
|
+
*
|
|
37
|
+
* @param title - Raw title
|
|
38
|
+
* @returns Title without a leading bracket tag
|
|
39
|
+
*/
|
|
40
|
+
function cleanTitle(title) {
|
|
41
|
+
return title.replace(/^\s*\[[^\]]{1,24}\]\s*/, '').trim() || title.trim();
|
|
42
|
+
}
|
|
43
|
+
/** Sessions a member answers to (live, permanent and derived). */
|
|
44
|
+
function sessionsOf(teamName, m) {
|
|
45
|
+
return memberSessionKeys(teamName, m).filter(nonEmpty);
|
|
46
|
+
}
|
|
47
|
+
/** What a member's brief says it is good at: "Strengths: …", "Focus: …", else its job description. */
|
|
48
|
+
function focusOf(m) {
|
|
49
|
+
if (nonEmpty(m.jobDescription))
|
|
50
|
+
return clip(m.jobDescription, 60);
|
|
51
|
+
const hit = /(?:strengths?|specializ\w*|focus(?:es)?|expertise)\s*[:\-—]\s*([^.\n]{8,})/i.exec(m.systemPrompt ?? '');
|
|
52
|
+
return hit ? clip(hit[1], 60) : undefined;
|
|
53
|
+
}
|
|
54
|
+
/** Member specialties: owned domains, job title, skill tags, then its stated focus (deduped, capped). */
|
|
55
|
+
function specialtiesOf(m) {
|
|
56
|
+
const raw = [...(m.ownershipScope?.domains ?? []), m.jobTitle, ...(m.skills ?? m.capabilities ?? []), focusOf(m)];
|
|
57
|
+
const seen = new Set();
|
|
58
|
+
const out = [];
|
|
59
|
+
for (const s of raw) {
|
|
60
|
+
if (!nonEmpty(s))
|
|
61
|
+
continue;
|
|
62
|
+
const v = s.trim();
|
|
63
|
+
const k = v.toLowerCase();
|
|
64
|
+
if (seen.has(k) || k === String(m.role).toLowerCase())
|
|
65
|
+
continue;
|
|
66
|
+
seen.add(k);
|
|
67
|
+
out.push(v);
|
|
68
|
+
}
|
|
69
|
+
return out.slice(0, C.MAX_SPECIALTIES);
|
|
70
|
+
}
|
|
71
|
+
/** Whether a WorkItem was born from a recurring trigger or cron. */
|
|
72
|
+
function isRoutine(wi) {
|
|
73
|
+
const origin = wi.metadata?.origin;
|
|
74
|
+
return origin?.kind === 'trigger' || origin?.kind === 'cron';
|
|
75
|
+
}
|
|
76
|
+
/** WorkItem types that carry the harness's own bookkeeping, not work anyone asked for. */
|
|
77
|
+
const CHORE_TYPES = new Set(['review', 'goal_replan', 'autopilot_self_review']);
|
|
78
|
+
/** Titles of harness chores that are plain `delegate` items. */
|
|
79
|
+
const CHORE_TITLE = /^\s*(watch:|retry \d+\/\d+:|verify:|refresh standing answer|follow-up for the owner|went quiet on|fallback check|autopilot retro|self-review:|plan next tickets)/i;
|
|
80
|
+
/**
|
|
81
|
+
* Whether a WorkItem is harness bookkeeping (verification, retries, follow-up
|
|
82
|
+
* nudges, standing-answer refreshes, watchers). These are not what a team is
|
|
83
|
+
* "working on" and would drown the real titles.
|
|
84
|
+
*
|
|
85
|
+
* @param wi - WorkItem
|
|
86
|
+
* @returns True for a chore
|
|
87
|
+
*/
|
|
88
|
+
function isChore(wi) {
|
|
89
|
+
if (wi.type && CHORE_TYPES.has(String(wi.type)))
|
|
90
|
+
return true;
|
|
91
|
+
if (wi.parentWorkItemId || wi.owner === 'system')
|
|
92
|
+
return true;
|
|
93
|
+
if (wi.metadata?.openItemFollowUp !== undefined)
|
|
94
|
+
return true;
|
|
95
|
+
return CHORE_TITLE.test(wi.title);
|
|
96
|
+
}
|
|
97
|
+
/** The ticket id a WorkItem works on, when it has one. */
|
|
98
|
+
function linkedTicketId(wi) {
|
|
99
|
+
const link = wi.metadata?.projectTicket;
|
|
100
|
+
if (typeof link?.id === 'string')
|
|
101
|
+
return link.id.toLowerCase();
|
|
102
|
+
return nonEmpty(wi.projectTaskId) ? wi.projectTaskId.toLowerCase() : null;
|
|
103
|
+
}
|
|
104
|
+
const OPEN_WI = new Set(['queued', 'scheduled', 'proposed', 'accepted', 'running', 'blocked', 'escalated', 'done_by_worker']);
|
|
105
|
+
const DONE_WI = new Set(['verified', 'done']);
|
|
106
|
+
const OPEN_TICKET = new Set(['in_progress', 'review', 'ready']);
|
|
107
|
+
/** Lower sorts first: what is moving now comes before what waits. */
|
|
108
|
+
const OPEN_RANK = { in_progress: 0, running: 0, review: 1, done_by_worker: 1, blocked: 2, escalated: 2, accepted: 3, proposed: 3, ready: 4, queued: 4, scheduled: 5 };
|
|
109
|
+
/**
|
|
110
|
+
* Derive a charter for a team that has none, from what is known about it.
|
|
111
|
+
*
|
|
112
|
+
* @param team - The team
|
|
113
|
+
* @param roles - Distinct member roles
|
|
114
|
+
* @param projects - Project names
|
|
115
|
+
* @param titles - Recent work titles
|
|
116
|
+
* @returns A one-or-two-line charter
|
|
117
|
+
*/
|
|
118
|
+
function deriveCharter(team, roles, projects, titles) {
|
|
119
|
+
const parts = [nonEmpty(team.description) ? team.description.trim() : `${team.name} team`];
|
|
120
|
+
if (roles.length)
|
|
121
|
+
parts.push(`roles: ${roles.join(', ')}`);
|
|
122
|
+
if (projects.length)
|
|
123
|
+
parts.push(`projects: ${projects.join(', ')}`);
|
|
124
|
+
if (titles.length)
|
|
125
|
+
parts.push(`recent work: ${titles.slice(0, 3).map((t) => clip(cleanTitle(t), 50)).join('; ')}`);
|
|
126
|
+
return `${parts.join(' — ')}.`;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Build the roster from the harness's records.
|
|
130
|
+
*
|
|
131
|
+
* Charter precedence: the lead's `charter`, then `description` (when it says
|
|
132
|
+
* something), then one derived from roles, projects and recent titles. Work
|
|
133
|
+
* is attributed to a team by ticket `team`, assignee session, WorkItem target
|
|
134
|
+
* session or `metadata.teamId`; a ticket with no owner goes to the only team
|
|
135
|
+
* on its project. Recurring-trigger runs are counted, not listed.
|
|
136
|
+
*
|
|
137
|
+
* @param src - Records and the clock
|
|
138
|
+
* @returns One entry per live team, busiest first
|
|
139
|
+
*/
|
|
140
|
+
export function buildRoster(src) {
|
|
141
|
+
const live = src.teams.filter((t) => !t.archived && nonEmpty(t.name));
|
|
142
|
+
const projectById = new Map(src.projects.map((p) => [p.id, p]));
|
|
143
|
+
const teamById = new Map(live.map((t) => [t.id, t]));
|
|
144
|
+
const sessionToTeam = new Map();
|
|
145
|
+
const sessionToName = new Map();
|
|
146
|
+
for (const t of live) {
|
|
147
|
+
for (const m of t.members ?? []) {
|
|
148
|
+
for (const s of sessionsOf(t.name, m)) {
|
|
149
|
+
sessionToTeam.set(s, t);
|
|
150
|
+
sessionToName.set(s, m.name);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const teamsOnProject = new Map();
|
|
155
|
+
for (const t of live) {
|
|
156
|
+
for (const pid of t.projectIds ?? []) {
|
|
157
|
+
const p = projectById.get(pid);
|
|
158
|
+
if (!p)
|
|
159
|
+
continue;
|
|
160
|
+
const list = teamsOnProject.get(p.path) ?? [];
|
|
161
|
+
list.push(t);
|
|
162
|
+
teamsOnProject.set(p.path, list);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const byNameLower = new Map(live.map((t) => [t.name.toLowerCase(), t]));
|
|
166
|
+
const now = src.now.getTime();
|
|
167
|
+
const recentSince = now - C.RECENT_DAYS * DAY_MS;
|
|
168
|
+
const historySince = now - C.MATCH_HISTORY_DAYS * DAY_MS;
|
|
169
|
+
const time = (iso) => {
|
|
170
|
+
const n = iso ? Date.parse(iso) : NaN;
|
|
171
|
+
return Number.isFinite(n) ? n : 0;
|
|
172
|
+
};
|
|
173
|
+
const acc = new Map();
|
|
174
|
+
const slot = (t) => {
|
|
175
|
+
let a = acc.get(t.id);
|
|
176
|
+
if (!a) {
|
|
177
|
+
a = { open: [], done: [], history: [], routine: 0, backlog: 0 };
|
|
178
|
+
acc.set(t.id, a);
|
|
179
|
+
}
|
|
180
|
+
return a;
|
|
181
|
+
};
|
|
182
|
+
const ticketTeam = new Map();
|
|
183
|
+
for (const tk of src.tickets) {
|
|
184
|
+
const owner = (tk.team ? teamById.get(tk.team) ?? byNameLower.get(tk.team.toLowerCase()) : undefined) ??
|
|
185
|
+
(tk.assignee ? sessionToTeam.get(tk.assignee) : undefined) ??
|
|
186
|
+
(() => { const only = teamsOnProject.get(tk.projectPath); return only && only.length === 1 ? only[0] : undefined; })();
|
|
187
|
+
if (!owner)
|
|
188
|
+
continue;
|
|
189
|
+
ticketTeam.set(`${tk.projectPath}\0${tk.id.toLowerCase()}`, owner);
|
|
190
|
+
ticketTeam.set(tk.id.toLowerCase(), owner);
|
|
191
|
+
const a = slot(owner);
|
|
192
|
+
const at = tk.updatedAt;
|
|
193
|
+
const work = { ref: tk.id, title: clip(cleanTitle(tk.title), C.TITLE_MAX_CHARS), status: tk.status, who: tk.assignee ? sessionToName.get(tk.assignee) ?? tk.assignee : undefined, at };
|
|
194
|
+
if (OPEN_TICKET.has(tk.status))
|
|
195
|
+
a.open.push(work);
|
|
196
|
+
else if (tk.status === 'backlog')
|
|
197
|
+
a.backlog++;
|
|
198
|
+
else if (tk.status === 'done' && time(at) >= recentSince)
|
|
199
|
+
a.done.push(work);
|
|
200
|
+
if (tk.status !== 'cancelled' && time(at) >= historySince)
|
|
201
|
+
a.history.push(cleanTitle(tk.title));
|
|
202
|
+
}
|
|
203
|
+
for (const wi of src.workItems) {
|
|
204
|
+
const meta = (wi.metadata ?? {});
|
|
205
|
+
const owner = (wi.target ? sessionToTeam.get(wi.target) : undefined) ??
|
|
206
|
+
(typeof meta.teamId === 'string' ? teamById.get(meta.teamId) : undefined);
|
|
207
|
+
if (!owner)
|
|
208
|
+
continue;
|
|
209
|
+
const a = slot(owner);
|
|
210
|
+
const at = wi.completedAt ?? wi.statusChangedAt ?? wi.createdAt;
|
|
211
|
+
if (isChore(wi))
|
|
212
|
+
continue;
|
|
213
|
+
if (isRoutine(wi)) {
|
|
214
|
+
if (time(at) >= recentSince || OPEN_WI.has(wi.status))
|
|
215
|
+
a.routine++;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const tid = linkedTicketId(wi);
|
|
219
|
+
if (tid && ticketTeam.has(tid))
|
|
220
|
+
continue; // the ticket already stands for it
|
|
221
|
+
const work = { ref: wi.id.slice(0, 8), title: clip(cleanTitle(wi.title), C.TITLE_MAX_CHARS), status: wi.status, who: wi.target ? sessionToName.get(wi.target) : undefined, at };
|
|
222
|
+
if (OPEN_WI.has(wi.status))
|
|
223
|
+
a.open.push(work);
|
|
224
|
+
else if (DONE_WI.has(wi.status) && time(at) >= recentSince)
|
|
225
|
+
a.done.push(work);
|
|
226
|
+
if (wi.status !== 'cancelled' && wi.status !== 'rejected' && time(at) >= historySince)
|
|
227
|
+
a.history.push(cleanTitle(wi.title));
|
|
228
|
+
}
|
|
229
|
+
const rows = live.map((team) => {
|
|
230
|
+
const a = acc.get(team.id) ?? { open: [], done: [], history: [], routine: 0, backlog: 0 };
|
|
231
|
+
a.open.sort((x, y) => (OPEN_RANK[x.status] ?? 9) - (OPEN_RANK[y.status] ?? 9) || time(y.at) - time(x.at));
|
|
232
|
+
a.done.sort((x, y) => time(y.at) - time(x.at));
|
|
233
|
+
const leadMembers = getTeamLeads(team);
|
|
234
|
+
const leadIds = new Set(leadMembers.map((m) => m.id));
|
|
235
|
+
const members = (team.members ?? []).map((m) => ({
|
|
236
|
+
name: m.name,
|
|
237
|
+
role: String(m.role),
|
|
238
|
+
isLead: leadIds.has(m.id),
|
|
239
|
+
specialties: specialtiesOf(m),
|
|
240
|
+
session: m.agentId || m.sessionName || '',
|
|
241
|
+
about: clip(m.systemPrompt ?? '', 300),
|
|
242
|
+
}));
|
|
243
|
+
const projects = (team.projectIds ?? []).map((id) => projectById.get(id)?.name).filter(nonEmpty);
|
|
244
|
+
const roles = [...new Set(members.map((m) => m.role))];
|
|
245
|
+
const workTitles = [...a.open, ...a.done].map((w) => w.title);
|
|
246
|
+
let charter;
|
|
247
|
+
let charterSource;
|
|
248
|
+
if (nonEmpty(team.charter)) {
|
|
249
|
+
charter = team.charter.trim();
|
|
250
|
+
charterSource = 'lead';
|
|
251
|
+
}
|
|
252
|
+
else if (nonEmpty(team.description) && tokenize(team.description).length >= C.MIN_DESCRIPTION_TOKENS) {
|
|
253
|
+
charter = team.description.trim();
|
|
254
|
+
charterSource = 'description';
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
charter = deriveCharter(team, roles, projects, workTitles.length ? workTitles : a.history);
|
|
258
|
+
charterSource = 'derived';
|
|
259
|
+
}
|
|
260
|
+
const scope = team.ownershipScope?.domains?.length ? ` Owns: ${team.ownershipScope.domains.join(', ')}.` : '';
|
|
261
|
+
const takes = team.serviceContract?.accepts?.length ? ` Takes: ${team.serviceContract.accepts.join('; ')}.` : '';
|
|
262
|
+
const avoids = team.serviceContract?.avoids?.length ? ` Avoids: ${team.serviceContract.avoids.join('; ')}.` : '';
|
|
263
|
+
const mission = nonEmpty(team.mission) && !charter.includes(team.mission.trim()) ? ` Mission: ${team.mission.trim()}` : '';
|
|
264
|
+
return {
|
|
265
|
+
id: team.id,
|
|
266
|
+
name: team.name,
|
|
267
|
+
parent: team.parentTeamId ? teamById.get(team.parentTeamId)?.name : undefined,
|
|
268
|
+
charter: `${charter}${scope}${takes}${avoids}${mission}`.replace(/\s+/g, ' ').trim(),
|
|
269
|
+
charterSource,
|
|
270
|
+
leads: leadMembers.map((m) => m.name),
|
|
271
|
+
members,
|
|
272
|
+
projects,
|
|
273
|
+
channel: src.channels?.get(team.id),
|
|
274
|
+
paused: isTeamPausedNow(team, now),
|
|
275
|
+
open: a.open,
|
|
276
|
+
recentDone: a.done,
|
|
277
|
+
routineRuns: a.routine,
|
|
278
|
+
backlog: a.backlog,
|
|
279
|
+
history: a.history,
|
|
280
|
+
};
|
|
281
|
+
});
|
|
282
|
+
const activity = (r) => r.open.length * 2 + r.recentDone.length;
|
|
283
|
+
return rows.sort((x, y) => activity(y) - activity(x) || x.name.localeCompare(y.name));
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Token estimate that counts each CJK character as a token (the plain
|
|
287
|
+
* 4-chars-per-token rule undercounts Chinese and Japanese several times over).
|
|
288
|
+
*
|
|
289
|
+
* @param text - Any text
|
|
290
|
+
* @returns Estimated tokens
|
|
291
|
+
*/
|
|
292
|
+
export function estimateRosterTokens(text) {
|
|
293
|
+
let cjk = 0;
|
|
294
|
+
for (const ch of text)
|
|
295
|
+
if (/[-ヿ㐀-䶿一-鿿豈-]/.test(ch))
|
|
296
|
+
cjk++;
|
|
297
|
+
return cjk + Math.ceil((text.length - cjk) / 4);
|
|
298
|
+
}
|
|
299
|
+
/** Render one team under a detail tier. */
|
|
300
|
+
function renderTeam(t, tier) {
|
|
301
|
+
const lead = t.leads.length ? ` — lead ${t.leads.join(' & ')}` : '';
|
|
302
|
+
const head = `### ${t.name}${lead}${t.channel ? ` · #${t.channel}` : ''}${t.paused ? ' · PAUSED (owner): do not hand it work' : ''}`;
|
|
303
|
+
const mark = t.charterSource === 'derived' ? ' (derived; the lead has not written a charter)' : '';
|
|
304
|
+
const lines = [head, `${clip(t.charter, tier.charter)}${mark}`];
|
|
305
|
+
const members = t.members
|
|
306
|
+
.map((m) => (tier.specialties && m.specialties.length ? `${m.name} (${m.role}: ${m.specialties.join(', ')})` : `${m.name} (${m.role})`))
|
|
307
|
+
.join('; ');
|
|
308
|
+
if (members)
|
|
309
|
+
lines.push(`Members: ${members}`);
|
|
310
|
+
if (t.projects.length)
|
|
311
|
+
lines.push(`Projects: ${t.projects.join(', ')}`);
|
|
312
|
+
const fmt = (w) => `${w.ref} ${w.title}${w.who ? ` [${w.who}]` : ''}`;
|
|
313
|
+
if (tier.open > 0 && t.open.length) {
|
|
314
|
+
const more = t.open.length - tier.open;
|
|
315
|
+
lines.push(`Now: ${t.open.slice(0, tier.open).map(fmt).join('; ')}${more > 0 ? ` (+${more} more)` : ''}`);
|
|
316
|
+
}
|
|
317
|
+
if (tier.done > 0 && t.recentDone.length) {
|
|
318
|
+
const more = t.recentDone.length - tier.done;
|
|
319
|
+
lines.push(`Done ${C.RECENT_DAYS}d: ${t.recentDone.slice(0, tier.done).map(fmt).join('; ')}${more > 0 ? ` (+${more} more)` : ''}`);
|
|
320
|
+
}
|
|
321
|
+
if (tier.open === 0) {
|
|
322
|
+
const bits = [t.open.length ? `${t.open.length} open` : '', t.recentDone.length ? `${t.recentDone.length} done in ${C.RECENT_DAYS}d` : ''].filter(Boolean);
|
|
323
|
+
if (bits.length)
|
|
324
|
+
lines.push(`Work: ${bits.join(', ')}`);
|
|
325
|
+
}
|
|
326
|
+
return lines.join('\n');
|
|
327
|
+
}
|
|
328
|
+
const ROSTER_INTRO = `${C.HEADING}
|
|
329
|
+
|
|
330
|
+
Generated from live team records. Charters marked (derived) were not written by a lead, and a plain description can be dated: trust the Now / Done lines over them. Route an owner request to the team whose charter, members or current work fits it; if the owner names nobody, pick the team yourself and tell the owner in one line whom you handed it to. Ask the owner only when two teams are equally plausible. For "what is the status of X", ask the owning team's lead (or the member shown) instead of guessing. Run \`find-owner-for "<request>"\` to rank teams, \`team-roster\` for the full list.`;
|
|
331
|
+
/**
|
|
332
|
+
* Render the roster under a token budget. The richest detail tier that fits
|
|
333
|
+
* wins; when even the leanest does not, the least active teams drop to a
|
|
334
|
+
* name-only line.
|
|
335
|
+
*
|
|
336
|
+
* @param teams - Roster from {@link buildRoster}
|
|
337
|
+
* @param maxTokens - Budget (defaults to the prompt budget)
|
|
338
|
+
* @returns Markdown, or '' when there are no teams
|
|
339
|
+
*/
|
|
340
|
+
export function renderRoster(teams, maxTokens = C.PROMPT_MAX_TOKENS) {
|
|
341
|
+
if (teams.length === 0)
|
|
342
|
+
return '';
|
|
343
|
+
const build = (tier, shown, rest) => {
|
|
344
|
+
const tail = rest.length ? `\n\n_Not detailed (budget): ${rest.map((t) => t.name).join(', ')} — run \`team-roster\`._` : '';
|
|
345
|
+
return `${ROSTER_INTRO}\n\n${shown.map((t) => renderTeam(t, tier)).join('\n\n')}${tail}`;
|
|
346
|
+
};
|
|
347
|
+
for (const tier of C.TIERS) {
|
|
348
|
+
const md = build(tier, teams, []);
|
|
349
|
+
if (estimateRosterTokens(md) <= maxTokens)
|
|
350
|
+
return md;
|
|
351
|
+
}
|
|
352
|
+
const lean = C.TIERS[C.TIERS.length - 1];
|
|
353
|
+
for (let keep = teams.length - 1; keep >= 1; keep--) {
|
|
354
|
+
const md = build(lean, teams.slice(0, keep), teams.slice(keep));
|
|
355
|
+
if (estimateRosterTokens(md) <= maxTokens)
|
|
356
|
+
return md;
|
|
357
|
+
}
|
|
358
|
+
return build(lean, teams.slice(0, 1), teams.slice(1));
|
|
359
|
+
}
|
|
360
|
+
const BM25_K1 = 1.2;
|
|
361
|
+
const BM25_B = 0.75;
|
|
362
|
+
/** A Latin query word also matches longer document words that start with it. */
|
|
363
|
+
function matches(docToken, q) {
|
|
364
|
+
if (docToken === q)
|
|
365
|
+
return true;
|
|
366
|
+
return q.length >= 3 && /^[a-z0-9]+$/.test(q) && docToken.startsWith(q);
|
|
367
|
+
}
|
|
368
|
+
/** Weighted bag of tokens: each field counts `weight` times. */
|
|
369
|
+
function makeDoc(key, fields) {
|
|
370
|
+
const tokens = [];
|
|
371
|
+
for (const [text, weight] of fields) {
|
|
372
|
+
if (!nonEmpty(text))
|
|
373
|
+
continue;
|
|
374
|
+
const toks = tokenize(text);
|
|
375
|
+
for (let i = 0; i < weight; i++)
|
|
376
|
+
tokens.push(...toks);
|
|
377
|
+
}
|
|
378
|
+
return { key, tokens };
|
|
379
|
+
}
|
|
380
|
+
/** BM25 over a small in-memory corpus. Returns a score and matched query words per doc. */
|
|
381
|
+
function bm25(docs, query) {
|
|
382
|
+
const out = new Map();
|
|
383
|
+
if (docs.length === 0 || query.length === 0)
|
|
384
|
+
return out;
|
|
385
|
+
const avgdl = docs.reduce((s, d) => s + d.tokens.length, 0) / docs.length || 1;
|
|
386
|
+
const freq = (d, q) => {
|
|
387
|
+
let n = 0;
|
|
388
|
+
for (const t of d.tokens)
|
|
389
|
+
if (matches(t, q))
|
|
390
|
+
n++;
|
|
391
|
+
return n;
|
|
392
|
+
};
|
|
393
|
+
for (const q of query) {
|
|
394
|
+
const containing = docs.filter((d) => freq(d, q) > 0).length;
|
|
395
|
+
const idf = Math.log(1 + (docs.length - containing + 0.5) / (containing + 0.5));
|
|
396
|
+
for (const d of docs) {
|
|
397
|
+
const f = freq(d, q);
|
|
398
|
+
if (f === 0)
|
|
399
|
+
continue;
|
|
400
|
+
const part = idf * ((f * (BM25_K1 + 1)) / (f + BM25_K1 * (1 - BM25_B + (BM25_B * d.tokens.length) / avgdl)));
|
|
401
|
+
const cur = out.get(d.key) ?? { score: 0, matched: new Set() };
|
|
402
|
+
cur.score += part;
|
|
403
|
+
cur.matched.add(q);
|
|
404
|
+
out.set(d.key, cur);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return out;
|
|
408
|
+
}
|
|
409
|
+
/** Words too common to say anything about who owns a request (English function words and request verbs). */
|
|
410
|
+
const STOP = new Set([
|
|
411
|
+
'a', 'an', 'the', 'and', 'or', 'but', 'for', 'with', 'that', 'this', 'these', 'those', 'from', 'to', 'of', 'in', 'on', 'at', 'by', 'as', 'is', 'are', 'was', 'were', 'be', 'been', 'it', 'its',
|
|
412
|
+
'i', 'we', 'you', 'he', 'she', 'they', 'me', 'us', 'my', 'our', 'your', 'their', 'do', 'does', 'did', 'done', 'can', 'could', 'would', 'should', 'will', 'please', 'want', 'need', 'make',
|
|
413
|
+
'get', 'have', 'has', 'how', 'what', 'why', 'when', 'where', 'who', 'which', 'about', 'any', 'new', 'into', 'out', 'up', 'not', 'no', 'so', 'if', 'then', 'help', 'check', 'look', 'status',
|
|
414
|
+
'update', 'asked', 'ask', 'tell', 'let', 'just', 'now', 'today', 'all', 'some', 'one', 'also',
|
|
415
|
+
]);
|
|
416
|
+
/** CJK function characters that match everything and mean nothing on their own. */
|
|
417
|
+
const CJK_STOP = new Set([...'的了是在我你他她它们这那有和与及或吗呢吧啊嗯一下到做查看个把被让给对从就也都还要会能可以为请帮想来去上中里什么怎么哪谁']);
|
|
418
|
+
/** Work titles per team that feed matching: enough to show the focus, too few to swamp the charter. */
|
|
419
|
+
const MATCH_TITLES = 25;
|
|
420
|
+
/** Titles of a team's open and recently finished work, newest first, capped. */
|
|
421
|
+
function recentTitles(t) {
|
|
422
|
+
return [...t.open, ...t.recentDone].slice(0, MATCH_TITLES).map((w) => w.title);
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Rank teams (and the member within each) for a free-text owner request.
|
|
426
|
+
*
|
|
427
|
+
* BM25 over each team's charter, name, projects, member roles and specialties
|
|
428
|
+
* and recent work titles, plus a flat boost when the request names a member
|
|
429
|
+
* or team outright. The hand-off target is the team lead (the rule for new
|
|
430
|
+
* work); `likelyDoer` names the member whose own work or skills fit best.
|
|
431
|
+
*
|
|
432
|
+
* @param teams - Roster from {@link buildRoster}
|
|
433
|
+
* @param request - What the owner asked for
|
|
434
|
+
* @param limit - Candidates to return
|
|
435
|
+
* @returns Best first; empty when nothing matches
|
|
436
|
+
*/
|
|
437
|
+
export function findOwnersFor(teams, request, limit = C.FIND_DEFAULT_LIMIT) {
|
|
438
|
+
const text = request.slice(0, C.QUERY_MAX_CHARS);
|
|
439
|
+
const query = [...new Set(tokenize(text))].filter((t) => !STOP.has(t) && !CJK_STOP.has(t));
|
|
440
|
+
if (query.length === 0 || teams.length === 0)
|
|
441
|
+
return [];
|
|
442
|
+
const lower = text.toLowerCase();
|
|
443
|
+
const capped = Math.max(1, Math.min(limit, C.FIND_MAX_LIMIT));
|
|
444
|
+
const teamDocs = teams.map((t) => makeDoc(t.id, [
|
|
445
|
+
[t.name, 3],
|
|
446
|
+
[t.charter, 4],
|
|
447
|
+
[t.projects.join(' '), 2],
|
|
448
|
+
[t.members.map((m) => `${m.role} ${m.specialties.join(' ')}`).join(' '), 3],
|
|
449
|
+
[t.members.map((m) => m.about).join(' '), 1],
|
|
450
|
+
[recentTitles(t).join(' '), 1],
|
|
451
|
+
[t.history.slice(0, MATCH_TITLES).join(' '), 1],
|
|
452
|
+
[t.channel, 1],
|
|
453
|
+
]));
|
|
454
|
+
const scores = bm25(teamDocs, query);
|
|
455
|
+
const ranked = teams
|
|
456
|
+
.map((t) => {
|
|
457
|
+
const s = scores.get(t.id);
|
|
458
|
+
const named = lower.includes(t.name.toLowerCase()) || t.members.some((m) => m.name.length >= 3 && new RegExp(`\\b${m.name.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(lower));
|
|
459
|
+
return { t, score: (s?.score ?? 0) + (named ? C.NAME_MATCH_BOOST : 0), matched: s?.matched ?? new Set() };
|
|
460
|
+
})
|
|
461
|
+
.filter((r) => r.score > 0)
|
|
462
|
+
.sort((a, b) => b.score - a.score || a.t.name.localeCompare(b.t.name));
|
|
463
|
+
if (ranked.length === 0)
|
|
464
|
+
return [];
|
|
465
|
+
const best = ranked[0].score;
|
|
466
|
+
return ranked.slice(0, capped).map((r, i) => {
|
|
467
|
+
const memberDocs = r.t.members.map((m) => makeDoc(m.name, [
|
|
468
|
+
[m.name, 4],
|
|
469
|
+
[m.role, 2],
|
|
470
|
+
[m.specialties.join(' '), 3],
|
|
471
|
+
[m.about, 1],
|
|
472
|
+
[[...r.t.open, ...r.t.recentDone].filter((w) => w.who === m.name).slice(0, MATCH_TITLES).map((w) => w.title).join(' '), 1],
|
|
473
|
+
]));
|
|
474
|
+
const ms = bm25(memberDocs, query);
|
|
475
|
+
const top = [...ms.entries()].sort((a, b) => b[1].score - a[1].score)[0];
|
|
476
|
+
const lead = r.t.leads[0];
|
|
477
|
+
const doer = top && top[1].score > 0 && top[0] !== lead ? top[0] : undefined;
|
|
478
|
+
const rival = i === 0 ? ranked[1] : undefined;
|
|
479
|
+
return {
|
|
480
|
+
team: r.t.name,
|
|
481
|
+
teamId: r.t.id,
|
|
482
|
+
handTo: lead ?? top?.[0] ?? r.t.members[0]?.name ?? r.t.name,
|
|
483
|
+
likelyDoer: doer,
|
|
484
|
+
score: Math.round(r.score * 100) / 100,
|
|
485
|
+
matched: [...r.matched].sort(),
|
|
486
|
+
paused: r.t.paused,
|
|
487
|
+
ambiguous: i === 0 ? Boolean(rival && rival.score >= best * C.AMBIGUOUS_SCORE_RATIO) : r.score >= best * C.AMBIGUOUS_SCORE_RATIO,
|
|
488
|
+
charterSource: r.t.charterSource,
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
//# sourceMappingURL=team-roster.builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-roster.builder.js","sourceRoot":"","sources":["../../../../../../backend/src/services/team-roster/team-roster.builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,qBAAqB,IAAI,CAAC,EAAE,MAAM,oBAAoB,CAAC;AAIhE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE1D,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAyEnC,2CAA2C;AAC3C,SAAS,QAAQ,CAAC,CAA4B;IAC7C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,GAAW;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IAClC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAAC,KAAa;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;AAC3E,CAAC;AAED,kEAAkE;AAClE,SAAS,UAAU,CAAC,QAAgB,EAAE,CAAa;IAClD,OAAO,iBAAiB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,sGAAsG;AACtG,SAAS,OAAO,CAAC,CAAa;IAC7B,IAAI,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,6EAA6E,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IACrH,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAED,yGAAyG;AACzG,SAAS,aAAa,CAAC,CAAa;IACnC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAClH,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS;QAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;YAAE,SAAS;QAChE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACZ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACb,CAAC;IACD,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;AACxC,CAAC;AAED,oEAAoE;AACpE,SAAS,SAAS,CAAC,EAAkB;IACpC,MAAM,MAAM,GAAI,EAAE,CAAC,QAAwD,EAAE,MAAM,CAAC;IACpF,OAAO,MAAM,EAAE,IAAI,KAAK,SAAS,IAAI,MAAM,EAAE,IAAI,KAAK,MAAM,CAAC;AAC9D,CAAC;AAED,0FAA0F;AAC1F,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,uBAAuB,CAAC,CAAC,CAAC;AAChF,gEAAgE;AAChE,MAAM,WAAW,GAAG,mKAAmK,CAAC;AAExL;;;;;;;GAOG;AACH,SAAS,OAAO,CAAC,EAAkB;IAClC,IAAI,EAAE,CAAC,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,IAAI,EAAE,CAAC,gBAAgB,IAAI,EAAE,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC9D,IAAK,EAAE,CAAC,QAAuD,EAAE,gBAAgB,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC7G,OAAO,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED,0DAA0D;AAC1D,SAAS,cAAc,CAAC,EAAkB;IACzC,MAAM,IAAI,GAAI,EAAE,CAAC,QAA6D,EAAE,aAAa,CAAC;IAC9F,IAAI,OAAO,IAAI,EAAE,EAAE,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/D,OAAO,QAAQ,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3E,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAC9H,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AAC9C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAChE,qEAAqE;AACrE,MAAM,SAAS,GAA2B,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAE9L;;;;;;;;GAQG;AACH,SAAS,aAAa,CAAC,IAAU,EAAE,KAAe,EAAE,QAAkB,EAAE,MAAgB;IACvF,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC;IAC3F,IAAI,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3D,IAAI,QAAQ,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpE,IAAI,MAAM,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnH,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAChC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,GAAkB;IAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAgB,CAAC;IAC9C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACjC,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBACvC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACxB,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;QACF,CAAC;IACF,CAAC;IACD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YACtC,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACb,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;IACF,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAExE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAG,GAAG,GAAG,CAAC,CAAC,WAAW,GAAG,MAAM,CAAC;IACjD,MAAM,YAAY,GAAG,GAAG,GAAG,CAAC,CAAC,kBAAkB,GAAG,MAAM,CAAC;IACzD,MAAM,IAAI,GAAG,CAAC,GAAuB,EAAU,EAAE;QAChD,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC;IAGF,MAAM,GAAG,GAAG,IAAI,GAAG,EAAe,CAAC;IACnC,MAAM,IAAI,GAAG,CAAC,CAAO,EAAO,EAAE;QAC7B,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtB,IAAI,CAAC,CAAC,EAAE,CAAC;YAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAAC,CAAC;QAC9F,OAAO,CAAC,CAAC;IACV,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAgB,CAAC;IAC3C,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,KAAK,GACV,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACvF,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC1D,CAAC,GAAG,EAAE,GAAG,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxH,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,KAAK,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QACnE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC;QACxB,MAAM,IAAI,GAAe,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC;QACnM,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;YAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC7C,IAAI,EAAE,CAAC,MAAM,KAAK,SAAS;YAAE,CAAC,CAAC,OAAO,EAAE,CAAC;aACzC,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,WAAW;YAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5E,IAAI,EAAE,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,YAAY;YAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACjG,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAyB,CAAC;QACzD,MAAM,KAAK,GACV,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACtD,CAAC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC3E,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,eAAe,IAAI,EAAE,CAAC,SAAS,CAAC;QAChE,IAAI,OAAO,CAAC,EAAE,CAAC;YAAE,SAAS;QAC1B,IAAI,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;YACnB,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;gBAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACnE,SAAS;QACV,CAAC;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,mCAAmC;QAC7E,MAAM,IAAI,GAAe,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC;QAC5L,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;YAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACzC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,WAAW;YAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9E,IAAI,EAAE,CAAC,MAAM,KAAK,WAAW,IAAI,EAAE,CAAC,MAAM,KAAK,UAAU,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,YAAY;YAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7H,CAAC;IAED,MAAM,IAAI,GAAiB,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QAC1F,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1G,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,MAAM,OAAO,GAAmB,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChE,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;YACpB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACzB,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;YAC7B,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,WAAW,IAAI,EAAE;YACzC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,EAAE,GAAG,CAAC;SACtC,CAAC,CAAC,CAAC;QACJ,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjG,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAE9D,IAAI,OAAe,CAAC;QACpB,IAAI,aAA4B,CAAC;QACjC,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC9B,aAAa,GAAG,MAAM,CAAC;QACxB,CAAC;aAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,sBAAsB,EAAE,CAAC;YACxG,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAClC,aAAa,GAAG,aAAa,CAAC;QAC/B,CAAC;aAAM,CAAC;YACP,OAAO,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC3F,aAAa,GAAG,SAAS,CAAC;QAC3B,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9G,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjH,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjH,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAE3H,OAAO;YACN,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS;YAC7E,OAAO,EAAE,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;YACpF,aAAa;YACb,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACrC,OAAO;YACP,QAAQ;YACR,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,EAAE,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC;YAClC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,UAAU,EAAE,CAAC,CAAC,IAAI;YAClB,WAAW,EAAE,CAAC,CAAC,OAAO;YACtB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,CAAC,CAAC,OAAO;SAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,CAAC,CAAa,EAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;IACpF,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACvF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAChD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,EAAE,IAAI,IAAI;QAAE,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,GAAG,EAAE,CAAC;IAC5D,OAAO,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACjD,CAAC;AAID,2CAA2C;AAC3C,SAAS,UAAU,CAAC,CAAa,EAAE,IAAU;IAC5C,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACrI,MAAM,IAAI,GAAG,CAAC,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,gDAAgD,CAAC,CAAC,CAAC,EAAE,CAAC;IACnG,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;SACvI,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,CAAC,CAAa,EAAU,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC1F,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3G,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,MAAM,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpI,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,YAAY,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3J,IAAI,IAAI,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,YAAY,GAAG,GAAG,CAAC,CAAC,OAAO;;klBAEijB,CAAC;AAEnlB;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,KAA4B,EAAE,YAAoB,CAAC,CAAC,iBAAiB;IACjG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,CAAC,IAAU,EAAE,KAA4B,EAAE,IAA2B,EAAU,EAAE;QAC/F,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,+BAA+B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5H,OAAO,GAAG,YAAY,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IAC1F,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI,oBAAoB,CAAC,EAAE,CAAC,IAAI,SAAS;YAAE,OAAO,EAAE,CAAC;IACtD,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,KAAK,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACrD,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,IAAI,oBAAoB,CAAC,EAAE,CAAC,IAAI,SAAS;YAAE,OAAO,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC;AAmBD,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,MAAM,GAAG,IAAI,CAAC;AAEpB,gFAAgF;AAChF,SAAS,OAAO,CAAC,QAAgB,EAAE,CAAS;IAC3C,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AAID,gEAAgE;AAChE,SAAS,OAAO,CAAC,GAAW,EAAE,MAAyD;IACtF,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACxB,CAAC;AAED,2FAA2F;AAC3F,SAAS,IAAI,CAAC,IAAW,EAAE,KAAe;IACzC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmD,CAAC;IACvE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,CAAC,CAAM,EAAE,CAAS,EAAU,EAAE;QAC1C,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;YAAE,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;gBAAE,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,CAAC;IACV,CAAC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,CAAC;QAChF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,KAAK,CAAC;gBAAE,SAAS;YACtB,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7G,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,GAAG,EAAU,EAAE,CAAC;YACvE,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC;YAClB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACrB,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,4GAA4G;AAC5G,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC;IACpB,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK;IAC9L,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACzL,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ;IAC3L,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAC7F,CAAC,CAAC;AAEH,mFAAmF;AACnF,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,6DAA6D,CAAC,CAAC,CAAC;AAE7F,uGAAuG;AACvG,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,gFAAgF;AAChF,SAAS,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAAC,KAA4B,EAAE,OAAe,EAAE,QAAgB,CAAC,CAAC,kBAAkB;IAChH,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;IAE9D,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAChC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACb,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACX,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACd,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;KACd,CAAC,CACF,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,KAAK;SAClB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACV,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAClM,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,IAAI,GAAG,EAAU,EAAE,CAAC;IACnH,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;SAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACxC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE;YACf,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACX,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACX,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5B,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACZ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SAC1H,CAAC,CACF,CAAC;QACF,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9C,OAAO;YACN,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;YACd,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;YACd,MAAM,EAAE,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;YAC5D,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG;YACtC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE;YAC9B,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM;YAClB,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,qBAAqB;YAChI,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa;SAChC,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team roster service (specs/2026-10-10-team-roster.md).
|
|
3
|
+
*
|
|
4
|
+
* Reads the harness's records, builds the roster with
|
|
5
|
+
* {@link buildRoster}, and keeps the result for a short time so the prompt
|
|
6
|
+
* module, the API and the skills share one build. Every source is read-only
|
|
7
|
+
* and fail-soft: a source that cannot be read leaves that part of the roster
|
|
8
|
+
* empty instead of failing the whole thing.
|
|
9
|
+
*
|
|
10
|
+
* @module services/team-roster/team-roster.service
|
|
11
|
+
*/
|
|
12
|
+
import type { Project, Team } from '../../types/index.js';
|
|
13
|
+
import { type OwnerCandidate, type RosterTeam, type RosterTicket, type RosterWorkItem } from './team-roster.builder.js';
|
|
14
|
+
/** Where the roster reads from; every member is replaceable in tests. */
|
|
15
|
+
export interface TeamRosterDeps {
|
|
16
|
+
getTeams: () => Promise<Team[]>;
|
|
17
|
+
getProjects: () => Promise<Project[]>;
|
|
18
|
+
listTickets: (projectPath: string) => Promise<RosterTicket[]>;
|
|
19
|
+
getWorkItems: () => Promise<RosterWorkItem[]>;
|
|
20
|
+
getChannels: () => Promise<Map<string, string>>;
|
|
21
|
+
now: () => Date;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Builds and serves the team roster.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const md = await TeamRosterService.getInstance().renderForPrompt();
|
|
29
|
+
* const hits = await TeamRosterService.getInstance().find('record a promo video for flopost');
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare class TeamRosterService {
|
|
33
|
+
private static instance;
|
|
34
|
+
private readonly deps;
|
|
35
|
+
private readonly logger;
|
|
36
|
+
private cached;
|
|
37
|
+
private inflight;
|
|
38
|
+
/**
|
|
39
|
+
* @param deps - Replacement sources (tests)
|
|
40
|
+
*/
|
|
41
|
+
constructor(deps?: Partial<TeamRosterDeps>);
|
|
42
|
+
/**
|
|
43
|
+
* Process-wide instance.
|
|
44
|
+
*
|
|
45
|
+
* @returns The singleton
|
|
46
|
+
*/
|
|
47
|
+
static getInstance(): TeamRosterService;
|
|
48
|
+
/** Reset the singleton (tests). */
|
|
49
|
+
static resetInstance(): void;
|
|
50
|
+
/** Drop the cached roster so the next read rebuilds it (a charter or team changed). */
|
|
51
|
+
invalidate(): void;
|
|
52
|
+
/**
|
|
53
|
+
* The roster, rebuilt at most once per {@link TEAM_ROSTER_CONSTANTS.CACHE_TTL_MS}.
|
|
54
|
+
*
|
|
55
|
+
* @param opts - `fresh` skips the cache
|
|
56
|
+
* @returns One entry per live team, busiest first
|
|
57
|
+
*/
|
|
58
|
+
getRoster(opts?: {
|
|
59
|
+
fresh?: boolean;
|
|
60
|
+
}): Promise<RosterTeam[]>;
|
|
61
|
+
/**
|
|
62
|
+
* The roster as prompt markdown, under the token budget.
|
|
63
|
+
*
|
|
64
|
+
* @param maxTokens - Budget (defaults to {@link TEAM_ROSTER_CONSTANTS.PROMPT_MAX_TOKENS})
|
|
65
|
+
* @returns Markdown, or '' when there are no teams
|
|
66
|
+
*/
|
|
67
|
+
renderForPrompt(maxTokens?: number): Promise<string>;
|
|
68
|
+
/**
|
|
69
|
+
* Rank teams and members for a request.
|
|
70
|
+
*
|
|
71
|
+
* @param request - What the owner asked for
|
|
72
|
+
* @param limit - Candidates to return
|
|
73
|
+
* @returns Best first; empty when nothing matches
|
|
74
|
+
*/
|
|
75
|
+
find(request: string, limit?: number): Promise<OwnerCandidate[]>;
|
|
76
|
+
/** Read every source and build. */
|
|
77
|
+
private build;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=team-roster.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-roster.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/team-roster/team-roster.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAM1D,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,MAAM,0BAA0B,CAAC;AAElC,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACtC,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC9D,YAAY,EAAE,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC9C,WAAW,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,GAAG,EAAE,MAAM,IAAI,CAAC;CAChB;AA4BD;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAEzD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiB;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,MAAM,CAAoD;IAClE,OAAO,CAAC,QAAQ,CAAsC;IAEtD;;OAEG;gBACS,IAAI,GAAE,OAAO,CAAC,cAAc,CAAM;IAK9C;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,iBAAiB;IAKvC,mCAAmC;IACnC,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B,uFAAuF;IACvF,UAAU,IAAI,IAAI;IAIlB;;;;;OAKG;IACG,SAAS,CAAC,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAkBtE;;;;;OAKG;IACG,eAAe,CAAC,SAAS,GAAE,MAA4B,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/E;;;;;;OAMG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAItE,mCAAmC;YACrB,KAAK;CAgBnB"}
|