@nac3/forge-cli 1.8.6 → 1.9.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.
- package/dist/chat/doctrine_digest.d.ts.map +1 -1
- package/dist/chat/doctrine_digest.js +11 -0
- package/dist/chat/doctrine_digest.js.map +1 -1
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +8 -2
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/tools/config_write.d.ts +35 -0
- package/dist/chat/tools/config_write.d.ts.map +1 -0
- package/dist/chat/tools/config_write.js +381 -0
- package/dist/chat/tools/config_write.js.map +1 -0
- package/dist/chat/tools/db_query.d.ts +20 -0
- package/dist/chat/tools/db_query.d.ts.map +1 -1
- package/dist/chat/tools/db_query.js +3 -3
- package/dist/chat/tools/db_query.js.map +1 -1
- package/dist/chat/tools/nac3_invoke.d.ts.map +1 -1
- package/dist/chat/tools/nac3_invoke.js +19 -1
- package/dist/chat/tools/nac3_invoke.js.map +1 -1
- package/dist/chat/tools/orchestrator_write.d.ts +27 -0
- package/dist/chat/tools/orchestrator_write.d.ts.map +1 -0
- package/dist/chat/tools/orchestrator_write.js +481 -0
- package/dist/chat/tools/orchestrator_write.js.map +1 -0
- package/dist/chat/tools.d.ts.map +1 -1
- package/dist/chat/tools.js +28 -0
- package/dist/chat/tools.js.map +1 -1
- package/dist/commands/embed.d.ts +1 -0
- package/dist/commands/embed.d.ts.map +1 -1
- package/dist/commands/embed.js +5 -1
- package/dist/commands/embed.js.map +1 -1
- package/dist/core/config_formats.d.ts +45 -0
- package/dist/core/config_formats.d.ts.map +1 -0
- package/dist/core/config_formats.js +519 -0
- package/dist/core/config_formats.js.map +1 -0
- package/dist/core/db_write.d.ts +26 -0
- package/dist/core/db_write.d.ts.map +1 -0
- package/dist/core/db_write.js +262 -0
- package/dist/core/db_write.js.map +1 -0
- package/dist/core/forge_embed.d.ts +1 -0
- package/dist/core/forge_embed.d.ts.map +1 -1
- package/dist/core/forge_embed.js +132 -2
- package/dist/core/forge_embed.js.map +1 -1
- package/dist/core/forge_profile.d.ts +23 -0
- package/dist/core/forge_profile.d.ts.map +1 -1
- package/dist/core/forge_profile.js +56 -0
- package/dist/core/forge_profile.js.map +1 -1
- package/dist/core/operate_guard.d.ts +154 -0
- package/dist/core/operate_guard.d.ts.map +1 -0
- package/dist/core/operate_guard.js +542 -0
- package/dist/core/operate_guard.js.map +1 -0
- package/dist/docs/doctrine/operate-mode.md +118 -0
- package/dist/nac3/internal_manifest.d.ts.map +1 -1
- package/dist/nac3/internal_manifest.js +186 -0
- package/dist/nac3/internal_manifest.js.map +1 -1
- package/dist/nac3/manifest_lazy.d.ts +5 -0
- package/dist/nac3/manifest_lazy.d.ts.map +1 -1
- package/dist/nac3/manifest_lazy.js +3 -1
- package/dist/nac3/manifest_lazy.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/doctrine/operate-mode.md +118 -0
- package/package.json +1 -1
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* operate_guard -- OPERATE MODE for the Forge Embedded assistant
|
|
3
|
+
* (Pablo 2026-10-10, PND-205 "salir del modo read-only, acotado").
|
|
4
|
+
*
|
|
5
|
+
* The resident assistant was strictly DIAGNOSTIC: read, SELECT-only queries,
|
|
6
|
+
* reports. Pablo extended the scope to exactly THREE actions -- and to nothing
|
|
7
|
+
* more:
|
|
8
|
+
*
|
|
9
|
+
* 1. CONFIGURE the attended system through its configuration DATA FILES
|
|
10
|
+
* (json / xml / txt / ini / env / yaml / toml / vaults ...).
|
|
11
|
+
* 2. CONFIGURE the attended system through its configuration TABLES
|
|
12
|
+
* (structured UPDATE / INSERT on allowlisted tables).
|
|
13
|
+
* 3. CREATE new processes and SCHEDULE them in the system's orchestrator.
|
|
14
|
+
*
|
|
15
|
+
* Explicitly OUT, by Pablo's own words: the system's DATA tables, and the
|
|
16
|
+
* system's SOFTWARE (source, binaries, units, build definitions).
|
|
17
|
+
*
|
|
18
|
+
* This module is the MECHANICAL enforcement of that scope (same law as the
|
|
19
|
+
* read-only gate: rules are enforcement, not prompt -- brains ignore prompts).
|
|
20
|
+
* It is pure validation + journaling; the verb handlers call it and refuse on
|
|
21
|
+
* a non-ok decision.
|
|
22
|
+
*
|
|
23
|
+
* Three layers, in this order (a later layer can never widen an earlier one):
|
|
24
|
+
*
|
|
25
|
+
* A. HARD INVARIANTS -- compiled in, not configurable: software extensions
|
|
26
|
+
* are never writable, the OS and Forge control surfaces are never
|
|
27
|
+
* writable, DB system schemas are never writable. An operator who writes
|
|
28
|
+
* a sloppy allowlist still cannot touch software.
|
|
29
|
+
* B. OPERATOR ALLOWLIST -- the profile's operate block declares WHICH config
|
|
30
|
+
* files (globs) and WHICH tables may change. Default deny: no allowlist,
|
|
31
|
+
* no writes.
|
|
32
|
+
* C. PER-CALL VALIDATION -- size caps, immutable columns, mandatory WHERE,
|
|
33
|
+
* affected-row preflight, cron grammar, command-arg sanitation.
|
|
34
|
+
*
|
|
35
|
+
* Every mutation is JOURNALED (<journal_dir>/changes.jsonl) and every file
|
|
36
|
+
* mutation keeps a timestamped BACKUP, so the operator can always see -- and
|
|
37
|
+
* revert -- what the assistant did.
|
|
38
|
+
*
|
|
39
|
+
* ASCII-only.
|
|
40
|
+
*/
|
|
41
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
42
|
+
import { promises as fs } from 'node:fs';
|
|
43
|
+
import path from 'node:path';
|
|
44
|
+
export const DEFAULT_JOURNAL_DIR = '.forge/changes';
|
|
45
|
+
export const DEFAULT_MAX_BYTES = 512 * 1024;
|
|
46
|
+
export const DEFAULT_MAX_ROWS = 25;
|
|
47
|
+
export const DEFAULT_IMMUTABLE_COLUMNS = ['id', 'created_at'];
|
|
48
|
+
/* ========================= layer A: invariants ========================= */
|
|
49
|
+
/** Extensions that are SOFTWARE (or compiled software): never writable here,
|
|
50
|
+
* whatever the allowlist says. This is Pablo's rule 5, in code. */
|
|
51
|
+
const CODE_EXT = new Set([
|
|
52
|
+
'js', 'mjs', 'cjs', 'jsx', 'ts', 'tsx', 'mts', 'cts', 'coffee',
|
|
53
|
+
'py', 'pyc', 'pyo', 'pyw', 'rb', 'php', 'phtml', 'php3', 'php4', 'php5', 'php7', 'phps',
|
|
54
|
+
'go', 'rs', 'java', 'class', 'jar', 'war', 'ear', 'kt', 'kts', 'scala', 'groovy',
|
|
55
|
+
'cs', 'vb', 'fs', 'c', 'cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'hxx', 'm', 'mm',
|
|
56
|
+
'swift', 'dart', 'pl', 'pm', 'lua', 'r', 'jl', 'ex', 'exs', 'erl', 'hrl', 'clj',
|
|
57
|
+
'sh', 'bash', 'zsh', 'ksh', 'fish', 'bat', 'cmd', 'ps1', 'psm1', 'psd1', 'vbs', 'wsf',
|
|
58
|
+
'sql', 'ddl', 'pls', 'pkb', 'prc',
|
|
59
|
+
'exe', 'dll', 'so', 'dylib', 'bin', 'msi', 'app', 'deb', 'rpm', 'apk', 'ipa',
|
|
60
|
+
'html', 'htm', 'xhtml', 'jsp', 'asp', 'aspx', 'cshtml', 'razor', 'erb', 'twig',
|
|
61
|
+
'blade', 'hbs', 'handlebars', 'ejs', 'pug', 'jade', 'tpl', 'vue', 'svelte', 'astro',
|
|
62
|
+
'css', 'scss', 'sass', 'less', 'styl',
|
|
63
|
+
'service', 'timer', 'socket', 'mount', 'target', 'path',
|
|
64
|
+
]);
|
|
65
|
+
/** Exact basenames that are software / build / infrastructure definitions. */
|
|
66
|
+
const CODE_BASENAME = new Set([
|
|
67
|
+
'dockerfile', 'containerfile', 'makefile', 'gnumakefile', 'cmakelists.txt',
|
|
68
|
+
'rakefile', 'gemfile', 'procfile', 'justfile', 'build.gradle', 'pom.xml',
|
|
69
|
+
'package.json', 'package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'composer.json',
|
|
70
|
+
'composer.lock', 'requirements.txt', 'pyproject.toml', 'setup.py', 'setup.cfg',
|
|
71
|
+
'cargo.toml', 'cargo.lock', 'go.mod', 'go.sum', 'tsconfig.json', 'jsconfig.json',
|
|
72
|
+
'webpack.config.js', 'vite.config.ts', '.htaccess',
|
|
73
|
+
'docker-compose.yml', 'docker-compose.yaml', 'compose.yml', 'compose.yaml',
|
|
74
|
+
]);
|
|
75
|
+
/** Extensions that ARE configuration data -- the only writable ones.
|
|
76
|
+
* A file whose extension is not here (a vault blob, an extensionless config)
|
|
77
|
+
* can still be written, but ONLY if the allowlist names it LITERALLY (no
|
|
78
|
+
* wildcard in the last path segment). */
|
|
79
|
+
const CONFIG_EXT = new Set([
|
|
80
|
+
'json', 'jsonc', 'json5', 'xml', 'txt', 'ini', 'cfg', 'conf', 'config',
|
|
81
|
+
'properties', 'props', 'prop', 'yaml', 'yml', 'toml', 'env', 'vault', 'vlt',
|
|
82
|
+
'csv', 'tsv', 'list', 'params', 'settings', 'plist',
|
|
83
|
+
]);
|
|
84
|
+
/** Path segments that are never part of a configuration surface. */
|
|
85
|
+
const DENY_SEGMENT = new Set([
|
|
86
|
+
'.git', '.hg', '.svn', 'node_modules', '__pycache__', '.ssh', '.gnupg', '.aws',
|
|
87
|
+
'site-packages', 'vendor', 'dist', 'build',
|
|
88
|
+
]);
|
|
89
|
+
/** Absolute prefixes that belong to the OPERATING SYSTEM, not to the attended
|
|
90
|
+
* application. Cron dirs are deliberately here: scheduling goes through the
|
|
91
|
+
* orchestrator verbs (which have their own declared dir), never through the
|
|
92
|
+
* generic config writer. */
|
|
93
|
+
const DENY_ABS_PREFIX = [
|
|
94
|
+
'/etc/passwd', '/etc/shadow', '/etc/group', '/etc/gshadow', '/etc/sudoers',
|
|
95
|
+
'/etc/ssh', '/etc/systemd', '/etc/init.d', '/etc/pam.d', '/etc/security',
|
|
96
|
+
'/etc/crontab', '/etc/cron.d', '/etc/cron.daily', '/etc/cron.hourly',
|
|
97
|
+
'/var/spool/cron', '/boot', '/bin', '/sbin', '/lib', '/lib64', '/usr/bin',
|
|
98
|
+
'/usr/sbin', '/usr/lib', '/proc', '/sys', '/dev',
|
|
99
|
+
];
|
|
100
|
+
/** DB schemas / objects that are never configuration of the attended system. */
|
|
101
|
+
const DENY_SCHEMA = new Set(['information_schema', 'mysql', 'performance_schema', 'sys', 'sqlite_master']);
|
|
102
|
+
/* ============================== utilities ============================== */
|
|
103
|
+
/** Normalise to forward slashes, no trailing slash, for matching. */
|
|
104
|
+
function norm(p) {
|
|
105
|
+
return String(p || '').replace(/\\/g, '/').replace(/\/+$/, '');
|
|
106
|
+
}
|
|
107
|
+
/** Minimal glob -> RegExp. Supports ** (any depth), * (one segment), ?. */
|
|
108
|
+
function globToRegExp(glob) {
|
|
109
|
+
const g = norm(glob);
|
|
110
|
+
let re = '';
|
|
111
|
+
for (let i = 0; i < g.length; i++) {
|
|
112
|
+
const ch = g[i];
|
|
113
|
+
if (ch === '*') {
|
|
114
|
+
if (g[i + 1] === '*') {
|
|
115
|
+
/* '**' -> any depth; swallow the following slash so a/**''/b also
|
|
116
|
+
* matches a/b. */
|
|
117
|
+
i++;
|
|
118
|
+
if (g[i + 1] === '/') {
|
|
119
|
+
i++;
|
|
120
|
+
re += '(?:.*/)?';
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
re += '.*';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
re += '[^/]*';
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else if (ch === '?') {
|
|
131
|
+
re += '[^/]';
|
|
132
|
+
}
|
|
133
|
+
else if ('^$.|+()[]{}'.indexOf(ch) >= 0) {
|
|
134
|
+
re += '\\' + ch;
|
|
135
|
+
}
|
|
136
|
+
else if (ch === '\\') {
|
|
137
|
+
re += '\\\\';
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
re += ch;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return new RegExp('^' + re + '$', process.platform === 'win32' ? 'i' : '');
|
|
144
|
+
}
|
|
145
|
+
/** True when the glob's LAST segment has no wildcard (the operator named the
|
|
146
|
+
* exact file). Used to let unknown-extension config (vault blobs) through. */
|
|
147
|
+
function globNamesFileLiterally(glob) {
|
|
148
|
+
const last = norm(glob).split('/').pop() || '';
|
|
149
|
+
return last.length > 0 && last.indexOf('*') < 0 && last.indexOf('?') < 0;
|
|
150
|
+
}
|
|
151
|
+
function extOf(p) {
|
|
152
|
+
const base = norm(p).split('/').pop() || '';
|
|
153
|
+
const dot = base.lastIndexOf('.');
|
|
154
|
+
if (dot <= 0)
|
|
155
|
+
return '';
|
|
156
|
+
return base.slice(dot + 1).toLowerCase();
|
|
157
|
+
}
|
|
158
|
+
function baseOf(p) {
|
|
159
|
+
return (norm(p).split('/').pop() || '').toLowerCase();
|
|
160
|
+
}
|
|
161
|
+
export function shortHash(text) {
|
|
162
|
+
return createHash('sha256').update(String(text ?? ''), 'utf8').digest('hex').slice(0, 16);
|
|
163
|
+
}
|
|
164
|
+
function no(reason) { return { ok: false, reason }; }
|
|
165
|
+
/* ===================== 1. configuration DATA FILES ===================== */
|
|
166
|
+
/**
|
|
167
|
+
* Decide whether `rawPath` may be WRITTEN as configuration data.
|
|
168
|
+
*
|
|
169
|
+
* Order: resolve -> hard invariants (segments, OS prefixes, Forge control
|
|
170
|
+
* surface, software extensions) -> operator allowlist -> deny list ->
|
|
171
|
+
* extension class. Returns the absolute path when ok.
|
|
172
|
+
*/
|
|
173
|
+
export function guardConfigFile(projectRoot, op, rawPath) {
|
|
174
|
+
const operate = op || {};
|
|
175
|
+
if (operate.enabled !== true) {
|
|
176
|
+
return no('operate mode is OFF in this deployment profile: configuration changes are not allowed. '
|
|
177
|
+
+ 'Diagnose and emit the precise instruction for the operator instead.');
|
|
178
|
+
}
|
|
179
|
+
const raw = String(rawPath || '').trim();
|
|
180
|
+
if (!raw)
|
|
181
|
+
return no('path is required.');
|
|
182
|
+
if (raw.indexOf('\u0000') >= 0)
|
|
183
|
+
return no('invalid path.');
|
|
184
|
+
const root = path.resolve(projectRoot);
|
|
185
|
+
const abs = path.isAbsolute(raw) ? path.resolve(raw) : path.resolve(root, raw);
|
|
186
|
+
const absN = norm(abs);
|
|
187
|
+
const rootN = norm(root);
|
|
188
|
+
const inRoot = absN === rootN || absN.indexOf(rootN + '/') === 0;
|
|
189
|
+
const rel = inRoot ? absN.slice(rootN.length + 1) : '';
|
|
190
|
+
/* --- A. hard invariants --- */
|
|
191
|
+
for (const seg of absN.split('/')) {
|
|
192
|
+
if (DENY_SEGMENT.has(seg.toLowerCase())) {
|
|
193
|
+
return no('refused: "' + seg + '" is not a configuration surface (vcs / dependency / build / key dir).');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (!inRoot) {
|
|
197
|
+
for (const pre of DENY_ABS_PREFIX) {
|
|
198
|
+
if (absN === pre || absN.indexOf(pre + '/') === 0) {
|
|
199
|
+
return no('refused: "' + pre + '" belongs to the operating system, not to the attended application. '
|
|
200
|
+
+ 'Emit the instruction for the operator (and schedule jobs with the orchestrator verbs, '
|
|
201
|
+
+ 'not by writing cron files by hand).');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/* Forge's own control surface: the profile that grants these powers, the DB
|
|
206
|
+
* credentials, the mission. Writing them would be self-escalation. */
|
|
207
|
+
if (inRoot && (rel === '.forge' || rel.indexOf('.forge/') === 0)) {
|
|
208
|
+
return no('refused: .forge/ is Forge\'s own control surface (profile, credentials, mission), '
|
|
209
|
+
+ 'not the attended system\'s configuration. Reports go through the report dirs; '
|
|
210
|
+
+ 'a profile change is the operator\'s call.');
|
|
211
|
+
}
|
|
212
|
+
const ext = extOf(absN);
|
|
213
|
+
const base = baseOf(absN);
|
|
214
|
+
if (CODE_EXT.has(ext) || CODE_BASENAME.has(base)) {
|
|
215
|
+
return no('refused: "' + base + '" is SOFTWARE (source / binary / unit / build definition). '
|
|
216
|
+
+ 'This deployment CONFIGURES the system, it never MODIFIES it. For a code change, '
|
|
217
|
+
+ 'open a ticket or record a pending with the analysis.');
|
|
218
|
+
}
|
|
219
|
+
/* --- B. operator allowlist --- */
|
|
220
|
+
const allow = Array.isArray(operate.config_files?.allow) ? operate.config_files.allow : [];
|
|
221
|
+
if (allow.length === 0) {
|
|
222
|
+
return no('no configuration files are allowlisted in this profile. Ask the operator to declare '
|
|
223
|
+
+ 'operate.config_files.allow (globs) in .forge/profile.<env>.json.');
|
|
224
|
+
}
|
|
225
|
+
let matched = '';
|
|
226
|
+
for (const g of allow) {
|
|
227
|
+
if (!g || typeof g !== 'string')
|
|
228
|
+
continue;
|
|
229
|
+
const target = path.isAbsolute(g) ? absN : (inRoot ? rel : '');
|
|
230
|
+
if (!target)
|
|
231
|
+
continue;
|
|
232
|
+
if (globToRegExp(g).test(target)) {
|
|
233
|
+
matched = g;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (!matched) {
|
|
238
|
+
return no('refused: "' + (inRoot ? rel : absN) + '" is not in this deployment\'s configuration allowlist '
|
|
239
|
+
+ '(operate.config_files.allow = ' + allow.join(', ') + ').');
|
|
240
|
+
}
|
|
241
|
+
const deny = Array.isArray(operate.config_files?.deny) ? operate.config_files.deny : [];
|
|
242
|
+
for (const g of deny) {
|
|
243
|
+
if (!g || typeof g !== 'string')
|
|
244
|
+
continue;
|
|
245
|
+
const target = path.isAbsolute(g) ? absN : (inRoot ? rel : absN);
|
|
246
|
+
if (globToRegExp(g).test(target)) {
|
|
247
|
+
return no('refused: "' + (inRoot ? rel : absN) + '" is excluded by operate.config_files.deny ("' + g + '").');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/* --- C. extension class --- */
|
|
251
|
+
if (!CONFIG_EXT.has(ext)) {
|
|
252
|
+
const literal = base.indexOf('.env') === 0 || globNamesFileLiterally(matched);
|
|
253
|
+
if (!literal) {
|
|
254
|
+
return no('refused: "' + base + '" is not a recognised configuration format and the allowlist entry '
|
|
255
|
+
+ '("' + matched + '") does not name it literally. To allow a vault / extensionless config file, '
|
|
256
|
+
+ 'the operator must list that exact path in operate.config_files.allow.');
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return { ok: true, abs, shown: inRoot ? rel : absN };
|
|
260
|
+
}
|
|
261
|
+
/** Size + text-only cap for a config-file write. */
|
|
262
|
+
export function guardConfigSize(op, content) {
|
|
263
|
+
const max = Math.max(1, Math.floor(Number(op?.config_files?.max_bytes) || DEFAULT_MAX_BYTES));
|
|
264
|
+
const text = String(content ?? '');
|
|
265
|
+
const bytes = Buffer.byteLength(text, 'utf8');
|
|
266
|
+
if (bytes > max) {
|
|
267
|
+
return { ok: false, reason: 'content too large (' + bytes + ' bytes, max ' + max + '). '
|
|
268
|
+
+ 'A configuration file this big is probably not configuration -- check the path.' };
|
|
269
|
+
}
|
|
270
|
+
if (text.indexOf('\u0000') >= 0) {
|
|
271
|
+
return { ok: false, reason: 'binary content (NUL byte) rejected: the config writer is text-only.' };
|
|
272
|
+
}
|
|
273
|
+
return { ok: true };
|
|
274
|
+
}
|
|
275
|
+
/* ====================== 2. configuration TABLES ======================= */
|
|
276
|
+
const IDENT_RE = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
277
|
+
/** Validate a table/column name, optionally db-qualified ("db.table"). */
|
|
278
|
+
export function guardIdentifier(name, what = 'identifier') {
|
|
279
|
+
const n = String(name || '').trim();
|
|
280
|
+
if (!n)
|
|
281
|
+
return { ok: false, reason: what + ' is required.' };
|
|
282
|
+
const parts = n.split('.');
|
|
283
|
+
if (parts.length > 2)
|
|
284
|
+
return { ok: false, reason: 'invalid ' + what + ' "' + n + '".' };
|
|
285
|
+
for (const p of parts) {
|
|
286
|
+
if (!IDENT_RE.test(p)) {
|
|
287
|
+
return { ok: false, reason: 'invalid ' + what + ' "' + n + '": letters, digits and _ only '
|
|
288
|
+
+ '(no quotes, spaces, parentheses or SQL expressions).' };
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
for (const p of parts) {
|
|
292
|
+
if (DENY_SCHEMA.has(p.toLowerCase())) {
|
|
293
|
+
return { ok: false, reason: 'refused: "' + n + '" is a DB system schema/object, not the attended system\'s configuration.' };
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return { ok: true };
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Decide whether a structured write on `table` is allowed. Pablo's rule 4
|
|
300
|
+
* (never touch the system's DATA tables) is enforced as DEFAULT DENY: only
|
|
301
|
+
* the tables the operator declared as configuration may change.
|
|
302
|
+
*/
|
|
303
|
+
export function guardConfigTable(op, table, tableOp, opts = {}) {
|
|
304
|
+
const operate = op || {};
|
|
305
|
+
if (operate.enabled !== true) {
|
|
306
|
+
return { ok: false, reason: 'operate mode is OFF in this deployment profile: table changes are not allowed. '
|
|
307
|
+
+ 'Emit the precise instruction (table, column, value, WHERE) for the operator instead.' };
|
|
308
|
+
}
|
|
309
|
+
const idc = guardIdentifier(table, 'table name');
|
|
310
|
+
if (!idc.ok)
|
|
311
|
+
return idc;
|
|
312
|
+
const tbl = String(table).trim().toLowerCase();
|
|
313
|
+
const bare = tbl.split('.').pop();
|
|
314
|
+
const cfg = operate.config_tables || {};
|
|
315
|
+
const allow = [
|
|
316
|
+
...(Array.isArray(cfg.allow) ? cfg.allow : []),
|
|
317
|
+
...(opts.extraAllow || []),
|
|
318
|
+
].filter((t) => typeof t === 'string' && t.trim()).map((t) => t.trim().toLowerCase());
|
|
319
|
+
if (allow.length === 0) {
|
|
320
|
+
return { ok: false, reason: 'no configuration tables are allowlisted in this profile. Ask the operator to declare '
|
|
321
|
+
+ 'operate.config_tables.allow in .forge/profile.<env>.json -- and never to list DATA tables there.' };
|
|
322
|
+
}
|
|
323
|
+
const hit = allow.some((a) => a === tbl || a === bare || a.split('.').pop() === bare);
|
|
324
|
+
if (!hit) {
|
|
325
|
+
return { ok: false, reason: 'refused: "' + table + '" is not an allowlisted CONFIGURATION table. '
|
|
326
|
+
+ 'This deployment may only change configuration tables (' + allow.join(', ') + '); '
|
|
327
|
+
+ 'the system\'s DATA tables are off limits. For a data change, emit the instruction for the '
|
|
328
|
+
+ 'operator or open a ticket.' };
|
|
329
|
+
}
|
|
330
|
+
const deny = (Array.isArray(cfg.deny) ? cfg.deny : []).filter((t) => typeof t === 'string').map((t) => t.trim().toLowerCase());
|
|
331
|
+
if (deny.some((d) => d === tbl || d === bare)) {
|
|
332
|
+
return { ok: false, reason: 'refused: "' + table + '" is excluded by operate.config_tables.deny.' };
|
|
333
|
+
}
|
|
334
|
+
if (tableOp === 'insert' && cfg.allow_insert === false) {
|
|
335
|
+
return { ok: false, reason: 'refused: INSERT is disabled in this profile (operate.config_tables.allow_insert=false).' };
|
|
336
|
+
}
|
|
337
|
+
if (tableOp === 'delete' && cfg.allow_delete !== true) {
|
|
338
|
+
return { ok: false, reason: 'refused: DELETE is disabled in this profile (operate.config_tables.allow_delete is not true). '
|
|
339
|
+
+ 'Disable the row instead (set its enabled/active flag to 0) or ask the operator.' };
|
|
340
|
+
}
|
|
341
|
+
return { ok: true };
|
|
342
|
+
}
|
|
343
|
+
/** Columns that can never be set: the profile's list, or the default. */
|
|
344
|
+
export function immutableColumns(op) {
|
|
345
|
+
const cfg = op?.config_tables || {};
|
|
346
|
+
const list = Array.isArray(cfg.immutable_columns) ? cfg.immutable_columns : [...DEFAULT_IMMUTABLE_COLUMNS];
|
|
347
|
+
return list.filter((c) => typeof c === 'string' && c.trim()).map((c) => c.trim().toLowerCase());
|
|
348
|
+
}
|
|
349
|
+
export function maxRows(op) {
|
|
350
|
+
const n = Math.floor(Number(op?.config_tables?.max_rows));
|
|
351
|
+
return n > 0 ? Math.min(n, 1000) : DEFAULT_MAX_ROWS;
|
|
352
|
+
}
|
|
353
|
+
/** Validate a {column: value} map: identifiers, scalars only, immutability. */
|
|
354
|
+
export function guardColumnMap(op, map, what) {
|
|
355
|
+
const out = {};
|
|
356
|
+
const entries = Object.entries(map || {});
|
|
357
|
+
if (entries.length === 0) {
|
|
358
|
+
return { ok: false, reason: what + ' must name at least one column.' };
|
|
359
|
+
}
|
|
360
|
+
if (entries.length > 50)
|
|
361
|
+
return { ok: false, reason: what + ' has too many columns (max 50).' };
|
|
362
|
+
const immutable = what === 'where' ? [] : immutableColumns(op);
|
|
363
|
+
for (const [col, val] of entries) {
|
|
364
|
+
const idc = guardIdentifier(col, 'column name');
|
|
365
|
+
if (!idc.ok)
|
|
366
|
+
return { ok: false, reason: idc.reason };
|
|
367
|
+
if (immutable.indexOf(col.toLowerCase()) >= 0) {
|
|
368
|
+
return { ok: false, reason: 'refused: column "' + col + '" is immutable in this profile '
|
|
369
|
+
+ '(operate.config_tables.immutable_columns).' };
|
|
370
|
+
}
|
|
371
|
+
if (val === null) {
|
|
372
|
+
out[col] = null;
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
const t = typeof val;
|
|
376
|
+
if (t === 'number') {
|
|
377
|
+
if (!Number.isFinite(val))
|
|
378
|
+
return { ok: false, reason: 'column "' + col + '": non-finite number.' };
|
|
379
|
+
out[col] = val;
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
if (t === 'boolean') {
|
|
383
|
+
out[col] = val;
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
if (t === 'string') {
|
|
387
|
+
const s = val;
|
|
388
|
+
if (s.length > 65535)
|
|
389
|
+
return { ok: false, reason: 'column "' + col + '": value too long (max 65535).' };
|
|
390
|
+
if (s.indexOf('\u0000') >= 0)
|
|
391
|
+
return { ok: false, reason: 'column "' + col + '": NUL byte rejected.' };
|
|
392
|
+
out[col] = s;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
return { ok: false, reason: 'column "' + col + '": only strings, numbers, booleans and null are accepted '
|
|
396
|
+
+ '(no objects, no SQL expressions -- pass a JSON string if the column stores JSON).' };
|
|
397
|
+
}
|
|
398
|
+
return { ok: true, clean: out };
|
|
399
|
+
}
|
|
400
|
+
/* ======================= 3. orchestrator / cron ======================= */
|
|
401
|
+
const CRON_BOUNDS = [[0, 59], [0, 23], [1, 31], [1, 12], [0, 7]];
|
|
402
|
+
/**
|
|
403
|
+
* Validate a 5-field Linux cron expression (the grammar the orchestrators in
|
|
404
|
+
* this ecosystem speak: '*', value, lists, ranges, steps). Returns the
|
|
405
|
+
* normalised expression. Macros (@daily) are refused on purpose: the
|
|
406
|
+
* orchestrators store 5 fields.
|
|
407
|
+
*/
|
|
408
|
+
export function guardCron(expr) {
|
|
409
|
+
const raw = String(expr || '').trim().replace(/\s+/g, ' ');
|
|
410
|
+
if (!raw)
|
|
411
|
+
return { ok: false, reason: 'cron expression is required (5 Linux fields, e.g. "0 3 * * *").' };
|
|
412
|
+
if (raw.charAt(0) === '@') {
|
|
413
|
+
return { ok: false, reason: 'cron macros (@daily, @hourly) are not accepted: use the 5 fields, e.g. "0 0 * * *".' };
|
|
414
|
+
}
|
|
415
|
+
const fields = raw.split(' ');
|
|
416
|
+
if (fields.length !== 5) {
|
|
417
|
+
return { ok: false, reason: 'cron must have 5 fields (minute hour day-of-month month day-of-week); got '
|
|
418
|
+
+ fields.length + ' in "' + raw + '".' };
|
|
419
|
+
}
|
|
420
|
+
for (let i = 0; i < 5; i++) {
|
|
421
|
+
const bounds = CRON_BOUNDS[i];
|
|
422
|
+
const min = bounds[0], max = bounds[1];
|
|
423
|
+
for (const token of fields[i].split(',')) {
|
|
424
|
+
const t = token.trim();
|
|
425
|
+
if (!t)
|
|
426
|
+
return { ok: false, reason: 'cron: empty token in field ' + (i + 1) + ' of "' + raw + '".' };
|
|
427
|
+
const m = t.match(/^(\*|\d+|\d+-\d+)(?:\/(\d+))?$/);
|
|
428
|
+
if (!m) {
|
|
429
|
+
return { ok: false, reason: 'cron: invalid token "' + t + '" in field ' + (i + 1)
|
|
430
|
+
+ ' (allowed: *, n, a-b, each with an optional /step).' };
|
|
431
|
+
}
|
|
432
|
+
if (m[2] !== undefined && Number(m[2]) === 0)
|
|
433
|
+
return { ok: false, reason: 'cron: step 0 in "' + t + '".' };
|
|
434
|
+
if (m[1] !== '*') {
|
|
435
|
+
const parts = m[1].split('-');
|
|
436
|
+
for (const v of parts.map((x) => Number(x))) {
|
|
437
|
+
if (v < min || v > max) {
|
|
438
|
+
return { ok: false, reason: 'cron: value ' + v + ' out of range [' + min + '-' + max + '] in field ' + (i + 1) + '.' };
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (parts.length === 2 && Number(parts[0]) > Number(parts[1])) {
|
|
442
|
+
return { ok: false, reason: 'cron: inverted range "' + m[1] + '" in field ' + (i + 1) + '.' };
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return { ok: true, cron: raw };
|
|
448
|
+
}
|
|
449
|
+
/** A process name must be a plain slug: it ends up in a table, in a cron file
|
|
450
|
+
* name and (templated) on a command line. No shell metacharacters, ever. */
|
|
451
|
+
export function guardProcessName(name) {
|
|
452
|
+
const n = String(name || '').trim();
|
|
453
|
+
if (!n)
|
|
454
|
+
return { ok: false, reason: 'process name is required.' };
|
|
455
|
+
if (n.length > 80)
|
|
456
|
+
return { ok: false, reason: 'process name too long (max 80).' };
|
|
457
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9 ._-]*$/.test(n)) {
|
|
458
|
+
return { ok: false, reason: 'invalid process name "' + n + '": letters, digits, space, dot, underscore and dash only '
|
|
459
|
+
+ '(the name reaches a command line -- no shell metacharacters).' };
|
|
460
|
+
}
|
|
461
|
+
return { ok: true, name: n };
|
|
462
|
+
}
|
|
463
|
+
/** Sanitise one templated command argument. */
|
|
464
|
+
export function guardCommandArg(value) {
|
|
465
|
+
const v = String(value ?? '').trim();
|
|
466
|
+
if (v.length > 200)
|
|
467
|
+
return { ok: false, reason: 'argument too long (max 200): "' + v.slice(0, 40) + '".' };
|
|
468
|
+
if (!/^[A-Za-z0-9 ._,:=@/+-]*$/.test(v)) {
|
|
469
|
+
return { ok: false, reason: 'refused argument "' + v + '": shell metacharacters are not allowed.' };
|
|
470
|
+
}
|
|
471
|
+
return { ok: true, value: v };
|
|
472
|
+
}
|
|
473
|
+
export function journalDirAbs(root, op) {
|
|
474
|
+
const d = (op?.journal_dir && String(op.journal_dir).trim()) || DEFAULT_JOURNAL_DIR;
|
|
475
|
+
return path.isAbsolute(d) ? d : path.join(root, d);
|
|
476
|
+
}
|
|
477
|
+
/** Copy a file into the journal's backup dir. Returns null when absent. */
|
|
478
|
+
export async function backupFile(root, op, abs) {
|
|
479
|
+
let before = '';
|
|
480
|
+
try {
|
|
481
|
+
before = await fs.readFile(abs, 'utf8');
|
|
482
|
+
}
|
|
483
|
+
catch {
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
const dir = path.join(journalDirAbs(root, op), 'backups');
|
|
487
|
+
await fs.mkdir(dir, { recursive: true });
|
|
488
|
+
const stamp = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 15);
|
|
489
|
+
const flat = norm(abs).replace(/^[A-Za-z]:/, '').replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^_+/, '').slice(-80);
|
|
490
|
+
const id = stamp + '-' + randomBytes(3).toString('hex') + '__' + flat;
|
|
491
|
+
const bp = path.join(dir, id);
|
|
492
|
+
await fs.writeFile(bp, before, 'utf8');
|
|
493
|
+
return { backup_id: id, backup_path: bp, before };
|
|
494
|
+
}
|
|
495
|
+
/** Append one record to <journal_dir>/changes.jsonl. Never throws. */
|
|
496
|
+
export async function journalChange(root, op, rec) {
|
|
497
|
+
const dir = journalDirAbs(root, op);
|
|
498
|
+
const file = path.join(dir, 'changes.jsonl');
|
|
499
|
+
try {
|
|
500
|
+
await fs.mkdir(dir, { recursive: true });
|
|
501
|
+
const line = JSON.stringify({ ts: new Date().toISOString(), ...rec }) + '\n';
|
|
502
|
+
await fs.appendFile(file, line, 'utf8');
|
|
503
|
+
}
|
|
504
|
+
catch { /* the change already happened; a journal failure must not mask it */ }
|
|
505
|
+
return file;
|
|
506
|
+
}
|
|
507
|
+
/** Read back a journal record by backup id (for file-revert). */
|
|
508
|
+
export async function findBackup(root, op, backupId) {
|
|
509
|
+
const id = String(backupId || '').trim();
|
|
510
|
+
if (!id || !/^[A-Za-z0-9._-]+$/.test(id))
|
|
511
|
+
return null;
|
|
512
|
+
const bp = path.join(journalDirAbs(root, op), 'backups', id);
|
|
513
|
+
try {
|
|
514
|
+
await fs.access(bp);
|
|
515
|
+
}
|
|
516
|
+
catch {
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
let rec = null;
|
|
520
|
+
try {
|
|
521
|
+
const text = await fs.readFile(path.join(journalDirAbs(root, op), 'changes.jsonl'), 'utf8');
|
|
522
|
+
for (const line of text.split('\n')) {
|
|
523
|
+
if (!line.trim())
|
|
524
|
+
continue;
|
|
525
|
+
try {
|
|
526
|
+
const r = JSON.parse(line);
|
|
527
|
+
if (r.backup_id === id)
|
|
528
|
+
rec = r;
|
|
529
|
+
}
|
|
530
|
+
catch { /* skip malformed */ }
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
catch { /* no journal -- the backup alone is enough to restore */ }
|
|
534
|
+
return { rec: rec || { kind: 'config_file', verb: 'unknown', target: '', backup_id: id }, backup_path: bp };
|
|
535
|
+
}
|
|
536
|
+
/** The journal dir as shown to humans (project-relative when inside root). */
|
|
537
|
+
export function journalDirShown(root, op) {
|
|
538
|
+
const n = norm(journalDirAbs(root, op));
|
|
539
|
+
const r = norm(path.resolve(root));
|
|
540
|
+
return n.indexOf(r + '/') === 0 ? n.slice(r.length + 1) : n;
|
|
541
|
+
}
|
|
542
|
+
//# sourceMappingURL=operate_guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operate_guard.js","sourceRoot":"","sources":["../../src/core/operate_guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAgE7B,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AACpD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,IAAI,EAAE,YAAY,CAAU,CAAC;AAEvE,6EAA6E;AAE7E;oEACoE;AACpE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;IACvB,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ;IAC9D,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACvF,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ;IAChF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI;IAC7E,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IAC/E,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IACrF,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IACjC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IAC5E,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IAC9E,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO;IACnF,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACrC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM;CACxD,CAAC,CAAC;AAEH,8EAA8E;AAC9E,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB;IAC1E,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS;IACxE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,eAAe;IACnF,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW;IAC9E,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe;IAChF,mBAAmB,EAAE,gBAAgB,EAAE,WAAW;IAClD,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc;CAC3E,CAAC,CAAC;AAEH;;;0CAG0C;AAC1C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ;IACtE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK;IAC3E,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO;CACpD,CAAC,CAAC;AAEH,oEAAoE;AACpE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAC9E,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO;CAC3C,CAAC,CAAC;AAEH;;;6BAG6B;AAC7B,MAAM,eAAe,GAAG;IACtB,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc;IAC1E,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe;IACxE,cAAc,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB;IACpE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;IACzE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM;CACjD,CAAC;AAEF,gFAAgF;AAChF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC;AAE3G,6EAA6E;AAE7E,qEAAqE;AACrE,SAAS,IAAI,CAAC,CAAS;IACrB,OAAO,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,2EAA2E;AAC3E,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAW,CAAC;QAC1B,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACrB;kCACkB;gBAClB,CAAC,EAAE,CAAC;gBACJ,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBAAC,CAAC,EAAE,CAAC;oBAAC,EAAE,IAAI,UAAU,CAAC;gBAAC,CAAC;qBAAM,CAAC;oBAAC,EAAE,IAAI,IAAI,CAAC;gBAAC,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACN,EAAE,IAAI,OAAO,CAAC;YAChB,CAAC;QACH,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACtB,EAAE,IAAI,MAAM,CAAC;QACf,CAAC;aAAM,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,EAAE,IAAI,IAAI,GAAG,EAAE,CAAC;QAClB,CAAC;aAAM,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YACvB,EAAE,IAAI,MAAM,CAAC;QACf,CAAC;aAAM,CAAC;YACN,EAAE,IAAI,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IACD,OAAO,IAAI,MAAM,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED;+EAC+E;AAC/E,SAAS,sBAAsB,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAC/C,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,KAAK,CAAC,CAAS;IACtB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACxB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AAC3C,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC5F,CAAC;AAeD,SAAS,EAAE,CAAC,MAAc,IAAkB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAE3E,6EAA6E;AAE7E;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,WAAmB,EACnB,EAAoC,EACpC,OAAe;IAEf,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC;IACzB,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC,yFAAyF;cAC/F,qEAAqE,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC,mBAAmB,CAAC,CAAC;IACzC,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC;IAE3D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvD,gCAAgC;IAChC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC,YAAY,GAAG,GAAG,GAAG,wEAAwE,CAAC,CAAC;QAC3G,CAAC;IACH,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YAClC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClD,OAAO,EAAE,CAAC,YAAY,GAAG,GAAG,GAAG,sEAAsE;sBACjG,wFAAwF;sBACxF,qCAAqC,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IACD;0EACsE;IACtE,IAAI,MAAM,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO,EAAE,CAAC,oFAAoF;cAC1F,gFAAgF;cAChF,2CAA2C,CAAC,CAAC;IACnD,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO,EAAE,CAAC,YAAY,GAAG,IAAI,GAAG,6DAA6D;cACzF,kFAAkF;cAClF,sDAAsD,CAAC,CAAC;IAC9D,CAAC;IAED,mCAAmC;IACnC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,CAAE,OAAO,CAAC,YAAmC,CAAC,KAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/H,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC,sFAAsF;cAC5F,kEAAkE,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,SAAS;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAAC,OAAO,GAAG,CAAC,CAAC;YAAC,MAAM;QAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,CAAC,YAAY,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,yDAAyD;cACtG,gCAAgC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,CAAE,OAAO,CAAC,YAAmC,CAAC,IAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5H,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,SAAS;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC,YAAY,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,+CAA+C,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QAChH,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAC9E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,CAAC,YAAY,GAAG,IAAI,GAAG,qEAAqE;kBACjG,IAAI,GAAG,OAAO,GAAG,+EAA+E;kBAChG,uEAAuE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACvD,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,eAAe,CAAC,EAAoC,EAAE,OAAe;IACnF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC;IAC9F,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9C,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,GAAG,KAAK,GAAG,cAAc,GAAG,GAAG,GAAG,KAAK;kBACpF,gFAAgF,EAAE,CAAC;IACzF,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qEAAqE,EAAE,CAAC;IACtG,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,4EAA4E;AAE5E,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,0EAA0E;AAC1E,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,IAAI,GAAG,YAAY;IAC/D,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAG,eAAe,EAAE,CAAC;IAC7D,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;IACxF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,gCAAgC;sBACvF,sDAAsD,EAAE,CAAC;QAC/D,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACrC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,GAAG,CAAC,GAAG,2EAA2E,EAAE,CAAC;QAC/H,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AASD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,EAAoC,EACpC,KAAa,EACb,OAAgB,EAChB,OAA0B,EAAE;IAE5B,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC;IACzB,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iFAAiF;kBACzG,sFAAsF,EAAE,CAAC;IAC/F,CAAC;IACD,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,GAAG,CAAC;IACxB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAY,CAAC;IAE5C,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG;QACZ,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;KAC3B,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IACtF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,uFAAuF;kBAC/G,kGAAkG,EAAE,CAAC;IAC3G,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAK,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAa,KAAK,IAAI,CAAC,CAAC;IAClG,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,GAAG,KAAK,GAAG,+CAA+C;kBAC9F,wDAAwD,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK;kBACnF,4FAA4F;kBAC5F,4BAA4B,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/H,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,GAAG,KAAK,GAAG,8CAA8C,EAAE,CAAC;IACtG,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;QACvD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yFAAyF,EAAE,CAAC;IAC1H,CAAC;IACD,IAAI,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QACtD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gGAAgG;kBACxH,iFAAiF,EAAE,CAAC;IAC1F,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,EAAoC;IACnE,MAAM,GAAG,GAAG,EAAE,EAAE,aAAa,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,yBAAyB,CAAC,CAAC;IAC3G,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,EAAoC;IAC1D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACtD,CAAC;AAID,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAC5B,EAAoC,EACpC,GAAwC,EACxC,IAAgC;IAEhC,MAAM,GAAG,GAA8B,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAG,iCAAiC,EAAE,CAAC;IACzE,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAG,iCAAiC,EAAE,CAAC;IAChG,MAAM,SAAS,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC/D,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,eAAe,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;QACtD,IAAI,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,GAAG,GAAG,GAAG,iCAAiC;sBACrF,4CAA4C,EAAE,CAAC;QACrD,CAAC;QACD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YAAC,SAAS;QAAC,CAAC;QAChD,MAAM,CAAC,GAAG,OAAO,GAAG,CAAC;QACrB,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAa,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAG,GAAG,GAAG,uBAAuB,EAAE,CAAC;YAC9G,GAAG,CAAC,GAAG,CAAC,GAAG,GAAa,CAAC;YAAC,SAAS;QACrC,CAAC;QACD,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAc,CAAC;YAAC,SAAS;QAAC,CAAC;QAC7D,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;YACnB,MAAM,CAAC,GAAG,GAAa,CAAC;YACxB,IAAI,CAAC,CAAC,MAAM,GAAG,KAAK;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAG,GAAG,GAAG,gCAAgC,EAAE,CAAC;YACxG,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAG,GAAG,GAAG,uBAAuB,EAAE,CAAC;YACvG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAAC,SAAS;QACzB,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAG,GAAG,GAAG,2DAA2D;kBACtG,mFAAmF,EAAE,CAAC;IAC5F,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAClC,CAAC;AAED,4EAA4E;AAE5E,MAAM,WAAW,GAA4B,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE1F;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3D,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iEAAiE,EAAE,CAAC;IAC1G,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qFAAqF,EAAE,CAAC;IACtH,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,4EAA4E;kBACpG,MAAM,CAAC,MAAM,GAAG,OAAO,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;IAC7C,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAqB,CAAC;QAClD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACvC,KAAK,MAAM,KAAK,IAAK,MAAM,CAAC,CAAC,CAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;YACrG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;YACpD,IAAI,CAAC,CAAC,EAAE,CAAC;gBACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;0BAC7E,qDAAqD,EAAE,CAAC;YAC9D,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;YAC3G,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACjB,MAAM,KAAK,GAAI,CAAC,CAAC,CAAC,CAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC1C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC5C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;wBACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,GAAG,CAAC,GAAG,iBAAiB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC;oBACzH,CAAC;gBACH,CAAC;gBACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC9D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC;gBAChG,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACjC,CAAC;AAED;6EAC6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;IAClE,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;IACnF,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,GAAG,CAAC,GAAG,2DAA2D;kBAClH,+DAA+D,EAAE,CAAC;IACxE,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/B,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,IAAI,CAAC,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC;IAC3G,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,GAAG,CAAC,GAAG,0CAA0C,EAAE,CAAC;IACtG,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAChC,CAAC;AAgBD,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,EAAoC;IAC9E,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,IAAI,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,mBAAmB,CAAC;IACpF,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,EAAoC,EACpC,GAAW;IAEX,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC;QAAC,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IACvE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;IAC1D,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IACjH,MAAM,EAAE,GAAG,KAAK,GAAG,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IACtE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;AACpD,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,EAAoC,EACpC,GAAiB;IAEjB,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;QAC7E,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC,CAAC,qEAAqE,CAAC,CAAC;IACjF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,EAAoC,EACpC,QAAgB;IAEhB,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IAC7D,IAAI,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IACnD,IAAI,GAAG,GAAwB,IAAI,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5F,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiB,CAAC;gBAC3C,IAAI,CAAC,CAAC,SAAS,KAAK,EAAE;oBAAE,GAAG,GAAG,CAAC,CAAC;YAClC,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,yDAAyD,CAAC,CAAC;IACrE,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;AAC9G,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,EAAoC;IAChF,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC"}
|