@neetru/cli 2.2.0 → 2.3.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.
@@ -1,19 +1,60 @@
1
1
  import * as readline from 'readline/promises';
2
2
  import chalk from 'chalk';
3
- import { chat } from '../lib/ai/orchestrator.js';
3
+ import { chat, chatParallel } from '../lib/ai/orchestrator.js';
4
+ import { discoveredKeys } from '../lib/ai/auth-discovery.js';
5
+ import { config } from '../lib/config.js';
4
6
  import { log } from '../utils/logger.js';
7
+ import { runAuthSetup } from './auth.js';
5
8
  const PROMPT_PREFIX = chalk.hex('#1E90FF').bold(' › ');
6
9
  const ASSISTANT_PREFIX = chalk.dim(' ◆ ');
10
+ // Help público — sem /modelo (orchestrator escolhe). /debug:model é o
11
+ // override avançado pra quem quer forçar.
7
12
  const HELP_TEXT = `
8
- Comandos especiais:
9
- /sair /exit encerrar sessão
10
- /limpar /clear limpar histórico de contexto
11
- /modelo <nome> trocar modelo (claude | openai | gemini | auto)
12
- /help mostrar este texto
13
+ Comandos:
14
+ /sair /exit encerrar sessão
15
+ /limpar /clear limpar histórico de contexto
16
+ /agentes <pergunta> consultar 2+ modelos em paralelo e comparar
17
+ /auth rodar wizard de configuração (claude/codex/gemini)
18
+ /help mostrar este texto
19
+ /debug:model <nome> forçar modelo (claude|openai|gemini|auto)
13
20
  `.trim();
