@brunoalz/smartgesti-site-editor 1.5.0 → 1.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.
Files changed (25) hide show
  1. package/dist/engine/export/exporters/layout/GridExporter.d.ts.map +1 -1
  2. package/dist/engine/export/exporters/layout/GridExporter.js +24 -22
  3. package/dist/engine/export/exporters/layout/GridExporter.js.map +1 -1
  4. package/dist/engine/export/exporters/layout/StackExporter.d.ts.map +1 -1
  5. package/dist/engine/export/exporters/layout/StackExporter.js +26 -14
  6. package/dist/engine/export/exporters/layout/StackExporter.js.map +1 -1
  7. package/dist/engine/plugins/builtin/blog/manifest.d.ts.map +1 -1
  8. package/dist/engine/plugins/builtin/blog/manifest.js +25 -16
  9. package/dist/engine/plugins/builtin/blog/manifest.js.map +1 -1
  10. package/dist/engine/registry/blocks/layout/grid.d.ts.map +1 -1
  11. package/dist/engine/registry/blocks/layout/grid.js +63 -7
  12. package/dist/engine/registry/blocks/layout/grid.js.map +1 -1
  13. package/dist/engine/registry/blocks/layout/stack.d.ts.map +1 -1
  14. package/dist/engine/registry/blocks/layout/stack.js +32 -3
  15. package/dist/engine/registry/blocks/layout/stack.js.map +1 -1
  16. package/dist/engine/render/renderers/layout/GridRenderer.d.ts.map +1 -1
  17. package/dist/engine/render/renderers/layout/GridRenderer.js +22 -20
  18. package/dist/engine/render/renderers/layout/GridRenderer.js.map +1 -1
  19. package/dist/engine/render/renderers/layout/StackRenderer.d.ts.map +1 -1
  20. package/dist/engine/render/renderers/layout/StackRenderer.js +36 -25
  21. package/dist/engine/render/renderers/layout/StackRenderer.js.map +1 -1
  22. package/dist/engine/schema/siteDocument.d.ts +10 -0
  23. package/dist/engine/schema/siteDocument.d.ts.map +1 -1
  24. package/dist/engine/schema/siteDocument.js.map +1 -1
  25. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GridExporter.d.ts","sourceRoot":"","sources":["../../../../../src/engine/export/exporters/layout/GridExporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAS1D,wBAAgB,UAAU,CACxB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,WAAW,EACnB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,KAAK,MAAM,GAC7F,MAAM,CA4CR"}
