estela 0.1.37 → 0.1.39
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/README.md +17 -0
- package/dist/cli-badge.test.d.ts +2 -0
- package/dist/cli-badge.test.d.ts.map +1 -0
- package/dist/cli-badge.test.js +118 -0
- package/dist/cli-badge.test.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +148 -0
- package/dist/cli.js.map +1 -1
- package/dist/export/badge.d.ts +26 -0
- package/dist/export/badge.d.ts.map +1 -0
- package/dist/export/badge.js +37 -0
- package/dist/export/badge.js.map +1 -0
- package/dist/export/badge.test.d.ts +2 -0
- package/dist/export/badge.test.d.ts.map +1 -0
- package/dist/export/badge.test.js +32 -0
- package/dist/export/badge.test.js.map +1 -0
- package/dist/export/idioma.test.js +6 -2
- package/dist/export/idioma.test.js.map +1 -1
- package/dist/export/panel.d.ts +7 -0
- package/dist/export/panel.d.ts.map +1 -1
- package/dist/export/panel.js +25 -6
- package/dist/export/panel.js.map +1 -1
- package/dist/export/panel.test.js +17 -4
- package/dist/export/panel.test.js.map +1 -1
- package/dist/export/pixelfont.d.ts +17 -0
- package/dist/export/pixelfont.d.ts.map +1 -0
- package/dist/export/pixelfont.js +157 -0
- package/dist/export/pixelfont.js.map +1 -0
- package/dist/export/png.d.ts +12 -0
- package/dist/export/png.d.ts.map +1 -0
- package/dist/export/png.js +85 -0
- package/dist/export/png.js.map +1 -0
- package/dist/export/receipt.d.ts +58 -0
- package/dist/export/receipt.d.ts.map +1 -0
- package/dist/export/receipt.js +216 -0
- package/dist/export/receipt.js.map +1 -0
- package/dist/export/receipt.test.d.ts +2 -0
- package/dist/export/receipt.test.d.ts.map +1 -0
- package/dist/export/receipt.test.js +207 -0
- package/dist/export/receipt.test.js.map +1 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +27 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/publish.d.ts +2 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +3 -1
- package/dist/publish.js.map +1 -1
- package/node_modules/@estela/shared/dist/money.d.ts +6 -0
- package/node_modules/@estela/shared/dist/money.d.ts.map +1 -1
- package/node_modules/@estela/shared/dist/money.js +11 -0
- package/node_modules/@estela/shared/dist/money.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { AiCost, TimeEntry } from "@estela/shared";
|
|
2
|
+
/**
|
|
3
|
+
* `estela receipt`: un ticket en PNG con lo que dejó tu trabajo.
|
|
4
|
+
*
|
|
5
|
+
* Todo se calcula y se pinta en esta máquina, y el fichero se queda en disco:
|
|
6
|
+
* compartirlo es decisión de quien lo tiene. Por eso lleva lo que ya enseña el
|
|
7
|
+
* panel local (horas medidas frente a estimadas, lo que costó la IA) y nada
|
|
8
|
+
* que no se pueda ver ahí.
|
|
9
|
+
*/
|
|
10
|
+
/** Lo que hace falta de un turno de agente para saber cuánto ahorró la caché. */
|
|
11
|
+
export interface ReceiptTurn {
|
|
12
|
+
readonly at: Date;
|
|
13
|
+
readonly model: string;
|
|
14
|
+
readonly cacheRead: number;
|
|
15
|
+
readonly cacheWrite5m: number;
|
|
16
|
+
readonly cacheWrite1h: number;
|
|
17
|
+
}
|
|
18
|
+
export interface ReceiptInput {
|
|
19
|
+
readonly entries: readonly TimeEntry[];
|
|
20
|
+
readonly projectNames: ReadonlyMap<string, string>;
|
|
21
|
+
readonly turns: readonly ReceiptTurn[];
|
|
22
|
+
/** Desde cuándo; null = desde el primer bloque. */
|
|
23
|
+
readonly from: Date | null;
|
|
24
|
+
/** Hasta cuándo, sin incluir. */
|
|
25
|
+
readonly to: Date;
|
|
26
|
+
}
|
|
27
|
+
export interface ReceiptData {
|
|
28
|
+
readonly from: Date;
|
|
29
|
+
/** Último día incluido. */
|
|
30
|
+
readonly to: Date;
|
|
31
|
+
readonly measuredSeconds: number;
|
|
32
|
+
readonly estimatedSeconds: number;
|
|
33
|
+
readonly manualSeconds: number;
|
|
34
|
+
/** Consumo de IA a tarifa API. */
|
|
35
|
+
readonly aiCost: AiCost;
|
|
36
|
+
readonly topProject: {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly cost: AiCost;
|
|
39
|
+
} | null;
|
|
40
|
+
readonly topFeature: {
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly project: string;
|
|
43
|
+
readonly cost: AiCost;
|
|
44
|
+
} | null;
|
|
45
|
+
/** Lo que se habría pagado sin caché, menos lo que se pagó con ella. Nunca negativo. */
|
|
46
|
+
readonly cacheSavings: AiCost;
|
|
47
|
+
}
|
|
48
|
+
export declare function receiptData(input: ReceiptInput): ReceiptData;
|
|
49
|
+
/** El texto de cada línea del recibo, tal como se pinta. Para los tests. */
|
|
50
|
+
export declare function receiptText(d: ReceiptData, options: {
|
|
51
|
+
week: boolean;
|
|
52
|
+
names?: boolean;
|
|
53
|
+
}): string[];
|
|
54
|
+
export declare function renderReceipt(d: ReceiptData, options: {
|
|
55
|
+
week: boolean;
|
|
56
|
+
names?: boolean;
|
|
57
|
+
}): Buffer;
|
|
58
|
+
//# sourceMappingURL=receipt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.d.ts","sourceRoot":"","sources":["../../src/export/receipt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAQxD;;;;;;;GAOG;AAEH,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvG,wFAAwF;IACxF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,CAiD5D;AAgHD,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,EAAE,CAGjG;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAmEjG"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.receiptData = receiptData;
|
|
4
|
+
exports.receiptText = receiptText;
|
|
5
|
+
exports.renderReceipt = renderReceipt;
|
|
6
|
+
const shared_1 = require("@estela/shared");
|
|
7
|
+
const index_js_1 = require("../i18n/index.js");
|
|
8
|
+
const catalog_js_1 = require("../pricing/catalog.js");
|
|
9
|
+
const pixelfont_js_1 = require("./pixelfont.js");
|
|
10
|
+
const png_js_1 = require("./png.js");
|
|
11
|
+
function receiptData(input) {
|
|
12
|
+
const dentro = input.entries.filter((e) => (!input.from || e.startedAt >= input.from) && e.startedAt < input.to);
|
|
13
|
+
const from = input.from ?? (dentro.length
|
|
14
|
+
? new Date(Math.min(...dentro.map((e) => e.startedAt.getTime()))) : input.to);
|
|
15
|
+
const suma = (fuente) => dentro.filter((e) => e.source === fuente).reduce((n, e) => n + e.seconds, 0);
|
|
16
|
+
const porProyecto = new Map();
|
|
17
|
+
const porRama = new Map();
|
|
18
|
+
for (const e of dentro) {
|
|
19
|
+
porProyecto.set(e.projectId, (porProyecto.get(e.projectId) ?? 0) + e.aiCost.microUsd);
|
|
20
|
+
if (!e.branch)
|
|
21
|
+
continue;
|
|
22
|
+
const clave = `${e.projectId}\u0000${e.branch}`;
|
|
23
|
+
const previo = porRama.get(clave);
|
|
24
|
+
porRama.set(clave, { project: e.projectId, micro: (previo?.micro ?? 0) + e.aiCost.microUsd });
|
|
25
|
+
}
|
|
26
|
+
const nombre = (id) => input.projectNames.get(id) ?? id;
|
|
27
|
+
const [pId, pMicro] = [...porProyecto].sort((a, b) => b[1] - a[1])[0] ?? [null, 0];
|
|
28
|
+
const [rClave, r] = [...porRama].sort((a, b) => b[1].micro - a[1].micro)[0] ?? [null, null];
|
|
29
|
+
let ahorro = 0;
|
|
30
|
+
for (const t of input.turns) {
|
|
31
|
+
if ((input.from && t.at < input.from) || t.at >= input.to)
|
|
32
|
+
continue;
|
|
33
|
+
const precio = (0, catalog_js_1.resolvePrice)(t.model, t.at);
|
|
34
|
+
if (!precio)
|
|
35
|
+
continue;
|
|
36
|
+
const porToken = precio.inputPerMTok / 1_000_000;
|
|
37
|
+
// Leer de caché cuesta una fracción del precio de entrada; escribir en
|
|
38
|
+
// ella, algo más. El ahorro es lo primero menos lo segundo.
|
|
39
|
+
ahorro += t.cacheRead * porToken * (1 - precio.cacheReadMultiplier)
|
|
40
|
+
- t.cacheWrite5m * porToken * (precio.cacheWrite5mMultiplier - 1)
|
|
41
|
+
- t.cacheWrite1h * porToken * (precio.cacheWrite1hMultiplier - 1);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
from,
|
|
45
|
+
to: new Date(input.to.getTime() - 1),
|
|
46
|
+
measuredSeconds: suma("agent"),
|
|
47
|
+
estimatedSeconds: suma("commit"),
|
|
48
|
+
manualSeconds: suma("manual"),
|
|
49
|
+
aiCost: { microUsd: dentro.reduce((n, e) => n + e.aiCost.microUsd, 0) },
|
|
50
|
+
topProject: pId && pMicro > 0 ? { name: nombre(pId), cost: { microUsd: pMicro } } : null,
|
|
51
|
+
topFeature: rClave && r && r.micro > 0
|
|
52
|
+
? { name: rClave.split("\u0000")[1], project: nombre(r.project), cost: { microUsd: r.micro } }
|
|
53
|
+
: null,
|
|
54
|
+
cacheSavings: { microUsd: Math.max(0, Math.round(ahorro * 1_000_000)) },
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const FONDO = [0xE6, 0xEA, 0xE5];
|
|
58
|
+
const PAPEL = [0xFF, 0xFD, 0xF8];
|
|
59
|
+
const TINTA = [0x1E, 0x24, 0x21];
|
|
60
|
+
const TENUE = [0x9A, 0xA2, 0x9D];
|
|
61
|
+
const JADE = [0x0E, 0x7C, 0x6B];
|
|
62
|
+
const S = 3; // escala del texto normal
|
|
63
|
+
const COLS = 34; // caracteres por línea, como un ticket de 80 mm
|
|
64
|
+
const PAD = 44; // margen interior del papel
|
|
65
|
+
const MARGEN = 28; // fondo alrededor del papel
|
|
66
|
+
const DIENTE = 12; // el borde dentado de arriba y abajo
|
|
67
|
+
const LINEA = pixelfont_js_1.GLYPH_H * S + 14;
|
|
68
|
+
function fecha(d) {
|
|
69
|
+
const lang = (0, index_js_1.getLang)();
|
|
70
|
+
return d.toLocaleDateString(lang === "en" ? "en-US" : "es-ES", { day: "numeric", month: "short" })
|
|
71
|
+
.replace(".", "").toUpperCase();
|
|
72
|
+
}
|
|
73
|
+
/** Dólares con dos decimales y separador de miles: "$42,999.71" se lee; "$42999.71" no. */
|
|
74
|
+
function dolares(cost) {
|
|
75
|
+
return "$" + (cost.microUsd / 1_000_000).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
76
|
+
}
|
|
77
|
+
function recortar(texto, max) {
|
|
78
|
+
const letras = [...texto];
|
|
79
|
+
// Sin "…": la fuente no lo tiene, y un punto se entiende igual en un ticket.
|
|
80
|
+
return letras.length <= max ? texto : letras.slice(0, Math.max(1, max - 1)).join("") + ".";
|
|
81
|
+
}
|
|
82
|
+
function filas(d, semana, nombres) {
|
|
83
|
+
const total = d.measuredSeconds + d.estimatedSeconds + d.manualSeconds;
|
|
84
|
+
const rango = `${fecha(d.from)} – ${fecha(d.to)} ${d.to.getFullYear()}`;
|
|
85
|
+
const f = [
|
|
86
|
+
{ t: "titulo", texto: "ESTELA" },
|
|
87
|
+
{ t: "centro", texto: semana ? (0, index_js_1.tr) `RECIBO DE LA SEMANA` : (0, index_js_1.tr) `RECIBO DE TU HISTORIAL` },
|
|
88
|
+
{ t: "centro", texto: rango, color: TENUE },
|
|
89
|
+
{ t: "corte" },
|
|
90
|
+
{ t: "par", izq: (0, index_js_1.tr) `HORAS MEDIDAS`, der: (0, shared_1.formatDuration)(d.measuredSeconds) },
|
|
91
|
+
{ t: "par", izq: (0, index_js_1.tr) `HORAS ESTIMADAS`, der: (0, shared_1.formatDuration)(d.estimatedSeconds) },
|
|
92
|
+
];
|
|
93
|
+
if (d.manualSeconds > 0)
|
|
94
|
+
f.push({ t: "par", izq: (0, index_js_1.tr) `AÑADIDAS A MANO`, der: (0, shared_1.formatDuration)(d.manualSeconds) });
|
|
95
|
+
f.push({ t: "par", izq: (0, index_js_1.tr) `TOTAL`, der: (0, shared_1.formatDuration)(total), negrita: true });
|
|
96
|
+
if (total > 0) {
|
|
97
|
+
const parte = d.measuredSeconds / total;
|
|
98
|
+
f.push({ t: "barra", parte, etiqueta: (0, index_js_1.tr) `${`${Math.round(parte * 100)}%`} MEDIDO` });
|
|
99
|
+
}
|
|
100
|
+
f.push({ t: "corte" });
|
|
101
|
+
if (d.aiCost.microUsd > 0) {
|
|
102
|
+
// La aclaración va en su línea: al lado del importe no cabe cuando pasa de mil.
|
|
103
|
+
f.push({ t: "par", izq: (0, index_js_1.tr) `COSTE DE IA`, der: dolares(d.aiCost), negrita: true });
|
|
104
|
+
f.push({ t: "texto", texto: (0, index_js_1.tr) `(A TARIFA API)`, color: TENUE });
|
|
105
|
+
if (d.cacheSavings.microUsd > 0) {
|
|
106
|
+
f.push({ t: "par", izq: (0, index_js_1.tr) `AHORRO POR CACHÉ`, der: dolares(d.cacheSavings) });
|
|
107
|
+
}
|
|
108
|
+
// Sin nombres salvo que se pidan: un recibo está hecho para enseñarse, y
|
|
109
|
+
// el nombre de un proyecto suele ser el de un cliente. Publicarlo diría
|
|
110
|
+
// para quién trabaja quien lo comparte.
|
|
111
|
+
if (d.topProject) {
|
|
112
|
+
f.push({ t: "hueco" });
|
|
113
|
+
if (nombres) {
|
|
114
|
+
f.push({ t: "texto", texto: (0, index_js_1.tr) `PROYECTO MÁS CARO`, color: TENUE });
|
|
115
|
+
f.push({ t: "par", izq: d.topProject.name, der: dolares(d.topProject.cost), sangria: true });
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
f.push({ t: "par", izq: (0, index_js_1.tr) `PROYECTO MÁS CARO`, der: dolares(d.topProject.cost) });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (d.topFeature) {
|
|
122
|
+
if (nombres) {
|
|
123
|
+
f.push({ t: "texto", texto: (0, index_js_1.tr) `RAMA MÁS CARA`, color: TENUE });
|
|
124
|
+
f.push({ t: "par", izq: d.topFeature.name, der: dolares(d.topFeature.cost), sangria: true });
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
f.push({ t: "par", izq: (0, index_js_1.tr) `RAMA MÁS CARA`, der: dolares(d.topFeature.cost) });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
f.push({ t: "centro", texto: (0, index_js_1.tr) `SIN CONSUMO DE IA`, color: TENUE });
|
|
133
|
+
}
|
|
134
|
+
f.push({ t: "corte" }, { t: "centro", texto: (0, index_js_1.tr) `HORAS QUE NO TUVISTE QUE RELLENAR`, color: TENUE }, { t: "hueco" }, { t: "centro", texto: "getestela.dev", color: JADE });
|
|
135
|
+
return f;
|
|
136
|
+
}
|
|
137
|
+
function alto(f) {
|
|
138
|
+
switch (f.t) {
|
|
139
|
+
case "titulo": return pixelfont_js_1.GLYPH_H * 7 + 22;
|
|
140
|
+
case "corte": return 34;
|
|
141
|
+
case "hueco": return 12;
|
|
142
|
+
case "barra": return LINEA + 10;
|
|
143
|
+
default: return LINEA;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** El texto de cada línea del recibo, tal como se pinta. Para los tests. */
|
|
147
|
+
function receiptText(d, options) {
|
|
148
|
+
return filas(d, options.week, options.names === true).flatMap((f) => f.t === "par" ? [`${f.izq} ${f.der}`] : "texto" in f ? [f.texto] : []);
|
|
149
|
+
}
|
|
150
|
+
function renderReceipt(d, options) {
|
|
151
|
+
const lista = filas(d, options.week, options.names === true);
|
|
152
|
+
const anchoTexto = COLS * pixelfont_js_1.ADVANCE * S;
|
|
153
|
+
const anchoPapel = anchoTexto + PAD * 2;
|
|
154
|
+
const altoPapel = PAD + DIENTE + lista.reduce((n, f) => n + alto(f), 0) + PAD;
|
|
155
|
+
const lienzo = new png_js_1.Lienzo(anchoPapel + MARGEN * 2, altoPapel + MARGEN * 2, FONDO);
|
|
156
|
+
// El papel, con los bordes de arriba y abajo en dientes de sierra: el corte
|
|
157
|
+
// de la impresora.
|
|
158
|
+
const x0 = MARGEN, y0 = MARGEN;
|
|
159
|
+
lienzo.rect(x0, y0, anchoPapel, altoPapel, PAPEL);
|
|
160
|
+
for (let x = 0; x < anchoPapel; x++) {
|
|
161
|
+
const h = Math.abs((x % (DIENTE * 2)) - DIENTE);
|
|
162
|
+
lienzo.rect(x0 + x, y0, 1, h, FONDO);
|
|
163
|
+
lienzo.rect(x0 + x, y0 + altoPapel - h, 1, h, FONDO);
|
|
164
|
+
}
|
|
165
|
+
const izq = x0 + PAD;
|
|
166
|
+
let y = y0 + PAD + DIENTE;
|
|
167
|
+
const centrado = (texto, escala) => x0 + Math.round((anchoPapel - (0, pixelfont_js_1.textWidth)(texto, escala)) / 2);
|
|
168
|
+
for (const f of lista) {
|
|
169
|
+
switch (f.t) {
|
|
170
|
+
case "titulo":
|
|
171
|
+
(0, pixelfont_js_1.drawText)(lienzo, f.texto, centrado(f.texto, 7), y, 7, JADE, true);
|
|
172
|
+
break;
|
|
173
|
+
case "centro": {
|
|
174
|
+
const texto = recortar(f.texto, COLS);
|
|
175
|
+
(0, pixelfont_js_1.drawText)(lienzo, texto, centrado(texto, S), y, S, f.color ?? TINTA);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case "texto":
|
|
179
|
+
(0, pixelfont_js_1.drawText)(lienzo, recortar(f.texto, COLS), izq, y, S, f.color ?? TINTA);
|
|
180
|
+
break;
|
|
181
|
+
case "par": {
|
|
182
|
+
const sangria = f.sangria ? 2 : 0;
|
|
183
|
+
const der = f.der;
|
|
184
|
+
const max = COLS - sangria - [...der].length - 2;
|
|
185
|
+
const etiqueta = recortar(f.izq, max);
|
|
186
|
+
(0, pixelfont_js_1.drawText)(lienzo, etiqueta, izq + sangria * pixelfont_js_1.ADVANCE * S, y, S, TINTA, f.negrita);
|
|
187
|
+
(0, pixelfont_js_1.drawText)(lienzo, der, izq + anchoTexto - (0, pixelfont_js_1.textWidth)(der, S), y, S, TINTA, f.negrita);
|
|
188
|
+
// Puntos de relleno entre la etiqueta y el importe, como en un ticket.
|
|
189
|
+
const desde = sangria + [...etiqueta].length + 1;
|
|
190
|
+
const hasta = COLS - [...der].length - 1;
|
|
191
|
+
for (let c = desde; c < hasta; c++) {
|
|
192
|
+
lienzo.rect(izq + c * pixelfont_js_1.ADVANCE * S + 2 * S, y + 8 * S, S, S, TENUE);
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case "barra": {
|
|
197
|
+
const ancho = anchoTexto - (0, pixelfont_js_1.textWidth)(f.etiqueta, S) - pixelfont_js_1.ADVANCE * S;
|
|
198
|
+
const lleno = Math.round(ancho * Math.min(1, Math.max(0, f.parte)));
|
|
199
|
+
const by = y + 3 * S;
|
|
200
|
+
lienzo.rect(izq, by, ancho, 5 * S, [0xE4, 0xE8, 0xE3]);
|
|
201
|
+
lienzo.rect(izq, by, lleno, 5 * S, JADE);
|
|
202
|
+
(0, pixelfont_js_1.drawText)(lienzo, f.etiqueta, izq + anchoTexto - (0, pixelfont_js_1.textWidth)(f.etiqueta, S), y, S, JADE);
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case "corte":
|
|
206
|
+
for (let x = 0; x < anchoTexto; x += 12)
|
|
207
|
+
lienzo.rect(izq + x, y + 15, 6, 2, TENUE);
|
|
208
|
+
break;
|
|
209
|
+
case "hueco":
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
y += alto(f);
|
|
213
|
+
}
|
|
214
|
+
return lienzo.png();
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=receipt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.js","sourceRoot":"","sources":["../../src/export/receipt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.test.d.ts","sourceRoot":"","sources":["../../src/export/receipt.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
40
|
+
const node_child_process_1 = require("node:child_process");
|
|
41
|
+
const node_fs_1 = require("node:fs");
|
|
42
|
+
const node_os_1 = require("node:os");
|
|
43
|
+
const node_path_1 = require("node:path");
|
|
44
|
+
const node_test_1 = require("node:test");
|
|
45
|
+
const node_zlib_1 = require("node:zlib");
|
|
46
|
+
const schema_js_1 = require("../db/schema.js");
|
|
47
|
+
const store = __importStar(require("../db/store.js"));
|
|
48
|
+
const en_js_1 = require("../i18n/en.js");
|
|
49
|
+
const catalog_js_1 = require("../pricing/catalog.js");
|
|
50
|
+
const pixelfont_js_1 = require("./pixelfont.js");
|
|
51
|
+
const png_js_1 = require("./png.js");
|
|
52
|
+
const receipt_js_1 = require("./receipt.js");
|
|
53
|
+
// ── El PNG ──────────────────────────────────────────────────────────────
|
|
54
|
+
/** Lee los trozos de un PNG: lo justo para comprobar que es uno de verdad. */
|
|
55
|
+
function trozos(png) {
|
|
56
|
+
strict_1.default.deepEqual([...png.subarray(0, 8)], [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
57
|
+
const out = new Map();
|
|
58
|
+
let i = 8;
|
|
59
|
+
while (i < png.length) {
|
|
60
|
+
const largo = png.readUInt32BE(i);
|
|
61
|
+
const tipo = png.subarray(i + 4, i + 8).toString("ascii");
|
|
62
|
+
const datos = png.subarray(i + 8, i + 8 + largo);
|
|
63
|
+
strict_1.default.equal(png.readUInt32BE(i + 8 + largo), (0, png_js_1.crc32)(png.subarray(i + 4, i + 8 + largo)), `CRC de ${tipo}`);
|
|
64
|
+
out.set(tipo, Buffer.concat([out.get(tipo) ?? Buffer.alloc(0), datos]));
|
|
65
|
+
i += 12 + largo;
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
(0, node_test_1.test)("crc32 da el valor de referencia", () => {
|
|
70
|
+
// El CRC del trozo IEND vacío: está en todos los PNG del mundo.
|
|
71
|
+
strict_1.default.equal((0, png_js_1.crc32)(Buffer.from("IEND", "ascii")), 0xae426082);
|
|
72
|
+
});
|
|
73
|
+
(0, node_test_1.test)("el PNG se decodifica con las medidas y los píxeles que se pintaron", () => {
|
|
74
|
+
const l = new png_js_1.Lienzo(3, 2, [255, 255, 255]);
|
|
75
|
+
l.set(1, 1, [10, 20, 30]);
|
|
76
|
+
const t = trozos(l.png());
|
|
77
|
+
strict_1.default.equal(t.get("IHDR").readUInt32BE(0), 3);
|
|
78
|
+
strict_1.default.equal(t.get("IHDR").readUInt32BE(4), 2);
|
|
79
|
+
const crudo = (0, node_zlib_1.inflateSync)(t.get("IDAT"));
|
|
80
|
+
strict_1.default.equal(crudo.length, (3 * 3 + 1) * 2);
|
|
81
|
+
// Fila 1, columna 1: saltar la fila 0 entera (10 bytes) y el byte de filtro.
|
|
82
|
+
strict_1.default.deepEqual([...crudo.subarray(10 + 1 + 3, 10 + 1 + 6)], [10, 20, 30]);
|
|
83
|
+
strict_1.default.ok(t.has("IEND"));
|
|
84
|
+
});
|
|
85
|
+
// ── La fuente ───────────────────────────────────────────────────────────
|
|
86
|
+
(0, node_test_1.test)("la fuente tiene todas las letras de las etiquetas del recibo, en los dos idiomas", () => {
|
|
87
|
+
const etiquetas = ["RECIBO DE LA SEMANA", "RECIBO DE TU HISTORIAL", "HORAS MEDIDAS", "HORAS ESTIMADAS",
|
|
88
|
+
"AÑADIDAS A MANO", "TOTAL", "{0} MEDIDO", "COSTE DE IA", "(A TARIFA API)", "AHORRO POR CACHÉ",
|
|
89
|
+
"PROYECTO MÁS CARO", "RAMA MÁS CARA", "SIN CONSUMO DE IA", "HORAS QUE NO TUVISTE QUE RELLENAR"];
|
|
90
|
+
const textos = [...etiquetas, ...etiquetas.map((e) => en_js_1.EN[e]), "getestela.dev", "SEPT – OCT $1,204.50 100%"];
|
|
91
|
+
for (const texto of textos) {
|
|
92
|
+
for (const ch of texto.replace("{0}", ""))
|
|
93
|
+
strict_1.default.ok((0, pixelfont_js_1.hasGlyph)(ch), `falta el glifo "${ch}" (en "${texto}")`);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
// ── Los números ─────────────────────────────────────────────────────────
|
|
97
|
+
function bloque(id, projectId, day, source, hours, aiUsd, branch = "main") {
|
|
98
|
+
const startedAt = new Date(`${day}T10:00:00Z`);
|
|
99
|
+
return {
|
|
100
|
+
id, projectId, startedAt, endedAt: new Date(startedAt.getTime() + hours * 3600_000),
|
|
101
|
+
seconds: hours * 3600, description: "Trabajo", billable: true, invoiceId: null,
|
|
102
|
+
aiCost: { microUsd: aiUsd * 1_000_000 }, agentSeconds: 0, commitHashes: [], agents: [],
|
|
103
|
+
source, kind: "development", branch,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const NOMBRES = new Map([["web", "Web"], ["app", "App"]]);
|
|
107
|
+
(0, node_test_1.test)("el recibo separa medido, estimado y a mano, y solo cuenta lo del periodo", () => {
|
|
108
|
+
const d = (0, receipt_js_1.receiptData)({
|
|
109
|
+
entries: [
|
|
110
|
+
bloque("a", "web", "2026-09-22", "agent", 5, 10),
|
|
111
|
+
bloque("b", "web", "2026-09-23", "commit", 2, 0),
|
|
112
|
+
bloque("c", "app", "2026-09-24", "manual", 1, 0),
|
|
113
|
+
bloque("fuera", "web", "2026-09-01", "agent", 50, 500),
|
|
114
|
+
],
|
|
115
|
+
projectNames: NOMBRES, turns: [],
|
|
116
|
+
from: new Date("2026-09-22T00:00:00Z"), to: new Date("2026-09-29T00:00:00Z"),
|
|
117
|
+
});
|
|
118
|
+
strict_1.default.equal(d.measuredSeconds, 5 * 3600);
|
|
119
|
+
strict_1.default.equal(d.estimatedSeconds, 2 * 3600);
|
|
120
|
+
strict_1.default.equal(d.manualSeconds, 3600);
|
|
121
|
+
strict_1.default.equal(d.aiCost.microUsd, 10_000_000);
|
|
122
|
+
});
|
|
123
|
+
(0, node_test_1.test)("el proyecto y la rama más caros son los de más coste de IA, no los de más horas", () => {
|
|
124
|
+
const d = (0, receipt_js_1.receiptData)({
|
|
125
|
+
entries: [
|
|
126
|
+
bloque("a", "web", "2026-09-22", "agent", 20, 5, "feat/login"),
|
|
127
|
+
bloque("b", "app", "2026-09-23", "agent", 2, 30, "feat/pagos"),
|
|
128
|
+
bloque("c", "app", "2026-09-24", "agent", 1, 4, "fix/menu"),
|
|
129
|
+
],
|
|
130
|
+
projectNames: NOMBRES, turns: [], from: null, to: new Date("2026-10-01T00:00:00Z"),
|
|
131
|
+
});
|
|
132
|
+
strict_1.default.deepEqual(d.topProject, { name: "App", cost: { microUsd: 34_000_000 } });
|
|
133
|
+
strict_1.default.equal(d.topFeature.name, "feat/pagos");
|
|
134
|
+
// Sin --week empieza en el primer bloque.
|
|
135
|
+
strict_1.default.equal(d.from.toISOString(), "2026-09-22T10:00:00.000Z");
|
|
136
|
+
});
|
|
137
|
+
(0, node_test_1.test)("por defecto el recibo no lleva nombres de proyectos ni de ramas: suelen ser de clientes", () => {
|
|
138
|
+
const d = (0, receipt_js_1.receiptData)({
|
|
139
|
+
entries: [bloque("a", "app", "2026-09-22", "agent", 2, 30, "feat/pagos-acme")],
|
|
140
|
+
projectNames: new Map([["app", "ACME Banca"]]), turns: [], from: null, to: new Date("2026-10-01T00:00:00Z"),
|
|
141
|
+
});
|
|
142
|
+
const sin = (0, receipt_js_1.receiptText)(d, { week: false }).join("\n");
|
|
143
|
+
strict_1.default.doesNotMatch(sin, /ACME|pagos-acme/);
|
|
144
|
+
strict_1.default.match(sin, /PROYECTO MÁS CARO \$30\.00/);
|
|
145
|
+
strict_1.default.match(sin, /RAMA MÁS CARA \$30\.00/);
|
|
146
|
+
const con = (0, receipt_js_1.receiptText)(d, { week: false, names: true }).join("\n");
|
|
147
|
+
strict_1.default.match(con, /ACME Banca \$30\.00/);
|
|
148
|
+
strict_1.default.match(con, /feat\/pagos-acme \$30\.00/);
|
|
149
|
+
});
|
|
150
|
+
(0, node_test_1.test)("sin consumo de IA no hay proyecto ni rama más caros que enseñar", () => {
|
|
151
|
+
const d = (0, receipt_js_1.receiptData)({
|
|
152
|
+
entries: [bloque("a", "web", "2026-09-22", "commit", 3, 0)],
|
|
153
|
+
projectNames: NOMBRES, turns: [], from: null, to: new Date("2026-10-01T00:00:00Z"),
|
|
154
|
+
});
|
|
155
|
+
strict_1.default.equal(d.topProject, null);
|
|
156
|
+
strict_1.default.equal(d.topFeature, null);
|
|
157
|
+
});
|
|
158
|
+
(0, node_test_1.test)("el ahorro por caché: lo leído de caché a precio completo, menos lo que costó escribir en ella", () => {
|
|
159
|
+
const precio = catalog_js_1.PRICE_CATALOG[0];
|
|
160
|
+
const at = new Date(new Date(precio.effectiveFrom).getTime() + 86_400_000);
|
|
161
|
+
const d = (0, receipt_js_1.receiptData)({
|
|
162
|
+
entries: [], projectNames: NOMBRES, from: null, to: new Date(at.getTime() + 86_400_000),
|
|
163
|
+
turns: [{ at, model: precio.modelPrefix, cacheRead: 1_000_000, cacheWrite5m: 100_000, cacheWrite1h: 0 }],
|
|
164
|
+
});
|
|
165
|
+
const esperado = precio.inputPerMTok * (1 - precio.cacheReadMultiplier)
|
|
166
|
+
- 0.1 * precio.inputPerMTok * (precio.cacheWrite5mMultiplier - 1);
|
|
167
|
+
strict_1.default.equal(d.cacheSavings.microUsd, Math.round(esperado * 1_000_000));
|
|
168
|
+
});
|
|
169
|
+
(0, node_test_1.test)("el recibo pintado es un PNG con el ancho de un ticket", () => {
|
|
170
|
+
const d = (0, receipt_js_1.receiptData)({
|
|
171
|
+
entries: [bloque("a", "web", "2026-09-22", "agent", 5, 10, "feat/una-rama-con-un-nombre-muy-largo")],
|
|
172
|
+
projectNames: NOMBRES, turns: [], from: null, to: new Date("2026-10-01T00:00:00Z"),
|
|
173
|
+
});
|
|
174
|
+
const t = trozos((0, receipt_js_1.renderReceipt)(d, { week: false }));
|
|
175
|
+
const ancho = t.get("IHDR").readUInt32BE(0);
|
|
176
|
+
const alto = t.get("IHDR").readUInt32BE(4);
|
|
177
|
+
strict_1.default.ok(ancho > 600 && ancho < 900, `ancho ${ancho}`);
|
|
178
|
+
strict_1.default.ok(alto > ancho, "un ticket es más alto que ancho");
|
|
179
|
+
});
|
|
180
|
+
// ── El comando ──────────────────────────────────────────────────────────
|
|
181
|
+
const BIN = (0, node_path_1.join)(__dirname, "..", "bin.js");
|
|
182
|
+
(0, node_test_1.test)("estela receipt deja un PNG en disco y dice dónde", () => {
|
|
183
|
+
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "estela-receipt-"));
|
|
184
|
+
const dbPath = (0, node_path_1.join)(dir, "estela.db");
|
|
185
|
+
const db = (0, schema_js_1.openDatabase)(dbPath);
|
|
186
|
+
try {
|
|
187
|
+
store.upsertClient(db, { id: "c", name: "Interno", currency: "EUR" });
|
|
188
|
+
store.upsertProject(db, {
|
|
189
|
+
id: "web", clientId: "c", name: "Web", repoPaths: [],
|
|
190
|
+
billable: true, roundingMinutes: 0, aiCostPolicy: "absorbed", kind: "client",
|
|
191
|
+
});
|
|
192
|
+
store.saveTimeEntry(db, bloque("a", "web", new Date().toISOString().slice(0, 10), "agent", 2, 3));
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
db.close();
|
|
196
|
+
}
|
|
197
|
+
const out = (0, node_path_1.join)(dir, "recibo.png");
|
|
198
|
+
const r = (0, node_child_process_1.spawnSync)(process.execPath, [BIN, "receipt", "--week", "--out", out, "--db", dbPath], {
|
|
199
|
+
encoding: "utf8", env: { ...process.env, ESTELA_LANG: "es", NO_COLOR: "1" },
|
|
200
|
+
});
|
|
201
|
+
strict_1.default.equal(r.status, 0, r.stderr);
|
|
202
|
+
strict_1.default.match(r.stdout, /Recibo guardado en .*recibo\.png/);
|
|
203
|
+
strict_1.default.match(r.stdout, /no se ha enviado a ningún sitio/);
|
|
204
|
+
strict_1.default.match(r.stdout, /Sin nombres de proyectos ni ramas/);
|
|
205
|
+
trozos((0, node_fs_1.readFileSync)(out));
|
|
206
|
+
});
|
|
207
|
+
//# sourceMappingURL=receipt.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.test.js","sourceRoot":"","sources":["../../src/export/receipt.test.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n/en.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAw4BrC,CAAC"}
|
package/dist/i18n/en.js
CHANGED
|
@@ -378,7 +378,7 @@ exports.EN = {
|
|
|
378
378
|
"Esto es una foto del proyecto": "This is a snapshot of the project",
|
|
379
379
|
"Se genera de la actividad real de Git y del editor, y se actualiza cuando quien lo publica lo vuelve a publicar.": "It is generated from real Git and editor activity, and it updates whenever whoever published it publishes it again.",
|
|
380
380
|
"Verlo para un equipo": "See it for a team",
|
|
381
|
-
"Horas
|
|
381
|
+
"Horas rellenadas por Estela": "Hours filled in by Estela",
|
|
382
382
|
"El grueso del trabajo fue **{0}**": "Most of the work went into **{0}**",
|
|
383
383
|
"con **{0} entrega**": "with **{0} delivery**",
|
|
384
384
|
"con **{0} entregas**": "with **{0} deliveries**",
|
|
@@ -456,5 +456,31 @@ exports.EN = {
|
|
|
456
456
|
// ── watchers/copilot.ts ──
|
|
457
457
|
"{0} de {1} peticiones de Copilot venían malformadas ": "{0} of {1} Copilot requests were malformed ",
|
|
458
458
|
"VS Code puede haber cambiado su formato: revisa los totales antes de facturar.": "VS Code may have changed its format: check the totals before billing.",
|
|
459
|
+
// ── cli.ts (setup: la estrella, una vez) ──
|
|
460
|
+
"\n ¿Te sirve? Una estrella en GitHub ayuda a que otros lo encuentren:": "\n Is Estela useful? A star on GitHub helps others find it:",
|
|
461
|
+
// ── cli.ts (badge) ──
|
|
462
|
+
"Este directorio no es de ningún proyecto. Indica cuál con --project <id>.": "This directory doesn't belong to any project. Say which one with --project <id>.",
|
|
463
|
+
"\"{0}\" no tiene horas medidas todavía: el badge solo cuenta las de sesiones de agente.": "\"{0}\" has no measured hours yet: the badge only counts hours from agent sessions.",
|
|
464
|
+
"Vista previa: {0}": "Preview: {0}",
|
|
465
|
+
"El coste es a tarifa API. Si pagas cuota fija, regístrala para que salga lo que pagas de verdad:": "That cost is at API rates. If you pay a flat subscription, add it so the badge shows what you actually pay:",
|
|
466
|
+
"Es una imagen estática: para actualizar las cifras, vuelve a generarlo.": "It's a static image: to update the numbers, generate it again.",
|
|
467
|
+
// ── cli.ts y export/receipt.ts (receipt) ──
|
|
468
|
+
"Recibo guardado en {0}": "Receipt saved to {0}",
|
|
469
|
+
"Sin nombres de proyectos ni ramas, para que puedas compartirlo. Con --names, se incluyen.": "No project or branch names, so you can share it. Add --names to include them.",
|
|
470
|
+
"Se ha generado en tu máquina y no se ha enviado a ningún sitio.": "It was generated on your machine and hasn't been sent anywhere.",
|
|
471
|
+
"RECIBO DE LA SEMANA": "RECEIPT FOR THE WEEK",
|
|
472
|
+
"RECIBO DE TU HISTORIAL": "RECEIPT FOR YOUR HISTORY",
|
|
473
|
+
"HORAS MEDIDAS": "MEASURED HOURS",
|
|
474
|
+
"HORAS ESTIMADAS": "ESTIMATED HOURS",
|
|
475
|
+
"AÑADIDAS A MANO": "ADDED BY HAND",
|
|
476
|
+
"TOTAL": "TOTAL",
|
|
477
|
+
"{0} MEDIDO": "{0} MEASURED",
|
|
478
|
+
"COSTE DE IA": "AI COST",
|
|
479
|
+
"(A TARIFA API)": "(AT API RATES)",
|
|
480
|
+
"AHORRO POR CACHÉ": "SAVED BY CACHING",
|
|
481
|
+
"PROYECTO MÁS CARO": "MOST EXPENSIVE PROJECT",
|
|
482
|
+
"RAMA MÁS CARA": "MOST EXPENSIVE BRANCH",
|
|
483
|
+
"SIN CONSUMO DE IA": "NO AI USAGE",
|
|
484
|
+
"HORAS QUE NO TUVISTE QUE RELLENAR": "HOURS YOU DIDN'T HAVE TO FILL IN",
|
|
459
485
|
};
|
|
460
486
|
//# sourceMappingURL=en.js.map
|