@agile-team/mach-report 0.7.0 → 0.9.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 (42) hide show
  1. package/LICENSE +107 -0
  2. package/dist/ReportPreview-BFTfls8h.js +923 -0
  3. package/dist/ReportPreview-D6VHDUvR.cjs +6 -0
  4. package/dist/format.d.ts +48 -0
  5. package/dist/grid-geometry-BXpOxznT.cjs +1 -0
  6. package/dist/grid-geometry-Bs8QXz1X.js +65 -0
  7. package/dist/index.cjs +6 -6
  8. package/dist/index.d.cts +1 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +858 -660
  11. package/dist/layout/paginate.d.ts +30 -2
  12. package/dist/pdf.cjs +46 -46
  13. package/dist/pdf.js +8 -7
  14. package/dist/{plugin-Cl-IqCqx.cjs → plugin-9eBK7khj.cjs} +1 -1
  15. package/dist/{plugin-Dp3kKWiQ.js → plugin-vi2GjP43.js} +3 -3
  16. package/dist/style-6ihHKVCM.js +192 -0
  17. package/dist/style-Xq08-IsV.cjs +3 -0
  18. package/dist/style.css +1 -1
  19. package/dist/vue/ReportPreview.d.ts +13 -0
  20. package/dist/vue/ReportToolbar.d.ts +20 -3
  21. package/dist/vue/async.d.cts +16 -0
  22. package/dist/vue/async.d.ts +16 -0
  23. package/dist/vue/composables/useHighlight.d.ts +8 -0
  24. package/dist/vue/composables/usePageWindow.d.ts +0 -3
  25. package/dist/vue/composables/usePrintExport.d.ts +8 -0
  26. package/dist/vue/composables/useReportSearch.d.ts +72 -0
  27. package/dist/vue/config.d.ts +17 -1
  28. package/dist/vue/plugin.d.ts +16 -0
  29. package/dist/vue-async.cjs +1 -1
  30. package/dist/vue-async.js +3 -3
  31. package/dist/vue.cjs +1 -1
  32. package/dist/vue.js +35 -33
  33. package/dist/xlsx/render-xlsx.d.ts +20 -0
  34. package/dist/xlsx.cjs +30 -0
  35. package/dist/xlsx.d.cts +5 -0
  36. package/dist/xlsx.d.ts +5 -0
  37. package/dist/xlsx.js +22648 -0
  38. package/package.json +15 -2
  39. package/dist/ReportPreview-CrVeTKu1.cjs +0 -6
  40. package/dist/ReportPreview-DgsOdO4y.js +0 -559
  41. package/dist/style-B3vxGDZd.cjs +0 -3
  42. package/dist/style-B7Xfo5I-.js +0 -255
package/dist/pdf.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { g as L1 } from "./_commonjsHelpers-DaMA6jEr.js";
2
- import { h as N1, i as U1, c as xo, d as hl, b as dl, g as z1, L as vu, a as Ed, w as j1 } from "./style-B7Xfo5I-.js";
2
+ import { h as N1, i as U1, c as xo, d as hl, b as dl, L as vu, a as Ed, w as z1 } from "./style-6ihHKVCM.js";
3
+ import { r as j1 } from "./grid-geometry-Bs8QXz1X.js";
3
4
  var pu = {}, vl;
