expxdev 0.5.0 → 0.5.2
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/cli/autonomo.d.ts +21 -0
- package/dist/cli/autonomo.js +37 -0
- package/dist/cli/autonomo.js.map +1 -0
- package/dist/cli/expx.js +4 -0
- package/dist/cli/expx.js.map +1 -1
- package/dist/cli/init.js +39 -5
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/principal.js +10 -5
- package/dist/cli/principal.js.map +1 -1
- package/dist/cli/subcomandos.d.ts +3 -0
- package/dist/cli/subcomandos.js +6 -0
- package/dist/cli/subcomandos.js.map +1 -1
- package/dist/harness/hooks.d.ts +9 -4
- package/dist/harness/hooks.js +34 -3
- package/dist/harness/hooks.js.map +1 -1
- package/dist/harness/instalar.d.ts +19 -0
- package/dist/harness/instalar.js +42 -1
- package/dist/harness/instalar.js.map +1 -1
- package/dist/harness/settings.js +6 -0
- package/dist/harness/settings.js.map +1 -1
- package/dist/nucleo/busca.d.ts +8 -0
- package/dist/nucleo/busca.js +27 -2
- package/dist/nucleo/busca.js.map +1 -1
- package/dist/nucleo/catalogo.d.ts +7 -1
- package/dist/nucleo/catalogo.js +73 -9
- package/dist/nucleo/catalogo.js.map +1 -1
- package/dist/nucleo/layout.d.ts +8 -0
- package/dist/nucleo/layout.js +22 -0
- package/dist/nucleo/layout.js.map +1 -1
- package/dist/parser/descoberta/trabalhos.d.ts +14 -2
- package/dist/parser/descoberta/trabalhos.js +59 -0
- package/dist/parser/descoberta/trabalhos.js.map +1 -1
- package/dist/parser/esquema/cabecalho.d.ts +21 -5
- package/dist/parser/esquema/cabecalho.js +24 -5
- package/dist/parser/esquema/cabecalho.js.map +1 -1
- package/dist/parser/esquema/enums.d.ts +41 -4
- package/dist/parser/esquema/enums.js +39 -9
- package/dist/parser/esquema/enums.js.map +1 -1
- package/dist/parser/esquema/evento.d.ts +1 -0
- package/dist/parser/esquema/kinds.d.ts +288 -0
- package/dist/parser/esquema/kinds.js +84 -1
- package/dist/parser/esquema/kinds.js.map +1 -1
- package/dist/plugin/montagem.d.ts +5 -0
- package/dist/plugin/montagem.js +67 -1
- package/dist/plugin/montagem.js.map +1 -1
- package/dist/servidor/http.d.ts +5 -0
- package/dist/servidor/http.js +28 -0
- package/dist/servidor/http.js.map +1 -1
- package/dist/servidor/observador.d.ts +27 -1
- package/dist/servidor/observador.js +152 -19
- package/dist/servidor/observador.js.map +1 -1
- package/dist/servidor/painel.js +13 -3
- package/dist/servidor/painel.js.map +1 -1
- package/dist/update/comparar.js +2 -2
- package/dist/update/comparar.js.map +1 -1
- package/dist/watch/desenho/barra.d.ts +29 -0
- package/dist/watch/desenho/barra.js +111 -0
- package/dist/watch/desenho/barra.js.map +1 -0
- package/dist/watch/desenho/desenhar.d.ts +15 -2
- package/dist/watch/desenho/desenhar.js +65 -11
- package/dist/watch/desenho/desenhar.js.map +1 -1
- package/dist/watch/desenho/painel.d.ts +14 -0
- package/dist/watch/desenho/painel.js +260 -0
- package/dist/watch/desenho/painel.js.map +1 -0
- package/dist/watch/fontes/estado-schema.d.ts +7 -0
- package/dist/watch/opcoes.d.ts +2 -0
- package/dist/watch/opcoes.js +11 -4
- package/dist/watch/opcoes.js.map +1 -1
- package/dist/watch/terminal/tela.d.ts +15 -12
- package/dist/watch/terminal/tela.js +79 -3
- package/dist/watch/terminal/tela.js.map +1 -1
- package/dist/watch/visao/atividade.d.ts +70 -0
- package/dist/watch/visao/atividade.js +0 -0
- package/dist/watch/visao/atividade.js.map +1 -0
- package/dist/watch/visao/frota.d.ts +46 -0
- package/dist/watch/visao/frota.js +67 -0
- package/dist/watch/visao/frota.js.map +1 -0
- package/dist/watch/visao/projetar.d.ts +9 -0
- package/dist/watch/visao/projetar.js +55 -0
- package/dist/watch/visao/projetar.js.map +1 -1
- package/dist/watch/watch.d.ts +2 -0
- package/dist/watch/watch.js +48 -3
- package/dist/watch/watch.js.map +1 -1
- package/nucleo/hooks/expx-lembrete.sh +136 -0
- package/package.json +1 -1
package/dist/watch/opcoes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opcoes.js","sourceRoot":"","sources":["../../src/watch/opcoes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"opcoes.js","sourceRoot":"","sources":["../../src/watch/opcoes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A tela: redesenho incremental, sem piscar.
|
|
3
|
-
*
|
|
4
|
-
* "Redesenho não pode piscar a tela inteira." Limpar tudo e reimprimir produz
|
|
5
|
-
* exatamente o piscar que a especificação proíbe, e o buffer alternativo do
|
|
6
|
-
* terminal foi descartado por apagar o que estava na tela quando o watch sai
|
|
7
|
-
* (decisão D-20).
|
|
8
|
-
*
|
|
9
|
-
* A técnica: guardamos as linhas do último desenho, comparamos com as novas e
|
|
10
|
-
* reescrevemos SÓ as que mudaram, movendo o cursor até cada uma.
|
|
11
|
-
*/
|
|
12
1
|
export type Tela = {
|
|
13
2
|
desenhar: (linhas: readonly string[]) => void;
|
|
14
3
|
/** Quantas linhas a tela ocupa agora — para quem precisa arrumar o cursor. */
|
|
15
4
|
altura: () => number;
|
|
16
5
|
};
|
|
17
|
-
export
|
|
6
|
+
export type LimitesTela = {
|
|
7
|
+
/** Largura do terminal, em colunas. */
|
|
8
|
+
colunas: number;
|
|
9
|
+
/** Altura do terminal, em linhas. */
|
|
10
|
+
linhas: number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Corta o texto por COLUNA sem partir escape ANSI no meio.
|
|
14
|
+
*
|
|
15
|
+
* As linhas chegam aqui já pintadas, e um `[32m` não ocupa coluna
|
|
16
|
+
* nenhuma: medir o texto pintado daria largura errada, e cortar às cegas
|
|
17
|
+
* partiria o escape ao meio, despejando `[32m` como texto na tela.
|
|
18
|
+
*/
|
|
19
|
+
export declare function cortarComAnsi(texto: string, colunas: number): string;
|
|
20
|
+
export declare function criarTela(escrever: (texto: string) => void, limites?: () => LimitesTela): Tela;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { largura } from "../desenho/largura.js";
|
|
1
2
|
/**
|
|
2
3
|
* A tela: redesenho incremental, sem piscar.
|
|
3
4
|
*
|
|
@@ -8,6 +9,20 @@
|
|
|
8
9
|
*
|
|
9
10
|
* A técnica: guardamos as linhas do último desenho, comparamos com as novas e
|
|
10
11
|
* reescrevemos SÓ as que mudaram, movendo o cursor até cada uma.
|
|
12
|
+
*
|
|
13
|
+
* DUAS invariantes sustentam essa aritmética de cursor. Quebrar qualquer uma
|
|
14
|
+
* delas embaralha a tela em vez de redesenhá-la:
|
|
15
|
+
*
|
|
16
|
+
* 1. UMA linha desenhada ocupa UMA linha física. Se o texto passar da largura
|
|
17
|
+
* do terminal, ele quebra sozinho, o bloco fica mais alto do que as linhas
|
|
18
|
+
* que contamos, e todo movimento de cursor seguinte erra o alvo — foi o
|
|
19
|
+
* que produziu o rastro sobrescrevendo a árvore no meio da tela. Por isso
|
|
20
|
+
* a tela CORTA na largura recebida, como último guarda, e corta em
|
|
21
|
+
* `colunas - 1`: escrever na última coluna deixa muitos terminais em
|
|
22
|
+
* "pending wrap", e o caractere seguinte pula de linha sem aviso.
|
|
23
|
+
* 2. O bloco cabe na altura do terminal. Se não couber, o terminal rola, as
|
|
24
|
+
* linhas de cima saem da vista e o cursor não tem como voltar até elas.
|
|
25
|
+
* Por isso o bloco é truncado na altura disponível.
|
|
11
26
|
*/
|
|
12
27
|
const ESC = "";
|
|
13
28
|
/** Move o cursor N linhas para cima. */
|
|
@@ -18,7 +33,44 @@ const desce = (n) => (n > 0 ? `${ESC}[${String(n)}B` : "");
|
|
|
18
33
|
const COLUNA_1 = `${ESC}[G`;
|
|
19
34
|
/** Apaga da posição do cursor até o fim da linha. */
|
|
20
35
|
const LIMPA_LINHA = `${ESC}[K`;
|
|
21
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Corta o texto por COLUNA sem partir escape ANSI no meio.
|
|
38
|
+
*
|
|
39
|
+
* As linhas chegam aqui já pintadas, e um `[32m` não ocupa coluna
|
|
40
|
+
* nenhuma: medir o texto pintado daria largura errada, e cortar às cegas
|
|
41
|
+
* partiria o escape ao meio, despejando `[32m` como texto na tela.
|
|
42
|
+
*/
|
|
43
|
+
export function cortarComAnsi(texto, colunas) {
|
|
44
|
+
if (colunas <= 0)
|
|
45
|
+
return "";
|
|
46
|
+
const partes = texto.split(/(\[[0-9;]*m)/);
|
|
47
|
+
let usadas = 0;
|
|
48
|
+
let saida = "";
|
|
49
|
+
let cortou = false;
|
|
50
|
+
for (const parte of partes) {
|
|
51
|
+
if (parte === "")
|
|
52
|
+
continue;
|
|
53
|
+
// escape: passa inteiro e não conta coluna
|
|
54
|
+
if (parte.startsWith(`${ESC}[`)) {
|
|
55
|
+
saida += parte;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (cortou)
|
|
59
|
+
continue;
|
|
60
|
+
const pontos = [...parte.normalize("NFC")];
|
|
61
|
+
if (usadas + pontos.length <= colunas) {
|
|
62
|
+
saida += pontos.join("");
|
|
63
|
+
usadas += pontos.length;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
// -1 para a reticência, que também ocupa uma coluna
|
|
67
|
+
saida += pontos.slice(0, Math.max(0, colunas - usadas - 1)).join("") + "…";
|
|
68
|
+
usadas = colunas;
|
|
69
|
+
cortou = true;
|
|
70
|
+
}
|
|
71
|
+
return saida;
|
|
72
|
+
}
|
|
73
|
+
export function criarTela(escrever, limites) {
|
|
22
74
|
let anteriores = [];
|
|
23
75
|
// Onde o cursor está, contando do topo do bloco desenhado.
|
|
24
76
|
let cursor = 0;
|
|
@@ -27,10 +79,34 @@ export function criarTela(escrever) {
|
|
|
27
79
|
cursor = linha;
|
|
28
80
|
return delta > 0 ? desce(delta) : sobe(-delta);
|
|
29
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Impõe as duas invariantes: nada mais largo que o terminal, nada mais alto.
|
|
84
|
+
*
|
|
85
|
+
* Sem `limites` — o caso dos testes de unidade da tela — não há terminal a
|
|
86
|
+
* respeitar e as linhas passam como estão.
|
|
87
|
+
*/
|
|
88
|
+
function ajustar(linhas) {
|
|
89
|
+
if (limites === undefined)
|
|
90
|
+
return [...linhas];
|
|
91
|
+
const { colunas, linhas: altura } = limites();
|
|
92
|
+
const largo = colunas > 1 ? colunas - 1 : 1;
|
|
93
|
+
const cortadas = linhas.map((l) => (largura(l) > largo ? cortarComAnsi(l, largo) : l));
|
|
94
|
+
// -1 na altura: a linha onde o cursor descansa depois do bloco.
|
|
95
|
+
const alto = Math.max(1, altura - 1);
|
|
96
|
+
if (cortadas.length <= alto)
|
|
97
|
+
return cortadas;
|
|
98
|
+
// Não cabe: mostramos o começo e dizemos quantas linhas ficaram de fora,
|
|
99
|
+
// em vez de rolar a tela e perder o controle do cursor.
|
|
100
|
+
const sobraram = cortadas.length - alto + 1;
|
|
101
|
+
return [
|
|
102
|
+
...cortadas.slice(0, alto - 1),
|
|
103
|
+
cortarComAnsi(` … mais ${String(sobraram)} linhas (aumente a janela)`, largo),
|
|
104
|
+
];
|
|
105
|
+
}
|
|
30
106
|
return {
|
|
31
107
|
altura: () => anteriores.length,
|
|
32
|
-
desenhar(
|
|
33
|
-
const novas =
|
|
108
|
+
desenhar(entrada) {
|
|
109
|
+
const novas = ajustar(entrada);
|
|
34
110
|
const partes = [];
|
|
35
111
|
const alturaAnterior = anteriores.length;
|
|
36
112
|
const total = Math.max(novas.length, alturaAnterior);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tela.js","sourceRoot":"","sources":["../../../src/watch/terminal/tela.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tela.js","sourceRoot":"","sources":["../../../src/watch/terminal/tela.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { LinhaEvento } from "../../parser/esquema/evento.js";
|
|
2
|
+
/**
|
|
3
|
+
* O rastro cru virando informação: eventos agrupados e progresso estimado.
|
|
4
|
+
*
|
|
5
|
+
* O rastro é append-only e cada hook grava uma linha. Numa execução autônoma
|
|
6
|
+
* isso produz dezenas de `suite_executada` iguais, e a tela dos "eventos
|
|
7
|
+
* recentes" vira um dump onde as dez linhas visíveis são todas o mesmo
|
|
8
|
+
* comando repetido — o que aconteceu de verdade some no ruído. Agrupar é o
|
|
9
|
+
* que devolve a informação: "suíte executada ×7, última às 15:54".
|
|
10
|
+
*/
|
|
11
|
+
export type GrupoAtividade = {
|
|
12
|
+
evento: LinhaEvento["evento"];
|
|
13
|
+
/** Quantas linhas do rastro este grupo resume. */
|
|
14
|
+
vezes: number;
|
|
15
|
+
/** O `ts` da mais recente do grupo. */
|
|
16
|
+
ts: string;
|
|
17
|
+
/** A task (ou fase) do evento mais recente do grupo. */
|
|
18
|
+
alvo: string;
|
|
19
|
+
/** O resultado do evento mais recente — `ok`, `verde`, `vermelha`… */
|
|
20
|
+
resultado: string;
|
|
21
|
+
/** Detalhe do mais recente, já sem comando de shell. */
|
|
22
|
+
detalhe: string;
|
|
23
|
+
/** O evento MAIS RECENTE do grupo falhou? É o que dita o sinal da linha. */
|
|
24
|
+
houveFalha: boolean;
|
|
25
|
+
/** Quantos do grupo falharam — para dizer "×12, 8 sem resultado". */
|
|
26
|
+
falhas: number;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Detalhe legível: comando de shell não é informação numa tela de
|
|
30
|
+
* acompanhamento.
|
|
31
|
+
*
|
|
32
|
+
* O que aparecia era `suite nao_determinado: cd /Users/thulio/... && npx
|
|
33
|
+
* vitest run ...` ocupando a linha inteira e sendo cortado antes de dizer
|
|
34
|
+
* qualquer coisa. O que importa é o resultado, não a linha de comando.
|
|
35
|
+
*/
|
|
36
|
+
export declare function limparDetalhe(detalhe: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Agrupa eventos consecutivos-por-tipo, do mais recente para o mais antigo.
|
|
39
|
+
*
|
|
40
|
+
* O agrupamento é por (evento, alvo): dez `suite_executada` da mesma task
|
|
41
|
+
* viram uma linha, mas a suíte de OUTRA task continua sendo outra linha —
|
|
42
|
+
* senão o agrupamento esconderia justamente o paralelismo que a pessoa quer
|
|
43
|
+
* enxergar.
|
|
44
|
+
*
|
|
45
|
+
* `eventos` chega do mais recente para o mais antigo (`lerRastro` já inverte).
|
|
46
|
+
*/
|
|
47
|
+
export declare function agrupar(eventos: readonly LinhaEvento[], limite?: number): GrupoAtividade[];
|
|
48
|
+
export type ProgressoTask = {
|
|
49
|
+
/** Quando a task começou, do evento `task_iniciada`. */
|
|
50
|
+
iniciadaEm: Date | null;
|
|
51
|
+
/** Fração 0..1 ESTIMADA a partir do rastro. Nunca é medida real. */
|
|
52
|
+
fracao: number;
|
|
53
|
+
/** Quantos sinais de trabalho o rastro registrou para esta task. */
|
|
54
|
+
sinais: number;
|
|
55
|
+
/** A suíte desta task já rodou verde? */
|
|
56
|
+
suiteVerde: boolean;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Progresso ESTIMADO de uma task em andamento.
|
|
60
|
+
*
|
|
61
|
+
* O método não mede percentual dentro de uma task: o status é pendente, em
|
|
62
|
+
* andamento, concluída ou bloqueada. Então este número não é medição, é
|
|
63
|
+
* leitura de sinais do rastro — e quem desenha rotula como estimativa.
|
|
64
|
+
*
|
|
65
|
+
* O modelo é o ciclo TDD que o método impõe a toda task: teste escrito
|
|
66
|
+
* (suíte vermelha) → implementação (arquivo alterado) → suíte verde → task
|
|
67
|
+
* concluída. Cada marco desses avança a estimativa, e ela satura em 90%:
|
|
68
|
+
* 100% é só o `task_concluida`, que muda o status de verdade.
|
|
69
|
+
*/
|
|
70
|
+
export declare function progressoDaTask(eventos: readonly LinhaEvento[], taskId: string): ProgressoTask;
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atividade.js","sourceRoot":"","sources":["../../../src/watch/visao/atividade.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { TrabalhoMontado } from "../../parser/projeto/montar.js";
|
|
2
|
+
import type { LinhaEvento } from "../../parser/esquema/evento.js";
|
|
3
|
+
import type { EstadoExpx } from "../fontes/estado-schema.js";
|
|
4
|
+
import { type ProgressoTask } from "./atividade.js";
|
|
5
|
+
/**
|
|
6
|
+
* A frota: cada trabalho aberto com o que a tela precisa mostrar dele.
|
|
7
|
+
*
|
|
8
|
+
* O watch antigo seguia UM trabalho e resumia os outros a nada. Numa execução
|
|
9
|
+
* de verdade há várias ocorrências andando ao mesmo tempo — e5 fechando, e3
|
|
10
|
+
* executando, e2 planejando — e a tela precisava dizer, de relance, onde cada
|
|
11
|
+
* uma está. É a diferença entre um log e um painel.
|
|
12
|
+
*/
|
|
13
|
+
export type TaskAtiva = {
|
|
14
|
+
id: string;
|
|
15
|
+
titulo: string;
|
|
16
|
+
/** A fase que a contém, para dizer quem roda em paralelo com quem. */
|
|
17
|
+
faseId: string;
|
|
18
|
+
/** A fase declarou rodar em paralelo com estas outras. */
|
|
19
|
+
paralelaCom: string[];
|
|
20
|
+
/** A task pode rodar em paralelo com as irmãs da mesma fase. */
|
|
21
|
+
paralelizavel: boolean;
|
|
22
|
+
/** Tasks das quais esta depende. */
|
|
23
|
+
dependeDe: string[];
|
|
24
|
+
bloqueada: boolean;
|
|
25
|
+
progresso: ProgressoTask;
|
|
26
|
+
};
|
|
27
|
+
export type TrabalhoNaFrota = {
|
|
28
|
+
trabalho: TrabalhoMontado;
|
|
29
|
+
/** Este é o trabalho que o `estado.json` aponta como corrente? */
|
|
30
|
+
corrente: boolean;
|
|
31
|
+
concluidas: number;
|
|
32
|
+
total: number;
|
|
33
|
+
/** O estágio do método: `e3`, `f6`… Do estado quando é o corrente. */
|
|
34
|
+
estagio: string;
|
|
35
|
+
/** As tasks em andamento AGORA. Mais de uma significa paralelismo real. */
|
|
36
|
+
ativas: TaskAtiva[];
|
|
37
|
+
bloqueiosAbertos: number;
|
|
38
|
+
/** O `ts` do evento mais recente deste trabalho, ou `null`. */
|
|
39
|
+
ultimoEventoTs: string | null;
|
|
40
|
+
/** Os eventos deste trabalho, para a coluna de atividade. */
|
|
41
|
+
eventos: LinhaEvento[];
|
|
42
|
+
};
|
|
43
|
+
/** As tasks em andamento de um trabalho, com sua fase e seu paralelismo. */
|
|
44
|
+
export declare function tasksAtivas(t: TrabalhoMontado, eventos: readonly LinhaEvento[]): TaskAtiva[];
|
|
45
|
+
/** Monta a linha de frota de um trabalho. */
|
|
46
|
+
export declare function montarNaFrota(t: TrabalhoMontado, eventos: readonly LinhaEvento[], estado: EstadoExpx | null, corrente: boolean): TrabalhoNaFrota;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { progressoDaTask } from "./atividade.js";
|
|
2
|
+
/** As tasks em andamento de um trabalho, com sua fase e seu paralelismo. */
|
|
3
|
+
export function tasksAtivas(t, eventos) {
|
|
4
|
+
const ativas = [];
|
|
5
|
+
for (const sprint of t.sprints) {
|
|
6
|
+
for (const fase of sprint.fases) {
|
|
7
|
+
for (const task of fase.tasks) {
|
|
8
|
+
if (task.status !== "em_andamento" && task.status !== "bloqueada")
|
|
9
|
+
continue;
|
|
10
|
+
ativas.push({
|
|
11
|
+
id: task.id,
|
|
12
|
+
titulo: task.titulo,
|
|
13
|
+
faseId: fase.id,
|
|
14
|
+
paralelaCom: fase.paralela_com,
|
|
15
|
+
paralelizavel: task.paralelizavel,
|
|
16
|
+
dependeDe: task.depende_de,
|
|
17
|
+
bloqueada: task.status === "bloqueada",
|
|
18
|
+
progresso: progressoDaTask(eventos, task.id),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Tasks cujo arquivo de fases não referencia continuam existindo: o vínculo
|
|
23
|
+
// autoritativo é o campo `fase` da task.
|
|
24
|
+
const nasFases = new Set(sprint.fases.flatMap((f) => f.tasks.map((x) => x.id)));
|
|
25
|
+
for (const task of sprint.tasks) {
|
|
26
|
+
if (nasFases.has(task.id))
|
|
27
|
+
continue;
|
|
28
|
+
if (task.status !== "em_andamento" && task.status !== "bloqueada")
|
|
29
|
+
continue;
|
|
30
|
+
ativas.push({
|
|
31
|
+
id: task.id,
|
|
32
|
+
titulo: task.titulo,
|
|
33
|
+
faseId: task.fase ?? "",
|
|
34
|
+
paralelaCom: [],
|
|
35
|
+
paralelizavel: task.paralelizavel,
|
|
36
|
+
dependeDe: task.depende_de,
|
|
37
|
+
bloqueada: task.status === "bloqueada",
|
|
38
|
+
progresso: progressoDaTask(eventos, task.id),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return ativas;
|
|
43
|
+
}
|
|
44
|
+
/** Monta a linha de frota de um trabalho. */
|
|
45
|
+
export function montarNaFrota(t, eventos, estado, corrente) {
|
|
46
|
+
const tasks = t.sprints.flatMap((s) => s.tasks);
|
|
47
|
+
// O par concluídas/total vem do estado.json SÓ para o trabalho corrente: o
|
|
48
|
+
// estado descreve um trabalho, e aplicar os inteiros dele aos outros mostraria
|
|
49
|
+
// o progresso de um no lugar do outro.
|
|
50
|
+
const doEstado = corrente && estado !== null;
|
|
51
|
+
const concluidas = doEstado
|
|
52
|
+
? estado.tasks_concluidas
|
|
53
|
+
: tasks.filter((x) => x.status === "concluida").length;
|
|
54
|
+
const total = doEstado ? estado.tasks_total : tasks.length;
|
|
55
|
+
return {
|
|
56
|
+
trabalho: t,
|
|
57
|
+
corrente,
|
|
58
|
+
concluidas,
|
|
59
|
+
total,
|
|
60
|
+
estagio: (doEstado ? estado.fase : null) ?? t.estagio,
|
|
61
|
+
ativas: tasksAtivas(t, eventos),
|
|
62
|
+
bloqueiosAbertos: t.bloqueios.filter((b) => b.aberto).length,
|
|
63
|
+
ultimoEventoTs: eventos[0]?.ts ?? null,
|
|
64
|
+
eventos: [...eventos],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=frota.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frota.js","sourceRoot":"","sources":["../../../src/watch/visao/frota.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAsB,MAAM,gBAAgB,CAAC;AA2CrE,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CACzB,CAAkB,EAClB,OAA+B;IAE/B,MAAM,MAAM,GAAgB,EAAE,CAAC;IAE/B,KAAK,MAAM,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,cAAc,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW;oBAAE,SAAS;gBAC5E,MAAM,CAAC,IAAI,CAAC;oBACV,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,WAAW,EAAE,IAAI,CAAC,YAAY;oBAC9B,aAAa,EAAE,IAAI,CAAC,aAAa;oBACjC,SAAS,EAAE,IAAI,CAAC,UAAU;oBAC1B,SAAS,EAAE,IAAI,CAAC,MAAM,KAAK,WAAW;oBACtC,SAAS,EAAE,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;iBAC7C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,4EAA4E;QAC5E,yCAAyC;QACzC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAChF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAE,SAAS;YACpC,IAAI,IAAI,CAAC,MAAM,KAAK,cAAc,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW;gBAAE,SAAS;YAC5E,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;gBACvB,WAAW,EAAE,EAAE;gBACf,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,SAAS,EAAE,IAAI,CAAC,UAAU;gBAC1B,SAAS,EAAE,IAAI,CAAC,MAAM,KAAK,WAAW;gBACtC,SAAS,EAAE,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;aAC7C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,aAAa,CAC3B,CAAkB,EAClB,OAA+B,EAC/B,MAAyB,EACzB,QAAiB;IAEjB,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAEhD,2EAA2E;IAC3E,+EAA+E;IAC/E,uCAAuC;IACvC,MAAM,QAAQ,GAAG,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;IAC7C,MAAM,UAAU,GAAG,QAAQ;QACzB,CAAC,CAAC,MAAM,CAAC,gBAAgB;QACzB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACzD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IAE3D,OAAO;QACL,QAAQ,EAAE,CAAC;QACX,QAAQ;QACR,UAAU;QACV,KAAK;QACL,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO;QACrD,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC;QAC/B,gBAAgB,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM;QAC5D,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI;QACtC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC;KACtB,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type BloqueioSituado, type TrabalhoMontado } from "../../parser/projeto/montar.js";
|
|
2
2
|
import type { LinhaEvento } from "../../parser/esquema/evento.js";
|
|
3
3
|
import type { EstadoExpx } from "../fontes/estado-schema.js";
|
|
4
|
+
import { type TrabalhoNaFrota } from "./frota.js";
|
|
4
5
|
/**
|
|
5
6
|
* A visão que o desenho consome — as três fontes reunidas numa estrutura só.
|
|
6
7
|
*
|
|
@@ -34,6 +35,14 @@ export type Visao = {
|
|
|
34
35
|
eventos: LinhaEvento[];
|
|
35
36
|
/** Violações em modo aviso desde que o watch subiu (decisão D-07). */
|
|
36
37
|
violacoesAviso: number;
|
|
38
|
+
/**
|
|
39
|
+
* Os trabalhos abertos com o que o painel mostra de cada um: progresso,
|
|
40
|
+
* estágio, tasks ativas e último evento.
|
|
41
|
+
*
|
|
42
|
+
* O trabalho corrente vem primeiro; os demais seguem por atividade mais
|
|
43
|
+
* recente, que é a ordem em que a pessoa quer varrer a tela.
|
|
44
|
+
*/
|
|
45
|
+
frota: TrabalhoNaFrota[];
|
|
37
46
|
/** Instante da leitura, para o rodapé calcular "tempo desde o último evento". */
|
|
38
47
|
lidoEm: Date;
|
|
39
48
|
};
|
|
@@ -2,6 +2,25 @@ import { montarProjeto } from "../../parser/projeto/montar.js";
|
|
|
2
2
|
import { lerEstadoExpx } from "../fontes/estado.js";
|
|
3
3
|
import { lerRastro } from "../fontes/rastro.js";
|
|
4
4
|
import { abertos, escolherTrabalho } from "./escolher.js";
|
|
5
|
+
import { montarNaFrota } from "./frota.js";
|
|
6
|
+
/**
|
|
7
|
+
* Quantas linhas do rastro a estimativa de progresso enxerga.
|
|
8
|
+
*
|
|
9
|
+
* Bem mais que as dez da tela: a estimativa procura marcos (`task_iniciada`,
|
|
10
|
+
* `arquivo_alterado`, suíte verde) que uma execução ruidosa empurra para longe
|
|
11
|
+
* do fim do arquivo. Continua sendo leitura de cauda, não varredura.
|
|
12
|
+
*/
|
|
13
|
+
const FUNDO_DA_ESTIMATIVA = 200;
|
|
14
|
+
/** Por quantos dias um trabalho concluído continua visível na frota. */
|
|
15
|
+
const DIAS_NA_FROTA = 2;
|
|
16
|
+
/** O trabalho fechou nos últimos dias? `atualizado_em` é `AAAA-MM-DD`. */
|
|
17
|
+
function recemFechado(atualizadoEm, agora) {
|
|
18
|
+
const q = Date.parse(`${atualizadoEm}T00:00:00Z`);
|
|
19
|
+
if (Number.isNaN(q))
|
|
20
|
+
return false;
|
|
21
|
+
const hoje = Date.UTC(agora.getUTCFullYear(), agora.getUTCMonth(), agora.getUTCDate());
|
|
22
|
+
return (hoje - q) / 86_400_000 <= DIAS_NA_FROTA;
|
|
23
|
+
}
|
|
5
24
|
export function projetarVisao(raizProjeto, op = {}, agora = new Date()) {
|
|
6
25
|
const projeto = montarProjeto(raizProjeto, agora);
|
|
7
26
|
const estado = lerEstadoExpx(raizProjeto);
|
|
@@ -16,6 +35,41 @@ export function projetarVisao(raizProjeto, op = {}, agora = new Date()) {
|
|
|
16
35
|
: tasks.filter((t) => t.status === "concluida").length;
|
|
17
36
|
const total = doEstado ? estado.tasks_total : tasks.length;
|
|
18
37
|
const eventos = trabalho === null ? [] : lerRastro(raizProjeto, trabalho.trabalho_id, op.linhasRastro);
|
|
38
|
+
// A frota lê o rastro de CADA trabalho, não só o do corrente: é o que permite
|
|
39
|
+
// dizer "e3 rodando, e2 parado há 40 min" numa tela só. É leitura de cauda
|
|
40
|
+
// (as últimas linhas de cada arquivo), não varredura — o custo cresce com o
|
|
41
|
+
// número de trabalhos abertos, que é unidade, não milhar.
|
|
42
|
+
//
|
|
43
|
+
// Entram os abertos MAIS os concluídos recentemente: um trabalho que fecha some da
|
|
44
|
+
// tela no meio de uma sessão de acompanhamento, e quem estava olhando fica
|
|
45
|
+
// sem saber se acabou ou se quebrou. Ele fica, marcado como concluído.
|
|
46
|
+
const emFrota = [
|
|
47
|
+
...abertos(projeto.trabalhos),
|
|
48
|
+
...projeto.trabalhos.filter((t) => t.status === "concluido" && recemFechado(t.atualizado_em, agora)),
|
|
49
|
+
];
|
|
50
|
+
// O trabalho corrente entra mesmo se estiver concluído: quem abriu o watch
|
|
51
|
+
// para conferir o fechamento não pode encontrar a tela vazia (D-19).
|
|
52
|
+
const listaFrota = trabalho !== null && !emFrota.some((t) => t.trabalho_id === trabalho.trabalho_id)
|
|
53
|
+
? [trabalho, ...emFrota]
|
|
54
|
+
: emFrota;
|
|
55
|
+
const frota = listaFrota
|
|
56
|
+
.map((t) => montarNaFrota(t,
|
|
57
|
+
// A frota lê MAIS FUNDO que a lista de atividade de propósito: o
|
|
58
|
+
// `task_iniciada` de uma task que roda há uma hora fica soterrado por
|
|
59
|
+
// dezenas de `suite_executada`, e com a janela curta o tempo decorrido
|
|
60
|
+
// — que é justamente o sinal de execução travada — não apareceria.
|
|
61
|
+
lerRastro(raizProjeto, t.trabalho_id, FUNDO_DA_ESTIMATIVA), estado, t.trabalho_id === trabalho?.trabalho_id))
|
|
62
|
+
.sort((a, b) => {
|
|
63
|
+
// o corrente primeiro: é o que a pessoa veio ver
|
|
64
|
+
if (a.corrente !== b.corrente)
|
|
65
|
+
return a.corrente ? -1 : 1;
|
|
66
|
+
// depois, quem se mexeu mais recentemente
|
|
67
|
+
const ta = a.ultimoEventoTs ?? "";
|
|
68
|
+
const tb = b.ultimoEventoTs ?? "";
|
|
69
|
+
if (ta !== tb)
|
|
70
|
+
return ta > tb ? -1 : 1;
|
|
71
|
+
return a.trabalho.trabalho_id < b.trabalho.trabalho_id ? -1 : 1;
|
|
72
|
+
});
|
|
19
73
|
// "Modo aviso" é vocabulário de hook e só existe no rastro: `regra_violada` é
|
|
20
74
|
// gravado por hook em modo aviso, `acao_bloqueada` em modo bloqueio. Não
|
|
21
75
|
// confundir com as `Violacao` da conformidade, que são defeitos do método nos
|
|
@@ -32,6 +86,7 @@ export function projetarVisao(raizProjeto, op = {}, agora = new Date()) {
|
|
|
32
86
|
bloqueiosAbertos: (trabalho?.bloqueios ?? []).filter((b) => b.aberto),
|
|
33
87
|
eventos,
|
|
34
88
|
violacoesAviso,
|
|
89
|
+
frota,
|
|
35
90
|
lidoEm: agora,
|
|
36
91
|
};
|
|
37
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projetar.js","sourceRoot":"","sources":["../../../src/watch/visao/projetar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA8C,MAAM,gCAAgC,CAAC;AAG3G,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"projetar.js","sourceRoot":"","sources":["../../../src/watch/visao/projetar.ts"],"names":[],"mappings":"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"}
|
package/dist/watch/watch.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export type OpcoesExecucao = {
|
|
|
20
20
|
escrever: (texto: string) => void;
|
|
21
21
|
cor: boolean;
|
|
22
22
|
debounceMs?: number;
|
|
23
|
+
/** Intervalo do redesenho por relógio. `0` desliga (teste). */
|
|
24
|
+
pulsoMs?: number;
|
|
23
25
|
/** Gancho de teste: chamado toda vez que o PLANO é relido do disco. */
|
|
24
26
|
aoLerPlano?: () => void;
|
|
25
27
|
};
|
package/dist/watch/watch.js
CHANGED
|
@@ -15,6 +15,22 @@ function larguraDe(op) {
|
|
|
15
15
|
// Abaixo de 80 continuamos desenhando: o corte é elegante por construção.
|
|
16
16
|
return typeof cols === "number" && cols > 0 ? cols : 80;
|
|
17
17
|
}
|
|
18
|
+
/** Altura de trabalho: a do terminal, ou um valor generoso quando não há TTY. */
|
|
19
|
+
function alturaDe() {
|
|
20
|
+
const linhas = process.stdout.rows;
|
|
21
|
+
// Sem TTY (teste, redirecionamento) nada rola: a altura não limita.
|
|
22
|
+
return typeof linhas === "number" && linhas > 0 ? linhas : Number.MAX_SAFE_INTEGER;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* De quanto em quanto tempo a tela se redesenha sozinha.
|
|
26
|
+
*
|
|
27
|
+
* O watch é movido a evento de arquivo, mas duas coisas na tela andam com o
|
|
28
|
+
* relógio e não com o disco: o tempo decorrido das tasks em andamento e a
|
|
29
|
+
* barra de atividade. Sem este pulso, uma task que roda dez minutos mostraria
|
|
30
|
+
* "0s" o tempo todo — e "parado ha 40 min", que é o sintoma de execução
|
|
31
|
+
* travada, nunca apareceria.
|
|
32
|
+
*/
|
|
33
|
+
const PULSO_MS = 1000;
|
|
18
34
|
export async function executarWatch(op) {
|
|
19
35
|
// Sem `.expx/`, o projeto não tem o Expx instalado. Mensagem curta e saída
|
|
20
36
|
// limpa, como manda a tolerância a falha — não é erro, é ausência.
|
|
@@ -29,7 +45,15 @@ export async function executarWatch(op) {
|
|
|
29
45
|
}
|
|
30
46
|
const subiuEm = new Date();
|
|
31
47
|
const colunas = larguraDe(op);
|
|
32
|
-
|
|
48
|
+
// A tela recebe os limites do terminal como FUNÇÃO, não como número: quem
|
|
49
|
+
// redimensiona a janela no meio da execução muda os dois, e uma tela presa
|
|
50
|
+
// à largura da subida passa a desenhar linhas que não cabem — que é
|
|
51
|
+
// exatamente o que embaralhava o painel.
|
|
52
|
+
const limites = () => ({
|
|
53
|
+
colunas: op.opcoes.colunas ?? larguraDe(op),
|
|
54
|
+
linhas: alturaDe(),
|
|
55
|
+
});
|
|
56
|
+
const tela = criarTela(op.escrever, limites);
|
|
33
57
|
// A visão fica guardada de propósito: é ela que carrega a árvore, cara de
|
|
34
58
|
// montar. O gatilho de estado NÃO a reconstrói.
|
|
35
59
|
let visao = lerTudo();
|
|
@@ -41,12 +65,30 @@ export async function executarWatch(op) {
|
|
|
41
65
|
});
|
|
42
66
|
}
|
|
43
67
|
function redesenhar() {
|
|
68
|
+
const c = op.opcoes.colunas ?? larguraDe(op);
|
|
44
69
|
const linhas = op.opcoes.todos
|
|
45
|
-
? desenharLista(visao,
|
|
46
|
-
: desenhar(visao, {
|
|
70
|
+
? desenharLista(visao, c, op.cor)
|
|
71
|
+
: desenhar(visao, {
|
|
72
|
+
colunas: c,
|
|
73
|
+
cor: op.cor,
|
|
74
|
+
agora: new Date(),
|
|
75
|
+
arvore: op.opcoes.arvore,
|
|
76
|
+
});
|
|
47
77
|
tela.desenhar(linhas);
|
|
48
78
|
}
|
|
49
79
|
redesenhar();
|
|
80
|
+
// O pulso do relógio. `unref` para não segurar o processo sozinho: quem
|
|
81
|
+
// mantém o watch vivo é o observador de arquivos, e um timer que segura o
|
|
82
|
+
// event loop faria o processo não morrer depois do `parar()`.
|
|
83
|
+
const pulso = op.pulsoMs ?? PULSO_MS;
|
|
84
|
+
const relogio = pulso > 0 ? setInterval(redesenhar, pulso) : null;
|
|
85
|
+
relogio?.unref();
|
|
86
|
+
// Redimensionar a janela muda a largura E a altura: sem redesenhar aqui, a
|
|
87
|
+
// tela fica com as linhas da largura antiga até o próximo evento de arquivo.
|
|
88
|
+
const aoRedimensionar = () => {
|
|
89
|
+
redesenhar();
|
|
90
|
+
};
|
|
91
|
+
process.stdout.on("resize", aoRedimensionar);
|
|
50
92
|
const observador = await observarFontes(op.raiz, {
|
|
51
93
|
// O plano mudou: reconstrói tudo. É a releitura cara, e ela só acontece
|
|
52
94
|
// aqui.
|
|
@@ -80,6 +122,9 @@ export async function executarWatch(op) {
|
|
|
80
122
|
}, op.debounceMs ?? 150);
|
|
81
123
|
return {
|
|
82
124
|
parar: async () => {
|
|
125
|
+
if (relogio !== null)
|
|
126
|
+
clearInterval(relogio);
|
|
127
|
+
process.stdout.off("resize", aoRedimensionar);
|
|
83
128
|
await observador.parar();
|
|
84
129
|
},
|
|
85
130
|
codigo: 0,
|
package/dist/watch/watch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/watch/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAyB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/watch/watch.ts"],"names":[],"mappings":"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"}
|