1
+ {"version":3,"file":"GridExporter.d.ts","sourceRoot":"","sources":["../../../../../src/engine/export/exporters/layout/GridExporter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAS1D,wBAAgB,UAAU,CACxB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,WAAW,EACnB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,KAAK,MAAM,GAC7F,MAAM,CAuER"}
@@ -1,35 +1,37 @@
1
- import { dataBlockIdAttr as l } from "../../shared/htmlHelpers.js";
2
- import { generateGridId as f } from "../../shared/idGenerator.js";
3
- import { resolveResponsiveColumns as g, generateResponsiveGridStyles as v, BREAKPOINTS as h } from "../../shared/responsiveGridHelper.js";
4
- function x(i, m, p, a, o) {
5
- const { cols: t = 3, colTemplate: s, gap: n = "1rem", children: c = [] } = i.props;
6
- if (!o)
1
+ import { dataBlockIdAttr as h } from "../../shared/htmlHelpers.js";
2
+ import { generateGridId as R } from "../../shared/idGenerator.js";
3
+ import { resolveResponsiveColumns as T, generateResponsiveGridStyles as j, BREAKPOINTS as A } from "../../shared/responsiveGridHelper.js";
4
+ function Q(e, f, y, v, n) {
5
+ const { cols: r = 3, colTemplate: o, gap: p = "1rem", maxWidth: a, padding: s, paddingTop: l, children: w = [] } = e.props;
6
+ if (!n)
7
7
  throw new Error("exportGrid requires renderChild function");
8
- const e = f(i.id || ""), d = c.map((r) => o(r, m + 1, p, a)).join("");
9
- if (s) {
10
- const r = `display: grid; gap: ${n};`;
11
- return `<style>${`
8
+ const i = R(e.id || ""), m = w.map((d) => n(d, f + 1, y, v)).join(""), t = [];
9
+ a && (t.push(`max-width: ${a}`), t.push("margin-left: auto"), t.push("margin-right: auto")), s && (t.push(`padding-left: ${s}`), t.push(`padding-right: ${s}`)), l && t.push(`padding-top: ${l}`);
10
+ const $ = t.length > 0, c = t.join("; ");
11
+ if (o) {
12
+ const d = `display: grid; gap: ${p};`, I = `
12
13
  /* Base: Mobile 1 coluna */
13
- #${e} {
14
+ #${i} {
14
15
  grid-template-columns: 1fr;
15
16
  }
16
17
 
17
18
  /* Desktop: template customizado */
18
- @media (min-width: ${h.md}) {
19
- #${e} {
20
- grid-template-columns: ${s};
19
+ @media (min-width: ${A.md}) {
20
+ #${i} {
21
+ grid-template-columns: ${o};
21
22
  }
22
23
  }
23
- `.trim()}</style><div id="${e}" ${l(i.id)} style="${r}">${d}</div>`;
24
+ `.trim(), u = `<div id="${i}" ${h(e.id)} style="${d}">${m}</div>`, B = $ ? `<div style="${c}">${u}</div>` : u;
25
+ return `<style>${I}</style>${B}`;
24
26
  }
25
- const $ = g(t, 1, 2, typeof t == "number" ? t : 3), { inlineStyles: u, mediaQueries: y } = v(
26
- e,
27
- $,
28
- n
29
- );
30
- return `<style>${y}</style><div id="${e}" ${l(i.id)} style="${u}">${d}</div>`;
27
+ const x = T(r, 1, 2, typeof r == "number" ? r : 3), { inlineStyles: H, mediaQueries: S } = j(
28
+ i,
29
+ x,
30
+ p
31
+ ), g = `<div id="${i}" ${h(e.id)} style="${H}">${m}</div>`, G = $ ? `<div style="${c}">${g}</div>` : g;
32
+ return `<style>${S}</style>${G}`;
31
33
  }
32
34
  export {
33
- x as exportGrid
35
+ Q as exportGrid
34
36
  };
35
37
  //# sourceMappingURL=GridExporter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GridExporter.js","sources":["../../../../../src/engine/export/exporters/layout/GridExporter.ts"],"sourcesContent":["/**\n * Grid Block Exporter\n * Sistema responsivo mobile-first com media queries\n * Suporte a colTemplate para templates customizados (ex: \"1fr 320px\")\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr } from \"../../shared/htmlHelpers\";\nimport { generateGridId } from \"../../shared/idGenerator\";\nimport {\n resolveResponsiveColumns,\n generateResponsiveGridStyles,\n BREAKPOINTS,\n} from \"../../shared/responsiveGridHelper\";\n\nexport function exportGrid(\n block: Block,\n depth: number,\n basePath?: string,\n theme?: ThemeTokens,\n renderChild?: (block: Block, _depth: number, basePath?: string, theme?: ThemeTokens) => string,\n): string {\n const { cols = 3, colTemplate, gap = \"1rem\", children = [] } = (block as any).props;\n\n if (!renderChild) {\n throw new Error(\"exportGrid requires renderChild function\");\n }\n\n // Gerar ID único para este grid\n const gridId = generateGridId(block.id || \"\");\n\n // Renderizar filhos\n const childrenHtml = children\n .map((c: Block) => renderChild(c, depth + 1, basePath, theme))\n .join(\"\");\n\n // Se colTemplate está definido, usar template customizado com responsive\n if (colTemplate) {\n const inlineStyles = `display: grid; gap: ${gap};`;\n const mediaQueries = `\n /* Base: Mobile 1 coluna */\n #${gridId} {\n grid-template-columns: 1fr;\n }\n\n /* Desktop: template customizado */\n @media (min-width: ${BREAKPOINTS.md}) {\n #${gridId} {\n grid-template-columns: ${colTemplate};\n }\n }\n `.trim();\n\n return `<style>${mediaQueries}</style><div id=\"${gridId}\" ${dataBlockIdAttr(block.id)} style=\"${inlineStyles}\">${childrenHtml}</div>`;\n }\n\n // Comportamento padrão: resolver configuração responsiva\n const responsiveConfig = resolveResponsiveColumns(cols, 1, 2, typeof cols === \"number\" ? cols : 3);\n const { inlineStyles, mediaQueries } = generateResponsiveGridStyles(\n gridId,\n responsiveConfig,\n gap,\n );\n\n return `<style>${mediaQueries}</style><div id=\"${gridId}\" ${dataBlockIdAttr(block.id)} style=\"${inlineStyles}\">${childrenHtml}</div>`;\n}\n"],"names":["exportGrid","block","depth","basePath","theme","renderChild","cols","colTemplate","gap","children","gridId","generateGridId","childrenHtml","c","inlineStyles","BREAKPOINTS","dataBlockIdAttr","responsiveConfig","resolveResponsiveColumns","mediaQueries","generateResponsiveGridStyles"],"mappings":";;;AAgBO,SAASA,EACdC,GACAC,GACAC,GACAC,GACAC,GACQ;AACR,QAAM,EAAE,MAAAC,IAAO,GAAG,aAAAC,GAAa,KAAAC,IAAM,QAAQ,UAAAC,IAAW,CAAA,MAAQR,EAAc;AAE9E,MAAI,CAACI;AACH,UAAM,IAAI,MAAM,0CAA0C;AAI5D,QAAMK,IAASC,EAAeV,EAAM,MAAM,EAAE,GAGtCW,IAAeH,EAClB,IAAI,CAACI,MAAaR,EAAYQ,GAAGX,IAAQ,GAAGC,GAAUC,CAAK,CAAC,EAC5D,KAAK,EAAE;AAGV,MAAIG,GAAa;AACf,UAAMO,IAAe,uBAAuBN,CAAG;AAe/C,WAAO,UAdc;AAAA;AAAA,OAElBE,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA,yBAKYK,EAAY,EAAE;AAAA,SAC9BL,CAAM;AAAA,iCACkBH,CAAW;AAAA;AAAA;AAAA,IAGxC,KAAA,CAE6B,oBAAoBG,CAAM,KAAKM,EAAgBf,EAAM,EAAE,CAAC,WAAWa,CAAY,KAAKF,CAAY;AAAA,EAC/H;AAGA,QAAMK,IAAmBC,EAAyBZ,GAAM,GAAG,GAAG,OAAOA,KAAS,WAAWA,IAAO,CAAC,GAC3F,EAAE,cAAAQ,GAAc,cAAAK,EAAA,IAAiBC;AAAA,IACrCV;AAAA,IACAO;AAAA,IACAT;AAAA,EAAA;AAGF,SAAO,UAAUW,CAAY,oBAAoBT,CAAM,KAAKM,EAAgBf,EAAM,EAAE,CAAC,WAAWa,CAAY,KAAKF,CAAY;AAC/H;"}
1
+ {"version":3,"file":"GridExporter.js","sources":["../../../../../src/engine/export/exporters/layout/GridExporter.ts"],"sourcesContent":["/**\n * Grid Block Exporter\n * Sistema responsivo mobile-first com media queries\n * Suporte a colTemplate para templates customizados (ex: \"1fr 320px\")\n * Suporte a maxWidth e padding para espaçamento\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr } from \"../../shared/htmlHelpers\";\nimport { generateGridId } from \"../../shared/idGenerator\";\nimport {\n resolveResponsiveColumns,\n generateResponsiveGridStyles,\n BREAKPOINTS,\n} from \"../../shared/responsiveGridHelper\";\n\nexport function exportGrid(\n block: Block,\n depth: number,\n basePath?: string,\n theme?: ThemeTokens,\n renderChild?: (block: Block, _depth: number, basePath?: string, theme?: ThemeTokens) => string,\n): string {\n const { cols = 3, colTemplate, gap = \"1rem\", maxWidth, padding, paddingTop, children = [] } = (block as any).props;\n\n if (!renderChild) {\n throw new Error(\"exportGrid requires renderChild function\");\n }\n\n // Gerar ID único para este grid\n const gridId = generateGridId(block.id || \"\");\n\n // Renderizar filhos\n const childrenHtml = children\n .map((c: Block) => renderChild(c, depth + 1, basePath, theme))\n .join(\"\");\n\n // Wrapper styles for maxWidth + padding\n const wrapperParts: string[] = [];\n if (maxWidth) {\n wrapperParts.push(`max-width: ${maxWidth}`);\n wrapperParts.push(\"margin-left: auto\");\n wrapperParts.push(\"margin-right: auto\");\n }\n if (padding) {\n wrapperParts.push(`padding-left: ${padding}`);\n wrapperParts.push(`padding-right: ${padding}`);\n }\n if (paddingTop) {\n wrapperParts.push(`padding-top: ${paddingTop}`);\n }\n const hasWrapper = wrapperParts.length > 0;\n const wrapperStyle = wrapperParts.join(\"; \");\n\n // Se colTemplate está definido, usar template customizado com responsive\n if (colTemplate) {\n const inlineStyles = `display: grid; gap: ${gap};`;\n const mediaQueries = `\n /* Base: Mobile 1 coluna */\n #${gridId} {\n grid-template-columns: 1fr;\n }\n\n /* Desktop: template customizado */\n @media (min-width: ${BREAKPOINTS.md}) {\n #${gridId} {\n grid-template-columns: ${colTemplate};\n }\n }\n `.trim();\n\n const gridHtml = `<div id=\"${gridId}\" ${dataBlockIdAttr(block.id)} style=\"${inlineStyles}\">${childrenHtml}</div>`;\n const wrappedHtml = hasWrapper\n ? `<div style=\"${wrapperStyle}\">${gridHtml}</div>`\n : gridHtml;\n\n return `<style>${mediaQueries}</style>${wrappedHtml}`;\n }\n\n // Comportamento padrão: resolver configuração responsiva\n const responsiveConfig = resolveResponsiveColumns(cols, 1, 2, typeof cols === \"number\" ? cols : 3);\n const { inlineStyles, mediaQueries } = generateResponsiveGridStyles(\n gridId,\n responsiveConfig,\n gap,\n );\n\n const gridHtml = `<div id=\"${gridId}\" ${dataBlockIdAttr(block.id)} style=\"${inlineStyles}\">${childrenHtml}</div>`;\n const wrappedHtml = hasWrapper\n ? `<div style=\"${wrapperStyle}\">${gridHtml}</div>`\n : gridHtml;\n\n return `<style>${mediaQueries}</style>${wrappedHtml}`;\n}\n"],"names":["exportGrid","block","depth","basePath","theme","renderChild","cols","colTemplate","gap","maxWidth","padding","paddingTop","children","gridId","generateGridId","childrenHtml","c","wrapperParts","hasWrapper","wrapperStyle","inlineStyles","mediaQueries","BREAKPOINTS","gridHtml","dataBlockIdAttr","wrappedHtml","responsiveConfig","resolveResponsiveColumns","generateResponsiveGridStyles"],"mappings":";;;AAiBO,SAASA,EACdC,GACAC,GACAC,GACAC,GACAC,GACQ;AACR,QAAM,EAAE,MAAAC,IAAO,GAAG,aAAAC,GAAa,KAAAC,IAAM,QAAQ,UAAAC,GAAU,SAAAC,GAAS,YAAAC,GAAY,UAAAC,IAAW,CAAA,EAAC,IAAOX,EAAc;AAE7G,MAAI,CAACI;AACH,UAAM,IAAI,MAAM,0CAA0C;AAI5D,QAAMQ,IAASC,EAAeb,EAAM,MAAM,EAAE,GAGtCc,IAAeH,EAClB,IAAI,CAACI,MAAaX,EAAYW,GAAGd,IAAQ,GAAGC,GAAUC,CAAK,CAAC,EAC5D,KAAK,EAAE,GAGJa,IAAyB,CAAA;AAC/B,EAAIR,MACFQ,EAAa,KAAK,cAAcR,CAAQ,EAAE,GAC1CQ,EAAa,KAAK,mBAAmB,GACrCA,EAAa,KAAK,oBAAoB,IAEpCP,MACFO,EAAa,KAAK,iBAAiBP,CAAO,EAAE,GAC5CO,EAAa,KAAK,kBAAkBP,CAAO,EAAE,IAE3CC,KACFM,EAAa,KAAK,gBAAgBN,CAAU,EAAE;AAEhD,QAAMO,IAAaD,EAAa,SAAS,GACnCE,IAAeF,EAAa,KAAK,IAAI;AAG3C,MAAIV,GAAa;AACf,UAAMa,IAAe,uBAAuBZ,CAAG,KACzCa,IAAe;AAAA;AAAA,OAElBR,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA,yBAKYS,EAAY,EAAE;AAAA,SAC9BT,CAAM;AAAA,iCACkBN,CAAW;AAAA;AAAA;AAAA,IAGxC,KAAA,GAEMgB,IAAW,YAAYV,CAAM,KAAKW,EAAgBvB,EAAM,EAAE,CAAC,WAAWmB,CAAY,KAAKL,CAAY,UACnGU,IAAcP,IAChB,eAAeC,CAAY,KAAKI,CAAQ,WACxCA;AAEJ,WAAO,UAAUF,CAAY,WAAWI,CAAW;AAAA,EACrD;AAGA,QAAMC,IAAmBC,EAAyBrB,GAAM,GAAG,GAAG,OAAOA,KAAS,WAAWA,IAAO,CAAC,GAC3F,EAAE,cAAAc,GAAc,cAAAC,EAAA,IAAiBO;AAAA,IACrCf;AAAA,IACAa;AAAA,IACAlB;AAAA,EAAA,GAGIe,IAAW,YAAYV,CAAM,KAAKW,EAAgBvB,EAAM,EAAE,CAAC,WAAWmB,CAAY,KAAKL,CAAY,UACnGU,IAAcP,IAChB,eAAeC,CAAY,KAAKI,CAAQ,WACxCA;AAEJ,SAAO,UAAUF,CAAY,WAAWI,CAAW;AACrD;"}
@@ -1 +1 @@
1
- {"version":3,"file":"StackExporter.d.ts","sourceRoot":"","sources":["../../../../../src/engine/export/exporters/layout/StackExporter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAK1D,wBAAgB,WAAW,CACzB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,WAAW,EACnB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,KAAK,MAAM,GAC7F,MAAM,CAsDR"}
1
+ {"version":3,"file":"StackExporter.d.ts","sourceRoot":"","sources":["../../../../../src/engine/export/exporters/layout/StackExporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAK1D,wBAAgB,WAAW,CACzB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,WAAW,EACnB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,KAAK,MAAM,GAC7F,MAAM,CAuER"}
@@ -1,21 +1,33 @@
1
- import { dataBlockIdAttr as p } from "../../shared/htmlHelpers.js";
1
+ import { dataBlockIdAttr as f } from "../../shared/htmlHelpers.js";
2
2
  import { generateScopedId as v } from "../../shared/idGenerator.js";
3
- import { generateFlexDirectionMediaQueries as I } from "../../shared/responsiveGridHelper.js";
4
- function F(e, f, m, u, n) {
3
+ import { generateFlexDirectionMediaQueries as D, BREAKPOINTS as A } from "../../shared/responsiveGridHelper.js";
4
+ function M(t, m, $, x, s) {
5
5
  const {
6
- direction: i = "col",
7
- gap: $ = "1rem",
8
- align: r = "stretch",
9
- justify: t = "start",
10
- wrap: w = !1,
11
- children: x = []
12
- } = e.props;
13
- if (!n)
6
+ direction: o = "col",
7
+ gap: u = "1rem",
8
+ align: i = "stretch",
9
+ justify: e = "start",
10
+ wrap: y = !1,
11
+ sticky: c = !1,
12
+ stickyOffset: w = "80px",
13
+ children: g = []
14
+ } = t.props;
15
+ if (!s)
14
16
  throw new Error("exportStack requires renderChild function");
15
- const o = v(e.id || "", "stack"), s = i === "row", c = "column", y = i === "row" ? "row" : "column", g = r === "start" ? "flex-start" : r === "end" ? "flex-end" : r === "center" ? "center" : "stretch", h = t === "start" ? "flex-start" : t === "end" ? "flex-end" : t === "center" ? "center" : t === "space-between" ? "space-between" : "space-around", a = s ? I(o, c, y) : "", d = x.map((j) => n(j, f + 1, m, u)).join(""), l = `display: flex; flex-direction: ${c}; gap: ${$}; align-items: ${g}; justify-content: ${h}; flex-wrap: ${w ? "wrap" : "nowrap"};`;
16
- return a ? `<style>${a}</style><div id="${o}" ${p(e.id)} style="${l}">${d}</div>` : `<div ${p(e.id)} style="${l}">${d}</div>`;
17
+ const n = v(t.id || "", "stack"), a = o === "row", l = "column", h = o === "row" ? "row" : "column", k = i === "start" ? "flex-start" : i === "end" ? "flex-end" : i === "center" ? "center" : "stretch", I = e === "start" ? "flex-start" : e === "end" ? "flex-end" : e === "center" ? "center" : e === "space-between" ? "space-between" : "space-around";
18
+ let r = a ? D(n, l, h) : "";
19
+ const S = c ? ` position: sticky; top: ${w}; align-self: flex-start;` : "";
20
+ c && (r += `
21
+ @media (max-width: ${A.md}) {
22
+ #${n} {
23
+ position: static !important;
24
+ align-self: stretch !important;
25
+ }
26
+ }`);
27
+ const d = g.map((j) => s(j, m + 1, $, x)).join(""), p = `display: flex; flex-direction: ${l}; gap: ${u}; align-items: ${k}; justify-content: ${I}; flex-wrap: ${y ? "wrap" : "nowrap"};${S}`;
28
+ return r ? `<style>${r}</style><div id="${n}" ${f(t.id)} style="${p}">${d}</div>` : `<div ${f(t.id)} style="${p}">${d}</div>`;
17
29
  }
18
30
  export {
19
- F as exportStack
31
+ M as exportStack
20
32
  };
21
33
  //# sourceMappingURL=StackExporter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StackExporter.js","sources":["../../../../../src/engine/export/exporters/layout/StackExporter.ts"],"sourcesContent":["/**\n * Stack Block Exporter\n * Responsive direction: column (mobile) → row (desktop) when direction=\"row\"\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr } from \"../../shared/htmlHelpers\";\nimport { generateScopedId } from \"../../shared/idGenerator\";\nimport { generateFlexDirectionMediaQueries, BREAKPOINTS } from \"../../shared/responsiveGridHelper\";\n\nexport function exportStack(\n block: Block,\n depth: number,\n basePath?: string,\n theme?: ThemeTokens,\n renderChild?: (block: Block, _depth: number, basePath?: string, theme?: ThemeTokens) => string,\n): string {\n const {\n direction = \"col\",\n gap = \"1rem\",\n align = \"stretch\",\n justify = \"start\",\n wrap = false,\n children = [],\n } = (block as any).props;\n\n if (!renderChild) {\n throw new Error(\"exportStack requires renderChild function\");\n }\n\n const stackId = generateScopedId(block.id || \"\", \"stack\");\n\n // Mobile-first: se direction=\"row\", começa column em mobile e vira row em desktop\n const isMobileFirst = direction === \"row\";\n const mobileDirection = isMobileFirst ? \"column\" : \"column\";\n const desktopDirection = direction === \"row\" ? \"row\" : \"column\";\n\n const alignItems =\n align === \"start\"\n ? \"flex-start\"\n : align === \"end\"\n ? \"flex-end\"\n : align === \"center\"\n ? \"center\"\n : \"stretch\";\n const justifyContent =\n justify === \"start\"\n ? \"flex-start\"\n : justify === \"end\"\n ? \"flex-end\"\n : justify === \"center\"\n ? \"center\"\n : justify === \"space-between\"\n ? \"space-between\"\n : \"space-around\";\n\n // Media queries apenas se for responsivo (row em desktop)\n const mediaQueries = isMobileFirst\n ? generateFlexDirectionMediaQueries(stackId, mobileDirection as any, desktopDirection as any)\n : \"\";\n\n const childrenHtml = children\n .map((c: Block) => renderChild(c, depth + 1, basePath, theme))\n .join(\"\");\n\n const inlineStyles = `display: flex; flex-direction: ${mobileDirection}; gap: ${gap}; align-items: ${alignItems}; justify-content: ${justifyContent}; flex-wrap: ${wrap ? \"wrap\" : \"nowrap\"};`;\n\n return mediaQueries\n ? `<style>${mediaQueries}</style><div id=\"${stackId}\" ${dataBlockIdAttr(block.id)} style=\"${inlineStyles}\">${childrenHtml}</div>`\n : `<div ${dataBlockIdAttr(block.id)} style=\"${inlineStyles}\">${childrenHtml}</div>`;\n}\n"],"names":["exportStack","block","depth","basePath","theme","renderChild","direction","gap","align","justify","wrap","children","stackId","generateScopedId","isMobileFirst","mobileDirection","desktopDirection","alignItems","justifyContent","mediaQueries","generateFlexDirectionMediaQueries","childrenHtml","c","inlineStyles","dataBlockIdAttr"],"mappings":";;;AAWO,SAASA,EACdC,GACAC,GACAC,GACAC,GACAC,GACQ;AACR,QAAM;AAAA,IACJ,WAAAC,IAAY;AAAA,IACZ,KAAAC,IAAM;AAAA,IACN,OAAAC,IAAQ;AAAA,IACR,SAAAC,IAAU;AAAA,IACV,MAAAC,IAAO;AAAA,IACP,UAAAC,IAAW,CAAA;AAAA,EAAC,IACTV,EAAc;AAEnB,MAAI,CAACI;AACH,UAAM,IAAI,MAAM,2CAA2C;AAG7D,QAAMO,IAAUC,EAAiBZ,EAAM,MAAM,IAAI,OAAO,GAGlDa,IAAgBR,MAAc,OAC9BS,IAAkC,UAClCC,IAAmBV,MAAc,QAAQ,QAAQ,UAEjDW,IACJT,MAAU,UACN,eACAA,MAAU,QACR,aACAA,MAAU,WACR,WACA,WACJU,IACJT,MAAY,UACR,eACAA,MAAY,QACV,aACAA,MAAY,WACV,WACAA,MAAY,kBACV,kBACA,gBAGNU,IAAeL,IACjBM,EAAkCR,GAASG,GAAwBC,CAAuB,IAC1F,IAEEK,IAAeV,EAClB,IAAI,CAACW,MAAajB,EAAYiB,GAAGpB,IAAQ,GAAGC,GAAUC,CAAK,CAAC,EAC5D,KAAK,EAAE,GAEJmB,IAAe,kCAAkCR,CAAe,UAAUR,CAAG,kBAAkBU,CAAU,sBAAsBC,CAAc,gBAAgBR,IAAO,SAAS,QAAQ;AAE3L,SAAOS,IACH,UAAUA,CAAY,oBAAoBP,CAAO,KAAKY,EAAgBvB,EAAM,EAAE,CAAC,WAAWsB,CAAY,KAAKF,CAAY,WACvH,QAAQG,EAAgBvB,EAAM,EAAE,CAAC,WAAWsB,CAAY,KAAKF,CAAY;AAC/E;"}
1
+ {"version":3,"file":"StackExporter.js","sources":["../../../../../src/engine/export/exporters/layout/StackExporter.ts"],"sourcesContent":["/**\n * Stack Block Exporter\n * Responsive direction: column (mobile) → row (desktop) when direction=\"row\"\n * Suporte a sticky positioning para sidebars\n */\n\nimport { Block } from \"../../../schema/siteDocument\";\nimport { ThemeTokens } from \"../../../schema/themeTokens\";\nimport { dataBlockIdAttr } from \"../../shared/htmlHelpers\";\nimport { generateScopedId } from \"../../shared/idGenerator\";\nimport { generateFlexDirectionMediaQueries, BREAKPOINTS } from \"../../shared/responsiveGridHelper\";\n\nexport function exportStack(\n block: Block,\n depth: number,\n basePath?: string,\n theme?: ThemeTokens,\n renderChild?: (block: Block, _depth: number, basePath?: string, theme?: ThemeTokens) => string,\n): string {\n const {\n direction = \"col\",\n gap = \"1rem\",\n align = \"stretch\",\n justify = \"start\",\n wrap = false,\n sticky = false,\n stickyOffset = \"80px\",\n children = [],\n } = (block as any).props;\n\n if (!renderChild) {\n throw new Error(\"exportStack requires renderChild function\");\n }\n\n const stackId = generateScopedId(block.id || \"\", \"stack\");\n\n // Mobile-first: se direction=\"row\", começa column em mobile e vira row em desktop\n const isMobileFirst = direction === \"row\";\n const mobileDirection = isMobileFirst ? \"column\" : \"column\";\n const desktopDirection = direction === \"row\" ? \"row\" : \"column\";\n\n const alignItems =\n align === \"start\"\n ? \"flex-start\"\n : align === \"end\"\n ? \"flex-end\"\n : align === \"center\"\n ? \"center\"\n : \"stretch\";\n const justifyContent =\n justify === \"start\"\n ? \"flex-start\"\n : justify === \"end\"\n ? \"flex-end\"\n : justify === \"center\"\n ? \"center\"\n : justify === \"space-between\"\n ? \"space-between\"\n : \"space-around\";\n\n // Media queries for responsive direction\n let mediaQueries = isMobileFirst\n ? generateFlexDirectionMediaQueries(stackId, mobileDirection as any, desktopDirection as any)\n : \"\";\n\n // Sticky: add position sticky on desktop, disable on mobile\n const stickyInline = sticky\n ? ` position: sticky; top: ${stickyOffset}; align-self: flex-start;`\n : \"\";\n\n if (sticky) {\n mediaQueries += `\n @media (max-width: ${BREAKPOINTS.md}) {\n #${stackId} {\n position: static !important;\n align-self: stretch !important;\n }\n }`;\n }\n\n const childrenHtml = children\n .map((c: Block) => renderChild(c, depth + 1, basePath, theme))\n .join(\"\");\n\n const inlineStyles = `display: flex; flex-direction: ${mobileDirection}; gap: ${gap}; align-items: ${alignItems}; justify-content: ${justifyContent}; flex-wrap: ${wrap ? \"wrap\" : \"nowrap\"};${stickyInline}`;\n\n return mediaQueries\n ? `<style>${mediaQueries}</style><div id=\"${stackId}\" ${dataBlockIdAttr(block.id)} style=\"${inlineStyles}\">${childrenHtml}</div>`\n : `<div ${dataBlockIdAttr(block.id)} style=\"${inlineStyles}\">${childrenHtml}</div>`;\n}\n"],"names":["exportStack","block","depth","basePath","theme","renderChild","direction","gap","align","justify","wrap","sticky","stickyOffset","children","stackId","generateScopedId","isMobileFirst","mobileDirection","desktopDirection","alignItems","justifyContent","mediaQueries","generateFlexDirectionMediaQueries","stickyInline","BREAKPOINTS","childrenHtml","c","inlineStyles","dataBlockIdAttr"],"mappings":";;;AAYO,SAASA,EACdC,GACAC,GACAC,GACAC,GACAC,GACQ;AACR,QAAM;AAAA,IACJ,WAAAC,IAAY;AAAA,IACZ,KAAAC,IAAM;AAAA,IACN,OAAAC,IAAQ;AAAA,IACR,SAAAC,IAAU;AAAA,IACV,MAAAC,IAAO;AAAA,IACP,QAAAC,IAAS;AAAA,IACT,cAAAC,IAAe;AAAA,IACf,UAAAC,IAAW,CAAA;AAAA,EAAC,IACTZ,EAAc;AAEnB,MAAI,CAACI;AACH,UAAM,IAAI,MAAM,2CAA2C;AAG7D,QAAMS,IAAUC,EAAiBd,EAAM,MAAM,IAAI,OAAO,GAGlDe,IAAgBV,MAAc,OAC9BW,IAAkC,UAClCC,IAAmBZ,MAAc,QAAQ,QAAQ,UAEjDa,IACJX,MAAU,UACN,eACAA,MAAU,QACR,aACAA,MAAU,WACR,WACA,WACJY,IACJX,MAAY,UACR,eACAA,MAAY,QACV,aACAA,MAAY,WACV,WACAA,MAAY,kBACV,kBACA;AAGZ,MAAIY,IAAeL,IACfM,EAAkCR,GAASG,GAAwBC,CAAuB,IAC1F;AAGJ,QAAMK,IAAeZ,IACjB,2BAA2BC,CAAY,8BACvC;AAEJ,EAAID,MACFU,KAAgB;AAAA,yBACKG,EAAY,EAAE;AAAA,SAC9BV,CAAO;AAAA;AAAA;AAAA;AAAA;AAOd,QAAMW,IAAeZ,EAClB,IAAI,CAACa,MAAarB,EAAYqB,GAAGxB,IAAQ,GAAGC,GAAUC,CAAK,CAAC,EAC5D,KAAK,EAAE,GAEJuB,IAAe,kCAAkCV,CAAe,UAAUV,CAAG,kBAAkBY,CAAU,sBAAsBC,CAAc,gBAAgBV,IAAO,SAAS,QAAQ,IAAIa,CAAY;AAE3M,SAAOF,IACH,UAAUA,CAAY,oBAAoBP,CAAO,KAAKc,EAAgB3B,EAAM,EAAE,CAAC,WAAW0B,CAAY,KAAKF,CAAY,WACvH,QAAQG,EAAgB3B,EAAM,EAAE,CAAC,WAAW0B,CAAY,KAAKF,CAAY;AAC/E;"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../../src/engine/plugins/builtin/blog/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAqFtD,eAAO,MAAM,UAAU,EAAE,kBAqdxB,CAAC"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../../src/engine/plugins/builtin/blog/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAqFtD,eAAO,MAAM,UAAU,EAAE,kBA8dxB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { pluginRegistry as f } from "../../pluginRegistry.js";
2
- import { logger as d } from "../../../../utils/logger.js";
2
+ import { logger as p } from "../../../../utils/logger.js";
3
3
  const m = "plugin-blog-home-grid", c = [
4
4
  {
5
5
  title: "Feira de Ciências 2026: Inovação e Criatividade",
@@ -128,19 +128,19 @@ const y = {
128
128
  }
129
129
  },
130
130
  onActivate(t) {
131
- d.debug("Blog plugin activating...");
131
+ p.debug("Blog plugin activating...");
132
132
  const n = new Set(t.pages.map((e) => e.id)), o = [...t.pages], i = t.pages.find((e) => e.slug === "home") || t.pages[0], l = i?.structure.find((e) => e.type === "navbar"), r = i?.structure.find((e) => e.type === "footer");
133
133
  if (i && l) {
134
134
  const e = o.findIndex((a) => a.id === i.id);
135
135
  if (e >= 0) {
136
136
  const a = l.props, s = Array.isArray(a.links) ? [...a.links] : [];
137
137
  if (!s.some(
138
- (p) => p.href === "/p/blog"
138
+ (d) => d.href === "/p/blog"
139
139
  )) {
140
- const p = s.length > 0 ? s.length - 1 : 0;
141
- s.splice(p, 0, { text: "Blog", href: "/p/blog" });
140
+ const d = s.length > 0 ? s.length - 1 : 0;
141
+ s.splice(d, 0, { text: "Blog", href: "/p/blog" });
142
142
  const h = o[e].structure.map((u) => u.id === l.id ? { ...u, props: { ...u.props, links: s } } : u);
143
- o[e] = { ...o[e], structure: h }, d.debug("Blog link added to home navbar"), l.props = { ...a, links: s };
143
+ o[e] = { ...o[e], structure: h }, p.debug("Blog link added to home navbar"), l.props = { ...a, links: s };
144
144
  }
145
145
  }
146
146
  }
@@ -162,13 +162,13 @@ const y = {
162
162
  viewAllText: "Ver todos os posts",
163
163
  viewAllHref: "/site/p/blog"
164
164
  }
165
- }, g = [...o[e].structure], p = g.findIndex(
165
+ }, g = [...o[e].structure], d = g.findIndex(
166
166
  (h) => h.type === "footer"
167
167
  );
168
- p >= 0 ? g.splice(p, 0, s) : g.push(s), o[e] = {
168
+ d >= 0 ? g.splice(d, 0, s) : g.push(s), o[e] = {
169
169
  ...o[e],
170
170
  structure: g
171
- }, d.debug("Blog section injected into home page");
171
+ }, p.debug("Blog section injected into home page");
172
172
  }
173
173
  }
174
174
  if (!n.has("blog")) {
@@ -237,16 +237,23 @@ const y = {
237
237
  mode: "list",
238
238
  defaultParams: { limit: 15 }
239
239
  }
240
- }), d.debug("Blog listing page created");
240
+ }), p.debug("Blog listing page created");
241
241
  }
