@agile-team/mach-report 0.6.0 → 0.8.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.
Files changed (47) hide show
  1. package/dist/ReportPreview-BQE0C_37.cjs +6 -0
  2. package/dist/ReportPreview-D8X75aLV.js +825 -0
  3. package/dist/format.d.ts +35 -0
  4. package/dist/grid-geometry-BXpOxznT.cjs +1 -0
  5. package/dist/grid-geometry-Bs8QXz1X.js +65 -0
  6. package/dist/index.cjs +6 -6
  7. package/dist/index.d.cts +1 -0
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +811 -606
  10. package/dist/layout/paginate.d.ts +29 -0
  11. package/dist/pdf.cjs +46 -46
  12. package/dist/pdf.js +12 -11
  13. package/dist/plugin-7W2Zy3Xc.cjs +1 -0
  14. package/dist/plugin-Bc6Px9Lq.js +92 -0
  15. package/dist/style-6ihHKVCM.js +192 -0
  16. package/dist/style-Xq08-IsV.cjs +3 -0
  17. package/dist/style.css +1 -1
  18. package/dist/vue/ReportPreview.d.ts +40 -3
  19. package/dist/vue/ReportToolbar.d.ts +15 -0
  20. package/dist/vue/adapters.d.ts +3 -0
  21. package/dist/vue/async.d.cts +209 -64
  22. package/dist/vue/async.d.ts +209 -64
  23. package/dist/vue/composables/useHighlight.d.ts +8 -0
  24. package/dist/vue/composables/usePrintExport.d.ts +7 -0
  25. package/dist/vue/config.d.ts +9 -0
  26. package/dist/vue/controller.d.ts +24 -0
  27. package/dist/vue/errors.d.ts +16 -0
  28. package/dist/vue/index.d.cts +2 -0
  29. package/dist/vue/index.d.ts +2 -0
  30. package/dist/vue/injection-keys.d.ts +2 -0
  31. package/dist/vue/plugin.d.ts +278 -2
  32. package/dist/vue-async.cjs +1 -1
  33. package/dist/vue-async.js +3 -3
  34. package/dist/vue.cjs +1 -1
  35. package/dist/vue.js +39 -29
  36. package/dist/xlsx/render-xlsx.d.ts +20 -0
  37. package/dist/xlsx.cjs +30 -0
  38. package/dist/xlsx.d.cts +5 -0
  39. package/dist/xlsx.d.ts +5 -0
  40. package/dist/xlsx.js +22647 -0
  41. package/package.json +13 -2
  42. package/dist/ReportPreview-DWLjYi_p.js +0 -527
  43. package/dist/ReportPreview-rBtmbu3W.cjs +0 -6
  44. package/dist/plugin-BIJxGHZX.cjs +0 -1
  45. package/dist/plugin-DrV67_VW.js +0 -89
  46. package/dist/style-B3vxGDZd.cjs +0 -3
  47. package/dist/style-B7Xfo5I-.js +0 -255
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 列值格式化(声明式、JSON 可序列化——不破坏 gridPlan 契约)。
3
+ * 在 paginate 的 cellText 出口统一消费:格式化发生在进 RenderPlan 之前,
4
+ * 三后端(DOM/Canvas/PDF)零改动。
5
+ */
6
+ export type ColumnFormat = {
7
+ kind: "number";
8
+ thousands?: boolean;
9
+ digits?: number;
10
+ } | {
11
+ kind: "percent";
12
+ digits?: number;
13
+ } | {
14
+ kind: "date";
15
+ pattern?: string;
16
+ };
17
+ /**
18
+ * 应用格式化。非数值/无法解析时原样返回基础文本(降级不报错):
19
+ * - number:digits 小数位 + 可选千分位(12,345.60)
20
+ * - percent:×100 + % 后缀(digits 默认 2)
21
+ * - date:Date/时间戳/可解析字符串 → pattern(默认 YYYY-MM-DD);
22
+ * 字符串不可解析时原样返回(上游已格式化过的场景)
23
+ */
24
+ export declare function formatValue(value: unknown, format?: ColumnFormat): string;
25
+ /** 条件格式规则求值(声明式,见 ListColumn.rules) */
26
+ export interface StyleRule {
27
+ when: {
28
+ field: string;
29
+ op: ">" | ">=" | "<" | "<=" | "==" | "!=";
30
+ value: number | string;
31
+ };
32
+ /** 命中时合并进单元格样式(color/bold/backgroundColor 等) */
33
+ style: Record<string, unknown>;
34
+ }
35
+ export declare function evalStyleRule(row: Record<string, unknown>, when: StyleRule["when"]): boolean;
@@ -0,0 +1 @@
1
+ "use strict";function B(h,i){const d=h.length;if(d===0)return[];const p=h.reduce((e,c)=>e+c,0),a=p>0&&i>0?i/p:1,s=[];let f=0;for(let e=0;e<d;e++){const c=Math.max(0,h[e]*a);s.push({pos:f,size:c}),f+=c}return s}function K(h,i,d){const p=h.cells??[],a=Math.max(p.length,1),s=h.colWidthsMm?.length??Math.max(1,...p.map(t=>Array.isArray(t)?t.length:0)),f=h.colWidthsMm?.length?B(h.colWidthsMm,i):Array.from({length:s},(t,o)=>({pos:i*o/s,size:i/s})),e=t=>t<=0?0:t>=s?f[f.length-1].pos+f[f.length-1].size:f[t].pos,c=h.rowHeightsMm?.length?B(h.rowHeightsMm,d):Array.from({length:a},(t,o)=>({pos:d*o/a,size:d/a})),w=t=>t<=0?0:t>=a?c[c.length-1].pos+c[c.length-1].size:c[t].pos,M=new Set,S=(t,o)=>`${t}:${o}`,v=[],x=new Set,A=new Set,$=(t,o)=>`v${t}:${o}`,k=(t,o)=>`h${t}:${o}`;p.forEach((t,o)=>{if(!Array.isArray(t))return;let n=0;for(const u of t){for(;n<s&&M.has(S(o,n));)n++;if(n>=s)break;const C=Math.max(1,Math.min(u?.colSpan??1,s-n)),G=Math.max(1,u?.rowSpan??1),g=Math.min(a,o+G),m=Math.min(s,n+C);for(let r=o;r<g;r++)for(let l=n;l<m;l++)M.add(S(r,l));for(let r=n+1;r<m;r++)for(let l=o;l<g;l++)x.add($(r,l));for(let r=o+1;r<g;r++)for(let l=n;l<m;l++)A.add(k(r,l));const z=e(n),E=w(o);v.push({ri:o,ci:n,cell:u??{},xMm:z,yMm:E,widthMm:e(m)-z,heightMm:w(g)-E}),n=m}});const y=[];for(let t=1;t<s;t++){let o=-1;for(let n=0;n<=a;n++){const u=n<a&&!x.has($(t,n));u&&o<0&&(o=n),!u&&o>=0&&(y.push({kind:"v",pos:e(t),from:w(o),to:w(n)}),o=-1)}}for(let t=1;t<a;t++){let o=-1;for(let n=0;n<=s;n++){const u=n<s&&!A.has(k(t,n));u&&o<0&&(o=n),!u&&o>=0&&(y.push({kind:"h",pos:w(t),from:e(o),to:e(n)}),o=-1)}}return{columns:f,rows:c,cells:v,edges:y}}exports.resolveGridLayout=K;
@@ -0,0 +1,65 @@
1
+ function B(h, p) {
2
+ const d = h.length;
3
+ if (d === 0) return [];
4
+ const i = h.reduce((e, c) => e + c, 0), a = i > 0 && p > 0 ? p / i : 1, s = [];
5
+ let f = 0;
6
+ for (let e = 0; e < d; e++) {
7
+ const c = Math.max(0, h[e] * a);
8
+ s.push({ pos: f, size: c }), f += c;
9
+ }
10
+ return s;
11
+ }
12
+ function P(h, p, d) {
13
+ const i = h.cells ?? [], a = Math.max(i.length, 1), s = h.colWidthsMm?.length ?? Math.max(1, ...i.map((t) => Array.isArray(t) ? t.length : 0)), f = h.colWidthsMm?.length ? B(h.colWidthsMm, p) : Array.from({ length: s }, (t, o) => ({
14
+ pos: p * o / s,
15
+ size: p / s
16
+ })), e = (t) => t <= 0 ? 0 : t >= s ? f[f.length - 1].pos + f[f.length - 1].size : f[t].pos, c = h.rowHeightsMm?.length ? B(h.rowHeightsMm, d) : Array.from({ length: a }, (t, o) => ({
17
+ pos: d * o / a,
18
+ size: d / a
19
+ })), w = (t) => t <= 0 ? 0 : t >= a ? c[c.length - 1].pos + c[c.length - 1].size : c[t].pos, M = /* @__PURE__ */ new Set(), S = (t, o) => `${t}:${o}`, x = [], A = /* @__PURE__ */ new Set(), $ = /* @__PURE__ */ new Set(), v = (t, o) => `v${t}:${o}`, k = (t, o) => `h${t}:${o}`;
20
+ i.forEach((t, o) => {
21
+ if (!Array.isArray(t)) return;
22
+ let n = 0;
23
+ for (const u of t) {
24
+ for (; n < s && M.has(S(o, n)); ) n++;
25
+ if (n >= s) break;
26
+ const C = Math.max(1, Math.min(u?.colSpan ?? 1, s - n)), K = Math.max(1, u?.rowSpan ?? 1), g = Math.min(a, o + K), m = Math.min(s, n + C);
27
+ for (let r = o; r < g; r++)
28
+ for (let l = n; l < m; l++)
29
+ M.add(S(r, l));
30
+ for (let r = n + 1; r < m; r++)
31
+ for (let l = o; l < g; l++) A.add(v(r, l));
32
+ for (let r = o + 1; r < g; r++)
33
+ for (let l = n; l < m; l++) $.add(k(r, l));
34
+ const z = e(n), E = w(o);
35
+ x.push({
36
+ ri: o,
37
+ ci: n,
38
+ cell: u ?? {},
39
+ xMm: z,
40
+ yMm: E,
41
+ widthMm: e(m) - z,
42
+ heightMm: w(g) - E
43
+ }), n = m;
44
+ }
45
+ });
46
+ const y = [];
47
+ for (let t = 1; t < s; t++) {
48
+ let o = -1;
49
+ for (let n = 0; n <= a; n++) {
50
+ const u = n < a && !A.has(v(t, n));
51
+ u && o < 0 && (o = n), !u && o >= 0 && (y.push({ kind: "v", pos: e(t), from: w(o), to: w(n) }), o = -1);
52
+ }
53
+ }
54
+ for (let t = 1; t < a; t++) {
55
+ let o = -1;
56
+ for (let n = 0; n <= s; n++) {
57
+ const u = n < s && !$.has(k(t, n));
58
+ u && o < 0 && (o = n), !u && o >= 0 && (y.push({ kind: "h", pos: w(t), from: e(o), to: e(n) }), o = -1);
59
+ }
60
+ }
61
+ return { columns: f, rows: c, cells: x, edges: y };
62
+ }
63
+ export {
64
+ P as r
65
+ };
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./style-B3vxGDZd.cjs"),ne=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function B(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function re(e,n,r,t){const i=e[n];i!=null&&(typeof i!="number"||!Number.isFinite(i))&&t.push({path:`${r}.${n}`,message:`应为有限数字,实际 ${JSON.stringify(i)}`})}function I(e,n,r,t=[]){if(!B(e)){r.push({path:n,message:"组件应为对象"});return}const i=e.kind;typeof i!="string"?r.push({path:`${n}.kind`,message:"组件缺少 kind 字符串"}):ne.has(i)||t.push({path:`${n}.kind`,message:`未知组件类型 ${JSON.stringify(i)},将以兜底方式渲染`});for(const o of["leftMm","topMm","widthMm","heightMm"])re(e,o,n,r);e.leftMm!=null&&e.widthMm!=null&&(e.leftMm<-100||e.widthMm<0)&&r.push({path:n,message:"几何数值异常(leftMm<-100 或 widthMm<0)"});const d=e.grid;d!==void 0&&(!B(d)||!Array.isArray(d.cells)?r.push({path:`${n}.grid.cells`,message:"grid.cells 应为二维数组"}):d.cells.forEach((o,l)=>{if(!Array.isArray(o)){r.push({path:`${n}.grid.cells.${l}`,message:"行应为数组"});return}o.forEach((h,c)=>{h!=null&&B(h)&&Array.isArray(h.children)&&h.children.forEach((m,g)=>{I(m,`${n}.grid.cells.${l}.${c}.children.${g}`,r,t)})})}));const a=e.richParagraphs;a!==void 0&&(Array.isArray(a)?a.forEach((o,l)=>{(!B(o)||!Array.isArray(o.segments))&&r.push({path:`${n}.richParagraphs.${l}`,message:"段落缺少 segments 数组"})}):r.push({path:`${n}.richParagraphs`,message:"richParagraphs 应为数组"}))}function V(e,n,r,t=[]){if(!B(e)){r.push({path:n,message:"页应为对象"});return}const i=e.pageWidthMm,d=e.pageHeightMm;(typeof i!="number"||!(i>0&&i<3e3))&&r.push({path:`${n}.pageWidthMm`,message:`页宽非法: ${JSON.stringify(i)}`}),(typeof d!="number"||!(d>0&&d<5e3))&&r.push({path:`${n}.pageHeightMm`,message:`页高非法: ${JSON.stringify(d)}`});const a=e.components;a!==void 0&&!Array.isArray(a)?r.push({path:`${n}.components`,message:"components 应为数组"}):Array.isArray(a)&&a.forEach((o,l)=>I(o,`${n}.components.${l}`,r,t))}function U(e){const n=[],r=[],t=B(e)?e.pages:void 0;return Array.isArray(t)?t.forEach((i,d)=>V(i,`$.pages.${d}`,n,r)):n.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"}),{ok:n.length===0,errors:n,warnings:r}}function ie(e){const n=U(e);if(!n.ok){const r=n.errors.slice(0,3).map(t=>`${t.path}: ${t.message}`).join("; ");throw new Error(`渲染计划校验失败(${n.errors.length} 处): ${r}`)}return e.pages}function G(e){return{widthMm:e.widthMm,heightMm:e.heightMm,marginTopMm:e.marginTopMm??0,marginBottomMm:e.marginBottomMm??0,marginLeftMm:e.marginLeftMm??0,marginRightMm:e.marginRightMm??0,components:[]}}function oe(e,n){return n.heightMm-(e.marginBottomMm??n.marginBottomMm)}function ae(e,n){const t=(e.fontSizePt??s.DEFAULT_FONT_PT)*s.LINE_HEIGHT*25.4/72,i=(e.paddingMm??1)*2;return Math.max(e.rowHeightMm??0,n*t+i)}function se(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number")return String(e);if(typeof e=="boolean")return e?"是":"否";if(e instanceof Date)return e.toISOString().slice(0,10);try{return JSON.stringify(e)}catch{return String(e)}}function le(e,n){const r=e.fontSizePt??s.DEFAULT_FONT_PT,t=e.paddingMm??1,i=e.columns.map(g=>g.style?{align:"left",verticalAlign:"middle",...g.style}:{align:"left",verticalAlign:"middle"}),d=e.columns.map(g=>({bold:e.headerBold??!0,align:"center",verticalAlign:"middle",backgroundColor:e.headerBackgroundColor,...g.style||{}})),a=e.columns.map(g=>g.header),o=a.map((g,u)=>s.wrapText(g,e.columns[u].widthMm-t*2,{fontSizePt:r,bold:e.headerBold??!0},n)),l=Math.max(...o.map(g=>g.length),1),h=ae(e,l),c=a.map((g,u)=>({text:g,style:d[u]})),m=e.border===!1?{borderTop:!1,borderRight:!1,borderBottom:!1,borderLeft:!1}:{borderBottom:!0,borderLeft:!0,borderRight:!0,borderTop:!0};return{fontSizePt:r,paddingMm:t,cellStyles:i,borderStyle:m,headerHeightMm:h,headerGrid:{cells:[c],rowHeightsMm:[h]},columns:e.columns}}function de(e,n,r){const t=e.columns,i=new Array(t.length);let d=1;for(let c=0;c<t.length;c++)i[c]=se(n[t[c].field]);const a=new Array(t.length);for(let c=0;c<t.length;c++){const m=s.wrapText(i[c],t[c].widthMm-e.paddingMm*2,{fontSizePt:e.fontSizePt},r);a[c]=m,m.length>d&&(d=m.length)}const o=e.fontSizePt*s.LINE_HEIGHT*25.4/72,l=Math.max(e.rowHeightFloorMm,d*o+e.paddingMm*2),h=new Array(t.length);for(let c=0;c<t.length;c++)h[c]={text:i[c],style:e.cellStyles[c]};return{grid:{cells:[h],rowHeightsMm:[l]},heightMm:l}}function he(e,n,r={}){const t=typeof r=="number"?{mmPerRow:r}:r,i=t.mmPerRow??0,d=t.measurer??s.heuristicMeasurer,a=[],o=[];let l=0;const h=c=>`${c}_${(++l).toString(36)}`;for(const c of e.pages){const m=G(c),g=()=>oe(c,m),u=m.marginTopMm,f=()=>{o.push({pageWidthMm:m.widthMm,pageHeightMm:m.heightMm,marginTopMm:m.marginTopMm,marginBottomMm:m.marginBottomMm,marginLeftMm:m.marginLeftMm,marginRightMm:m.marginRightMm,components:m.components})};for(const b of c.components){if(b.kind!=="list"){m.components.push(b);continue}const M=b,C=n[M.dataset];Array.isArray(C)||a.push(`数据集 ${M.dataset} 未提供数据,列表 ${M.id??""} 输出为空`);const P=Array.isArray(C)?C:[],H=M.columns.reduce((y,w)=>y+w.widthMm,0),S=H>M.widthMm?M.widthMm/H:1,F=S===1?M:{...M,columns:M.columns.map(y=>({...y,widthMm:y.widthMm*S}))},_={...le(F,d),rowHeightFloorMm:F.rowHeightMm??0},z={kind:"rect",leftMm:M.leftMm,topMm:0,widthMm:M.widthMm,heightMm:_.headerHeightMm,grid:_.headerGrid,nid:h("listh"),style:_.borderStyle};let $=M.topMm;const p=(y,w)=>{y.components.push({...z,topMm:w})};p(m,$),$+=_.headerHeightMm+i;for(let y=0;y<P.length;y++){const w=de(_,P[y],d);if($+w.heightMm>g()){f();const T=G(c);m.components=T.components,m.heightMm=T.heightMm,F.headerEveryPage!==!1?(p(m,M.topMm),$=M.topMm+_.headerHeightMm):$=u}m.components.push({kind:"rect",leftMm:M.leftMm,topMm:$,widthMm:M.widthMm,heightMm:w.heightMm,grid:w.grid,nid:h("listr"),style:_.borderStyle}),$+=w.heightMm}}f()}return{plan:{schemaVersion:s.RENDER_PLAN_SCHEMA_VERSION,pages:o},warnings:a}}const ce={root:"mr-root",page:"mr-page",comp:"mr-comp",text:"mr-text",lines:"mr-lines",line:"mr-line",rich:"mr-rich",paragraph:"mr-paragraph",segment:"mr-segment",image:"mr-image",shape:"mr-shape",grid:"mr-grid",row:"mr-row",cell:"mr-cell",unknown:"mr-unknown"};function x(e,n){return n?.classNames?.[e]??ce[e]}class R{constructor(){this.props=[]}add(n,r){return r==null||r===!1||r===""?this:(this.props.push([n,String(r)]),this)}mm(n,r,t,i=2){return this.add(n,`${s.round(s.mmToPx(r,t),i)}px`)}toString(){let n="";for(const[r,t]of this.props)n+=`${r}:${t};`;return n}applyTo(n){const r=this.toString();r&&(n.style.cssText=r)}}function J(e,n,r){const t=n.style||{};e.add("color",t.color).add("background-color",t.backgroundColor).add("font-family",t.fontFamily).add("font-weight",t.bold?"700":void 0).add("font-style",t.italic?"italic":void 0).add("text-decoration",t.underline?"underline":void 0).add("letter-spacing",t.letterSpacing!=null?`${t.letterSpacing}pt`:void 0).add("opacity",t.opacity!=null?String(t.opacity):void 0).add("transform",t.rotateDeg?`rotate(${t.rotateDeg}deg)`:void 0);const i=s.resolveFontSize(t,r);e.add("font-size",`${s.round(i.fontSizePx,2)}px`)}function me(e,n,r,t,i){const d=i.createElement("table");if(d.className=x("grid",t),new R().add("width","100%").add("height","100%").add("border-collapse","collapse").add("table-layout",e.colWidthsMm?"fixed":"auto").applyTo(d),e.colWidthsMm){const h=i.createElement("colgroup");for(const c of e.colWidthsMm){const m=i.createElement("col");new R().mm("width",c,r).applyTo(m),h.appendChild(m)}d.appendChild(h)}const a=s.resolveBoxBorders(n.style),o=s.resolveStroke(n.style),l=a.inner?`${s.round(o.widthPt*r/72,2)}px solid ${o.color}`:"";return e.cells.forEach((h,c)=>{const m=i.createElement("tr");m.className=x("row",t),e.rowHeightsMm?.[c]!=null&&new R().mm("height",e.rowHeightsMm[c],r).applyTo(m),(h||[]).forEach(g=>{const u=i.createElement("td");u.className=x("cell",t),g?.colSpan&&(u.colSpan=g.colSpan),g?.rowSpan&&(u.rowSpan=g.rowSpan);const f=new R;if(l&&f.add("border",l),g?.style){const b=g.style;f.add("text-align",b.align).add("vertical-align",b.verticalAlign).add("background-color",b.backgroundColor).add("color",b.color).add("font-weight",b.bold?"700":void 0),f.add("font-size",`${s.round(s.resolveFontSize(b,r).fontSizePx,2)}px`)}if(f.applyTo(u),g?.text!=null&&(u.textContent=g.text),g?.children?.length)for(const b of g.children)u.appendChild(O(b,r,t,i));m.appendChild(u)}),d.appendChild(m)}),d}function ge(e,n,r,t){const i=t.createElement("div");i.className=x("text",r);const d=e.style||{},a=new R().add("text-align",d.align).add("display","flex").add("flex-direction","column").add("justify-content",d.verticalAlign==="middle"?"center":d.verticalAlign==="bottom"?"flex-end":"flex-start").add("overflow","hidden");if(J(a,e,n),a.applyTo(i),s.isRichText(e)){const o=t.createElement("div");o.className=x("rich",r);for(const l of e.richParagraphs){const h=t.createElement("div");h.className=x("paragraph",r),new R().add("text-align",l.align).add("line-height",l.lineHeight!=null?String(l.lineHeight):void 0).mm("margin-top",l.spaceBeforeMm??0,n).mm("margin-bottom",l.spaceAfterMm??0,n).mm("text-indent",l.indentMm??0,n).applyTo(h);for(const m of l.segments||[]){const g=t.createElement("span");if(g.className=x("segment",r),g.textContent=m.kind==="field"?m.field??"":m.text??"",m.style){const u=new R().add("color",m.style.color).add("font-weight",m.style.bold?"700":void 0);u.add("font-size",`${s.round(s.resolveFontSize(m.style,n).fontSizePx,2)}px`),u.applyTo(g)}h.appendChild(g)}o.appendChild(h)}return i.appendChild(o),i}if(Array.isArray(e.lines)&&e.lines.length>0){const o=t.createElement("div");o.className=x("lines",r),d.lineHeight!=null&&new R().add("line-height",String(d.lineHeight)).applyTo(o);for(const l of e.lines){const h=t.createElement("div");h.className=x("line",r),h.textContent=l,o.appendChild(h)}return i.appendChild(o),i}return i.textContent=e.text??"",i}function fe(e,n,r){const t=r.createElement("img");return t.className=x("image",n),t.src=e.imageData,new R().add("width","100%").add("height","100%").add("object-fit","contain").add("display","block").applyTo(t),t.alt=e.kind,t}function j(e,n,r,t){const i=t.createElement("div");i.className=x("shape",r);const d=e.style||{},a=s.resolveStroke(d),o=s.resolveBoxBorders(d),l=`${s.round(a.widthPt*n/72,2)}px solid ${a.color}`,h=new R;return e.grid||e.kind==="rect"?(o.top&&h.add("border-top",l),o.right&&h.add("border-right",l),o.bottom&&h.add("border-bottom",l),o.left&&h.add("border-left",l)):e.kind==="ellipse"?(o.inner&&h.add("border",l).add("border-radius","50%"),d.backgroundColor&&h.add("background-color",d.backgroundColor)):e.kind==="line"&&h.add("height","0").add("border-top",l),h.add("box-sizing","border-box").add("width","100%").add("height","100%"),h.applyTo(i),i}function O(e,n,r,t){const i=t.createElement("div");i.className=`${x("comp",r)} mr-kind-${e.kind}`;const d=new R().add("position","absolute").mm("left",e.leftMm,n).mm("top",e.topMm,n).mm("width",e.widthMm,n).mm("height",e.heightMm,n).add("box-sizing","border-box");if(J(d,e,n),d.applyTo(i),s.isImageBackedComponent(e))return i.appendChild(fe(e,r,t)),i;if(e.kind==="text")return i.appendChild(ge(e,n,r,t)),i;if(e.grid){const o=j(e,n,r,t);return o.appendChild(me(e.grid,e,n,r,t)),i.appendChild(o),i}if(e.kind==="line"||e.kind==="rect"||e.kind==="ellipse"||e.kind==="chart")return i.appendChild(j(e,n,r,t)),i;const a=t.createElement("div");return a.className=x("unknown",r),a.textContent=e.fallbackText??"",i.appendChild(a),i}function q(e,n,r,t){const i=t.createElement("div");i.className=x("page",r),new R().add("position","relative").mm("width",e.pageWidthMm,n).mm("height",e.pageHeightMm,n).add("background-color","#fff").add("overflow","hidden").add("box-sizing","border-box").applyTo(i);for(const d of e.components)i.appendChild(O(d,n,r,t));return i}function ue(e,n,r={}){const t=r.dpi??96,i=n.createElement("div");return i.className=x("root",r),i.dataset.schemaVersion=e.schemaVersion,e.pages.forEach(d=>{i.appendChild(q(d,t,r,n))}),i}function K(e){const{pageHeightsPx:n,viewportHeightPx:r,scrollTopPx:t,overscan:i=1,gapPx:d=0}=e,a=n.length;if(a===0)return{start:0,end:-1,padTopPx:0,padBottomPx:0};const o=Math.max(0,d),l=new Array(a+1);l[0]=0;for(let S=0;S<a;S++)l[S+1]=l[S]+Math.max(0,n[S]??0)+o;const h=l[a],c=Math.max(0,t);let m=0,g=0,u=a-1;for(;g<=u;){const S=g+u>>1;l[S]<=c?(m=S,g=S+1):u=S-1}const f=Math.max(0,Math.min(a-1,m-i)),b=l[m]+Math.max(0,r);let M=a-1;for(g=0,u=a-1;g<=u;){const S=g+u>>1;l[S+1]<b?g=S+1:(M=S,u=S-1)}const C=Math.min(a-1,M+i),P=l[f],H=Math.max(0,h-l[C+1]);return{start:f,end:C,padTopPx:P,padBottomPx:H}}const D=96/25.4;function W(e,n=96){const r=n/96*D;return{widthPx:Math.max(1,Math.round(e.pageWidthMm*r)),heightPx:Math.max(1,Math.round(e.pageHeightMm*r))}}function pe(e,n,r){const t=document.createElement("canvas"),{widthPx:i,heightPx:d}=W(e,r);t.width=Math.round(i*n),t.height=Math.round(d*n),t.style.width=`${i}px`,t.style.height=`${d}px`;const a=t.getContext("2d");if(!a)throw new Error("当前环境不支持 Canvas 2D(测试需真浏览器,见 e2e/canvas.spec.ts)");return a.scale(n,n),a.fillStyle="#ffffff",a.fillRect(0,0,i,d),{canvas:t,ctx:a}}function Me(e,n=96){return s.resolveFontSize(e,n).fontSizePx}function X(e,n,r,t,i,d,a,o="top"){e.font=`${n.bold?"bold ":""}${n.fontSizePx}px ${a}`,e.fillStyle=n.color,e.textBaseline="alphabetic";const l=n.fontSizePx*n.lineHeight,h=n.text===""?[""]:n.text.split(`
2
- `),c=h.length*l;let m=t;o==="middle"?m=t+(d-c)/2:o==="bottom"&&(m=t+d-c),h.forEach((g,u)=>{e.textAlign=n.align==="center"?"center":n.align==="right"?"right":"left";const f=n.align==="center"?r+i/2:n.align==="right"?r+i:r;e.fillText(g,f,m+u*l+n.fontSizePx*.8,i)}),e.textAlign="left"}function Te(e,n,r,t,i,d,a,o,l,h,c){const m=s.resolveGridLayout(n,d/o,a/o),g=s.resolveBoxBorders(r.style),u=s.resolveStroke(r.style);for(const f of m.cells){const b=f.cell.style?.backgroundColor;b&&(e.fillStyle=b,e.fillRect(t+f.xMm*o,i+f.yMm*o,f.widthMm*o,f.heightMm*o))}if(g.inner){e.strokeStyle=u.color,e.lineWidth=s.ptToPx(u.widthPt,l);for(const f of m.edges)e.beginPath(),f.kind==="v"?(e.moveTo(t+f.pos*o,i+f.from*o),e.lineTo(t+f.pos*o,i+f.to*o)):(e.moveTo(t+f.from*o,i+f.pos*o),e.lineTo(t+f.to*o,i+f.pos*o)),e.stroke();e.beginPath(),g.top&&(e.moveTo(t,i),e.lineTo(t+d,i)),g.right&&(e.moveTo(t+d,i),e.lineTo(t+d,i+a)),g.bottom&&(e.moveTo(t+d,i+a),e.lineTo(t,i+a)),g.left&&(e.moveTo(t,i+a),e.lineTo(t,i)),e.stroke()}for(const f of m.cells){const b=typeof f.cell.text=="string"?f.cell.text:"";if(!b)continue;const M=f.cell.style,C=M?.fontSize??s.DEFAULT_FONT_PT,P=s.wrapText(b,f.widthMm-1,{fontSizePt:C},c).join(`
3
- `);X(e,{text:P,fontSizePx:s.resolveFontSize(M,l).fontSizePx,bold:M?.bold??!1,color:M?.color??s.resolveTextColor(r.style,s.DEFAULT_TEXT_COLOR),align:M?.align??"left",lineHeight:s.LINE_HEIGHT},t+(f.xMm+.5)*o,i+f.yMm*o,Math.max(0,(f.widthMm-1)*o),f.heightMm*o,h,M?.verticalAlign??"middle")}}function Z(e,n,r,t,i,d){const a=n.leftMm*r,o=n.topMm*r,l=n.widthMm*r,h=n.heightMm*r,c=n.style??{};if(n.grid){Te(e,n.grid,n,a,o,l,h,r,t,i,d);return}switch(n.kind){case"text":{const m=c.fontSize??s.DEFAULT_FONT_PT,g=s.isRichText(n)?n.richParagraphs.map(u=>(u.segments??[]).map(f=>f.text??f.field??"").join("")).join(`
4
- `):Array.isArray(n.lines)&&n.lines.length>0?n.lines.join(`
5
- `):s.wrapText(n.text??"",n.widthMm,{fontSizePt:m},d).join(`
6
- `);X(e,{text:g,fontSizePx:s.resolveFontSize(c,t).fontSizePx,bold:c.bold??!1,color:s.resolveTextColor(c),align:c.align??"left",lineHeight:s.resolveLineHeight(c)},a,o,l,h,i,c.verticalAlign);break}case"rect":{const m=s.resolveStroke(c),g=s.resolveBoxBorders(c);c.backgroundColor&&(e.fillStyle=c.backgroundColor,e.fillRect(a,o,l,h)),g.inner&&(e.strokeStyle=m.color,e.lineWidth=s.ptToPx(m.widthPt,t),e.beginPath(),g.top&&(e.moveTo(a,o),e.lineTo(a+l,o)),g.right&&(e.moveTo(a+l,o),e.lineTo(a+l,o+h)),g.bottom&&(e.moveTo(a+l,o+h),e.lineTo(a,o+h)),g.left&&(e.moveTo(a,o+h),e.lineTo(a,o)),e.stroke());break}case"line":{const m=s.resolveStroke({...c,borderColor:c.lineColor??c.borderColor});e.strokeStyle=m.color,e.lineWidth=s.ptToPx(m.widthPt,t),e.beginPath(),e.moveTo(a,o+h/2),e.lineTo(a+l,o+h/2),e.stroke();break}case"ellipse":{const m=s.resolveStroke(c);e.strokeStyle=m.color,e.lineWidth=s.ptToPx(m.widthPt,t),c.backgroundColor&&(e.fillStyle=c.backgroundColor,e.beginPath(),e.ellipse(a+l/2,o+h/2,l/2,h/2,0,0,Math.PI*2),e.fill()),e.beginPath(),e.ellipse(a+l/2,o+h/2,l/2,h/2,0,0,Math.PI*2),e.stroke();break}}}function be(e,n={}){const r=n.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),t=n.dpi??96,i=t/96*D,d=n.fontFamily??'"Microsoft YaHei", sans-serif',a=n.measurer??s.heuristicMeasurer,o=Math.max(0,n.start??0),l=Math.min(e.pages.length-1,n.end??e.pages.length-1),h=[];for(let c=o;c<=l;c++){const m=e.pages[c],{canvas:g,ctx:u}=pe(m,r,t);for(const f of m.components)Z(u,f,i,t,d,a);h.push(g)}return{canvases:h}}function ye(e,n={}){const r=n.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),t=n.dpi??96,i=t/96*D,d=n.fontFamily??'"Microsoft YaHei", sans-serif',a=n.measurer??s.heuristicMeasurer,o=n.overscan??1,l=n.gapPx??18,h=n.pagesPerFrame??1,c=e.pages.map(p=>p.pageHeightMm*i),m=Math.max(1,...e.pages.map(p=>p.pageWidthMm*i)),g={start:0,end:-1};let u=null,f=null,b=null,M=null,C=[],P=0,H=[];function S(){const p=u;p.innerHTML="",f=document.createElement("div"),f.style.cssText=`width:${m}px;margin:0 auto;`,b=document.createElement("div"),M=document.createElement("div"),f.appendChild(b),C=[];const y=Math.min(e.pages.length,3+o*2);for(let w=0;w<y;w++){const T=document.createElement("div");T.style.cssText=`margin:0 auto ${l}px;box-shadow:0 2px 8px rgba(0,0,0,.35);background:#fff;`,f.appendChild(T),C.push(T)}f.appendChild(M),p.appendChild(f)}function F(p,y){const w=e.pages[y],{widthPx:T,heightPx:k}=W(w,t);let A=p.firstElementChild;(!A||A.tagName!=="CANVAS")&&(A=document.createElement("canvas"),p.innerHTML="",p.appendChild(A)),A.width=Math.round(T*r),A.height=Math.round(k*r),A.style.width=`${T}px`,A.style.height=`${k}px`;const N=A.getContext("2d");if(N){N.setTransform(1,0,0,1,0,0),N.scale(r,r),N.fillStyle="#ffffff",N.fillRect(0,0,T,k);for(const te of w.components)Z(N,te,i,t,d,a);A.dataset.canvasPage=String(y),p.style.height=`${k}px`,p.style.width=`${T}px`}}function _(p){g.start=p.start,g.end=p.end,b.style.height=`${p.start*l+c.slice(0,p.start).reduce((T,k)=>T+k,0)}px`;const y=e.pages.length-1-p.end;M.style.height=`${y*l+c.slice(p.end+1).reduce((T,k)=>T+k,0)}px`;const w=p.end-p.start+1;C.forEach((T,k)=>{if(k<w){T.style.display="";const A=p.start+k;T.style.height=`${c[A]??0}px`}else T.style.display="none"}),H=[];for(let T=p.start;T<=p.end;T++){const k=C[T-p.start];if(!k)continue;k.firstElementChild?.dataset?.canvasPage!==String(T)&&H.push(T)}z()}function z(){P||H.length===0||(P=requestAnimationFrame(()=>{P=0;let p=Math.max(1,h);for(;H.length>0&&p-- >0;){const y=H.shift(),w=C[y-g.start];w&&F(w,y)}H.length>0&&z()}))}function $(){P||(P=requestAnimationFrame(()=>{P=0;const p=u,y=K({pageHeightsPx:c,viewportHeightPx:p.clientHeight,scrollTopPx:p.scrollTop,overscan:o,gapPx:l});y.start!==g.start||y.end!==g.end?_(y):z()}))}return{attach(p){u=p,S(),p.addEventListener("scroll",$,{passive:!0}),$()},destroy(){P&&cancelAnimationFrame(P),P=0,u?.removeEventListener("scroll",$),H=[],f?.remove(),u=null},window(){return{...g}}}}function v(e,n){return typeof e=="number"&&Number.isFinite(e)?e:n}function E(e,n=""){return typeof e=="string"?e:n}function L(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Se(e){return e==="Center"?"center":e==="Right"?"right":"left"}function we(e){return e==="Center"?"middle":e==="Bottom"?"bottom":"top"}function ve(e){const n=parseFloat(E(e.FontSize,"10.5"));return{fontSize:Number.isFinite(n)?n:10.5,fontFamily:E(e.FontFamily,"黑体")||void 0,bold:E(e.FontWeight)==="bold"||void 0,italic:E(e.FontStyle)==="italic"||void 0,underline:e.Underline===!0||void 0,color:E(e.FontColor)||void 0,backgroundColor:E(e.BackgroundColor)||void 0,align:Se(E(e.HorAlignment,"Left")),verticalAlign:we(E(e.VertAlignment,"Top")),lineHeight:(()=>{const r=parseFloat(E(e.RowSpace,"1"));return Number.isFinite(r)&&r!==1?r:void 0})(),borderColor:E(e.BorderColor)||void 0,borderTop:e.BorderTop!==!1,borderRight:e.BorderRight!==!1,borderBottom:e.BorderBottom!==!1,borderLeft:e.BorderLeft!==!1}}function Pe(e,n){const r=E(e.uitype),t={kind:"text",leftMm:v(e.left,0),topMm:v(e.top,0),widthMm:v(e.width,40),heightMm:v(e.height,8),nid:E(e.nid)||void 0,style:ve(e)};switch(r){case"text":{t.kind="text";const i=e.Text??e.text??e.Value;t.text=i==null?"":String(i);const d=e.Lines??e.lines;return Array.isArray(d)&&(t.lines=d.map(a=>String(a))),t}case"richtext":return t.kind="text",t.text=E(e.Text),n.push(`富文本 ${t.nid??""} 导入为纯文本(版式细节可能损失)`),t;case"image":case"barcode":case"qrcode":case"chart":return t.kind=r==="image"?"image":r,t.fallbackText=`[${r}]`,n.push(`图片类组件 ${t.nid??""} 需运行时数据(imageData),已导入为占位`),t;case"table":{t.kind="rect";const i=e.Cells??e.cells;if(Array.isArray(i)){const d={cells:i.map(a=>Array.isArray(a)?a.map(o=>({text:L(o)?E(o.Text??o.text):"",colSpan:L(o)?v(o.ColSpan,1):1})):[])};t.grid=d}else t.fallbackText="[table]",n.push(`表格 ${t.nid??""} 缺少 Cells,导入为空框`);return t}case"subreport":return n.push(`子报表 ${t.nid??""} 暂不支持导入,已跳过`),null;default:return E(e.ShapeType)==="hline"||r==="hline"||r==="vline"?(t.kind="line",t):r==="rect"||r==="oval"||r==="shape"?(t.kind=r==="oval"?"ellipse":"rect",t):(n.push(`未知组件类型 ${r},已跳过`),null)}}function Ee(e){const n=[];let r=null;if(typeof e=="string")try{const h=JSON.parse(e);L(h)&&(r=h)}catch{return{template:{pages:[]},warnings:["content 不是合法 JSON"]}}else L(e)&&(r=e);if(!r)return{template:{pages:[]},warnings:["content 为空"]};const t=L(r.GlobalConfig)?r.GlobalConfig:{},i=v(t.paperWidthMm,210),d=v(t.paperHeightMm,297),a={top:v(t.marginTop,10),bottom:v(t.marginBottom,10),left:v(t.marginLeft,10),right:v(t.marginRight,10)},o=Array.isArray(r.children)?r.children.filter(h=>L(h)&&E(h.uitype)==="page"):[];o.length===0&&n.push("content 中没有 uitype=page 的页节点");const l=o.map(h=>{const c=h,m=Array.isArray(c.children)?c.children:[],g=[];for(const u of m){if(!L(u))continue;const f=Pe(u,n);f&&g.push(f)}return{widthMm:v(c.width,i),heightMm:v(c.DesignHeight,d),marginTopMm:v(c.MarginTop,a.top),marginBottomMm:v(c.MarginBottom,a.bottom),marginLeftMm:v(c.MarginLeft,a.left),marginRightMm:v(c.MarginRight,a.right),components:g}});return l.length===0&&(n.push("转换结果为空页,已回退一张空白页"),l.push({widthMm:i,heightMm:d,...a,components:[]})),{template:{pages:l},warnings:n}}function Y(e,n,r){let t,i;if(typeof e=="string"){const d=s.PAPER_SIZES[e];if(!d)throw new Error(`未知纸张预设 "${e}"(可用:${Object.keys(s.PAPER_SIZES).join("/")})`);t=d.widthMm,i=d.heightMm}else typeof e=="number"?(t=e,i=n??297):(t=e.widthMm,i=e.heightMm);return r?{widthMm:i,heightMm:t}:{widthMm:t,heightMm:i}}class Q{constructor(){this.pages=[],this.pending=null}page(n="a4",r={},t){this.collect();const d=t!=null&&!("margins"in t)&&!("landscape"in t)&&("marginTopMm"in t||"marginBottomMm"in t||"marginLeftMm"in t||"marginRightMm"in t)?{margins:t}:t??{},{widthMm:a,heightMm:o}=Y(n,typeof r=="number"?r:void 0,d.landscape),l=d.margins??{};return this.pending=new ee(this,{widthMm:a,heightMm:o,marginTopMm:l.marginTopMm??10,marginBottomMm:l.marginBottomMm??10,marginLeftMm:l.marginLeftMm??10,marginRightMm:l.marginRightMm??10}),this.pending}collect(){this.pending&&(this.pages.push(this.pending.buildPage()),this.pending=null)}build(){if(this.collect(),this.pages.length===0)throw new Error("模板至少需要一页:先调用 .page() 添加内容");return{pages:this.pages}}}class ee{constructor(n,r){this.parent=n,this.page=r,this.components=[]}text(n,r={},t={}){return this.components.push({kind:"text",leftMm:r.leftMm??0,topMm:r.topMm??0,widthMm:r.widthMm??60,heightMm:r.heightMm??8,text:n,style:t}),this}list(n,r,t,i={}){return this.components.push({kind:"list",leftMm:r.leftMm??10,topMm:r.topMm??30,widthMm:r.widthMm??180,dataset:n,columns:t,...i}),this}rect(n,r={}){return this.components.push({kind:"rect",...n,style:r}),this}line(n,r,t,i={}){return this.components.push({kind:"line",leftMm:n,topMm:r,widthMm:t,heightMm:.5,style:i}),this}barcode(n,r){return this.components.push({kind:"barcode",leftMm:r.leftMm??0,topMm:r.topMm??0,widthMm:r.widthMm??40,heightMm:r.heightMm??12,fallbackText:n}),this}qrcode(n,r,t,i){return this.components.push({kind:"qrcode",leftMm:t,topMm:i,widthMm:r,heightMm:r,fallbackText:n}),this}buildPage(){return{...this.page,components:this.components}}done(){return this.parent}build(){return this.done().build()}}function xe(){return new Q}exports.CSS_DPI=s.CSS_DPI;exports.DEFAULT_BORDER_PT=s.DEFAULT_BORDER_PT;exports.DEFAULT_FONT_PT=s.DEFAULT_FONT_PT;exports.DEFAULT_STROKE_COLOR=s.DEFAULT_STROKE_COLOR;exports.DEFAULT_TEXT_COLOR=s.DEFAULT_TEXT_COLOR;exports.LINE_HEIGHT=s.LINE_HEIGHT;exports.MM_PER_INCH=s.MM_PER_INCH;exports.PAPER_SIZES=s.PAPER_SIZES;exports.RENDER_PLAN_SCHEMA_VERSION=s.RENDER_PLAN_SCHEMA_VERSION;exports.SCHEMA_VERSION_JH4J=s.SCHEMA_VERSION_JH4J;exports.SCHEMA_VERSION_LOCAL=s.SCHEMA_VERSION_LOCAL;exports.SCHEMA_VERSION_MACH=s.SCHEMA_VERSION_MACH;exports.charWidthEm=s.charWidthEm;exports.createCanvasMeasurer=s.createCanvasMeasurer;exports.createHeuristicMeasurer=s.createHeuristicMeasurer;exports.heuristicMeasurer=s.heuristicMeasurer;exports.isImageBackedComponent=s.isImageBackedComponent;exports.isRichText=s.isRichText;exports.measureTextMm=s.measureTextMm;exports.mmToPx=s.mmToPx;exports.mmToPxFactor=s.mmToPxFactor;exports.ptToPx=s.ptToPx;exports.pxToMm=s.pxToMm;exports.resolveBoxBorders=s.resolveBoxBorders;exports.resolveFontSize=s.resolveFontSize;exports.resolveGridLayout=s.resolveGridLayout;exports.resolveLineHeight=s.resolveLineHeight;exports.resolveStroke=s.resolveStroke;exports.resolveTextColor=s.resolveTextColor;exports.round=s.round;exports.toRenderPlan=s.toRenderPlan;exports.wrapText=s.wrapText;exports.PageBuilder=ee;exports.TemplateBuilder=Q;exports.assertRenderPlan=ie;exports.classOf=x;exports.computePageWindow=K;exports.createCanvasPager=ye;exports.createTemplate=xe;exports.importJh4jTemplateContent=Ee;exports.measurePageSizePx=W;exports.paginateTemplate=he;exports.planFontSizePx=Me;exports.renderComponent=O;exports.renderPage=q;exports.renderPlan=ue;exports.renderPlanToCanvas=be;exports.resolvePaper=Y;exports.validateComponent=I;exports.validatePage=V;exports.validateRenderPlan=U;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./style-Xq08-IsV.cjs"),ce=require("./grid-geometry-BXpOxznT.cjs");function se(e,t){return t!=null?e.toLocaleString("en-US",{minimumFractionDigits:t,maximumFractionDigits:t}):e.toLocaleString("en-US")}function Pe(e,t){const r=(n,o=2)=>String(n).padStart(o,"0");return t.replace(/YYYY/g,String(e.getFullYear())).replace(/MM/g,r(e.getMonth()+1)).replace(/DD/g,r(e.getDate())).replace(/hh/g,r(e.getHours())).replace(/mm/g,r(e.getMinutes())).replace(/ss/g,r(e.getSeconds()))}function K(e,t){if(e==null||e===""||!t)return String(e??"");switch(t.kind){case"number":{const r=typeof e=="number"?e:Number(String(e).replace(/,/g,""));return Number.isFinite(r)?t.thousands===!1?r.toFixed(t.digits??0).replace(/\.?0+$/,"")||String(r):se(r,t.digits):String(e)}case"percent":{const r=typeof e=="number"?e:Number(String(e).replace(/,/g,""));if(!Number.isFinite(r))return String(e);const n=t.digits??2;return`${se(r*100,n)}%`}case"date":{const r=t.pattern??"YYYY-MM-DD",n=e instanceof Date?e:new Date(e);return Number.isNaN(n.getTime())?String(e):Pe(n,r)}default:return String(e)}}function he(e,t){const r=e[t.field];if(typeof t.value=="number"){const s=typeof r=="number"?r:Number(r);if(!Number.isFinite(s))return!1;switch(t.op){case">":return s>t.value;case">=":return s>=t.value;case"<":return s<t.value;case"<=":return s<=t.value;case"==":return s===t.value;case"!=":return s!==t.value}}const n=String(r??""),o=String(t.value);switch(t.op){case"==":return n===o;case"!=":return n!==o;case">":return n>o;case">=":return n>=o;case"<":return n<o;case"<=":return n<=o}return!1}const Ee=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function W(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ce(e,t,r,n){const o=e[t];o!=null&&(typeof o!="number"||!Number.isFinite(o))&&n.push({path:`${r}.${t}`,message:`应为有限数字,实际 ${JSON.stringify(o)}`})}function X(e,t,r,n=[]){if(!W(e)){r.push({path:t,message:"组件应为对象"});return}const o=e.kind;typeof o!="string"?r.push({path:`${t}.kind`,message:"组件缺少 kind 字符串"}):Ee.has(o)||n.push({path:`${t}.kind`,message:`未知组件类型 ${JSON.stringify(o)},将以兜底方式渲染`});for(const i of["leftMm","topMm","widthMm","heightMm"])Ce(e,i,t,r);e.leftMm!=null&&e.widthMm!=null&&(e.leftMm<-100||e.widthMm<0)&&r.push({path:t,message:"几何数值异常(leftMm<-100 或 widthMm<0)"});const s=e.grid;s!==void 0&&(!W(s)||!Array.isArray(s.cells)?r.push({path:`${t}.grid.cells`,message:"grid.cells 应为二维数组"}):s.cells.forEach((i,c)=>{if(!Array.isArray(i)){r.push({path:`${t}.grid.cells.${c}`,message:"行应为数组"});return}i.forEach((h,m)=>{h!=null&&W(h)&&Array.isArray(h.children)&&h.children.forEach((g,l)=>{X(g,`${t}.grid.cells.${c}.${m}.children.${l}`,r,n)})})}));const a=e.richParagraphs;a!==void 0&&(Array.isArray(a)?a.forEach((i,c)=>{(!W(i)||!Array.isArray(i.segments))&&r.push({path:`${t}.richParagraphs.${c}`,message:"段落缺少 segments 数组"})}):r.push({path:`${t}.richParagraphs`,message:"richParagraphs 应为数组"}))}function me(e,t,r,n=[]){if(!W(e)){r.push({path:t,message:"页应为对象"});return}const o=e.pageWidthMm,s=e.pageHeightMm;(typeof o!="number"||!(o>0&&o<3e3))&&r.push({path:`${t}.pageWidthMm`,message:`页宽非法: ${JSON.stringify(o)}`}),(typeof s!="number"||!(s>0&&s<5e3))&&r.push({path:`${t}.pageHeightMm`,message:`页高非法: ${JSON.stringify(s)}`});const a=e.components;a!==void 0&&!Array.isArray(a)?r.push({path:`${t}.components`,message:"components 应为数组"}):Array.isArray(a)&&a.forEach((i,c)=>X(i,`${t}.components.${c}`,r,n))}function ge(e){const t=[],r=[],n=W(e)?e.pages:void 0;if(!Array.isArray(n))t.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{n.forEach((s,a)=>me(s,`$.pages.${a}`,t,r)),n.length>2e3&&r.push({path:"$.pages",message:`页数异常大(${n.length} 页),渲染与打印耗时可能显著增加`});const o=n.reduce((s,a)=>s+(W(a)&&Array.isArray(a.components)?a.components.length:0),0);o>5e4&&r.push({path:"$.pages",message:`组件总数异常大(${o} 个),可能触发浏览器性能限制`})}return{ok:t.length===0,errors:t,warnings:r}}function ke(e){const t=ge(e);if(!t.ok){const r=t.errors.slice(0,3).map(n=>`${n.path}: ${n.message}`).join("; ");throw new Error(`渲染计划校验失败(${t.errors.length} 处): ${r}`)}return e.pages}function ae(e){return{widthMm:e.widthMm,heightMm:e.heightMm,marginTopMm:e.marginTopMm??0,marginBottomMm:e.marginBottomMm??0,marginLeftMm:e.marginLeftMm??0,marginRightMm:e.marginRightMm??0,components:[]}}function Ae(e,t){return t.heightMm-(e.marginBottomMm??t.marginBottomMm)}function Re(e,t){const n=(e.fontSizePt??d.DEFAULT_FONT_PT)*d.LINE_HEIGHT*25.4/72,o=(e.paddingMm??1)*2;return Math.max(e.rowHeightMm??0,t*n+o)}function q(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number")return String(e);if(typeof e=="boolean")return e?"是":"否";if(e instanceof Date)return e.toISOString().slice(0,10);try{return JSON.stringify(e)}catch{return String(e)}}function He(e,t){const r=e.fontSizePt??d.DEFAULT_FONT_PT,n=e.paddingMm??1,o=e.columns.map(l=>l.style?{align:"left",verticalAlign:"middle",...l.style}:{align:"left",verticalAlign:"middle"}),s=e.columns.map(l=>({bold:e.headerBold??!0,align:"center",verticalAlign:"middle",backgroundColor:e.headerBackgroundColor,...l.style||{}})),a=e.columns.map(l=>l.header),i=a.map((l,u)=>d.wrapText(l,e.columns[u].widthMm-n*2,{fontSizePt:r,bold:e.headerBold??!0},t)),c=Math.max(...i.map(l=>l.length),1),h=Re(e,c),m=a.map((l,u)=>({text:l,style:s[u]})),g=e.border===!1?{borderTop:!1,borderRight:!1,borderBottom:!1,borderLeft:!1}:{borderBottom:!0,borderLeft:!0,borderRight:!0,borderTop:!0};return{fontSizePt:r,paddingMm:n,cellStyles:o,borderStyle:g,headerHeightMm:h,headerGrid:{cells:[m],rowHeightsMm:[h]},columns:e.columns}}function le(e,t,r){const n=e.columns,o=new Array(n.length);let s=1;for(let m=0;m<n.length;m++){const g=n[m];o[m]=g.format?K(t[g.field],g.format):q(t[g.field])}const a=new Array(n.length);for(let m=0;m<n.length;m++){const g=d.wrapText(o[m],n[m].widthMm-e.paddingMm*2,{fontSizePt:e.fontSizePt},r);a[m]=g,g.length>s&&(s=g.length)}const i=e.fontSizePt*d.LINE_HEIGHT*25.4/72,c=Math.max(e.rowHeightFloorMm,s*i+e.paddingMm*2),h=new Array(n.length);for(let m=0;m<n.length;m++){const g=n[m];let l=e.cellStyles[m];if(g.rules){for(const u of g.rules)if(he(t,u.when)){l={...l??{},...u.style};break}}h[m]={text:o[m],style:l}}return{grid:{cells:[h],rowHeightsMm:[c]},heightMm:c}}function Ne(e,t,r={}){const n=typeof r=="number"?{mmPerRow:r}:r,o=n.mmPerRow??0,s=n.measurer??d.heuristicMeasurer,a=[],i=[];let c=0;const h=g=>`${g}_${(++c).toString(36)}`,m=[];for(const g of e.pages){const l=ae(g),u=()=>Ae(g,l),f=l.marginTopMm,T=[],R=()=>{if(i.push({pageWidthMm:l.widthMm,pageHeightMm:l.heightMm,marginTopMm:l.marginTopMm,marginBottomMm:l.marginBottomMm,marginLeftMm:l.marginLeftMm,marginRightMm:l.marginRightMm,components:l.components}),T.length>0){const x=i.length;for(const S of T){const C={...S,text:String(S.text??"").replace(/\{page\}/g,String(x))};i[i.length-1].components.push(C),C.text.includes("{totalPages}")&&m.push(C)}}};for(const x of g.components){if(x.kind!=="list"){if(x.kind==="text"&&typeof x.text=="string"){const M=x.text;if(M.includes("{page}")||M.includes("{totalPages}")){T.push(x);continue}}l.components.push(x);continue}const S=x,C=t[S.dataset];Array.isArray(C)||a.push(`数据集 ${S.dataset} 未提供数据,列表 ${S.id??""} 输出为空`);const w=Array.isArray(C)?C:[],V=S.columns.reduce((M,b)=>M+b.widthMm,0),U=V>S.widthMm?S.widthMm/V:1,v=U===1?S:{...S,columns:S.columns.map(M=>({...M,widthMm:M.widthMm*U}))},H={...He(v,s),rowHeightFloorMm:v.rowHeightMm??0},G={kind:"rect",leftMm:S.leftMm,topMm:0,widthMm:S.widthMm,heightMm:H.headerHeightMm,grid:H.headerGrid,nid:h("listh"),style:H.borderStyle};let p=S.topMm;const N=(M,b)=>{M.components.push({...G,topMm:b})};N(l,p),p+=H.headerHeightMm+o;const B=M=>{if(p+M>u()){R();const b=ae(g);l.components=b.components,l.heightMm=b.heightMm,v.headerEveryPage!==!1?(N(l,S.topMm),p=S.topMm+H.headerHeightMm):p=f}},y=(M,b,P)=>{B(b),l.components.push({kind:"rect",leftMm:S.leftMm,topMm:p,widthMm:S.widthMm,heightMm:b,grid:M,nid:h(P),style:H.borderStyle}),p+=b},$=()=>le(H,{},s).heightMm,k=(M,b,P,E)=>{const L=[],oe=Math.max(1,Math.min(E,v.columns.length));L.push({text:M,colSpan:oe,style:{bold:!0,...P}});for(let Y=oe;Y<v.columns.length;Y++){const ve=v.columns[Y];L.push({text:b.get(ve.field)??"",style:P})}const xe=H.fontSizePt*d.LINE_HEIGHT*25.4/72,ie=Math.max(H.rowHeightFloorMm,xe+H.paddingMm*2);return{grid:{cells:[L],rowHeightsMm:[ie]},heightMm:ie}},D=(M,b)=>{let P=0;for(const E of M){const L=typeof E[b]=="number"?E[b]:Number(E[b]);Number.isFinite(L)&&(P+=L)}return P},J=(M,b)=>{const P=v.columns.find(E=>E.field===b);return K(D(M,b),P?.format??{kind:"number",thousands:!0})},z=v.groupBy,we=typeof v.grandTotal=="object"&&v.grandTotal.fields||z?.subtotal||[],te=v.columns.findIndex(M=>we.includes(M.field)),ne=te>0?te:1,j=[];if(z){let M=null,b=[];const P=()=>{if(b.length===0)return;const E=q(b[0][z.field]);j.push({kind:"groupHeader",label:(z.headerTemplate??"{value}").replace(/\{value\}/g,E)});for(const L of b)j.push({kind:"row",row:L});z.subtotal&&z.subtotal.length>0&&j.push({kind:"subtotal",label:z.subtotalLabel??"小计",rows:b})};for(const E of w){const L=q(E[z.field]);M===null&&(M=L),L!==M&&(P(),b=[],M=L),b.push(E)}P()}else for(const M of w)j.push({kind:"row",row:M});const re=$();for(const M of j)if(M.kind==="row"){const b=le(H,M.row,s);y(b.grid,b.heightMm,"listr")}else if(M.kind==="groupHeader"){const b=k(M.label,new Map,z?.headerStyle??{},v.columns.length);z?.keepWithNext!==!1&&p+b.heightMm+re>u()&&B(b.heightMm+re),y(b.grid,b.heightMm,"listg")}else if(M.kind==="subtotal"){const b=new Map;for(const E of z.subtotal??[])b.set(E,J(M.rows,E));const P=k(M.label,b,z?.subtotalStyle??{},ne);y(P.grid,P.heightMm,"listst")}if(v.grandTotal){const M=typeof v.grandTotal=="object"?v.grandTotal:void 0,b=M?.fields??z?.subtotal??[];if(b.length>0){const P=new Map;for(const L of b)P.set(L,J(w,L));const E=k(M?.label??"合计",P,M?.style??{},ne);y(E.grid,E.heightMm,"listgt")}else a.push(`列表 ${S.id??""} 配置了 grandTotal 但未提供合计字段(groupBy.subtotal 或 grandTotal.fields)`)}}R()}for(const g of m){const l=g.text;typeof l=="string"&&l.includes("{totalPages}")&&(g.text=l.replace(/\{totalPages\}/g,String(i.length)))}return{plan:{schemaVersion:d.RENDER_PLAN_SCHEMA_VERSION,pages:i},warnings:a}}const $e={root:"mr-root",page:"mr-page",comp:"mr-comp",text:"mr-text",lines:"mr-lines",line:"mr-line",rich:"mr-rich",paragraph:"mr-paragraph",segment:"mr-segment",image:"mr-image",shape:"mr-shape",grid:"mr-grid",row:"mr-row",cell:"mr-cell",unknown:"mr-unknown"};function F(e,t){return t?.classNames?.[e]??$e[e]}class I{constructor(){this.props=[]}add(t,r){return r==null||r===!1||r===""?this:(this.props.push([t,String(r)]),this)}mm(t,r,n,o=2){return this.add(t,`${d.round(d.mmToPx(r,n),o)}px`)}toString(){let t="";for(const[r,n]of this.props)t+=`${r}:${n};`;return t}applyTo(t){const r=this.toString();r&&(t.style.cssText=r)}}function fe(e,t,r){const n=t.style||{};e.add("color",n.color).add("background-color",n.backgroundColor).add("font-family",n.fontFamily).add("font-weight",n.bold?"700":void 0).add("font-style",n.italic?"italic":void 0).add("text-decoration",n.underline?"underline":void 0).add("letter-spacing",n.letterSpacing!=null?`${n.letterSpacing}pt`:void 0).add("opacity",n.opacity!=null?String(n.opacity):void 0).add("transform",n.rotateDeg?`rotate(${n.rotateDeg}deg)`:void 0);const o=d.resolveFontSize(n,r);e.add("font-size",`${d.round(o.fontSizePx,2)}px`)}function _e(e,t,r,n,o){const s=o.createElement("table");if(s.className=F("grid",n),new I().add("width","100%").add("height","100%").add("border-collapse","collapse").add("table-layout",e.colWidthsMm?"fixed":"auto").applyTo(s),e.colWidthsMm){const h=o.createElement("colgroup");for(const m of e.colWidthsMm){const g=o.createElement("col");new I().mm("width",m,r).applyTo(g),h.appendChild(g)}s.appendChild(h)}const a=d.resolveBoxBorders(t.style),i=d.resolveStroke(t.style),c=a.inner?`${d.round(i.widthPt*r/72,2)}px solid ${i.color}`:"";return e.cells.forEach((h,m)=>{const g=o.createElement("tr");g.className=F("row",n),e.rowHeightsMm?.[m]!=null&&new I().mm("height",e.rowHeightsMm[m],r).applyTo(g),(h||[]).forEach(l=>{const u=o.createElement("td");u.className=F("cell",n),l?.colSpan&&(u.colSpan=l.colSpan),l?.rowSpan&&(u.rowSpan=l.rowSpan);const f=new I;if(c&&f.add("border",c),l?.style){const T=l.style;f.add("text-align",T.align).add("vertical-align",T.verticalAlign).add("background-color",T.backgroundColor).add("color",T.color).add("font-weight",T.bold?"700":void 0),f.add("font-size",`${d.round(d.resolveFontSize(T,r).fontSizePx,2)}px`)}if(f.applyTo(u),l?.text!=null&&(u.textContent=l.text),l?.children?.length)for(const T of l.children)u.appendChild(Z(T,r,n,o));g.appendChild(u)}),s.appendChild(g)}),s}function Fe(e,t,r,n){const o=n.createElement("div");o.className=F("text",r);const s=e.style||{},a=new I().add("text-align",s.align).add("display","flex").add("flex-direction","column").add("justify-content",s.verticalAlign==="middle"?"center":s.verticalAlign==="bottom"?"flex-end":"flex-start").add("overflow","hidden");if(fe(a,e,t),a.applyTo(o),d.isRichText(e)){const i=n.createElement("div");i.className=F("rich",r);for(const c of e.richParagraphs){const h=n.createElement("div");h.className=F("paragraph",r),new I().add("text-align",c.align).add("line-height",c.lineHeight!=null?String(c.lineHeight):void 0).mm("margin-top",c.spaceBeforeMm??0,t).mm("margin-bottom",c.spaceAfterMm??0,t).mm("text-indent",c.indentMm??0,t).applyTo(h);for(const g of c.segments||[]){const l=n.createElement("span");if(l.className=F("segment",r),l.textContent=g.kind==="field"?g.field??"":g.text??"",g.style){const u=new I().add("color",g.style.color).add("font-weight",g.style.bold?"700":void 0);u.add("font-size",`${d.round(d.resolveFontSize(g.style,t).fontSizePx,2)}px`),u.applyTo(l)}h.appendChild(l)}i.appendChild(h)}return o.appendChild(i),o}if(Array.isArray(e.lines)&&e.lines.length>0){const i=n.createElement("div");i.className=F("lines",r),s.lineHeight!=null&&new I().add("line-height",String(s.lineHeight)).applyTo(i);for(const c of e.lines){const h=n.createElement("div");h.className=F("line",r),h.textContent=c,i.appendChild(h)}return o.appendChild(i),o}return o.textContent=e.text??"",o}function Le(e,t,r){const n=r.createElement("img");return n.className=F("image",t),n.src=e.imageData,new I().add("width","100%").add("height","100%").add("object-fit","contain").add("display","block").applyTo(n),n.alt=e.kind,n}function de(e,t,r,n){const o=n.createElement("div");o.className=F("shape",r);const s=e.style||{},a=d.resolveStroke(s),i=d.resolveBoxBorders(s),c=`${d.round(a.widthPt*t/72,2)}px solid ${a.color}`,h=new I;return e.grid||e.kind==="rect"?(i.top&&h.add("border-top",c),i.right&&h.add("border-right",c),i.bottom&&h.add("border-bottom",c),i.left&&h.add("border-left",c)):e.kind==="ellipse"?(i.inner&&h.add("border",c).add("border-radius","50%"),s.backgroundColor&&h.add("background-color",s.backgroundColor)):e.kind==="line"&&h.add("height","0").add("border-top",c),h.add("box-sizing","border-box").add("width","100%").add("height","100%"),h.applyTo(o),o}function Z(e,t,r,n){const o=n.createElement("div");o.className=`${F("comp",r)} mr-kind-${e.kind}`;const s=new I().add("position","absolute").mm("left",e.leftMm,t).mm("top",e.topMm,t).mm("width",e.widthMm,t).mm("height",e.heightMm,t).add("box-sizing","border-box");if(fe(s,e,t),s.applyTo(o),d.isImageBackedComponent(e))return o.appendChild(Le(e,r,n)),o;if(e.kind==="text")return o.appendChild(Fe(e,t,r,n)),o;if(e.grid){const i=de(e,t,r,n);return i.appendChild(_e(e.grid,e,t,r,n)),o.appendChild(i),o}if(e.kind==="line"||e.kind==="rect"||e.kind==="ellipse"||e.kind==="chart")return o.appendChild(de(e,t,r,n)),o;const a=n.createElement("div");return a.className=F("unknown",r),a.textContent=e.fallbackText??"",o.appendChild(a),o}function ue(e,t,r,n){const o=n.createElement("div");o.className=F("page",r),new I().add("position","relative").mm("width",e.pageWidthMm,t).mm("height",e.pageHeightMm,t).add("background-color","#fff").add("overflow","hidden").add("box-sizing","border-box").applyTo(o);for(const s of e.components)o.appendChild(Z(s,t,r,n));return o}function Be(e,t,r={}){const n=r.dpi??96,o=t.createElement("div");return o.className=F("root",r),o.dataset.schemaVersion=e.schemaVersion,e.pages.forEach(s=>{o.appendChild(ue(s,n,r,t))}),o}function pe(e){const{pageHeightsPx:t,viewportHeightPx:r,scrollTopPx:n,overscan:o=1,gapPx:s=0}=e,a=t.length;if(a===0)return{start:0,end:-1,padTopPx:0,padBottomPx:0};const i=Math.max(0,s),c=new Array(a+1);c[0]=0;for(let w=0;w<a;w++)c[w+1]=c[w]+Math.max(0,t[w]??0)+i;const h=c[a],m=Math.max(0,n);let g=0,l=0,u=a-1;for(;l<=u;){const w=l+u>>1;c[w]<=m?(g=w,l=w+1):u=w-1}const f=Math.max(0,Math.min(a-1,g-o)),T=c[g]+Math.max(0,r);let R=a-1;for(l=0,u=a-1;l<=u;){const w=l+u>>1;c[w+1]<T?l=w+1:(R=w,u=w-1)}const x=Math.min(a-1,R+o),S=c[f],C=Math.max(0,h-c[x+1]);return{start:f,end:x,padTopPx:S,padBottomPx:C}}const Q=96/25.4;function ee(e,t=96){const r=t/96*Q;return{widthPx:Math.max(1,Math.round(e.pageWidthMm*r)),heightPx:Math.max(1,Math.round(e.pageHeightMm*r))}}function ze(e,t,r){const n=document.createElement("canvas"),{widthPx:o,heightPx:s}=ee(e,r);n.width=Math.round(o*t),n.height=Math.round(s*t),n.style.width=`${o}px`,n.style.height=`${s}px`;const a=n.getContext("2d");if(!a)throw new Error("当前环境不支持 Canvas 2D(测试需真浏览器,见 e2e/canvas.spec.ts)");return a.scale(t,t),a.fillStyle="#ffffff",a.fillRect(0,0,o,s),{canvas:n,ctx:a}}function Ie(e,t=96){return d.resolveFontSize(e,t).fontSizePx}function Me(e,t,r,n,o,s,a,i="top"){e.font=`${t.bold?"bold ":""}${t.fontSizePx}px ${a}`,e.fillStyle=t.color,e.textBaseline="alphabetic";const c=t.fontSizePx*t.lineHeight,h=t.text===""?[""]:t.text.split(`
2
+ `),m=h.length*c;let g=n;i==="middle"?g=n+(s-m)/2:i==="bottom"&&(g=n+s-m),h.forEach((l,u)=>{e.textAlign=t.align==="center"?"center":t.align==="right"?"right":"left";const f=t.align==="center"?r+o/2:t.align==="right"?r+o:r;e.fillText(l,f,g+u*c+t.fontSizePx*.8,o)}),e.textAlign="left"}function De(e,t,r,n,o,s,a,i,c,h,m){const g=ce.resolveGridLayout(t,s/i,a/i),l=d.resolveBoxBorders(r.style),u=d.resolveStroke(r.style);for(const f of g.cells){const T=f.cell.style?.backgroundColor;T&&(e.fillStyle=T,e.fillRect(n+f.xMm*i,o+f.yMm*i,f.widthMm*i,f.heightMm*i))}if(l.inner){e.strokeStyle=u.color,e.lineWidth=d.ptToPx(u.widthPt,c);for(const f of g.edges)e.beginPath(),f.kind==="v"?(e.moveTo(n+f.pos*i,o+f.from*i),e.lineTo(n+f.pos*i,o+f.to*i)):(e.moveTo(n+f.from*i,o+f.pos*i),e.lineTo(n+f.to*i,o+f.pos*i)),e.stroke();e.beginPath(),l.top&&(e.moveTo(n,o),e.lineTo(n+s,o)),l.right&&(e.moveTo(n+s,o),e.lineTo(n+s,o+a)),l.bottom&&(e.moveTo(n+s,o+a),e.lineTo(n,o+a)),l.left&&(e.moveTo(n,o+a),e.lineTo(n,o)),e.stroke()}for(const f of g.cells){const T=typeof f.cell.text=="string"?f.cell.text:"";if(!T)continue;const R=f.cell.style,x=R?.fontSize??d.DEFAULT_FONT_PT,S=d.wrapText(T,f.widthMm-1,{fontSizePt:x},m).join(`
3
+ `);Me(e,{text:S,fontSizePx:d.resolveFontSize(R,c).fontSizePx,bold:R?.bold??!1,color:R?.color??d.resolveTextColor(r.style,d.DEFAULT_TEXT_COLOR),align:R?.align??"left",lineHeight:d.LINE_HEIGHT},n+(f.xMm+.5)*i,o+f.yMm*i,Math.max(0,(f.widthMm-1)*i),f.heightMm*i,h,R?.verticalAlign??"middle")}}function be(e,t,r,n,o,s){const a=t.leftMm*r,i=t.topMm*r,c=t.widthMm*r,h=t.heightMm*r,m=t.style??{};if(t.grid){De(e,t.grid,t,a,i,c,h,r,n,o,s);return}switch(t.kind){case"text":{const g=m.fontSize??d.DEFAULT_FONT_PT,l=d.isRichText(t)?t.richParagraphs.map(u=>(u.segments??[]).map(f=>f.text??f.field??"").join("")).join(`
4
+ `):Array.isArray(t.lines)&&t.lines.length>0?t.lines.join(`
5
+ `):d.wrapText(t.text??"",t.widthMm,{fontSizePt:g},s).join(`
6
+ `);Me(e,{text:l,fontSizePx:d.resolveFontSize(m,n).fontSizePx,bold:m.bold??!1,color:d.resolveTextColor(m),align:m.align??"left",lineHeight:d.resolveLineHeight(m)},a,i,c,h,o,m.verticalAlign);break}case"rect":{const g=d.resolveStroke(m),l=d.resolveBoxBorders(m);m.backgroundColor&&(e.fillStyle=m.backgroundColor,e.fillRect(a,i,c,h)),l.inner&&(e.strokeStyle=g.color,e.lineWidth=d.ptToPx(g.widthPt,n),e.beginPath(),l.top&&(e.moveTo(a,i),e.lineTo(a+c,i)),l.right&&(e.moveTo(a+c,i),e.lineTo(a+c,i+h)),l.bottom&&(e.moveTo(a+c,i+h),e.lineTo(a,i+h)),l.left&&(e.moveTo(a,i+h),e.lineTo(a,i)),e.stroke());break}case"line":{const g=d.resolveStroke({...m,borderColor:m.lineColor??m.borderColor});e.strokeStyle=g.color,e.lineWidth=d.ptToPx(g.widthPt,n),e.beginPath(),e.moveTo(a,i+h/2),e.lineTo(a+c,i+h/2),e.stroke();break}case"ellipse":{const g=d.resolveStroke(m);e.strokeStyle=g.color,e.lineWidth=d.ptToPx(g.widthPt,n),m.backgroundColor&&(e.fillStyle=m.backgroundColor,e.beginPath(),e.ellipse(a+c/2,i+h/2,c/2,h/2,0,0,Math.PI*2),e.fill()),e.beginPath(),e.ellipse(a+c/2,i+h/2,c/2,h/2,0,0,Math.PI*2),e.stroke();break}}}function Oe(e,t={}){if(typeof document>"u")throw new Error("renderPlanToCanvas 需要浏览器环境(SSR 请在客户端钩子中调用)");const r=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),n=t.dpi??96,o=n/96*Q,s=t.fontFamily??'"Microsoft YaHei", sans-serif',a=t.measurer??d.heuristicMeasurer,i=Math.max(0,t.start??0),c=Math.min(e.pages.length-1,t.end??e.pages.length-1),h=[];for(let m=i;m<=c;m++){const g=e.pages[m],{canvas:l,ctx:u}=ze(g,r,n);for(const f of g.components)be(u,f,o,n,s,a);h.push(l)}return{canvases:h}}function We(e,t={}){const r=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),n=t.dpi??96,o=n/96*Q,s=t.fontFamily??'"Microsoft YaHei", sans-serif',a=t.measurer??d.heuristicMeasurer,i=t.overscan??1,c=t.gapPx??18,h=t.pagesPerFrame??1,m=e.pages.map(p=>p.pageHeightMm*o),g=Math.max(1,...e.pages.map(p=>p.pageWidthMm*o)),l={start:0,end:-1};let u=null,f=null,T=null,R=null,x=[],S=0,C=[];function w(){const p=u;p.innerHTML="",f=document.createElement("div"),f.style.cssText=`width:${g}px;margin:0 auto;`,T=document.createElement("div"),R=document.createElement("div"),f.appendChild(T),x=[];const N=Math.min(e.pages.length,3+i*2);for(let B=0;B<N;B++){const y=document.createElement("div");y.style.cssText=`margin:0 auto ${c}px;box-shadow:0 2px 8px rgba(0,0,0,.35);background:#fff;`,f.appendChild(y),x.push(y)}f.appendChild(R),p.appendChild(f)}function V(p,N){const B=e.pages[N],{widthPx:y,heightPx:$}=ee(B,n);let k=p.firstElementChild;(!k||k.tagName!=="CANVAS")&&(k=document.createElement("canvas"),p.innerHTML="",p.appendChild(k)),k.width=Math.round(y*r),k.height=Math.round($*r),k.style.width=`${y}px`,k.style.height=`${$}px`;const D=k.getContext("2d");if(D){D.setTransform(1,0,0,1,0,0),D.scale(r,r),D.fillStyle="#ffffff",D.fillRect(0,0,y,$);for(const J of B.components)be(D,J,o,n,s,a);k.dataset.canvasPage=String(N),p.style.height=`${$}px`,p.style.width=`${y}px`}}function U(p){l.start=p.start,l.end=p.end,T.style.height=`${p.start*c+m.slice(0,p.start).reduce((y,$)=>y+$,0)}px`;const N=e.pages.length-1-p.end;R.style.height=`${N*c+m.slice(p.end+1).reduce((y,$)=>y+$,0)}px`;const B=p.end-p.start+1;x.forEach((y,$)=>{if($<B){y.style.display="";const k=p.start+$;y.style.height=`${m[k]??0}px`}else y.style.display="none"}),C=[];for(let y=p.start;y<=p.end;y++){const $=x[y-p.start];if(!$)continue;$.firstElementChild?.dataset?.canvasPage!==String(y)&&C.push(y)}v()}function v(){S||C.length===0||(S=requestAnimationFrame(()=>{S=0;let p=Math.max(1,h);for(;C.length>0&&p-- >0;){const N=C.shift(),B=x[N-l.start];B&&V(B,N)}C.length>0&&v()}))}function H(){S||(S=requestAnimationFrame(()=>{S=0;const p=u,N=pe({pageHeightsPx:m,viewportHeightPx:p.clientHeight,scrollTopPx:p.scrollTop,overscan:i,gapPx:c});N.start!==l.start||N.end!==l.end?U(N):v()}))}let G=null;return{attach(p){if(typeof document>"u")throw new Error("createCanvasPager 需要浏览器环境(SSR 请在客户端钩子中调用 attach)");u=p,w(),p.addEventListener("scroll",H,{passive:!0}),typeof ResizeObserver<"u"&&(G=new ResizeObserver(()=>H()),G.observe(p)),H()},destroy(){S&&cancelAnimationFrame(S),S=0,G?.disconnect(),G=null,u?.removeEventListener("scroll",H),C=[],f?.remove(),u=null},window(){return{...l}}}}function A(e,t){return typeof e=="number"&&Number.isFinite(e)?e:t}function _(e,t=""){return typeof e=="string"?e:t}function O(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ge(e){return e==="Center"?"center":e==="Right"?"right":"left"}function je(e){return e==="Center"?"middle":e==="Bottom"?"bottom":"top"}function Ve(e){const t=parseFloat(_(e.FontSize,"10.5"));return{fontSize:Number.isFinite(t)?t:10.5,fontFamily:_(e.FontFamily,"黑体")||void 0,bold:_(e.FontWeight)==="bold"||void 0,italic:_(e.FontStyle)==="italic"||void 0,underline:e.Underline===!0||void 0,color:_(e.FontColor)||void 0,backgroundColor:_(e.BackgroundColor)||void 0,align:Ge(_(e.HorAlignment,"Left")),verticalAlign:je(_(e.VertAlignment,"Top")),lineHeight:(()=>{const r=parseFloat(_(e.RowSpace,"1"));return Number.isFinite(r)&&r!==1?r:void 0})(),borderColor:_(e.BorderColor)||void 0,borderTop:e.BorderTop!==!1,borderRight:e.BorderRight!==!1,borderBottom:e.BorderBottom!==!1,borderLeft:e.BorderLeft!==!1}}function Ue(e,t){const r=_(e.uitype),n={kind:"text",leftMm:A(e.left,0),topMm:A(e.top,0),widthMm:A(e.width,40),heightMm:A(e.height,8),nid:_(e.nid)||void 0,style:Ve(e)};switch(r){case"text":{n.kind="text";const o=e.Text??e.text??e.Value;n.text=o==null?"":String(o);const s=e.Lines??e.lines;return Array.isArray(s)&&(n.lines=s.map(a=>String(a))),n}case"richtext":return n.kind="text",n.text=_(e.Text),t.push(`富文本 ${n.nid??""} 导入为纯文本(版式细节可能损失)`),n;case"image":case"barcode":case"qrcode":case"chart":return n.kind=r==="image"?"image":r,n.fallbackText=`[${r}]`,t.push(`图片类组件 ${n.nid??""} 需运行时数据(imageData),已导入为占位`),n;case"table":{n.kind="rect";const o=e.Cells??e.cells;if(Array.isArray(o)){const s={cells:o.map(a=>Array.isArray(a)?a.map(i=>({text:O(i)?_(i.Text??i.text):"",colSpan:O(i)?A(i.ColSpan,1):1})):[])};n.grid=s}else n.fallbackText="[table]",t.push(`表格 ${n.nid??""} 缺少 Cells,导入为空框`);return n}case"subreport":return t.push(`子报表 ${n.nid??""} 暂不支持导入,已跳过`),null;default:return _(e.ShapeType)==="hline"||r==="hline"||r==="vline"?(n.kind="line",n):r==="rect"||r==="oval"||r==="shape"?(n.kind=r==="oval"?"ellipse":"rect",n):(t.push(`未知组件类型 ${r},已跳过`),null)}}function Je(e){const t=[];let r=null;if(typeof e=="string")try{const h=JSON.parse(e);O(h)&&(r=h)}catch{return{template:{pages:[]},warnings:["content 不是合法 JSON"]}}else O(e)&&(r=e);if(!r)return{template:{pages:[]},warnings:["content 为空"]};const n=O(r.GlobalConfig)?r.GlobalConfig:{},o=A(n.paperWidthMm,210),s=A(n.paperHeightMm,297),a={top:A(n.marginTop,10),bottom:A(n.marginBottom,10),left:A(n.marginLeft,10),right:A(n.marginRight,10)},i=Array.isArray(r.children)?r.children.filter(h=>O(h)&&_(h.uitype)==="page"):[];i.length===0&&t.push("content 中没有 uitype=page 的页节点");const c=i.map(h=>{const m=h,g=Array.isArray(m.children)?m.children:[],l=[];for(const u of g){if(!O(u))continue;const f=Ue(u,t);f&&l.push(f)}return{widthMm:A(m.width,o),heightMm:A(m.DesignHeight,s),marginTopMm:A(m.MarginTop,a.top),marginBottomMm:A(m.MarginBottom,a.bottom),marginLeftMm:A(m.MarginLeft,a.left),marginRightMm:A(m.MarginRight,a.right),components:l}});return c.length===0&&(t.push("转换结果为空页,已回退一张空白页"),c.push({widthMm:o,heightMm:s,...a,components:[]})),{template:{pages:c},warnings:t}}function Se(e,t,r){let n,o;if(typeof e=="string"){const s=d.PAPER_SIZES[e];if(!s)throw new Error(`未知纸张预设 "${e}"(可用:${Object.keys(d.PAPER_SIZES).join("/")})`);n=s.widthMm,o=s.heightMm}else typeof e=="number"?(n=e,o=t??297):(n=e.widthMm,o=e.heightMm);return r?{widthMm:o,heightMm:n}:{widthMm:n,heightMm:o}}class ye{constructor(){this.pages=[],this.pending=null}page(t="a4",r={},n){this.collect();const s=n!=null&&!("margins"in n)&&!("landscape"in n)&&("marginTopMm"in n||"marginBottomMm"in n||"marginLeftMm"in n||"marginRightMm"in n)?{margins:n}:n??{},{widthMm:a,heightMm:i}=Se(t,typeof r=="number"?r:void 0,s.landscape),c=s.margins??{};return this.pending=new Te(this,{widthMm:a,heightMm:i,marginTopMm:c.marginTopMm??10,marginBottomMm:c.marginBottomMm??10,marginLeftMm:c.marginLeftMm??10,marginRightMm:c.marginRightMm??10}),this.pending}collect(){this.pending&&(this.pages.push(this.pending.buildPage()),this.pending=null)}build(){if(this.collect(),this.pages.length===0)throw new Error("模板至少需要一页:先调用 .page() 添加内容");return{pages:this.pages}}}class Te{constructor(t,r){this.parent=t,this.page=r,this.components=[]}text(t,r={},n={}){return this.components.push({kind:"text",leftMm:r.leftMm??0,topMm:r.topMm??0,widthMm:r.widthMm??60,heightMm:r.heightMm??8,text:t,style:n}),this}list(t,r,n,o={}){return this.components.push({kind:"list",leftMm:r.leftMm??10,topMm:r.topMm??30,widthMm:r.widthMm??180,dataset:t,columns:n,...o}),this}rect(t,r={}){return this.components.push({kind:"rect",...t,style:r}),this}line(t,r,n,o={}){return this.components.push({kind:"line",leftMm:t,topMm:r,widthMm:n,heightMm:.5,style:o}),this}barcode(t,r){return this.components.push({kind:"barcode",leftMm:r.leftMm??0,topMm:r.topMm??0,widthMm:r.widthMm??40,heightMm:r.heightMm??12,fallbackText:t}),this}qrcode(t,r,n,o){return this.components.push({kind:"qrcode",leftMm:n,topMm:o,widthMm:r,heightMm:r,fallbackText:t}),this}buildPage(){return{...this.page,components:this.components}}done(){return this.parent}build(){return this.done().build()}}function Ye(){return new ye}exports.CSS_DPI=d.CSS_DPI;exports.DEFAULT_BORDER_PT=d.DEFAULT_BORDER_PT;exports.DEFAULT_FONT_PT=d.DEFAULT_FONT_PT;exports.DEFAULT_STROKE_COLOR=d.DEFAULT_STROKE_COLOR;exports.DEFAULT_TEXT_COLOR=d.DEFAULT_TEXT_COLOR;exports.LINE_HEIGHT=d.LINE_HEIGHT;exports.MM_PER_INCH=d.MM_PER_INCH;exports.PAPER_SIZES=d.PAPER_SIZES;exports.RENDER_PLAN_SCHEMA_VERSION=d.RENDER_PLAN_SCHEMA_VERSION;exports.SCHEMA_VERSION_JH4J=d.SCHEMA_VERSION_JH4J;exports.SCHEMA_VERSION_LOCAL=d.SCHEMA_VERSION_LOCAL;exports.SCHEMA_VERSION_MACH=d.SCHEMA_VERSION_MACH;exports.charWidthEm=d.charWidthEm;exports.createCanvasMeasurer=d.createCanvasMeasurer;exports.createHeuristicMeasurer=d.createHeuristicMeasurer;exports.heuristicMeasurer=d.heuristicMeasurer;exports.isImageBackedComponent=d.isImageBackedComponent;exports.isRichText=d.isRichText;exports.measureTextMm=d.measureTextMm;exports.mmToPx=d.mmToPx;exports.mmToPxFactor=d.mmToPxFactor;exports.ptToPx=d.ptToPx;exports.pxToMm=d.pxToMm;exports.resolveBoxBorders=d.resolveBoxBorders;exports.resolveFontSize=d.resolveFontSize;exports.resolveLineHeight=d.resolveLineHeight;exports.resolveStroke=d.resolveStroke;exports.resolveTextColor=d.resolveTextColor;exports.round=d.round;exports.toRenderPlan=d.toRenderPlan;exports.wrapText=d.wrapText;exports.resolveGridLayout=ce.resolveGridLayout;exports.PageBuilder=Te;exports.TemplateBuilder=ye;exports.assertRenderPlan=ke;exports.classOf=F;exports.computePageWindow=pe;exports.createCanvasPager=We;exports.createTemplate=Ye;exports.evalStyleRule=he;exports.formatValue=K;exports.importJh4jTemplateContent=Je;exports.measurePageSizePx=ee;exports.paginateTemplate=Ne;exports.planFontSizePx=Ie;exports.renderComponent=Z;exports.renderPage=ue;exports.renderPlan=Be;exports.renderPlanToCanvas=Oe;exports.resolvePaper=Se;exports.validateComponent=X;exports.validatePage=me;exports.validateRenderPlan=ge;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './defaults';
2
+ export * from './format';
2
3
  export * from './units';
3
4
  export * from './schema/render-plan';
4
5
  export * from './schema/validate';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './defaults';
2
+ export * from './format';
2
3
  export * from './units';
3
4
  export * from './schema/render-plan';
4
5
  export * from './schema/validate';