4
5
  function Hn() {
5
6
  return vl || (vl = 1, (function(t) {
@@ -35924,7 +35925,7 @@ function FE(t) {
35924
35925
  }
35925
35926
  return e;
35926
35927
  }
35927
- async function TE(t, e = {}) {
35928
+ async function OE(t, e = {}) {
35928
35929
  const r = await Gn.create();
35929
35930
  r.registerFontkit(wi);
35930
35931
  const n = [], i = [];
@@ -35933,7 +35934,7 @@ async function TE(t, e = {}) {
35933
35934
  subset: !0
35934
35935
  }) : void 0) ?? s, l = /* @__PURE__ */ new Map();
35935
35936
  function h(w, x, T) {
35936
- return w ? j1(w, x, { fontSizePt: T }, o) : [];
35937
+ return w ? z1(w, x, { fontSizePt: T }, o) : [];
35937
35938
  }
35938
35939
  function d(w) {
35939
35940
  const x = l.get(w);
@@ -35967,7 +35968,7 @@ async function TE(t, e = {}) {
35967
35968
  });
35968
35969
  }
35969
35970
  function g(w, x, T, A, R) {
35970
- const P = z1(x, T.widthMm, T.heightMm), I = hl(T.style), B = xo(T.style), j = ii(B.color, [0.2, 0.2, 0.2]), W = Math.max(0.1, B.widthPt);
35971
+ const P = j1(x, T.widthMm, T.heightMm), I = hl(T.style), B = xo(T.style), j = ii(B.color, [0.2, 0.2, 0.2]), W = Math.max(0.1, B.widthPt);
35971
35972
  for (const N of P.cells) {
35972
35973
  const V = N.cell.style?.backgroundColor;
35973
35974
  V && w.drawRectangle({
@@ -36121,7 +36122,7 @@ async function CE(t, e) {
36121
36122
  }
36122
36123
  }
36123
36124
  const bf = /* @__PURE__ */ new Map(), wf = /* @__PURE__ */ new Map();
36124
- async function OE(t) {
36125
+ async function kE(t) {
36125
36126
  const e = bf.get(t);
36126
36127
  if (e) return e;
36127
36128
  const r = wf.get(t);
@@ -36147,6 +36148,6 @@ async function OE(t) {
36147
36148
  }
36148
36149
  }
36149
36150
  export {
36150
- OE as loadFontWithCache,
36151
- TE as renderPlanToPdf
36151
+ kE as loadFontWithCache,
36152
+ OE as renderPlanToPdf
36152
36153
  };
@@ -1 +1 @@
1
- "use strict";var O=Object.create;var E=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var U=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of b(e))!F.call(r,n)&&n!==t&&E(r,n,{get:()=>e[n],enumerable:!(o=A(e,n))||o.enumerable});return r};var M=(r,e,t)=>(t=r!=null?O(y(r)):{},U(e||!r||!r.__esModule?E(t,"default",{value:r,enumerable:!0}):t,r));const R=require("vue");function m(r){return r==null?[]:Array.isArray(r)?r.map(String).filter(e=>e!==""):String(r).split(",").map(e=>e.trim()).filter(e=>e!=="")}function j(r){return m(r).join(",")}class s extends Error{constructor(e){super(e),this.name="PlanLoadError"}}function P(r={}){const{baseUrl:e="",headers:t,credentials:o,timeoutMs:n=3e4}=r;return async({url:c,method:i,params:a})=>{const h=a&&Object.keys(a).length>0?`?${new URLSearchParams(a)}`:"",l=new AbortController,f=setTimeout(()=>l.abort(),n);let d;try{d=await fetch(`${e}${c}${h}`,{method:i.toUpperCase(),headers:{Accept:"application/json",...t},credentials:o,signal:l.signal})}catch(u){throw u instanceof DOMException&&u.name==="AbortError"?new s(`请求超时(${n}ms): ${c}`):new s(`请求失败(${c}): ${u instanceof Error?u.message:String(u)}`)}finally{clearTimeout(f)}if(!d.ok)throw new s(`HTTP ${d.status} ${c}`);return d.json()}}function p(r){const{request:e,baseUrl:t=""}=r;return async({tempIds:o,furnitureTempId:n,params:c})=>{if(o.length===0)throw new s("缺少报表模板 ID");const i={tempId:o.join(",")};n&&(i.furnitureTempId=n);for(const[l,f]of Object.entries(c||{}))l&&f!=null&&f!==""&&(i[l]=String(f));const a=await e({url:`${t}/report/codePrintReport/gridPlan`,method:"get",params:i});if(a&&a.code!=null&&a.code!==200)throw new s(String(a.message||"预览加载失败"));const h=a?.data?.pages;return{schemaVersion:"jh4j-compatible",pages:Array.isArray(h)?h:[]}}}function _(r={fontUrl:"/simhei.ttf"}){let e=null;return async t=>{e||(e=await import("@agile-team/mach-report/pdf"));const o=r.fontUrl?await e.loadFontWithCache(r.fontUrl):null,{bytes:n}=await e.renderPlanToPdf(t,o?{customFontBytes:o}:{});return n}}const T="mach-report/fetcher",g="mach-report/pdf-exporter",w="mach-report/config",$="mach-report/controller",C=R.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-CrVeTKu1.cjs")).then(r=>r.ReportPreview$1)),H={install(r,e={}){const t=e.fetcher??p({request:e.request??P({baseUrl:e.baseUrl}),baseUrl:e.baseUrl});r.provide(T,t);const o=e.pdfFontUrl??e.config?.defaults?.pdfFontUrl??"/simhei.ttf";r.provide(g,e.pdfExporter??_({fontUrl:o})),r.provide(w,R.computed(()=>e.config??null)),e.globalComponent!==!1&&r.component("MachReportPreview",C)}};exports.MACH_REPORT_CONFIG_KEY=w;exports.MACH_REPORT_CONTROLLER_KEY=$;exports.MACH_REPORT_FETCHER_KEY=T;exports.MACH_REPORT_PDF_EXPORTER_KEY=g;exports.MachReportPreview=C;exports.PlanLoadError=s;exports.createDefaultPdfExporter=_;exports.createFetchRequest=P;exports.createJh4jGridPlanFetcher=p;exports.joinTempIds=j;exports.machReportPlugin=H;exports.normalizeTempIds=m;
1
+ "use strict";var O=Object.create;var E=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var U=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of b(e))!F.call(r,n)&&n!==t&&E(r,n,{get:()=>e[n],enumerable:!(o=A(e,n))||o.enumerable});return r};var M=(r,e,t)=>(t=r!=null?O(y(r)):{},U(e||!r||!r.__esModule?E(t,"default",{value:r,enumerable:!0}):t,r));const R=require("vue");function m(r){return r==null?[]:Array.isArray(r)?r.map(String).filter(e=>e!==""):String(r).split(",").map(e=>e.trim()).filter(e=>e!=="")}function j(r){return m(r).join(",")}class s extends Error{constructor(e){super(e),this.name="PlanLoadError"}}function P(r={}){const{baseUrl:e="",headers:t,credentials:o,timeoutMs:n=3e4}=r;return async({url:c,method:i,params:a})=>{const h=a&&Object.keys(a).length>0?`?${new URLSearchParams(a)}`:"",l=new AbortController,f=setTimeout(()=>l.abort(),n);let d;try{d=await fetch(`${e}${c}${h}`,{method:i.toUpperCase(),headers:{Accept:"application/json",...t},credentials:o,signal:l.signal})}catch(u){throw u instanceof DOMException&&u.name==="AbortError"?new s(`请求超时(${n}ms): ${c}`):new s(`请求失败(${c}): ${u instanceof Error?u.message:String(u)}`)}finally{clearTimeout(f)}if(!d.ok)throw new s(`HTTP ${d.status} ${c}`);return d.json()}}function p(r){const{request:e,baseUrl:t=""}=r;return async({tempIds:o,furnitureTempId:n,params:c})=>{if(o.length===0)throw new s("缺少报表模板 ID");const i={tempId:o.join(",")};n&&(i.furnitureTempId=n);for(const[l,f]of Object.entries(c||{}))l&&f!=null&&f!==""&&(i[l]=String(f));const a=await e({url:`${t}/report/codePrintReport/gridPlan`,method:"get",params:i});if(a&&a.code!=null&&a.code!==200)throw new s(String(a.message||"预览加载失败"));const h=a?.data?.pages;return{schemaVersion:"jh4j-compatible",pages:Array.isArray(h)?h:[]}}}function _(r={fontUrl:"/simhei.ttf"}){let e=null;return async t=>{e||(e=await import("@agile-team/mach-report/pdf"));const o=r.fontUrl?await e.loadFontWithCache(r.fontUrl):null,{bytes:n}=await e.renderPlanToPdf(t,o?{customFontBytes:o}:{});return n}}const T="mach-report/fetcher",g="mach-report/pdf-exporter",w="mach-report/config",$="mach-report/controller",C=R.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-D6VHDUvR.cjs")).then(r=>r.ReportPreview$1)),H={install(r,e={}){const t=e.fetcher??p({request:e.request??P({baseUrl:e.baseUrl}),baseUrl:e.baseUrl});r.provide(T,t);const o=e.pdfFontUrl??e.config?.defaults?.pdfFontUrl??"/simhei.ttf";r.provide(g,e.pdfExporter??_({fontUrl:o})),r.provide(w,R.computed(()=>e.config??null)),e.globalComponent!==!1&&r.component("MachReportPreview",C)}};exports.MACH_REPORT_CONFIG_KEY=w;exports.MACH_REPORT_CONTROLLER_KEY=$;exports.MACH_REPORT_FETCHER_KEY=T;exports.MACH_REPORT_PDF_EXPORTER_KEY=g;exports.MachReportPreview=C;exports.PlanLoadError=s;exports.createDefaultPdfExporter=_;exports.createFetchRequest=P;exports.createJh4jGridPlanFetcher=p;exports.joinTempIds=j;exports.machReportPlugin=H;exports.normalizeTempIds=m;
@@ -62,7 +62,7 @@ function w(r = { fontUrl: "/simhei.ttf" }) {
62
62
  return a;
63
63
  };
64
64
  }
65
- const R = "mach-report/fetcher", b = "mach-report/pdf-exporter", y = "mach-report/config", j = "mach-report/controller", U = d(() => import("./ReportPreview-DgsOdO4y.js").then((r) => r.j)), A = {
65
+ const R = "mach-report/fetcher", b = "mach-report/pdf-exporter", y = "mach-report/config", A = "mach-report/controller", U = d(() => import("./ReportPreview-BFTfls8h.js").then((r) => r.k)), C = {
66
66
  install(r, e = {}) {
67
67
  const o = e.fetcher ?? P({
68
68
  request: e.request ?? E({ baseUrl: e.baseUrl }),
@@ -77,7 +77,7 @@ const R = "mach-report/fetcher", b = "mach-report/pdf-exporter", y = "mach-repor
77
77
  }
78
78
  };
79
79
  export {
80
- j as M,
80
+ A as M,
81
81
  u as P,
82
82
  y as a,
83
83
  R as b,
@@ -87,6 +87,6 @@ export {
87
87
  E as f,
88
88
  P as g,
89
89
  _ as j,
90
- A as m,
90
+ C as m,
91
91
  g as n
92
92
  };
@@ -0,0 +1,192 @@
1
+ const C = 1.35, w = 10.5, x = 0.75, M = "#333333", S = "#000000", _ = "1.0.0-mach", R = "mach-local", I = "jh4j-compatible", L = 25.4, D = 96;
2
+ function m(t = 96) {
3
+ return t / 25.4;
4
+ }
5
+ function b(t, e = 96) {
6
+ return (t || 0) * m(e);
7
+ }
8
+ function H(t, e = 96) {
9
+ return t / m(e);
10
+ }
11
+ function P(t, e = 96) {
12
+ return t * e / 72;
13
+ }
14
+ function k(t, e) {
15
+ const r = 10 ** e;
16
+ return Math.round(t * r) / r;
17
+ }
18
+ const N = {
19
+ a3: { widthMm: 297, heightMm: 420 },
20
+ a4: { widthMm: 210, heightMm: 297 },
21
+ a5: { widthMm: 148, heightMm: 210 },
22
+ b4: { widthMm: 250, heightMm: 353 },
23
+ b5: { widthMm: 176, heightMm: 250 }
24
+ }, E = _;
25
+ function O(t) {
26
+ if (t && t.code != null && t.code !== 200)
27
+ throw new Error(String(t.message || "渲染计划加载失败"));
28
+ const e = t?.data?.pages;
29
+ return {
30
+ schemaVersion: E,
31
+ pages: Array.isArray(e) ? e : []
32
+ };
33
+ }
34
+ function z(t) {
35
+ return (t.kind === "image" || t.kind === "barcode" || t.kind === "qrcode" || t.kind === "chart") && !!t.imageData;
36
+ }
37
+ function p(t) {
38
+ return t.kind === "text" && Array.isArray(t.richParagraphs) && t.richParagraphs.length > 0;
39
+ }
40
+ const l = /[\u3000-\u9fff\uff00-\uffef]/, f = new Uint8Array(128);
41
+ {
42
+ for (const t of "iljtf.,:;'`|!()[]") f[t.charCodeAt(0)] = 1;
43
+ for (const t of "mwMW@") f[t.charCodeAt(0)] = 2;
44
+ for (let t = 48; t <= 57; t++) f[t] = 3;
45
+ for (let t = 65; t <= 90; t++) f[t] = 4;
46
+ f[32] = 5;
47
+ }
48
+ const T = [0.54, 0.26, 0.95, 0.59, 0.67, 0.3];
49
+ function g(t) {
50
+ const e = t.charCodeAt(0);
51
+ return e < 128 ? T[f[e]] : l.test(t) ? 1 : /[A-Z]/.test(t) ? 0.67 : 0.54;
52
+ }
53
+ const u = {
54
+ measureMm(t, e) {
55
+ const { fontSizePt: r, bold: n = !1, letterSpacingPt: c = 0 } = e, s = 25.4 / 72;
56
+ let i = 0;
57
+ for (const o of t)
58
+ i += g(o);
59
+ return n && (i *= 1.04), (i * r + c * t.length) * s;
60
+ }
61
+ };
62
+ function F() {
63
+ return u;
64
+ }
65
+ function j(t, e) {
66
+ return u.measureMm(t, e);
67
+ }
68
+ function v(t) {
69
+ let e;
70
+ return {
71
+ measureMm(r, n) {
72
+ if (e === void 0 && (e = t()), !e) return u.measureMm(r, n);
73
+ const c = n.fontSizePt * 96 / 72;
74
+ return e.font = `${n.bold ? "bold " : ""}${c}px sans-serif`, e.measureText(r).width * 25.4 / 96;
75
+ }
76
+ };
77
+ }
78
+ function A(t, e, r) {
79
+ const n = [];
80
+ let c = "", s = 0;
81
+ const i = () => {
82
+ c && (n.push({ text: c, widthMm: s, cjk: !1 }), c = "", s = 0);
83
+ };
84
+ for (const o of t) {
85
+ if (o === `
86
+ `) {
87
+ i(), n.push({ text: `
88
+ `, widthMm: 0, cjk: !1, br: !0 });
89
+ continue;
90
+ }
91
+ if (o === " ") {
92
+ i(), n.push({ text: o, widthMm: r.measureMm(o, e), cjk: !1, space: !0 });
93
+ continue;
94
+ }
95
+ if (l.test(o)) {
96
+ i(), n.push({ text: o, widthMm: r.measureMm(o, e), cjk: !0 });
97
+ continue;
98
+ }
99
+ c += o, s += r.measureMm(o, e);
100
+ }
101
+ return i(), n;
102
+ }
103
+ function U(t, e, r, n = u) {
104
+ if (!t) return [""];
105
+ const c = [];
106
+ let s = "", i = 0;
107
+ const o = () => {
108
+ c.push(s), s = "", i = 0;
109
+ };
110
+ for (const a of A(t, r, n)) {
111
+ if (a.br) {
112
+ o();
113
+ continue;
114
+ }
115
+ if (i + a.widthMm <= e) {
116
+ s += a.text, i += a.widthMm;
117
+ continue;
118
+ }
119
+ if (a.space) {
120
+ o();
121
+ continue;
122
+ }
123
+ if (a.cjk) {
124
+ s.length > 0 && o(), s = a.text, i = a.widthMm;
125
+ continue;
126
+ }
127
+ if (s.length > 0 && o(), a.widthMm <= e) {
128
+ s = a.text, i = a.widthMm;
129
+ continue;
130
+ }
131
+ for (const h of a.text) {
132
+ const d = n.measureMm(h, r);
133
+ i + d > e && s.length > 0 && o(), s += h, i += d;
134
+ }
135
+ }
136
+ return o(), c;
137
+ }
138
+ function B(t, e = 96, r = 10.5) {
139
+ if (t?.fontSizePx != null)
140
+ return { fontSizePt: t.fontSizePx * 72 / e, fontSizePx: t.fontSizePx };
141
+ const n = t?.fontSize ?? r;
142
+ return { fontSizePt: n, fontSizePx: P(n, e) };
143
+ }
144
+ function V(t, e = M) {
145
+ return {
146
+ color: t?.borderColor ?? t?.lineColor ?? e,
147
+ widthPt: t?.lineWidthPt ?? 0.75
148
+ };
149
+ }
150
+ function W(t, e = S) {
151
+ return t?.color ?? e;
152
+ }
153
+ function J(t) {
154
+ return t?.lineHeight ?? 1.35;
155
+ }
156
+ function q(t) {
157
+ const e = t?.borderTop !== !1, r = t?.borderRight !== !1, n = t?.borderBottom !== !1, c = t?.borderLeft !== !1;
158
+ return { top: e, right: r, bottom: n, left: c, inner: e || r || n || c };
159
+ }
160
+ export {
161
+ D as C,
162
+ w as D,
163
+ C as L,
164
+ L as M,
165
+ N as P,
166
+ E as R,
167
+ I as S,
168
+ B as a,
169
+ p as b,
170
+ V as c,
171
+ q as d,
172
+ J as e,
173
+ W as f,
174
+ S as g,
175
+ u as h,
176
+ z as i,
177
+ x as j,
178
+ M as k,
179
+ R as l,
180
+ b as m,
181
+ _ as n,
182
+ g as o,
183
+ P as p,
184
+ v as q,
185
+ k as r,
186
+ F as s,
187
+ j as t,
188
+ m as u,
189
+ H as v,
190
+ U as w,
191
+ O as x
192
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";const m="#333333",M="#000000",T="1.0.0-mach",A="mach-local",C="jh4j-compatible";function h(t=96){return t/25.4}function R(t,e=96){return(t||0)*h(e)}function I(t,e=96){return t/h(e)}function S(t,e=96){return t*e/72}function L(t,e){const r=10**e;return Math.round(t*r)/r}const x={a3:{widthMm:297,heightMm:420},a4:{widthMm:210,heightMm:297},a5:{widthMm:148,heightMm:210},b4:{widthMm:250,heightMm:353},b5:{widthMm:176,heightMm:250}},d=T;function H(t){if(t&&t.code!=null&&t.code!==200)throw new Error(String(t.message||"渲染计划加载失败"));const e=t?.data?.pages;return{schemaVersion:d,pages:Array.isArray(e)?e:[]}}function O(t){return(t.kind==="image"||t.kind==="barcode"||t.kind==="qrcode"||t.kind==="chart")&&!!t.imageData}function g(t){return t.kind==="text"&&Array.isArray(t.richParagraphs)&&t.richParagraphs.length>0}const l=/[\u3000-\u9fff\uff00-\uffef]/,f=new Uint8Array(128);{for(const t of"iljtf.,:;'`|!()[]")f[t.charCodeAt(0)]=1;for(const t of"mwMW@")f[t.charCodeAt(0)]=2;for(let t=48;t<=57;t++)f[t]=3;for(let t=65;t<=90;t++)f[t]=4;f[32]=5}const D=[.54,.26,.95,.59,.67,.3];function P(t){const e=t.charCodeAt(0);return e<128?D[f[e]]:l.test(t)?1:/[A-Z]/.test(t)?.67:.54}const a={measureMm(t,e){const{fontSizePt:r,bold:n=!1,letterSpacingPt:u=0}=e,c=25.4/72;let i=0;for(const o of t)i+=P(o);return n&&(i*=1.04),(i*r+u*t.length)*c}};function N(){return a}function w(t,e){return a.measureMm(t,e)}function F(t){let e;return{measureMm(r,n){if(e===void 0&&(e=t()),!e)return a.measureMm(r,n);const u=n.fontSizePt*96/72;return e.font=`${n.bold?"bold ":""}${u}px sans-serif`,e.measureText(r).width*25.4/96}}}function b(t,e,r){const n=[];let u="",c=0;const i=()=>{u&&(n.push({text:u,widthMm:c,cjk:!1}),u="",c=0)};for(const o of t){if(o===`
2
+ `){i(),n.push({text:`
3
+ `,widthMm:0,cjk:!1,br:!0});continue}if(o===" "){i(),n.push({text:o,widthMm:r.measureMm(o,e),cjk:!1,space:!0});continue}if(l.test(o)){i(),n.push({text:o,widthMm:r.measureMm(o,e),cjk:!0});continue}u+=o,c+=r.measureMm(o,e)}return i(),n}function k(t,e,r,n=a){if(!t)return[""];const u=[];let c="",i=0;const o=()=>{u.push(c),c="",i=0};for(const s of b(t,r,n)){if(s.br){o();continue}if(i+s.widthMm<=e){c+=s.text,i+=s.widthMm;continue}if(s.space){o();continue}if(s.cjk){c.length>0&&o(),c=s.text,i=s.widthMm;continue}if(c.length>0&&o(),s.widthMm<=e){c=s.text,i=s.widthMm;continue}for(const _ of s.text){const E=n.measureMm(_,r);i+E>e&&c.length>0&&o(),c+=_,i+=E}}return o(),u}function p(t,e=96,r=10.5){if(t?.fontSizePx!=null)return{fontSizePt:t.fontSizePx*72/e,fontSizePx:t.fontSizePx};const n=t?.fontSize??r;return{fontSizePt:n,fontSizePx:S(n,e)}}function v(t,e=m){return{color:t?.borderColor??t?.lineColor??e,widthPt:t?.lineWidthPt??.75}}function z(t,e=M){return t?.color??e}function U(t){return t?.lineHeight??1.35}function B(t){const e=t?.borderTop!==!1,r=t?.borderRight!==!1,n=t?.borderBottom!==!1,u=t?.borderLeft!==!1;return{top:e,right:r,bottom:n,left:u,inner:e||r||n||u}}exports.CSS_DPI=96;exports.DEFAULT_BORDER_PT=.75;exports.DEFAULT_FONT_PT=10.5;exports.DEFAULT_STROKE_COLOR=m;exports.DEFAULT_TEXT_COLOR=M;exports.LINE_HEIGHT=1.35;exports.MM_PER_INCH=25.4;exports.PAPER_SIZES=x;exports.RENDER_PLAN_SCHEMA_VERSION=d;exports.SCHEMA_VERSION_JH4J=C;exports.SCHEMA_VERSION_LOCAL=A;exports.SCHEMA_VERSION_MACH=T;exports.charWidthEm=P;exports.createCanvasMeasurer=F;exports.createHeuristicMeasurer=N;exports.heuristicMeasurer=a;exports.isImageBackedComponent=O;exports.isRichText=g;exports.measureTextMm=w;exports.mmToPx=R;exports.mmToPxFactor=h;exports.ptToPx=S;exports.pxToMm=I;exports.resolveBoxBorders=B;exports.resolveFontSize=p;exports.resolveLineHeight=U;exports.resolveStroke=v;exports.resolveTextColor=z;exports.round=L;exports.toRenderPlan=H;exports.wrapText=k;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .mrp-toolbar[data-v-2bfb2c61]{display:flex;align-items:center;gap:8px;padding:6px 12px;background:var(--mrp-toolbar-bg, #323639);border-bottom:1px solid var(--mrp-toolbar-border, #22252a);flex:none}.mrp-title[data-v-2bfb2c61]{font-size:13px;font-weight:600;margin-right:8px;color:var(--mrp-toolbar-fg, #e8e8e8)}.mrp-nav[data-v-2bfb2c61]{background:transparent;color:var(--mrp-btn-fg, #cfcfcf);border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:2px 8px;font-size:12px;cursor:pointer;white-space:nowrap}.mrp-nav[data-v-2bfb2c61]:hover:not(:disabled){background:var(--mrp-btn-hover-bg, #414549);color:var(--mrp-btn-hover-fg, #fff)}.mrp-nav[data-v-2bfb2c61]:disabled{opacity:.4;cursor:not-allowed}.mrp-active[data-v-2bfb2c61]{background:var(--mrp-btn-active-bg, #2d5fb8);border-color:var(--mrp-btn-active-bg, #2d5fb8);color:#fff}.mrp-pageinfo[data-v-2bfb2c61]{font-size:12px;min-width:56px;text-align:center;color:var(--mrp-toolbar-fg, #e8e8e8)}.mrp-spacer[data-v-2bfb2c61]{flex:1}.mach-report-preview[data-v-6e07f84a]{--mrp-shell-bg: #525659;--mrp-shell-fg: #e8e8e8;position:relative;--mrp-toolbar-bg: #323639;--mrp-toolbar-border: #22252a;--mrp-toolbar-fg: #e8e8e8;--mrp-btn-fg: #cfcfcf;--mrp-btn-border: #4a4d52;--mrp-btn-hover-bg: #414549;--mrp-btn-hover-fg: #ffffff;--mrp-btn-active-bg: #2d5fb8;display:flex;flex-direction:column;background:var(--mrp-shell-bg);color:var(--mrp-shell-fg);overflow:hidden}.mrp-body[data-v-6e07f84a]{flex:1;overflow:auto;padding:24px}.mrp-scale[data-v-6e07f84a]{margin:0 auto}.mrp-scale-inner[data-v-6e07f84a]{display:flex;flex-direction:column;align-items:center}.mrp-page-holder[data-v-6e07f84a]{background:#fff;box-shadow:0 2px 8px #00000059;margin-bottom:var(--v8289d092);flex:none}.mrp-state[data-v-6e07f84a]{padding:40px;text-align:center;color:#bfbfbf;font-size:13px}.mrp-overlay[data-v-6e07f84a]{position:absolute;inset:0;pointer-events:none}.mrp-error[data-v-6e07f84a]{color:#ff9d9d}.mrp-retry[data-v-6e07f84a]{margin-left:12px;background:transparent;color:#8fb7ff;border:1px solid #5a7fbf;border-radius:4px;padding:1px 10px;cursor:pointer}
1
+ .mrp-toolbar[data-v-f50c26e8]{display:flex;align-items:center;gap:8px;padding:6px 12px;background:var(--mrp-toolbar-bg, #323639);border-bottom:1px solid var(--mrp-toolbar-border, #22252a);flex:none;flex-wrap:wrap}.mrp-title[data-v-f50c26e8]{font-size:13px;font-weight:600;margin-right:8px;color:var(--mrp-toolbar-fg, #e8e8e8)}.mrp-nav[data-v-f50c26e8]{background:transparent;color:var(--mrp-btn-fg, #cfcfcf);border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:2px 8px;font-size:12px;cursor:pointer;white-space:nowrap}.mrp-nav[data-v-f50c26e8]:hover:not(:disabled){background:var(--mrp-btn-hover-bg, #414549);color:var(--mrp-btn-hover-fg, #fff)}.mrp-nav[data-v-f50c26e8]:disabled{opacity:.4;cursor:not-allowed}.mrp-active[data-v-f50c26e8]{background:var(--mrp-btn-active-bg, #2d5fb8);border-color:var(--mrp-btn-active-bg, #2d5fb8);color:#fff}.mrp-pageinfo[data-v-f50c26e8]{font-size:12px;min-width:56px;text-align:center;color:var(--mrp-toolbar-fg, #e8e8e8)}.mrp-spacer[data-v-f50c26e8]{flex:1}.mrp-search[data-v-f50c26e8]{display:flex;align-items:center;gap:4px}.mrp-search-input[data-v-f50c26e8]{background:#22252a;color:#e8e8e8;border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:2px 8px;font-size:12px;width:150px;outline:none}.mrp-search-input[data-v-f50c26e8]:focus{border-color:var(--mrp-btn-active-bg, #2d5fb8)}.mrp-search-count[data-v-f50c26e8]{font-size:12px;color:var(--mrp-toolbar-fg, #e8e8e8);min-width:42px;text-align:center}.mach-report-preview[data-v-02570f40]{--mrp-shell-bg: #525659;--mrp-shell-fg: #e8e8e8;--mrp-toolbar-bg: #323639;--mrp-toolbar-border: #22252a;--mrp-toolbar-fg: #e8e8e8;--mrp-btn-fg: #cfcfcf;--mrp-btn-border: #4a4d52;--mrp-btn-hover-bg: #414549;--mrp-btn-hover-fg: #ffffff;--mrp-btn-active-bg: #2d5fb8;position:relative;display:flex;flex-direction:column;background:var(--mrp-shell-bg);color:var(--mrp-shell-fg);overflow:hidden}.mrp-main[data-v-02570f40]{display:flex;flex:1;min-height:0}.mrp-body[data-v-02570f40]{flex:1;overflow:auto;padding:24px;outline:none}.mrp-scale[data-v-02570f40]{margin:0 auto}.mrp-scale-inner[data-v-02570f40]{display:flex;flex-direction:column;align-items:center}.mrp-page-holder[data-v-02570f40]{background:#fff;box-shadow:0 2px 8px #00000059;margin-bottom:var(--v6094bc50);flex:none}.mrp-state[data-v-02570f40]{padding:40px;text-align:center;color:#bfbfbf;font-size:13px}.mrp-error[data-v-02570f40]{color:#ff9d9d}.mrp-retry[data-v-02570f40]{margin-left:12px;background:transparent;color:#8fb7ff;border:1px solid #5a7fbf;border-radius:4px;padding:1px 10px;cursor:pointer}.mrp-overlay[data-v-02570f40]{position:absolute;inset:0;pointer-events:none}.mrp-page-holder[data-v-02570f40] mark.mrp-hit{background:#ffe066;color:#7a5c00;border-radius:2px;padding:0 1px}.mrp-thumbs[data-v-02570f40]{width:140px;flex:none;overflow-y:auto;border-left:1px solid var(--mrp-toolbar-border);background:var(--mrp-toolbar-bg);padding:8px;display:flex;flex-direction:column;gap:8px}.mrp-thumb[data-v-02570f40]{cursor:pointer;text-align:center}.mrp-thumb-box[data-v-02570f40]{width:116px;background:#fff;box-shadow:0 1px 4px #0006;overflow:hidden;border:2px solid transparent}.mrp-thumb-active .mrp-thumb-box[data-v-02570f40]{border-color:var(--mrp-btn-active-bg)}.mrp-thumb-no[data-v-02570f40]{font-size:11px;color:var(--mrp-toolbar-fg)}.mrp-debug[data-v-02570f40]{position:absolute;right:8px;bottom:8px;background:#000000c7;color:#7ee787;font:11px/1.6 ui-monospace,monospace;padding:6px 10px;border-radius:6px;pointer-events:none;white-space:pre}
@@ -11,6 +11,7 @@ declare function __VLS_template(): {
11
11
  refs: {
12
12
  viewportRef: HTMLDivElement;
13
13
  containerRef: HTMLDivElement;
14
+ thumbsRef: HTMLElement;
14
15
  };
15
16
  rootEl: HTMLDivElement;
16
17
  };
@@ -64,6 +65,11 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
64
65
  type: StringConstructor;
65
66
  default: undefined;
66
67
  };
68
+ /** 调试面板(也可用 URL ?mrp-debug=1 开启) */
69
+ debug: {
70
+ type: BooleanConstructor;
71
+ default: boolean;
72
+ };
67
73
  fetcher: {
68
74
  type: PropType<PlanFetcher | null>;
69
75
  default: null;
@@ -129,6 +135,11 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
129
135
  type: StringConstructor;
130
136
  default: undefined;
131
137
  };
138
+ /** 调试面板(也可用 URL ?mrp-debug=1 开启) */
139
+ debug: {
140
+ type: BooleanConstructor;
141
+ default: boolean;
142
+ };
132
143
  fetcher: {
133
144
  type: PropType<PlanFetcher | null>;
134
145
  default: null;
@@ -145,6 +156,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
145
156
  params: Record<string, string>;
146
157
  furnitureTempId: string;
147
158
  tempId: string | string[] | null;
159
+ debug: boolean;
148
160
  showExport: boolean;
149
161
  showPrint: boolean;
150
162
  showPdfWindow: boolean;
@@ -155,6 +167,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
155
167
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
156
168
  viewportRef: HTMLDivElement;
157
169
  containerRef: HTMLDivElement;
170
+ thumbsRef: HTMLElement;
158
171
  }, HTMLDivElement>;
159
172
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
160
173
  export default _default;
@@ -8,18 +8,35 @@ type __VLS_Props = {
8
8
  showPrint: boolean;
9
9
  showPdfWindow: boolean;
10
10
  messages: MachReportMessages;
11
+ search: {
12
+ visible: boolean;
13
+ query: string;
14
+ matchIndex: number;
15
+ matchCount: number;
16
+ };
17
+ thumbsVisible: boolean;
11
18
  };
12
19
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
13
- print: () => any;
14
20
  zoom: (mode: number | "fit") => any;
21
+ print: () => any;
15
22
  goto: (page: number) => any;
16
23
  export: (format: "html" | "pdf") => any;
17
24
  "pdf-window": () => any;
25
+ "search-input": (query: string) => any;
26
+ "search-nav": (dir: 1 | -1) => any;
27
+ "search-toggle": () => any;
28
+ "thumbs-toggle": () => any;
18
29
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
19
- onPrint?: (() => any) | undefined;
20
30
  onZoom?: ((mode: number | "fit") => any) | undefined;
31
+ onPrint?: (() => any) | undefined;
21
32
  onGoto?: ((page: number) => any) | undefined;
22
33
  onExport?: ((format: "html" | "pdf") => any) | undefined;
23
34
  "onPdf-window"?: (() => any) | undefined;
24
- }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
35
+ "onSearch-input"?: ((query: string) => any) | undefined;
36
+ "onSearch-nav"?: ((dir: 1 | -1) => any) | undefined;
37
+ "onSearch-toggle"?: (() => any) | undefined;
38
+ "onThumbs-toggle"?: (() => any) | undefined;
39
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
40
+ searchInputRef: HTMLInputElement;
41
+ }, HTMLDivElement>;
25
42
  export default _default;
@@ -59,6 +59,10 @@ export declare const MachReportPreview: {
59
59
  type: StringConstructor;
60
60
  default: undefined;
61
61
  };
62
+ debug: {
63
+ type: BooleanConstructor;
64
+ default: boolean;
65
+ };
62
66
  fetcher: {
63
67
  type: import('vue').PropType<import('./adapters').PlanFetcher | null>;
64
68
  default: null;
@@ -87,6 +91,7 @@ export declare const MachReportPreview: {
87
91
  params: Record<string, string>;
88
92
  furnitureTempId: string;
89
93
  tempId: string | string[] | null;
94
+ debug: boolean;
90
95
  showExport: boolean;
91
96
  showPrint: boolean;
92
97
  showPdfWindow: boolean;
@@ -97,6 +102,7 @@ export declare const MachReportPreview: {
97
102
  }, true, {}, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, {
98
103
  viewportRef: HTMLDivElement;
99
104
  containerRef: HTMLDivElement;
105
+ thumbsRef: HTMLElement;
100
106
  }, HTMLDivElement, import('vue').ComponentProvideOptions, {
101
107
  P: {};
102
108
  B: {};
@@ -149,6 +155,10 @@ export declare const MachReportPreview: {
149
155
  type: StringConstructor;
150
156
  default: undefined;
151
157
  };
158
+ debug: {
159
+ type: BooleanConstructor;
160
+ default: boolean;
161
+ };
152
162
  fetcher: {
153
163
  type: import('vue').PropType<import('./adapters').PlanFetcher | null>;
154
164
  default: null;
@@ -171,6 +181,7 @@ export declare const MachReportPreview: {
171
181
  params: Record<string, string>;
172
182
  furnitureTempId: string;
173
183
  tempId: string | string[] | null;
184
+ debug: boolean;
174
185
  showExport: boolean;
175
186
  showPrint: boolean;
176
187
  showPdfWindow: boolean;
@@ -227,6 +238,10 @@ export declare const MachReportPreview: {
227
238
  type: StringConstructor;
228
239
  default: undefined;
229
240
  };
241
+ debug: {
242
+ type: BooleanConstructor;
243
+ default: boolean;
244
+ };
230
245
  fetcher: {
231
246
  type: import('vue').PropType<import('./adapters').PlanFetcher | null>;
232
247
  default: null;
@@ -255,6 +270,7 @@ export declare const MachReportPreview: {
255
270
  params: Record<string, string>;
256
271
  furnitureTempId: string;
257
272
  tempId: string | string[] | null;
273
+ debug: boolean;
258
274
  showExport: boolean;
259
275
  showPrint: boolean;
260
276
  showPdfWindow: boolean;
@@ -59,6 +59,10 @@ export declare const MachReportPreview: {
59
59
  type: StringConstructor;
60
60
  default: undefined;
61
61
  };
62
+ debug: {
63
+ type: BooleanConstructor;
64
+ default: boolean;
65
+ };
62
66
  fetcher: {
63
67
  type: import('vue').PropType<import('./adapters').PlanFetcher | null>;
64
68
  default: null;
@@ -87,6 +91,7 @@ export declare const MachReportPreview: {
87
91
  params: Record<string, string>;
88
92
  furnitureTempId: string;
89
93
  tempId: string | string[] | null;
94
+ debug: boolean;
90
95
  showExport: boolean;
91
96
  showPrint: boolean;
92
97
  showPdfWindow: boolean;
@@ -97,6 +102,7 @@ export declare const MachReportPreview: {
97
102
  }, true, {}, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, {
98
103
  viewportRef: HTMLDivElement;
99
104
  containerRef: HTMLDivElement;
105
+ thumbsRef: HTMLElement;
100
106
  }, HTMLDivElement, import('vue').ComponentProvideOptions, {
101
107
  P: {};
102
108
  B: {};
@@ -149,6 +155,10 @@ export declare const MachReportPreview: {
149
155
  type: StringConstructor;
150
156
  default: undefined;
151
157
  };
158
+ debug: {
159
+ type: BooleanConstructor;
160
+ default: boolean;
161
+ };
152
162
  fetcher: {
153
163
  type: import('vue').PropType<import('./adapters').PlanFetcher | null>;
154
164
  default: null;
@@ -171,6 +181,7 @@ export declare const MachReportPreview: {
171
181
  params: Record<string, string>;
172
182
  furnitureTempId: string;
173
183
  tempId: string | string[] | null;
184
+ debug: boolean;
174
185
  showExport: boolean;
175
186
  showPrint: boolean;
176
187
  showPdfWindow: boolean;
@@ -227,6 +238,10 @@ export declare const MachReportPreview: {
227
238
  type: StringConstructor;
228
239
  default: undefined;
229
240
  };
241
+ debug: {
242
+ type: BooleanConstructor;
243
+ default: boolean;
244
+ };
230
245
  fetcher: {
231
246
  type: import('vue').PropType<import('./adapters').PlanFetcher | null>;
232
247
  default: null;
@@ -255,6 +270,7 @@ export declare const MachReportPreview: {
255
270
  params: Record<string, string>;
256
271
  furnitureTempId: string;
257
272
  tempId: string | string[] | null;
273
+ debug: boolean;
258
274
  showExport: boolean;
259
275
  showPrint: boolean;
260
276
  showPdfWindow: boolean;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 预览内文本高亮(搜索命中标记):
3
+ * - highlightTextNodes:TreeWalker 找文本节点,命中片段包 <mark class="mrp-hit">
4
+ * - clearHighlights:拆包还原(避免重复高亮叠加)
5
+ * 纯 DOM 操作,虚拟化窗口外的页不处理(随窗口重建自然清理)。
6
+ */
7
+ export declare function clearHighlights(root: HTMLElement): void;
8
+ export declare function highlightTextNodes(root: HTMLElement, query: string): number;
@@ -11,7 +11,6 @@ export declare function usePageWindow(plan: Ref<RenderPlan | null>, zoom: Ref<nu
11
11
  pxPerMm?: number;
12
12
  gapPx?: number;
13
13
  }): {
14
- pageHeightsPx: import('vue').ComputedRef<number[]>;
15
14
  contentSize: import('vue').ComputedRef<{
16
15
  w: number;
17
16
  h: number;
@@ -21,8 +20,6 @@ export declare function usePageWindow(plan: Ref<RenderPlan | null>, zoom: Ref<nu
21
20
  page: PlanPage;
22
21
  index: number;
23
22
  }[]>;
24
- scrollTop: Ref<number, number>;
25
- viewportHeight: Ref<number, number>;
26
23
  makeScrollHandler: (currentPage: Ref<number>, pageCount: Ref<number>) => (vp: HTMLElement) => void;
27
24
  refreshViewport(vp: HTMLElement | null): void;
28
25
  };
@@ -7,6 +7,14 @@ interface PrintHtmlResult {
7
7
  }
8
8
  /** 构建打印文档:head(含按尺寸分组的 @page 规则)+ 每页一段 HTML(供流式写入) */
9
9
  export declare function buildPrintDocument(p: RenderPlan): PrintHtmlResult;
10
+ /**
11
+ * 批量打印(多单连打):把多份计划合并为一个打印文档——
12
+ * named pages 保证混合纸张正确分页,浏览器只弹一次打印对话框。
13
+ */
14
+ export declare function printPlans(plans: RenderPlan[], options?: {
15
+ onProgress?: (done: number, total: number) => void;
16
+ onError?: (message: string) => void;
17
+ }): Promise<void>;
10
18
  export declare function usePrintExport(plan: Ref<RenderPlan | null>, hooks: {
11
19
  getPdfExporter: () => PdfExporter;
12
20
  onError: (message: string) => void;
@@ -0,0 +1,72 @@
1
+ import { Ref } from 'vue';
2
+ import { RenderPlan } from '@agile-team/mach-report';
3
+ /**
4
+ * 预览搜索:计划全文索引 → 跳页导航 → 命中页高亮。
5
+ *
6
+ * - 输入防抖(默认 200ms):避免逐键触发 O(全计划) 扫描与页面跳转抖动
7
+ * - matchIndex 循环导航(‹/›),每次导航 gotoPage 到命中所在页
8
+ * - 高亮由页面挂载方调用 apply/clear(虚拟化窗口外的页随窗口重建自然清理)
9
+ */
10
+ export interface ReportSearchState {
11
+ visible: Ref<boolean>;
12
+ query: Ref<string>;
13
+ matchIndex: Ref<number>;
14
+ matchCount: Ref<number>;
15
+ toggle(): void;
16
+ onInput(query: string): void;
17
+ onNav(dir: 1 | -1): void;
18
+ /** 页面元素高亮(查询为空时为 no-op) */
19
+ apply(pageEl: HTMLElement): void;
20
+ clear(pageEl: HTMLElement): void;
21
+ /** 换单据/清空时的整体复位 */
22
+ reset(): void;
23
+ }
24
+ export interface ReportSearchOptions {
25
+ plan: Ref<RenderPlan | null>;
26
+ gotoPage(page: number): void;
27
+ debounceMs?: number;
28
+ highlight: (pageEl: HTMLElement, query: string) => number;
29
+ clearHighlights: (pageEl: HTMLElement) => void;
30
+ }
31
+ export declare function useReportSearch(options: ReportSearchOptions): ReportSearchState;
32
+ /**
33
+ * 调试面板状态:?mrp-debug=1 或 debug prop。
34
+ * planKB 按 plan 引用缓存(滚动/缩放不触发全量 JSON 序列化)。
35
+ */
36
+ export declare function useDebugPanel(debug: Ref<boolean>, stats: {
37
+ plan: Ref<RenderPlan | null>;
38
+ pageCount: Ref<number>;
39
+ windowRange: Ref<{
40
+ start: number;
41
+ end: number;
42
+ }>;
43
+ zoom: Ref<number>;
44
+ loadMs: Ref<number>;
45
+ }): {
46
+ enabled: import('vue').ComputedRef<boolean>;
47
+ debugStats: import('vue').ComputedRef<{
48
+ pages: number;
49
+ window: string;
50
+ zoom: string;
51
+ loadMs: string;
52
+ planKB: number;
53
+ } | null>;
54
+ };
55
+ /**
56
+ * 缩略图侧栏:懒渲染小画布(IntersectionObserver + 低 dpr)。
57
+ * 无 2D 环境(SSR/测试)保留占位框,不抛错。
58
+ */
59
+ export declare function useThumbs(plan: Ref<RenderPlan | null>, opts: {
60
+ thumbsRoot: Ref<HTMLElement | null>;
61
+ visible: Ref<boolean>;
62
+ renderThumbCanvas: (pageIndex: number) => HTMLCanvasElement | null;
63
+ }): {
64
+ schedule: () => void;
65
+ destroy: () => void;
66
+ };
67
+ /** 加载耗时计时(performance 不可用时为 0) */
68
+ export declare function useLoadTiming(): {
69
+ loadMs: Ref<number>;
70
+ start(): number;
71
+ end(t0: number): void;
72
+ };