sagadeck 1.2.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/LICENSE +21 -0
- package/README.md +305 -0
- package/SKILL.md +148 -0
- package/bin/sagadeck.js +511 -0
- package/docs/ANDAMENTO.md +1255 -0
- package/docs/EXPERIENCIAS.md +39 -0
- package/docs/PLANO-EXPERIENCIAS.md +39 -0
- package/docs/PLANO-TESTE-AULAS-TECNICAS.md +44 -0
- package/docs/PLANO-TESTE-DESINFORMACAO.md +38 -0
- package/docs/REFERENCIA.md +1131 -0
- package/package.json +59 -0
- package/src/adaptive-layouts.js +18 -0
- package/src/ai/art-direction.js +8 -0
- package/src/ai/commands.js +130 -0
- package/src/ai/context.js +245 -0
- package/src/ai/deck-ai.js +1135 -0
- package/src/ai/directions.js +74 -0
- package/src/ai/document-materials.js +49 -0
- package/src/ai/document-visuals.js +215 -0
- package/src/ai/evaluation.js +31 -0
- package/src/ai/ground.js +55 -0
- package/src/ai/llm.js +292 -0
- package/src/ai/quality.js +51 -0
- package/src/ai/relay.js +45 -0
- package/src/ai/staged-generation.js +24 -0
- package/src/ai/transform.js +858 -0
- package/src/ai/usage.js +17 -0
- package/src/ai/variety.js +80 -0
- package/src/ai/video-frames.js +24 -0
- package/src/ai/video-generation.js +126 -0
- package/src/ai/web-operation.js +31 -0
- package/src/algo-catalog.js +153 -0
- package/src/algo-trace.js +139 -0
- package/src/api-client.js +514 -0
- package/src/api-collections.js +14 -0
- package/src/api-demo.js +222 -0
- package/src/aspect.js +40 -0
- package/src/build.js +323 -0
- package/src/carousel.js +56 -0
- package/src/chrome.js +65 -0
- package/src/code-highlight.js +68 -0
- package/src/code-lab-browser.js +22 -0
- package/src/code-lab.js +3 -0
- package/src/code-language.js +52 -0
- package/src/csv.js +74 -0
- package/src/decision-lab.js +20 -0
- package/src/deck-file.js +119 -0
- package/src/diagram/napkin-examples.js +13 -0
- package/src/diagram/napkin.js +539 -0
- package/src/docx.js +128 -0
- package/src/dynamics/git-sim.js +200 -0
- package/src/dynamics/layouts.js +112 -0
- package/src/elements.js +554 -0
- package/src/experiences.js +124 -0
- package/src/exploration.js +31 -0
- package/src/export/browser.js +53 -0
- package/src/export/estudo.js +67 -0
- package/src/export/pptx.js +475 -0
- package/src/export/roteiro.js +40 -0
- package/src/export/shots.js +182 -0
- package/src/figures/charts.js +383 -0
- package/src/figures/diagrams.js +117 -0
- package/src/figures/icons.js +166 -0
- package/src/figures/material-pictos.js +20 -0
- package/src/figures/pictos.js +255 -0
- package/src/figures/points.js +106 -0
- package/src/figures/qr.js +29 -0
- package/src/figures/ufmap.js +48 -0
- package/src/fiscal/autofix.js +377 -0
- package/src/fiscal/normalize.js +115 -0
- package/src/graph-lab.js +24 -0
- package/src/hologram.js +30 -0
- package/src/identity.js +86 -0
- package/src/import/crop.js +59 -0
- package/src/import/index.js +132 -0
- package/src/import/legacy-word.js +42 -0
- package/src/import/merge.js +45 -0
- package/src/import/office.js +123 -0
- package/src/import/omml.js +69 -0
- package/src/import/pdf-render.js +56 -0
- package/src/import/pptx.js +701 -0
- package/src/import/xml.js +42 -0
- package/src/infographic.js +401 -0
- package/src/layouts.js +723 -0
- package/src/lessons.js +171 -0
- package/src/library.js +399 -0
- package/src/markup.js +116 -0
- package/src/master.js +214 -0
- package/src/mcp/server.js +371 -0
- package/src/meeting.js +42 -0
- package/src/motion.js +56 -0
- package/src/package.js +116 -0
- package/src/playground.js +19 -0
- package/src/portal-scene.js +20 -0
- package/src/preferences.js +61 -0
- package/src/protect.js +51 -0
- package/src/purpose.js +24 -0
- package/src/pytrace.js +1092 -0
- package/src/research/duckduckgo.js +73 -0
- package/src/research/research.js +202 -0
- package/src/research/svg-image.js +17 -0
- package/src/research/visuals.js +52 -0
- package/src/runtime/api-collection-ui.js +5 -0
- package/src/runtime/api-collections.js +28 -0
- package/src/runtime/api-core.js +530 -0
- package/src/runtime/api-ui.js +966 -0
- package/src/runtime/base.css +1774 -0
- package/src/runtime/calc.js +139 -0
- package/src/runtime/code-lab.js +371 -0
- package/src/runtime/decision-lab.js +49 -0
- package/src/runtime/diagram.js +341 -0
- package/src/runtime/fit.js +268 -0
- package/src/runtime/fonts/caveat.css +2 -0
- package/src/runtime/fonts/comic-neue.css +3 -0
- package/src/runtime/fonts/fredoka.css +2 -0
- package/src/runtime/fonts/index.json +10 -0
- package/src/runtime/fonts/inter.css +2 -0
- package/src/runtime/fonts/patrick-hand.css +2 -0
- package/src/runtime/fonts/plus-jakarta-sans.css +2 -0
- package/src/runtime/fonts/press-start-2p.css +2 -0
- package/src/runtime/fonts/vt323.css +2 -0
- package/src/runtime/formula.js +148 -0
- package/src/runtime/graph-lab.js +72 -0
- package/src/runtime/meeting.css +7 -0
- package/src/runtime/meeting.js +10 -0
- package/src/runtime/motion.js +15 -0
- package/src/runtime/playground.js +11 -0
- package/src/runtime/points.js +19 -0
- package/src/runtime/portal-scene.css +6 -0
- package/src/runtime/portal-scene.js +22 -0
- package/src/runtime/runtime.js +827 -0
- package/src/runtime/science.js +89 -0
- package/src/runtime/skins/aluminio.css +31 -0
- package/src/runtime/skins/arcade.css +25 -0
- package/src/runtime/skins/aurora.css +17 -0
- package/src/runtime/skins/bauhaus.css +19 -0
- package/src/runtime/skins/editorial.css +19 -0
- package/src/runtime/skins/jornal.css +17 -0
- package/src/runtime/skins/manual-noite.css +14 -0
- package/src/runtime/skins/manual.css +14 -0
- package/src/runtime/skins/noite.css +21 -0
- package/src/runtime/skins/oceano.css +17 -0
- package/src/runtime/skins/pop.css +23 -0
- package/src/runtime/skins/prata.css +18 -0
- package/src/runtime/skins/prisma.css +28 -0
- package/src/runtime/skins/rabisco.css +18 -0
- package/src/runtime/skins/relevo.css +33 -0
- package/src/runtime/skins/sinal.css +16 -0
- package/src/runtime/skins/terminal.css +23 -0
- package/src/runtime/vendor/KATEX-LICENSE.txt +21 -0
- package/src/runtime/vendor/MERMAID-LICENSE.txt +21 -0
- package/src/runtime/vendor/PLOTLY-LICENSE.txt +21 -0
- package/src/runtime/vendor/katex.css +1 -0
- package/src/runtime/vendor/mermaid.min.js +3636 -0
- package/src/runtime/vendor/plotly.min.js +3620 -0
- package/src/runtime/video-player.js +35 -0
- package/src/science.js +162 -0
- package/src/studio/ai-response.js +36 -0
- package/src/studio/api-routes.js +152 -0
- package/src/studio/assets/contexto/leia-me.md +12 -0
- package/src/studio/assets/contexto/vendas.csv +7 -0
- package/src/studio/assets/imagens/colecao-arquitetura.png +0 -0
- package/src/studio/assets/imagens/colecao-cor.png +0 -0
- package/src/studio/assets/imagens/colecao-equipe.png +0 -0
- package/src/studio/assets/imagens/lavanda-cover.jpg +0 -0
- package/src/studio/code-routes.js +32 -0
- package/src/studio/command-approval.js +48 -0
- package/src/studio/demo-decks.js +98 -0
- package/src/studio/direction-routes.js +29 -0
- package/src/studio/errors.js +65 -0
- package/src/studio/exploration-demo.js +17 -0
- package/src/studio/exporting.js +105 -0
- package/src/studio/generation-report.js +10 -0
- package/src/studio/instance.js +48 -0
- package/src/studio/layout-samples.js +152 -0
- package/src/studio/project.js +371 -0
- package/src/studio/public/api-collections.js +28 -0
- package/src/studio/public/app.js +5265 -0
- package/src/studio/public/art-preview.js +10 -0
- package/src/studio/public/calc-fields.js +11 -0
- package/src/studio/public/chat-progress.js +47 -0
- package/src/studio/public/developer-fields.js +22 -0
- package/src/studio/public/explorer.js +443 -0
- package/src/studio/public/history.js +58 -0
- package/src/studio/public/index.html +867 -0
- package/src/studio/public/inspector.js +270 -0
- package/src/studio/public/lab-fields.js +5 -0
- package/src/studio/public/library.css +275 -0
- package/src/studio/public/library.html +55 -0
- package/src/studio/public/library.js +471 -0
- package/src/studio/public/merge-decks.js +155 -0
- package/src/studio/public/review-ui.js +100 -0
- package/src/studio/public/screenshot-editor.js +140 -0
- package/src/studio/public/share-ui.js +72 -0
- package/src/studio/public/slide-clipboard.js +23 -0
- package/src/studio/public/slide-form.js +1263 -0
- package/src/studio/public/studio-awareness.js +154 -0
- package/src/studio/public/studio-next.css +303 -0
- package/src/studio/public/style.css +1262 -0
- package/src/studio/public/ui-icons.js +2 -0
- package/src/studio/public/viewers.js +372 -0
- package/src/studio/public/visual-editor.js +326 -0
- package/src/studio/public/workspace.js +18 -0
- package/src/studio/public-files.js +1 -0
- package/src/studio/request-helpers.js +41 -0
- package/src/studio/server.js +1583 -0
- package/src/studio/share-routes.js +146 -0
- package/src/studio/slide-copy-routes.js +26 -0
- package/src/studio/slide-copy.js +30 -0
- package/src/studio/snapshot.js +160 -0
- package/src/studio/style-routes.js +103 -0
- package/src/studio/template-collections.js +97 -0
- package/src/studio/versions.js +95 -0
- package/src/studio/video-download.js +29 -0
- package/src/studio/visual-keys.js +52 -0
- package/src/studio/workspaces.js +39 -0
- package/src/table.js +93 -0
- package/src/templates/scaffold.js +372 -0
- package/src/themes.js +604 -0
- package/src/trace-view.js +450 -0
- package/src/uid.js +19 -0
- package/src/video-player.js +40 -0
- package/src/visual-edits.js +99 -0
- package/src/ws.js +134 -0
- package/templates/cenario/Texto no cen/303/241rio.yaml" +171 -0
- package/templates/cenario/imagens/cidade.svg +30 -0
- package/templates/cenario/imagens/pessoa.svg +15 -0
- package/templates/cenario-e-ciencia.yaml +47 -0
- package/templates/ensaio-api.yaml +160 -0
- package/templates/exemplo-alegre.yaml +75 -0
- package/templates/exemplo-keynote.yaml +90 -0
- package/templates/exemplo-napkin.yaml +139 -0
- package/templates/exemplo.yaml +228 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Calculadora ao vivo (layout calc): a mesma conta no motor (Node: prévia, PDF) e na apresentação (controles).
|
|
2
|
+
// Precisa de src/runtime/formula.js carregado antes (SagaFormula).
|
|
3
|
+
(function (root) {
|
|
4
|
+
const SUP = { "-": "⁻", 0: "⁰", 1: "¹", 2: "²", 3: "³", 4: "⁴", 5: "⁵", 6: "⁶", 7: "⁷", 8: "⁸", 9: "⁹" };
|
|
5
|
+
function format(v, o = {}) {
|
|
6
|
+
if (v == null || !Number.isFinite(v)) return "—";
|
|
7
|
+
if (o.sci || Math.abs(v) >= 1e7 || (Math.abs(v) < 1e-3 && v !== 0)) {
|
|
8
|
+
const [m, e] = v.toExponential(2).split("e");
|
|
9
|
+
return `${m.replace(".", ",")} × 10${String(Number(e)).split("").map((c) => SUP[c] ?? c).join("")}`;
|
|
10
|
+
}
|
|
11
|
+
if (o.decimals != null) return v.toLocaleString("pt-BR", { minimumFractionDigits: o.decimals, maximumFractionDigits: o.decimals });
|
|
12
|
+
return v.toLocaleString("pt-BR", { maximumSignificantDigits: Math.abs(v) >= 1000 ? 7 : 4 });
|
|
13
|
+
}
|
|
14
|
+
// todas as saídas na ordem (uma saída usa as anteriores); `cases` escolhe texto/cor/fórmula pela faixa de `of`
|
|
15
|
+
function evaluate(model, values = {}) {
|
|
16
|
+
const F = root.SagaFormula;
|
|
17
|
+
const env = Object.fromEntries(model.inputs.map((i) => [i.name, values[i.name] ?? i.value]));
|
|
18
|
+
const vars = [...model.inputs.map((i) => i.name), ...model.outputs.map((o) => o.name)];
|
|
19
|
+
const out = {};
|
|
20
|
+
for (const o of model.outputs) {
|
|
21
|
+
const ofVal = o.of ? env[o.of] : null;
|
|
22
|
+
const kase = o.cases.length ? o.cases.find((c) => c.below == null || (ofVal ?? NaN) < c.below) || o.cases[o.cases.length - 1] : null;
|
|
23
|
+
const src = (kase && kase.fn) || o.fn;
|
|
24
|
+
let value = null, error = "";
|
|
25
|
+
if (src) { try { value = F.compile(src, vars).eval(env); } catch (e) { error = e.message; } }
|
|
26
|
+
if (src && !Number.isFinite(value)) error ||= 'A fórmula não produziu um número finito para estas entradas.';
|
|
27
|
+
if (value != null) env[o.name] = value;
|
|
28
|
+
out[o.name] = { value, error, text: (kase && kase.text) || "", color: (kase && kase.color) || "" };
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
function scalePos(v, sc) {
|
|
33
|
+
if (v == null) return 0;
|
|
34
|
+
const lg = (x) => Math.log10(Math.max(x, 1e-12));
|
|
35
|
+
const t = sc.log ? (lg(v) - lg(sc.min)) / (lg(sc.max) - lg(sc.min)) : (v - sc.min) / (sc.max - sc.min);
|
|
36
|
+
return Math.max(0, Math.min(1, t)) * 100;
|
|
37
|
+
}
|
|
38
|
+
function curveData(model, values, output) {
|
|
39
|
+
const input = model.inputs.find(i => i.name === model.sweep);
|
|
40
|
+
if (!input) return { path: '', min: null, max: null };
|
|
41
|
+
const points = Array.from({ length: 41 }, (_, k) => {
|
|
42
|
+
const x = input.min + (input.max - input.min) * k / 40;
|
|
43
|
+
return { x, y: evaluate(model, { ...values, [input.name]: x })[output]?.value };
|
|
44
|
+
});
|
|
45
|
+
const valid = points.filter(p => Number.isFinite(p.y));
|
|
46
|
+
if (!valid.length) return { path: '', min: null, max: null };
|
|
47
|
+
const lo = Math.min(...valid.map(p => p.y)), hi = Math.max(...valid.map(p => p.y));
|
|
48
|
+
let lift = true;
|
|
49
|
+
const path = points.map((p, k) => {
|
|
50
|
+
if (!Number.isFinite(p.y)) { lift = true; return ''; }
|
|
51
|
+
const command = lift ? 'M' : 'L'; lift = false;
|
|
52
|
+
return `${command}${(k * 8).toFixed(1)},${(75 - (p.y - lo) / (hi - lo || 1) * 70).toFixed(1)}`;
|
|
53
|
+
}).join(' ');
|
|
54
|
+
return { path, min: lo, max: hi };
|
|
55
|
+
}
|
|
56
|
+
const curve = (model, values, output) => curveData(model, values, output).path;
|
|
57
|
+
// na apresentação: mexeu no controle, recalcula e atualiza números, selos e ponteiros
|
|
58
|
+
function mount(doc) {
|
|
59
|
+
doc.querySelectorAll("[data-calc]:not([data-calc-ready])").forEach((rootEl) => {
|
|
60
|
+
rootEl.dataset.calcReady = "1";
|
|
61
|
+
const model = JSON.parse(rootEl.querySelector(".calc-model").textContent);
|
|
62
|
+
let frozen = null;
|
|
63
|
+
let previous = null;
|
|
64
|
+
const resultsEl = rootEl.querySelector('.calc-outputs');
|
|
65
|
+
const explain = rootEl.querySelector('[data-calc-explanation]');
|
|
66
|
+
const setValues = (v) => rootEl.querySelectorAll('[data-calc-in]').forEach(el => { el.value = v[el.dataset.calcIn] ?? model.inputs.find(i => i.name === el.dataset.calcIn).value; });
|
|
67
|
+
if (model.prediction) rootEl.classList.add('calc-unrevealed');
|
|
68
|
+
const values = () => Object.fromEntries([...rootEl.querySelectorAll("[data-calc-in]")].map((i) => [i.dataset.calcIn, Number(i.value)]));
|
|
69
|
+
const revealButton = rootEl.querySelector('[data-calc-reveal]');
|
|
70
|
+
const reveal = () => { rootEl.classList.remove('calc-unrevealed'); if (revealButton) { revealButton.textContent = 'Resultado revelado'; revealButton.disabled = true; } };
|
|
71
|
+
const redraw = () => {
|
|
72
|
+
const v = values(), res = evaluate(model, v);
|
|
73
|
+
for (const i of model.inputs) { const el = rootEl.querySelector(`[data-calc-show="${i.name}"]`); if (el) el.textContent = format(v[i.name], i); }
|
|
74
|
+
for (const o of model.outputs) {
|
|
75
|
+
const r = res[o.name];
|
|
76
|
+
const out = rootEl.querySelector(`[data-calc-out="${o.name}"]`); if (out) out.textContent = format(r.value, o);
|
|
77
|
+
if (out) out.classList.toggle('calc-changed', !!previous && previous[o.name]?.value !== r.value);
|
|
78
|
+
const comparison = rootEl.querySelector(`[data-calc-compare="${o.name}"]`);
|
|
79
|
+
if (comparison) {
|
|
80
|
+
comparison.hidden = !frozen;
|
|
81
|
+
comparison.textContent = frozen ? `Antes: ${format(frozen.results[o.name].value, o)} ${o.unit || ''} · Variação: ${format(r.value == null || frozen.results[o.name].value == null ? null : r.value - frozen.results[o.name].value, o)}` : '';
|
|
82
|
+
}
|
|
83
|
+
const b = rootEl.querySelector(`[data-calc-badge="${o.name}"]`); if (b) { b.textContent = r.text; b.style.background = r.color ? `var(--${r.color})` : ""; }
|
|
84
|
+
const ptr = rootEl.querySelector(`[data-calc-pointer="${o.name}"]`);
|
|
85
|
+
if (ptr && o.scale) ptr.style.left = `${scalePos(o.of ? res[o.of] ? res[o.of].value : v[o.of] : r.value, o.scale)}%`;
|
|
86
|
+
const path = rootEl.querySelector(`[data-calc-curve="${o.name}"]`);
|
|
87
|
+
if (path) {
|
|
88
|
+
const data = curveData(model, v, o.name);
|
|
89
|
+
path.setAttribute('d', data.path);
|
|
90
|
+
const axis = rootEl.querySelector(`[data-calc-axis="${o.name}"]`);
|
|
91
|
+
if (axis) axis.textContent = `${o.label}: ${format(data.min, o)} a ${format(data.max, o)} ${o.unit || ''} (escala automática)`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
previous = res;
|
|
95
|
+
rootEl.dispatchEvent(new CustomEvent('sagadeck:values', { bubbles: true, detail: { inputs: { ...v }, outputs: res } }));
|
|
96
|
+
// Comparação e explicação podem aumentar o painel depois da primeira montagem.
|
|
97
|
+
const slide = rootEl.closest('.slide');
|
|
98
|
+
if (slide && root.SagadeckFit) root.requestAnimationFrame(() => root.SagadeckFit.shrink(slide));
|
|
99
|
+
};
|
|
100
|
+
rootEl.querySelectorAll('button').forEach(button => {
|
|
101
|
+
['keydown', 'pointerdown', 'click'].forEach(ev => button.addEventListener(ev, e => e.stopPropagation()));
|
|
102
|
+
});
|
|
103
|
+
rootEl.querySelectorAll('[data-calc-scenario]').forEach(button => button.addEventListener('click', () => {
|
|
104
|
+
const scenario = model.scenarios[Number(button.dataset.calcScenario)];
|
|
105
|
+
setValues(scenario.values || {});
|
|
106
|
+
if (explain) explain.textContent = scenario.explanation || model.explanation;
|
|
107
|
+
rootEl.querySelectorAll('[data-calc-scenario]').forEach(b => b.setAttribute('aria-pressed', String(b === button)));
|
|
108
|
+
redraw();
|
|
109
|
+
}));
|
|
110
|
+
const freezeButton = rootEl.querySelector('[data-calc-freeze]');
|
|
111
|
+
freezeButton?.addEventListener('click', () => { frozen = { values: values(), results: evaluate(model, values()) }; freezeButton.textContent = 'Comparação fixada'; freezeButton.setAttribute('aria-pressed', 'true'); redraw(); });
|
|
112
|
+
rootEl.querySelector('[data-calc-reset]')?.addEventListener('click', () => {
|
|
113
|
+
frozen = null; previous = null; setValues({});
|
|
114
|
+
if (revealButton) { revealButton.textContent = 'Ver resultado'; revealButton.disabled = false; }
|
|
115
|
+
if (freezeButton) { freezeButton.textContent = 'Comparar com este'; freezeButton.setAttribute('aria-pressed', 'false'); }
|
|
116
|
+
rootEl.querySelectorAll('[data-calc-scenario]').forEach(b => b.setAttribute('aria-pressed', 'false'));
|
|
117
|
+
if (explain) explain.textContent = model.explanation;
|
|
118
|
+
rootEl.classList.toggle('calc-unrevealed', !!model.prediction); redraw();
|
|
119
|
+
});
|
|
120
|
+
revealButton?.addEventListener('click', reveal);
|
|
121
|
+
rootEl.querySelector('[data-calc-free]')?.addEventListener('click', () => { reveal(); if (explain) explain.textContent = `Modo livre: ajuste as entradas. ${model.explanation || ''}`; rootEl.querySelector('[data-calc-in]')?.focus(); });
|
|
122
|
+
rootEl.querySelectorAll("[data-calc-in]").forEach((inp) => {
|
|
123
|
+
const stop = (e) => e.stopPropagation(); // setas e cliques no controle não trocam de slide
|
|
124
|
+
["keydown", "pointerdown", "click"].forEach((ev) => inp.addEventListener(ev, stop));
|
|
125
|
+
inp.addEventListener("input", () => {
|
|
126
|
+
rootEl.querySelectorAll('[data-calc-scenario]').forEach(b => b.setAttribute('aria-pressed', 'false'));
|
|
127
|
+
if (explain) explain.textContent = model.explanation;
|
|
128
|
+
redraw();
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
redraw();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
root.SagaCalc = { evaluate, format, scalePos, curve, curveData, mount };
|
|
135
|
+
if (typeof document !== "undefined") {
|
|
136
|
+
const go = () => mount(document);
|
|
137
|
+
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", go) : go();
|
|
138
|
+
}
|
|
139
|
+
})(typeof globalThis !== "undefined" ? globalThis : window);
|