@agimon-ai/po-config 0.0.0-alpha.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 (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +170 -0
  3. package/dist/agentPluginMcp.cjs +322 -0
  4. package/dist/agentPluginMcp.cjs.map +1 -0
  5. package/dist/agentPluginMcp.d.mts +38 -0
  6. package/dist/agentPluginMcp.d.mts.map +1 -0
  7. package/dist/agentPluginMcp.mjs +318 -0
  8. package/dist/agentPluginMcp.mjs.map +1 -0
  9. package/dist/apiContracts.cjs +203 -0
  10. package/dist/apiContracts.cjs.map +1 -0
  11. package/dist/apiContracts.d.mts +53 -0
  12. package/dist/apiContracts.d.mts.map +1 -0
  13. package/dist/apiContracts.mjs +198 -0
  14. package/dist/apiContracts.mjs.map +1 -0
  15. package/dist/atomicJson-1W0WhuFF.mjs +44 -0
  16. package/dist/atomicJson-1W0WhuFF.mjs.map +1 -0
  17. package/dist/atomicJson-Dt2z_DXl.cjs +52 -0
  18. package/dist/atomicJson-Dt2z_DXl.cjs.map +1 -0
  19. package/dist/atomicJson.cjs +3 -0
  20. package/dist/atomicJson.d.mts +2 -0
  21. package/dist/atomicJson.mjs +2 -0
  22. package/dist/config-BUw5kHsx.cjs +219 -0
  23. package/dist/config-BUw5kHsx.cjs.map +1 -0
  24. package/dist/config-CKA07FxG.mjs +162 -0
  25. package/dist/config-CKA07FxG.mjs.map +1 -0
  26. package/dist/config-Cm3EV1jp.d.mts +320 -0
  27. package/dist/config-Cm3EV1jp.d.mts.map +1 -0
  28. package/dist/config-NSHRd6na.mjs +2 -0
  29. package/dist/config-zZz80Mh5.cjs +1 -0
  30. package/dist/config.cjs +24 -0
  31. package/dist/config.d.mts +3 -0
  32. package/dist/config.mjs +3 -0
  33. package/dist/configPolicy--TNX7feH.mjs +718 -0
  34. package/dist/configPolicy--TNX7feH.mjs.map +1 -0
  35. package/dist/configPolicy-DmsZEp0t.cjs +795 -0
  36. package/dist/configPolicy-DmsZEp0t.cjs.map +1 -0
  37. package/dist/configSchema.cjs +0 -0
  38. package/dist/configSchema.d.mts +2 -0
  39. package/dist/configSchema.mjs +1 -0
  40. package/dist/configWriter-BTuinLjs.cjs +150 -0
  41. package/dist/configWriter-BTuinLjs.cjs.map +1 -0
  42. package/dist/configWriter-BgkGaLrf.mjs +130 -0
  43. package/dist/configWriter-BgkGaLrf.mjs.map +1 -0
  44. package/dist/configWriter.cjs +5 -0
  45. package/dist/configWriter.d.mts +2 -0
  46. package/dist/configWriter.mjs +2 -0
  47. package/dist/domains-CBYkuxs5.cjs +727 -0
  48. package/dist/domains-CBYkuxs5.cjs.map +1 -0
  49. package/dist/domains-DZOu9vYM.mjs +633 -0
  50. package/dist/domains-DZOu9vYM.mjs.map +1 -0
  51. package/dist/domains.cjs +19 -0
  52. package/dist/domains.d.mts +3 -0
  53. package/dist/domains.mjs +3 -0
  54. package/dist/extensions/mcp-ui.mjs +101 -0
  55. package/dist/extensions/mcp-ui.mjs.map +1 -0
  56. package/dist/extensions/mcp.cjs +171 -0
  57. package/dist/extensions/mcp.cjs.map +1 -0
  58. package/dist/extensions/mcp.d.mts +5 -0
  59. package/dist/extensions/mcp.d.mts.map +1 -0
  60. package/dist/extensions/mcp.mjs +166 -0
  61. package/dist/extensions/mcp.mjs.map +1 -0
  62. package/dist/extensions/server.cjs +504 -0
  63. package/dist/extensions/server.cjs.map +1 -0
  64. package/dist/extensions/server.d.mts +5 -0
  65. package/dist/extensions/server.d.mts.map +1 -0
  66. package/dist/extensions/server.mjs +499 -0
  67. package/dist/extensions/server.mjs.map +1 -0
  68. package/dist/harnessState-CCyBeutB.cjs +188 -0
  69. package/dist/harnessState-CCyBeutB.cjs.map +1 -0
  70. package/dist/harnessState-Dn_S7fB9.mjs +163 -0
  71. package/dist/harnessState-Dn_S7fB9.mjs.map +1 -0
  72. package/dist/harnessState.cjs +6 -0
  73. package/dist/harnessState.d.mts +2 -0
  74. package/dist/harnessState.mjs +2 -0
  75. package/dist/harnessStore-CJSxdSkV.cjs +343 -0
  76. package/dist/harnessStore-CJSxdSkV.cjs.map +1 -0
  77. package/dist/harnessStore-CltwLB7M.mjs +262 -0
  78. package/dist/harnessStore-CltwLB7M.mjs.map +1 -0
  79. package/dist/harnessStore.cjs +15 -0
  80. package/dist/harnessStore.d.mts +2 -0
  81. package/dist/harnessStore.mjs +2 -0
  82. package/dist/index-BAaTySaM.d.mts +35 -0
  83. package/dist/index-BAaTySaM.d.mts.map +1 -0
  84. package/dist/index-BT29GZx5.d.mts +142 -0
  85. package/dist/index-BT29GZx5.d.mts.map +1 -0
  86. package/dist/index-B_lp0W3U.d.mts +114 -0
  87. package/dist/index-B_lp0W3U.d.mts.map +1 -0
  88. package/dist/index-C6GaYjq-.d.mts +6 -0
  89. package/dist/index-C6GaYjq-.d.mts.map +1 -0
  90. package/dist/index-CIQrKS1A.d.mts +50 -0
  91. package/dist/index-CIQrKS1A.d.mts.map +1 -0
  92. package/dist/index-CRcoVYXz.d.mts +39 -0
  93. package/dist/index-CRcoVYXz.d.mts.map +1 -0
  94. package/dist/index-CVlciCJF.d.mts +40 -0
  95. package/dist/index-CVlciCJF.d.mts.map +1 -0
  96. package/dist/index-CeOk2kqs.d.mts +118 -0
  97. package/dist/index-CeOk2kqs.d.mts.map +1 -0
  98. package/dist/index-Ch7ptOkW.d.mts +54 -0
  99. package/dist/index-Ch7ptOkW.d.mts.map +1 -0
  100. package/dist/index-Cvdt-Y-i.d.mts +66 -0
  101. package/dist/index-Cvdt-Y-i.d.mts.map +1 -0
  102. package/dist/index-DJpG-I9K.d.mts +122 -0
  103. package/dist/index-DJpG-I9K.d.mts.map +1 -0
  104. package/dist/index-DNk4q0Qm.d.mts +81 -0
  105. package/dist/index-DNk4q0Qm.d.mts.map +1 -0
  106. package/dist/index.cjs +121 -0
  107. package/dist/index.d.mts +15 -0
  108. package/dist/index.mjs +15 -0
  109. package/dist/init-C_9nyp3-.cjs +448 -0
  110. package/dist/init-C_9nyp3-.cjs.map +1 -0
  111. package/dist/init-DJ6wm-dr.mjs +415 -0
  112. package/dist/init-DJ6wm-dr.mjs.map +1 -0
  113. package/dist/init.cjs +7 -0
  114. package/dist/init.d.mts +2 -0
  115. package/dist/init.mjs +2 -0
  116. package/dist/layeredConfig-B922ibgn.mjs +67 -0
  117. package/dist/layeredConfig-B922ibgn.mjs.map +1 -0
  118. package/dist/layeredConfig-DdI5ysUf.cjs +94 -0
  119. package/dist/layeredConfig-DdI5ysUf.cjs.map +1 -0
  120. package/dist/layeredConfig.cjs +6 -0
  121. package/dist/layeredConfig.d.mts +2 -0
  122. package/dist/layeredConfig.mjs +2 -0
  123. package/dist/majorModes-CmPLEpMT.mjs +333 -0
  124. package/dist/majorModes-CmPLEpMT.mjs.map +1 -0
  125. package/dist/majorModes-DPhVMuhT.cjs +383 -0
  126. package/dist/majorModes-DPhVMuhT.cjs.map +1 -0
  127. package/dist/majorModes.cjs +10 -0
  128. package/dist/majorModes.d.mts +2 -0
  129. package/dist/majorModes.mjs +2 -0
  130. package/dist/piConfig-Bx26HMb_.d.mts +33 -0
  131. package/dist/piConfig-Bx26HMb_.d.mts.map +1 -0
  132. package/dist/piConfig-CCBdZXQr.cjs +260 -0
  133. package/dist/piConfig-CCBdZXQr.cjs.map +1 -0
  134. package/dist/piConfig-qGyCbcVj.mjs +197 -0
  135. package/dist/piConfig-qGyCbcVj.mjs.map +1 -0
  136. package/dist/piConfig.cjs +12 -0
  137. package/dist/piConfig.d.mts +2 -0
  138. package/dist/piConfig.mjs +2 -0
  139. package/dist/piContext.cjs +18 -0
  140. package/dist/piContext.d.mts +3 -0
  141. package/dist/piContext.mjs +2 -0
  142. package/dist/profiles-CTrUCmIh.d.mts +27 -0
  143. package/dist/profiles-CTrUCmIh.d.mts.map +1 -0
  144. package/dist/profiles-DnF9DBpd.cjs +552 -0
  145. package/dist/profiles-DnF9DBpd.cjs.map +1 -0
  146. package/dist/profiles-fujQKrS0.mjs +483 -0
  147. package/dist/profiles-fujQKrS0.mjs.map +1 -0
  148. package/dist/profiles.cjs +13 -0
  149. package/dist/profiles.d.mts +25 -0
  150. package/dist/profiles.d.mts.map +1 -0
  151. package/dist/profiles.mjs +2 -0
  152. package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
  153. package/dist/selectionSwitch.cjs +70 -0
  154. package/dist/selectionSwitch.cjs.map +1 -0
  155. package/dist/selectionSwitch.d.mts +30 -0
  156. package/dist/selectionSwitch.d.mts.map +1 -0
  157. package/dist/selectionSwitch.mjs +64 -0
  158. package/dist/selectionSwitch.mjs.map +1 -0
  159. package/dist/sessionConfig-Boh4Fdje.cjs +342 -0
  160. package/dist/sessionConfig-Boh4Fdje.cjs.map +1 -0
  161. package/dist/sessionConfig-CtLoc-lO.mjs +240 -0
  162. package/dist/sessionConfig-CtLoc-lO.mjs.map +1 -0
  163. package/dist/types.cjs +9 -0
  164. package/dist/types.d.mts +2 -0
  165. package/dist/types.mjs +2 -0
  166. package/llms.txt +12 -0
  167. package/package.json +206 -0
  168. package/src/prompts/po-author-config/SKILL.md +26 -0
  169. package/src/prompts/po-author-config/agents/openai.yaml +4 -0
  170. package/src/prompts/po-author-config/references/config-contract.md +201 -0
@@ -0,0 +1,552 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
+ const require_layeredConfig = require("./layeredConfig-DdI5ysUf.cjs");
3
+ let node_fs = require("node:fs");
4
+ node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
5
+ let node_path = require("node:path");
6
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
7
+ let node_os = require("node:os");
8
+ node_os = require_rolldown_runtime.__toESM(node_os, 1);
9
+ let yaml = require("yaml");
10
+ let _agimon_ai_po_core_profileIdentity = require("@agimon-ai/po-core/profileIdentity");
11
+ //#region src/services/personaFrontMatter/index.ts
12
+ /**
13
+ * Optional identity a persona declares at the top of its `profile.md`.
14
+ *
15
+ * A profile used to be prompt text only, so there was nowhere to say who the
16
+ * persona is or how it should sound. Front-matter puts that beside the persona
17
+ * text it describes, which is the only place that works for both explicit
18
+ * `profiles.yaml` entries and folders found by root discovery.
19
+ *
20
+ * Recognition is deliberately narrow. Personas that exist today were written
21
+ * without any of this, and one of them may legitimately open with a horizontal
22
+ * rule, so a leading fence alone is not enough to claim the block. A block is
23
+ * only treated as identity when it is fenced at the very first line, closed,
24
+ * parses as a mapping, and declares at least one field this contract owns.
25
+ * Anything else is passed through byte for byte.
26
+ */
27
+ const FENCE = "---";
28
+ const OWNED_KEYS = [
29
+ "name",
30
+ "icon",
31
+ "voice"
32
+ ];
33
+ function isRecord$1(value) {
34
+ return typeof value === "object" && value !== null && !Array.isArray(value);
35
+ }
36
+ function readVoice(value) {
37
+ if (!isRecord$1(value)) return void 0;
38
+ const voice = typeof value.voice === "string" && value.voice.trim().length > 0 ? value.voice.trim() : void 0;
39
+ const rate = typeof value.rate === "number" && Number.isFinite(value.rate) ? value.rate : void 0;
40
+ if (voice === void 0 && rate === void 0) return void 0;
41
+ return {
42
+ ...voice === void 0 ? {} : { voice },
43
+ ...rate === void 0 ? {} : { rate }
44
+ };
45
+ }
46
+ function readFrontMatter(parsed) {
47
+ const name = typeof parsed.name === "string" && parsed.name.trim().length > 0 ? parsed.name.trim() : void 0;
48
+ const icon = typeof parsed.icon === "string" && parsed.icon.trim().length > 0 ? parsed.icon.trim() : void 0;
49
+ const voice = readVoice(parsed.voice);
50
+ if (name === void 0 && icon === void 0 && voice === void 0) return void 0;
51
+ return {
52
+ ...name === void 0 ? {} : { name },
53
+ ...icon === void 0 ? {} : { icon },
54
+ ...voice === void 0 ? {} : { voice }
55
+ };
56
+ }
57
+ /**
58
+ * Splits a recognised identity block off a persona document.
59
+ *
60
+ * Never throws: a malformed avatar must not make a persona unloadable, so an
61
+ * unparseable or unrecognised block leaves the document exactly as it arrived.
62
+ */
63
+ function parsePersonaFrontMatter(content) {
64
+ const lines = content.split("\n");
65
+ if (lines[0]?.trimEnd() !== FENCE) return { body: content };
66
+ const closingIndex = lines.findIndex((line, index) => index > 0 && line.trimEnd() === FENCE);
67
+ if (closingIndex === -1) return { body: content };
68
+ let parsed;
69
+ try {
70
+ parsed = (0, yaml.parse)(lines.slice(1, closingIndex).join("\n"));
71
+ } catch {
72
+ return { body: content };
73
+ }
74
+ if (!isRecord$1(parsed)) return { body: content };
75
+ if (!OWNED_KEYS.some((key) => Object.hasOwn(parsed, key))) return { body: content };
76
+ const frontMatter = readFrontMatter(parsed);
77
+ if (!frontMatter) return { body: content };
78
+ return {
79
+ frontMatter,
80
+ body: lines.slice(closingIndex + 1).join("\n")
81
+ };
82
+ }
83
+ //#endregion
84
+ //#region src/services/personaIcon/index.ts
85
+ /**
86
+ * Reads a persona icon into a bounded `data:` URL.
87
+ *
88
+ * The icon travels inside the journalled identity entry rather than through an
89
+ * HTTP route. A route would leave a request-time filesystem resolution reachable
90
+ * from the browser for the life of a session, defended on every request forever;
91
+ * this resolves the path once, server side, at the moment the profile loads.
92
+ *
93
+ * The path comes from user-authored front-matter, so it is confined the same way
94
+ * `buildPersonaPrompt` confines persona files: a symlink must not read outside
95
+ * the persona directory.
96
+ *
97
+ * Every failure is silent and returns undefined. An avatar is decoration, and a
98
+ * broken one must never stop a persona from loading.
99
+ */
100
+ const PARENT_DIRECTORY$1 = "..";
101
+ /**
102
+ * Magic-byte signatures, checked instead of trusting the filename.
103
+ *
104
+ * `image/svg+xml` is absent on purpose: an SVG rendered same-origin executes
105
+ * script, and the author of this path is whoever wrote the persona. Do not add
106
+ * it to match the cockpit's broader media catalog.
107
+ */
108
+ const SIGNATURES = [
109
+ {
110
+ mime: "image/png",
111
+ test: (b) => b.length > 8 && b.subarray(0, 8).equals(Buffer.from([
112
+ 137,
113
+ 80,
114
+ 78,
115
+ 71,
116
+ 13,
117
+ 10,
118
+ 26,
119
+ 10
120
+ ]))
121
+ },
122
+ {
123
+ mime: "image/jpeg",
124
+ test: (b) => b.length > 3 && b[0] === 255 && b[1] === 216 && b[2] === 255
125
+ },
126
+ {
127
+ mime: "image/gif",
128
+ test: (b) => b.length > 6 && b.subarray(0, 6).toString("latin1").startsWith("GIF8")
129
+ },
130
+ {
131
+ mime: "image/webp",
132
+ test: (b) => b.length > 12 && b.subarray(0, 4).toString("latin1") === "RIFF" && b.subarray(8, 12).toString("latin1") === "WEBP"
133
+ }
134
+ ];
135
+ function sniff(bytes) {
136
+ return SIGNATURES.find((signature) => signature.test(bytes))?.mime;
137
+ }
138
+ /**
139
+ * Resolves an icon declared in persona front-matter, or undefined when it is
140
+ * missing, unreadable, not an allowed image, escapes the persona directory, or
141
+ * exceeds the data-URL ceiling.
142
+ */
143
+ function readPersonaIcon(personaPath, iconRelative) {
144
+ if (node_path.default.isAbsolute(iconRelative)) return void 0;
145
+ try {
146
+ const realPersonaPath = node_fs.default.realpathSync(personaPath);
147
+ const iconPath = node_path.default.resolve(realPersonaPath, iconRelative);
148
+ if (!node_fs.default.existsSync(iconPath)) return void 0;
149
+ const realIconPath = node_fs.default.realpathSync(iconPath);
150
+ const relative = node_path.default.relative(realPersonaPath, realIconPath);
151
+ if (relative === PARENT_DIRECTORY$1 || relative.startsWith(`${PARENT_DIRECTORY$1}${node_path.default.sep}`) || node_path.default.isAbsolute(relative)) return;
152
+ if (!node_fs.default.statSync(realIconPath).isFile()) return void 0;
153
+ const bytes = node_fs.default.readFileSync(realIconPath);
154
+ const mime = sniff(bytes);
155
+ if (!mime) return void 0;
156
+ const dataUrl = `data:${mime};base64,${bytes.toString("base64")}`;
157
+ return dataUrl.length > _agimon_ai_po_core_profileIdentity.PROFILE_ICON_MAX_DATA_URL_LENGTH ? void 0 : dataUrl;
158
+ } catch {
159
+ return;
160
+ }
161
+ }
162
+ //#endregion
163
+ //#region src/services/profileBinding/index.ts
164
+ const BINDING_KEYS = /* @__PURE__ */ new Set([
165
+ "provider",
166
+ "organizationId",
167
+ "mailboxId",
168
+ "credentialRef",
169
+ "secrets",
170
+ "browser"
171
+ ]);
172
+ const SECRET_KEYS = /* @__PURE__ */ new Set([
173
+ "credentialId",
174
+ "field",
175
+ "allowedOrigins"
176
+ ]);
177
+ const BROWSER_KEYS = /* @__PURE__ */ new Set(["profileName", "allowedOrigins"]);
178
+ const ALIAS_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;
179
+ const FIELD_PATTERN = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;
180
+ const BROWSER_PROFILE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
181
+ function record(value, location, keys) {
182
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${location} must be a mapping`);
183
+ if (keys && Object.keys(value).some((key) => !keys.has(key))) throw new Error(`${location} contains unsupported metadata`);
184
+ return value;
185
+ }
186
+ function reference(value, location) {
187
+ if (typeof value !== "string" || value.length === 0 || value.length > 256 || /\s/.test(value)) throw new Error(`${location} must be a non-empty reference without whitespace`);
188
+ return value;
189
+ }
190
+ function origins(value, location) {
191
+ if (!Array.isArray(value) || value.length === 0) throw new Error(`${location} must contain exact HTTP(S) origins`);
192
+ const result = value.map((entry) => {
193
+ if (typeof entry !== "string") throw new Error(`${location} must contain exact HTTP(S) origins`);
194
+ let url;
195
+ try {
196
+ url = new URL(entry);
197
+ } catch {
198
+ throw new Error(`${location} must contain exact HTTP(S) origins`);
199
+ }
200
+ if (url.protocol !== "https:" && url.protocol !== "http:" || url.origin !== entry || url.username || url.password) throw new Error(`${location} must contain exact HTTP(S) origins`);
201
+ return entry;
202
+ });
203
+ return Object.freeze([...new Set(result)]);
204
+ }
205
+ function browser(value, location) {
206
+ const entry = record(value, location, BROWSER_KEYS);
207
+ if (typeof entry.profileName !== "string" || !BROWSER_PROFILE_PATTERN.test(entry.profileName)) throw new Error(`${location}.profileName must be a safe browser profile name`);
208
+ return Object.freeze({
209
+ profileName: entry.profileName,
210
+ allowedOrigins: origins(entry.allowedOrigins, `${location}.allowedOrigins`)
211
+ });
212
+ }
213
+ /** Validates and deeply freezes a detached metadata snapshot. No provider SDK or secret is loaded. */
214
+ function parseProfileBinding(value, location = "Profile integration") {
215
+ const entry = record(value, location, BINDING_KEYS);
216
+ const sourceSecrets = record(entry.secrets, `${location}.secrets`);
217
+ const secrets = {};
218
+ for (const [alias, value] of Object.entries(sourceSecrets)) {
219
+ if (!ALIAS_PATTERN.test(alias)) throw new Error(`${location}.secrets requires uppercase alias names`);
220
+ const secret = record(value, `${location}.secrets.${alias}`, SECRET_KEYS);
221
+ if (typeof secret.field !== "string" || !FIELD_PATTERN.test(secret.field)) throw new Error(`${location}.secrets.${alias}.field must be a credential field name`);
222
+ secrets[alias] = Object.freeze({
223
+ credentialId: reference(secret.credentialId, `${location}.secrets.${alias}.credentialId`),
224
+ field: secret.field,
225
+ allowedOrigins: origins(secret.allowedOrigins, `${location}.secrets.${alias}.allowedOrigins`)
226
+ });
227
+ }
228
+ const browserBinding = entry.browser === void 0 ? void 0 : browser(entry.browser, `${location}.browser`);
229
+ if (browserBinding && Object.values(secrets).some((secret) => secret.allowedOrigins.some((origin) => !browserBinding.allowedOrigins.includes(origin)))) throw new Error(`${location} secret origins must be included in browser.allowedOrigins`);
230
+ return Object.freeze({
231
+ provider: reference(entry.provider, `${location}.provider`),
232
+ organizationId: reference(entry.organizationId, `${location}.organizationId`),
233
+ mailboxId: reference(entry.mailboxId, `${location}.mailboxId`),
234
+ credentialRef: reference(entry.credentialRef, `${location}.credentialRef`),
235
+ secrets: Object.freeze(secrets),
236
+ ...browserBinding === void 0 ? {} : { browser: browserBinding }
237
+ });
238
+ }
239
+ //#endregion
240
+ //#region src/services/profiles/index.ts
241
+ /** Files that make up one repository persona, concatenated in this order. */
242
+ const PERSONA_FILES = [
243
+ "profile.md",
244
+ "SOUL.md",
245
+ "AGENTS.md"
246
+ ];
247
+ /** The persona file that may carry an identity block; the others are prose only. */
248
+ const PERSONA_IDENTITY_FILE = "profile.md";
249
+ const PROFILE_KEYS = /* @__PURE__ */ new Set([
250
+ "persona",
251
+ "env",
252
+ "integration"
253
+ ]);
254
+ const PROFILE_CATALOG_KEYS = /* @__PURE__ */ new Set([
255
+ "roots",
256
+ "entries",
257
+ "defaultProfile"
258
+ ]);
259
+ const PROFILES_FILE = "profiles.yaml";
260
+ const PROFILES_ROOT_KEY = "profiles";
261
+ const AGENTS_DIRECTORY = "agents";
262
+ const PARENT_DIRECTORY = "..";
263
+ const TEXT_ENCODING = "utf8";
264
+ function isRecord(value) {
265
+ return typeof value === "object" && value !== null && !Array.isArray(value);
266
+ }
267
+ function isPathInside(root, candidate) {
268
+ const relative = node_path.default.relative(root, candidate);
269
+ return relative === "" || !node_path.default.isAbsolute(relative) && relative !== PARENT_DIRECTORY && !relative.startsWith(`${PARENT_DIRECTORY}${node_path.default.sep}`);
270
+ }
271
+ function parseEnvironment(name, value) {
272
+ if (value === void 0) return {};
273
+ if (!isRecord(value)) throw new Error(`Profile "${name}" env must be a string mapping`);
274
+ const environment = {};
275
+ for (const [key, entry] of Object.entries(value)) {
276
+ if (typeof entry !== "string") throw new Error(`Profile "${name}" env.${key} must be a string`);
277
+ if (entry.includes("${secrets.")) throw new Error(`Profile "${name}" env cannot contain secret aliases`);
278
+ environment[key] = entry;
279
+ }
280
+ return environment;
281
+ }
282
+ function parseProfileRoots(value, filePath, baseDirectory) {
283
+ if (value === void 0) return [];
284
+ if (!Array.isArray(value)) throw new Error(`profiles.roots in ${filePath} must be an array`);
285
+ return value.map((entry, index) => {
286
+ if (typeof entry !== "string" || entry.trim().length === 0) throw new Error(`profiles.roots[${index}] in ${filePath} must be a non-empty string`);
287
+ return node_path.default.resolve(baseDirectory, entry.trim());
288
+ });
289
+ }
290
+ function parseProfileLayer(source) {
291
+ if (!isRecord(source.document) || !isRecord(source.document[PROFILES_ROOT_KEY])) throw new Error(`${source.filePath} must contain a profiles mapping`);
292
+ const unsupportedDocumentKeys = Object.keys(source.document).filter((key) => key !== PROFILES_ROOT_KEY);
293
+ if (unsupportedDocumentKeys.length > 0) throw new Error(`${source.filePath} may only contain profiles; unsupported: ${unsupportedDocumentKeys.join(", ")}`);
294
+ const profiles = source.document[PROFILES_ROOT_KEY];
295
+ if (!(Object.hasOwn(profiles, "roots") || Object.hasOwn(profiles, "entries"))) return {
296
+ filePath: source.filePath,
297
+ baseDirectory: source.baseDirectory,
298
+ roots: [],
299
+ entries: profiles
300
+ };
301
+ const unsupportedCatalogKeys = Object.keys(profiles).filter((key) => !PROFILE_CATALOG_KEYS.has(key));
302
+ if (unsupportedCatalogKeys.length > 0) throw new Error(`profiles in ${source.filePath} may only contain roots, entries and defaultProfile; unsupported: ${unsupportedCatalogKeys.join(", ")}`);
303
+ if (profiles.defaultProfile !== void 0 && (typeof profiles.defaultProfile !== "string" || profiles.defaultProfile.trim().length === 0)) throw new Error(`profiles.defaultProfile in ${source.filePath} must be a non-empty string`);
304
+ if (profiles.entries !== void 0 && !isRecord(profiles.entries)) throw new Error(`profiles.entries in ${source.filePath} must be a mapping`);
305
+ return {
306
+ filePath: source.filePath,
307
+ baseDirectory: source.baseDirectory,
308
+ roots: parseProfileRoots(profiles.roots, source.filePath, source.baseDirectory),
309
+ entries: profiles.entries ?? {},
310
+ ...profiles.defaultProfile === void 0 ? {} : { defaultProfile: String(profiles.defaultProfile).trim() }
311
+ };
312
+ }
313
+ function assertProfileInsideAllowedRoot(name, personaPath, lexicalRoots) {
314
+ const realPersonaPath = node_fs.default.realpathSync(personaPath);
315
+ if (!lexicalRoots.some((root) => isPathInside(node_fs.default.realpathSync(root), realPersonaPath))) throw new Error(`Profile "${name}" persona must stay inside agents/ or a configured profile root`);
316
+ }
317
+ function parseProfile(personaRoot, configuredRoots, name, value) {
318
+ if (!isRecord(value)) throw new Error(`Profile "${name}" must be a mapping`);
319
+ const unsupported = Object.keys(value).filter((key) => !PROFILE_KEYS.has(key));
320
+ if (unsupported.length > 0) throw new Error(`Profile "${name}" may only set persona, env and integration; unsupported: ${unsupported.join(", ")}`);
321
+ if (typeof value.persona !== "string" || value.persona.trim().length === 0) throw new Error(`Profile "${name}" must set a persona`);
322
+ if (node_path.default.isAbsolute(value.persona)) throw new Error(`Profile "${name}" persona must be relative to the config that declares it`);
323
+ const persona = value.persona;
324
+ const personaPath = node_path.default.resolve(personaRoot, persona);
325
+ const lexicalRoots = [node_path.default.resolve(personaRoot, AGENTS_DIRECTORY), ...configuredRoots].filter((root) => isPathInside(root, personaPath));
326
+ if (lexicalRoots.length === 0) throw new Error(`Profile "${name}" persona must stay inside agents/ or a configured profile root`);
327
+ if (!node_fs.default.existsSync(personaPath) || !node_fs.default.statSync(personaPath).isDirectory()) throw new Error(`Profile "${name}" references a missing persona: ${persona}`);
328
+ assertProfileInsideAllowedRoot(name, personaPath, lexicalRoots);
329
+ if (!buildPersonaPrompt(personaRoot, persona)) {
330
+ const declaresIdentity = readPersonaFrontMatter(personaRoot, persona) !== void 0;
331
+ throw new Error(declaresIdentity ? `Profile "${name}" persona declares identity front-matter but no persona text: ${persona}` : `Profile "${name}" persona has no readable persona files: ${persona}`);
332
+ }
333
+ return {
334
+ name,
335
+ persona,
336
+ personaRoot,
337
+ env: parseEnvironment(name, value.env),
338
+ ...value.integration === void 0 ? {} : { integration: parseProfileBinding(value.integration, `Profile "${name}" integration`) },
339
+ ...readPersonaPresentation(personaRoot, persona)
340
+ };
341
+ }
342
+ function containsPersonaFile(directory) {
343
+ return PERSONA_FILES.some((file) => {
344
+ try {
345
+ return node_fs.default.lstatSync(node_path.default.join(directory, file)).isFile();
346
+ } catch {
347
+ return false;
348
+ }
349
+ });
350
+ }
351
+ function discoverProfile(directory, configuredRoot, personaRoot) {
352
+ if (!containsPersonaFile(directory)) return void 0;
353
+ try {
354
+ if (!isPathInside(node_fs.default.realpathSync(configuredRoot), node_fs.default.realpathSync(directory))) return void 0;
355
+ const persona = node_path.default.relative(personaRoot, directory) || ".";
356
+ if (!buildPersonaPrompt(personaRoot, persona)) return void 0;
357
+ return {
358
+ name: node_path.default.basename(directory),
359
+ persona,
360
+ personaRoot,
361
+ env: {},
362
+ ...readPersonaPresentation(personaRoot, persona)
363
+ };
364
+ } catch {
365
+ return;
366
+ }
367
+ }
368
+ function discoverProfileRoot(root, personaRoot) {
369
+ if (!node_fs.default.existsSync(root) || !node_fs.default.statSync(root).isDirectory()) throw new Error(`Configured profile root is not a directory: ${root}`);
370
+ const rootProfile = discoverProfile(root, root, personaRoot);
371
+ if (rootProfile) return [rootProfile];
372
+ return node_fs.default.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).sort((left, right) => left.name.localeCompare(right.name)).flatMap((entry) => {
373
+ const profile = discoverProfile(node_path.default.join(root, entry.name), root, personaRoot);
374
+ return profile ? [profile] : [];
375
+ });
376
+ }
377
+ /**
378
+ * Loads profiles from the global and repository configs, repository last.
379
+ *
380
+ * Configured roots accumulate and inspect themselves or their direct-child
381
+ * directories for persona files. Later discoveries replace earlier names, and
382
+ * explicit entries replace discoveries. Legacy flat profile mappings remain
383
+ * accepted as explicit entries.
384
+ */
385
+ function loadProfiles(repoRoot, homeDirectory = node_os.default.homedir()) {
386
+ const layers = require_layeredConfig.readDoomConfigSources(PROFILES_FILE, repoRoot, homeDirectory).map(parseProfileLayer);
387
+ const byName = /* @__PURE__ */ new Map();
388
+ for (const layer of layers) for (const root of layer.roots) for (const profile of discoverProfileRoot(root, layer.baseDirectory)) byName.set(profile.name, profile);
389
+ for (const layer of layers) for (const [name, value] of Object.entries(layer.entries)) byName.set(name, parseProfile(layer.baseDirectory, layer.roots, name, value));
390
+ return [...byName.values()].sort((left, right) => left.name.localeCompare(right.name));
391
+ }
392
+ /**
393
+ * The profile catalog: every resolved profile, plus the name a launch starts on
394
+ * when the caller names none.
395
+ *
396
+ * `defaultProfile` mirrors `defaultMajorMode` in modes.yaml and `defaultDomains`
397
+ * in domains.yaml, so each selection axis declares its default in its own
398
+ * catalog. A repository declaration replaces a personal one. An unknown name is
399
+ * an error rather than a silent fallback: a typo that quietly starts the session
400
+ * with no persona is worse than a refused launch.
401
+ */
402
+ function loadProfileCatalog(repoRoot, homeDirectory = node_os.default.homedir()) {
403
+ const layers = require_layeredConfig.readDoomConfigSources(PROFILES_FILE, repoRoot, homeDirectory).map(parseProfileLayer);
404
+ const profiles = loadProfiles(repoRoot, homeDirectory);
405
+ let defaultProfile;
406
+ for (const layer of layers) if (layer.defaultProfile !== void 0) defaultProfile = layer.defaultProfile;
407
+ if (defaultProfile !== void 0 && !profiles.some((profile) => profile.name === defaultProfile)) throw new Error(`profiles.defaultProfile names an unknown profile: ${defaultProfile}`);
408
+ return {
409
+ profiles,
410
+ ...defaultProfile === void 0 ? {} : { defaultProfile }
411
+ };
412
+ }
413
+ /** Resolves one selected profile and fails clearly when its name is unknown. */
414
+ function resolveProfile(repoRoot, name, homeDirectory) {
415
+ const profile = loadProfiles(repoRoot, homeDirectory).find((candidate) => candidate.name === name);
416
+ if (!profile) throw new Error(`Unknown profile: ${name}`);
417
+ return profile;
418
+ }
419
+ function listProfileNames(repoRoot, homeDirectory) {
420
+ return loadProfiles(repoRoot, homeDirectory).map((profile) => profile.name);
421
+ }
422
+ /**
423
+ * Reads the identity block from a persona's `profile.md`.
424
+ *
425
+ * Separate from `buildPersonaPrompt` because the prompt is assembled on several
426
+ * paths that do not want the icon bytes, and because a persona that declares
427
+ * nothing must stay exactly as cheap as it is today.
428
+ */
429
+ function readPersonaPresentation(personaRoot, personaDirectory) {
430
+ const frontMatter = readPersonaFrontMatter(personaRoot, personaDirectory);
431
+ if (!frontMatter) return {};
432
+ const icon = frontMatter.icon === void 0 ? void 0 : readPersonaIcon(node_path.default.join(personaRoot, personaDirectory), frontMatter.icon);
433
+ const identity = {
434
+ ...frontMatter.name === void 0 ? {} : { name: frontMatter.name },
435
+ ...icon === void 0 ? {} : { icon }
436
+ };
437
+ return {
438
+ ...identity.name === void 0 && identity.icon === void 0 ? {} : { identity },
439
+ ...frontMatter.voice === void 0 ? {} : { voice: frontMatter.voice }
440
+ };
441
+ }
442
+ function readPersonaFrontMatter(personaRoot, personaDirectory) {
443
+ try {
444
+ const personaPath = node_fs.default.realpathSync(node_path.default.join(personaRoot, personaDirectory));
445
+ const filePath = node_path.default.join(personaPath, PERSONA_IDENTITY_FILE);
446
+ if (!node_fs.default.existsSync(filePath)) return void 0;
447
+ return parsePersonaFrontMatter(node_fs.default.readFileSync(node_fs.default.realpathSync(filePath), TEXT_ENCODING)).frontMatter;
448
+ } catch {
449
+ return;
450
+ }
451
+ }
452
+ /** Builds the persona system-prompt block, or undefined when nothing is readable. */
453
+ function buildPersonaPrompt(personaRoot, personaDirectory) {
454
+ const sections = [];
455
+ const personaPath = node_fs.default.realpathSync(node_path.default.join(personaRoot, personaDirectory));
456
+ for (const file of PERSONA_FILES) {
457
+ const filePath = node_path.default.join(personaPath, file);
458
+ if (!node_fs.default.existsSync(filePath)) continue;
459
+ const realFilePath = node_fs.default.realpathSync(filePath);
460
+ const relativeFilePath = node_path.default.relative(personaPath, realFilePath);
461
+ if (relativeFilePath === PARENT_DIRECTORY || relativeFilePath.startsWith(`${PARENT_DIRECTORY}${node_path.default.sep}`)) throw new Error(`Persona file must stay inside ${personaDirectory}: ${file}`);
462
+ const raw = node_fs.default.readFileSync(realFilePath, TEXT_ENCODING);
463
+ const content = (file === PERSONA_IDENTITY_FILE ? parsePersonaFrontMatter(raw).body : raw).trim();
464
+ if (content) sections.push(content);
465
+ }
466
+ if (sections.length === 0) return void 0;
467
+ return [`[PERSONA] You are operating as the person described below (source: ${personaDirectory}).`, ...sections].join("\n\n");
468
+ }
469
+ /** Applies profile environment defaults and returns only the values it contributed. */
470
+ function applyProfileEnvironment(environment, defaults) {
471
+ const applied = {};
472
+ for (const [key, value] of Object.entries(defaults)) {
473
+ if (environment[key] !== void 0) continue;
474
+ environment[key] = value;
475
+ applied[key] = value;
476
+ }
477
+ return applied;
478
+ }
479
+ /** Replaces environment defaults previously contributed by another profile. */
480
+ function replaceProfileEnvironment(environment, previous, next) {
481
+ for (const [key, value] of Object.entries(previous)) if (environment[key] === value) delete environment[key];
482
+ return applyProfileEnvironment(environment, next);
483
+ }
484
+ //#endregion
485
+ Object.defineProperty(exports, "PERSONA_FILES", {
486
+ enumerable: true,
487
+ get: function() {
488
+ return PERSONA_FILES;
489
+ }
490
+ });
491
+ Object.defineProperty(exports, "applyProfileEnvironment", {
492
+ enumerable: true,
493
+ get: function() {
494
+ return applyProfileEnvironment;
495
+ }
496
+ });
497
+ Object.defineProperty(exports, "buildPersonaPrompt", {
498
+ enumerable: true,
499
+ get: function() {
500
+ return buildPersonaPrompt;
501
+ }
502
+ });
503
+ Object.defineProperty(exports, "listProfileNames", {
504
+ enumerable: true,
505
+ get: function() {
506
+ return listProfileNames;
507
+ }
508
+ });
509
+ Object.defineProperty(exports, "loadProfileCatalog", {
510
+ enumerable: true,
511
+ get: function() {
512
+ return loadProfileCatalog;
513
+ }
514
+ });
515
+ Object.defineProperty(exports, "loadProfiles", {
516
+ enumerable: true,
517
+ get: function() {
518
+ return loadProfiles;
519
+ }
520
+ });
521
+ Object.defineProperty(exports, "parsePersonaFrontMatter", {
522
+ enumerable: true,
523
+ get: function() {
524
+ return parsePersonaFrontMatter;
525
+ }
526
+ });
527
+ Object.defineProperty(exports, "parseProfileBinding", {
528
+ enumerable: true,
529
+ get: function() {
530
+ return parseProfileBinding;
531
+ }
532
+ });
533
+ Object.defineProperty(exports, "readPersonaIcon", {
534
+ enumerable: true,
535
+ get: function() {
536
+ return readPersonaIcon;
537
+ }
538
+ });
539
+ Object.defineProperty(exports, "replaceProfileEnvironment", {
540
+ enumerable: true,
541
+ get: function() {
542
+ return replaceProfileEnvironment;
543
+ }
544
+ });
545
+ Object.defineProperty(exports, "resolveProfile", {
546
+ enumerable: true,
547
+ get: function() {
548
+ return resolveProfile;
549
+ }
550
+ });
551
+
552
+ //# sourceMappingURL=profiles-DnF9DBpd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles-DnF9DBpd.cjs","names":["isRecord","parseYaml","PARENT_DIRECTORY","path","fs","PROFILE_ICON_MAX_DATA_URL_LENGTH","path","fs","os","readDoomConfigSources"],"sources":["../src/services/personaFrontMatter/index.ts","../src/services/personaIcon/index.ts","../src/services/profileBinding/index.ts","../src/services/profiles/index.ts"],"sourcesContent":["import { parse as parseYaml } from 'yaml';\n\nimport type { PersonaDocument, PersonaFrontMatter, PersonaVoiceOverride } from '../../types/profiles';\n\n/**\n * Optional identity a persona declares at the top of its `profile.md`.\n *\n * A profile used to be prompt text only, so there was nowhere to say who the\n * persona is or how it should sound. Front-matter puts that beside the persona\n * text it describes, which is the only place that works for both explicit\n * `profiles.yaml` entries and folders found by root discovery.\n *\n * Recognition is deliberately narrow. Personas that exist today were written\n * without any of this, and one of them may legitimately open with a horizontal\n * rule, so a leading fence alone is not enough to claim the block. A block is\n * only treated as identity when it is fenced at the very first line, closed,\n * parses as a mapping, and declares at least one field this contract owns.\n * Anything else is passed through byte for byte.\n */\n\nconst FENCE = '---';\nconst OWNED_KEYS = ['name', 'icon', 'voice'] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readVoice(value: unknown): PersonaVoiceOverride | undefined {\n if (!isRecord(value)) return undefined;\n const voice = typeof value.voice === 'string' && value.voice.trim().length > 0 ? value.voice.trim() : undefined;\n const rate = typeof value.rate === 'number' && Number.isFinite(value.rate) ? value.rate : undefined;\n if (voice === undefined && rate === undefined) return undefined;\n return { ...(voice === undefined ? {} : { voice }), ...(rate === undefined ? {} : { rate }) };\n}\n\nfunction readFrontMatter(parsed: Record<string, unknown>): PersonaFrontMatter | undefined {\n const name = typeof parsed.name === 'string' && parsed.name.trim().length > 0 ? parsed.name.trim() : undefined;\n const icon = typeof parsed.icon === 'string' && parsed.icon.trim().length > 0 ? parsed.icon.trim() : undefined;\n const voice = readVoice(parsed.voice);\n if (name === undefined && icon === undefined && voice === undefined) return undefined;\n return {\n ...(name === undefined ? {} : { name }),\n ...(icon === undefined ? {} : { icon }),\n ...(voice === undefined ? {} : { voice }),\n };\n}\n\n/**\n * Splits a recognised identity block off a persona document.\n *\n * Never throws: a malformed avatar must not make a persona unloadable, so an\n * unparseable or unrecognised block leaves the document exactly as it arrived.\n */\nexport function parsePersonaFrontMatter(content: string): PersonaDocument {\n const lines = content.split('\\n');\n if (lines[0]?.trimEnd() !== FENCE) return { body: content };\n\n const closingIndex = lines.findIndex((line, index) => index > 0 && line.trimEnd() === FENCE);\n if (closingIndex === -1) return { body: content };\n\n let parsed: unknown;\n try {\n parsed = parseYaml(lines.slice(1, closingIndex).join('\\n'));\n } catch {\n return { body: content };\n }\n if (!isRecord(parsed)) return { body: content };\n if (!OWNED_KEYS.some((key) => Object.hasOwn(parsed, key))) return { body: content };\n\n const frontMatter = readFrontMatter(parsed);\n if (!frontMatter) return { body: content };\n return { frontMatter, body: lines.slice(closingIndex + 1).join('\\n') };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { PROFILE_ICON_MAX_DATA_URL_LENGTH, type ProfileIconMimeType } from '@agimon-ai/po-core/profileIdentity';\n\n/**\n * Reads a persona icon into a bounded `data:` URL.\n *\n * The icon travels inside the journalled identity entry rather than through an\n * HTTP route. A route would leave a request-time filesystem resolution reachable\n * from the browser for the life of a session, defended on every request forever;\n * this resolves the path once, server side, at the moment the profile loads.\n *\n * The path comes from user-authored front-matter, so it is confined the same way\n * `buildPersonaPrompt` confines persona files: a symlink must not read outside\n * the persona directory.\n *\n * Every failure is silent and returns undefined. An avatar is decoration, and a\n * broken one must never stop a persona from loading.\n */\nconst PARENT_DIRECTORY = '..';\n\n/**\n * Magic-byte signatures, checked instead of trusting the filename.\n *\n * `image/svg+xml` is absent on purpose: an SVG rendered same-origin executes\n * script, and the author of this path is whoever wrote the persona. Do not add\n * it to match the cockpit's broader media catalog.\n */\nconst SIGNATURES: readonly { readonly mime: ProfileIconMimeType; readonly test: (bytes: Buffer) => boolean }[] = [\n {\n mime: 'image/png',\n test: (b) => b.length > 8 && b.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])),\n },\n { mime: 'image/jpeg', test: (b) => b.length > 3 && b[0] === 0xff && b[1] === 0xd8 && b[2] === 0xff },\n { mime: 'image/gif', test: (b) => b.length > 6 && b.subarray(0, 6).toString('latin1').startsWith('GIF8') },\n {\n mime: 'image/webp',\n test: (b) =>\n b.length > 12 &&\n b.subarray(0, 4).toString('latin1') === 'RIFF' &&\n b.subarray(8, 12).toString('latin1') === 'WEBP',\n },\n];\n\nfunction sniff(bytes: Buffer): ProfileIconMimeType | undefined {\n return SIGNATURES.find((signature) => signature.test(bytes))?.mime;\n}\n\n/**\n * Resolves an icon declared in persona front-matter, or undefined when it is\n * missing, unreadable, not an allowed image, escapes the persona directory, or\n * exceeds the data-URL ceiling.\n */\nexport function readPersonaIcon(personaPath: string, iconRelative: string): string | undefined {\n if (path.isAbsolute(iconRelative)) return undefined;\n\n try {\n const realPersonaPath = fs.realpathSync(personaPath);\n const iconPath = path.resolve(realPersonaPath, iconRelative);\n if (!fs.existsSync(iconPath)) return undefined;\n\n const realIconPath = fs.realpathSync(iconPath);\n const relative = path.relative(realPersonaPath, realIconPath);\n if (\n relative === PARENT_DIRECTORY ||\n relative.startsWith(`${PARENT_DIRECTORY}${path.sep}`) ||\n path.isAbsolute(relative)\n ) {\n return undefined;\n }\n if (!fs.statSync(realIconPath).isFile()) return undefined;\n\n const bytes = fs.readFileSync(realIconPath);\n const mime = sniff(bytes);\n if (!mime) return undefined;\n\n const dataUrl = `data:${mime};base64,${bytes.toString('base64')}`;\n return dataUrl.length > PROFILE_ICON_MAX_DATA_URL_LENGTH ? undefined : dataUrl;\n } catch {\n return undefined;\n }\n}\n","import type { ProfileBrowserBinding, ProfileIntegrationBinding, ProfileSecretReference } from './type';\n\nconst BINDING_KEYS = new Set(['provider', 'organizationId', 'mailboxId', 'credentialRef', 'secrets', 'browser']);\nconst SECRET_KEYS = new Set(['credentialId', 'field', 'allowedOrigins']);\nconst BROWSER_KEYS = new Set(['profileName', 'allowedOrigins']);\nconst ALIAS_PATTERN = /^[A-Z][A-Z0-9_]{0,63}$/;\nconst FIELD_PATTERN = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/;\nconst BROWSER_PROFILE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;\n\nfunction record(value: unknown, location: string, keys?: ReadonlySet<string>): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`${location} must be a mapping`);\n }\n if (keys && Object.keys(value).some((key) => !keys.has(key))) {\n // Never echo an unknown key or value, either of which might contain a misplaced secret.\n throw new Error(`${location} contains unsupported metadata`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction reference(value: unknown, location: string): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > 256 || /\\s/.test(value)) {\n throw new Error(`${location} must be a non-empty reference without whitespace`);\n }\n return value;\n}\n\nfunction origins(value: unknown, location: string): readonly string[] {\n if (!Array.isArray(value) || value.length === 0) throw new Error(`${location} must contain exact HTTP(S) origins`);\n const result = value.map((entry: unknown) => {\n if (typeof entry !== 'string') throw new Error(`${location} must contain exact HTTP(S) origins`);\n let url: URL;\n try {\n url = new URL(entry);\n } catch {\n throw new Error(`${location} must contain exact HTTP(S) origins`);\n }\n if (\n (url.protocol !== 'https:' && url.protocol !== 'http:') ||\n url.origin !== entry ||\n url.username ||\n url.password\n ) {\n throw new Error(`${location} must contain exact HTTP(S) origins`);\n }\n return entry;\n });\n return Object.freeze([...new Set(result)]);\n}\n\nfunction browser(value: unknown, location: string): ProfileBrowserBinding {\n const entry = record(value, location, BROWSER_KEYS);\n if (typeof entry.profileName !== 'string' || !BROWSER_PROFILE_PATTERN.test(entry.profileName)) {\n throw new Error(`${location}.profileName must be a safe browser profile name`);\n }\n return Object.freeze({\n profileName: entry.profileName,\n allowedOrigins: origins(entry.allowedOrigins, `${location}.allowedOrigins`),\n });\n}\n\n/** Validates and deeply freezes a detached metadata snapshot. No provider SDK or secret is loaded. */\nexport function parseProfileBinding(value: unknown, location = 'Profile integration'): ProfileIntegrationBinding {\n const entry = record(value, location, BINDING_KEYS);\n const sourceSecrets = record(entry.secrets, `${location}.secrets`);\n const secrets: Record<string, ProfileSecretReference> = {};\n for (const [alias, value] of Object.entries(sourceSecrets)) {\n if (!ALIAS_PATTERN.test(alias)) throw new Error(`${location}.secrets requires uppercase alias names`);\n const secret = record(value, `${location}.secrets.${alias}`, SECRET_KEYS);\n if (typeof secret.field !== 'string' || !FIELD_PATTERN.test(secret.field)) {\n throw new Error(`${location}.secrets.${alias}.field must be a credential field name`);\n }\n secrets[alias] = Object.freeze({\n credentialId: reference(secret.credentialId, `${location}.secrets.${alias}.credentialId`),\n field: secret.field,\n allowedOrigins: origins(secret.allowedOrigins, `${location}.secrets.${alias}.allowedOrigins`),\n });\n }\n const browserBinding = entry.browser === undefined ? undefined : browser(entry.browser, `${location}.browser`);\n if (\n browserBinding &&\n Object.values(secrets).some((secret) =>\n secret.allowedOrigins.some((origin) => !browserBinding.allowedOrigins.includes(origin)),\n )\n ) {\n throw new Error(`${location} secret origins must be included in browser.allowedOrigins`);\n }\n return Object.freeze({\n provider: reference(entry.provider, `${location}.provider`),\n organizationId: reference(entry.organizationId, `${location}.organizationId`),\n mailboxId: reference(entry.mailboxId, `${location}.mailboxId`),\n credentialRef: reference(entry.credentialRef, `${location}.credentialRef`),\n secrets: Object.freeze(secrets),\n ...(browserBinding === undefined ? {} : { browser: browserBinding }),\n });\n}\n","import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { PersonaIdentity } from '../../types/profiles';\nimport { type PersonaFrontMatter, type PersonaVoiceOverride } from '../../types/profiles';\nimport { readDoomConfigSources } from '../layeredConfig';\nimport { parsePersonaFrontMatter } from '../personaFrontMatter';\nimport { readPersonaIcon } from '../personaIcon';\nimport { parseProfileBinding } from '../profileBinding';\nimport type { ProfileIntegrationBinding } from '../profileBinding/type';\n\n/** Files that make up one repository persona, concatenated in this order. */\nexport const PERSONA_FILES = ['profile.md', 'SOUL.md', 'AGENTS.md'];\n\n/** The persona file that may carry an identity block; the others are prose only. */\nconst PERSONA_IDENTITY_FILE = 'profile.md';\n\n/** A persona's resolved presentation: display name, and an icon already read into a data URL. */\n\nexport interface AgentProfile {\n name: string;\n /** Directory relative to personaRoot, which remains the persona source. */\n persona: string;\n /**\n * Root the persona path resolves against: the repository root for a\n * repository profile, the global `.po` directory for a global one.\n */\n personaRoot: string;\n /** Environment defaults. Values already exported by the caller win. */\n env: Record<string, string>;\n /** Nonsecret integration metadata. Resolved secrets never enter profile environment. */\n integration?: ProfileIntegrationBinding;\n /** Display name and avatar declared in the persona's own front-matter. */\n identity?: PersonaIdentity;\n /** Narrowly scoped TTS override declared alongside the identity. */\n voice?: PersonaVoiceOverride;\n}\n\ninterface ProfileConfigLayer {\n filePath: string;\n baseDirectory: string;\n roots: string[];\n entries: Record<string, unknown>;\n defaultProfile?: string;\n}\n\nconst PROFILE_KEYS = new Set(['persona', 'env', 'integration']);\nconst PROFILE_CATALOG_KEYS = new Set(['roots', 'entries', 'defaultProfile']);\nconst PROFILES_FILE = 'profiles.yaml';\nconst PROFILES_ROOT_KEY = 'profiles';\nconst AGENTS_DIRECTORY = 'agents';\nconst PARENT_DIRECTORY = '..';\nconst TEXT_ENCODING = 'utf8';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isPathInside(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return (\n relative === '' ||\n (!path.isAbsolute(relative) &&\n relative !== PARENT_DIRECTORY &&\n !relative.startsWith(`${PARENT_DIRECTORY}${path.sep}`))\n );\n}\n\nfunction parseEnvironment(name: string, value: unknown): Record<string, string> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new Error(`Profile \"${name}\" env must be a string mapping`);\n\n const environment: Record<string, string> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry !== 'string') throw new Error(`Profile \"${name}\" env.${key} must be a string`);\n if (entry.includes('${secrets.')) throw new Error(`Profile \"${name}\" env cannot contain secret aliases`);\n environment[key] = entry;\n }\n return environment;\n}\n\nfunction parseProfileRoots(value: unknown, filePath: string, baseDirectory: string): string[] {\n if (value === undefined) return [];\n if (!Array.isArray(value)) throw new Error(`profiles.roots in ${filePath} must be an array`);\n return value.map((entry, index) => {\n if (typeof entry !== 'string' || entry.trim().length === 0) {\n throw new Error(`profiles.roots[${index}] in ${filePath} must be a non-empty string`);\n }\n return path.resolve(baseDirectory, entry.trim());\n });\n}\n\nfunction parseProfileLayer(source: { filePath: string; baseDirectory: string; document: unknown }): ProfileConfigLayer {\n if (!isRecord(source.document) || !isRecord(source.document[PROFILES_ROOT_KEY])) {\n throw new Error(`${source.filePath} must contain a profiles mapping`);\n }\n const unsupportedDocumentKeys = Object.keys(source.document).filter((key) => key !== PROFILES_ROOT_KEY);\n if (unsupportedDocumentKeys.length > 0) {\n throw new Error(`${source.filePath} may only contain profiles; unsupported: ${unsupportedDocumentKeys.join(', ')}`);\n }\n\n const profiles = source.document[PROFILES_ROOT_KEY];\n const usesCatalogShape = Object.hasOwn(profiles, 'roots') || Object.hasOwn(profiles, 'entries');\n if (!usesCatalogShape) {\n return { filePath: source.filePath, baseDirectory: source.baseDirectory, roots: [], entries: profiles };\n }\n\n const unsupportedCatalogKeys = Object.keys(profiles).filter((key) => !PROFILE_CATALOG_KEYS.has(key));\n if (unsupportedCatalogKeys.length > 0) {\n throw new Error(\n `profiles in ${source.filePath} may only contain roots, entries and defaultProfile; unsupported: ${unsupportedCatalogKeys.join(', ')}`,\n );\n }\n if (\n profiles.defaultProfile !== undefined &&\n (typeof profiles.defaultProfile !== 'string' || profiles.defaultProfile.trim().length === 0)\n ) {\n throw new Error(`profiles.defaultProfile in ${source.filePath} must be a non-empty string`);\n }\n if (profiles.entries !== undefined && !isRecord(profiles.entries)) {\n throw new Error(`profiles.entries in ${source.filePath} must be a mapping`);\n }\n return {\n filePath: source.filePath,\n baseDirectory: source.baseDirectory,\n roots: parseProfileRoots(profiles.roots, source.filePath, source.baseDirectory),\n entries: profiles.entries ?? {},\n ...(profiles.defaultProfile === undefined ? {} : { defaultProfile: String(profiles.defaultProfile).trim() }),\n };\n}\n\nfunction assertProfileInsideAllowedRoot(name: string, personaPath: string, lexicalRoots: readonly string[]): void {\n const realPersonaPath = fs.realpathSync(personaPath);\n if (!lexicalRoots.some((root) => isPathInside(fs.realpathSync(root), realPersonaPath))) {\n throw new Error(`Profile \"${name}\" persona must stay inside agents/ or a configured profile root`);\n }\n}\n\nfunction parseProfile(\n personaRoot: string,\n configuredRoots: readonly string[],\n name: string,\n value: unknown,\n): AgentProfile {\n if (!isRecord(value)) throw new Error(`Profile \"${name}\" must be a mapping`);\n\n const unsupported = Object.keys(value).filter((key) => !PROFILE_KEYS.has(key));\n if (unsupported.length > 0) {\n throw new Error(\n `Profile \"${name}\" may only set persona, env and integration; unsupported: ${unsupported.join(', ')}`,\n );\n }\n if (typeof value.persona !== 'string' || value.persona.trim().length === 0) {\n throw new Error(`Profile \"${name}\" must set a persona`);\n }\n if (path.isAbsolute(value.persona)) {\n throw new Error(`Profile \"${name}\" persona must be relative to the config that declares it`);\n }\n\n const persona = value.persona;\n const personaPath = path.resolve(personaRoot, persona);\n const lexicalRoots = [path.resolve(personaRoot, AGENTS_DIRECTORY), ...configuredRoots].filter((root) =>\n isPathInside(root, personaPath),\n );\n if (lexicalRoots.length === 0) {\n throw new Error(`Profile \"${name}\" persona must stay inside agents/ or a configured profile root`);\n }\n if (!fs.existsSync(personaPath) || !fs.statSync(personaPath).isDirectory()) {\n throw new Error(`Profile \"${name}\" references a missing persona: ${persona}`);\n }\n assertProfileInsideAllowedRoot(name, personaPath, lexicalRoots);\n if (!buildPersonaPrompt(personaRoot, persona)) {\n // An identity block is not persona text, so a profile.md holding nothing else\n // leaves the persona empty. Say that, rather than claiming the file is unreadable.\n const declaresIdentity = readPersonaFrontMatter(personaRoot, persona) !== undefined;\n throw new Error(\n declaresIdentity\n ? `Profile \"${name}\" persona declares identity front-matter but no persona text: ${persona}`\n : `Profile \"${name}\" persona has no readable persona files: ${persona}`,\n );\n }\n\n return {\n name,\n persona,\n personaRoot,\n env: parseEnvironment(name, value.env),\n ...(value.integration === undefined\n ? {}\n : { integration: parseProfileBinding(value.integration, `Profile \"${name}\" integration`) }),\n ...readPersonaPresentation(personaRoot, persona),\n };\n}\n\nfunction containsPersonaFile(directory: string): boolean {\n return PERSONA_FILES.some((file) => {\n try {\n return fs.lstatSync(path.join(directory, file)).isFile();\n } catch {\n return false;\n }\n });\n}\n\nfunction discoverProfile(directory: string, configuredRoot: string, personaRoot: string): AgentProfile | undefined {\n if (!containsPersonaFile(directory)) return undefined;\n try {\n const realConfiguredRoot = fs.realpathSync(configuredRoot);\n const realDirectory = fs.realpathSync(directory);\n if (!isPathInside(realConfiguredRoot, realDirectory)) return undefined;\n const persona = path.relative(personaRoot, directory) || '.';\n if (!buildPersonaPrompt(personaRoot, persona)) return undefined;\n return {\n name: path.basename(directory),\n persona,\n personaRoot,\n env: {},\n ...readPersonaPresentation(personaRoot, persona),\n };\n } catch {\n // Automatic discovery ignores unreadable or unsafe candidates; explicit entries remain fatal.\n return undefined;\n }\n}\n\nfunction discoverProfileRoot(root: string, personaRoot: string): AgentProfile[] {\n if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {\n throw new Error(`Configured profile root is not a directory: ${root}`);\n }\n\n const rootProfile = discoverProfile(root, root, personaRoot);\n if (rootProfile) return [rootProfile];\n\n return fs\n .readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .sort((left, right) => left.name.localeCompare(right.name))\n .flatMap((entry) => {\n const profile = discoverProfile(path.join(root, entry.name), root, personaRoot);\n return profile ? [profile] : [];\n });\n}\n\n/**\n * Loads profiles from the global and repository configs, repository last.\n *\n * Configured roots accumulate and inspect themselves or their direct-child\n * directories for persona files. Later discoveries replace earlier names, and\n * explicit entries replace discoveries. Legacy flat profile mappings remain\n * accepted as explicit entries.\n */\nexport function loadProfiles(repoRoot: string, homeDirectory: string = os.homedir()): AgentProfile[] {\n const layers = readDoomConfigSources<unknown>(PROFILES_FILE, repoRoot, homeDirectory).map(parseProfileLayer);\n const byName = new Map<string, AgentProfile>();\n\n for (const layer of layers) {\n for (const root of layer.roots) {\n for (const profile of discoverProfileRoot(root, layer.baseDirectory)) byName.set(profile.name, profile);\n }\n }\n\n for (const layer of layers) {\n for (const [name, value] of Object.entries(layer.entries)) {\n byName.set(name, parseProfile(layer.baseDirectory, layer.roots, name, value));\n }\n }\n\n return [...byName.values()].sort((left, right) => left.name.localeCompare(right.name));\n}\n\n/**\n * The profile catalog: every resolved profile, plus the name a launch starts on\n * when the caller names none.\n *\n * `defaultProfile` mirrors `defaultMajorMode` in modes.yaml and `defaultDomains`\n * in domains.yaml, so each selection axis declares its default in its own\n * catalog. A repository declaration replaces a personal one. An unknown name is\n * an error rather than a silent fallback: a typo that quietly starts the session\n * with no persona is worse than a refused launch.\n */\nexport function loadProfileCatalog(\n repoRoot: string,\n homeDirectory: string = os.homedir(),\n): { profiles: AgentProfile[]; defaultProfile?: string } {\n const layers = readDoomConfigSources<unknown>(PROFILES_FILE, repoRoot, homeDirectory).map(parseProfileLayer);\n const profiles = loadProfiles(repoRoot, homeDirectory);\n let defaultProfile: string | undefined;\n for (const layer of layers) {\n if (layer.defaultProfile !== undefined) defaultProfile = layer.defaultProfile;\n }\n if (defaultProfile !== undefined && !profiles.some((profile) => profile.name === defaultProfile)) {\n throw new Error(`profiles.defaultProfile names an unknown profile: ${defaultProfile}`);\n }\n return { profiles, ...(defaultProfile === undefined ? {} : { defaultProfile }) };\n}\n\n/** Resolves one selected profile and fails clearly when its name is unknown. */\nexport function resolveProfile(repoRoot: string, name: string, homeDirectory?: string): AgentProfile {\n const profile = loadProfiles(repoRoot, homeDirectory).find((candidate) => candidate.name === name);\n if (!profile) throw new Error(`Unknown profile: ${name}`);\n return profile;\n}\n\nexport function listProfileNames(repoRoot: string, homeDirectory?: string): string[] {\n return loadProfiles(repoRoot, homeDirectory).map((profile) => profile.name);\n}\n\n/**\n * Reads the identity block from a persona's `profile.md`.\n *\n * Separate from `buildPersonaPrompt` because the prompt is assembled on several\n * paths that do not want the icon bytes, and because a persona that declares\n * nothing must stay exactly as cheap as it is today.\n */\nfunction readPersonaPresentation(\n personaRoot: string,\n personaDirectory: string,\n): { identity?: PersonaIdentity; voice?: PersonaVoiceOverride } {\n const frontMatter = readPersonaFrontMatter(personaRoot, personaDirectory);\n if (!frontMatter) return {};\n\n const icon =\n frontMatter.icon === undefined\n ? undefined\n : readPersonaIcon(path.join(personaRoot, personaDirectory), frontMatter.icon);\n const identity: PersonaIdentity = {\n ...(frontMatter.name === undefined ? {} : { name: frontMatter.name }),\n ...(icon === undefined ? {} : { icon }),\n };\n return {\n ...(identity.name === undefined && identity.icon === undefined ? {} : { identity }),\n ...(frontMatter.voice === undefined ? {} : { voice: frontMatter.voice }),\n };\n}\n\nfunction readPersonaFrontMatter(personaRoot: string, personaDirectory: string): PersonaFrontMatter | undefined {\n try {\n const personaPath = fs.realpathSync(path.join(personaRoot, personaDirectory));\n const filePath = path.join(personaPath, PERSONA_IDENTITY_FILE);\n if (!fs.existsSync(filePath)) return undefined;\n return parsePersonaFrontMatter(fs.readFileSync(fs.realpathSync(filePath), TEXT_ENCODING)).frontMatter;\n } catch {\n return undefined;\n }\n}\n/** Builds the persona system-prompt block, or undefined when nothing is readable. */\nexport function buildPersonaPrompt(personaRoot: string, personaDirectory: string): string | undefined {\n const sections: string[] = [];\n const personaPath = fs.realpathSync(path.join(personaRoot, personaDirectory));\n for (const file of PERSONA_FILES) {\n const filePath = path.join(personaPath, file);\n if (!fs.existsSync(filePath)) continue;\n const realFilePath = fs.realpathSync(filePath);\n const relativeFilePath = path.relative(personaPath, realFilePath);\n if (relativeFilePath === PARENT_DIRECTORY || relativeFilePath.startsWith(`${PARENT_DIRECTORY}${path.sep}`)) {\n throw new Error(`Persona file must stay inside ${personaDirectory}: ${file}`);\n }\n const raw = fs.readFileSync(realFilePath, TEXT_ENCODING);\n // Only profile.md may declare identity, so only profile.md is stripped.\n const content = (file === PERSONA_IDENTITY_FILE ? parsePersonaFrontMatter(raw).body : raw).trim();\n if (content) sections.push(content);\n }\n if (sections.length === 0) return undefined;\n return [`[PERSONA] You are operating as the person described below (source: ${personaDirectory}).`, ...sections].join(\n '\\n\\n',\n );\n}\n\n/** Applies profile environment defaults and returns only the values it contributed. */\nexport function applyProfileEnvironment(\n environment: NodeJS.ProcessEnv,\n defaults: Record<string, string>,\n): Record<string, string> {\n const applied: Record<string, string> = {};\n for (const [key, value] of Object.entries(defaults)) {\n if (environment[key] !== undefined) continue;\n environment[key] = value;\n applied[key] = value;\n }\n return applied;\n}\n\n/** Replaces environment defaults previously contributed by another profile. */\nexport function replaceProfileEnvironment(\n environment: NodeJS.ProcessEnv,\n previous: Record<string, string>,\n next: Record<string, string>,\n): Record<string, string> {\n for (const [key, value] of Object.entries(previous)) {\n if (environment[key] === value) delete environment[key];\n }\n return applyProfileEnvironment(environment, next);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAM,QAAQ;AACd,MAAM,aAAa;CAAC;CAAQ;CAAQ;AAAO;AAE3C,SAASA,WAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,UAAU,OAAkD;CACnE,IAAI,CAACA,WAAS,KAAK,GAAG,OAAO,KAAA;CAC7B,MAAM,QAAQ,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,IAAI,MAAM,MAAM,KAAK,IAAI,KAAA;CACtG,MAAM,OAAO,OAAO,MAAM,SAAS,YAAY,OAAO,SAAS,MAAM,IAAI,IAAI,MAAM,OAAO,KAAA;CAC1F,IAAI,UAAU,KAAA,KAAa,SAAS,KAAA,GAAW,OAAO,KAAA;CACtD,OAAO;EAAE,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EAAI,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CAAG;AAC9F;AAEA,SAAS,gBAAgB,QAAiE;CACxF,MAAM,OAAO,OAAO,OAAO,SAAS,YAAY,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,IAAI,OAAO,KAAK,KAAK,IAAI,KAAA;CACrG,MAAM,OAAO,OAAO,OAAO,SAAS,YAAY,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,IAAI,OAAO,KAAK,KAAK,IAAI,KAAA;CACrG,MAAM,QAAQ,UAAU,OAAO,KAAK;CACpC,IAAI,SAAS,KAAA,KAAa,SAAS,KAAA,KAAa,UAAU,KAAA,GAAW,OAAO,KAAA;CAC5E,OAAO;EACL,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;EACrC,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;EACrC,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;CACzC;AACF;;;;;;;AAQA,SAAgB,wBAAwB,SAAkC;CACxE,MAAM,QAAQ,QAAQ,MAAM,IAAI;CAChC,IAAI,MAAM,EAAE,EAAE,QAAQ,MAAM,OAAO,OAAO,EAAE,MAAM,QAAQ;CAE1D,MAAM,eAAe,MAAM,WAAW,MAAM,UAAU,QAAQ,KAAK,KAAK,QAAQ,MAAM,KAAK;CAC3F,IAAI,iBAAiB,IAAI,OAAO,EAAE,MAAM,QAAQ;CAEhD,IAAI;CACJ,IAAI;EACF,UAAA,GAASC,KAAAA,MAAAA,CAAU,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,KAAK,IAAI,CAAC;CAC5D,QAAQ;EACN,OAAO,EAAE,MAAM,QAAQ;CACzB;CACA,IAAI,CAACD,WAAS,MAAM,GAAG,OAAO,EAAE,MAAM,QAAQ;CAC9C,IAAI,CAAC,WAAW,MAAM,QAAQ,OAAO,OAAO,QAAQ,GAAG,CAAC,GAAG,OAAO,EAAE,MAAM,QAAQ;CAElF,MAAM,cAAc,gBAAgB,MAAM;CAC1C,IAAI,CAAC,aAAa,OAAO,EAAE,MAAM,QAAQ;CACzC,OAAO;EAAE;EAAa,MAAM,MAAM,MAAM,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI;CAAE;AACvE;;;;;;;;;;;;;;;;;;ACpDA,MAAME,qBAAmB;;;;;;;;AASzB,MAAM,aAA2G;CAC/G;EACE,MAAM;EACN,OAAO,MAAM,EAAE,SAAS,KAAK,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK;GAAC;GAAK;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI;EAAE,CAAC,CAAC;CACrG;CACA;EAAE,MAAM;EAAc,OAAO,MAAM,EAAE,SAAS,KAAK,EAAE,OAAO,OAAQ,EAAE,OAAO,OAAQ,EAAE,OAAO;CAAK;CACnG;EAAE,MAAM;EAAa,OAAO,MAAM,EAAE,SAAS,KAAK,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,WAAW,MAAM;CAAE;CACzG;EACE,MAAM;EACN,OAAO,MACL,EAAE,SAAS,MACX,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,QAAQ,MAAM,UACxC,EAAE,SAAS,GAAG,EAAE,CAAC,CAAC,SAAS,QAAQ,MAAM;CAC7C;AACF;AAEA,SAAS,MAAM,OAAgD;CAC7D,OAAO,WAAW,MAAM,cAAc,UAAU,KAAK,KAAK,CAAC,CAAC,EAAE;AAChE;;;;;;AAOA,SAAgB,gBAAgB,aAAqB,cAA0C;CAC7F,IAAIC,UAAAA,QAAK,WAAW,YAAY,GAAG,OAAO,KAAA;CAE1C,IAAI;EACF,MAAM,kBAAkBC,QAAAA,QAAG,aAAa,WAAW;EACnD,MAAM,WAAWD,UAAAA,QAAK,QAAQ,iBAAiB,YAAY;EAC3D,IAAI,CAACC,QAAAA,QAAG,WAAW,QAAQ,GAAG,OAAO,KAAA;EAErC,MAAM,eAAeA,QAAAA,QAAG,aAAa,QAAQ;EAC7C,MAAM,WAAWD,UAAAA,QAAK,SAAS,iBAAiB,YAAY;EAC5D,IACE,aAAaD,sBACb,SAAS,WAAW,GAAGA,qBAAmBC,UAAAA,QAAK,KAAK,KACpDA,UAAAA,QAAK,WAAW,QAAQ,GAExB;EAEF,IAAI,CAACC,QAAAA,QAAG,SAAS,YAAY,CAAC,CAAC,OAAO,GAAG,OAAO,KAAA;EAEhD,MAAM,QAAQA,QAAAA,QAAG,aAAa,YAAY;EAC1C,MAAM,OAAO,MAAM,KAAK;EACxB,IAAI,CAAC,MAAM,OAAO,KAAA;EAElB,MAAM,UAAU,QAAQ,KAAK,UAAU,MAAM,SAAS,QAAQ;EAC9D,OAAO,QAAQ,SAASC,mCAAAA,mCAAmC,KAAA,IAAY;CACzE,QAAQ;EACN;CACF;AACF;;;AChFA,MAAM,+BAAe,IAAI,IAAI;CAAC;CAAY;CAAkB;CAAa;CAAiB;CAAW;AAAS,CAAC;AAC/G,MAAM,8BAAc,IAAI,IAAI;CAAC;CAAgB;CAAS;AAAgB,CAAC;AACvE,MAAM,+BAAe,IAAI,IAAI,CAAC,eAAe,gBAAgB,CAAC;AAC9D,MAAM,gBAAgB;AACtB,MAAM,gBAAgB;AACtB,MAAM,0BAA0B;AAEhC,SAAS,OAAO,OAAgB,UAAkB,MAAqD;CACrG,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,MAAM,IAAI,MAAM,GAAG,SAAS,mBAAmB;CAEjD,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,IAAI,GAAG,CAAC,GAEzD,MAAM,IAAI,MAAM,GAAG,SAAS,+BAA+B;CAE7D,OAAO;AACT;AAEA,SAAS,UAAU,OAAgB,UAA0B;CAC3D,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS,OAAO,KAAK,KAAK,KAAK,GAC1F,MAAM,IAAI,MAAM,GAAG,SAAS,kDAAkD;CAEhF,OAAO;AACT;AAEA,SAAS,QAAQ,OAAgB,UAAqC;CACpE,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAAG,MAAM,IAAI,MAAM,GAAG,SAAS,oCAAoC;CACjH,MAAM,SAAS,MAAM,KAAK,UAAmB;EAC3C,IAAI,OAAO,UAAU,UAAU,MAAM,IAAI,MAAM,GAAG,SAAS,oCAAoC;EAC/F,IAAI;EACJ,IAAI;GACF,MAAM,IAAI,IAAI,KAAK;EACrB,QAAQ;GACN,MAAM,IAAI,MAAM,GAAG,SAAS,oCAAoC;EAClE;EACA,IACG,IAAI,aAAa,YAAY,IAAI,aAAa,WAC/C,IAAI,WAAW,SACf,IAAI,YACJ,IAAI,UAEJ,MAAM,IAAI,MAAM,GAAG,SAAS,oCAAoC;EAElE,OAAO;CACT,CAAC;CACD,OAAO,OAAO,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC;AAC3C;AAEA,SAAS,QAAQ,OAAgB,UAAyC;CACxE,MAAM,QAAQ,OAAO,OAAO,UAAU,YAAY;CAClD,IAAI,OAAO,MAAM,gBAAgB,YAAY,CAAC,wBAAwB,KAAK,MAAM,WAAW,GAC1F,MAAM,IAAI,MAAM,GAAG,SAAS,iDAAiD;CAE/E,OAAO,OAAO,OAAO;EACnB,aAAa,MAAM;EACnB,gBAAgB,QAAQ,MAAM,gBAAgB,GAAG,SAAS,gBAAgB;CAC5E,CAAC;AACH;;AAGA,SAAgB,oBAAoB,OAAgB,WAAW,uBAAkD;CAC/G,MAAM,QAAQ,OAAO,OAAO,UAAU,YAAY;CAClD,MAAM,gBAAgB,OAAO,MAAM,SAAS,GAAG,SAAS,SAAS;CACjE,MAAM,UAAkD,CAAC;CACzD,KAAK,MAAM,CAAC,OAAO,UAAU,OAAO,QAAQ,aAAa,GAAG;EAC1D,IAAI,CAAC,cAAc,KAAK,KAAK,GAAG,MAAM,IAAI,MAAM,GAAG,SAAS,wCAAwC;EACpG,MAAM,SAAS,OAAO,OAAO,GAAG,SAAS,WAAW,SAAS,WAAW;EACxE,IAAI,OAAO,OAAO,UAAU,YAAY,CAAC,cAAc,KAAK,OAAO,KAAK,GACtE,MAAM,IAAI,MAAM,GAAG,SAAS,WAAW,MAAM,uCAAuC;EAEtF,QAAQ,SAAS,OAAO,OAAO;GAC7B,cAAc,UAAU,OAAO,cAAc,GAAG,SAAS,WAAW,MAAM,cAAc;GACxF,OAAO,OAAO;GACd,gBAAgB,QAAQ,OAAO,gBAAgB,GAAG,SAAS,WAAW,MAAM,gBAAgB;EAC9F,CAAC;CACH;CACA,MAAM,iBAAiB,MAAM,YAAY,KAAA,IAAY,KAAA,IAAY,QAAQ,MAAM,SAAS,GAAG,SAAS,SAAS;CAC7G,IACE,kBACA,OAAO,OAAO,OAAO,CAAC,CAAC,MAAM,WAC3B,OAAO,eAAe,MAAM,WAAW,CAAC,eAAe,eAAe,SAAS,MAAM,CAAC,CACxF,GAEA,MAAM,IAAI,MAAM,GAAG,SAAS,2DAA2D;CAEzF,OAAO,OAAO,OAAO;EACnB,UAAU,UAAU,MAAM,UAAU,GAAG,SAAS,UAAU;EAC1D,gBAAgB,UAAU,MAAM,gBAAgB,GAAG,SAAS,gBAAgB;EAC5E,WAAW,UAAU,MAAM,WAAW,GAAG,SAAS,WAAW;EAC7D,eAAe,UAAU,MAAM,eAAe,GAAG,SAAS,eAAe;EACzE,SAAS,OAAO,OAAO,OAAO;EAC9B,GAAI,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,eAAe;CACpE,CAAC;AACH;;;;AClFA,MAAa,gBAAgB;CAAC;CAAc;CAAW;AAAW;;AAGlE,MAAM,wBAAwB;AA+B9B,MAAM,+BAAe,IAAI,IAAI;CAAC;CAAW;CAAO;AAAa,CAAC;AAC9D,MAAM,uCAAuB,IAAI,IAAI;CAAC;CAAS;CAAW;AAAgB,CAAC;AAC3E,MAAM,gBAAgB;AACtB,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB;AACzB,MAAM,mBAAmB;AACzB,MAAM,gBAAgB;AAEtB,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,aAAa,MAAc,WAA4B;CAC9D,MAAM,WAAWC,UAAAA,QAAK,SAAS,MAAM,SAAS;CAC9C,OACE,aAAa,MACZ,CAACA,UAAAA,QAAK,WAAW,QAAQ,KACxB,aAAa,oBACb,CAAC,SAAS,WAAW,GAAG,mBAAmBA,UAAAA,QAAK,KAAK;AAE3D;AAEA,SAAS,iBAAiB,MAAc,OAAwC;CAC9E,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC;CACjC,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,+BAA+B;CAEtF,MAAM,cAAsC,CAAC;CAC7C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,IAAI,OAAO,UAAU,UAAU,MAAM,IAAI,MAAM,YAAY,KAAK,QAAQ,IAAI,kBAAkB;EAC9F,IAAI,MAAM,SAAS,YAAY,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,oCAAoC;EACvG,YAAY,OAAO;CACrB;CACA,OAAO;AACT;AAEA,SAAS,kBAAkB,OAAgB,UAAkB,eAAiC;CAC5F,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC;CACjC,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,MAAM,IAAI,MAAM,qBAAqB,SAAS,kBAAkB;CAC3F,OAAO,MAAM,KAAK,OAAO,UAAU;EACjC,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,CAAC,CAAC,WAAW,GACvD,MAAM,IAAI,MAAM,kBAAkB,MAAM,OAAO,SAAS,4BAA4B;EAEtF,OAAOA,UAAAA,QAAK,QAAQ,eAAe,MAAM,KAAK,CAAC;CACjD,CAAC;AACH;AAEA,SAAS,kBAAkB,QAA4F;CACrH,IAAI,CAAC,SAAS,OAAO,QAAQ,KAAK,CAAC,SAAS,OAAO,SAAS,kBAAkB,GAC5E,MAAM,IAAI,MAAM,GAAG,OAAO,SAAS,iCAAiC;CAEtE,MAAM,0BAA0B,OAAO,KAAK,OAAO,QAAQ,CAAC,CAAC,QAAQ,QAAQ,QAAQ,iBAAiB;CACtG,IAAI,wBAAwB,SAAS,GACnC,MAAM,IAAI,MAAM,GAAG,OAAO,SAAS,2CAA2C,wBAAwB,KAAK,IAAI,GAAG;CAGpH,MAAM,WAAW,OAAO,SAAS;CAEjC,IAAI,EADqB,OAAO,OAAO,UAAU,OAAO,KAAK,OAAO,OAAO,UAAU,SAAS,IAE5F,OAAO;EAAE,UAAU,OAAO;EAAU,eAAe,OAAO;EAAe,OAAO,CAAC;EAAG,SAAS;CAAS;CAGxG,MAAM,yBAAyB,OAAO,KAAK,QAAQ,CAAC,CAAC,QAAQ,QAAQ,CAAC,qBAAqB,IAAI,GAAG,CAAC;CACnG,IAAI,uBAAuB,SAAS,GAClC,MAAM,IAAI,MACR,eAAe,OAAO,SAAS,oEAAoE,uBAAuB,KAAK,IAAI,GACrI;CAEF,IACE,SAAS,mBAAmB,KAAA,MAC3B,OAAO,SAAS,mBAAmB,YAAY,SAAS,eAAe,KAAK,CAAC,CAAC,WAAW,IAE1F,MAAM,IAAI,MAAM,8BAA8B,OAAO,SAAS,4BAA4B;CAE5F,IAAI,SAAS,YAAY,KAAA,KAAa,CAAC,SAAS,SAAS,OAAO,GAC9D,MAAM,IAAI,MAAM,uBAAuB,OAAO,SAAS,mBAAmB;CAE5E,OAAO;EACL,UAAU,OAAO;EACjB,eAAe,OAAO;EACtB,OAAO,kBAAkB,SAAS,OAAO,OAAO,UAAU,OAAO,aAAa;EAC9E,SAAS,SAAS,WAAW,CAAC;EAC9B,GAAI,SAAS,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,OAAO,SAAS,cAAc,CAAC,CAAC,KAAK,EAAE;CAC5G;AACF;AAEA,SAAS,+BAA+B,MAAc,aAAqB,cAAuC;CAChH,MAAM,kBAAkBC,QAAAA,QAAG,aAAa,WAAW;CACnD,IAAI,CAAC,aAAa,MAAM,SAAS,aAAaA,QAAAA,QAAG,aAAa,IAAI,GAAG,eAAe,CAAC,GACnF,MAAM,IAAI,MAAM,YAAY,KAAK,gEAAgE;AAErG;AAEA,SAAS,aACP,aACA,iBACA,MACA,OACc;CACd,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,IAAI,MAAM,YAAY,KAAK,oBAAoB;CAE3E,MAAM,cAAc,OAAO,KAAK,KAAK,CAAC,CAAC,QAAQ,QAAQ,CAAC,aAAa,IAAI,GAAG,CAAC;CAC7E,IAAI,YAAY,SAAS,GACvB,MAAM,IAAI,MACR,YAAY,KAAK,4DAA4D,YAAY,KAAK,IAAI,GACpG;CAEF,IAAI,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,KAAK,CAAC,CAAC,WAAW,GACvE,MAAM,IAAI,MAAM,YAAY,KAAK,qBAAqB;CAExD,IAAID,UAAAA,QAAK,WAAW,MAAM,OAAO,GAC/B,MAAM,IAAI,MAAM,YAAY,KAAK,0DAA0D;CAG7F,MAAM,UAAU,MAAM;CACtB,MAAM,cAAcA,UAAAA,QAAK,QAAQ,aAAa,OAAO;CACrD,MAAM,eAAe,CAACA,UAAAA,QAAK,QAAQ,aAAa,gBAAgB,GAAG,GAAG,eAAe,CAAC,CAAC,QAAQ,SAC7F,aAAa,MAAM,WAAW,CAChC;CACA,IAAI,aAAa,WAAW,GAC1B,MAAM,IAAI,MAAM,YAAY,KAAK,gEAAgE;CAEnG,IAAI,CAACC,QAAAA,QAAG,WAAW,WAAW,KAAK,CAACA,QAAAA,QAAG,SAAS,WAAW,CAAC,CAAC,YAAY,GACvE,MAAM,IAAI,MAAM,YAAY,KAAK,kCAAkC,SAAS;CAE9E,+BAA+B,MAAM,aAAa,YAAY;CAC9D,IAAI,CAAC,mBAAmB,aAAa,OAAO,GAAG;EAG7C,MAAM,mBAAmB,uBAAuB,aAAa,OAAO,MAAM,KAAA;EAC1E,MAAM,IAAI,MACR,mBACI,YAAY,KAAK,gEAAgE,YACjF,YAAY,KAAK,2CAA2C,SAClE;CACF;CAEA,OAAO;EACL;EACA;EACA;EACA,KAAK,iBAAiB,MAAM,MAAM,GAAG;EACrC,GAAI,MAAM,gBAAgB,KAAA,IACtB,CAAC,IACD,EAAE,aAAa,oBAAoB,MAAM,aAAa,YAAY,KAAK,cAAc,EAAE;EAC3F,GAAG,wBAAwB,aAAa,OAAO;CACjD;AACF;AAEA,SAAS,oBAAoB,WAA4B;CACvD,OAAO,cAAc,MAAM,SAAS;EAClC,IAAI;GACF,OAAOA,QAAAA,QAAG,UAAUD,UAAAA,QAAK,KAAK,WAAW,IAAI,CAAC,CAAC,CAAC,OAAO;EACzD,QAAQ;GACN,OAAO;EACT;CACF,CAAC;AACH;AAEA,SAAS,gBAAgB,WAAmB,gBAAwB,aAA+C;CACjH,IAAI,CAAC,oBAAoB,SAAS,GAAG,OAAO,KAAA;CAC5C,IAAI;EAGF,IAAI,CAAC,aAFsBC,QAAAA,QAAG,aAAa,cAER,GADbA,QAAAA,QAAG,aAAa,SACY,CAAC,GAAG,OAAO,KAAA;EAC7D,MAAM,UAAUD,UAAAA,QAAK,SAAS,aAAa,SAAS,KAAK;EACzD,IAAI,CAAC,mBAAmB,aAAa,OAAO,GAAG,OAAO,KAAA;EACtD,OAAO;GACL,MAAMA,UAAAA,QAAK,SAAS,SAAS;GAC7B;GACA;GACA,KAAK,CAAC;GACN,GAAG,wBAAwB,aAAa,OAAO;EACjD;CACF,QAAQ;EAEN;CACF;AACF;AAEA,SAAS,oBAAoB,MAAc,aAAqC;CAC9E,IAAI,CAACC,QAAAA,QAAG,WAAW,IAAI,KAAK,CAACA,QAAAA,QAAG,SAAS,IAAI,CAAC,CAAC,YAAY,GACzD,MAAM,IAAI,MAAM,+CAA+C,MAAM;CAGvE,MAAM,cAAc,gBAAgB,MAAM,MAAM,WAAW;CAC3D,IAAI,aAAa,OAAO,CAAC,WAAW;CAEpC,OAAOA,QAAAA,QACJ,YAAY,MAAM,EAAE,eAAe,KAAK,CAAC,CAAC,CAC1C,QAAQ,UAAU,MAAM,YAAY,CAAC,CAAC,CACtC,MAAM,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC,CAAC,CAC1D,SAAS,UAAU;EAClB,MAAM,UAAU,gBAAgBD,UAAAA,QAAK,KAAK,MAAM,MAAM,IAAI,GAAG,MAAM,WAAW;EAC9E,OAAO,UAAU,CAAC,OAAO,IAAI,CAAC;CAChC,CAAC;AACL;;;;;;;;;AAUA,SAAgB,aAAa,UAAkB,gBAAwBE,QAAAA,QAAG,QAAQ,GAAmB;CACnG,MAAM,SAASC,sBAAAA,sBAA+B,eAAe,UAAU,aAAa,CAAC,CAAC,IAAI,iBAAiB;CAC3G,MAAM,yBAAS,IAAI,IAA0B;CAE7C,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,QAAQ,MAAM,OACvB,KAAK,MAAM,WAAW,oBAAoB,MAAM,MAAM,aAAa,GAAG,OAAO,IAAI,QAAQ,MAAM,OAAO;CAI1G,KAAK,MAAM,SAAS,QAClB,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,OAAO,GACtD,OAAO,IAAI,MAAM,aAAa,MAAM,eAAe,MAAM,OAAO,MAAM,KAAK,CAAC;CAIhF,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;AACvF;;;;;;;;;;;AAYA,SAAgB,mBACd,UACA,gBAAwBD,QAAAA,QAAG,QAAQ,GACoB;CACvD,MAAM,SAASC,sBAAAA,sBAA+B,eAAe,UAAU,aAAa,CAAC,CAAC,IAAI,iBAAiB;CAC3G,MAAM,WAAW,aAAa,UAAU,aAAa;CACrD,IAAI;CACJ,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,mBAAmB,KAAA,GAAW,iBAAiB,MAAM;CAEjE,IAAI,mBAAmB,KAAA,KAAa,CAAC,SAAS,MAAM,YAAY,QAAQ,SAAS,cAAc,GAC7F,MAAM,IAAI,MAAM,qDAAqD,gBAAgB;CAEvF,OAAO;EAAE;EAAU,GAAI,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe;CAAG;AACjF;;AAGA,SAAgB,eAAe,UAAkB,MAAc,eAAsC;CACnG,MAAM,UAAU,aAAa,UAAU,aAAa,CAAC,CAAC,MAAM,cAAc,UAAU,SAAS,IAAI;CACjG,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,oBAAoB,MAAM;CACxD,OAAO;AACT;AAEA,SAAgB,iBAAiB,UAAkB,eAAkC;CACnF,OAAO,aAAa,UAAU,aAAa,CAAC,CAAC,KAAK,YAAY,QAAQ,IAAI;AAC5E;;;;;;;;AASA,SAAS,wBACP,aACA,kBAC8D;CAC9D,MAAM,cAAc,uBAAuB,aAAa,gBAAgB;CACxE,IAAI,CAAC,aAAa,OAAO,CAAC;CAE1B,MAAM,OACJ,YAAY,SAAS,KAAA,IACjB,KAAA,IACA,gBAAgBH,UAAAA,QAAK,KAAK,aAAa,gBAAgB,GAAG,YAAY,IAAI;CAChF,MAAM,WAA4B;EAChC,GAAI,YAAY,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,YAAY,KAAK;EACnE,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;CACvC;CACA,OAAO;EACL,GAAI,SAAS,SAAS,KAAA,KAAa,SAAS,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS;EACjF,GAAI,YAAY,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,YAAY,MAAM;CACxE;AACF;AAEA,SAAS,uBAAuB,aAAqB,kBAA0D;CAC7G,IAAI;EACF,MAAM,cAAcC,QAAAA,QAAG,aAAaD,UAAAA,QAAK,KAAK,aAAa,gBAAgB,CAAC;EAC5E,MAAM,WAAWA,UAAAA,QAAK,KAAK,aAAa,qBAAqB;EAC7D,IAAI,CAACC,QAAAA,QAAG,WAAW,QAAQ,GAAG,OAAO,KAAA;EACrC,OAAO,wBAAwBA,QAAAA,QAAG,aAAaA,QAAAA,QAAG,aAAa,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC;CAC5F,QAAQ;EACN;CACF;AACF;;AAEA,SAAgB,mBAAmB,aAAqB,kBAA8C;CACpG,MAAM,WAAqB,CAAC;CAC5B,MAAM,cAAcA,QAAAA,QAAG,aAAaD,UAAAA,QAAK,KAAK,aAAa,gBAAgB,CAAC;CAC5E,KAAK,MAAM,QAAQ,eAAe;EAChC,MAAM,WAAWA,UAAAA,QAAK,KAAK,aAAa,IAAI;EAC5C,IAAI,CAACC,QAAAA,QAAG,WAAW,QAAQ,GAAG;EAC9B,MAAM,eAAeA,QAAAA,QAAG,aAAa,QAAQ;EAC7C,MAAM,mBAAmBD,UAAAA,QAAK,SAAS,aAAa,YAAY;EAChE,IAAI,qBAAqB,oBAAoB,iBAAiB,WAAW,GAAG,mBAAmBA,UAAAA,QAAK,KAAK,GACvG,MAAM,IAAI,MAAM,iCAAiC,iBAAiB,IAAI,MAAM;EAE9E,MAAM,MAAMC,QAAAA,QAAG,aAAa,cAAc,aAAa;EAEvD,MAAM,WAAW,SAAS,wBAAwB,wBAAwB,GAAG,CAAC,CAAC,OAAO,IAAA,CAAK,KAAK;EAChG,IAAI,SAAS,SAAS,KAAK,OAAO;CACpC;CACA,IAAI,SAAS,WAAW,GAAG,OAAO,KAAA;CAClC,OAAO,CAAC,sEAAsE,iBAAiB,KAAK,GAAG,QAAQ,CAAC,CAAC,KAC/G,MACF;AACF;;AAGA,SAAgB,wBACd,aACA,UACwB;CACxB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAAG;EACnD,IAAI,YAAY,SAAS,KAAA,GAAW;EACpC,YAAY,OAAO;EACnB,QAAQ,OAAO;CACjB;CACA,OAAO;AACT;;AAGA,SAAgB,0BACd,aACA,UACA,MACwB;CACxB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,IAAI,YAAY,SAAS,OAAO,OAAO,YAAY;CAErD,OAAO,wBAAwB,aAAa,IAAI;AAClD"}