@detergent-software/conductor 1.4.0-dev.1 → 1.4.0-dev.10
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/CHANGELOG.md +91 -0
- package/README.md +80 -17
- package/build/brief-cli.js +105 -23
- package/build/brief-cli.js.map +1 -1
- package/build/brief.js +107 -9
- package/build/brief.js.map +1 -1
- package/build/broker.js +40 -14
- package/build/broker.js.map +1 -1
- package/build/cli.js +49 -18
- package/build/cli.js.map +1 -1
- package/build/code-host-cli.js +46 -2
- package/build/code-host-cli.js.map +1 -1
- package/build/code-host.js +2 -0
- package/build/code-host.js.map +1 -1
- package/build/conditions.js +22 -13
- package/build/conditions.js.map +1 -1
- package/build/daemon.js +64 -16
- package/build/daemon.js.map +1 -1
- package/build/follow-ups.js +72 -0
- package/build/follow-ups.js.map +1 -0
- package/build/help.js +712 -208
- package/build/help.js.map +1 -1
- package/build/in-process.js +30 -0
- package/build/in-process.js.map +1 -0
- package/build/inbox.js +113 -11
- package/build/inbox.js.map +1 -1
- package/build/lib/providers/ado/code-host.js +8 -5
- package/build/lib/providers/ado/code-host.js.map +1 -1
- package/build/lib/providers/ado/pipelines.js +16 -10
- package/build/lib/providers/ado/pipelines.js.map +1 -1
- package/build/lib/providers/github/actions.js +11 -0
- package/build/lib/providers/github/actions.js.map +1 -1
- package/build/lib/providers/github/code-host.js +17 -0
- package/build/lib/providers/github/code-host.js.map +1 -1
- package/build/lib/providers/index.js +1 -1
- package/build/lib/providers/index.js.map +1 -1
- package/build/lib/providers/verdicts/pr.js +14 -12
- package/build/lib/providers/verdicts/pr.js.map +1 -1
- package/build/manager.js +8 -3
- package/build/manager.js.map +1 -1
- package/build/note.js +95 -14
- package/build/note.js.map +1 -1
- package/build/notes.js +104 -16
- package/build/notes.js.map +1 -1
- package/build/notify.js +2 -1
- package/build/notify.js.map +1 -1
- package/build/package-info.js +12 -0
- package/build/package-info.js.map +1 -0
- package/build/profile.js +64 -13
- package/build/profile.js.map +1 -1
- package/build/project-check-cli.js +85 -0
- package/build/project-check-cli.js.map +1 -0
- package/build/project-check.js +362 -0
- package/build/project-check.js.map +1 -0
- package/build/resolve.js +11 -3
- package/build/resolve.js.map +1 -1
- package/build/rule-actions.js +9 -0
- package/build/rule-actions.js.map +1 -1
- package/build/rules-service.js +28 -19
- package/build/rules-service.js.map +1 -1
- package/build/runs.js.map +1 -1
- package/build/scheduler.js +43 -1
- package/build/scheduler.js.map +1 -1
- package/build/server.js +76 -7
- package/build/server.js.map +1 -1
- package/build/store.js +27 -4
- package/build/store.js.map +1 -1
- package/build/tracker-writes.js +74 -0
- package/build/tracker-writes.js.map +1 -0
- package/build/trackers.js +20 -0
- package/build/trackers.js.map +1 -1
- package/build/watchers/ado.js +7 -1
- package/build/watchers/ado.js.map +1 -1
- package/build/watchers/boards-writes.js +182 -34
- package/build/watchers/boards-writes.js.map +1 -1
- package/build/watchers/boards.js +7 -2
- package/build/watchers/boards.js.map +1 -1
- package/build/watchers/github.js +20 -2
- package/build/watchers/github.js.map +1 -1
- package/build/watchers/index.js +32 -4
- package/build/watchers/index.js.map +1 -1
- package/build/watchers/issues-brief.js +48 -0
- package/build/watchers/issues-brief.js.map +1 -0
- package/build/watchers/issues-queue.js +85 -0
- package/build/watchers/issues-queue.js.map +1 -0
- package/build/watchers/issues-writes.js +233 -0
- package/build/watchers/issues-writes.js.map +1 -0
- package/build/watchers/issues.js +264 -0
- package/build/watchers/issues.js.map +1 -0
- package/build/watchers/linear-writes.js +198 -0
- package/build/watchers/linear-writes.js.map +1 -0
- package/build/watchers/source.js.map +1 -1
- package/build/worktrees.js +1 -0
- package/build/worktrees.js.map +1 -1
- package/mod/hooks/model.ts +11 -0
- package/mod/hooks/register.tsx +25 -3
- package/package.json +1 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ConductorError } from "../errors.js";
|
|
3
|
+
import { NotFound } from "../lib/providers/index.js";
|
|
4
|
+
import { NotePostError } from "../notes.js";
|
|
5
|
+
import { followUpLinks, keepsClosed, transitionsOf } from "../tracker-writes.js";
|
|
6
|
+
import { issueNumber, issuesGet, issueState, labelsOf, readComments, readIssue, readPages, readViewer, repoPath, requireIssueRepo, } from "./issues.js";
|
|
7
|
+
// The conductor's writes to GitHub Issues (ATK-458), as the project's gh account: phase notes as
|
|
8
|
+
// issue comments, a rule's label edit, and the tracker writes a worker's notes and verbs cause. A
|
|
9
|
+
// phase is a label (`in-progress`, `in-review`) until Landed closes the issue as completed; labels
|
|
10
|
+
// are added and removed one at a time, never replaced as a set, so a label someone added meanwhile
|
|
11
|
+
// stays. None takes from the watchers' budget, as Linear's and Boards' writes don't.
|
|
12
|
+
const created = z.looseObject({ html_url: z.string(), id: z.number(), number: z.number() });
|
|
13
|
+
const comment = z.looseObject({ html_url: z.string().nullish(), id: z.number() });
|
|
14
|
+
const pull = z.looseObject({ body: z.string().nullish() });
|
|
15
|
+
export function issuesLabels(options) {
|
|
16
|
+
return {
|
|
17
|
+
label: async (item, label, op, profile) => {
|
|
18
|
+
const { issue, number, repo, write } = await target(options, item, profile);
|
|
19
|
+
const has = labelsOf(issue).some((l) => l.toLowerCase() === label.toLowerCase());
|
|
20
|
+
if (has === (op === 'add'))
|
|
21
|
+
return 'already';
|
|
22
|
+
if (op === 'add')
|
|
23
|
+
await addLabel(write, repo, number, label, item);
|
|
24
|
+
else
|
|
25
|
+
await removeLabel(write, repo, number, label);
|
|
26
|
+
return op === 'add' ? 'added' : 'removed';
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// A note as an issue comment. A refused request (a 4xx, or no gh login) posted nothing; a lost
|
|
31
|
+
// answer or a 5xx may have posted it.
|
|
32
|
+
export function issuesNotes(options) {
|
|
33
|
+
return {
|
|
34
|
+
comment: async (item, body, profile) => {
|
|
35
|
+
const repo = requireIssueRepo(profile);
|
|
36
|
+
const number = issueNumber(item, repo);
|
|
37
|
+
if (number === null)
|
|
38
|
+
throw new NotePostError(`${item} isn't an issue of the repo keyed ${repo.key}`, 'no');
|
|
39
|
+
let answer;
|
|
40
|
+
try {
|
|
41
|
+
answer = await options.credentials.ghWrite(repo.conducted)('POST', `${repoPath(repo)}/issues/${number}/comments`, {
|
|
42
|
+
body,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
47
|
+
// No gh login (nothing was sent), no such issue, or GitHub refusing it: nothing was posted.
|
|
48
|
+
if (error instanceof ConductorError)
|
|
49
|
+
throw new NotePostError(message, 'no', error.details);
|
|
50
|
+
if (error instanceof NotFound || /HTTP 4\d\d/.test(message))
|
|
51
|
+
throw new NotePostError(`GitHub refused the comment on ${item}: ${message}`, 'no');
|
|
52
|
+
throw new NotePostError(`GitHub unreachable: ${message}`, 'unknown');
|
|
53
|
+
}
|
|
54
|
+
const posted = comment.safeParse(answer).data;
|
|
55
|
+
if (!posted)
|
|
56
|
+
throw new NotePostError(`GitHub's answer to the comment on ${item} didn't read`, 'unknown');
|
|
57
|
+
return { id: String(posted.id), url: posted.html_url ?? null };
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// The tracker writes on GitHub Issues: the phase label (and the assignee on `started`), Landed's
|
|
62
|
+
// close as completed, a PR linked by the reference its body carries (else a comment with its URL),
|
|
63
|
+
// and a follow-up as a new issue with its labels and dependencies.
|
|
64
|
+
export function issuesWrites(options) {
|
|
65
|
+
// The gh account's login by account, which an assignee takes.
|
|
66
|
+
const viewers = new Map();
|
|
67
|
+
const viewerOf = async (get, repo) => {
|
|
68
|
+
const who = options.credentials.account('github', repo.conducted).id;
|
|
69
|
+
const known = viewers.get(who) ?? (await readViewer(get));
|
|
70
|
+
viewers.set(who, known);
|
|
71
|
+
return known;
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
file: async (followUp, profile) => {
|
|
75
|
+
const repo = requireIssueRepo(profile);
|
|
76
|
+
const get = issuesGet(options.credentials, repo, null);
|
|
77
|
+
const write = options.credentials.ghWrite(repo.conducted);
|
|
78
|
+
const area = `${repo.areaPrefix}${followUp.area.replace(new RegExp(`^${escape(repo.areaPrefix)}`, 'i'), '')}`;
|
|
79
|
+
// An Area the repo has no label for is refused before anything is written.
|
|
80
|
+
try {
|
|
81
|
+
await get(`${repoPath(repo)}/labels/${encodeURIComponent(area)}`);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
if (!(error instanceof NotFound))
|
|
85
|
+
throw error;
|
|
86
|
+
const known = (await readPages(get, `${repoPath(repo)}/labels`))
|
|
87
|
+
.map((l) => z.looseObject({ name: z.string() }).parse(l).name)
|
|
88
|
+
.filter((n) => n.toLowerCase().startsWith(repo.areaPrefix.toLowerCase()))
|
|
89
|
+
.map((n) => n.slice(repo.areaPrefix.length))
|
|
90
|
+
.sort();
|
|
91
|
+
throw new ConductorError(`"${followUp.area}" isn't an Area: a "${repo.areaPrefix}" label of ${repo.owner}/${repo.repo}`, [`the Areas: ${known.join(', ') || 'none'}`]);
|
|
92
|
+
}
|
|
93
|
+
const links = followUpLinks(followUp);
|
|
94
|
+
const numberOf = (key) => {
|
|
95
|
+
const n = issueNumber(key, repo);
|
|
96
|
+
if (n === null)
|
|
97
|
+
throw new ConductorError(`${key} isn't an issue of the repo keyed ${repo.key}`);
|
|
98
|
+
return n;
|
|
99
|
+
};
|
|
100
|
+
const related = links.related.map(numberOf);
|
|
101
|
+
const blockedBy = links.blockedBy.map(numberOf);
|
|
102
|
+
// GitHub has no "related" relation: a mention in the body links each in its timeline.
|
|
103
|
+
const body = related.length > 0
|
|
104
|
+
? `${followUp.body.trimEnd()}\n\nRelated: ${related.map((n) => `#${n}`).join(', ')}`
|
|
105
|
+
: followUp.body;
|
|
106
|
+
const labels = [repo.queueLabel, area, repo.triageLabel, followUp.human ? repo.humanLabel : null].flatMap((l) => l === null ? [] : [l]);
|
|
107
|
+
const made = created.safeParse(await write('POST', `${repoPath(repo)}/issues`, { body, labels, title: followUp.title })).data;
|
|
108
|
+
if (!made)
|
|
109
|
+
throw new ConductorError("GitHub didn't create the follow-up");
|
|
110
|
+
const warnings = [];
|
|
111
|
+
// The issue exists now: a dependency that doesn't take is a warning on it, not a failed filing.
|
|
112
|
+
for (const n of blockedBy) {
|
|
113
|
+
try {
|
|
114
|
+
const blocker = await readIssue(get, repo, n);
|
|
115
|
+
if (!blocker?.id)
|
|
116
|
+
throw new Error(`${repo.owner}/${repo.repo} has no issue #${n}`);
|
|
117
|
+
await write('POST', `${repoPath(repo)}/issues/${made.number}/dependencies/blocked_by`, {
|
|
118
|
+
issue_id: blocker.id,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
warnings.push(`not blocked by ${repo.key}-${n}: ${error instanceof Error ? error.message : String(error)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { key: `${repo.key}-${made.number}`, url: made.html_url, warnings };
|
|
126
|
+
},
|
|
127
|
+
linkPr: async (item, pr, profile) => {
|
|
128
|
+
const { get, number, repo, write } = await target(options, item, profile);
|
|
129
|
+
// A GitHub PR whose body carries the issue's reference is linked by GitHub itself.
|
|
130
|
+
if (pr.repo.host === 'github') {
|
|
131
|
+
const body = pull.parse(await get(`repos/${pr.repo.owner}/${pr.repo.repo}/pulls/${pr.number}`)).body ?? '';
|
|
132
|
+
if (mentions(body, repo, number, pr.repo))
|
|
133
|
+
return 'already';
|
|
134
|
+
}
|
|
135
|
+
const comments = await readComments(get, repo, number);
|
|
136
|
+
if (comments.some((c) => c.body.includes(pr.url)))
|
|
137
|
+
return 'already';
|
|
138
|
+
await write('POST', `${repoPath(repo)}/issues/${number}/comments`, { body: `PR: ${pr.url}` });
|
|
139
|
+
return 'linked';
|
|
140
|
+
},
|
|
141
|
+
prReference: (item, host, profile) => {
|
|
142
|
+
if (host !== 'github')
|
|
143
|
+
return null;
|
|
144
|
+
const repo = requireIssueRepo(profile);
|
|
145
|
+
const number = issueNumber(item, repo);
|
|
146
|
+
return number === null ? null : `Refs ${repo.owner}/${repo.repo}#${number}`;
|
|
147
|
+
},
|
|
148
|
+
transition: async (item, phase, profile) => {
|
|
149
|
+
const name = transitionsOf(profile)[phase];
|
|
150
|
+
// A phase with no label moves nothing, but `started` still assigns.
|
|
151
|
+
if (name === null && phase !== 'started')
|
|
152
|
+
return { result: 'skipped', state: null };
|
|
153
|
+
const { get, issue, number, repo, write } = await target(options, item, profile);
|
|
154
|
+
const state = issueState(issue, repo);
|
|
155
|
+
if (keepsClosed(phase, state.type))
|
|
156
|
+
return { result: 'kept', state: state.name };
|
|
157
|
+
const labels = labelsOf(issue);
|
|
158
|
+
const phaseLabels = labels.filter((l) => repo.phaseLabels.some((p) => p.toLowerCase() === l.toLowerCase()));
|
|
159
|
+
if (phase === 'landed') {
|
|
160
|
+
if (state.type === 'completed')
|
|
161
|
+
return { result: 'already', state: state.name };
|
|
162
|
+
const after = z
|
|
163
|
+
.looseObject({ state: z.string() })
|
|
164
|
+
.safeParse(await write('PATCH', `${repoPath(repo)}/issues/${number}`, { state: 'closed', state_reason: 'completed' })).data;
|
|
165
|
+
if (after?.state.toLowerCase() !== 'closed')
|
|
166
|
+
throw new ConductorError(`GitHub didn't close ${item}: it is ${after?.state ?? 'unreadable'}`);
|
|
167
|
+
for (const l of phaseLabels)
|
|
168
|
+
await removeLabel(write, repo, number, l);
|
|
169
|
+
return { result: 'moved', state: 'closed' };
|
|
170
|
+
}
|
|
171
|
+
const assignee = phase === 'started' ? await viewerOf(get, repo) : null;
|
|
172
|
+
const assign = assignee !== null && !(issue.assignees ?? []).some((a) => a.login.toLowerCase() === assignee.toLowerCase());
|
|
173
|
+
// A phase with no label of its own leaves the other phase's label where it is.
|
|
174
|
+
const stale = name === null ? [] : phaseLabels.filter((l) => l.toLowerCase() !== name.toLowerCase());
|
|
175
|
+
const add = name !== null && !labels.some((l) => l.toLowerCase() === name.toLowerCase());
|
|
176
|
+
// A PR opened on a closed issue reopens it, for a follow-up PR on a landed item.
|
|
177
|
+
const reopen = state.type === 'completed' || state.type === 'canceled';
|
|
178
|
+
if (!assign && !add && stale.length === 0 && !reopen)
|
|
179
|
+
return { result: name === null ? 'skipped' : 'already', state: name === null ? null : state.name };
|
|
180
|
+
if (reopen)
|
|
181
|
+
await write('PATCH', `${repoPath(repo)}/issues/${number}`, { state: 'open' });
|
|
182
|
+
if (assign)
|
|
183
|
+
await write('POST', `${repoPath(repo)}/issues/${number}/assignees`, { assignees: [assignee] });
|
|
184
|
+
if (add)
|
|
185
|
+
await addLabel(write, repo, number, name, item);
|
|
186
|
+
for (const l of stale)
|
|
187
|
+
await removeLabel(write, repo, number, l);
|
|
188
|
+
return { result: name === null ? 'skipped' : 'moved', state: name };
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
async function addLabel(write, repo, number, label, item) {
|
|
193
|
+
// GitHub makes a label the repo doesn't have yet. The answer is the issue's labels after the add.
|
|
194
|
+
const after = z
|
|
195
|
+
.array(z.looseObject({ name: z.string() }))
|
|
196
|
+
.safeParse(await write('POST', `${repoPath(repo)}/issues/${number}/labels`, { labels: [label] })).data;
|
|
197
|
+
if (!after?.some((l) => l.name.toLowerCase() === label.toLowerCase()))
|
|
198
|
+
throw new ConductorError(`GitHub didn't add the label "${label}" to ${item}`);
|
|
199
|
+
}
|
|
200
|
+
function escape(text) {
|
|
201
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
202
|
+
}
|
|
203
|
+
// The issue's reference in a PR body: `#n` in the issue's own repo, `owner/repo#n` or the issue's
|
|
204
|
+
// URL from anywhere.
|
|
205
|
+
function mentions(body, repo, number, prRepo) {
|
|
206
|
+
const full = new RegExp(`(?:^|[^\\w/])${escape(`${repo.owner}/${repo.repo}`)}#${number}\\b`, 'i');
|
|
207
|
+
const url = new RegExp(`github\\.com/${escape(`${repo.owner}/${repo.repo}`)}/issues/${number}\\b`, 'i');
|
|
208
|
+
const same = prRepo.owner.toLowerCase() === repo.owner.toLowerCase() && prRepo.repo.toLowerCase() === repo.repo.toLowerCase();
|
|
209
|
+
return full.test(body) || url.test(body) || (same && new RegExp(`(?:^|[^\\w/])#${number}\\b`).test(body));
|
|
210
|
+
}
|
|
211
|
+
// A label taken off; one already gone (GitHub's 404) is fine.
|
|
212
|
+
async function removeLabel(write, repo, number, label) {
|
|
213
|
+
try {
|
|
214
|
+
await write('DELETE', `${repoPath(repo)}/issues/${number}/labels/${encodeURIComponent(label)}`);
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
if (!(error instanceof NotFound))
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// The item's repo, number and issue, refused when the item isn't one of the repo's issues.
|
|
222
|
+
async function target(options, item, profile) {
|
|
223
|
+
const repo = requireIssueRepo(profile);
|
|
224
|
+
const number = issueNumber(item, repo);
|
|
225
|
+
if (number === null)
|
|
226
|
+
throw new ConductorError(`${item} isn't an issue of the repo keyed ${repo.key}, such as ${repo.key}-12`);
|
|
227
|
+
const get = issuesGet(options.credentials, repo, null);
|
|
228
|
+
const issue = await readIssue(get, repo, number);
|
|
229
|
+
if (!issue || issue.pull_request !== undefined)
|
|
230
|
+
throw new ConductorError(`${repo.owner}/${repo.repo} has no issue #${number} (${item})`);
|
|
231
|
+
return { get, issue, number, repo, write: options.credentials.ghWrite(repo.conducted) };
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=issues-writes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issues-writes.js","sourceRoot":"","sources":["../../src/watchers/issues-writes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAsB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrG,OAAO,EAEL,WAAW,EAEX,SAAS,EAGT,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,EACT,UAAU,EACV,QAAQ,EACR,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,iGAAiG;AACjG,kGAAkG;AAClG,mGAAmG;AACnG,mGAAmG;AACnG,qFAAqF;AAErF,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC5F,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAClF,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAE3D,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;YACxC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAC5E,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACjF,IAAI,GAAG,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YAC7C,IAAI,EAAE,KAAK,KAAK;gBAAE,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;;gBAC9D,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YACnD,OAAO,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5C,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+FAA+F;AAC/F,sCAAsC;AACtC,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,OAAO;QACL,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACvC,IAAI,MAAM,KAAK,IAAI;gBAAE,MAAM,IAAI,aAAa,CAAC,GAAG,IAAI,qCAAqC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;YAC3G,IAAI,MAAe,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CACxD,MAAM,EACN,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,MAAM,WAAW,EAC7C;oBACE,IAAI;iBACL,CACF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvE,4FAA4F;gBAC5F,IAAI,KAAK,YAAY,cAAc;oBAAE,MAAM,IAAI,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC3F,IAAI,KAAK,YAAY,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;oBACzD,MAAM,IAAI,aAAa,CAAC,iCAAiC,IAAI,KAAK,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;gBACrF,MAAM,IAAI,aAAa,CAAC,uBAAuB,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;YACvE,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;YAC9C,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,aAAa,CAAC,qCAAqC,IAAI,cAAc,EAAE,SAAS,CAAC,CAAC;YACzG,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QACjE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,mGAAmG;AACnG,mEAAmE;AACnE,MAAM,UAAU,YAAY,CAAC,OAAsB;IACjD,8DAA8D;IAC9D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAc,EAAE,IAAe,EAAmB,EAAE;QAC1E,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACrE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;YAChC,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YACvD,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1D,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YAC9G,2EAA2E;YAC3E,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;oBAAE,MAAM,KAAK,CAAC;gBAC9C,MAAM,KAAK,GAAG,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;qBAC7D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;qBAC7D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;qBACxE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;qBAC3C,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,cAAc,CACtB,IAAI,QAAQ,CAAC,IAAI,uBAAuB,IAAI,CAAC,UAAU,cAAc,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,EAC9F,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC,CAC7C,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAU,EAAE;gBACvC,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACjC,IAAI,CAAC,KAAK,IAAI;oBAAE,MAAM,IAAI,cAAc,CAAC,GAAG,GAAG,qCAAqC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAChG,OAAO,CAAC,CAAC;YACX,CAAC,CAAC;YACF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAChD,sFAAsF;YACtF,MAAM,IAAI,GACR,OAAO,CAAC,MAAM,GAAG,CAAC;gBAChB,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACpF,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YACpB,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9G,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACtB,CAAC;YACF,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAC5B,MAAM,KAAK,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CACzF,CAAC,IAAI,CAAC;YACP,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,cAAc,CAAC,oCAAoC,CAAC,CAAC;YAC1E,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,gGAAgG;YAChG,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC9C,IAAI,CAAC,OAAO,EAAE,EAAE;wBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,kBAAkB,CAAC,EAAE,CAAC,CAAC;oBACnF,MAAM,KAAK,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,0BAA0B,EAAE;wBACrF,QAAQ,EAAE,OAAO,CAAC,EAAE;qBACrB,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,QAAQ,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC9G,CAAC;YACH,CAAC;YACD,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAC7E,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;YAClC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAC1E,mFAAmF;YACnF,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC3G,IAAI,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC;oBAAE,OAAO,SAAS,CAAC;YAC9D,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACvD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gBAAE,OAAO,SAAS,CAAC;YACpE,MAAM,KAAK,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,MAAM,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC9F,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YACnC,IAAI,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACnC,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACvC,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;QAC9E,CAAC;QACD,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACzC,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC;YAC3C,oEAAoE;YACpE,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YACpF,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YACjF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACtC,IAAI,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC;gBAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YACjF,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC/B,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAC5G,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACvB,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;oBAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;gBAChF,MAAM,KAAK,GAAG,CAAC;qBACZ,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;qBAClC,SAAS,CACR,MAAM,KAAK,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAC3G,CAAC,IAAI,CAAC;gBACT,IAAI,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,QAAQ;oBACzC,MAAM,IAAI,cAAc,CAAC,uBAAuB,IAAI,WAAW,KAAK,EAAE,KAAK,IAAI,YAAY,EAAE,CAAC,CAAC;gBACjG,KAAK,MAAM,CAAC,IAAI,WAAW;oBAAE,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;gBACvE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YAC9C,CAAC;YACD,MAAM,QAAQ,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACxE,MAAM,MAAM,GACV,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;YAC9G,+EAA+E;YAC/E,MAAM,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACrG,MAAM,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACzF,iFAAiF;YACjF,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC;YACvE,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM;gBAClD,OAAO,EAAE,MAAM,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACrG,IAAI,MAAM;gBAAE,MAAM,KAAK,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1F,IAAI,MAAM;gBAAE,MAAM,KAAK,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,MAAM,YAAY,EAAE,EAAE,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC3G,IAAI,GAAG;gBAAE,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YACzD,KAAK,MAAM,CAAC,IAAI,KAAK;gBAAE,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YACjE,OAAO,EAAE,MAAM,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACtE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,KAAc,EAAE,IAAe,EAAE,MAAc,EAAE,KAAa,EAAE,IAAY;IAClG,kGAAkG;IAClG,MAAM,KAAK,GAAG,CAAC;SACZ,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;SAC1C,SAAS,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,MAAM,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACzG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC;QACnE,MAAM,IAAI,cAAc,CAAC,gCAAgC,KAAK,QAAQ,IAAI,EAAE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,kGAAkG;AAClG,qBAAqB;AACrB,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAe,EAAE,MAAc,EAAE,MAAuC;IACtG,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,gBAAgB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,MAAM,KAAK,EAAE,GAAG,CAAC,CAAC;IAClG,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,gBAAgB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,MAAM,KAAK,EAAE,GAAG,CAAC,CAAC;IACxG,MAAM,IAAI,GACR,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACnH,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,iBAAiB,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5G,CAAC;AAED,8DAA8D;AAC9D,KAAK,UAAU,WAAW,CAAC,KAAc,EAAE,IAAe,EAAE,MAAc,EAAE,KAAa;IACvF,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,QAAQ,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,MAAM,WAAW,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;YAAE,MAAM,KAAK,CAAC;IAChD,CAAC;AACH,CAAC;AAED,2FAA2F;AAC3F,KAAK,UAAU,MAAM,CACnB,OAAsB,EACtB,IAAY,EACZ,OAA0E;IAE1E,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvC,IAAI,MAAM,KAAK,IAAI;QACjB,MAAM,IAAI,cAAc,CAAC,GAAG,IAAI,qCAAqC,IAAI,CAAC,GAAG,aAAa,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IAC3G,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS;QAC5C,MAAM,IAAI,cAAc,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,kBAAkB,MAAM,KAAK,IAAI,GAAG,CAAC,CAAC;IAC3F,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;AAC1F,CAAC"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { LoginNeeded } from "../credentials.js";
|
|
3
|
+
import { ConductorError } from "../errors.js";
|
|
4
|
+
import { NotFound } from "../lib/providers/index.js";
|
|
5
|
+
import { notePrefixes } from "../profile.js";
|
|
6
|
+
import { transitionsOf } from "../tracker-writes.js";
|
|
7
|
+
import { approvalAfterPlan, phaseOf } from "./linear.js";
|
|
8
|
+
import { perWait, spend, WaitProblem } from "./source.js";
|
|
9
|
+
const label = z.union([z.string(), z.looseObject({ name: z.string() })]);
|
|
10
|
+
export const ghIssue = z.looseObject({
|
|
11
|
+
assignees: z.array(z.looseObject({ login: z.string() })).nullish(),
|
|
12
|
+
body: z.string().nullish(),
|
|
13
|
+
comments: z.number().optional(),
|
|
14
|
+
created_at: z.string().nullish(),
|
|
15
|
+
html_url: z.string(),
|
|
16
|
+
// The database id, which a dependency write takes.
|
|
17
|
+
id: z.number().optional(),
|
|
18
|
+
// Counts of the open blockers and blocked issues, which saves reading the lists of most issues.
|
|
19
|
+
issue_dependencies_summary: z.looseObject({ blocked_by: z.number(), blocking: z.number() }).nullish(),
|
|
20
|
+
labels: z.array(label).default([]),
|
|
21
|
+
number: z.number(),
|
|
22
|
+
// Set on a PR: the issues API lists PRs too.
|
|
23
|
+
pull_request: z.unknown().optional(),
|
|
24
|
+
state: z.string(),
|
|
25
|
+
state_reason: z.string().nullish(),
|
|
26
|
+
title: z.string(),
|
|
27
|
+
updated_at: z.string().nullish(),
|
|
28
|
+
});
|
|
29
|
+
const ghComment = z.looseObject({
|
|
30
|
+
body: z.string().nullish(),
|
|
31
|
+
created_at: z.string(),
|
|
32
|
+
user: z.looseObject({ login: z.string() }).nullish(),
|
|
33
|
+
});
|
|
34
|
+
const PAGE = 100;
|
|
35
|
+
// The Area of an issue: the name after the prefix of its first Area label, or null.
|
|
36
|
+
export function areaOf(labels, prefix) {
|
|
37
|
+
const found = labels.find((l) => l.toLowerCase().startsWith(prefix.toLowerCase()) && l.length > prefix.length);
|
|
38
|
+
return found === undefined ? null : found.slice(prefix.length);
|
|
39
|
+
}
|
|
40
|
+
// The issue number of `PAR-12` in the repo keyed PAR, or null for another key.
|
|
41
|
+
export function issueNumber(item, repo) {
|
|
42
|
+
const match = /^([A-Za-z][A-Za-z0-9]*)-(\d+)$/.exec(item);
|
|
43
|
+
return match?.[1]?.toUpperCase() === repo.key && match[2] ? Number(match[2]) : null;
|
|
44
|
+
}
|
|
45
|
+
// The issue's key: `PAR-12` in the repo, `owner/repo#12` in another (a dependency can cross repos).
|
|
46
|
+
export function issueRef(issue, repo) {
|
|
47
|
+
const [owner, name] = ownerRepo(issue.html_url);
|
|
48
|
+
const here = owner?.toLowerCase() === repo.owner.toLowerCase() && name?.toLowerCase() === repo.repo.toLowerCase();
|
|
49
|
+
return here || owner === undefined ? `${repo.key}-${issue.number}` : `${owner}/${name}#${issue.number}`;
|
|
50
|
+
}
|
|
51
|
+
// The profile's repo of issues, or null when its tracker isn't GitHub Issues.
|
|
52
|
+
export function issueRepoOf(profile) {
|
|
53
|
+
if (profile?.tracker.kind !== 'github-issues')
|
|
54
|
+
return null;
|
|
55
|
+
const { tracker } = profile;
|
|
56
|
+
const host = profile.codeHost.kind === 'github' ? profile.codeHost : null;
|
|
57
|
+
// The profile's schema requires both beside a code host that isn't GitHub.
|
|
58
|
+
const owner = tracker.owner ?? host?.owner;
|
|
59
|
+
const repo = tracker.repo ?? host?.repo;
|
|
60
|
+
if (owner === undefined || repo === undefined)
|
|
61
|
+
return null;
|
|
62
|
+
const phases = transitionsOf(profile);
|
|
63
|
+
return {
|
|
64
|
+
areaPrefix: tracker.areaPrefix,
|
|
65
|
+
conducted: profile.name,
|
|
66
|
+
humanLabel: tracker.humanLabel,
|
|
67
|
+
key: tracker.key,
|
|
68
|
+
owner,
|
|
69
|
+
phaseLabels: [phases.started, phases['pr-opened']].flatMap((l) => (l === null ? [] : [l])),
|
|
70
|
+
priority: tracker.priority,
|
|
71
|
+
queueLabel: tracker.queueLabel,
|
|
72
|
+
repo,
|
|
73
|
+
triageLabel: tracker.triageLabel ?? null,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export function issuesGet(credentials, repo, budget) {
|
|
77
|
+
const gh = credentials.gh(repo.conducted);
|
|
78
|
+
return (path) => {
|
|
79
|
+
if (budget)
|
|
80
|
+
spend(budget);
|
|
81
|
+
return gh(path);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// The issue's state as the conductor reads it: closed as not planned (or a duplicate) is canceled,
|
|
85
|
+
// any other close completed; open with a phase label started (its name the label, the later phase's
|
|
86
|
+
// first), else unstarted.
|
|
87
|
+
export function issueState(issue, repo) {
|
|
88
|
+
if (issue.state.toLowerCase() === 'closed') {
|
|
89
|
+
const reason = issue.state_reason?.toLowerCase() ?? null;
|
|
90
|
+
return reason === 'not_planned' || reason === 'duplicate'
|
|
91
|
+
? { name: `closed (${reason.replace('_', ' ')})`, type: 'canceled' }
|
|
92
|
+
: { name: 'closed', type: 'completed' };
|
|
93
|
+
}
|
|
94
|
+
const labels = labelsOf(issue).map((l) => l.toLowerCase());
|
|
95
|
+
const phase = [...repo.phaseLabels].reverse().find((p) => labels.includes(p.toLowerCase()));
|
|
96
|
+
return phase === undefined ? { name: 'open', type: 'unstarted' } : { name: phase, type: 'started' };
|
|
97
|
+
}
|
|
98
|
+
// The approval and item waits on GitHub issues, for the GitHub source. Each pass reads every waited
|
|
99
|
+
// issue once, and an issue's comments only when a wait needs them and they changed since the last
|
|
100
|
+
// read. State lives in memory.
|
|
101
|
+
export function issuesWaits({ credentials }) {
|
|
102
|
+
const repos = new Map();
|
|
103
|
+
return {
|
|
104
|
+
check: async (waits, budget, outcomes) => {
|
|
105
|
+
const byRepo = new Map();
|
|
106
|
+
for (const wait of waits) {
|
|
107
|
+
const c = wait.condition;
|
|
108
|
+
if ((c.kind !== 'approval' && c.kind !== 'item') || c.tracker !== 'github-issues')
|
|
109
|
+
continue;
|
|
110
|
+
const repo = issueRepoOf(wait.profile);
|
|
111
|
+
if (!repo) {
|
|
112
|
+
outcomes.set(wait.id, { error: "the project's profile has no GitHub Issues tracker" });
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
// By repo, key and gh account: the viewer whose approvals count is the account's.
|
|
116
|
+
const at = `${repoPath(repo)} ${repo.key} ${credentials.account('github', repo.conducted).id}`;
|
|
117
|
+
const group = byRepo.get(at) ?? { repo, waits: [] };
|
|
118
|
+
group.waits.push(wait);
|
|
119
|
+
byRepo.set(at, group);
|
|
120
|
+
}
|
|
121
|
+
for (const [at, group] of byRepo) {
|
|
122
|
+
try {
|
|
123
|
+
await checkRepo(at, group, budget, outcomes);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
// A repo whose project's gh login is lost is a problem with its waits alone, so the PR and
|
|
127
|
+
// merge waits of the same pass go on.
|
|
128
|
+
if (!(error instanceof LoginNeeded))
|
|
129
|
+
throw error;
|
|
130
|
+
for (const wait of group.waits)
|
|
131
|
+
if (!outcomes.has(wait.id))
|
|
132
|
+
outcomes.set(wait.id, { error: error.line });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
async function checkRepo(at, group, budget, outcomes) {
|
|
138
|
+
const { repo } = group;
|
|
139
|
+
const get = issuesGet(credentials, repo, budget);
|
|
140
|
+
const state = repos.get(at) ?? { issues: new Map(), viewer: null };
|
|
141
|
+
repos.set(at, state);
|
|
142
|
+
const numbers = new Set(group.waits.flatMap((w) => issueNumber(itemOf(w), repo) ?? []));
|
|
143
|
+
// Only the issues something waits on are kept, with their comments.
|
|
144
|
+
for (const n of state.issues.keys())
|
|
145
|
+
if (!numbers.has(n))
|
|
146
|
+
state.issues.delete(n);
|
|
147
|
+
const read = new Map();
|
|
148
|
+
const readsNotes = (wait) => wait.condition.kind === 'approval' || (wait.condition.kind === 'item' && wait.condition.field === 'note');
|
|
149
|
+
if (state.viewer === null && group.waits.some((w) => w.condition.kind === 'approval'))
|
|
150
|
+
state.viewer = await readViewer(get);
|
|
151
|
+
for (const wait of group.waits) {
|
|
152
|
+
const c = wait.condition;
|
|
153
|
+
if (c.kind !== 'approval' && c.kind !== 'item')
|
|
154
|
+
continue;
|
|
155
|
+
await perWait(outcomes, wait.id, async () => {
|
|
156
|
+
const n = issueNumber(c.item, repo);
|
|
157
|
+
if (n === null)
|
|
158
|
+
throw new WaitProblem(`${c.item} isn't an issue of the repo keyed ${repo.key}`);
|
|
159
|
+
if (!read.has(n))
|
|
160
|
+
read.set(n, await readIssue(get, repo, n));
|
|
161
|
+
const issue = read.get(n) ?? null;
|
|
162
|
+
if (!issue || issue.pull_request !== undefined) {
|
|
163
|
+
state.issues.delete(n);
|
|
164
|
+
throw new WaitProblem(`${repo.owner}/${repo.repo} has no issue #${n} (${c.item})`);
|
|
165
|
+
}
|
|
166
|
+
const was = state.issues.get(n);
|
|
167
|
+
const version = `${issue.updated_at ?? ''}/${String(issue.comments ?? 0)}`;
|
|
168
|
+
const item = { comments: was?.comments ?? null, issue, readAt: was?.readAt ?? null };
|
|
169
|
+
state.issues.set(n, item);
|
|
170
|
+
if (readsNotes(wait) && (item.comments === null || item.readAt !== version)) {
|
|
171
|
+
item.comments = await readComments(get, repo, n);
|
|
172
|
+
item.readAt = version;
|
|
173
|
+
}
|
|
174
|
+
const prefixes = notePrefixes(wait.profile);
|
|
175
|
+
if (c.kind === 'approval') {
|
|
176
|
+
const found = approvalAfterPlan(item.comments ?? [], state.viewer, prefixes);
|
|
177
|
+
return found ? `approval ${c.item}: ${found.kind}` : null;
|
|
178
|
+
}
|
|
179
|
+
const value = c.value.toLowerCase();
|
|
180
|
+
if (c.field === 'state') {
|
|
181
|
+
const { name, type } = issueState(issue, repo);
|
|
182
|
+
return name.toLowerCase() === value || type === value || issue.state.toLowerCase() === value
|
|
183
|
+
? `item ${c.item} state ${name}`
|
|
184
|
+
: null;
|
|
185
|
+
}
|
|
186
|
+
if (c.field === 'label') {
|
|
187
|
+
const found = labelsOf(issue).find((l) => l.toLowerCase() === value);
|
|
188
|
+
return found ? `item ${c.item} labelled ${found}` : null;
|
|
189
|
+
}
|
|
190
|
+
const note = (item.comments ?? [])
|
|
191
|
+
.map((x) => phaseOf(x.body, prefixes))
|
|
192
|
+
.find((p) => p?.toLowerCase() === value);
|
|
193
|
+
return note ? `item ${c.item} note ${note}` : null;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
export function labelsOf(issue) {
|
|
199
|
+
return issue.labels.map((l) => (typeof l === 'string' ? l : l.name));
|
|
200
|
+
}
|
|
201
|
+
// The issue's comments, oldest first, each by its author's login.
|
|
202
|
+
export async function readComments(get, repo, number) {
|
|
203
|
+
const raw = await readPages(get, `${repoPath(repo)}/issues/${number}/comments`);
|
|
204
|
+
return raw.map((c) => {
|
|
205
|
+
const comment = ghComment.parse(c);
|
|
206
|
+
return { authorId: comment.user?.login ?? null, body: comment.body ?? '', createdAt: comment.created_at };
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
// The issues that block this one (`blocked_by`) or that it blocks (`blocking`), open or closed.
|
|
210
|
+
export async function readDependencies(get, repo, number, which) {
|
|
211
|
+
const raw = await readPages(get, `${repoPath(repo)}/issues/${number}/dependencies/${which}`);
|
|
212
|
+
return raw.map((i) => ghIssue.parse(i));
|
|
213
|
+
}
|
|
214
|
+
// The issue, or null when the repo has no issue of that number. A PR's number reads as one too:
|
|
215
|
+
// the caller checks `pull_request`.
|
|
216
|
+
export async function readIssue(get, repo, number) {
|
|
217
|
+
try {
|
|
218
|
+
return ghIssue.parse(await get(`${repoPath(repo)}/issues/${number}`));
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
if (error instanceof NotFound)
|
|
222
|
+
return null;
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Every page of a list. None is left out, since an approval is among an issue's newest comments;
|
|
227
|
+
// each page takes from the budget, which ends a pass that runs long.
|
|
228
|
+
export async function readPages(get, path) {
|
|
229
|
+
const all = [];
|
|
230
|
+
for (let page = 1;; page++) {
|
|
231
|
+
const answer = z
|
|
232
|
+
.array(z.unknown())
|
|
233
|
+
.parse(await get(`${path}${path.includes('?') ? '&' : '?'}per_page=${PAGE}&page=${page}`));
|
|
234
|
+
all.push(...answer);
|
|
235
|
+
if (answer.length < PAGE)
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
return all;
|
|
239
|
+
}
|
|
240
|
+
// The gh account's login, whose `approve` / `revise:` counts.
|
|
241
|
+
export async function readViewer(get) {
|
|
242
|
+
return z.looseObject({ login: z.string() }).parse(await get('user')).login;
|
|
243
|
+
}
|
|
244
|
+
// `repos/<owner>/<repo>`, which the repo's API paths start with.
|
|
245
|
+
export function repoPath(repo) {
|
|
246
|
+
return `repos/${repo.owner}/${repo.repo}`;
|
|
247
|
+
}
|
|
248
|
+
// A ConductorError for a project whose tracker isn't GitHub Issues.
|
|
249
|
+
export function requireIssueRepo(profile) {
|
|
250
|
+
const repo = issueRepoOf(profile);
|
|
251
|
+
if (!repo)
|
|
252
|
+
throw new ConductorError(`project ${profile?.name ?? '?'} has no GitHub Issues tracker`);
|
|
253
|
+
return repo;
|
|
254
|
+
}
|
|
255
|
+
function itemOf(wait) {
|
|
256
|
+
const c = wait.condition;
|
|
257
|
+
return c.kind === 'approval' || c.kind === 'item' ? c.item : '';
|
|
258
|
+
}
|
|
259
|
+
// The owner and repo in a github.com issue or PR URL.
|
|
260
|
+
function ownerRepo(url) {
|
|
261
|
+
const match = /github\.com\/([\w.-]+)\/([\w.-]+)\//i.exec(url);
|
|
262
|
+
return [match?.[1], match?.[2]];
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=issues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issues.js","sourceRoot":"","sources":["../../src/watchers/issues.ts"],"names":[],"mappings":"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"}
|