@lolkda/dsh-prompt-manager 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +606 -0
  3. package/client/client.js +2320 -0
  4. package/cordis.patch.yml +20 -0
  5. package/environment.md +24 -0
  6. package/lib/entries.js +303 -0
  7. package/lib/entries.js.map +1 -0
  8. package/lib/guard.js +134 -0
  9. package/lib/guard.js.map +1 -0
  10. package/lib/index.js +959 -0
  11. package/lib/index.js.map +1 -0
  12. package/lib/net.js +179 -0
  13. package/lib/net.js.map +1 -0
  14. package/lib/pack.js +327 -0
  15. package/lib/pack.js.map +1 -0
  16. package/lib/probe.js +251 -0
  17. package/lib/probe.js.map +1 -0
  18. package/lib/routes.js +718 -0
  19. package/lib/routes.js.map +1 -0
  20. package/lib/scripts.js +803 -0
  21. package/lib/scripts.js.map +1 -0
  22. package/lib/source.js +308 -0
  23. package/lib/source.js.map +1 -0
  24. package/lib/store.js +223 -0
  25. package/lib/store.js.map +1 -0
  26. package/lib/subscriptions.js +269 -0
  27. package/lib/subscriptions.js.map +1 -0
  28. package/lib/sync.js +646 -0
  29. package/lib/sync.js.map +1 -0
  30. package/lib/types/entries.d.ts +194 -0
  31. package/lib/types/entries.d.ts.map +1 -0
  32. package/lib/types/guard.d.ts +63 -0
  33. package/lib/types/guard.d.ts.map +1 -0
  34. package/lib/types/index.d.ts +176 -0
  35. package/lib/types/index.d.ts.map +1 -0
  36. package/lib/types/net.d.ts +81 -0
  37. package/lib/types/net.d.ts.map +1 -0
  38. package/lib/types/pack.d.ts +298 -0
  39. package/lib/types/pack.d.ts.map +1 -0
  40. package/lib/types/probe.d.ts +150 -0
  41. package/lib/types/probe.d.ts.map +1 -0
  42. package/lib/types/routes.d.ts +85 -0
  43. package/lib/types/routes.d.ts.map +1 -0
  44. package/lib/types/scripts.d.ts +455 -0
  45. package/lib/types/scripts.d.ts.map +1 -0
  46. package/lib/types/source.d.ts +194 -0
  47. package/lib/types/source.d.ts.map +1 -0
  48. package/lib/types/store.d.ts +140 -0
  49. package/lib/types/store.d.ts.map +1 -0
  50. package/lib/types/subscriptions.d.ts +204 -0
  51. package/lib/types/subscriptions.d.ts.map +1 -0
  52. package/lib/types/sync.d.ts +248 -0
  53. package/lib/types/sync.d.ts.map +1 -0
  54. package/package.json +100 -0