242
242
  if (!n.has("blog-post")) {
243
243
  const e = [];
244
- l && e.push(b(l, "post-page-navbar")), e.push({
244
+ if (l) {
245
+ const a = b(l, "post-page-navbar");
246
+ a.props.sticky = !0, e.push(a);
247
+ }
248
+ e.push({
245
249
  id: "blog-detail-layout",
246
250
  type: "grid",
247
251
  props: {
248
252
  colTemplate: "1fr 320px",
249
- gap: "2rem",
253
+ gap: "2.5rem",
254
+ maxWidth: "1200px",
255
+ padding: "2rem",
256
+ paddingTop: "6rem",
250
257
  children: [
251
258
  // Coluna principal: blogPostDetail
252
259
  {
@@ -269,13 +276,15 @@ const y = {
269
276
  contentMaxWidth: "720px"
270
277
  }
271
278
  },
272
- // Sidebar: stack vertical com widgets
279
+ // Sidebar: stack vertical com widgets (sticky por padrão)
273
280
  {
274
281
  id: "blog-detail-sidebar",
275
282
  type: "stack",
276
283
  props: {
277
284
  direction: "col",
278
285
  gap: "1.5rem",
286
+ sticky: !0,
287
+ stickyOffset: "80px",
279
288
  children: [
280
289
  {
281
290
  id: "blog-sidebar-search",
@@ -357,7 +366,7 @@ const y = {
357
366
  editRestrictions: {
358
367
  nonRemovable: !0
359
368
  }
360
- }), d.debug("Blog post detail page created with sidebar layout");
369
+ }), p.debug("Blog post detail page created with sidebar layout");
361
370
  }
362
371
  return {
363
372
  ...t,
@@ -365,7 +374,7 @@ const y = {
365
374
  };
366
375
  },
367
376
  onDeactivate(t) {
368
- d.debug("Blog plugin deactivating...");
377
+ p.debug("Blog plugin deactivating...");
369
378
  const n = t.pages.filter((o) => o.pluginId !== "blog").map((o) => {
370
379
  let i = o.structure;
371
380
  return i.some(
@@ -378,7 +387,7 @@ const y = {
378
387
  return s.length !== a.length ? { ...r, props: { ...e, links: s } } : r;
379
388
  }), i !== o.structure ? { ...o, structure: i } : o;
380
389
  });
381
- return d.debug(
390
+ return p.debug(
382
391
  `Removed ${t.pages.length - n.length} blog page(s) and injected section`
383
392
  ), {
384
393
  ...t,
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sources":["../../../../../src/engine/plugins/builtin/blog/manifest.ts"],"sourcesContent":["/**\n * Blog Plugin Manifest\n * Plugin para blog com posts, categorias e tags.\n *\n * onActivate:\n * 1. Injeta seção blogPostGrid na home page (antes do footer)\n * 2. Cria página \"Blog\" com navbar + grid de posts + footer\n * 3. Cria página \"Post\" com navbar + detalhe do post + footer\n *\n * onDeactivate:\n * 1. Remove a seção injetada na home page\n * 2. Remove as páginas do plugin\n */\n\nimport type { PluginRegistration } from \"../../types\";\nimport type { SiteDocument, Block, BlockType } from \"../../../schema/siteDocument\";\nimport { pluginRegistry } from \"../../pluginRegistry\";\nimport { logger } from \"../../../../utils/logger\";\n\n// ─── ID usado para a seção de blog injetada na home page ───\nconst BLOG_HOME_SECTION_ID = \"plugin-blog-home-grid\";\n\n// ─── Sample blog cards para preview ───\nconst SAMPLE_BLOG_CARDS = [\n {\n title: \"Feira de Ciências 2026: Inovação e Criatividade\",\n excerpt:\n \"Nossos alunos apresentaram projetos incríveis na Feira de Ciências deste ano. Confira os destaques e premiações!\",\n image:\n \"https://images.unsplash.com/photo-1567168544230-3b9e5ec47659?w=800&h=400&fit=crop\",\n category: \"Eventos\",\n date: \"05 Fev 2026\",\n linkHref: \"/site/p/blog/feira-de-ciencias-2026\",\n linkText: \"Ler mais\",\n },\n {\n title: \"Matrículas Abertas para o Segundo Semestre\",\n excerpt:\n \"Garanta a vaga do seu filho na melhor escola da região. Condições especiais para matrículas antecipadas.\",\n image:\n \"https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop\",\n category: \"Institucional\",\n date: \"01 Fev 2026\",\n linkHref: \"/site/p/blog/matriculas-segundo-semestre\",\n linkText: \"Ler mais\",\n },\n {\n title: \"5 Dicas para Preparar seu Filho para o Ano Letivo\",\n excerpt:\n \"Dicas práticas para uma transição tranquila e um início de ano produtivo para toda a família.\",\n image:\n \"https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=800&h=400&fit=crop\",\n category: \"Educação\",\n date: \"28 Jan 2026\",\n linkHref: \"/site/p/blog/dicas-preparar-ano-letivo\",\n linkText: \"Ler mais\",\n },\n];\n\n// ─── Conteúdo HTML rico para o post de exemplo ───\nconst SAMPLE_POST_CONTENT = `\n<h2>O que é a Feira de Ciências?</h2>\n<p>A Feira de Ciências é um evento anual que celebra a curiosidade, a pesquisa e a criatividade dos nossos alunos. Nesta edição especial de 2026, recebemos mais de <strong>500 visitantes</strong> e contamos com a participação de todas as turmas do Ensino Fundamental e Médio.</p>\n<p>Este ano, o tema central foi <em>\"Ciência e Sustentabilidade\"</em>, incentivando os estudantes a desenvolverem projetos que aliassem inovação tecnológica com responsabilidade ambiental.</p>\n\n<h2>Destaques da Edição 2026</h2>\n<p>Entre os mais de 50 projetos apresentados, alguns se destacaram pela originalidade e impacto:</p>\n<ul>\n <li><strong>Jardim Sustentável Inteligente</strong> — Alunos do 5º ano desenvolveram um sistema de irrigação automática usando sensores de umidade e placa Arduino.</li>\n <li><strong>Robótica Educacional</strong> — A turma do 8º ano criou um robô que auxilia no ensino de matemática para crianças do 1º ao 3º ano.</li>\n <li><strong>Energia Solar na Escola</strong> — Projeto do 2º ano do Ensino Médio demonstrou como painéis solares poderiam reduzir em 40% o consumo de energia da escola.</li>\n</ul>\n\n<blockquote>\n <p>\"A Feira de Ciências é um dos momentos mais importantes do nosso calendário escolar. Ver a dedicação e o brilho nos olhos dos alunos ao apresentarem seus projetos nos enche de orgulho e nos motiva a continuar investindo em educação de qualidade.\"</p>\n <p><strong>— Prof. Maria Silva, Coordenadora Pedagógica</strong></p>\n</blockquote>\n\n<h2>Premiações</h2>\n<p>O júri, composto por professores universitários e profissionais da área de tecnologia, selecionou os três melhores projetos:</p>\n<ol>\n <li><strong>1º Lugar:</strong> Jardim Sustentável Inteligente (5º ano)</li>\n <li><strong>2º Lugar:</strong> Energia Solar na Escola (2º EM)</li>\n <li><strong>3º Lugar:</strong> Robótica Educacional (8º ano)</li>\n</ol>\n\n<h2>Próximos Passos</h2>\n<p>Os três projetos finalistas representarão nossa escola na <strong>Feira Regional de Ciências</strong>, que acontecerá em março na capital. Os alunos já estão se preparando para levar suas apresentações a um público ainda maior.</p>\n<p>Parabéns a todos os participantes, professores orientadores e famílias que apoiaram essa jornada de descobertas!</p>\n`.trim();\n\n/**\n * Deep-clone um bloco com novo ID\n */\nfunction cloneBlock(block: Block, newId: string): Block {\n const cloned: Block = JSON.parse(JSON.stringify(block));\n return { ...cloned, id: newId };\n}\n\nexport const blogPlugin: PluginRegistration = {\n manifest: {\n id: \"blog\",\n version: \"1.0.0\",\n name: \"Blog\",\n description: \"Blog com posts, categorias e tags\",\n icon: \"FileText\",\n\n capabilities: {\n blocks: [\"blogPostCard\", \"blogPostGrid\", \"blogPostDetail\", \"blogCategoryFilter\", \"blogSearchBar\", \"blogRecentPosts\", \"blogTagCloud\"],\n\n pageTemplates: [\n {\n id: \"blog-listing\",\n name: \"Blog\",\n slug: \"blog\",\n pluginId: \"blog\",\n structure: [],\n dataSource: {\n provider: \"blog-posts\",\n mode: \"list\",\n },\n },\n {\n id: \"blog-post\",\n name: \"Post\",\n slug: \"blog/:slug\",\n pluginId: \"blog\",\n structure: [],\n dataSource: {\n provider: \"blog-posts\",\n mode: \"single\",\n paramMapping: { slug: \":slug\" },\n },\n editRestrictions: {\n nonRemovable: true,\n },\n },\n ],\n\n dataSchemas: [\n {\n type: \"blog-post\",\n label: \"Blog Post\",\n fields: [\n { name: \"title\", type: \"string\", required: true, label: \"Title\" },\n { name: \"slug\", type: \"string\", required: true, label: \"Slug\" },\n { name: \"excerpt\", type: \"string\", label: \"Excerpt\" },\n { name: \"content\", type: \"richtext\", required: true, label: \"Content\" },\n { name: \"featuredImage\", type: \"image\", label: \"Featured Image\" },\n { name: \"category\", type: \"string\", label: \"Category\" },\n { name: \"tags\", type: \"array\", label: \"Tags\" },\n { name: \"authorVariant\", type: \"string\", label: \"Author Variant\" },\n { name: \"readingTime\", type: \"number\", label: \"Reading Time\" },\n { name: \"metaTitle\", type: \"string\", label: \"Meta Title (SEO)\" },\n { name: \"metaDescription\", type: \"string\", label: \"Meta Description (SEO)\" },\n { name: \"ogImage\", type: \"image\", label: \"Open Graph Image\" },\n ],\n },\n ],\n\n contentProviders: [\"blog-posts\", \"blog-categories\"],\n },\n\n restrictions: {\n lockedFields: {\n blogPostDetail: [\"content\", \"date\"],\n },\n requiredPages: [\"blog-listing\", \"blog-post\"],\n },\n },\n\n onActivate(document: SiteDocument): SiteDocument {\n logger.debug(\"Blog plugin activating...\");\n\n const existingPageIds = new Set(document.pages.map((p) => p.id));\n const newPages = [...document.pages];\n\n // ── Encontrar home page para clonar navbar/footer ──\n const homePage =\n document.pages.find((p) => p.slug === \"home\") || document.pages[0];\n\n const homeNavbar = homePage?.structure.find((b) => b.type === \"navbar\");\n const homeFooter = homePage?.structure.find((b) => b.type === \"footer\");\n\n // ── 1. Adicionar link \"Blog\" à navbar da home page ──\n // Preserva os links existentes e apenas insere \"Blog\" antes do último item.\n if (homePage && homeNavbar) {\n const homeIdx = newPages.findIndex((p) => p.id === homePage.id);\n if (homeIdx >= 0) {\n const navbarProps = homeNavbar.props as Record<string, any>;\n const existingLinks: Array<{ text: string; href: string }> =\n Array.isArray(navbarProps.links) ? [...navbarProps.links] : [];\n const hasBlogLink = existingLinks.some(\n (l) => l.href === \"/p/blog\",\n );\n\n if (!hasBlogLink) {\n // Inserir \"Blog\" antes do último link (geralmente \"Contato\")\n const insertIdx = existingLinks.length > 0 ? existingLinks.length - 1 : 0;\n existingLinks.splice(insertIdx, 0, { text: \"Blog\", href: \"/p/blog\" });\n\n // Atualizar navbar na home page com o novo link\n const updatedStructure = newPages[homeIdx].structure.map((b) => {\n if (b.id === homeNavbar.id) {\n return { ...b, props: { ...b.props, links: existingLinks } } as Block;\n }\n return b;\n });\n newPages[homeIdx] = { ...newPages[homeIdx], structure: updatedStructure };\n logger.debug(\"Blog link added to home navbar\");\n\n // Atualizar referência para que clones nas páginas do blog usem navbar com link\n // (homeNavbar é const, então criamos a versão atualizada para uso nos clones)\n (homeNavbar as any).props = { ...navbarProps, links: existingLinks };\n }\n }\n }\n\n // ── 2. Injetar seção de blog na home page (antes do footer) ──\n if (homePage) {\n const homeIdx = newPages.findIndex((p) => p.id === homePage.id);\n const alreadyInjected = homePage.structure.some(\n (b) => b.id === BLOG_HOME_SECTION_ID,\n );\n\n if (homeIdx >= 0 && !alreadyInjected) {\n const blogHomeSection: Block = {\n id: BLOG_HOME_SECTION_ID,\n type: \"blogPostGrid\",\n props: {\n title: \"Blog\",\n subtitle: \"Últimas publicações\",\n columns: 3,\n cards: SAMPLE_BLOG_CARDS,\n variant: \"default\",\n showViewAll: true,\n viewAllText: \"Ver todos os posts\",\n viewAllHref: \"/site/p/blog\",\n },\n } as Block;\n\n const updatedStructure = [...newPages[homeIdx].structure];\n const footerIdx = updatedStructure.findIndex(\n (b) => b.type === \"footer\",\n );\n\n if (footerIdx >= 0) {\n updatedStructure.splice(footerIdx, 0, blogHomeSection);\n } else {\n updatedStructure.push(blogHomeSection);\n }\n\n newPages[homeIdx] = {\n ...newPages[homeIdx],\n structure: updatedStructure,\n };\n logger.debug(\"Blog section injected into home page\");\n }\n }\n\n // ── 3. Criar página \"Blog\" (listagem completa) ──\n if (!existingPageIds.has(\"blog\")) {\n const blogPageStructure: Block[] = [];\n\n // Navbar clonada da home\n if (homeNavbar) {\n blogPageStructure.push(cloneBlock(homeNavbar, \"blog-page-navbar\"));\n }\n\n // Hero banner do blog\n blogPageStructure.push({\n id: \"blog-page-hero\",\n type: \"hero\",\n props: {\n title: \"Blog\",\n subtitle: \"Novidades & Publicações\",\n description:\n \"Acompanhe as últimas novidades, eventos e conquistas da nossa comunidade escolar.\",\n variant: \"centered\",\n align: \"center\",\n overlay: true,\n overlayColor: \"rgba(79, 70, 229, 0.9)\",\n background: \"#4f46e5\",\n minHeight: \"280px\",\n },\n } as Block);\n\n // Search bar\n blogPageStructure.push({\n id: \"blog-search-bar\",\n type: \"blogSearchBar\",\n props: {\n placeholder: \"Buscar posts...\",\n variant: \"simple\",\n showIcon: true,\n searchUrl: \"/site/p/blog\",\n },\n } as Block);\n\n // Category filter\n blogPageStructure.push({\n id: \"blog-category-filter\",\n type: \"blogCategoryFilter\",\n props: {\n title: \"\",\n categories: SAMPLE_BLOG_CARDS.map((c) => ({\n name: c.category,\n slug: c.category.toLowerCase().replace(/\\s+/g, \"-\"),\n count: 1,\n })),\n variant: \"chips\",\n showCount: false,\n showAll: true,\n allLabel: \"Todas\",\n filterUrl: \"/site/p/blog\",\n },\n } as Block);\n\n // Grid de posts\n blogPageStructure.push({\n id: \"blog-grid-main\",\n type: \"blogPostGrid\",\n props: {\n title: \"\",\n subtitle: \"\",\n columns: 3,\n cards: SAMPLE_BLOG_CARDS,\n variant: \"default\",\n showViewAll: false,\n viewAllText: \"Ver todos\",\n viewAllHref: \"/site/p/blog\",\n },\n } as Block);\n\n // Footer clonado da home\n if (homeFooter) {\n blogPageStructure.push(cloneBlock(homeFooter, \"blog-page-footer\"));\n }\n\n newPages.push({\n id: \"blog\",\n name: \"Blog\",\n slug: \"blog\",\n pluginId: \"blog\",\n pageTemplateId: \"blog-listing\",\n structure: blogPageStructure,\n dataSource: {\n provider: \"blog-posts\",\n mode: \"list\",\n defaultParams: { limit: 15 },\n },\n });\n logger.debug(\"Blog listing page created\");\n }\n\n // ── 4. Criar página \"Post\" (detalhe com sidebar) ──\n if (!existingPageIds.has(\"blog-post\")) {\n const postPageStructure: Block[] = [];\n\n if (homeNavbar) {\n postPageStructure.push(cloneBlock(homeNavbar, \"post-page-navbar\"));\n }\n\n // Grid layout: conteúdo principal + sidebar\n postPageStructure.push({\n id: \"blog-detail-layout\",\n type: \"grid\",\n props: {\n colTemplate: \"1fr 320px\",\n gap: \"2rem\",\n children: [\n // Coluna principal: blogPostDetail\n {\n id: \"blog-detail-main\",\n type: \"blogPostDetail\",\n props: {\n title: \"Feira de Ciências 2026: Inovação e Criatividade\",\n content: SAMPLE_POST_CONTENT,\n featuredImage:\n \"https://images.unsplash.com/photo-1567168544230-3b9e5ec47659?w=1200&h=600&fit=crop\",\n date: \"05 Fev 2026\",\n category: \"Eventos\",\n authorVariant: \"inline\",\n readingTime: \"5 min de leitura\",\n tags: [\"Feira de Ciências\", \"Eventos\", \"Sustentabilidade\", \"Projetos\"],\n showFeaturedImage: true,\n showAuthor: true,\n showDate: true,\n showTags: true,\n showReadingTime: true,\n contentMaxWidth: \"720px\",\n },\n },\n // Sidebar: stack vertical com widgets\n {\n id: \"blog-detail-sidebar\",\n type: \"stack\",\n props: {\n direction: \"col\",\n gap: \"1.5rem\",\n children: [\n {\n id: \"blog-sidebar-search\",\n type: \"blogSearchBar\",\n props: {\n placeholder: \"Buscar posts...\",\n variant: \"simple\",\n showIcon: true,\n searchUrl: \"/site/p/blog\",\n },\n },\n {\n id: \"blog-sidebar-categories\",\n type: \"blogCategoryFilter\",\n props: {\n title: \"Categorias\",\n categories: SAMPLE_BLOG_CARDS.map((c) => ({\n name: c.category,\n slug: c.category.toLowerCase().replace(/\\s+/g, \"-\"),\n count: 1,\n })),\n variant: \"list\",\n showCount: true,\n showAll: true,\n allLabel: \"Todas\",\n filterUrl: \"/site/p/blog\",\n },\n },\n {\n id: \"blog-sidebar-recent\",\n type: \"blogRecentPosts\",\n props: {\n title: \"Posts Recentes\",\n count: 5,\n showThumbnail: true,\n showDate: true,\n showCategory: false,\n posts: SAMPLE_BLOG_CARDS.map((c) => ({\n title: c.title,\n slug: c.linkHref.replace(\"/site/p/blog/\", \"\"),\n date: c.date,\n image: c.image,\n category: c.category,\n })),\n },\n },\n {\n id: \"blog-sidebar-tags\",\n type: \"blogTagCloud\",\n props: {\n title: \"Tags\",\n tags: [\n { name: \"Eventos\", count: 3 },\n { name: \"Educação\", count: 2 },\n { name: \"Institucional\", count: 1 },\n { name: \"Sustentabilidade\", count: 1 },\n ],\n variant: \"badges\",\n },\n },\n ],\n },\n },\n ] as Block[],\n },\n } as Block);\n\n if (homeFooter) {\n postPageStructure.push(cloneBlock(homeFooter, \"post-page-footer\"));\n }\n\n newPages.push({\n id: \"blog-post\",\n name: \"Post\",\n slug: \"blog/:slug\",\n pluginId: \"blog\",\n pageTemplateId: \"blog-post\",\n isDynamic: true,\n structure: postPageStructure,\n dataSource: {\n provider: \"blog-posts\",\n mode: \"single\",\n paramMapping: { slug: \":slug\" },\n },\n editRestrictions: {\n nonRemovable: true,\n },\n });\n logger.debug(\"Blog post detail page created with sidebar layout\");\n }\n\n return {\n ...document,\n pages: newPages,\n };\n },\n\n onDeactivate(document: SiteDocument): SiteDocument {\n logger.debug(\"Blog plugin deactivating...\");\n\n const newPages = document.pages\n // Remover páginas do plugin\n .filter((page) => page.pluginId !== \"blog\")\n // Remover seção de blog injetada + link \"Blog\" da navbar\n .map((page) => {\n let structure = page.structure;\n\n // Remover seção de blog injetada\n const hasInjected = structure.some(\n (b) => b.id === BLOG_HOME_SECTION_ID,\n );\n if (hasInjected) {\n structure = structure.filter(\n (b) => b.id !== BLOG_HOME_SECTION_ID,\n );\n }\n\n // Remover link \"Blog\" (/p/blog) da navbar\n structure = structure.map((b) => {\n if (b.type !== \"navbar\") return b;\n const props = b.props as Record<string, any>;\n const links: Array<{ text: string; href: string }> = Array.isArray(props.links) ? props.links : [];\n const filtered = links.filter((l) => l.href !== \"/p/blog\");\n if (filtered.length !== links.length) {\n return { ...b, props: { ...props, links: filtered } } as Block;\n }\n return b;\n });\n\n if (structure !== page.structure) {\n return { ...page, structure };\n }\n return page;\n });\n\n logger.debug(\n `Removed ${document.pages.length - newPages.length} blog page(s) and injected section`,\n );\n\n return {\n ...document,\n pages: newPages,\n };\n },\n\n getEditorRestrictions(blockType: BlockType) {\n if (blockType === \"blogPostDetail\") {\n return {\n lockedFields: [\"content\", \"date\"],\n };\n }\n if (blockType === \"blogCategoryFilter\") {\n return {\n lockedFields: [\"categories\"],\n };\n }\n if (blockType === \"blogRecentPosts\") {\n return {\n lockedFields: [\"posts\"],\n };\n }\n if (blockType === \"blogTagCloud\") {\n return {\n lockedFields: [\"tags\"],\n };\n }\n return undefined;\n },\n};\n\n// Auto-registrar o plugin (side effect — como os blocos fazem com componentRegistry)\npluginRegistry.register(blogPlugin);\n"],"names":["BLOG_HOME_SECTION_ID","SAMPLE_BLOG_CARDS","SAMPLE_POST_CONTENT","cloneBlock","block","newId","blogPlugin","document","logger","existingPageIds","p","newPages","homePage","homeNavbar","b","homeFooter","homeIdx","navbarProps","existingLinks","l","insertIdx","updatedStructure","alreadyInjected","blogHomeSection","footerIdx","blogPageStructure","c","postPageStructure","page","structure","props","links","filtered","blockType","pluginRegistry"],"mappings":";;AAoBA,MAAMA,IAAuB,yBAGvBC,IAAoB;AAAA,EACxB;AAAA,IACE,OAAO;AAAA,IACP,SACE;AAAA,IACF,OACE;AAAA,IACF,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,OAAO;AAAA,IACP,SACE;AAAA,IACF,OACE;AAAA,IACF,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAAA,EAEZ;AAAA,IACE,OAAO;AAAA,IACP,SACE;AAAA,IACF,OACE;AAAA,IACF,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,EAAA;AAEd,GAGMC,IAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6B1B,KAAA;AAKF,SAASC,EAAWC,GAAcC,GAAsB;AAEtD,SAAO,EAAE,GADa,KAAK,MAAM,KAAK,UAAUD,CAAK,CAAC,GAClC,IAAIC,EAAA;AAC1B;AAEO,MAAMC,IAAiC;AAAA,EAC5C,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,IAEN,cAAc;AAAA,MACZ,QAAQ,CAAC,gBAAgB,gBAAgB,kBAAkB,sBAAsB,iBAAiB,mBAAmB,cAAc;AAAA,MAEnI,eAAe;AAAA,QACb;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,WAAW,CAAA;AAAA,UACX,YAAY;AAAA,YACV,UAAU;AAAA,YACV,MAAM;AAAA,UAAA;AAAA,QACR;AAAA,QAEF;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,WAAW,CAAA;AAAA,UACX,YAAY;AAAA,YACV,UAAU;AAAA,YACV,MAAM;AAAA,YACN,cAAc,EAAE,MAAM,QAAA;AAAA,UAAQ;AAAA,UAEhC,kBAAkB;AAAA,YAChB,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,MACF;AAAA,MAGF,aAAa;AAAA,QACX;AAAA,UACE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,QAAQ;AAAA,YACN,EAAE,MAAM,SAAS,MAAM,UAAU,UAAU,IAAM,OAAO,QAAA;AAAA,YACxD,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,IAAM,OAAO,OAAA;AAAA,YACvD,EAAE,MAAM,WAAW,MAAM,UAAU,OAAO,UAAA;AAAA,YAC1C,EAAE,MAAM,WAAW,MAAM,YAAY,UAAU,IAAM,OAAO,UAAA;AAAA,YAC5D,EAAE,MAAM,iBAAiB,MAAM,SAAS,OAAO,iBAAA;AAAA,YAC/C,EAAE,MAAM,YAAY,MAAM,UAAU,OAAO,WAAA;AAAA,YAC3C,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO,OAAA;AAAA,YACtC,EAAE,MAAM,iBAAiB,MAAM,UAAU,OAAO,iBAAA;AAAA,YAChD,EAAE,MAAM,eAAe,MAAM,UAAU,OAAO,eAAA;AAAA,YAC9C,EAAE,MAAM,aAAa,MAAM,UAAU,OAAO,mBAAA;AAAA,YAC5C,EAAE,MAAM,mBAAmB,MAAM,UAAU,OAAO,yBAAA;AAAA,YAClD,EAAE,MAAM,WAAW,MAAM,SAAS,OAAO,mBAAA;AAAA,UAAmB;AAAA,QAC9D;AAAA,MACF;AAAA,MAGF,kBAAkB,CAAC,cAAc,iBAAiB;AAAA,IAAA;AAAA,IAGpD,cAAc;AAAA,MACZ,cAAc;AAAA,QACZ,gBAAgB,CAAC,WAAW,MAAM;AAAA,MAAA;AAAA,MAEpC,eAAe,CAAC,gBAAgB,WAAW;AAAA,IAAA;AAAA,EAC7C;AAAA,EAGF,WAAWC,GAAsC;AAC/C,IAAAC,EAAO,MAAM,2BAA2B;AAExC,UAAMC,IAAkB,IAAI,IAAIF,EAAS,MAAM,IAAI,CAACG,MAAMA,EAAE,EAAE,CAAC,GACzDC,IAAW,CAAC,GAAGJ,EAAS,KAAK,GAG7BK,IACJL,EAAS,MAAM,KAAK,CAACG,MAAMA,EAAE,SAAS,MAAM,KAAKH,EAAS,MAAM,CAAC,GAE7DM,IAAaD,GAAU,UAAU,KAAK,CAACE,MAAMA,EAAE,SAAS,QAAQ,GAChEC,IAAaH,GAAU,UAAU,KAAK,CAACE,MAAMA,EAAE,SAAS,QAAQ;AAItE,QAAIF,KAAYC,GAAY;AAC1B,YAAMG,IAAUL,EAAS,UAAU,CAACD,MAAMA,EAAE,OAAOE,EAAS,EAAE;AAC9D,UAAII,KAAW,GAAG;AAChB,cAAMC,IAAcJ,EAAW,OACzBK,IACJ,MAAM,QAAQD,EAAY,KAAK,IAAI,CAAC,GAAGA,EAAY,KAAK,IAAI,CAAA;AAK9D,YAAI,CAJgBC,EAAc;AAAA,UAChC,CAACC,MAAMA,EAAE,SAAS;AAAA,QAAA,GAGF;AAEhB,gBAAMC,IAAYF,EAAc,SAAS,IAAIA,EAAc,SAAS,IAAI;AACxE,UAAAA,EAAc,OAAOE,GAAW,GAAG,EAAE,MAAM,QAAQ,MAAM,WAAW;AAGpE,gBAAMC,IAAmBV,EAASK,CAAO,EAAE,UAAU,IAAI,CAACF,MACpDA,EAAE,OAAOD,EAAW,KACf,EAAE,GAAGC,GAAG,OAAO,EAAE,GAAGA,EAAE,OAAO,OAAOI,IAAc,IAEpDJ,CACR;AACD,UAAAH,EAASK,CAAO,IAAI,EAAE,GAAGL,EAASK,CAAO,GAAG,WAAWK,EAAA,GACvDb,EAAO,MAAM,gCAAgC,GAI5CK,EAAmB,QAAQ,EAAE,GAAGI,GAAa,OAAOC,EAAA;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAGA,QAAIN,GAAU;AACZ,YAAMI,IAAUL,EAAS,UAAU,CAACD,MAAMA,EAAE,OAAOE,EAAS,EAAE,GACxDU,IAAkBV,EAAS,UAAU;AAAA,QACzC,CAACE,MAAMA,EAAE,OAAOd;AAAA,MAAA;AAGlB,UAAIgB,KAAW,KAAK,CAACM,GAAiB;AACpC,cAAMC,IAAyB;AAAA,UAC7B,IAAIvB;AAAA,UACJ,MAAM;AAAA,UACN,OAAO;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,SAAS;AAAA,YACT,OAAOC;AAAA,YACP,SAAS;AAAA,YACT,aAAa;AAAA,YACb,aAAa;AAAA,YACb,aAAa;AAAA,UAAA;AAAA,QACf,GAGIoB,IAAmB,CAAC,GAAGV,EAASK,CAAO,EAAE,SAAS,GAClDQ,IAAYH,EAAiB;AAAA,UACjC,CAACP,MAAMA,EAAE,SAAS;AAAA,QAAA;AAGpB,QAAIU,KAAa,IACfH,EAAiB,OAAOG,GAAW,GAAGD,CAAe,IAErDF,EAAiB,KAAKE,CAAe,GAGvCZ,EAASK,CAAO,IAAI;AAAA,UAClB,GAAGL,EAASK,CAAO;AAAA,UACnB,WAAWK;AAAA,QAAA,GAEbb,EAAO,MAAM,sCAAsC;AAAA,MACrD;AAAA,IACF;AAGA,QAAI,CAACC,EAAgB,IAAI,MAAM,GAAG;AAChC,YAAMgB,IAA6B,CAAA;AAGnC,MAAIZ,KACFY,EAAkB,KAAKtB,EAAWU,GAAY,kBAAkB,CAAC,GAInEY,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,OAAO;AAAA,UACP,UAAU;AAAA,UACV,aACE;AAAA,UACF,SAAS;AAAA,UACT,OAAO;AAAA,UACP,SAAS;AAAA,UACT,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,WAAW;AAAA,QAAA;AAAA,MACb,CACQ,GAGVA,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,aAAa;AAAA,UACb,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAW;AAAA,QAAA;AAAA,MACb,CACQ,GAGVA,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,OAAO;AAAA,UACP,YAAYxB,EAAkB,IAAI,CAACyB,OAAO;AAAA,YACxC,MAAMA,EAAE;AAAA,YACR,MAAMA,EAAE,SAAS,cAAc,QAAQ,QAAQ,GAAG;AAAA,YAClD,OAAO;AAAA,UAAA,EACP;AAAA,UACF,SAAS;AAAA,UACT,WAAW;AAAA,UACX,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAW;AAAA,QAAA;AAAA,MACb,CACQ,GAGVD,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,OAAO;AAAA,UACP,UAAU;AAAA,UACV,SAAS;AAAA,UACT,OAAOxB;AAAA,UACP,SAAS;AAAA,UACT,aAAa;AAAA,UACb,aAAa;AAAA,UACb,aAAa;AAAA,QAAA;AAAA,MACf,CACQ,GAGNc,KACFU,EAAkB,KAAKtB,EAAWY,GAAY,kBAAkB,CAAC,GAGnEJ,EAAS,KAAK;AAAA,QACZ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,WAAWc;AAAA,QACX,YAAY;AAAA,UACV,UAAU;AAAA,UACV,MAAM;AAAA,UACN,eAAe,EAAE,OAAO,GAAA;AAAA,QAAG;AAAA,MAC7B,CACD,GACDjB,EAAO,MAAM,2BAA2B;AAAA,IAC1C;AAGA,QAAI,CAACC,EAAgB,IAAI,WAAW,GAAG;AACrC,YAAMkB,IAA6B,CAAA;AAEnC,MAAId,KACFc,EAAkB,KAAKxB,EAAWU,GAAY,kBAAkB,CAAC,GAInEc,EAAkB,KAAK;AAAA,QACrB,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,UACL,aAAa;AAAA,UACb,KAAK;AAAA,UACL,UAAU;AAAA;AAAA,YAER;AAAA,cACE,IAAI;AAAA,cACJ,MAAM;AAAA,cACN,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,SAASzB;AAAA,gBACT,eACE;AAAA,gBACF,MAAM;AAAA,gBACN,UAAU;AAAA,gBACV,eAAe;AAAA,gBACf,aAAa;AAAA,gBACb,MAAM,CAAC,qBAAqB,WAAW,oBAAoB,UAAU;AAAA,gBACrE,mBAAmB;AAAA,gBACnB,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,UAAU;AAAA,gBACV,iBAAiB;AAAA,gBACjB,iBAAiB;AAAA,cAAA;AAAA,YACnB;AAAA;AAAA,YAGF;AAAA,cACE,IAAI;AAAA,cACJ,MAAM;AAAA,cACN,OAAO;AAAA,gBACL,WAAW;AAAA,gBACX,KAAK;AAAA,gBACL,UAAU;AAAA,kBACR;AAAA,oBACE,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,OAAO;AAAA,sBACL,aAAa;AAAA,sBACb,SAAS;AAAA,sBACT,UAAU;AAAA,sBACV,WAAW;AAAA,oBAAA;AAAA,kBACb;AAAA,kBAEF;AAAA,oBACE,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,OAAO;AAAA,sBACL,OAAO;AAAA,sBACP,YAAYD,EAAkB,IAAI,CAACyB,OAAO;AAAA,wBACxC,MAAMA,EAAE;AAAA,wBACR,MAAMA,EAAE,SAAS,cAAc,QAAQ,QAAQ,GAAG;AAAA,wBAClD,OAAO;AAAA,sBAAA,EACP;AAAA,sBACF,SAAS;AAAA,sBACT,WAAW;AAAA,sBACX,SAAS;AAAA,sBACT,UAAU;AAAA,sBACV,WAAW;AAAA,oBAAA;AAAA,kBACb;AAAA,kBAEF;AAAA,oBACE,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,OAAO;AAAA,sBACL,OAAO;AAAA,sBACP,OAAO;AAAA,sBACP,eAAe;AAAA,sBACf,UAAU;AAAA,sBACV,cAAc;AAAA,sBACd,OAAOzB,EAAkB,IAAI,CAACyB,OAAO;AAAA,wBACnC,OAAOA,EAAE;AAAA,wBACT,MAAMA,EAAE,SAAS,QAAQ,iBAAiB,EAAE;AAAA,wBAC5C,MAAMA,EAAE;AAAA,wBACR,OAAOA,EAAE;AAAA,wBACT,UAAUA,EAAE;AAAA,sBAAA,EACZ;AAAA,oBAAA;AAAA,kBACJ;AAAA,kBAEF;AAAA,oBACE,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,OAAO;AAAA,sBACL,OAAO;AAAA,sBACP,MAAM;AAAA,wBACJ,EAAE,MAAM,WAAW,OAAO,EAAA;AAAA,wBAC1B,EAAE,MAAM,YAAY,OAAO,EAAA;AAAA,wBAC3B,EAAE,MAAM,iBAAiB,OAAO,EAAA;AAAA,wBAChC,EAAE,MAAM,oBAAoB,OAAO,EAAA;AAAA,sBAAE;AAAA,sBAEvC,SAAS;AAAA,oBAAA;AAAA,kBACX;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,CACQ,GAENX,KACFY,EAAkB,KAAKxB,EAAWY,GAAY,kBAAkB,CAAC,GAGnEJ,EAAS,KAAK;AAAA,QACZ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,WAAWgB;AAAA,QACX,YAAY;AAAA,UACV,UAAU;AAAA,UACV,MAAM;AAAA,UACN,cAAc,EAAE,MAAM,QAAA;AAAA,QAAQ;AAAA,QAEhC,kBAAkB;AAAA,UAChB,cAAc;AAAA,QAAA;AAAA,MAChB,CACD,GACDnB,EAAO,MAAM,mDAAmD;AAAA,IAClE;AAEA,WAAO;AAAA,MACL,GAAGD;AAAA,MACH,OAAOI;AAAA,IAAA;AAAA,EAEX;AAAA,EAEA,aAAaJ,GAAsC;AACjD,IAAAC,EAAO,MAAM,6BAA6B;AAE1C,UAAMG,IAAWJ,EAAS,MAEvB,OAAO,CAACqB,MAASA,EAAK,aAAa,MAAM,EAEzC,IAAI,CAACA,MAAS;AACb,UAAIC,IAAYD,EAAK;AAwBrB,aArBoBC,EAAU;AAAA,QAC5B,CAACf,MAAMA,EAAE,OAAOd;AAAA,MAAA,MAGhB6B,IAAYA,EAAU;AAAA,QACpB,CAACf,MAAMA,EAAE,OAAOd;AAAA,MAAA,IAKpB6B,IAAYA,EAAU,IAAI,CAACf,MAAM;AAC/B,YAAIA,EAAE,SAAS,SAAU,QAAOA;AAChC,cAAMgB,IAAQhB,EAAE,OACViB,IAA+C,MAAM,QAAQD,EAAM,KAAK,IAAIA,EAAM,QAAQ,CAAA,GAC1FE,IAAWD,EAAM,OAAO,CAACZ,MAAMA,EAAE,SAAS,SAAS;AACzD,eAAIa,EAAS,WAAWD,EAAM,SACrB,EAAE,GAAGjB,GAAG,OAAO,EAAE,GAAGgB,GAAO,OAAOE,IAAS,IAE7ClB;AAAA,MACT,CAAC,GAEGe,MAAcD,EAAK,YACd,EAAE,GAAGA,GAAM,WAAAC,EAAA,IAEbD;AAAA,IACT,CAAC;AAEH,WAAApB,EAAO;AAAA,MACL,WAAWD,EAAS,MAAM,SAASI,EAAS,MAAM;AAAA,IAAA,GAG7C;AAAA,MACL,GAAGJ;AAAA,MACH,OAAOI;AAAA,IAAA;AAAA,EAEX;AAAA,EAEA,sBAAsBsB,GAAsB;AAC1C,QAAIA,MAAc;AAChB,aAAO;AAAA,QACL,cAAc,CAAC,WAAW,MAAM;AAAA,MAAA;AAGpC,QAAIA,MAAc;AAChB,aAAO;AAAA,QACL,cAAc,CAAC,YAAY;AAAA,MAAA;AAG/B,QAAIA,MAAc;AAChB,aAAO;AAAA,QACL,cAAc,CAAC,OAAO;AAAA,MAAA;AAG1B,QAAIA,MAAc;AAChB,aAAO;AAAA,QACL,cAAc,CAAC,MAAM;AAAA,MAAA;AAAA,EAI3B;AACF;AAGAC,EAAe,SAAS5B,CAAU;"}
1
+ {"version":3,"file":"manifest.js","sources":["../../../../../src/engine/plugins/builtin/blog/manifest.ts"],"sourcesContent":["/**\n * Blog Plugin Manifest\n * Plugin para blog com posts, categorias e tags.\n *\n * onActivate:\n * 1. Injeta seção blogPostGrid na home page (antes do footer)\n * 2. Cria página \"Blog\" com navbar + grid de posts + footer\n * 3. Cria página \"Post\" com navbar + detalhe do post + footer\n *\n * onDeactivate:\n * 1. Remove a seção injetada na home page\n * 2. Remove as páginas do plugin\n */\n\nimport type { PluginRegistration } from \"../../types\";\nimport type { SiteDocument, Block, BlockType } from \"../../../schema/siteDocument\";\nimport { pluginRegistry } from \"../../pluginRegistry\";\nimport { logger } from \"../../../../utils/logger\";\n\n// ─── ID usado para a seção de blog injetada na home page ───\nconst BLOG_HOME_SECTION_ID = \"plugin-blog-home-grid\";\n\n// ─── Sample blog cards para preview ───\nconst SAMPLE_BLOG_CARDS = [\n {\n title: \"Feira de Ciências 2026: Inovação e Criatividade\",\n excerpt:\n \"Nossos alunos apresentaram projetos incríveis na Feira de Ciências deste ano. Confira os destaques e premiações!\",\n image:\n \"https://images.unsplash.com/photo-1567168544230-3b9e5ec47659?w=800&h=400&fit=crop\",\n category: \"Eventos\",\n date: \"05 Fev 2026\",\n linkHref: \"/site/p/blog/feira-de-ciencias-2026\",\n linkText: \"Ler mais\",\n },\n {\n title: \"Matrículas Abertas para o Segundo Semestre\",\n excerpt:\n \"Garanta a vaga do seu filho na melhor escola da região. Condições especiais para matrículas antecipadas.\",\n image:\n \"https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop\",\n category: \"Institucional\",\n date: \"01 Fev 2026\",\n linkHref: \"/site/p/blog/matriculas-segundo-semestre\",\n linkText: \"Ler mais\",\n },\n {\n title: \"5 Dicas para Preparar seu Filho para o Ano Letivo\",\n excerpt:\n \"Dicas práticas para uma transição tranquila e um início de ano produtivo para toda a família.\",\n image:\n \"https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=800&h=400&fit=crop\",\n category: \"Educação\",\n date: \"28 Jan 2026\",\n linkHref: \"/site/p/blog/dicas-preparar-ano-letivo\",\n linkText: \"Ler mais\",\n },\n];\n\n// ─── Conteúdo HTML rico para o post de exemplo ───\nconst SAMPLE_POST_CONTENT = `\n<h2>O que é a Feira de Ciências?</h2>\n<p>A Feira de Ciências é um evento anual que celebra a curiosidade, a pesquisa e a criatividade dos nossos alunos. Nesta edição especial de 2026, recebemos mais de <strong>500 visitantes</strong> e contamos com a participação de todas as turmas do Ensino Fundamental e Médio.</p>\n<p>Este ano, o tema central foi <em>\"Ciência e Sustentabilidade\"</em>, incentivando os estudantes a desenvolverem projetos que aliassem inovação tecnológica com responsabilidade ambiental.</p>\n\n<h2>Destaques da Edição 2026</h2>\n<p>Entre os mais de 50 projetos apresentados, alguns se destacaram pela originalidade e impacto:</p>\n<ul>\n <li><strong>Jardim Sustentável Inteligente</strong> — Alunos do 5º ano desenvolveram um sistema de irrigação automática usando sensores de umidade e placa Arduino.</li>\n <li><strong>Robótica Educacional</strong> — A turma do 8º ano criou um robô que auxilia no ensino de matemática para crianças do 1º ao 3º ano.</li>\n <li><strong>Energia Solar na Escola</strong> — Projeto do 2º ano do Ensino Médio demonstrou como painéis solares poderiam reduzir em 40% o consumo de energia da escola.</li>\n</ul>\n\n<blockquote>\n <p>\"A Feira de Ciências é um dos momentos mais importantes do nosso calendário escolar. Ver a dedicação e o brilho nos olhos dos alunos ao apresentarem seus projetos nos enche de orgulho e nos motiva a continuar investindo em educação de qualidade.\"</p>\n <p><strong>— Prof. Maria Silva, Coordenadora Pedagógica</strong></p>\n</blockquote>\n\n<h2>Premiações</h2>\n<p>O júri, composto por professores universitários e profissionais da área de tecnologia, selecionou os três melhores projetos:</p>\n<ol>\n <li><strong>1º Lugar:</strong> Jardim Sustentável Inteligente (5º ano)</li>\n <li><strong>2º Lugar:</strong> Energia Solar na Escola (2º EM)</li>\n <li><strong>3º Lugar:</strong> Robótica Educacional (8º ano)</li>\n</ol>\n\n<h2>Próximos Passos</h2>\n<p>Os três projetos finalistas representarão nossa escola na <strong>Feira Regional de Ciências</strong>, que acontecerá em março na capital. Os alunos já estão se preparando para levar suas apresentações a um público ainda maior.</p>\n<p>Parabéns a todos os participantes, professores orientadores e famílias que apoiaram essa jornada de descobertas!</p>\n`.trim();\n\n/**\n * Deep-clone um bloco com novo ID\n */\nfunction cloneBlock(block: Block, newId: string): Block {\n const cloned: Block = JSON.parse(JSON.stringify(block));\n return { ...cloned, id: newId };\n}\n\nexport const blogPlugin: PluginRegistration = {\n manifest: {\n id: \"blog\",\n version: \"1.0.0\",\n name: \"Blog\",\n description: \"Blog com posts, categorias e tags\",\n icon: \"FileText\",\n\n capabilities: {\n blocks: [\"blogPostCard\", \"blogPostGrid\", \"blogPostDetail\", \"blogCategoryFilter\", \"blogSearchBar\", \"blogRecentPosts\", \"blogTagCloud\"],\n\n pageTemplates: [\n {\n id: \"blog-listing\",\n name: \"Blog\",\n slug: \"blog\",\n pluginId: \"blog\",\n structure: [],\n dataSource: {\n provider: \"blog-posts\",\n mode: \"list\",\n },\n },\n {\n id: \"blog-post\",\n name: \"Post\",\n slug: \"blog/:slug\",\n pluginId: \"blog\",\n structure: [],\n dataSource: {\n provider: \"blog-posts\",\n mode: \"single\",\n paramMapping: { slug: \":slug\" },\n },\n editRestrictions: {\n nonRemovable: true,\n },\n },\n ],\n\n dataSchemas: [\n {\n type: \"blog-post\",\n label: \"Blog Post\",\n fields: [\n { name: \"title\", type: \"string\", required: true, label: \"Title\" },\n { name: \"slug\", type: \"string\", required: true, label: \"Slug\" },\n { name: \"excerpt\", type: \"string\", label: \"Excerpt\" },\n { name: \"content\", type: \"richtext\", required: true, label: \"Content\" },\n { name: \"featuredImage\", type: \"image\", label: \"Featured Image\" },\n { name: \"category\", type: \"string\", label: \"Category\" },\n { name: \"tags\", type: \"array\", label: \"Tags\" },\n { name: \"authorVariant\", type: \"string\", label: \"Author Variant\" },\n { name: \"readingTime\", type: \"number\", label: \"Reading Time\" },\n { name: \"metaTitle\", type: \"string\", label: \"Meta Title (SEO)\" },\n { name: \"metaDescription\", type: \"string\", label: \"Meta Description (SEO)\" },\n { name: \"ogImage\", type: \"image\", label: \"Open Graph Image\" },\n ],\n },\n ],\n\n contentProviders: [\"blog-posts\", \"blog-categories\"],\n },\n\n restrictions: {\n lockedFields: {\n blogPostDetail: [\"content\", \"date\"],\n },\n requiredPages: [\"blog-listing\", \"blog-post\"],\n },\n },\n\n onActivate(document: SiteDocument): SiteDocument {\n logger.debug(\"Blog plugin activating...\");\n\n const existingPageIds = new Set(document.pages.map((p) => p.id));\n const newPages = [...document.pages];\n\n // ── Encontrar home page para clonar navbar/footer ──\n const homePage =\n document.pages.find((p) => p.slug === \"home\") || document.pages[0];\n\n const homeNavbar = homePage?.structure.find((b) => b.type === \"navbar\");\n const homeFooter = homePage?.structure.find((b) => b.type === \"footer\");\n\n // ── 1. Adicionar link \"Blog\" à navbar da home page ──\n // Preserva os links existentes e apenas insere \"Blog\" antes do último item.\n if (homePage && homeNavbar) {\n const homeIdx = newPages.findIndex((p) => p.id === homePage.id);\n if (homeIdx >= 0) {\n const navbarProps = homeNavbar.props as Record<string, any>;\n const existingLinks: Array<{ text: string; href: string }> =\n Array.isArray(navbarProps.links) ? [...navbarProps.links] : [];\n const hasBlogLink = existingLinks.some(\n (l) => l.href === \"/p/blog\",\n );\n\n if (!hasBlogLink) {\n // Inserir \"Blog\" antes do último link (geralmente \"Contato\")\n const insertIdx = existingLinks.length > 0 ? existingLinks.length - 1 : 0;\n existingLinks.splice(insertIdx, 0, { text: \"Blog\", href: \"/p/blog\" });\n\n // Atualizar navbar na home page com o novo link\n const updatedStructure = newPages[homeIdx].structure.map((b) => {\n if (b.id === homeNavbar.id) {\n return { ...b, props: { ...b.props, links: existingLinks } } as Block;\n }\n return b;\n });\n newPages[homeIdx] = { ...newPages[homeIdx], structure: updatedStructure };\n logger.debug(\"Blog link added to home navbar\");\n\n // Atualizar referência para que clones nas páginas do blog usem navbar com link\n // (homeNavbar é const, então criamos a versão atualizada para uso nos clones)\n (homeNavbar as any).props = { ...navbarProps, links: existingLinks };\n }\n }\n }\n\n // ── 2. Injetar seção de blog na home page (antes do footer) ──\n if (homePage) {\n const homeIdx = newPages.findIndex((p) => p.id === homePage.id);\n const alreadyInjected = homePage.structure.some(\n (b) => b.id === BLOG_HOME_SECTION_ID,\n );\n\n if (homeIdx >= 0 && !alreadyInjected) {\n const blogHomeSection: Block = {\n id: BLOG_HOME_SECTION_ID,\n type: \"blogPostGrid\",\n props: {\n title: \"Blog\",\n subtitle: \"Últimas publicações\",\n columns: 3,\n cards: SAMPLE_BLOG_CARDS,\n variant: \"default\",\n showViewAll: true,\n viewAllText: \"Ver todos os posts\",\n viewAllHref: \"/site/p/blog\",\n },\n } as Block;\n\n const updatedStructure = [...newPages[homeIdx].structure];\n const footerIdx = updatedStructure.findIndex(\n (b) => b.type === \"footer\",\n );\n\n if (footerIdx >= 0) {\n updatedStructure.splice(footerIdx, 0, blogHomeSection);\n } else {\n updatedStructure.push(blogHomeSection);\n }\n\n newPages[homeIdx] = {\n ...newPages[homeIdx],\n structure: updatedStructure,\n };\n logger.debug(\"Blog section injected into home page\");\n }\n }\n\n // ── 3. Criar página \"Blog\" (listagem completa) ──\n if (!existingPageIds.has(\"blog\")) {\n const blogPageStructure: Block[] = [];\n\n // Navbar clonada da home\n if (homeNavbar) {\n blogPageStructure.push(cloneBlock(homeNavbar, \"blog-page-navbar\"));\n }\n\n // Hero banner do blog\n blogPageStructure.push({\n id: \"blog-page-hero\",\n type: \"hero\",\n props: {\n title: \"Blog\",\n subtitle: \"Novidades & Publicações\",\n description:\n \"Acompanhe as últimas novidades, eventos e conquistas da nossa comunidade escolar.\",\n variant: \"centered\",\n align: \"center\",\n overlay: true,\n overlayColor: \"rgba(79, 70, 229, 0.9)\",\n background: \"#4f46e5\",\n minHeight: \"280px\",\n },\n } as Block);\n\n // Search bar\n blogPageStructure.push({\n id: \"blog-search-bar\",\n type: \"blogSearchBar\",\n props: {\n placeholder: \"Buscar posts...\",\n variant: \"simple\",\n showIcon: true,\n searchUrl: \"/site/p/blog\",\n },\n } as Block);\n\n // Category filter\n blogPageStructure.push({\n id: \"blog-category-filter\",\n type: \"blogCategoryFilter\",\n props: {\n title: \"\",\n categories: SAMPLE_BLOG_CARDS.map((c) => ({\n name: c.category,\n slug: c.category.toLowerCase().replace(/\\s+/g, \"-\"),\n count: 1,\n })),\n variant: \"chips\",\n showCount: false,\n showAll: true,\n allLabel: \"Todas\",\n filterUrl: \"/site/p/blog\",\n },\n } as Block);\n\n // Grid de posts\n blogPageStructure.push({\n id: \"blog-grid-main\",\n type: \"blogPostGrid\",\n props: {\n title: \"\",\n subtitle: \"\",\n columns: 3,\n cards: SAMPLE_BLOG_CARDS,\n variant: \"default\",\n showViewAll: false,\n viewAllText: \"Ver todos\",\n viewAllHref: \"/site/p/blog\",\n },\n } as Block);\n\n // Footer clonado da home\n if (homeFooter) {\n blogPageStructure.push(cloneBlock(homeFooter, \"blog-page-footer\"));\n }\n\n newPages.push({\n id: \"blog\",\n name: \"Blog\",\n slug: \"blog\",\n pluginId: \"blog\",\n pageTemplateId: \"blog-listing\",\n structure: blogPageStructure,\n dataSource: {\n provider: \"blog-posts\",\n mode: \"list\",\n defaultParams: { limit: 15 },\n },\n });\n logger.debug(\"Blog listing page created\");\n }\n\n // ── 4. Criar página \"Post\" (detalhe com sidebar) ──\n if (!existingPageIds.has(\"blog-post\")) {\n const postPageStructure: Block[] = [];\n\n if (homeNavbar) {\n const navClone = cloneBlock(homeNavbar, \"post-page-navbar\");\n // Garantir navbar fixa no topo (position:fixed) mesmo se home não tem\n (navClone.props as Record<string, any>).sticky = true;\n postPageStructure.push(navClone);\n }\n\n // Grid layout: conteúdo principal + sidebar (com container e espaçamento)\n // paddingTop compensa a navbar fixa (position:fixed sai do fluxo)\n postPageStructure.push({\n id: \"blog-detail-layout\",\n type: \"grid\",\n props: {\n colTemplate: \"1fr 320px\",\n gap: \"2.5rem\",\n maxWidth: \"1200px\",\n padding: \"2rem\",\n paddingTop: \"6rem\",\n children: [\n // Coluna principal: blogPostDetail\n {\n id: \"blog-detail-main\",\n type: \"blogPostDetail\",\n props: {\n title: \"Feira de Ciências 2026: Inovação e Criatividade\",\n content: SAMPLE_POST_CONTENT,\n featuredImage:\n \"https://images.unsplash.com/photo-1567168544230-3b9e5ec47659?w=1200&h=600&fit=crop\",\n date: \"05 Fev 2026\",\n category: \"Eventos\",\n authorVariant: \"inline\",\n readingTime: \"5 min de leitura\",\n tags: [\"Feira de Ciências\", \"Eventos\", \"Sustentabilidade\", \"Projetos\"],\n showFeaturedImage: true,\n showAuthor: true,\n showDate: true,\n showTags: true,\n showReadingTime: true,\n contentMaxWidth: \"720px\",\n },\n },\n // Sidebar: stack vertical com widgets (sticky por padrão)\n {\n id: \"blog-detail-sidebar\",\n type: \"stack\",\n props: {\n direction: \"col\",\n gap: \"1.5rem\",\n sticky: true,\n stickyOffset: \"80px\",\n children: [\n {\n id: \"blog-sidebar-search\",\n type: \"blogSearchBar\",\n props: {\n placeholder: \"Buscar posts...\",\n variant: \"simple\",\n showIcon: true,\n searchUrl: \"/site/p/blog\",\n },\n },\n {\n id: \"blog-sidebar-categories\",\n type: \"blogCategoryFilter\",\n props: {\n title: \"Categorias\",\n categories: SAMPLE_BLOG_CARDS.map((c) => ({\n name: c.category,\n slug: c.category.toLowerCase().replace(/\\s+/g, \"-\"),\n count: 1,\n })),\n variant: \"list\",\n showCount: true,\n showAll: true,\n allLabel: \"Todas\",\n filterUrl: \"/site/p/blog\",\n },\n },\n {\n id: \"blog-sidebar-recent\",\n type: \"blogRecentPosts\",\n props: {\n title: \"Posts Recentes\",\n count: 5,\n showThumbnail: true,\n showDate: true,\n showCategory: false,\n posts: SAMPLE_BLOG_CARDS.map((c) => ({\n title: c.title,\n slug: c.linkHref.replace(\"/site/p/blog/\", \"\"),\n date: c.date,\n image: c.image,\n category: c.category,\n })),\n },\n },\n {\n id: \"blog-sidebar-tags\",\n type: \"blogTagCloud\",\n props: {\n title: \"Tags\",\n tags: [\n { name: \"Eventos\", count: 3 },\n { name: \"Educação\", count: 2 },\n { name: \"Institucional\", count: 1 },\n { name: \"Sustentabilidade\", count: 1 },\n ],\n variant: \"badges\",\n },\n },\n ],\n },\n },\n ] as Block[],\n },\n } as Block);\n\n if (homeFooter) {\n postPageStructure.push(cloneBlock(homeFooter, \"post-page-footer\"));\n }\n\n newPages.push({\n id: \"blog-post\",\n name: \"Post\",\n slug: \"blog/:slug\",\n pluginId: \"blog\",\n pageTemplateId: \"blog-post\",\n isDynamic: true,\n structure: postPageStructure,\n dataSource: {\n provider: \"blog-posts\",\n mode: \"single\",\n paramMapping: { slug: \":slug\" },\n },\n editRestrictions: {\n nonRemovable: true,\n },\n });\n logger.debug(\"Blog post detail page created with sidebar layout\");\n }\n\n return {\n ...document,\n pages: newPages,\n };\n },\n\n onDeactivate(document: SiteDocument): SiteDocument {\n logger.debug(\"Blog plugin deactivating...\");\n\n const newPages = document.pages\n // Remover páginas do plugin\n .filter((page) => page.pluginId !== \"blog\")\n // Remover seção de blog injetada + link \"Blog\" da navbar\n .map((page) => {\n let structure = page.structure;\n\n // Remover seção de blog injetada\n const hasInjected = structure.some(\n (b) => b.id === BLOG_HOME_SECTION_ID,\n );\n if (hasInjected) {\n structure = structure.filter(\n (b) => b.id !== BLOG_HOME_SECTION_ID,\n );\n }\n\n // Remover link \"Blog\" (/p/blog) da navbar\n structure = structure.map((b) => {\n if (b.type !== \"navbar\") return b;\n const props = b.props as Record<string, any>;\n const links: Array<{ text: string; href: string }> = Array.isArray(props.links) ? props.links : [];\n const filtered = links.filter((l) => l.href !== \"/p/blog\");\n if (filtered.length !== links.length) {\n return { ...b, props: { ...props, links: filtered } } as Block;\n }\n return b;\n });\n\n if (structure !== page.structure) {\n return { ...page, structure };\n }\n return page;\n });\n\n logger.debug(\n `Removed ${document.pages.length - newPages.length} blog page(s) and injected section`,\n );\n\n return {\n ...document,\n pages: newPages,\n };\n },\n\n getEditorRestrictions(blockType: BlockType) {\n if (blockType === \"blogPostDetail\") {\n return {\n lockedFields: [\"content\", \"date\"],\n };\n }\n if (blockType === \"blogCategoryFilter\") {\n return {\n lockedFields: [\"categories\"],\n };\n }\n if (blockType === \"blogRecentPosts\") {\n return {\n lockedFields: [\"posts\"],\n };\n }\n if (blockType === \"blogTagCloud\") {\n return {\n lockedFields: [\"tags\"],\n };\n }\n return undefined;\n },\n};\n\n// Auto-registrar o plugin (side effect — como os blocos fazem com componentRegistry)\npluginRegistry.register(blogPlugin);\n"],"names":["BLOG_HOME_SECTION_ID","SAMPLE_BLOG_CARDS","SAMPLE_POST_CONTENT","cloneBlock","block","newId","blogPlugin","document","logger","existingPageIds","p","newPages","homePage","homeNavbar","b","homeFooter","homeIdx","navbarProps","existingLinks","l","insertIdx","updatedStructure","alreadyInjected","blogHomeSection","footerIdx","blogPageStructure","c","postPageStructure","navClone","page","structure","props","links","filtered","blockType","pluginRegistry"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../../../src/engine/registry/blocks/layout/grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,eAAO,MAAM,SAAS,EAAE,eA+BvB,CAAC"}
1
+ {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../../../src/engine/registry/blocks/layout/grid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,eAAO,MAAM,SAAS,EAAE,eAuFvB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { componentRegistry as e } from "../../registry.js";
2
- const o = {
2
+ const a = {
3
3
  type: "grid",
4
4
  name: "Grid",
5
5
  description: "Layout em grid responsivo",
@@ -20,19 +20,75 @@ const o = {
20
20
  },
21
21
  colTemplate: {
22
22
  label: "Template de Colunas",
23
- description: "CSS grid-template-columns (ex: '1fr 320px'). Se definido, sobrescreve 'Colunas'.",
24
- inputType: "text",
23
+ description: "CSS grid-template-columns. Se definido, sobrescreve 'Colunas'.",
24
+ inputType: "select",
25
+ options: [
26
+ { label: "Automático (usa Colunas)", value: "" },
27
+ { label: "Conteúdo + Sidebar (1fr 320px)", value: "1fr 320px" },
28
+ { label: "Sidebar + Conteúdo (320px 1fr)", value: "320px 1fr" },
29
+ { label: "Conteúdo + Sidebar Larga (1fr 380px)", value: "1fr 380px" },
30
+ { label: "Sidebar Larga + Conteúdo (380px 1fr)", value: "380px 1fr" },
31
+ { label: "2/3 + 1/3", value: "2fr 1fr" },
32
+ { label: "1/3 + 2/3", value: "1fr 2fr" },
33
+ { label: "Metade + Metade", value: "1fr 1fr" }
34
+ ],
25
35
  group: "Layout"
26
36
  },
27
37
  gap: {
28
- label: "Gap",
29
- inputType: "text",
38
+ label: "Distância entre Colunas",
39
+ inputType: "select",
40
+ options: [
41
+ { label: "Compacto", value: "1rem" },
42
+ { label: "Padrão", value: "1.5rem" },
43
+ { label: "Espaçoso", value: "2rem" },
44
+ { label: "Largo", value: "2.5rem" },
45
+ { label: "X. Largo", value: "3rem" }
46
+ ],
30
47
  group: "Layout"
48
+ },
49
+ maxWidth: {
50
+ label: "Largura Máxima",
51
+ description: "Largura máxima do container. Centraliza automaticamente.",
52
+ inputType: "select",
53
+ options: [
54
+ { label: "Nenhuma", value: "" },
55
+ { label: "Compacta (960px)", value: "960px" },
56
+ { label: "Padrão (1200px)", value: "1200px" },
57
+ { label: "Larga (1400px)", value: "1400px" },
58
+ { label: "Máxima (1600px)", value: "1600px" }
59
+ ],
60
+ group: "Espaçamento"
61
+ },
62
+ padding: {
63
+ label: "Padding Lateral",
64
+ description: "Espaçamento horizontal interno",
65
+ inputType: "select",
66
+ options: [
67
+ { label: "Nenhum", value: "" },
68
+ { label: "Pequeno (1rem)", value: "1rem" },
69
+ { label: "Padrão (2rem)", value: "2rem" },
70
+ { label: "Grande (3rem)", value: "3rem" },
71
+ { label: "Extra Grande (4rem)", value: "4rem" }
72
+ ],
73
+ group: "Espaçamento"
74
+ },
75
+ paddingTop: {
76
+ label: "Espaço do Topo",
77
+ description: "Margem superior (útil abaixo de navbars fixas)",
78
+ inputType: "select",
79
+ options: [
80
+ { label: "Nenhum", value: "" },
81
+ { label: "Pequeno (2rem)", value: "2rem" },
82
+ { label: "Navbar Padrão (5rem)", value: "5rem" },
83
+ { label: "Navbar + Respiro (6rem)", value: "6rem" },
84
+ { label: "Grande (8rem)", value: "8rem" }
85
+ ],
86
+ group: "Espaçamento"
31
87
  }
32
88
  }
33
89
  };
34
- e.register(o);
90
+ e.register(a);
35
91
  export {
36
- o as gridBlock
92
+ a as gridBlock
37
93
  };
38
94
  //# sourceMappingURL=grid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"grid.js","sources":["../../../../../src/engine/registry/blocks/layout/grid.ts"],"sourcesContent":["import { BlockDefinition } from \"../../types\";\nimport { componentRegistry } from \"../../registry\";\n\nexport const gridBlock: BlockDefinition = {\n type: \"grid\",\n name: \"Grid\",\n description: \"Layout em grid responsivo\",\n category: \"layout\",\n canHaveChildren: true,\n defaultProps: {\n cols: 3,\n gap: \"1rem\",\n },\n inspectorMeta: {\n cols: {\n label: \"Colunas\",\n description: \"Número de colunas (ou objeto responsivo)\",\n inputType: \"number\",\n min: 1,\n max: 12,\n group: \"Layout\",\n },\n colTemplate: {\n label: \"Template de Colunas\",\n description: \"CSS grid-template-columns (ex: '1fr 320px'). Se definido, sobrescreve 'Colunas'.\",\n inputType: \"text\",\n group: \"Layout\",\n },\n gap: {\n label: \"Gap\",\n inputType: \"text\",\n group: \"Layout\",\n },\n },\n};\n\n// Auto-registro\ncomponentRegistry.register(gridBlock);\n"],"names":["gridBlock","componentRegistry"],"mappings":";AAGO,MAAMA,IAA6B;AAAA,EACxC,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,KAAK;AAAA,EAAA;AAAA,EAEP,eAAe;AAAA,IACb,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,WAAW;AAAA,MACX,KAAK;AAAA,MACL,KAAK;AAAA,MACL,OAAO;AAAA,IAAA;AAAA,IAET,aAAa;AAAA,MACX,OAAO;AAAA,MACP,aAAa;AAAA,MACb,WAAW;AAAA,MACX,OAAO;AAAA,IAAA;AAAA,IAET,KAAK;AAAA,MACH,OAAO;AAAA,MACP,WAAW;AAAA,MACX,OAAO;AAAA,IAAA;AAAA,EACT;AAEJ;AAGAC,EAAkB,SAASD,CAAS;"}
1
+ {"version":3,"file":"grid.js","sources":["../../../../../src/engine/registry/blocks/layout/grid.ts"],"sourcesContent":["import { BlockDefinition } from \"../../types\";\nimport { componentRegistry } from \"../../registry\";\n\nexport const gridBlock: BlockDefinition = {\n type: \"grid\",\n name: \"Grid\",\n description: \"Layout em grid responsivo\",\n category: \"layout\",\n canHaveChildren: true,\n defaultProps: {\n cols: 3,\n gap: \"1rem\",\n },\n inspectorMeta: {\n cols: {\n label: \"Colunas\",\n description: \"Número de colunas (ou objeto responsivo)\",\n inputType: \"number\",\n min: 1,\n max: 12,\n group: \"Layout\",\n },\n colTemplate: {\n label: \"Template de Colunas\",\n description: \"CSS grid-template-columns. Se definido, sobrescreve 'Colunas'.\",\n inputType: \"select\",\n options: [\n { label: \"Automático (usa Colunas)\", value: \"\" },\n { label: \"Conteúdo + Sidebar (1fr 320px)\", value: \"1fr 320px\" },\n { label: \"Sidebar + Conteúdo (320px 1fr)\", value: \"320px 1fr\" },\n { label: \"Conteúdo + Sidebar Larga (1fr 380px)\", value: \"1fr 380px\" },\n { label: \"Sidebar Larga + Conteúdo (380px 1fr)\", value: \"380px 1fr\" },\n { label: \"2/3 + 1/3\", value: \"2fr 1fr\" },\n { label: \"1/3 + 2/3\", value: \"1fr 2fr\" },\n { label: \"Metade + Metade\", value: \"1fr 1fr\" },\n ],\n group: \"Layout\",\n },\n gap: {\n label: \"Distância entre Colunas\",\n inputType: \"select\",\n options: [\n { label: \"Compacto\", value: \"1rem\" },\n { label: \"Padrão\", value: \"1.5rem\" },\n { label: \"Espaçoso\", value: \"2rem\" },\n { label: \"Largo\", value: \"2.5rem\" },\n { label: \"X. Largo\", value: \"3rem\" },\n ],\n group: \"Layout\",\n },\n maxWidth: {\n label: \"Largura Máxima\",\n description: \"Largura máxima do container. Centraliza automaticamente.\",\n inputType: \"select\",\n options: [\n { label: \"Nenhuma\", value: \"\" },\n { label: \"Compacta (960px)\", value: \"960px\" },\n { label: \"Padrão (1200px)\", value: \"1200px\" },\n { label: \"Larga (1400px)\", value: \"1400px\" },\n { label: \"Máxima (1600px)\", value: \"1600px\" },\n ],\n group: \"Espaçamento\",\n },\n padding: {\n label: \"Padding Lateral\",\n description: \"Espaçamento horizontal interno\",\n inputType: \"select\",\n options: [\n { label: \"Nenhum\", value: \"\" },\n { label: \"Pequeno (1rem)\", value: \"1rem\" },\n { label: \"Padrão (2rem)\", value: \"2rem\" },\n { label: \"Grande (3rem)\", value: \"3rem\" },\n { label: \"Extra Grande (4rem)\", value: \"4rem\" },\n ],\n group: \"Espaçamento\",\n },\n paddingTop: {\n label: \"Espaço do Topo\",\n description: \"Margem superior (útil abaixo de navbars fixas)\",\n inputType: \"select\",\n options: [\n { label: \"Nenhum\", value: \"\" },\n { label: \"Pequeno (2rem)\", value: \"2rem\" },\n { label: \"Navbar Padrão (5rem)\", value: \"5rem\" },\n { label: \"Navbar + Respiro (6rem)\", value: \"6rem\" },\n { label: \"Grande (8rem)\", value: \"8rem\" },\n ],\n group: \"Espaçamento\",\n },\n },\n};\n\n// Auto-registro\ncomponentRegistry.register(gridBlock);\n"],"names":["gridBlock","componentRegistry"],"mappings":";AAGO,MAAMA,IAA6B;AAAA,EACxC,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,KAAK;AAAA,EAAA;AAAA,EAEP,eAAe;AAAA,IACb,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,WAAW;AAAA,MACX,KAAK;AAAA,MACL,KAAK;AAAA,MACL,OAAO;AAAA,IAAA;AAAA,IAET,aAAa;AAAA,MACX,OAAO;AAAA,MACP,aAAa;AAAA,MACb,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,4BAA4B,OAAO,GAAA;AAAA,QAC5C,EAAE,OAAO,kCAAkC,OAAO,YAAA;AAAA,QAClD,EAAE,OAAO,kCAAkC,OAAO,YAAA;AAAA,QAClD,EAAE,OAAO,wCAAwC,OAAO,YAAA;AAAA,QACxD,EAAE,OAAO,wCAAwC,OAAO,YAAA;AAAA,QACxD,EAAE,OAAO,aAAa,OAAO,UAAA;AAAA,QAC7B,EAAE,OAAO,aAAa,OAAO,UAAA;AAAA,QAC7B,EAAE,OAAO,mBAAmB,OAAO,UAAA;AAAA,MAAU;AAAA,MAE/C,OAAO;AAAA,IAAA;AAAA,IAET,KAAK;AAAA,MACH,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,YAAY,OAAO,OAAA;AAAA,QAC5B,EAAE,OAAO,UAAU,OAAO,SAAA;AAAA,QAC1B,EAAE,OAAO,YAAY,OAAO,OAAA;AAAA,QAC5B,EAAE,OAAO,SAAS,OAAO,SAAA;AAAA,QACzB,EAAE,OAAO,YAAY,OAAO,OAAA;AAAA,MAAO;AAAA,MAErC,OAAO;AAAA,IAAA;AAAA,IAET,UAAU;AAAA,MACR,OAAO;AAAA,MACP,aAAa;AAAA,MACb,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,WAAW,OAAO,GAAA;AAAA,QAC3B,EAAE,OAAO,oBAAoB,OAAO,QAAA;AAAA,QACpC,EAAE,OAAO,mBAAmB,OAAO,SAAA;AAAA,QACnC,EAAE,OAAO,kBAAkB,OAAO,SAAA;AAAA,QAClC,EAAE,OAAO,mBAAmB,OAAO,SAAA;AAAA,MAAS;AAAA,MAE9C,OAAO;AAAA,IAAA;AAAA,IAET,SAAS;AAAA,MACP,OAAO;AAAA,MACP,aAAa;AAAA,MACb,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,OAAO,GAAA;AAAA,QAC1B,EAAE,OAAO,kBAAkB,OAAO,OAAA;AAAA,QAClC,EAAE,OAAO,iBAAiB,OAAO,OAAA;AAAA,QACjC,EAAE,OAAO,iBAAiB,OAAO,OAAA;AAAA,QACjC,EAAE,OAAO,uBAAuB,OAAO,OAAA;AAAA,MAAO;AAAA,MAEhD,OAAO;AAAA,IAAA;AAAA,IAET,YAAY;AAAA,MACV,OAAO;AAAA,MACP,aAAa;AAAA,MACb,WAAW;AAAA,MACX,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,OAAO,GAAA;AAAA,QAC1B,EAAE,OAAO,kBAAkB,OAAO,OAAA;AAAA,QAClC,EAAE,OAAO,wBAAwB,OAAO,OAAA;AAAA,QACxC,EAAE,OAAO,2BAA2B,OAAO,OAAA;AAAA,QAC3C,EAAE,OAAO,iBAAiB,OAAO,OAAA;AAAA,MAAO;AAAA,MAE1C,OAAO;AAAA,IAAA;AAAA,EACT;AAEJ;AAGAC,EAAkB,SAASD,CAAS;"}
@@ -1 +1 @@
1
- {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../../src/engine/registry/blocks/layout/stack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,eAAO,MAAM,UAAU,EAAE,eAoDxB,CAAC"}
1
+ {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../../../src/engine/registry/blocks/layout/stack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,eAAO,MAAM,UAAU,EAAE,eAiFxB,CAAC"}