21
+ /**
22
+ * Checa se o usuário tem pelo menos uma cred (local OU descoberta). Se zero,
23
+ * roda o setup wizard inline antes de abrir o REPL.
24
+ */
25
+ async function ensureAtLeastOneProvider() {
26
+ const local = {
27
+ anthropic: !!config.get('anthropicApiKey'),
28
+ openai: !!config.get('openaiApiKey'),
29
+ gemini: !!config.get('geminiApiKey'),
30
+ };
31
+ if (local.anthropic || local.openai || local.gemini)
32
+ return true;
33
+ const discovered = discoveredKeys();
34
+ if (discovered.anthropic || discovered.openai || discovered.gemini)
35
+ return true;
36
+ // Zero — força setup interativo.
37
+ log.warn('Nenhum provedor de IA configurado.');
38
+ log.info('Abrindo wizard de configuração...');
39
+ await runAuthSetup();
40
+ // Re-checa.
41
+ const after = !!config.get('anthropicApiKey') ||
42
+ !!config.get('openaiApiKey') ||
43
+ !!config.get('geminiApiKey') ||
44
+ !!discoveredKeys().anthropic ||
45
+ !!discoveredKeys().openai ||
46
+ !!discoveredKeys().gemini;
47
+ return after;
48
+ }
14
49
  export async function runAiRepl(opts = {}) {
15
50
  log.banner();
16
51
  log.info('Assistente Neetru — contexto da plataforma carregado.');
52
+ // Bloqueia antes do REPL se não tem cred nenhuma.
53
+ const ready = await ensureAtLeastOneProvider();
54
+ if (!ready) {
55
+ log.error('Sem credenciais configuradas. Saindo.');
56
+ process.exit(1);
57
+ }
17
58
  log.info('Digite /help para ver comandos. /sair para encerrar.');
18
59
  log.separator();
19
60
  console.log();
@@ -38,7 +79,7 @@ export async function runAiRepl(opts = {}) {
38
79
  }
39
80
  if (!input)
40
81
  continue;
41
- // Comandos internos
82
+ // ── Comandos internos ──────────────────────────────────────────
42
83
  if (input === '/sair' || input === '/exit') {
43
84
  log.dim('Encerrando sessão.');
44
85
  break;
@@ -52,17 +93,48 @@ export async function runAiRepl(opts = {}) {
52
93
  console.log(HELP_TEXT);
53
94
  continue;
54
95
  }
55
- if (input.startsWith('/modelo ') || input.startsWith('/model ')) {
96
+ if (input === '/auth') {
97
+ await runAuthSetup();
98
+ continue;
99
+ }
100
+ if (input.startsWith('/debug:model ')) {
56
101
  const m = input.split(' ')[1];
57
102
  if (['claude', 'openai', 'gemini', 'auto'].includes(m)) {
58
103
  currentModel = m;
59
- log.success(`Modelo alterado para: ${m}`);
104
+ log.success(`Modelo forçado: ${m}`);
60
105
  }
61
106
  else {
62
- log.warn('Modelos disponíveis: claude | openai | gemini | auto');
107
+ log.warn('Use: claude | openai | gemini | auto');
108
+ }
109
+ continue;
110
+ }
111
+ if (input.startsWith('/agentes ')) {
112
+ const question = input.slice('/agentes '.length).trim();
113
+ if (!question) {
114
+ log.warn('Use: /agentes <pergunta>');
115
+ continue;
116
+ }
117
+ console.log();
118
+ log.info('Consultando todos os provedores configurados em paralelo...');
119
+ try {
120
+ const results = await chatParallel(question, '');
121
+ for (const r of results) {
122
+ console.log(chalk.bold(`\n── ${r.model.toUpperCase()} ──`));
123
+ if (r.ok) {
124
+ console.log(r.response);
125
+ }
126
+ else {
127
+ console.log(chalk.red(`(erro) ${r.error}`));
128
+ }
129
+ }
130
+ console.log();
131
+ }
132
+ catch (err) {
133
+ log.error(err?.message ?? 'Erro ao executar chatParallel.');
63
134
  }
64
135
  continue;
65
136
  }
137
+ // ── Chat normal ────────────────────────────────────────────────
66
138
  history.push({ role: 'user', content: input });
67
139
  console.log();
68
140
  process.stdout.write(ASSISTANT_PREFIX);
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ interface CommonOpts {
2
+ json?: boolean;
3
+ }
4
+ /**
5
+ * `neetru auth status` — pura leitura, mostra tabela.
6
+ */
7
+ export declare function runAuthStatus(opts?: CommonOpts): Promise<void>;
8
+ /**
9
+ * `neetru auth pull` — sem perguntar, copia toda apiKey extraída dos CLIs
10
+ * concorrentes pra config do Neetru. Útil pra CI/script.
11
+ */
12
+ export declare function runAuthPull(opts?: CommonOpts): Promise<void>;
13
+ /**
14
+ * Wizard interativo: detecta → pergunta quais quer ativar → instala faltantes
15
+ * → guia login. Idempotente. Pode ser chamado direto pelo `neetru ai` quando
16
+ * detecta zero credenciais.
17
+ */
18
+ export declare function runAuthSetup(opts?: CommonOpts): Promise<void>;
19
+ export {};
@@ -0,0 +1,203 @@
1
+ /**
2
+ * `neetru auth` — gerencia credenciais dos provedores de IA usados pelo
3
+ * `neetru ai` (Anthropic, OpenAI, Gemini).
4
+ *
5
+ * Sub-comandos:
6
+ * neetru auth status → lista provedores detectados (binário + creds)
7
+ * neetru auth setup → wizard interativo: detecta, instala faltantes,
8
+ * guia login
9
+ * neetru auth pull → puxa creds dos CLIs concorrentes pra config do Neetru
10
+ *
11
+ * Objetivo: zerar fricção do "anthropicApiKey não configurada". Se user
12
+ * já tem Claude Code/Codex/Gemini, reaproveita.
13
+ */
14
+ import chalk from 'chalk';
15
+ import * as readline from 'readline/promises';
16
+ import { detectAllProviders, installGlobal, } from '../lib/ai/auth-discovery.js';
17
+ import { config } from '../lib/config.js';
18
+ import { log } from '../utils/logger.js';
19
+ const PROVIDER_TO_CONFIG = {
20
+ anthropic: 'anthropicApiKey',
21
+ openai: 'openaiApiKey',
22
+ gemini: 'geminiApiKey',
23
+ };
24
+ function badge(s) {
25
+ if (s.apiKey)
26
+ return chalk.green('✓ pronto');
27
+ if (s.installed && s.credentialSource)
28
+ return chalk.yellow('! login parcial');
29
+ if (s.installed)
30
+ return chalk.yellow('! sem creds');
31
+ return chalk.dim('- não instalado');
32
+ }
33
+ function rowName(p) {
34
+ switch (p) {
35
+ case 'anthropic':
36
+ return 'Claude (Anthropic)';
37
+ case 'openai':
38
+ return 'Codex (OpenAI)';
39
+ case 'gemini':
40
+ return 'Gemini (Google)';
41
+ }
42
+ }
43
+ /**
44
+ * `neetru auth status` — pura leitura, mostra tabela.
45
+ */
46
+ export async function runAuthStatus(opts = {}) {
47
+ const providers = detectAllProviders();
48
+ const configured = {
49
+ anthropic: !!config.get('anthropicApiKey'),
50
+ openai: !!config.get('openaiApiKey'),
51
+ gemini: !!config.get('geminiApiKey'),
52
+ };
53
+ if (opts.json) {
54
+ console.log(JSON.stringify({
55
+ providers: providers.map((p) => ({
56
+ ...p,
57
+ apiKey: p.apiKey ? '<redacted>' : undefined,
58
+ })),
59
+ configured,
60
+ }, null, 2));
61
+ return;
62
+ }
63
+ console.log(chalk.bold('\nNeetru Auth — status dos provedores de IA\n'));
64
+ for (const p of providers) {
65
+ const configuredHere = configured[p.provider] ? chalk.green('(neetru config OK)') : '';
66
+ console.log(` ${badge(p)} ${chalk.bold(rowName(p.provider))} ${configuredHere}`);
67
+ console.log(` ${chalk.dim(p.hint)}`);
68
+ }
69
+ console.log();
70
+ console.log(chalk.dim('Para configurar tudo de uma vez: neetru auth setup'));
71
+ }
72
+ /**
73
+ * `neetru auth pull` — sem perguntar, copia toda apiKey extraída dos CLIs
74
+ * concorrentes pra config do Neetru. Útil pra CI/script.
75
+ */
76
+ export async function runAuthPull(opts = {}) {
77
+ const providers = detectAllProviders();
78
+ const copied = [];
79
+ for (const p of providers) {
80
+ if (!p.apiKey)
81
+ continue;
82
+ const cfgKey = PROVIDER_TO_CONFIG[p.provider];
83
+ if (config.get(cfgKey))
84
+ continue; // não sobrescreve
85
+ config.set(cfgKey, p.apiKey);
86
+ copied.push(p.provider);
87
+ }
88
+ if (opts.json) {
89
+ console.log(JSON.stringify({ copied }, null, 2));
90
+ return;
91
+ }
92
+ if (copied.length === 0) {
93
+ log.info('Nenhuma cred nova para copiar (ou já estão configuradas).');
94
+ return;
95
+ }
96
+ log.success(`Copiadas ${copied.length} credenciais: ${copied.join(', ')}`);
97
+ }
98
+ /**
99
+ * Pergunta sim/não pro usuário via readline. Default = no.
100
+ */
101
+ async function confirm(rl, question, def = false) {
102
+ const hint = def ? '[S/n]' : '[s/N]';
103
+ const ans = (await rl.question(`${question} ${chalk.dim(hint)} `)).trim().toLowerCase();
104
+ if (!ans)
105
+ return def;
106
+ return ans === 's' || ans === 'sim' || ans === 'y' || ans === 'yes';
107
+ }
108
+ /**
109
+ * Wizard interativo: detecta → pergunta quais quer ativar → instala faltantes
110
+ * → guia login. Idempotente. Pode ser chamado direto pelo `neetru ai` quando
111
+ * detecta zero credenciais.
112
+ */
113
+ export async function runAuthSetup(opts = {}) {
114
+ const providers = detectAllProviders();
115
+ if (opts.json) {
116
+ // Modo não-interativo: só roda pull silencioso.
117
+ return runAuthPull(opts);
118
+ }
119
+ console.log(chalk.bold('\nNeetru Auth — wizard de configuração\n'));
120
+ console.log(chalk.dim('Detectado:\n'));
121
+ for (const p of providers) {
122
+ console.log(` ${badge(p)} ${rowName(p.provider)}`);
123
+ }
124
+ console.log();
125
+ // Pull silencioso de tudo que já tá pronto.
126
+ const autoConfigured = [];
127
+ for (const p of providers) {
128
+ if (!p.apiKey)
129
+ continue;
130
+ const cfgKey = PROVIDER_TO_CONFIG[p.provider];
131
+ if (!config.get(cfgKey)) {
132
+ config.set(cfgKey, p.apiKey);
133
+ autoConfigured.push(p.provider);
134
+ }
135
+ }
136
+ if (autoConfigured.length) {
137
+ log.success(`Reaproveitadas creds de: ${autoConfigured.join(', ')}`);
138
+ }
139
+ // Identifica provedores que precisam de ação (sem cred ou sem binário).
140
+ const needsAction = providers.filter((p) => !p.apiKey);
141
+ if (needsAction.length === 0) {
142
+ log.success('Todos os provedores prontos. Você pode rodar `neetru ai`.');
143
+ return;
144
+ }
145
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
146
+ try {
147
+ console.log(chalk.bold('\nProvedores que precisam de configuração:'));
148
+ const wanted = [];
149
+ for (const p of needsAction) {
150
+ const want = await confirm(rl, ` Configurar ${rowName(p.provider)}?`, false);
151
+ if (want)
152
+ wanted.push(p);
153
+ }
154
+ if (wanted.length === 0) {
155
+ log.dim('Nada para configurar. OK.');
156
+ return;
157
+ }
158
+ for (const p of wanted) {
159
+ console.log(chalk.bold(`\n→ ${rowName(p.provider)}`));
160
+ // Instalar binário se ausente.
161
+ if (!p.installed) {
162
+ const install = await confirm(rl, ` Instalar ${p.npmPackage} globalmente?`, true);
163
+ if (install) {
164
+ log.info(`Rodando: npm install -g ${p.npmPackage}`);
165
+ const ok = installGlobal(p.npmPackage);
166
+ if (!ok) {
167
+ log.error(`Falha ao instalar ${p.npmPackage}. Instale manualmente.`);
168
+ continue;
169
+ }
170
+ log.success(`${p.binary} instalado.`);
171
+ }
172
+ else {
173
+ log.dim('Pulado.');
174
+ continue;
175
+ }
176
+ }
177
+ else {
178
+ log.dim(` ${p.binary} já instalado.`);
179
+ }
180
+ // Pedir api key direto (mais simples que mandar usuário pro `claude /login`).
181
+ const provideKey = await confirm(rl, ` Colar API key agora? (alternativa: ${p.hint.replace(/^.*— /, '')})`, true);
182
+ if (provideKey) {
183
+ const key = (await rl.question(` Cole a API key: `)).trim();
184
+ if (key) {
185
+ config.set(PROVIDER_TO_CONFIG[p.provider], key);
186
+ log.success(`${rowName(p.provider)} configurado.`);
187
+ }
188
+ else {
189
+ log.warn('Vazio — não configurado.');
190
+ }
191
+ }
192
+ else {
193
+ log.dim(`Use o login do ${p.binary} ou rode "neetru auth pull" depois pra puxar.`);
194
+ }
195
+ }
196
+ console.log();
197
+ log.success('Wizard finalizado. Rode `neetru ai` pra testar.');
198
+ }
199
+ finally {
200
+ rl.close();
201
+ }
202
+ }
203
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,aAAa,GAGd,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAMzC,MAAM,kBAAkB,GAA0E;IAChG,SAAS,EAAE,iBAAiB;IAC5B,MAAM,EAAE,cAAc;IACtB,MAAM,EAAE,cAAc;CACvB,CAAC;AAEF,SAAS,KAAK,CAAC,CAAiB;IAC9B,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,gBAAgB;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC9E,IAAI,CAAC,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,OAAO,CAAC,CAAW;IAC1B,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,WAAW;YACd,OAAO,oBAAoB,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,gBAAgB,CAAC;QAC1B,KAAK,QAAQ;YACX,OAAO,iBAAiB,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAmB,EAAE;IACvD,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,UAAU,GAAG;QACjB,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;QACpC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;KACrC,CAAC;IAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;YACE,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/B,GAAG,CAAC;gBACJ,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;aAC5C,CAAC,CAAC;YACH,UAAU;SACX,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,CAAC;IACzE,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,cAAc,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,cAAc,EAAE,CAAC,CAAC;QACpF,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAmB,EAAE;IACrD,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,MAAM,GAAe,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,CAAC,MAAM;YAAE,SAAS;QACxB,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,SAAS,CAAC,kBAAkB;QACpD,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IACD,GAAG,CAAC,OAAO,CAAC,YAAY,MAAM,CAAC,MAAM,iBAAiB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CAAC,EAAsB,EAAE,QAAgB,EAAE,GAAG,GAAG,KAAK;IAC1E,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACrC,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxF,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAC;IACrB,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,KAAK,CAAC;AACtE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAmB,EAAE;IACtD,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IAEvC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,gDAAgD;QAChD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,4CAA4C;IAC5C,MAAM,cAAc,GAAe,EAAE,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,CAAC,MAAM;YAAE,SAAS;QACxB,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YAC7B,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,OAAO,CAAC,4BAA4B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,wEAAwE;IACxE,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,GAAG,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtF,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC,CAAC;QACtE,MAAM,MAAM,GAAqB,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,gBAAgB,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9E,IAAI,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;YAEtD,+BAA+B;YAC/B,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;gBACjB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,UAAU,eAAe,EAAE,IAAI,CAAC,CAAC;gBACnF,IAAI,OAAO,EAAE,CAAC;oBACZ,GAAG,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;oBACpD,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;oBACvC,IAAI,CAAC,EAAE,EAAE,CAAC;wBACR,GAAG,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,UAAU,wBAAwB,CAAC,CAAC;wBACrE,SAAS;oBACX,CAAC;oBACD,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC;gBACxC,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;oBACnB,SAAS;gBACX,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,gBAAgB,CAAC,CAAC;YACzC,CAAC;YAED,8EAA8E;YAC9E,MAAM,UAAU,GAAG,MAAM,OAAO,CAC9B,EAAE,EACF,wCAAwC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EACtE,IAAI,CACL,CAAC;YACF,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC7D,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;oBAChD,GAAG,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;gBACrD,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,MAAM,+CAA+C,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC;IACjE,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}