@@ -0,0 +1,269 @@
1
+ /**
2
+ * The subscription engine: the one thing the HTTP routes call, the one thing the
3
+ * settings page reads, and the source of truth for the bodies of subscribed
4
+ * entries.
5
+ *
6
+ * It owns no global state of its own. Sources come from the resolved settings
7
+ * document, proxy and mirror come from the same place, and the index it rewrites
8
+ * is handed back to the plugin through {@link SubscriptionHost.setEntries}, so
9
+ * the plugin stays the only writer of its own namespace.
10
+ *
11
+ * @module @lolkda/dsh-prompt-manager/subscriptions
12
+ */
13
+ import { createFetcher } from './net.js';
14
+ import { stemOf } from './source.js';
15
+ import { applyChanges, checkSource, CheckError, revertChanges, SourceWorkspace, titleFor, } from './sync.js';
16
+ /** The subscription engine. */
17
+ export class Subscriptions {
18
+ host;
19
+ /** How one source's workspace is built; replaced in tests. */
20
+ workspaceOf;
21
+ /**
22
+ * Where the subscribed bodies were last found.
23
+ *
24
+ * Section text is resolved on every assembly, so `readBody` runs once per
25
+ * subscribed entry per model step. Rebuilding this map each time would re-read
26
+ * and re-parse every source's `state.json` in that hot path, so it is computed
27
+ * once and dropped whenever the files or the source list can have changed.
28
+ */
29
+ cachedLocations;
30
+ /**
31
+ * @param host - the plugin side of the engine.
32
+ * @param options - workspace factory, for tests that count what the engine reads.
33
+ */
34
+ constructor(host, options = {}) {
35
+ this.host = host;
36
+ this.workspaceOf = options.workspace ?? ((slug) => new SourceWorkspace(this.host.root(), slug));
37
+ }
38
+ /**
39
+ * The workspace of one source.
40
+ * @param slug - source id.
41
+ * @returns its file workspace.
42
+ */
43
+ workspace(slug) {
44
+ return this.workspaceOf(slug);
45
+ }
46
+ /**
47
+ * Where every subscribed entry's body lives.
48
+ * @returns entry id → source and path, for the entries on disk.
49
+ */
50
+ locate() {
51
+ this.cachedLocations ??= this.computeLocations();
52
+ return this.cachedLocations;
53
+ }
54
+ /**
55
+ * Forget the cached map and read the sources again.
56
+ *
57
+ * Called when the source list changed, or after this engine moved files, so
58
+ * the map never describes a snapshot that has already been replaced.
59
+ *
60
+ * @returns the freshly computed map.
61
+ */
62
+ refreshLocations() {
63
+ this.cachedLocations = undefined;
64
+ return this.locate();
65
+ }
66
+ /**
67
+ * Read one subscribed entry's body.
68
+ * @param id - entry id.
69
+ * @returns the body, or `undefined` when it is not a subscribed entry.
70
+ */
71
+ readBody(id) {
72
+ const location = this.locate().get(id);
73
+ if (location === undefined)
74
+ return undefined;
75
+ return this.workspace(location.slug).read('current', location.path);
76
+ }
77
+ /** Build the location map from every source's bookkeeping. */
78
+ computeLocations() {
79
+ const located = new Map();
80
+ for (const source of this.host.sources()) {
81
+ const state = this.workspace(source.id).readState();
82
+ for (const [path, file] of Object.entries(state.files)) {
83
+ located.set(file.id, { slug: source.id, path });
84
+ }
85
+ }
86
+ return located;
87
+ }
88
+ /**
89
+ * The configured sources with their on-disk situation.
90
+ * @returns one summary per source.
91
+ */
92
+ list() {
93
+ return this.host.sources().map((source) => {
94
+ const workspace = this.workspace(source.id);
95
+ const state = workspace.readState();
96
+ const plan = workspace.readPlan();
97
+ const summary = {
98
+ id: source.id,
99
+ repo: source.repo,
100
+ ref: source.ref,
101
+ mirror: this.effectiveMirror(source),
102
+ enabled: source.enabled,
103
+ files: Object.keys(state.files).length,
104
+ pending: plan === undefined ? 0 : plan.changes.length,
105
+ };
106
+ if (state.appliedAt !== undefined)
107
+ summary.appliedAt = state.appliedAt;
108
+ if (state.headSha !== undefined)
109
+ summary.headSha = state.headSha;
110
+ return summary;
111
+ });
112
+ }
113
+ /**
114
+ * Check one source against its upstream and stage whatever changed.
115
+ * @param slug - source id.
116
+ * @returns the check outcome, tagged with its source.
117
+ * @throws {CheckError} when the source is unknown, switched off, or the check cannot conclude.
118
+ */
119
+ async check(slug) {
120
+ const source = this.writableSource(slug);
121
+ const outcome = await checkSource({
122
+ source,
123
+ workspace: this.workspace(slug),
124
+ fetcher: createFetcher({ proxy: this.host.proxy(), mirror: this.effectiveMirror(source) }),
125
+ });
126
+ return { ...outcome, slug };
127
+ }
128
+ /**
129
+ * Apply what a check staged.
130
+ * @param slug - source id.
131
+ * @param files - paths to apply; all staged changes when omitted.
132
+ * @returns what landed and the index that resulted.
133
+ * @throws {CheckError} when nothing is staged for this source.
134
+ */
135
+ async apply(slug, files) {
136
+ const source = this.writableSource(slug);
137
+ const workspace = this.workspace(slug);
138
+ const plan = workspace.readPlan();
139
+ if (plan === undefined)
140
+ throw new CheckError('nothing-staged', `${slug} 还没有检查结果,先点「检查更新」`);
141
+ const state = workspace.readState();
142
+ const next = applyChanges({
143
+ workspace,
144
+ state,
145
+ plan,
146
+ source,
147
+ ...(files === undefined ? {} : { selected: files }),
148
+ nowIso: new Date().toISOString(),
149
+ });
150
+ workspace.writeState(next.state);
151
+ workspace.clearStaging();
152
+ this.cachedLocations = undefined;
153
+ const entries = await this.syncEntries();
154
+ return { slug, applied: next.applied, entries };
155
+ }
156
+ /**
157
+ * Put back the version the last apply replaced.
158
+ * @param slug - source id.
159
+ * @returns the paths that moved back and the index that resulted.
160
+ */
161
+ async revert(slug) {
162
+ this.writableSource(slug);
163
+ const workspace = this.workspace(slug);
164
+ const next = revertChanges({ workspace, state: workspace.readState() });
165
+ workspace.writeState(next.state);
166
+ workspace.clearStaging();
167
+ this.cachedLocations = undefined;
168
+ const entries = await this.syncEntries();
169
+ return { slug, reverted: next.reverted, entries };
170
+ }
171
+ /**
172
+ * Forget one source: its files and its entries.
173
+ *
174
+ * A source that is switched off can still be forgotten: removing it is exactly
175
+ * what a person does with one they no longer want.
176
+ *
177
+ * @param slug - source id.
178
+ * @returns the index that resulted.
179
+ */
180
+ async remove(slug) {
181
+ this.workspace(slug).remove();
182
+ this.cachedLocations = undefined;
183
+ const entries = await this.syncEntries();
184
+ return { slug, entries };
185
+ }
186
+ /**
187
+ * Rebuild the index's subscribed half from every source's state.
188
+ *
189
+ * Local entries are carried through untouched. A subscribed entry keeps the
190
+ * title, placement, and switch a person gave it; an entry seen for the first
191
+ * time arrives disabled, because remote prose must not reach the prompt before
192
+ * someone turns it on.
193
+ *
194
+ * @returns the index now in force.
195
+ */
196
+ async syncEntries() {
197
+ const current = this.host.entries();
198
+ const previous = new Map(current.filter((entry) => entry.source !== undefined).map((entry) => [entry.id, entry]));
199
+ const locals = current.filter((entry) => entry.source === undefined);
200
+ const subscribed = [];
201
+ let order = this.host.nextOrder();
202
+ for (const source of this.host.sources()) {
203
+ const state = this.workspace(source.id).readState();
204
+ for (const [path, file] of Object.entries(state.files)) {
205
+ // What this file was called before, when the last apply changed its id:
206
+ // a manifest that started declaring its own `id`, or a rename. The title,
207
+ // placement, and switch a person gave the old id belong to the entry that
208
+ // is still this prompt, so they move with it rather than starting over.
209
+ const history = file.renamedFromId === undefined ? undefined : previous.get(file.renamedFromId);
210
+ const known = previous.get(file.id) ?? history;
211
+ // `file` here is the state record, so the manifest path is `path`.
212
+ const title = known?.title ?? file.title ?? titleFor(source, { file: path });
213
+ const placement = known?.order ?? file.order ?? order;
214
+ if (known === undefined && file.order === undefined)
215
+ order += 10;
216
+ subscribed.push({
217
+ id: file.id,
218
+ title: title.length > 0 ? title : stemOf(path),
219
+ order: placement,
220
+ enabled: known?.enabled ?? false,
221
+ source: source.id,
222
+ });
223
+ }
224
+ }
225
+ const next = [...locals, ...subscribed];
226
+ if (JSON.stringify(next) !== JSON.stringify(current))
227
+ await this.host.setEntries(next);
228
+ return next;
229
+ }
230
+ /**
231
+ * The mirror actually used for one source.
232
+ * @param source - the source.
233
+ * @returns its own mirror, or the global one.
234
+ */
235
+ effectiveMirror(source) {
236
+ return source.mirror.length > 0 ? source.mirror : this.host.mirror();
237
+ }
238
+ /**
239
+ * Look one source up.
240
+ * @param slug - source id.
241
+ * @returns the source.
242
+ * @throws {CheckError} when no such source is configured.
243
+ */
244
+ source(slug) {
245
+ const found = this.host.sources().find((candidate) => candidate.id === slug);
246
+ if (found === undefined)
247
+ throw new CheckError('unknown-source', `没有这个订阅源:${slug}`);
248
+ return found;
249
+ }
250
+ /**
251
+ * Look up a source that may be operated on.
252
+ *
253
+ * A switched-off source keeps the bodies it already applied — turning it off
254
+ * is not a way to erase entries that are in force — but it takes no new work
255
+ * from upstream until it is switched back on.
256
+ *
257
+ * @param slug - source id.
258
+ * @returns the source.
259
+ * @throws {CheckError} when no such source is configured, or it is switched off.
260
+ */
261
+ writableSource(slug) {
262
+ const source = this.source(slug);
263
+ if (!source.enabled) {
264
+ throw new CheckError('disabled', `${slug} 已关闭:在设置页打开它,或删掉它,再对上游做操作`);
265
+ }
266
+ return source;
267
+ }
268
+ }
269
+ //# sourceMappingURL=subscriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriptions.js","sourceRoot":"","sources":["../src/subscriptions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAoB,MAAM,UAAU,CAAA;AAC1D,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAA;AACvD,OAAO,EACL,YAAY,EACZ,WAAW,EACX,UAAU,EACV,aAAa,EACb,eAAe,EACf,QAAQ,GAGT,MAAM,WAAW,CAAA;AA+DlB,+BAA+B;AAC/B,MAAM,OAAO,aAAa;IACP,IAAI,CAAkB;IAEvC,8DAA8D;IAC7C,WAAW,CAAmC;IAE/D;;;;;;;OAOG;IACK,eAAe,CAA+C;IAEtE;;;OAGG;IACH,YAAY,IAAsB,EAAE,UAA6D,EAAE;QACjG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,CAAA;IACjG,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,IAAY;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,IAAI,CAAC,eAAe,KAAK,IAAI,CAAC,gBAAgB,EAAE,CAAA;QAChD,OAAO,IAAI,CAAC,eAAe,CAAA;IAC7B,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB;QACd,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;QAChC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAA;IACtB,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,EAAU;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACtC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;IACrE,CAAC;IAED,8DAA8D;IACtD,gBAAgB;QACtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAgC,CAAA;QACvD,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAA;YACnD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;YACjD,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACxC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,EAAE,CAAA;YACnC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAA;YACjC,MAAM,OAAO,GAAkB;gBAC7B,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;gBACpC,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM;gBACtC,OAAO,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;aACtD,CAAA;YACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;gBAAE,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;YACtE,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;gBAAE,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAA;YAChE,OAAO,OAAO,CAAA;QAChB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QACxC,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC;YAChC,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC/B,OAAO,EAAE,aAAa,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;SAC3F,CAAC,CAAA;QACF,OAAO,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,CAAA;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,KAAyB;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAA;QACjC,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,GAAG,IAAI,mBAAmB,CAAC,CAAA;QAC1F,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,EAAE,CAAA;QACnC,MAAM,IAAI,GAAG,YAAY,CAAC;YACxB,SAAS;YACT,KAAK;YACL,IAAI;YACJ,MAAM;YACN,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;YACnD,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACjC,CAAC,CAAA;QACF,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChC,SAAS,CAAC,YAAY,EAAE,CAAA;QACxB,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;QAChC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;QACxC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAA;IACjD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACtC,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QACvE,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChC,SAAS,CAAC,YAAY,EAAE,CAAA;QACxB,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;QAChC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;QACxC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnD,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAA;QAC7B,IAAI,CAAC,eAAe,GAAG,SAAS,CAAA;QAChC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;QACxC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC1B,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,WAAW;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAA;QACnC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;QACjH,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAA;QACpE,MAAM,UAAU,GAAkB,EAAE,CAAA;QACpC,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAA;QACjC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,CAAA;YACnD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,wEAAwE;gBACxE,0EAA0E;gBAC1E,0EAA0E;gBAC1E,wEAAwE;gBACxE,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;gBAC/F,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,OAAO,CAAA;gBAC9C,mEAAmE;gBACnE,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;gBAC5E,MAAM,SAAS,GAAG,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,CAAA;gBACrD,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;oBAAE,KAAK,IAAI,EAAE,CAAA;gBAChE,UAAU,CAAC,IAAI,CAAC;oBACd,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;oBAC9C,KAAK,EAAE,SAAS;oBAChB,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK;oBAChC,MAAM,EAAE,MAAM,CAAC,EAAE;iBAClB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,UAAU,CAAC,CAAA;QACvC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACtF,OAAO,IAAI,CAAA;IACb,CAAC;IACD;;;;OAIG;IACK,eAAe,CAAC,MAAoB;QAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAA;IACtE,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,IAAY;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,CAAA;QAC5E,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,WAAW,IAAI,EAAE,CAAC,CAAA;QAClF,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;;;;;;;;;OAUG;IACK,cAAc,CAAC,IAAY;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,UAAU,CAAC,UAAU,EAAE,GAAG,IAAI,2BAA2B,CAAC,CAAA;QACtE,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;CACF"}